Browse Source

Statistics: drop redundant explicit null checks

optimization-1
Christoph Ruegg 13 years ago
parent
commit
4e031e7a91
  1. 17
      src/Numerics/Statistics/ArrayStatistics.cs
  2. 7
      src/Numerics/Statistics/SortedArrayStatistics.cs
  3. 39
      src/Numerics/Statistics/Statistics.cs
  4. 30
      src/Numerics/Statistics/StreamingStatistics.cs
  5. 97
      src/UnitTests/StatisticsTests/StatisticsTests.cs

17
src/Numerics/Statistics/ArrayStatistics.cs

@ -52,7 +52,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">Sample array, no sorting is assumed.</param>
public static double Minimum(double[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length == 0) return double.NaN;
var min = double.PositiveInfinity;
@ -73,7 +72,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">Sample array, no sorting is assumed.</param>
public static double Maximum(double[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length == 0) return double.NaN;
var max = double.NegativeInfinity;
@ -94,7 +92,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">Sample array, no sorting is assumed.</param>
public static double Mean(double[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length == 0) return double.NaN;
double mean = 0;
@ -114,7 +111,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples">Sample array, no sorting is assumed.</param>
public static double Variance(double[] samples)
{
if (samples == null) throw new ArgumentNullException("samples");
if (samples.Length <= 1) return double.NaN;
double variance = 0;
@ -136,7 +132,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="population">Sample array, no sorting is assumed.</param>
public static double PopulationVariance(double[] population)
{
if (population == null) throw new ArgumentNullException("population");
if (population.Length == 0) return double.NaN;
double variance = 0;
@ -180,7 +175,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples">Sample array, no sorting is assumed.</param>
public static Tuple<double, double> MeanVariance(double[] samples)
{
if (samples == null) throw new ArgumentNullException("samples");
return new Tuple<double, double>(Mean(samples), Variance(samples));
}
@ -193,14 +187,11 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples2">Second sample array.</param>
public static double Covariance(double[] samples1, double[] samples2)
{
if (samples1 == null) throw new ArgumentNullException("samples1");
if (samples2 == null) throw new ArgumentNullException("samples2");
if (samples1.Length != samples2.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength);
if (samples1.Length <= 1) return double.NaN;
var mean1 = Mean(samples1);
var mean2 = Mean(samples2);
var covariance = 0.0;
for (int i = 0; i < samples1.Length; i++)
{
@ -218,14 +209,11 @@ namespace MathNet.Numerics.Statistics
/// <param name="population2">Second population array.</param>
public static double PopulationCovariance(double[] population1, double[] population2)
{
if (population1 == null) throw new ArgumentNullException("population1");
if (population2 == null) throw new ArgumentNullException("population2");
if (population1.Length != population2.Length) throw new ArgumentException(Resources.ArgumentVectorsSameLength);
if (population1.Length == 0) return double.NaN;
var mean1 = Mean(population1);
var mean2 = Mean(population2);
var covariance = 0.0;
for (int i = 0; i < population1.Length; i++)
{
@ -242,7 +230,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="order">One-based order of the statistic, must be between 1 and N (inclusive).</param>
public static double OrderStatisticInplace(double[] data, int order)
{
if (data == null) throw new ArgumentNullException("data");
if (order < 1 || order > data.Length) return double.NaN;
if (order == 1) return Minimum(data);
@ -316,7 +303,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">Sample array, no sorting is assumed. Will be reordered.</param>
public static double[] FiveNumberSummaryInplace(double[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length == 0) return new[] { double.NaN, double.NaN, double.NaN, double.NaN, double.NaN };
// TODO: Benchmark: is this still faster than sorting the array then using SortedArrayStatistics instead?
@ -339,7 +325,6 @@ namespace MathNet.Numerics.Statistics
/// </remarks>
public static double QuantileInplace(double[] data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN;
double h = (data.Length + 1d/3d)*tau + 1d/3d;
@ -374,7 +359,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="d">d-parameter</param>
public static double QuantileCustomInplace(double[] data, double tau, double a, double b, double c, double d)
{
if (data == null) throw new ArgumentNullException("data");
if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN;
var x = a + (data.Length + b) * tau - 1;
@ -407,7 +391,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
public static double QuantileCustomInplace(double[] data, double tau, QuantileDefinition definition)
{
if (data == null) throw new ArgumentNullException("data");
if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN;
if (tau == 0d || data.Length == 1) return Minimum(data);
if (tau == 1d) return Maximum(data);

7
src/Numerics/Statistics/SortedArrayStatistics.cs

@ -46,7 +46,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">Sample array, must be sorted ascendingly.</param>
public static double Minimum(double[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length == 0) return double.NaN;
return data[0];
@ -58,7 +57,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">Sample array, must be sorted ascendingly.</param>
public static double Maximum(double[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length == 0) return double.NaN;
return data[data.Length - 1];
@ -71,7 +69,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="order">One-based order of the statistic, must be between 1 and N (inclusive).</param>
public static double OrderStatistic(double[] data, int order)
{
if (data == null) throw new ArgumentNullException("data");
if (order < 1 || order > data.Length) return double.NaN;
return data[order - 1];
@ -136,7 +133,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">Sample array, must be sorted ascendingly.</param>
public static double[] FiveNumberSummary(double[] data)
{
if (data == null) throw new ArgumentNullException("data");
if (data.Length == 0) return new[] {double.NaN, double.NaN, double.NaN, double.NaN, double.NaN};
return new[] {data[0], Quantile(data, 0.25), Quantile(data, 0.50), Quantile(data, 0.75), data[data.Length - 1]};
}
@ -156,7 +152,6 @@ namespace MathNet.Numerics.Statistics
/// </remarks>
public static double Quantile(double[] data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN;
if (tau == 0d || data.Length == 1) return data[0];
if (tau == 1d) return data[data.Length - 1];
@ -182,7 +177,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="d">d-parameter</param>
public static double QuantileCustom(double[] data, double tau, double a, double b, double c, double d)
{
if (data == null) throw new ArgumentNullException("data");
if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN;
var x = a + (data.Length + b)*tau - 1;
@ -214,7 +208,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
public static double QuantileCustom(double[] data, double tau, QuantileDefinition definition)
{
if (data == null) throw new ArgumentNullException("data");
if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN;
if (tau == 0d || data.Length == 1) return data[0];
if (tau == 1d) return data[data.Length - 1];

39
src/Numerics/Statistics/Statistics.cs

@ -61,7 +61,6 @@ namespace MathNet.Numerics.Statistics
/// <returns>The minimum value in the sample data.</returns>
public static double Minimum(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
return StreamingStatistics.Minimum(data.Where(d => d.HasValue).Select(d => d.Value));
}
@ -88,7 +87,6 @@ namespace MathNet.Numerics.Statistics
/// <returns>The maximum value in the sample data.</returns>
public static double Maximum(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
return StreamingStatistics.Maximum(data.Where(d => d.HasValue).Select(d => d.Value));
}
@ -115,7 +113,6 @@ namespace MathNet.Numerics.Statistics
/// <returns>The mean of the sample.</returns>
public static double Mean(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
return StreamingStatistics.Mean(data.Where(d => d.HasValue).Select(d => d.Value));
}
@ -142,7 +139,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples">A subset of samples, sampled from the full population.</param>
public static double Variance(this IEnumerable<double?> samples)
{
if (samples == null) throw new ArgumentNullException("samples");
return StreamingStatistics.Variance(samples.Where(d => d.HasValue).Select(d => d.Value));
}
@ -169,7 +165,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="population">The full population data.</param>
public static double PopulationVariance(this IEnumerable<double?> population)
{
if (population == null) throw new ArgumentNullException("population");
return StreamingStatistics.PopulationVariance(population.Where(d => d.HasValue).Select(d => d.Value));
}
@ -196,7 +191,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples">A subset of samples, sampled from the full population.</param>
public static double StandardDeviation(this IEnumerable<double?> samples)
{
if (samples == null) throw new ArgumentNullException("samples");
return StreamingStatistics.StandardDeviation(samples.Where(d => d.HasValue).Select(d => d.Value));
}
@ -223,7 +217,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="population">The full population data.</param>
public static double PopulationStandardDeviation(this IEnumerable<double?> population)
{
if (population == null) throw new ArgumentNullException("population");
return StreamingStatistics.PopulationStandardDeviation(population.Where(d => d.HasValue).Select(d => d.Value));
}
@ -268,8 +261,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples2">A subset of samples, sampled from the full population.</param>
public static double Covariance(this IEnumerable<double?> samples1, IEnumerable<double?> samples2)
{
if (samples1 == null) throw new ArgumentNullException("samples1");
if (samples2 == null) throw new ArgumentNullException("samples2");
return StreamingStatistics.Covariance(samples1.Where(d => d.HasValue).Select(d => d.Value), samples2.Where(d => d.HasValue).Select(d => d.Value));
}
@ -299,8 +290,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="population2">The full population data.</param>
public static double PopulationCovariance(this IEnumerable<double?> population1, IEnumerable<double?> population2)
{
if (population1 == null) throw new ArgumentNullException("population1");
if (population2 == null) throw new ArgumentNullException("population2");
return StreamingStatistics.PopulationCovariance(population1.Where(d => d.HasValue).Select(d => d.Value), population2.Where(d => d.HasValue).Select(d => d.Value));
}
@ -310,7 +299,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double Median(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.MedianInplace(array);
}
@ -321,7 +309,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double Median(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.MedianInplace(array);
}
@ -336,7 +323,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double Quantile(this IEnumerable<double> data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.QuantileInplace(array, tau);
}
@ -351,7 +337,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double Quantile(this IEnumerable<double?> data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.QuantileInplace(array, tau);
}
@ -365,7 +350,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static Func<double,double> QuantileFunc(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.Quantile(array, tau);
@ -380,7 +364,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> QuantileFunc(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.Quantile(array, tau);
@ -393,7 +376,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double InverseCDF(this IEnumerable<double> data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF);
}
@ -405,7 +387,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double InverseCDF(this IEnumerable<double?> data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF);
}
@ -416,7 +397,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> InverseCDFFunc(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF);
@ -428,7 +408,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> InverseCDFFunc(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF);
@ -445,7 +424,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
public static double QuantileCustom(this IEnumerable<double> data, double tau, QuantileDefinition definition)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.QuantileCustomInplace(array, tau, definition);
}
@ -461,7 +439,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
public static double QuantileCustom(this IEnumerable<double?> data, double tau, QuantileDefinition definition)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.QuantileCustomInplace(array, tau, definition);
}
@ -476,7 +453,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
public static Func<double, double> QuantileCustomFunc(this IEnumerable<double> data, QuantileDefinition definition)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition);
@ -492,7 +468,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
public static Func<double, double> QuantileCustomFunc(this IEnumerable<double?> data, QuantileDefinition definition)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition);
@ -507,7 +482,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="p">Percentile selector, between 0 and 100 (inclusive).</param>
public static double Percentile(this IEnumerable<double> data, int p)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.PercentileInplace(array, p);
}
@ -521,7 +495,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="p">Percentile selector, between 0 and 100 (inclusive).</param>
public static double Percentile(this IEnumerable<double?> data, int p)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.PercentileInplace(array, p);
}
@ -534,7 +507,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static Func<int, double> PercentileFunc(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
Array.Sort(array);
return p => SortedArrayStatistics.Percentile(array, p);
@ -548,7 +520,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static Func<int, double> PercentileFunc(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
Array.Sort(array);
return p => SortedArrayStatistics.Percentile(array, p);
@ -561,7 +532,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double LowerQuartile(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.LowerQuartileInplace(array);
}
@ -573,7 +543,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double LowerQuartile(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.LowerQuartileInplace(array);
}
@ -585,7 +554,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double UpperQuartile(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.UpperQuartileInplace(array);
}
@ -597,7 +565,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double UpperQuartile(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.UpperQuartileInplace(array);
}
@ -609,7 +576,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double InterquartileRange(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.InterquartileRangeInplace(array);
}
@ -621,7 +587,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double InterquartileRange(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.InterquartileRangeInplace(array);
}
@ -633,7 +598,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double[] FiveNumberSummary(this IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.FiveNumberSummaryInplace(array);
}
@ -645,7 +609,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static double[] FiveNumberSummary(this IEnumerable<double?> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.FiveNumberSummaryInplace(array);
}
@ -657,7 +620,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="order">One-based order of the statistic, must be between 1 and N (inclusive).</param>
public static double OrderStatistic(IEnumerable<double> data, int order)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
return ArrayStatistics.OrderStatisticInplace(array, order);
}
@ -668,7 +630,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="data">The data sample sequence.</param>
public static Func<int, double> OrderStatisticFunc(IEnumerable<double> data)
{
if (data == null) throw new ArgumentNullException("data");
var array = data.ToArray();
Array.Sort(array);
return order => SortedArrayStatistics.OrderStatistic(array, order);

30
src/Numerics/Statistics/StreamingStatistics.cs

@ -50,8 +50,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="stream">Sample stream, no sorting is assumed.</param>
public static double Minimum(IEnumerable<double> stream)
{
if (stream == null) throw new ArgumentNullException("stream");
var min = double.PositiveInfinity;
bool any = false;
foreach (var d in stream)
@ -72,8 +70,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="stream">Sample stream, no sorting is assumed.</param>
public static double Maximum(IEnumerable<double> stream)
{
if (stream == null) throw new ArgumentNullException("stream");
var max = double.NegativeInfinity;
bool any = false;
foreach (var d in stream)
@ -94,8 +90,6 @@ namespace MathNet.Numerics.Statistics
/// <param name="stream">Sample stream, no sorting is assumed.</param>
public static double Mean(IEnumerable<double> stream)
{
if (stream == null) throw new ArgumentNullException("stream");
double mean = 0;
ulong m = 0;
bool any = false;
@ -115,12 +109,9 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples">Sample stream, no sorting is assumed.</param>
public static double Variance(IEnumerable<double> samples)
{
if (samples == null) throw new ArgumentNullException("samples");
double variance = 0;
double sum = 0;
ulong count = 0;
using (var iterator = samples.GetEnumerator())
{
if (iterator.MoveNext())
@ -138,7 +129,6 @@ namespace MathNet.Numerics.Statistics
variance += (diff*diff)/(count*(count - 1));
}
}
return count > 1 ? variance/(count - 1) : double.NaN;
}
@ -150,12 +140,9 @@ namespace MathNet.Numerics.Statistics
/// <param name="population">Sample stream, no sorting is assumed.</param>
public static double PopulationVariance(IEnumerable<double> population)
{
if (population == null) throw new ArgumentNullException("population");
double variance = 0;
double sum = 0;
ulong count = 0;
using (var iterator = population.GetEnumerator())
{
if (iterator.MoveNext())
@ -173,7 +160,6 @@ namespace MathNet.Numerics.Statistics
variance += (diff*diff)/(count*(count - 1));
}
}
return variance/count;
}
@ -207,13 +193,10 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples">Sample stream, no sorting is assumed.</param>
public static Tuple<double, double> MeanVariance(IEnumerable<double> samples)
{
if (samples == null) throw new ArgumentNullException("samples");
double mean = 0;
double variance = 0;
double sum = 0;
ulong count = 0;
using (var iterator = samples.GetEnumerator())
{
if (iterator.MoveNext())
@ -232,7 +215,6 @@ namespace MathNet.Numerics.Statistics
mean += (xi - mean) / count;
}
}
return new Tuple<double, double>(
count > 0 ? mean : double.NaN,
count > 1 ? variance/(count - 1) : double.NaN);
@ -247,16 +229,11 @@ namespace MathNet.Numerics.Statistics
/// <param name="samples2">Second sample stream.</param>
public static double Covariance(IEnumerable<double> samples1, IEnumerable<double> samples2)
{
if (samples1 == null) throw new ArgumentNullException("samples1");
if (samples2 == null) throw new ArgumentNullException("samples2");
// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
var n = 0;
var mean1 = 0.0;
var mean2 = 0.0;
var comoment = 0.0;
using (var s1 = samples1.GetEnumerator())
using (var s2 = samples2.GetEnumerator())
{
@ -279,7 +256,6 @@ namespace MathNet.Numerics.Statistics
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
}
return n > 1 ? comoment/(n - 1) : double.NaN;
}
@ -292,16 +268,11 @@ namespace MathNet.Numerics.Statistics
/// <param name="population2">Second population stream.</param>
public static double PopulationCovariance(IEnumerable<double> population1, IEnumerable<double> population2)
{
if (population1 == null) throw new ArgumentNullException("population1");
if (population2 == null) throw new ArgumentNullException("population2");
// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
var n = 0;
var mean1 = 0.0;
var mean2 = 0.0;
var comoment = 0.0;
using (var p1 = population1.GetEnumerator())
using (var p2 = population2.GetEnumerator())
{
@ -324,7 +295,6 @@ namespace MathNet.Numerics.Statistics
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
}
return comoment/n;
}
}

97
src/UnitTests/StatisticsTests/StatisticsTests.cs

@ -63,53 +63,56 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
{
double[] data = null;
Assert.Throws<ArgumentNullException>(() => Statistics.Minimum(data));
Assert.Throws<ArgumentNullException>(() => Statistics.Maximum(data));
Assert.Throws<ArgumentNullException>(() => Statistics.Mean(data));
Assert.Throws<ArgumentNullException>(() => Statistics.Median(data));
Assert.Throws<ArgumentNullException>(() => Statistics.Quantile(data, 0.3));
Assert.Throws<ArgumentNullException>(() => Statistics.Variance(data));
Assert.Throws<ArgumentNullException>(() => Statistics.StandardDeviation(data));
Assert.Throws<ArgumentNullException>(() => Statistics.PopulationVariance(data));
Assert.Throws<ArgumentNullException>(() => Statistics.PopulationStandardDeviation(data));
Assert.Throws<ArgumentNullException>(() => Statistics.Covariance(data, data));
Assert.Throws<ArgumentNullException>(() => Statistics.PopulationCovariance(data, data));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.Minimum(data));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.Maximum(data));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.OrderStatistic(data, 1));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.Median(data));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.LowerQuartile(data));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.UpperQuartile(data));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.Percentile(data, 30));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.Quantile(data, 0.3));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.QuantileCustom(data, 0.3, 0, 0, 1, 0));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.QuantileCustom(data, 0.3, QuantileDefinition.Nearest));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.InterquartileRange(data));
Assert.Throws<ArgumentNullException>(() => SortedArrayStatistics.FiveNumberSummary(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.Minimum(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.Maximum(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.OrderStatisticInplace(data, 1));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.Mean(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.Variance(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.StandardDeviation(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.PopulationVariance(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.PopulationStandardDeviation(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.Covariance(data, data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.PopulationCovariance(data, data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.MedianInplace(data));
Assert.Throws<ArgumentNullException>(() => ArrayStatistics.QuantileInplace(data, 0.3));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.Minimum(data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.Maximum(data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.Mean(data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.Variance(data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.StandardDeviation(data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.PopulationVariance(data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.PopulationStandardDeviation(data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.Covariance(data, data));
Assert.Throws<ArgumentNullException>(() => StreamingStatistics.PopulationCovariance(data, data));
// ReSharper disable InvokeAsExtensionMethod
Assert.That(() => Statistics.Minimum(data), Throws.Exception);
Assert.That(() => Statistics.Maximum(data), Throws.Exception);
Assert.That(() => Statistics.Mean(data), Throws.Exception);
Assert.That(() => Statistics.Median(data), Throws.Exception);
Assert.That(() => Statistics.Quantile(data, 0.3), Throws.Exception);
Assert.That(() => Statistics.Variance(data), Throws.Exception);
Assert.That(() => Statistics.StandardDeviation(data), Throws.Exception);
Assert.That(() => Statistics.PopulationVariance(data), Throws.Exception);
Assert.That(() => Statistics.PopulationStandardDeviation(data), Throws.Exception);
Assert.That(() => Statistics.Covariance(data, data), Throws.Exception);
Assert.That(() => Statistics.PopulationCovariance(data, data), Throws.Exception);
// ReSharper restore InvokeAsExtensionMethod
Assert.That(() => SortedArrayStatistics.Minimum(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.Minimum(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.Maximum(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.OrderStatistic(data, 1), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.Median(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.LowerQuartile(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.UpperQuartile(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.Percentile(data, 30), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.Quantile(data, 0.3), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.QuantileCustom(data, 0.3, 0, 0, 1, 0), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.QuantileCustom(data, 0.3, QuantileDefinition.Nearest), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.InterquartileRange(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => SortedArrayStatistics.FiveNumberSummary(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.Minimum(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.Maximum(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.OrderStatisticInplace(data, 1), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.Mean(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.Variance(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.StandardDeviation(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.PopulationVariance(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.PopulationStandardDeviation(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.Covariance(data, data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.PopulationCovariance(data, data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.MedianInplace(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.QuantileInplace(data, 0.3), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.Minimum(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.Maximum(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.Mean(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.Variance(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.StandardDeviation(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.PopulationVariance(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.PopulationStandardDeviation(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.Covariance(data, data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.PopulationCovariance(data, data), Throws.Exception.TypeOf<NullReferenceException>());
}
[Test]

Loading…
Cancel
Save