Browse Source

Statistics: geometric and harmonic mean

pull/345/head
Christoph Ruegg 11 years ago
parent
commit
13f7163f96
  1. 42
      src/Numerics/Statistics/ArrayStatistics.cs
  2. 28
      src/Numerics/Statistics/Statistics.cs
  3. 38
      src/Numerics/Statistics/StreamingStatistics.cs
  4. 11
      src/UnitTests/StatisticsTests/StatisticsTests.cs

42
src/Numerics/Statistics/ArrayStatistics.cs

@ -163,6 +163,48 @@ namespace MathNet.Numerics.Statistics
return mean;
}
/// <summary>
/// Evaluates the geometric mean of the unsorted data array.
/// Returns NaN if data is empty or any entry is NaN.
/// </summary>
/// <param name="data">Sample array, no sorting is assumed.</param>
public static double GeometricMean(double[] data)
{
if (data.Length == 0)
{
return double.NaN;
}
double sum = 0;
for (int i = 0; i < data.Length; i++)
{
sum += Math.Log(data[i]);
}
return Math.Exp(sum/data.Length);
}
/// <summary>
/// Evaluates the harmonic mean of the unsorted data array.
/// Returns NaN if data is empty or any entry is NaN.
/// </summary>
/// <param name="data">Sample array, no sorting is assumed.</param>
public static double HarmonicMean(double[] data)
{
if (data.Length == 0)
{
return double.NaN;
}
double sum = 0;
for (int i = 0; i < data.Length; i++)
{
sum += 1.0/data[i];
}
return data.Length/sum;
}
/// <summary>
/// Estimates the unbiased population variance from the provided samples as unsorted array.
/// On a dataset of size N will use an N-1 normalizer (Bessel's correction).

28
src/Numerics/Statistics/Statistics.cs

@ -117,6 +117,34 @@ namespace MathNet.Numerics.Statistics
return StreamingStatistics.Mean(data.Where(d => d.HasValue).Select(d => d.Value));
}
/// <summary>
/// Evaluates the geometric mean.
/// Returns NaN if data is empty or if any entry is NaN.
/// </summary>
/// <param name="data">The data to calculate the geometric mean of.</param>
/// <returns>The geometric mean of the sample.</returns>
public static double GeometricMean(this IEnumerable<double> data)
{
var array = data as double[];
return array != null
? ArrayStatistics.GeometricMean(array)
: StreamingStatistics.GeometricMean(data);
}
/// <summary>
/// Evaluates the harmonic mean.
/// Returns NaN if data is empty or if any entry is NaN.
/// </summary>
/// <param name="data">The data to calculate the harmonic mean of.</param>
/// <returns>The harmonic mean of the sample.</returns>
public static double HarmonicMean(this IEnumerable<double> data)
{
var array = data as double[];
return array != null
? ArrayStatistics.HarmonicMean(array)
: StreamingStatistics.HarmonicMean(data);
}
/// <summary>
/// Estimates the unbiased population variance from the provided samples.
/// On a dataset of size N will use an N-1 normalizer (Bessel's correction).

38
src/Numerics/Statistics/StreamingStatistics.cs

@ -109,6 +109,44 @@ namespace MathNet.Numerics.Statistics
return any ? mean : double.NaN;
}
/// <summary>
/// Evaluates the geometric mean of the enumerable, in a single pass without memoization.
/// Returns NaN if data is empty or any entry is NaN.
/// </summary>
/// <param name="stream">Sample stream, no sorting is assumed.</param>
public static double GeometricMean(IEnumerable<double> stream)
{
ulong m = 0;
double sum = 0;
foreach (var d in stream)
{
sum += Math.Log(d);
m++;
}
return m > 0 ? Math.Exp(sum / m) : double.NaN;
}
/// <summary>
/// Evaluates the harmonic mean of the enumerable, in a single pass without memoization.
/// Returns NaN if data is empty or any entry is NaN.
/// </summary>
/// <param name="stream">Sample stream, no sorting is assumed.</param>
public static double HarmonicMean(IEnumerable<double> stream)
{
ulong m = 0;
double sum = 0;
foreach (var d in stream)
{
sum += 1.0 / d;
m++;
}
return m > 0 ? m/sum : double.NaN;
}
/// <summary>
/// Estimates the unbiased population variance from the provided samples as enumerable sequence, in a single pass without memoization.
/// On a dataset of size N will use an N-1 normalizer (Bessel's correction).

11
src/UnitTests/StatisticsTests/StatisticsTests.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2014 Math.NET
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -30,7 +30,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.Random;
@ -71,6 +70,8 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
Assert.That(() => Statistics.Minimum(data), Throws.Exception);
Assert.That(() => Statistics.Maximum(data), Throws.Exception);
Assert.That(() => Statistics.Mean(data), Throws.Exception);
Assert.That(() => Statistics.HarmonicMean(data), Throws.Exception);
Assert.That(() => Statistics.GeometricMean(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);
@ -99,6 +100,8 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
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.HarmonicMean(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => ArrayStatistics.GeometricMean(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>());
@ -112,6 +115,8 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
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.HarmonicMean(data), Throws.Exception.TypeOf<NullReferenceException>());
Assert.That(() => StreamingStatistics.GeometricMean(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>());
@ -134,6 +139,8 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
Assert.DoesNotThrow(() => Statistics.Minimum(data));
Assert.DoesNotThrow(() => Statistics.Maximum(data));
Assert.DoesNotThrow(() => Statistics.Mean(data));
Assert.DoesNotThrow(() => Statistics.HarmonicMean(data));
Assert.DoesNotThrow(() => Statistics.GeometricMean(data));
Assert.DoesNotThrow(() => Statistics.Median(data));
Assert.DoesNotThrow(() => Statistics.Quantile(data, 0.3));
Assert.DoesNotThrow(() => Statistics.Variance(data));

Loading…
Cancel
Save