diff --git a/src/Numerics/Statistics/Statistics.cs b/src/Numerics/Statistics/Statistics.cs
index d8e7405f..b0fd1638 100644
--- a/src/Numerics/Statistics/Statistics.cs
+++ b/src/Numerics/Statistics/Statistics.cs
@@ -258,6 +258,37 @@ namespace MathNet.Numerics.Statistics
return ArrayStatistics.QuantileInplace(array, tau);
}
+ ///
+ /// Estimates the tau-th quantile from the provided samples.
+ /// The tau-th quantile is the data value where the cumulative distribution
+ /// function crosses tau.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static Func QuantileFunc(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ Array.Sort(array);
+ return tau => SortedArrayStatistics.Quantile(array, tau);
+ }
+
+ ///
+ /// Estimates the tau-th quantile from the provided samples.
+ /// The tau-th quantile is the data value where the cumulative distribution
+ /// function crosses tau.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ /// Quantile selector, between 0.0 and 1.0 (inclusive).
+ public static Func QuantileFunc(this IEnumerable 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);
+ }
+
///
/// Estimates the empiric inverse CDF at tau from the provided samples.
///
@@ -282,6 +313,30 @@ namespace MathNet.Numerics.Statistics
return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF);
}
+ ///
+ /// Estimates the empiric inverse CDF at tau from the provided samples.
+ ///
+ /// The data sample sequence.
+ public static Func InverseCDFFunc(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ Array.Sort(array);
+ return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF);
+ }
+
+ ///
+ /// Estimates the empiric inverse CDF at tau from the provided samples.
+ ///
+ /// The data sample sequence.
+ public static Func InverseCDFFunc(this IEnumerable 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);
+ }
+
///
/// stimates the tau-th quantile from the provided samples.
/// The tau-th quantile is the data value where the cumulative distribution
@@ -314,6 +369,38 @@ namespace MathNet.Numerics.Statistics
return ArrayStatistics.QuantileCustomInplace(array, tau, definition);
}
+ ///
+ /// stimates the tau-th quantile from the provided samples.
+ /// The tau-th quantile is the data value where the cumulative distribution
+ /// function crosses tau. The quantile definition can be specificed to be compatible
+ /// with an existing system.
+ ///
+ /// The data sample sequence.
+ /// Quantile definition, to choose what product/definition it should be consistent with
+ public static Func QuantileCustomFunc(this IEnumerable data, QuantileDefinition definition)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ Array.Sort(array);
+ return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition);
+ }
+
+ ///
+ /// stimates the tau-th quantile from the provided samples.
+ /// The tau-th quantile is the data value where the cumulative distribution
+ /// function crosses tau. The quantile definition can be specificed to be compatible
+ /// with an existing system.
+ ///
+ /// The data sample sequence.
+ /// Quantile definition, to choose what product/definition it should be consistent with
+ public static Func QuantileCustomFunc(this IEnumerable 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);
+ }
+
///
/// Estimates the p-Percentile value from the provided samples.
/// If a non-integer Percentile is needed, use Quantile instead.
@@ -342,6 +429,34 @@ namespace MathNet.Numerics.Statistics
return ArrayStatistics.PercentileInplace(array, p);
}
+ ///
+ /// Estimates the p-Percentile value from the provided samples.
+ /// If a non-integer Percentile is needed, use Quantile instead.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static Func PercentileFunc(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ Array.Sort(array);
+ return p => SortedArrayStatistics.Percentile(array, p);
+ }
+
+ ///
+ /// Estimates the p-Percentile value from the provided samples.
+ /// If a non-integer Percentile is needed, use Quantile instead.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static Func PercentileFunc(this IEnumerable 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);
+ }
+
///
/// Estimates the first quartile value from the provided samples.
/// Approximately median-unbiased regardless of the sample distribution (R8).
@@ -449,5 +564,17 @@ namespace MathNet.Numerics.Statistics
var array = data.ToArray();
return ArrayStatistics.OrderStatisticInplace(array, order);
}
+
+ ///
+ /// Returns the order statistic (order 1..N) from the provided samples.
+ ///
+ /// The data sample sequence.
+ public static Func OrderStatisticFunc(IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ Array.Sort(array);
+ return order => SortedArrayStatistics.OrderStatistic(array, order);
+ }
}
}
diff --git a/src/UnitTests/StatisticsTests/StatisticsTests.cs b/src/UnitTests/StatisticsTests/StatisticsTests.cs
index f06d468d..82592bef 100644
--- a/src/UnitTests/StatisticsTests/StatisticsTests.cs
+++ b/src/UnitTests/StatisticsTests/StatisticsTests.cs
@@ -233,6 +233,16 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
// -3 -1 -0.5 0 1 4 5 6 10
var samples = new[] { -1, 5, 0, -3, 10, -0.5, 4, 1, 6 };
+ var f = Statistics.OrderStatisticFunc(samples);
+ Assert.That(f(0), Is.NaN, "Order-0 (bad)");
+ Assert.That(f(1), Is.EqualTo(-3), "Order-1");
+ Assert.That(f(2), Is.EqualTo(-1), "Order-2");
+ Assert.That(f(3), Is.EqualTo(-0.5), "Order-3");
+ Assert.That(f(7), Is.EqualTo(5), "Order-7");
+ Assert.That(f(8), Is.EqualTo(6), "Order-8");
+ Assert.That(f(9), Is.EqualTo(10), "Order-9");
+ Assert.That(f(10), Is.NaN, "Order-10 (bad)");
+
Assert.That(Statistics.OrderStatistic(samples, 0), Is.NaN, "Order-0 (bad)");
Assert.That(Statistics.OrderStatistic(samples, 1), Is.EqualTo(-3), "Order-1");
Assert.That(Statistics.OrderStatistic(samples, 2), Is.EqualTo(-1), "Order-2");
@@ -279,7 +289,9 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.InverseCDF(samples, tau), 1e-14);
+ Assert.AreEqual(expected, Statistics.InverseCDFFunc(samples)(tau), 1e-14);
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.InverseCDF), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.InverseCDF)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.InverseCDF), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 0d, 0d, 1d, 0d), 1e-14);
@@ -306,6 +318,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R2), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R2)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.InverseCDFAverage), 1e-14);
@@ -330,6 +343,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R3), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R3)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.Nearest), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 0.5d, 0d, 0d, 0d), 1e-14);
@@ -356,6 +370,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R4), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R4)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.California), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 0d, 0d, 0d, 1d), 1e-14);
@@ -382,6 +397,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R5), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R5)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.Hydrology), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 0.5d, 0d, 0d, 1d), 1e-14);
@@ -408,6 +424,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R6), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R6)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.Weibull), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 0d, 1d, 0d, 1d), 1e-14);
@@ -434,6 +451,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R7), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R7)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.Excel), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 1d, -1d, 0d, 1d), 1e-14);
@@ -460,6 +478,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
Assert.AreEqual(expected, Statistics.Quantile(samples, tau), 1e-14);
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R8), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R8)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileInplace(samples, tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.Median), 1e-14);
@@ -487,6 +506,7 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
var samples = new[] {-1, 5, 0, -3, 10, -0.5, 4, 0.2, 1, 6};
Assert.AreEqual(expected, Statistics.QuantileCustom(samples, tau, QuantileDefinition.R9), 1e-14);
+ Assert.AreEqual(expected, Statistics.QuantileCustomFunc(samples, QuantileDefinition.R9)(tau), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, QuantileDefinition.Normal), 1e-14);
Assert.AreEqual(expected, ArrayStatistics.QuantileCustomInplace(samples, tau, 3/8d, 1/4d, 0d, 1d), 1e-14);