Browse Source
Lowered the accuracy of StdDev computation on the numacc2 test to 13 significant digits.pull/2/head
committed by
Christoph Ruegg
12 changed files with 1397 additions and 3 deletions
@ -0,0 +1,212 @@ |
|||||
|
// <copyright file="DescriptiveStatisticsTests.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 Math.NET
|
||||
|
//
|
||||
|
// Permission is hereby granted, free of charge, to any person
|
||||
|
// obtaining a copy of this software and associated documentation
|
||||
|
// files (the "Software"), to deal in the Software without
|
||||
|
// restriction, including without limitation the rights to use,
|
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
// copies of the Software, and to permit persons to whom the
|
||||
|
// Software is furnished to do so, subject to the following
|
||||
|
// conditions:
|
||||
|
//
|
||||
|
// The above copyright notice and this permission notice shall be
|
||||
|
// included in all copies or substantial portions of the Software.
|
||||
|
//
|
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.Statistics |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using MathNet.Numerics.Statistics; |
||||
|
using MbUnit.Framework; |
||||
|
|
||||
|
[TestFixture] |
||||
|
public class DescriptiveStatisticsTests |
||||
|
{ |
||||
|
private readonly IDictionary<string, StatTestData> mData = new Dictionary<string, StatTestData>(); |
||||
|
|
||||
|
public DescriptiveStatisticsTests() |
||||
|
{ |
||||
|
StatTestData lottery = new StatTestData("./data/NIST/Lottery.dat"); |
||||
|
mData.Add("lottery", lottery); |
||||
|
StatTestData lew = new StatTestData("./data/NIST/Lew.dat"); |
||||
|
mData.Add("lew", lew); |
||||
|
StatTestData mavro = new StatTestData("./data/NIST/Mavro.dat"); |
||||
|
mData.Add("mavro", mavro); |
||||
|
StatTestData michelso = new StatTestData("./data/NIST/Michelso.dat"); |
||||
|
mData.Add("michelso", michelso); |
||||
|
StatTestData numacc1 = new StatTestData("./data/NIST/NumAcc1.dat"); |
||||
|
mData.Add("numacc1", numacc1); |
||||
|
StatTestData numacc2 = new StatTestData("./data/NIST/NumAcc2.dat"); |
||||
|
mData.Add("numacc2", numacc2); |
||||
|
StatTestData numacc3 = new StatTestData("./data/NIST/NumAcc3.dat"); |
||||
|
mData.Add("numacc3", numacc3); |
||||
|
StatTestData numacc4 = new StatTestData("./data/NIST/NumAcc4.dat"); |
||||
|
mData.Add("numacc4", numacc4); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
public void Constructor_ThrowArgumentNullException() |
||||
|
{ |
||||
|
const IEnumerable<double> data = null; |
||||
|
const IEnumerable<double?> nullableData = null; |
||||
|
|
||||
|
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(data)); |
||||
|
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(data, true)); |
||||
|
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(nullableData)); |
||||
|
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(nullableData, true)); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)] |
||||
|
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] |
||||
|
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] |
||||
|
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] |
||||
|
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] |
||||
|
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] |
||||
|
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] |
||||
|
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] |
||||
|
public void IEnumerableDouble(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
DescriptiveStatistics stats = new DescriptiveStatistics(data.Data); |
||||
|
|
||||
|
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15); |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits); |
||||
|
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7); |
||||
|
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7); |
||||
|
AssertHelpers.AlmostEqual(median, stats.Median, 15); |
||||
|
Assert.AreEqual(stats.Minimum, min); |
||||
|
Assert.AreEqual(stats.Maximum, max); |
||||
|
Assert.AreEqual(stats.Count, count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)] |
||||
|
[Row("lew", -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] |
||||
|
[Row("mavro", 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] |
||||
|
[Row("michelso", -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] |
||||
|
[Row("numacc1", 0, 0, 10000002, 10000001, 10000003, 3)] |
||||
|
[Row("numacc2", 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] |
||||
|
[Row("numacc3", 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] |
||||
|
[Row("numacc4", 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] |
||||
|
public void IEnumerableDoubleHighAccuracy(string dataSet, double skewness, double kurtosis, double median, double min, double max, int count) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
DescriptiveStatistics stats = new DescriptiveStatistics(data.Data, true); |
||||
|
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15); |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, 15); |
||||
|
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 9); |
||||
|
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 9); |
||||
|
AssertHelpers.AlmostEqual(median, stats.Median, 15); |
||||
|
Assert.AreEqual(stats.Minimum, min); |
||||
|
Assert.AreEqual(stats.Maximum, max); |
||||
|
Assert.AreEqual(stats.Count, count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)] |
||||
|
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] |
||||
|
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] |
||||
|
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] |
||||
|
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] |
||||
|
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] |
||||
|
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] |
||||
|
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] |
||||
|
public void IEnumerableDoubleLowAccuracy(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
DescriptiveStatistics stats = new DescriptiveStatistics(data.Data, false); |
||||
|
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15); |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits); |
||||
|
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7); |
||||
|
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7); |
||||
|
AssertHelpers.AlmostEqual(median, stats.Median, 15); |
||||
|
Assert.AreEqual(stats.Minimum, min); |
||||
|
Assert.AreEqual(stats.Maximum, max); |
||||
|
Assert.AreEqual(stats.Count, count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)] |
||||
|
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] |
||||
|
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] |
||||
|
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] |
||||
|
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] |
||||
|
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] |
||||
|
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] |
||||
|
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] |
||||
|
public void IEnumerableNullableDouble(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
DescriptiveStatistics stats = new DescriptiveStatistics(data.DataWithNulls); |
||||
|
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15); |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits); |
||||
|
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7); |
||||
|
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7); |
||||
|
AssertHelpers.AlmostEqual(median, stats.Median, 15); |
||||
|
Assert.AreEqual(stats.Minimum, min); |
||||
|
Assert.AreEqual(stats.Maximum, max); |
||||
|
Assert.AreEqual(stats.Count, count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)] |
||||
|
[Row("lew", -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] |
||||
|
[Row("mavro", 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] |
||||
|
[Row("michelso", -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] |
||||
|
[Row("numacc1", 0, 0, 10000002, 10000001, 10000003, 3)] |
||||
|
[Row("numacc2", 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] |
||||
|
[Row("numacc3", 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] |
||||
|
[Row("numacc4", 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] |
||||
|
public void IEnumerableNullableDoubleHighAccuracy(string dataSet, double skewness, double kurtosis, double median, double min, double max, int count) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
DescriptiveStatistics stats = new DescriptiveStatistics(data.DataWithNulls, true); |
||||
|
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15); |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, 15); |
||||
|
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 9); |
||||
|
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 9); |
||||
|
AssertHelpers.AlmostEqual(median, stats.Median, 15); |
||||
|
Assert.AreEqual(stats.Minimum, min); |
||||
|
Assert.AreEqual(stats.Maximum, max); |
||||
|
Assert.AreEqual(stats.Count, count); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)] |
||||
|
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)] |
||||
|
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)] |
||||
|
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)] |
||||
|
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)] |
||||
|
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)] |
||||
|
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)] |
||||
|
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)] |
||||
|
public void IEnumerableNullableDoubleLowAccuracy(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
DescriptiveStatistics stats = new DescriptiveStatistics(data.DataWithNulls, false); |
||||
|
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15); |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits); |
||||
|
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7); |
||||
|
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7); |
||||
|
AssertHelpers.AlmostEqual(median, stats.Median, 15); |
||||
|
Assert.AreEqual(stats.Minimum, min); |
||||
|
Assert.AreEqual(stats.Maximum, max); |
||||
|
Assert.AreEqual(stats.Count, count); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
// <copyright file="StatTestData.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 Math.NET
|
||||
|
//
|
||||
|
// Permission is hereby granted, free of charge, to any person
|
||||
|
// obtaining a copy of this software and associated documentation
|
||||
|
// files (the "Software"), to deal in the Software without
|
||||
|
// restriction, including without limitation the rights to use,
|
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
// copies of the Software, and to permit persons to whom the
|
||||
|
// Software is furnished to do so, subject to the following
|
||||
|
// conditions:
|
||||
|
//
|
||||
|
// The above copyright notice and this permission notice shall be
|
||||
|
// included in all copies or substantial portions of the Software.
|
||||
|
//
|
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.Statistics |
||||
|
{ |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
internal class StatTestData |
||||
|
{ |
||||
|
public readonly double[] Data; |
||||
|
public readonly double?[] DataWithNulls; |
||||
|
|
||||
|
public readonly double Mean; |
||||
|
public readonly double StandardDeviation; |
||||
|
|
||||
|
public StatTestData(string file) |
||||
|
{ |
||||
|
using (StreamReader reader = new StreamReader(file)) |
||||
|
{ |
||||
|
string line = reader.ReadLine().Trim(); |
||||
|
|
||||
|
while (!line.StartsWith("--")) |
||||
|
{ |
||||
|
if (line.StartsWith("Sample Mean")) |
||||
|
{ |
||||
|
Mean = GetValue(line); |
||||
|
} |
||||
|
else if (line.StartsWith("Sample Standard Deviation")) |
||||
|
{ |
||||
|
StandardDeviation = GetValue(line); |
||||
|
} |
||||
|
line = reader.ReadLine().Trim(); |
||||
|
} |
||||
|
|
||||
|
line = reader.ReadLine(); |
||||
|
|
||||
|
IList<double> list = new List<double>(); |
||||
|
while (line != null) |
||||
|
{ |
||||
|
line = line.Trim(); |
||||
|
if (!line.Equals(string.Empty)) |
||||
|
{ |
||||
|
list.Add(double.Parse(line)); |
||||
|
} |
||||
|
line = reader.ReadLine(); |
||||
|
} |
||||
|
|
||||
|
Data = list.ToArray(); |
||||
|
} |
||||
|
|
||||
|
DataWithNulls = new double?[Data.Length + 2]; |
||||
|
for (int i = 0; i < Data.Length; i++) |
||||
|
{ |
||||
|
DataWithNulls[i + 1] = Data[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static double GetValue(string str) |
||||
|
{ |
||||
|
int start = str.IndexOf(":"); |
||||
|
string value = str.Substring(start + 1).Trim(); |
||||
|
if (value.Equals("NaN")) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
return double.Parse(str.Substring(start + 1).Trim()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,138 @@ |
|||||
|
// <copyright file="StatisticsTests.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 Math.NET
|
||||
|
//
|
||||
|
// Permission is hereby granted, free of charge, to any person
|
||||
|
// obtaining a copy of this software and associated documentation
|
||||
|
// files (the "Software"), to deal in the Software without
|
||||
|
// restriction, including without limitation the rights to use,
|
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
// copies of the Software, and to permit persons to whom the
|
||||
|
// Software is furnished to do so, subject to the following
|
||||
|
// conditions:
|
||||
|
//
|
||||
|
// The above copyright notice and this permission notice shall be
|
||||
|
// included in all copies or substantial portions of the Software.
|
||||
|
//
|
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.UnitTests.Statistics |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
using MbUnit.Framework; |
||||
|
using MathNet.Numerics.Statistics; |
||||
|
|
||||
|
[TestFixture] |
||||
|
public class StatisticsTests |
||||
|
{ |
||||
|
private readonly IDictionary<string, StatTestData> mData = new Dictionary<string, StatTestData>(); |
||||
|
public StatisticsTests() |
||||
|
{ |
||||
|
StatTestData lottery = new StatTestData("./data/NIST/Lottery.dat"); |
||||
|
mData.Add("lottery", lottery); |
||||
|
StatTestData lew = new StatTestData("./data/NIST/Lew.dat"); |
||||
|
mData.Add("lew", lew); |
||||
|
StatTestData mavro = new StatTestData("./data/NIST/Mavro.dat"); |
||||
|
mData.Add("mavro", mavro); |
||||
|
StatTestData michelso = new StatTestData("./data/NIST/Michelso.dat"); |
||||
|
mData.Add("michelso", michelso); |
||||
|
StatTestData numacc1 = new StatTestData("./data/NIST/NumAcc1.dat"); |
||||
|
mData.Add("numacc1", numacc1); |
||||
|
StatTestData numacc2 = new StatTestData("./data/NIST/NumAcc2.dat"); |
||||
|
mData.Add("numacc2", numacc2); |
||||
|
StatTestData numacc3 = new StatTestData("./data/NIST/NumAcc3.dat"); |
||||
|
mData.Add("numacc3", numacc3); |
||||
|
StatTestData numacc4 = new StatTestData("./data/NIST/NumAcc4.dat"); |
||||
|
mData.Add("numacc4", numacc4); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery")] |
||||
|
[Row("lew")] |
||||
|
[Row("mavro")] |
||||
|
[Row("michelso")] |
||||
|
[Row("numacc1")] |
||||
|
[Row("numacc2")] |
||||
|
[Row("numacc3")] |
||||
|
[Row("numacc4")] |
||||
|
public void Mean(string dataSet) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
AssertHelpers.AlmostEqual(data.Mean, data.Data.Mean(), 15); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery")] |
||||
|
[Row("lew")] |
||||
|
[Row("mavro")] |
||||
|
[Row("michelso")] |
||||
|
[Row("numacc1")] |
||||
|
[Row("numacc2")] |
||||
|
[Row("numacc3")] |
||||
|
[Row("numacc4")] |
||||
|
public void NullableMean(string dataSet) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
AssertHelpers.AlmostEqual(data.Mean, data.DataWithNulls.Mean(), 15); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedException(typeof(ArgumentNullException))] |
||||
|
public void Mean_ThrowsArgumentNullException() |
||||
|
{ |
||||
|
double[] data = null; |
||||
|
MathNet.Numerics.Statistics.Statistics.Mean(data); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", 15)] |
||||
|
[Row("lew", 15)] |
||||
|
[Row("mavro", 12)] |
||||
|
[Row("michelso", 12)] |
||||
|
[Row("numacc1", 15)] |
||||
|
[Row("numacc2", 14)] |
||||
|
[Row("numacc3", 9)] |
||||
|
[Row("numacc4", 8)] |
||||
|
public void StandardDeviation(string dataSet, int digits) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, data.Data.StandardDeviation(), digits); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[Row("lottery", 15)] |
||||
|
[Row("lew", 15)] |
||||
|
[Row("mavro", 12)] |
||||
|
[Row("michelso", 12)] |
||||
|
[Row("numacc1", 15)] |
||||
|
[Row("numacc2", 14)] |
||||
|
[Row("numacc3", 9)] |
||||
|
[Row("numacc4", 8)] |
||||
|
public void NullableStandardDeviation(string dataSet, int digits) |
||||
|
{ |
||||
|
StatTestData data = mData[dataSet]; |
||||
|
AssertHelpers.AlmostEqual(data.StandardDeviation, data.DataWithNulls.StandardDeviation(), digits); |
||||
|
} |
||||
|
|
||||
|
[Test] |
||||
|
[ExpectedException(typeof(ArgumentNullException))] |
||||
|
public void StandardDeviation_ThrowsArgumentNullException() |
||||
|
{ |
||||
|
double[] data = null; |
||||
|
MathNet.Numerics.Statistics.Statistics.StandardDeviation(data); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,343 @@ |
|||||
|
// <copyright file="DescriptiveStatistics.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 Math.NET
|
||||
|
//
|
||||
|
// Permission is hereby granted, free of charge, to any person
|
||||
|
// obtaining a copy of this software and associated documentation
|
||||
|
// files (the "Software"), to deal in the Software without
|
||||
|
// restriction, including without limitation the rights to use,
|
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
// copies of the Software, and to permit persons to whom the
|
||||
|
// Software is furnished to do so, subject to the following
|
||||
|
// conditions:
|
||||
|
//
|
||||
|
// The above copyright notice and this permission notice shall be
|
||||
|
// included in all copies or substantial portions of the Software.
|
||||
|
//
|
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.Statistics |
||||
|
{ |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 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
|
||||
|
/// in increased accuracy mode.
|
||||
|
/// </summary>
|
||||
|
public class DescriptiveStatistics |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
public DescriptiveStatistics(IEnumerable<double> data) : this(data, false) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
public DescriptiveStatistics(IEnumerable<double?> data) : this(data, false) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
/// <param name="increasedAccuracy">if set to <c>true</c>, increased accuracy mode used.
|
||||
|
/// Increased accuracy mode uses <see cref="decimal"/> types for internal calculations.</param>
|
||||
|
/// <remarks>Don't use increased accuracy for data sets containing large values (in absolute value).
|
||||
|
/// This may cause the calculations to overflow.</remarks>
|
||||
|
public DescriptiveStatistics(IEnumerable<double> data, bool increasedAccuracy) |
||||
|
{ |
||||
|
if (increasedAccuracy) |
||||
|
{ |
||||
|
ComputeHA(data); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Compute(data); |
||||
|
} |
||||
|
|
||||
|
Median = data.Median(); |
||||
|
Maximum = data.Maximum(); |
||||
|
Minimum = data.Minimum(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
/// <param name="increasedAccuracy">if set to <c>true</c>, increased accuracy mode used.
|
||||
|
/// Increased accuracy mode uses <see cref="decimal"/> types for internal calculations.</param>
|
||||
|
/// <remarks>Don't use increased accuracy for data sets containing large values (in absolute value).
|
||||
|
/// This may cause the calculations to overflow.</remarks>
|
||||
|
public DescriptiveStatistics(IEnumerable<double?> data, bool increasedAccuracy) |
||||
|
{ |
||||
|
if (increasedAccuracy) |
||||
|
{ |
||||
|
ComputeHA(data); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Compute(data); |
||||
|
} |
||||
|
|
||||
|
Median = data.Median(); |
||||
|
Maximum = data.Maximum(); |
||||
|
Minimum = data.Minimum(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the size of the sample.
|
||||
|
/// </summary>
|
||||
|
/// <value>The size of the sample.</value>
|
||||
|
public int Count { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the sample mean.
|
||||
|
/// </summary>
|
||||
|
/// <value>The sample mean.</value>
|
||||
|
public double Mean { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the sample variance.
|
||||
|
/// </summary>
|
||||
|
/// <value>The sample variance.</value>
|
||||
|
public double Variance { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the sample standard deviation.
|
||||
|
/// </summary>
|
||||
|
/// <value>The sample standard deviation.</value>
|
||||
|
public double StandardDeviation { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the sample skewness.
|
||||
|
/// </summary>
|
||||
|
/// <value>The sample skewness.</value>
|
||||
|
/// <remarks>Returns zero if <see cref="Count"/> is less than three. </remarks>
|
||||
|
public double Skewness { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the sample median.
|
||||
|
/// </summary>
|
||||
|
/// <value>The sample median.</value>
|
||||
|
public double Median { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the sample kurtosis.
|
||||
|
/// </summary>
|
||||
|
/// <value>The sample kurtosis.</value>
|
||||
|
/// <remarks>Returns zero if <see cref="Count"/> is less than four. </remarks>
|
||||
|
public double Kurtosis { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the maximum sample value.
|
||||
|
/// </summary>
|
||||
|
/// <value>The maximum sample value.</value>
|
||||
|
public double Maximum { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the minimum sample value.
|
||||
|
/// </summary>
|
||||
|
/// <value>The minimum sample value.</value>
|
||||
|
public double Minimum { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes descriptive statistics from a stream of data values.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">A sequence of datapoints.</param>
|
||||
|
private void Compute(IEnumerable<double> data) |
||||
|
{ |
||||
|
Mean = data.Mean(); |
||||
|
double variance = 0; |
||||
|
double correction = 0; |
||||
|
double skewness = 0; |
||||
|
double kurtosis = 0; |
||||
|
int n = 0; |
||||
|
foreach (var xi in data) |
||||
|
{ |
||||
|
double diff = xi - Mean; |
||||
|
correction += diff; |
||||
|
double tmp = diff*diff; |
||||
|
variance += tmp; |
||||
|
tmp *= diff; |
||||
|
skewness += tmp; |
||||
|
tmp *= diff; |
||||
|
kurtosis += tmp; |
||||
|
n++; |
||||
|
} |
||||
|
|
||||
|
Count = n; |
||||
|
Variance = (variance - (correction*correction)/n)/(n - 1); |
||||
|
StandardDeviation = System.Math.Sqrt(Variance); |
||||
|
if (Variance != 0) |
||||
|
{ |
||||
|
if (n > 2) |
||||
|
{ |
||||
|
Skewness = (double) n/((n - 1)*(n - 2))*(skewness/(Variance*StandardDeviation)); |
||||
|
} |
||||
|
|
||||
|
if (n > 3) |
||||
|
{ |
||||
|
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*(kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes descriptive statistics from a stream of nullable data values.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">A sequence of datapoints.</param>
|
||||
|
private void Compute(IEnumerable<double?> data) |
||||
|
{ |
||||
|
Mean = data.Mean(); |
||||
|
double variance = 0; |
||||
|
double correction = 0; |
||||
|
double skewness = 0; |
||||
|
double kurtosis = 0; |
||||
|
int n = 0; |
||||
|
foreach (var xi in data) |
||||
|
{ |
||||
|
if (xi.HasValue) |
||||
|
{ |
||||
|
double diff = xi.Value - Mean; |
||||
|
double tmp = diff*diff; |
||||
|
correction += diff; |
||||
|
variance += tmp; |
||||
|
tmp *= diff; |
||||
|
skewness += tmp; |
||||
|
tmp *= diff; |
||||
|
kurtosis += tmp; |
||||
|
n++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Count = n; |
||||
|
if (n > 0) |
||||
|
{ |
||||
|
Variance = (variance - (correction*correction)/n)/(n - 1); |
||||
|
StandardDeviation = System.Math.Sqrt(Variance); |
||||
|
if (Variance != 0) |
||||
|
{ |
||||
|
if (n > 2) |
||||
|
{ |
||||
|
Skewness = (double) n/((n - 1)*(n - 2))*(skewness/(Variance*StandardDeviation)); |
||||
|
} |
||||
|
|
||||
|
if (n > 3) |
||||
|
{ |
||||
|
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*(kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes descriptive statistics from a stream of data values using high accuracy.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">A sequence of datapoints.</param>
|
||||
|
private void ComputeHA(IEnumerable<double> data) |
||||
|
{ |
||||
|
Mean = data.Mean(); |
||||
|
decimal mean = (decimal) Mean; |
||||
|
decimal variance = 0; |
||||
|
decimal correction = 0; |
||||
|
decimal skewness = 0; |
||||
|
decimal kurtosis = 0; |
||||
|
int n = 0; |
||||
|
foreach (decimal xi in data) |
||||
|
{ |
||||
|
decimal diff = xi - mean; |
||||
|
decimal tmp = diff*diff; |
||||
|
correction += diff; |
||||
|
variance += tmp; |
||||
|
tmp *= diff; |
||||
|
skewness += tmp; |
||||
|
tmp *= diff; |
||||
|
kurtosis += tmp; |
||||
|
n++; |
||||
|
} |
||||
|
|
||||
|
Count = n; |
||||
|
Variance = (double) (variance - (correction*correction)/n)/(n - 1); |
||||
|
StandardDeviation = System.Math.Sqrt(Variance); |
||||
|
if (Variance != 0) |
||||
|
{ |
||||
|
if (n > 2) |
||||
|
{ |
||||
|
Skewness = (double) n/((n - 1)*(n - 2))*((double) skewness/(Variance*StandardDeviation)); |
||||
|
} |
||||
|
|
||||
|
if (n > 3) |
||||
|
{ |
||||
|
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*((double) kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes descriptive statistics from a stream of nullable data values using high accuracy.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">A sequence of datapoints.</param>
|
||||
|
private void ComputeHA(IEnumerable<double?> data) |
||||
|
{ |
||||
|
Mean = data.Mean(); |
||||
|
decimal mean = (decimal) Mean; |
||||
|
decimal variance = 0; |
||||
|
decimal correction = 0; |
||||
|
decimal skewness = 0; |
||||
|
decimal kurtosis = 0; |
||||
|
int n = 0; |
||||
|
foreach (decimal? xi in data) |
||||
|
{ |
||||
|
if (xi.HasValue) |
||||
|
{ |
||||
|
decimal diff = xi.Value - mean; |
||||
|
decimal tmp = diff*diff; |
||||
|
correction += diff; |
||||
|
variance += tmp; |
||||
|
tmp *= diff; |
||||
|
skewness += tmp; |
||||
|
tmp *= diff; |
||||
|
kurtosis += tmp; |
||||
|
n++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Count = n; |
||||
|
if (n > 0) |
||||
|
{ |
||||
|
Variance = (double) (variance - (correction*correction)/n)/(n - 1); |
||||
|
StandardDeviation = System.Math.Sqrt(Variance); |
||||
|
if (Variance != 0) |
||||
|
{ |
||||
|
if (n > 2) |
||||
|
{ |
||||
|
Skewness = (double) n/((n - 1)*(n - 2))*((double) skewness/(Variance*StandardDeviation)); |
||||
|
} |
||||
|
|
||||
|
if (n > 3) |
||||
|
{ |
||||
|
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*((double) kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,570 @@ |
|||||
|
// <copyright file="Statistics.cs" company="Math.NET">
|
||||
|
// Math.NET Numerics, part of the Math.NET Project
|
||||
|
// http://mathnet.opensourcedotnet.info
|
||||
|
//
|
||||
|
// Copyright (c) 2009 Math.NET
|
||||
|
//
|
||||
|
// Permission is hereby granted, free of charge, to any person
|
||||
|
// obtaining a copy of this software and associated documentation
|
||||
|
// files (the "Software"), to deal in the Software without
|
||||
|
// restriction, including without limitation the rights to use,
|
||||
|
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
|
// copies of the Software, and to permit persons to whom the
|
||||
|
// Software is furnished to do so, subject to the following
|
||||
|
// conditions:
|
||||
|
//
|
||||
|
// The above copyright notice and this permission notice shall be
|
||||
|
// included in all copies or substantial portions of the Software.
|
||||
|
//
|
||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
|
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
|
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace MathNet.Numerics.Statistics |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using MathNet.Numerics.Properties; |
||||
|
using MathNet.Numerics.NumberTheory; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods to return basic statistics on set of data.
|
||||
|
/// </summary>
|
||||
|
public static class Statistics |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Calculates the sample mean.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the mean of.</param>
|
||||
|
/// <returns>The mean of the sample.</returns>
|
||||
|
public static double Mean(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double mean = 0; |
||||
|
int m = 0; |
||||
|
foreach (var item in data) |
||||
|
{ |
||||
|
mean += (item - mean)/++m; |
||||
|
} |
||||
|
|
||||
|
return mean; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the sample mean.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the mean of.</param>
|
||||
|
/// <returns>The mean of the sample.</returns>
|
||||
|
public static double Mean(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double mean = 0; |
||||
|
int m = 0; |
||||
|
foreach (var item in data) |
||||
|
{ |
||||
|
if (item.HasValue) |
||||
|
{ |
||||
|
mean += (item.Value - mean)/++m; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return mean; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the unbiased population variance estimator (on a dataset of size N will use an N-1 normalizer).
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the variance of.</param>
|
||||
|
/// <returns>The unbiased population variance of the sample.</returns>
|
||||
|
public static double Variance(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double variance = 0; |
||||
|
double t = 0; |
||||
|
int j = 0; |
||||
|
|
||||
|
IEnumerator<double> iterator = data.GetEnumerator(); |
||||
|
if (iterator.MoveNext()) |
||||
|
{ |
||||
|
j++; |
||||
|
t = iterator.Current; |
||||
|
} |
||||
|
|
||||
|
while (iterator.MoveNext()) |
||||
|
{ |
||||
|
j++; |
||||
|
double xi = iterator.Current; |
||||
|
t += xi; |
||||
|
double diff = j*xi - t; |
||||
|
variance += (diff*diff)/(j*(j - 1)); |
||||
|
} |
||||
|
|
||||
|
return variance/(j - 1); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the unbiased population variance estimator (on a dataset of size N will use an N-1 normalizer) for nullable data.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the variance of.</param>
|
||||
|
/// <returns>The population variance of the sample.</returns>
|
||||
|
public static double Variance(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double variance = 0; |
||||
|
double t = 0; |
||||
|
int j = 0; |
||||
|
|
||||
|
IEnumerator<double?> iterator = data.GetEnumerator(); |
||||
|
|
||||
|
while (true) |
||||
|
{ |
||||
|
bool hasNext = iterator.MoveNext(); |
||||
|
if (!hasNext) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
if (iterator.Current.HasValue) |
||||
|
{ |
||||
|
j++; |
||||
|
t = iterator.Current.Value; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
while (iterator.MoveNext()) |
||||
|
{ |
||||
|
if (iterator.Current.HasValue) |
||||
|
{ |
||||
|
j++; |
||||
|
double xi = iterator.Current.Value; |
||||
|
t += xi; |
||||
|
double diff = j*xi - t; |
||||
|
variance += (diff*diff)/(j*(j - 1)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return variance/(j - 1); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the biased population variance estimator (on a dataset of size N will use an N normalizer).
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the variance of.</param>
|
||||
|
/// <returns>The biased population variance of the sample.</returns>
|
||||
|
public static double PopulationVariance(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double variance = 0; |
||||
|
double t = 0; |
||||
|
int j = 0; |
||||
|
|
||||
|
IEnumerator<double> iterator = data.GetEnumerator(); |
||||
|
if (iterator.MoveNext()) |
||||
|
{ |
||||
|
j++; |
||||
|
t = iterator.Current; |
||||
|
} |
||||
|
|
||||
|
while (iterator.MoveNext()) |
||||
|
{ |
||||
|
j++; |
||||
|
double xi = iterator.Current; |
||||
|
t += xi; |
||||
|
double diff = j * xi - t; |
||||
|
variance += (diff * diff) / (j * (j - 1)); |
||||
|
} |
||||
|
|
||||
|
return variance / j; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Computes the biased population variance estimator (on a dataset of size N will use an N normalizer) for nullable data.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the variance of.</param>
|
||||
|
/// <returns>The population variance of the sample.</returns>
|
||||
|
public static double PopulationVariance(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double variance = 0; |
||||
|
double t = 0; |
||||
|
int j = 0; |
||||
|
|
||||
|
IEnumerator<double?> iterator = data.GetEnumerator(); |
||||
|
|
||||
|
while (true) |
||||
|
{ |
||||
|
bool hasNext = iterator.MoveNext(); |
||||
|
if (!hasNext) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
if (iterator.Current.HasValue) |
||||
|
{ |
||||
|
j++; |
||||
|
t = iterator.Current.Value; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
while (iterator.MoveNext()) |
||||
|
{ |
||||
|
if (iterator.Current.HasValue) |
||||
|
{ |
||||
|
j++; |
||||
|
double xi = iterator.Current.Value; |
||||
|
t += xi; |
||||
|
double diff = j * xi - t; |
||||
|
variance += (diff * diff) / (j * (j - 1)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return variance / j; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the unbiased sample standard deviation (on a dataset of size N will use an N-1 normalizer).
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the standard deviation of.</param>
|
||||
|
/// <returns>The standard deviation of the sample.</returns>
|
||||
|
public static double StandardDeviation(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
return System.Math.Sqrt(Variance(data)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the unbiased sample standard deviation (on a dataset of size N will use an N-1 normalizer).
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the standard deviation of.</param>
|
||||
|
/// <returns>The standard deviation of the sample.</returns>
|
||||
|
public static double StandardDeviation(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
return System.Math.Sqrt(Variance(data)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the biased sample standard deviation (on a dataset of size N will use an N normalizer).
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the standard deviation of.</param>
|
||||
|
/// <returns>The standard deviation of the sample.</returns>
|
||||
|
public static double PopulationStandardDeviation(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
return System.Math.Sqrt(PopulationVariance(data)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the biased sample standard deviation (on a dataset of size N will use an N normalizer).
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the standard deviation of.</param>
|
||||
|
/// <returns>The standard deviation of the sample.</returns>
|
||||
|
public static double PopulationStandardDeviation(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
return System.Math.Sqrt(PopulationVariance(data)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the minimum value in the sample data.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
/// <returns>The minimum value in the sample data.</returns>
|
||||
|
public static double Minimum(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double min = double.MaxValue; |
||||
|
int count = 0; |
||||
|
foreach (double? d in data) |
||||
|
{ |
||||
|
if (d.HasValue) |
||||
|
{ |
||||
|
min = System.Math.Min(min, d.Value); |
||||
|
count++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (count == 0) |
||||
|
{ |
||||
|
throw new ArgumentException(Resources.CollectionEmpty, "data"); |
||||
|
} |
||||
|
|
||||
|
return min; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the maximum value in the sample data.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
/// <returns>The maximum value in the sample data.</returns>
|
||||
|
public static double Maximum(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double max = double.MinValue; |
||||
|
int count = 0; |
||||
|
foreach (double? d in data) |
||||
|
{ |
||||
|
if (d.HasValue) |
||||
|
{ |
||||
|
max = System.Math.Max(max, d.Value); |
||||
|
count++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (count == 0) |
||||
|
{ |
||||
|
throw new ArgumentException(Resources.CollectionEmpty, "data"); |
||||
|
} |
||||
|
|
||||
|
return max; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the minimum value in the sample data.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
/// <returns>The minimum value in the sample data.</returns>
|
||||
|
public static double Minimum(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double min = double.MaxValue; |
||||
|
int count = 0; |
||||
|
foreach (double d in data) |
||||
|
{ |
||||
|
min = System.Math.Min(min, d); |
||||
|
count++; |
||||
|
} |
||||
|
|
||||
|
if (count == 0) |
||||
|
{ |
||||
|
throw new ArgumentException(Resources.CollectionEmpty, "data"); |
||||
|
} |
||||
|
|
||||
|
return min; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the maximum value in the sample data.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
/// <returns>The maximum value in the sample data.</returns>
|
||||
|
public static double Maximum(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
double max = double.MinValue; |
||||
|
int count = 0; |
||||
|
foreach (double d in data) |
||||
|
{ |
||||
|
max = System.Math.Max(max, d); |
||||
|
count++; |
||||
|
} |
||||
|
|
||||
|
if (count == 0) |
||||
|
{ |
||||
|
throw new ArgumentException(Resources.CollectionEmpty, "data"); |
||||
|
} |
||||
|
|
||||
|
return max; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the sample median.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the median of.</param>
|
||||
|
/// <returns>The median of the sample.</returns>
|
||||
|
public static double Median(this IEnumerable<double> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
List<double> dataArray = new List<double>(data); |
||||
|
int index = dataArray.Count/2 + 1; |
||||
|
if (dataArray.Count % 2 == 0) |
||||
|
{ |
||||
|
double lower = OrderSelect(dataArray, 0, dataArray.Count - 1, index - 1); |
||||
|
double upper = OrderSelect(dataArray, 0, dataArray.Count - 1, index); |
||||
|
return (lower + upper) / 2.0; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return OrderSelect(dataArray, 0, dataArray.Count - 1, index); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Calculates the sample median.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The data to calculate the median of.</param>
|
||||
|
/// <returns>The median of the sample.</returns>
|
||||
|
public static double Median(this IEnumerable<double?> data) |
||||
|
{ |
||||
|
if (data == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("data"); |
||||
|
} |
||||
|
|
||||
|
List<double> nonNull = new List<double>(); |
||||
|
foreach (double? value in data) |
||||
|
{ |
||||
|
if (value.HasValue) |
||||
|
{ |
||||
|
nonNull.Add(value.Value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (nonNull.Count == 0) |
||||
|
{ |
||||
|
throw new ArgumentException(Resources.CollectionEmpty, "data"); |
||||
|
} |
||||
|
|
||||
|
return nonNull.Median(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Evaluate the i-order (1..N) statistic of the provided samples.
|
||||
|
/// </summary>
|
||||
|
/// <param name="data">The sample data.</param>
|
||||
|
/// <returns>The i'th order statistic in the sample data.</returns>
|
||||
|
public static double OrderStatistic(IEnumerable<double> samples, int order) |
||||
|
{ |
||||
|
if (order == 1) |
||||
|
{ |
||||
|
// Can be done in linear time by Min()
|
||||
|
return Minimum(samples); |
||||
|
} |
||||
|
|
||||
|
List<double> list = new List<double>(samples); |
||||
|
if (order < 1 || order > list.Count) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException("order", Resources.ArgumentInIntervalXYInclusive); |
||||
|
} |
||||
|
|
||||
|
if (order == list.Count) |
||||
|
{ |
||||
|
// Can be done in linear time by Max()
|
||||
|
return Maximum(list); |
||||
|
} |
||||
|
|
||||
|
return OrderSelect(list, 0, list.Count - 1, order); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Implementation of the order statistics finding algorithm based on the algorithm in
|
||||
|
/// "Introduction to Algorithms", Cormen et al. section 7.1.
|
||||
|
/// </summary>
|
||||
|
/// <param name="samples">The sample data.</param>
|
||||
|
/// <param name="left">The left bound in which to order select.</param>
|
||||
|
/// <param name="right">The right bound in which to order select.</param>
|
||||
|
/// <param name="order">The order we are trying to find.</param>
|
||||
|
/// <returns>The <paramref name="order"/> order statistic.</returns>
|
||||
|
static double OrderSelect(IList<double> samples, int left, int right, int order) |
||||
|
{ |
||||
|
// Order most always be positive.
|
||||
|
System.Diagnostics.Debug.Assert(order > 0); |
||||
|
// Left side must always be positive and smaller than right side.
|
||||
|
System.Diagnostics.Debug.Assert(left >= 0 && left <= right); |
||||
|
// Right side must always be smaller than number of elements in list.
|
||||
|
System.Diagnostics.Debug.Assert(right < samples.Count); |
||||
|
// Make sure there are at least order items in the segment [left, right].
|
||||
|
System.Diagnostics.Debug.Assert(right - left + 1 >= order); |
||||
|
|
||||
|
if (left == right) |
||||
|
{ |
||||
|
return samples[left]; |
||||
|
} |
||||
|
|
||||
|
// The pivot point.
|
||||
|
double pivot = samples[right]; |
||||
|
|
||||
|
// The partioning code.
|
||||
|
int i = left - 1; |
||||
|
for(int j = left; j <= right - 1; j++) |
||||
|
{ |
||||
|
if(samples[j] <= pivot) |
||||
|
{ |
||||
|
i++; |
||||
|
Sorting.Swap(samples, i, j); |
||||
|
} |
||||
|
} |
||||
|
Sorting.Swap(samples, i+1, right); |
||||
|
|
||||
|
// Recursive order finding algorithm.
|
||||
|
if(order == (i-left)+2) |
||||
|
{ |
||||
|
return pivot; |
||||
|
} |
||||
|
else if (order < (i-left)+2) |
||||
|
{ |
||||
|
return OrderSelect(samples, left, i, order); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return OrderSelect(samples, i+2, right, order - i + left - 2); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue