From 69a8b656da5513f125c645b325ee7a5f9f7c1394 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Wed, 16 Apr 2014 01:42:21 +0200 Subject: [PATCH] Statistics: DescriptiveStatistics must use a long counter to support large sample sets --- .../Statistics/DescriptiveStatistics.cs | 12 +++++----- .../StatisticsTests/StatisticsTests.cs | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Numerics/Statistics/DescriptiveStatistics.cs b/src/Numerics/Statistics/DescriptiveStatistics.cs index ccb97c6c..e49c8444 100644 --- a/src/Numerics/Statistics/DescriptiveStatistics.cs +++ b/src/Numerics/Statistics/DescriptiveStatistics.cs @@ -104,7 +104,7 @@ namespace MathNet.Numerics.Statistics /// Gets the size of the sample. /// /// The size of the sample. - public int Count { get; private set; } + public long Count { get; private set; } /// /// Gets the sample mean. @@ -162,7 +162,7 @@ namespace MathNet.Numerics.Statistics double kurtosis = 0; double minimum = Double.PositiveInfinity; double maximum = Double.NegativeInfinity; - int n = 0; + long n = 0; foreach (var xi in data) { double delta = xi - mean; @@ -202,7 +202,7 @@ namespace MathNet.Numerics.Statistics double kurtosis = 0; double minimum = Double.PositiveInfinity; double maximum = Double.NegativeInfinity; - int n = 0; + long n = 0; foreach (var xi in data) { if (xi.HasValue) @@ -244,7 +244,7 @@ namespace MathNet.Numerics.Statistics decimal kurtosis = 0; decimal minimum = Decimal.MaxValue; decimal maximum = Decimal.MinValue; - int n = 0; + long n = 0; foreach (double x in data) { decimal xi = (decimal)x; @@ -284,7 +284,7 @@ namespace MathNet.Numerics.Statistics decimal kurtosis = 0; decimal minimum = Decimal.MaxValue; decimal maximum = Decimal.MinValue; - int n = 0; + long n = 0; foreach (double? x in data) { if (x.HasValue) @@ -325,7 +325,7 @@ namespace MathNet.Numerics.Statistics /// For setting Minimum. /// For setting Maximum. /// For setting Count. - void SetStatistics(double mean, double variance, double skewness, double kurtosis, double minimum, double maximum, int n) + void SetStatistics(double mean, double variance, double skewness, double kurtosis, double minimum, double maximum, long n) { Mean = mean; Count = n; diff --git a/src/UnitTests/StatisticsTests/StatisticsTests.cs b/src/UnitTests/StatisticsTests/StatisticsTests.cs index 8c84c349..87a16ece 100644 --- a/src/UnitTests/StatisticsTests/StatisticsTests.cs +++ b/src/UnitTests/StatisticsTests/StatisticsTests.cs @@ -988,6 +988,29 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests Assert.That(SortedArrayStatistics.Median(new[] { double.NegativeInfinity, 2.0, double.PositiveInfinity }), Is.EqualTo(2.0)); Assert.That(SortedArrayStatistics.Median(new[] { double.NegativeInfinity, 2.0, 3.0, double.PositiveInfinity }), Is.EqualTo(2.5)); } + + [Test] + public void RobustOnLargeSampleSets() + { + // 0, 0.25, 0.5, 0.75, 0, 0.25, 0.5, 0.75, ... + var shorter = Generate.Periodic(4*4096, 4, 1); + var longer = Generate.Periodic(4*32768, 4, 1); + + Assert.That(Statistics.Mean(shorter), Is.EqualTo(0.375).Within(1e-14), "Statistics.Mean: shorter"); + Assert.That(Statistics.Mean(longer), Is.EqualTo(0.375).Within(1e-14), "Statistics.Mean: longer"); + Assert.That(new DescriptiveStatistics(shorter).Mean, Is.EqualTo(0.375).Within(1e-14), "DescriptiveStatistics.Mean: shorter"); + Assert.That(new DescriptiveStatistics(longer).Mean, Is.EqualTo(00.375).Within(1e-14), "DescriptiveStatistics.Mean: longer"); + + Assert.That(Statistics.Skewness(shorter), Is.EqualTo(0.0).Within(1e-12), "Statistics.Skewness: shorter"); + Assert.That(Statistics.Skewness(longer), Is.EqualTo(0.0).Within(1e-12), "Statistics.Skewness: longer"); + Assert.That(new DescriptiveStatistics(shorter).Skewness, Is.EqualTo(0.0).Within(1e-12), "DescriptiveStatistics.Skewness: shorter"); + Assert.That(new DescriptiveStatistics(longer).Skewness, Is.EqualTo(0.0).Within(1e-12), "DescriptiveStatistics.Skewness: longer"); + + Assert.That(Statistics.Kurtosis(shorter), Is.EqualTo(-1.36).Within(1e-4), "Statistics.Kurtosis: shorter"); + Assert.That(Statistics.Kurtosis(longer), Is.EqualTo(-1.36).Within(1e-4), "Statistics.Kurtosis: longer"); + Assert.That(new DescriptiveStatistics(shorter).Kurtosis, Is.EqualTo(-1.36).Within(1e-4), "DescriptiveStatistics.Kurtosis: shorter"); + Assert.That(new DescriptiveStatistics(longer).Kurtosis, Is.EqualTo(-1.36).Within(1e-4), "DescriptiveStatistics.Kurtosis: longer"); + } } }