/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

package org.apache.samoa.moa.core;

import org.apache.samoa.moa.AbstractMOAObject;

/**
 * Gaussian incremental estimator that uses incremental method that is more resistant to floating point imprecision. for
 * more info see Donald Knuth's "The Art of Computer Programming, Volume 2: Seminumerical Algorithms", section 4.2.2.
 * 
 * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz)
 * @version $Revision: 7 $
 */
public class GaussianEstimator extends AbstractMOAObject {

  private static final long serialVersionUID = 1L;

  protected double weightSum;

  protected double mean;

  protected double varianceSum;

  public static final double NORMAL_CONSTANT = Math.sqrt(2 * Math.PI);

  public void addObservation(double value, double weight) {
    if (Double.isInfinite(value) || Double.isNaN(value)) {
      return;
    }
    if (this.weightSum > 0.0) {
      this.weightSum += weight;
      double lastMean = this.mean;
      this.mean += weight * (value - lastMean) / this.weightSum;
      this.varianceSum += weight * (value - lastMean) * (value - this.mean);
    } else {
      this.mean = value;
      this.weightSum = weight;
    }
  }

  public void addObservations(GaussianEstimator obs) {
    // Follows Variance Combination Rule in Section 2 of
    // Brian Babcock, Mayur Datar, Rajeev Motwani, Liadan O'Callaghan:
    // Maintaining variance and k-medians over data stream windows. PODS 2003:
    // 234-243
    //
    if ((this.weightSum >= 0.0) && (obs.weightSum > 0.0)) {
      double oldMean = this.mean;
      this.mean = (this.mean * (this.weightSum / (this.weightSum + obs.weightSum)))
          + (obs.mean * (obs.weightSum / (this.weightSum + obs.weightSum)));
      this.varianceSum += obs.varianceSum + (this.weightSum * obs.weightSum / (this.weightSum + obs.weightSum) *
          Math.pow(obs.mean - oldMean, 2));
      this.weightSum += obs.weightSum;
    }
  }

  public double getTotalWeightObserved() {
    return this.weightSum;
  }

  public double getMean() {
    return this.mean;
  }

  public double getStdDev() {
    return Math.sqrt(getVariance());
  }

  public double getVariance() {
    return this.weightSum > 1.0 ? this.varianceSum / (this.weightSum - 1.0)
        : 0.0;
  }

  public double probabilityDensity(double value) {
    if (this.weightSum > 0.0) {
      double stdDev = getStdDev();
      if (stdDev > 0.0) {
        double diff = value - getMean();
        return (1.0 / (NORMAL_CONSTANT * stdDev))
            * Math.exp(-(diff * diff / (2.0 * stdDev * stdDev)));
      }
      return value == getMean() ? 1.0 : 0.0;
    }
    return 0.0;
  }

  public double[] estimatedWeight_LessThan_EqualTo_GreaterThan_Value(
      double value) {
    double equalToWeight = probabilityDensity(value) * this.weightSum;
    double stdDev = getStdDev();
    double lessThanWeight = stdDev > 0.0 ? org.apache.samoa.moa.core.Statistics
        .normalProbability((value - getMean()) / stdDev)
        * this.weightSum - equalToWeight
        : (value < getMean() ? this.weightSum - equalToWeight : 0.0);
    double greaterThanWeight = this.weightSum - equalToWeight
        - lessThanWeight;
    if (greaterThanWeight < 0.0) {
      greaterThanWeight = 0.0;
    }
    return new double[] { lessThanWeight, equalToWeight, greaterThanWeight };
  }

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