package lsr.common;
/**
* Represents exponential moving average
*
* A moving average is the simplest average, to calculate it we need only last
* value and a constant how much from the new value has to be taken.
*
* The recursion follows as this: factor*newValue + (1-factor)*oldValue
*
* Transforming from recursion to typical equation it turns out that the weights
* for older elements are exponentially fading. If, after some time the input
* stabilizes to a constant, the bigger our factor is, the faster our average
* approaches this constant. That's why we call it a "convergence" factor.
*/
public class MovingAverage {
/** How important is the last value - range (0,1) */
private final double convergenceFactor;
/** Starting point if no given */
private volatile double average = 0;
public MovingAverage(double convergenceFactor, double firstAverage) {
if (0 >= convergenceFactor || convergenceFactor >= 1) {
throw new IllegalArgumentException("Incorrect convergence factor in moving average.");
}
this.convergenceFactor = convergenceFactor;
average = firstAverage;
}
/** Calculates next average basing on next value */
public double add(double value) {
average = (1 - convergenceFactor) * average + convergenceFactor * value;
return average;
}
/**
* (re)Starts the calculation with newAverage, that is treats newAverage as
* the current value
*/
public void reset(double newAverage) {
average = newAverage;
}
/** Returns the current value */
public double get() {
return average;
}
}