From 3e1cd366989ab8e81e2cdc7075e601bedb38c63b Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Thu, 10 Apr 2014 22:59:37 +0200 Subject: [PATCH] Statistics: descriptive statistics which are not available must be NaN #210 --- .../Statistics/DescriptiveStatistics.cs | 21 ++++----- .../DescriptiveStatisticsTests.cs | 44 ++++++++++++++++--- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/Numerics/Statistics/DescriptiveStatistics.cs b/src/Numerics/Statistics/DescriptiveStatistics.cs index 88e49fb6..b93f73d2 100644 --- a/src/Numerics/Statistics/DescriptiveStatistics.cs +++ b/src/Numerics/Statistics/DescriptiveStatistics.cs @@ -36,13 +36,13 @@ namespace MathNet.Numerics.Statistics /// /// Computes the basic statistics of data set. The class meets the /// NIST standard of accuracy for mean, variance, and standard deviation - /// (the only statistics they provide exact values for) and exceeds them + /// (the only statistics they provide exact values for) and exceeds them /// in increased accuracy mode. /// public class DescriptiveStatistics { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The sample data. /// @@ -71,7 +71,7 @@ namespace MathNet.Numerics.Statistics } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The sample data. /// @@ -189,8 +189,6 @@ namespace MathNet.Numerics.Statistics SetStatistics(mean, variance, skewness, kurtosis, minimum, maximum, n); } - - /// /// Computes descriptive statistics from a stream of nullable data values. /// @@ -230,9 +228,7 @@ namespace MathNet.Numerics.Statistics } } } - SetStatistics(mean, variance, skewness, kurtosis, minimum, maximum, n); - } /// @@ -272,9 +268,7 @@ namespace MathNet.Numerics.Statistics maximum = xi; } } - SetStatistics((double)mean, (double)variance, (double)skewness, (double)kurtosis, (double)minimum, (double)maximum, n); - } /// @@ -318,7 +312,6 @@ namespace MathNet.Numerics.Statistics } } SetStatistics((double)mean, (double)variance, (double)skewness, (double)kurtosis, (double)minimum, (double)maximum, n); - } /// @@ -335,6 +328,14 @@ namespace MathNet.Numerics.Statistics { Mean = mean; Count = n; + + Minimum = double.NaN; + Maximum = double.NaN; + Variance = double.NaN; + StandardDeviation = double.NaN; + Skewness = double.NaN; + Kurtosis = double.NaN; + if (n > 0) { Minimum = minimum; diff --git a/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs b/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs index b99e2eb3..96b5331e 100644 --- a/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs +++ b/src/UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs @@ -95,7 +95,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase("lew", 12, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] [TestCase("mavro", 11, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] [TestCase("michelso", 11, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] - [TestCase("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] + [TestCase("numacc1", 15, 0, double.NaN, 10000002, 10000001, 10000003, 3)] [TestCase("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] [TestCase("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] [TestCase("numacc4", 7, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] @@ -128,7 +128,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase("lew", -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] [TestCase("mavro", 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] [TestCase("michelso", -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] - [TestCase("numacc1", 0, 0, 10000002, 10000001, 10000003, 3)] + [TestCase("numacc1", 0, double.NaN, 10000002, 10000001, 10000003, 3)] [TestCase("numacc2", 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] [TestCase("numacc3", 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] [TestCase("numacc4", 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] @@ -160,7 +160,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase("lew", 14, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] [TestCase("mavro", 11, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] [TestCase("michelso", 11, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] - [TestCase("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] + [TestCase("numacc1", 15, 0, double.NaN, 10000002, 10000001, 10000003, 3)] [TestCase("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] [TestCase("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] [TestCase("numacc4", 7, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] @@ -192,7 +192,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase("lew", 14, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] [TestCase("mavro", 11, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] [TestCase("michelso", 11, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] - [TestCase("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] + [TestCase("numacc1", 15, 0, double.NaN, 10000002, 10000001, 10000003, 3)] [TestCase("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] [TestCase("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] [TestCase("numacc4", 7, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] @@ -223,7 +223,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase("lew", -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] [TestCase("mavro", 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] [TestCase("michelso", -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] - [TestCase("numacc1", 0, 0, 10000002, 10000001, 10000003, 3)] + [TestCase("numacc1", 0, double.NaN, 10000002, 10000001, 10000003, 3)] [TestCase("numacc2", 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] [TestCase("numacc3", 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] [TestCase("numacc4", 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] @@ -255,7 +255,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests [TestCase("lew", 14, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] [TestCase("mavro", 11, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] [TestCase("michelso", 11, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] - [TestCase("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] + [TestCase("numacc1", 15, 0, double.NaN, 10000002, 10000001, 10000003, 3)] [TestCase("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] [TestCase("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] [TestCase("numacc4", 7, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] @@ -271,6 +271,38 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests Assert.AreEqual(stats.Maximum, max); Assert.AreEqual(stats.Count, count); } + + [Test] + public void ShortSequences() + { + var stats0 = new DescriptiveStatistics(new double[0]); + Assert.That(stats0.Skewness, Is.NaN); + Assert.That(stats0.Kurtosis, Is.NaN); + + var stats1 = new DescriptiveStatistics(new[] { 1.0 }); + Assert.That(stats1.Skewness, Is.NaN); + Assert.That(stats1.Kurtosis, Is.NaN); + + var stats2 = new DescriptiveStatistics(new[] { 1.0, 2.0 }); + Assert.That(stats2.Skewness, Is.NaN); + Assert.That(stats2.Kurtosis, Is.NaN); + + var stats3 = new DescriptiveStatistics(new[] { 1.0, 2.0, -3.0 }); + Assert.That(stats3.Skewness, Is.Not.NaN); + Assert.That(stats3.Kurtosis, Is.NaN); + + var stats4 = new DescriptiveStatistics(new[] { 1.0, 2.0, -3.0, -4.0 }); + Assert.That(stats4.Skewness, Is.Not.NaN); + Assert.That(stats4.Kurtosis, Is.Not.NaN); + } + + [Test] + public void ZeroVarianceSequence() + { + var stats = new DescriptiveStatistics(new[] { 2.0, 2.0, 2.0, 2.0 }); + Assert.That(stats.Skewness, Is.NaN); + Assert.That(stats.Kurtosis, Is.NaN); + } } #endif }