public PAA(MultivariateTimeSeries ts, int shrunkSize) { this.originalLength = ts.size(); this.aggPtSize = new int[shrunkSize]; this.setDimensions(ts.getDimensions()); final double reducedPtSize = ts.size() / (double) shrunkSize; while (ptToReadFrom < ts.size()) { ptToReadTo = (int) Math.round(reducedPtSize * (this.size() + 1)) - 1; // determine end of current range final int ptsToRead = ptToReadTo - ptToReadFrom + 1; final double[] measurementSums = new double[ts.numOfDimensions()]; final double[] currentPoint = ts.getMeasurementVector(pt); timeSum += ts.getTimeAtNthPoint(pt); for (int dim = 0; dim < ts.numOfDimensions(); dim++) measurementSums[dim] += currentPoint[dim]; for (int dim = 0; dim < ts.numOfDimensions(); dim++) this.aggPtSize[super.size()] = ptsToRead; this.add(timeSum, measurementSums);
public void normalize() { // Calculate the mean of each FD. final double[] mean = new double[this.numOfDimensions()]; for (int col = 0; col < numOfDimensions(); col++) { double currentSum = 0.0; for (int row = 0; row < this.size(); row++) currentSum += this.getMeasurement(row, col); mean[col] = currentSum / this.size(); } // end for loop // Calculate the standard deviation of each FD. final double[] stdDev = new double[numOfDimensions()]; for (int col = 0; col < numOfDimensions(); col++) { double variance = 0.0; for (int row = 0; row < this.size(); row++) variance += Math.abs(getMeasurement(row, col) - mean[col]); stdDev[col] = variance / this.size(); } // end for loop // Normalize the values in the data using the mean and standard deviation // for each FD. => Xrc = (Xrc-Mc)/SDc for (int row = 0; row < this.size(); row++) { for (int col = 0; col < numOfDimensions(); col++) { // Normalize data point. if (stdDev[col] == 0.0) // prevent divide by zero errors setMeasurement(row, col, 0.0); // stdDev is zero means all pts identical else // typical case setMeasurement(row, col, (getMeasurement(row, col) - mean[col]) / stdDev[col]); } // end for loop } // end for loop } // end normalize();
@Override public String toString() { return new ToStringBuilder(this) .appendSuper(super.toString()) .append("aggPtSize", aggPtSize) .append("originalLength", originalLength) .toString(); } }
final double[][] costMatrix = new double[tsI.size()][tsJ.size()]; final int maxI = tsI.size() - 1; final int maxJ = tsJ.size() - 1; costMatrix[0][0] = distFn.calcDistance(tsI.getMeasurementVector(0), tsJ.getMeasurementVector(0)); for (int j = 1; j <= maxJ; j++) costMatrix[0][j] = costMatrix[0][j - 1] + distFn.calcDistance(tsI.getMeasurementVector(0), tsJ.getMeasurementVector(j)); costMatrix[i][0] = costMatrix[i - 1][0] + distFn.calcDistance(tsI.getMeasurementVector(i), tsJ.getMeasurementVector(0)); Math.min(costMatrix[i - 1][j - 1], costMatrix[i][j - 1])); costMatrix[i][j] = minGlobalCost + distFn.calcDistance(tsI.getMeasurementVector(i), tsJ.getMeasurementVector(j)); return new TimeWarpInfo(minimumCost, minCostPath, tsI.size(), tsJ.size());
public static TimeWarpInfo getWarpInfoBetween(final MultivariateTimeSeries tsI, final MultivariateTimeSeries tsJ, int searchRadius, final DistanceFunction distFn) { if (tsI.size() == 0 || tsJ.size() == 0) { return new TimeWarpInfo(0, new WarpPath(0), tsI.size(), tsJ.size()); } return fastDTW(tsI, tsJ, searchRadius, distFn); }
MultivariateTimeSeries multivariateTimeSeries = new MultivariateTimeSeries(1); multivariateTimeSeries.add(formerTimestamp, new double[]{formerValue}); formerTimestamp = timeSeries.getTime(i); formerValue = timeSeries.getValue(i); multivariateTimeSeries.add(formerTimestamp, new double[]{formerValue});
private static void calcCostMatrix(MultivariateTimeSeries tsI, MultivariateTimeSeries tsJ, DistanceFunction distFn, CostMatrix costMatrix, Iterator<ColMajorCell> matrixIterator) { while (matrixIterator.hasNext()) { final ColMajorCell currentCell = matrixIterator.next(); // current cell being filled final int i = currentCell.getCol(); final int j = currentCell.getRow(); if ((i == 0) && (j == 0)) // bottom left cell (first row AND first column) costMatrix.put(i, j, distFn.calcDistance(tsI.getMeasurementVector(0), tsJ.getMeasurementVector(0))); else if (i == 0) // first column { costMatrix.put(i, j, distFn.calcDistance(tsI.getMeasurementVector(0), tsJ.getMeasurementVector(j)) + costMatrix.get(i, j - 1)); } else if (j == 0) // first row { costMatrix.put(i, j, distFn.calcDistance(tsI.getMeasurementVector(i), tsJ.getMeasurementVector(0)) + costMatrix.get(i - 1, j)); } else // not first column or first row { final double minGlobalCost = Math.min(costMatrix.get(i - 1, j), Math.min(costMatrix.get(i - 1, j - 1), costMatrix.get(i, j - 1))); costMatrix.put(i, j, minGlobalCost + distFn.calcDistance(tsI.getMeasurementVector(i), tsJ.getMeasurementVector(j))); } } }
public void add(long time, double[] values) { if (labels.size() != values.length + 1) // labels include a label for time throw new InternalError("ERROR: The TSValues: " + values + " contains the wrong number of values. " + "expected: " + labels.size() + ", " + "found: " + values.length); if ((this.size() > 0) && (time <= times.get(times.size() - 1))) throw new InternalError("ERROR: The point being inserted at the " + "end of the time series does not have " + "the correct time sequence. "); times.add(time); this.values.add(values); }
public static double calcWarpCost(WarpPath path, MultivariateTimeSeries tsI, MultivariateTimeSeries tsJ, DistanceFunction distFn) { double totalCost = 0.0; for (int p = 0; p < path.size(); p++) { final ColMajorCell currWarp = path.get(p); totalCost += distFn.calcDistance(tsI.getMeasurementVector(currWarp.getCol()), tsJ.getMeasurementVector(currWarp.getRow())); } return totalCost; }
private static TimeWarpInfo fastDTW(final MultivariateTimeSeries tsI, final MultivariateTimeSeries tsJ, int searchRadius, final DistanceFunction distFn) { if (searchRadius < 0) searchRadius = 0; final int minTSsize = searchRadius + 2; if ((tsI.size() <= minTSsize) || (tsJ.size() <= minTSsize)) { // Perform full Dynamic Time Warping. return DTW.getWarpInfoBetween(tsI, tsJ, distFn); } else { final PAA shrunkI = new PAA(tsI, tsI.size() / 2); final PAA shrunkJ = new PAA(tsJ, tsJ.size() / 2); // Determine the search window that constrains the area of the cost matrix that will be evaluated based on // the warp path found at the previous resolution (smaller time series). final WarpPath warpPath = getWarpInfoBetween(shrunkI, shrunkJ, searchRadius, distFn).getPath(); final SearchWindow window = new ExpandedResWindow(tsI, tsJ, shrunkI, shrunkJ, warpPath, searchRadius); // Find the optimal warp path through this search window constraint. return DTW.getWarpInfoBetween(tsI, tsJ, window, distFn); } } }