package com.github.pfichtner.jrunalyser.base.util;
import static com.google.common.base.Preconditions.checkArgument;
import javax.annotation.Nonnegative;
import javax.annotation.concurrent.NotThreadSafe;
@NotThreadSafe
public class MovingAverage {
private final int period;
private int pos;
private double[] window = new double[0];
private double sum;
public MovingAverage(@Nonnegative int period) {
this.period = period;
checkArgument(period > 0, "Period must be a positive integer");
}
public double add(double num) {
boolean resizeNeeded = this.pos >= this.window.length
&& this.pos < this.period;
this.sum += num; // add new value
if (resizeNeeded) {
resize();
} else {
this.sum -= this.window[this.pos]; // subtract old value
}
this.window[this.pos] = num;
if (++this.pos == this.period) {
this.pos = 0;
}
return getValue();
}
public double getValue() {
return this.sum / this.window.length;
}
private void resize() {
double[] tmp = new double[this.window.length + 1];
System.arraycopy(this.window, 0, tmp, 0, this.window.length);
this.window = tmp;
}
}