Example #1
0
  @Override
  public void detect(AdaptiveFilter<Long> filter) {

    // Preamble
    int threshold = getSetting(THRESHOLD_PROPERTY).intValue();
    double drift = getSetting(DRIFT_PROPERTY).doubleValue();
    int robustness = getSetting(ROBUSTNESS_PROPERTY).intValue();

    double negativeCusum = 0;
    double positiveCusum = 0;

    List<DataPoint<Long>> residuals = filter.getResiduals().getDataAsList();
    List<DataPoint<Long>> variances = filter.getVariance().getDataAsList();

    for (int i = 0; i < residuals.size(); i++) {

      List<Detection<Long>> detections = getDetections();
      Detection<Long> lastDetection = null;
      if (!detections.isEmpty()) {
        lastDetection = detections.get(detections.size() - 1);
      }

      // Get residual
      double residual = residuals.get(i).getValue();
      double variance = variances.get(i).getValue();

      // normalize residual, but avoid division by zero. Cause that's bad.
      if (variance != 0) {
        residual = Math.pow(residual, 2) / Math.pow(variance, 2);
      } else {
        residual = Math.pow(residual, 2);
      }

      // CUSUM algorithm performed on residuals
      positiveCusum = Math.max(0, positiveCusum + drift + residual);
      negativeCusum =
          Math.max(0, Math.abs(negativeCusum + drift - residual)); /* Abs might not be needed -->*/

      if (positiveCusum > threshold || negativeCusum > threshold) {

        robustness--;
        if (robustness == 0) {

          if (detections.isEmpty() || lastDetection.hasStop()) {
            detections.add(
                new Detection<Long>(
                    new Long(i), Math.round(Math.max(positiveCusum, negativeCusum))));

            positiveCusum = 0;
            negativeCusum = 0;

            robustness = getSetting(ROBUSTNESS_PROPERTY).intValue();
          } else {
            if (i - lastDetection.getTouched() > getSetting(ROBUSTNESS_PROPERTY).intValue()) {
              lastDetection.setStop(new Long(i));
            } else {
              lastDetection.touch(new Long(i));
            }
          }
        }
      } else {

        boolean detectionsExist = detections.size() > 0;
        boolean lastDetectionIsNotAlreadyStopped = !lastDetection.hasStop();

        if (detectionsExist && lastDetectionIsNotAlreadyStopped) {
          if ((i - lastDetection.getTouched()) > robustness) {
            lastDetection.setStop(new Long(i));
          }
        }
        robustness = getSetting(ROBUSTNESS_PROPERTY).intValue();
      }
    }
    if (!getDetections().isEmpty()) {
      Detection<Long> lastDetection = getDetections().get(getDetections().size() - 1);
      if (!lastDetection.hasStop()) {
        lastDetection.setStop(new Long(residuals.size()));
      }
    }
  }