diff --git a/src/Numerics/Statistics/ArrayStatistics.cs b/src/Numerics/Statistics/ArrayStatistics.cs
index ccb5afb4..6e41011d 100644
--- a/src/Numerics/Statistics/ArrayStatistics.cs
+++ b/src/Numerics/Statistics/ArrayStatistics.cs
@@ -120,6 +120,17 @@ namespace MathNet.Numerics.Statistics
return variance/(data.Length - 1);
}
+ ///
+ /// Estimates the unbiased population or sample standard deviation from the unsorted data array.
+ /// On a dataset of size N will use an N-1 normalizer
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample array, no sorting is assumed.
+ public static double StandardDeviation(double[] data)
+ {
+ return Math.Sqrt(Variance(data));
+ }
+
///
/// Estimates the biased population variance from the unsorted data array.
/// On a dataset of size N will use an N normalizer
@@ -141,5 +152,16 @@ namespace MathNet.Numerics.Statistics
}
return variance/data.Length;
}
+
+ ///
+ /// Estimates the biased population standard deviation from the unsorted data array.
+ /// On a dataset of size N will use an N normalizer
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample array, no sorting is assumed.
+ public static double PopulationStandardDeviation(double[] data)
+ {
+ return Math.Sqrt(PopulationVariance(data));
+ }
}
}
\ No newline at end of file
diff --git a/src/Numerics/Statistics/Statistics.cs b/src/Numerics/Statistics/Statistics.cs
index 1c345882..2917ab67 100644
--- a/src/Numerics/Statistics/Statistics.cs
+++ b/src/Numerics/Statistics/Statistics.cs
@@ -166,12 +166,10 @@ namespace MathNet.Numerics.Statistics
/// The standard deviation of the sample.
public static double StandardDeviation(this IEnumerable data)
{
- if (data == null)
- {
- throw new ArgumentNullException("data");
- }
-
- return Math.Sqrt(Variance(data));
+ var array = data as double[];
+ return array != null
+ ? ArrayStatistics.StandardDeviation(array)
+ : StreamingStatistics.StandardDeviation(data);
}
///
@@ -181,12 +179,8 @@ namespace MathNet.Numerics.Statistics
/// The standard deviation of the sample.
public static double StandardDeviation(this IEnumerable data)
{
- if (data == null)
- {
- throw new ArgumentNullException("data");
- }
-
- return Math.Sqrt(Variance(data));
+ if (data == null) throw new ArgumentNullException("data");
+ return StreamingStatistics.StandardDeviation(data.Where(d => d.HasValue).Select(d => d.Value));
}
///
@@ -196,12 +190,10 @@ namespace MathNet.Numerics.Statistics
/// The standard deviation of the sample.
public static double PopulationStandardDeviation(this IEnumerable data)
{
- if (data == null)
- {
- throw new ArgumentNullException("data");
- }
-
- return Math.Sqrt(PopulationVariance(data));
+ var array = data as double[];
+ return array != null
+ ? ArrayStatistics.PopulationStandardDeviation(array)
+ : StreamingStatistics.PopulationStandardDeviation(data);
}
///
@@ -211,12 +203,8 @@ namespace MathNet.Numerics.Statistics
/// The standard deviation of the sample.
public static double PopulationStandardDeviation(this IEnumerable data)
{
- if (data == null)
- {
- throw new ArgumentNullException("data");
- }
-
- return Math.Sqrt(PopulationVariance(data));
+ if (data == null) throw new ArgumentNullException("data");
+ return StreamingStatistics.PopulationStandardDeviation(data.Where(d => d.HasValue).Select(d => d.Value));
}
///
diff --git a/src/Numerics/Statistics/StreamingStatistics.cs b/src/Numerics/Statistics/StreamingStatistics.cs
index 86146c25..6a60022f 100644
--- a/src/Numerics/Statistics/StreamingStatistics.cs
+++ b/src/Numerics/Statistics/StreamingStatistics.cs
@@ -132,6 +132,17 @@ namespace MathNet.Numerics.Statistics
return j > 1 ? variance/(j - 1) : double.NaN;
}
+ ///
+ /// Estimates the unbiased population or sample standard deviation from the enumerable, in a single pass without memoization.
+ /// On a dataset of size N will use an N-1 normalizer
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample stream, no sorting is assumed.
+ public static double StandardDeviation(IEnumerable stream)
+ {
+ return Math.Sqrt(Variance(stream));
+ }
+
///
/// Estimates the biased population variance from the enumerable, in a single pass without memoization.
/// On a dataset of size N will use an N normalizer
@@ -164,5 +175,16 @@ namespace MathNet.Numerics.Statistics
}
return variance/j;
}
+
+ ///
+ /// Estimates the biased population standard deviation from the enumerable, in a single pass without memoization.
+ /// On a dataset of size N will use an N normalizer
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample stream, no sorting is assumed.
+ public static double PopulationStandardDeviation(IEnumerable stream)
+ {
+ return Math.Sqrt(PopulationVariance(stream));
+ }
}
}
diff --git a/src/UnitTests/StatisticsTests/StatisticsTests.cs b/src/UnitTests/StatisticsTests/StatisticsTests.cs
index 7b4e31ef..fe7cfcf7 100644
--- a/src/UnitTests/StatisticsTests/StatisticsTests.cs
+++ b/src/UnitTests/StatisticsTests/StatisticsTests.cs
@@ -84,13 +84,17 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
Assert.Throws(() => ArrayStatistics.Maximum(data));
Assert.Throws(() => ArrayStatistics.Mean(data));
Assert.Throws(() => ArrayStatistics.Variance(data));
+ Assert.Throws(() => ArrayStatistics.StandardDeviation(data));
Assert.Throws(() => ArrayStatistics.PopulationVariance(data));
+ Assert.Throws(() => ArrayStatistics.PopulationStandardDeviation(data));
Assert.Throws(() => StreamingStatistics.Minimum(data));
Assert.Throws(() => StreamingStatistics.Maximum(data));
Assert.Throws(() => StreamingStatistics.Mean(data));
Assert.Throws(() => StreamingStatistics.Variance(data));
+ Assert.Throws(() => StreamingStatistics.StandardDeviation(data));
Assert.Throws(() => StreamingStatistics.PopulationVariance(data));
+ Assert.Throws(() => StreamingStatistics.PopulationStandardDeviation(data));
}
[Test]
@@ -122,13 +126,17 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
Assert.DoesNotThrow(() => ArrayStatistics.Maximum(data));
Assert.DoesNotThrow(() => ArrayStatistics.Mean(data));
Assert.DoesNotThrow(() => ArrayStatistics.Variance(data));
+ Assert.DoesNotThrow(() => ArrayStatistics.StandardDeviation(data));
Assert.DoesNotThrow(() => ArrayStatistics.PopulationVariance(data));
+ Assert.DoesNotThrow(() => ArrayStatistics.PopulationStandardDeviation(data));
Assert.DoesNotThrow(() => StreamingStatistics.Minimum(data));
Assert.DoesNotThrow(() => StreamingStatistics.Maximum(data));
Assert.DoesNotThrow(() => StreamingStatistics.Mean(data));
Assert.DoesNotThrow(() => StreamingStatistics.Variance(data));
+ Assert.DoesNotThrow(() => StreamingStatistics.StandardDeviation(data));
Assert.DoesNotThrow(() => StreamingStatistics.PopulationVariance(data));
+ Assert.DoesNotThrow(() => StreamingStatistics.PopulationStandardDeviation(data));
}
[TestCase("lottery")]
@@ -173,6 +181,8 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
{
var data = _data[dataSet];
AssertHelpers.AlmostEqual(data.StandardDeviation, Statistics.StandardDeviation(data.Data), digits);
+ AssertHelpers.AlmostEqual(data.StandardDeviation, ArrayStatistics.StandardDeviation(data.Data), digits);
+ AssertHelpers.AlmostEqual(data.StandardDeviation, StreamingStatistics.StandardDeviation(data.Data), digits);
}
[TestCase("lottery", 15)]
@@ -240,9 +250,11 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
AssertHelpers.AlmostEqual(1e+9, ArrayStatistics.Mean(gaussian.Samples().Take(10000).ToArray()), 11);
AssertHelpers.AlmostEqual(4d, ArrayStatistics.Variance(gaussian.Samples().Take(10000).ToArray()), 1);
+ AssertHelpers.AlmostEqual(2d, ArrayStatistics.StandardDeviation(gaussian.Samples().Take(10000).ToArray()), 2);
AssertHelpers.AlmostEqual(1e+9, StreamingStatistics.Mean(gaussian.Samples().Take(10000)), 11);
AssertHelpers.AlmostEqual(4d, StreamingStatistics.Variance(gaussian.Samples().Take(10000)), 1);
+ AssertHelpers.AlmostEqual(2d, StreamingStatistics.StandardDeviation(gaussian.Samples().Take(10000)), 2);
}
[Test]