diff --git a/src/Numerics/Statistics/ArrayStatistics.cs b/src/Numerics/Statistics/ArrayStatistics.cs
index 80ff3023..8b0bca39 100644
--- a/src/Numerics/Statistics/ArrayStatistics.cs
+++ b/src/Numerics/Statistics/ArrayStatistics.cs
@@ -163,6 +163,48 @@ namespace MathNet.Numerics.Statistics
return mean;
}
+ ///
+ /// Evaluates the geometric mean of the unsorted data array.
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample array, no sorting is assumed.
+ 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);
+ }
+
+ ///
+ /// Evaluates the harmonic mean of the unsorted data array.
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample array, no sorting is assumed.
+ 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;
+ }
+
///
/// 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).
diff --git a/src/Numerics/Statistics/Statistics.cs b/src/Numerics/Statistics/Statistics.cs
index 610a51e4..981d2ef5 100644
--- a/src/Numerics/Statistics/Statistics.cs
+++ b/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));
}
+ ///
+ /// Evaluates the geometric mean.
+ /// Returns NaN if data is empty or if any entry is NaN.
+ ///
+ /// The data to calculate the geometric mean of.
+ /// The geometric mean of the sample.
+ public static double GeometricMean(this IEnumerable data)
+ {
+ var array = data as double[];
+ return array != null
+ ? ArrayStatistics.GeometricMean(array)
+ : StreamingStatistics.GeometricMean(data);
+ }
+
+ ///
+ /// Evaluates the harmonic mean.
+ /// Returns NaN if data is empty or if any entry is NaN.
+ ///
+ /// The data to calculate the harmonic mean of.
+ /// The harmonic mean of the sample.
+ public static double HarmonicMean(this IEnumerable data)
+ {
+ var array = data as double[];
+ return array != null
+ ? ArrayStatistics.HarmonicMean(array)
+ : StreamingStatistics.HarmonicMean(data);
+ }
+
///
/// Estimates the unbiased population variance from the provided samples.
/// On a dataset of size N will use an N-1 normalizer (Bessel's correction).
diff --git a/src/Numerics/Statistics/StreamingStatistics.cs b/src/Numerics/Statistics/StreamingStatistics.cs
index d0ba11ec..7ec802bb 100644
--- a/src/Numerics/Statistics/StreamingStatistics.cs
+++ b/src/Numerics/Statistics/StreamingStatistics.cs
@@ -109,6 +109,44 @@ namespace MathNet.Numerics.Statistics
return any ? mean : double.NaN;
}
+ ///
+ /// Evaluates the geometric mean of the enumerable, in a single pass without memoization.
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample stream, no sorting is assumed.
+ public static double GeometricMean(IEnumerable 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;
+ }
+
+ ///
+ /// Evaluates the harmonic mean of the enumerable, in a single pass without memoization.
+ /// Returns NaN if data is empty or any entry is NaN.
+ ///
+ /// Sample stream, no sorting is assumed.
+ public static double HarmonicMean(IEnumerable stream)
+ {
+ ulong m = 0;
+ double sum = 0;
+
+ foreach (var d in stream)
+ {
+ sum += 1.0 / d;
+ m++;
+ }
+
+ return m > 0 ? m/sum : double.NaN;
+ }
+
///
/// 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).
diff --git a/src/UnitTests/StatisticsTests/StatisticsTests.cs b/src/UnitTests/StatisticsTests/StatisticsTests.cs
index 64e8023e..3943609f 100644
--- a/src/UnitTests/StatisticsTests/StatisticsTests.cs
+++ b/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());
Assert.That(() => ArrayStatistics.OrderStatisticInplace(data, 1), Throws.Exception.TypeOf());
Assert.That(() => ArrayStatistics.Mean(data), Throws.Exception.TypeOf());
+ Assert.That(() => ArrayStatistics.HarmonicMean(data), Throws.Exception.TypeOf());
+ Assert.That(() => ArrayStatistics.GeometricMean(data), Throws.Exception.TypeOf());
Assert.That(() => ArrayStatistics.Variance(data), Throws.Exception.TypeOf());
Assert.That(() => ArrayStatistics.StandardDeviation(data), Throws.Exception.TypeOf());
Assert.That(() => ArrayStatistics.PopulationVariance(data), Throws.Exception.TypeOf());
@@ -112,6 +115,8 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
Assert.That(() => StreamingStatistics.Minimum(data), Throws.Exception.TypeOf());
Assert.That(() => StreamingStatistics.Maximum(data), Throws.Exception.TypeOf());
Assert.That(() => StreamingStatistics.Mean(data), Throws.Exception.TypeOf());
+ Assert.That(() => StreamingStatistics.HarmonicMean(data), Throws.Exception.TypeOf());
+ Assert.That(() => StreamingStatistics.GeometricMean(data), Throws.Exception.TypeOf());
Assert.That(() => StreamingStatistics.Variance(data), Throws.Exception.TypeOf());
Assert.That(() => StreamingStatistics.StandardDeviation(data), Throws.Exception.TypeOf());
Assert.That(() => StreamingStatistics.PopulationVariance(data), Throws.Exception.TypeOf());
@@ -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));