in library-udf/src/main/java/org/apache/iotdb/library/match/PatternExecutor.java [434:593]
private PatternCalculationResult calculatePointsMatch(
List<Section> querySections, List<Section> matchedSections, boolean partialQuery) {
if (PatternMatchConfig.CHECK_QUERY_COMPATIBILITY) {
if (!areCompatibleSections(querySections, matchedSections, !partialQuery)) {
return null;
}
} else {
if (querySections.size() > matchedSections.size()) {
matchedSections = expandSections(matchedSections, querySections.size());
} else if (querySections.size() < matchedSections.size()) {
matchedSections = reduceSections(matchedSections, querySections.size());
}
if (matchedSections == null) {
return null;
}
if (!areCompatibleSections(querySections, matchedSections, !partialQuery)) {
return null;
}
}
double centroidsDifference;
int i, si;
Bounds matchedSecBounds =
getBounds(
matchedSections,
(matchedSections.size() > 2 ? 1 : 0),
matchedSections.size() - (matchedSections.size() > 2 ? 2 : 1));
Bounds queryBounds =
getBounds(
querySections,
(querySections.size() > 2 ? 1 : 0),
querySections.size() - (querySections.size() > 2 ? 2 : 1));
double subSequenceScaleFactorX =
(matchedSecBounds.getMaxX() - matchedSecBounds.getMinX())
/ (queryBounds.getMaxX() - queryBounds.getMinX());
double subSequenceScaleFactorY =
(matchedSecBounds.getMaxY() - matchedSecBounds.getMinY())
/ (queryBounds.getMaxY() - queryBounds.getMinY());
List<Point> matchedPoints = new ArrayList<>();
double pointDifferencesCost = 0;
double rescalingCost = 0;
double sum = 0;
double num = 0;
for (si = 0; si < querySections.size(); si++) {
SectionCalculation dataSect = new SectionCalculation();
SectionCalculation querySect = new SectionCalculation();
sum = 0;
num = 0;
querySect.setPoints(querySections.get(si).getPoints());
querySect.setWidth(calcWidth(querySect.getPoints()));
querySect.setHeight(calcHeight(querySect.getPoints()));
if (querySect.getHeight() == 0) {
continue;
}
if (si == 0 && querySections.size() > 2 && PatternMatchConfig.START_END_CUT_IN_SUBPARTS) {
dataSect.setPoints(
sectionEndSubpartPoints(
matchedSections.get(si), querySect.getWidth() * subSequenceScaleFactorX));
} else if (si == querySections.size() - 1
&& querySections.size() > 2
&& PatternMatchConfig.START_END_CUT_IN_SUBPARTS_IN_RESULTS) {
dataSect.setPoints(
sectionStartSubpartPoints(
matchedSections.get(si), querySect.getWidth() * subSequenceScaleFactorX));
} else {
dataSect.setPoints(matchedSections.get(si).getPoints());
}
dataSect.setWidth(calcWidth(dataSect.getPoints()));
dataSect.setHeight(calcHeight(dataSect.getPoints()));
if (dataSect.getHeight() == 0) {
continue;
}
double scaleFactorX = dataSect.getWidth() / (querySect.getWidth() * subSequenceScaleFactorX);
double scaleFactorY =
dataSect.getHeight()
/ (querySect.getHeight()
* (PatternMatchConfig.RESCALING_Y
? subSequenceScaleFactorY
: subSequenceScaleFactorX));
if (scaleFactorX != 0 && scaleFactorY != 0) {
rescalingCost +=
(Math.pow(Math.log(scaleFactorX), 2) + Math.pow(Math.log(scaleFactorY), 2));
}
// calculate the centroid of the two sections to align them
dataSect.setCentroidY(0);
for (i = 0; i < dataSect.getPoints().size(); i++) {
dataSect.setCentroidY(dataSect.getCentroidY() + dataSect.getPoints().get(i).getY());
}
dataSect.setCentroidY(dataSect.getCentroidY() / dataSect.getPoints().size());
querySect.setCentroidY(0);
for (i = 0; i < querySect.getPoints().size(); i++) {
querySect.setCentroidY(
querySect.getPoints().get(0).getY()
* (PatternMatchConfig.RESCALING_Y
? subSequenceScaleFactorY
: subSequenceScaleFactorX)
* scaleFactorY);
}
querySect.setCentroidY(querySect.getCentroidY() / querySect.getPoints().size());
centroidsDifference =
querySect.getPoints().get(0).getY()
* (PatternMatchConfig.RESCALING_Y
? subSequenceScaleFactorY
: subSequenceScaleFactorX)
* scaleFactorY
- dataSect.getPoints().get(0).getY();
double queryPtsStep = (double) querySect.getPoints().size() / dataSect.getPoints().size();
for (i = 0; i < dataSect.getPoints().size(); i++) {
Point dataPt = dataSect.getPoints().get(i);
Point queryPt = querySect.getPoints().get((int) Math.floor(i * queryPtsStep));
double resSum =
Math.abs(
(queryPt.getY()
* (PatternMatchConfig.RESCALING_Y
? subSequenceScaleFactorY
: subSequenceScaleFactorX)
* scaleFactorY
- centroidsDifference)
- dataPt.getY())
/ dataSect.getHeight();
sum += resSum;
num++;
}
if (!partialQuery) {
if (PatternMatchConfig.START_END_CUT_IN_SUBPARTS_IN_RESULTS) {
for (i = 0; i < dataSect.getPoints().size(); i++) {
matchedPoints.add(dataSect.getPoints().get(i));
}
} else {
for (i = 0; i < matchedSections.get(si).getPoints().size(); i++) {
matchedPoints.add(matchedSections.get(si).getPoints().get(i));
}
}
}
if (num > 0) {
pointDifferencesCost += sum / num;
}
}
PatternCalculationResult result = new PatternCalculationResult();
result.setMatch(
pointDifferencesCost * PatternMatchConfig.VALUE_DIFFERENCE_WEIGHT
+ rescalingCost * PatternMatchConfig.RESCALING_COST_WEIGHT);
result.setMatchedPoints(matchedPoints);
return result;
}