package org.streaminer.stream.change; /** * Non-parametric CUSUM change detection algorithm. * Source code: https://github.com/blockmon/blockmon * * @author Maycon Viana Bordin <mayconbordin@gmail.com> */ public class CusumNP extends AbstractCusum { private int meanWindow; private double offset; private double[] lastValues; private int lastValueIndex = 0; private int lastValuesCount = 0; /** * Constructor * * @param threshold The minimum sum to throw an alarm * @param meanWindow Number of last values with which the mean should be evaluated * @param offset Value to add to the difference in the score computation */ public CusumNP(double threshold, int meanWindow, double offset) { super(threshold); this.meanWindow = meanWindow; this.offset = offset; lastValues = new double[meanWindow]; } @Override protected double computeScore(double value) { // compute the mean double mean; if (lastValuesCount > 0) { mean = 0; for (int i=0; i<lastValuesCount; i++) mean += lastValues[i]; mean /= (double)lastValuesCount; } else { mean = value; } // compute the score double score = value - mean - offset; // Add the current value to compute the next mean lastValues[lastValueIndex] = value; lastValueIndex = (lastValueIndex + 1) % meanWindow; if (lastValuesCount < meanWindow) lastValuesCount++; return score; } @Override protected void resetScore() { lastValueIndex = 0; lastValuesCount = 0; } }