public class SegmentStoreStatistics {
private long fMin;
private long fMax;
- private long fSum;
private long fNbSegments;
+ private double fAverage;
+ private double fVariance;
/**
* Constructor
*/
public SegmentStoreStatistics() {
- this.fMin = Long.MAX_VALUE;
- this.fMax = Long.MIN_VALUE;
- this.fSum = 0;
- this.fNbSegments = 0;
+ fMin = Long.MAX_VALUE;
+ fMax = Long.MIN_VALUE;
+ fNbSegments = 0;
+ fAverage = 0.0;
+ fVariance = 0.0;
}
/**
* @return arithmetic average
*/
public double getAverage() {
- return ((double) fSum) / fNbSegments;
+ return fAverage;
+ }
+
+ /**
+ * Gets the standard deviation of the segments, uses the online algorithm
+ * shown here <a href=
+ * "https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm">
+ * Wikipedia article of dec 3 2015 </a>
+ *
+ * @return the standard deviation of the segment store, will return NaN if
+ * there are less than 3 elements
+ */
+ public double getStdDev() {
+ return fNbSegments > 2 ? Math.sqrt(fVariance / (fNbSegments - 1)) : Double.NaN;
}
/**
* Update the statistics based on a given segment
+ * <p>
+ * This is an online algorithm and must retain a complexity of O(1)
*
* @param segment
* the segment used for the update
*/
- public void update (ISegment segment) {
+ public void update(ISegment segment) {
long value = segment.getLength();
+ /*
+ * Min and max are trivial, as well as number of segments
+ */
fMin = Math.min(fMin, value);
fMax = Math.max(fMax, value);
- fSum += value;
+
fNbSegments++;
+ /*
+ * The running mean is not trivial, see proof in javadoc.
+ */
+ double delta = value - fAverage;
+ fAverage += delta / fNbSegments;
+ fVariance += delta * (value - fAverage);
}
}