package com.yahoo.labs.samoa.moa.classifiers.core.driftdetection;

/*
 * #%L
 * SAMOA
 * %%
 * Copyright (C) 2014 - 2015 Apache Software Foundation
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import com.yahoo.labs.samoa.moa.core.ObjectRepository;
import com.yahoo.labs.samoa.moa.tasks.TaskMonitor;

/**
 * Drift detection method based in EDDM method of Manuel Baena et al.
 * 
 * <p>
 * Early Drift Detection Method. Manuel Baena-Garcia, Jose Del Campo-Avila, Raúl Fidalgo, Albert Bifet, Ricard Gavalda,
 * Rafael Morales-Bueno. In Fourth International Workshop on Knowledge Discovery from Data Streams, 2006.
 * </p>
 * 
 * @author Manuel Baena (mbaena@lcc.uma.es)
 * @version $Revision: 7 $
 */
public class EDDM extends AbstractChangeDetector {

  /**
     *
     */
  private static final long serialVersionUID = 140980267062162000L;

  private static final double FDDM_OUTCONTROL = 0.9;

  private static final double FDDM_WARNING = 0.95;

  private static final double FDDM_MINNUMINSTANCES = 30;

  private double m_numErrors;

  private int m_minNumErrors = 30;

  private int m_n;

  private int m_d;

  private int m_lastd;

  private double m_mean;

  private double m_stdTemp;

  private double m_m2smax;

  public EDDM() {
    resetLearning();
  }

  @Override
  public void resetLearning() {
    m_n = 1;
    m_numErrors = 0;
    m_d = 0;
    m_lastd = 0;
    m_mean = 0.0;
    m_stdTemp = 0.0;
    m_m2smax = 0.0;
    this.estimation = 0.0;
  }

  @Override
  public void input(double prediction) {
    // prediction must be 1 or 0
    // It monitors the error rate
    // System.out.print(prediction + " " + m_n + " " + probability + " ");
    if (this.isChangeDetected) {
      resetLearning();
    }
    this.isChangeDetected = false;

    m_n++;
    if (prediction == 1.0) {
      this.isWarningZone = false;
      this.delay = 0;
      m_numErrors += 1;
      m_lastd = m_d;
      m_d = m_n - 1;
      int distance = m_d - m_lastd;
      double oldmean = m_mean;
      m_mean = m_mean + ((double) distance - m_mean) / m_numErrors;
      this.estimation = m_mean;
      m_stdTemp = m_stdTemp + (distance - m_mean) * (distance - oldmean);
      double std = Math.sqrt(m_stdTemp / m_numErrors);
      double m2s = m_mean + 2 * std;

      if (m2s > m_m2smax) {
        if (m_n > FDDM_MINNUMINSTANCES) {
          m_m2smax = m2s;
        }
        // m_lastLevel = DDM_INCONTROL_LEVEL;
        // System.out.print(1 + " ");
      } else {
        double p = m2s / m_m2smax;
        // System.out.print(p + " ");
        if (m_n > FDDM_MINNUMINSTANCES && m_numErrors > m_minNumErrors
            && p < FDDM_OUTCONTROL) {
          // System.out.println(m_mean + ",D");
          this.isChangeDetected = true;
          // resetLearning();
        } else {
          this.isWarningZone = m_n > FDDM_MINNUMINSTANCES
              && m_numErrors > m_minNumErrors && p < FDDM_WARNING;
        }
      }
    }
  }

  @Override
  public void getDescription(StringBuilder sb, int indent) {
    // TODO Auto-generated method stub
  }

  @Override
  protected void prepareForUseImpl(TaskMonitor monitor,
      ObjectRepository repository) {
    // TODO Auto-generated method stub
  }
}
