diff --git a/FastRngTests/Double/RunningStatistics.cs b/FastRngTests/Double/RunningStatistics.cs new file mode 100644 index 0000000..f1b5210 --- /dev/null +++ b/FastRngTests/Double/RunningStatistics.cs @@ -0,0 +1,47 @@ +using System; + +namespace FastRngTests.Double +{ + internal sealed class RunningStatistics + { + private double previousM; + private double previousS; + private double nextM; + private double nextS; + + public RunningStatistics() + { + } + + public int NumberRecords { get; private set; } = 0; + + public void Clear() => this.NumberRecords = 0; + + public void Push(double x) + { + this.NumberRecords++; + + // See Knuth TAOCP vol 2, 3rd edition, page 232 + if (this.NumberRecords == 1) + { + previousM = nextM = x; + previousS = 0.0; + } + else + { + nextM = previousM + (x - previousM) / this.NumberRecords; + nextS = previousS + (x - previousM) * (x - nextM); + + // set up for next iteration + previousM = nextM; + previousS = nextS; + } + } + + public double Mean => this.NumberRecords > 0 ? nextM : 0.0; + + public double Variance => this.NumberRecords > 1 ? nextS / (NumberRecords - 1) : 0.0; + + public double StandardDeviation => Math.Sqrt(this.Variance); + } +} \ No newline at end of file