diff --git a/src/Numerics/Statistics/ArrayStatistics.cs b/src/Numerics/Statistics/ArrayStatistics.cs
index 628e53ec..76152f3e 100644
--- a/src/Numerics/Statistics/ArrayStatistics.cs
+++ b/src/Numerics/Statistics/ArrayStatistics.cs
@@ -86,22 +86,6 @@ namespace MathNet.Numerics.Statistics
return max;
}
- ///
- /// Returns the order statistic (order 1..N) from the unsorted data array.
- /// WARNING: Works inplace and can thus causes the data array to be reordered.
- ///
- /// Sample array, no sorting is assumed. Will be reordered.
- /// One-based order of the statistic, must be between 1 and N (inclusive).
- 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);
- if (order == data.Length) return Maximum(data);
- return SelectInplace(data, order - 1);
- }
-
///
/// Estimates the arithmetic sample mean from the unsorted data array.
/// Returns NaN if data is empty or any entry is NaN.
@@ -187,9 +171,25 @@ namespace MathNet.Numerics.Statistics
return Math.Sqrt(PopulationVariance(data));
}
+ ///
+ /// Returns the order statistic (order 1..N) from the unsorted data array.
+ /// WARNING: Works inplace and can thus causes the data array to be reordered.
+ ///
+ /// Sample array, no sorting is assumed. Will be reordered.
+ /// One-based order of the statistic, must be between 1 and N (inclusive).
+ 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);
+ if (order == data.Length) return Maximum(data);
+ return SelectInplace(data, order - 1);
+ }
+
///
/// Estimates the median value from the unsorted data array.
- /// Applies a linear interpolation, consistent with Quantile and R-8.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
/// WARNING: Works inplace and can thus causes the data array to be reordered.
///
/// Sample array, no sorting is assumed. Will be reordered.
@@ -198,10 +198,73 @@ namespace MathNet.Numerics.Statistics
return QuantileInplace(data, 0.5d);
}
+
+ ///
+ /// Estimates the p-Percentile value from the unsorted data array.
+ /// If a non-integer Percentile is needed, use Quantile instead.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ /// WARNING: Works inplace and can thus causes the data array to be reordered.
+ ///
+ /// Sample array, no sorting is assumed. Will be reordered.
+ /// Percentile selector, between 0 and 100 (inclusive).
+ public static double PercentileInplace(double[] data, int p)
+ {
+ return QuantileInplace(data, p / 100d);
+ }
+
+ ///
+ /// Estimates the first quartile value from the unsorted data array.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ /// WARNING: Works inplace and can thus causes the data array to be reordered.
+ ///
+ /// Sample array, no sorting is assumed. Will be reordered.
+ public static double LowerQuartileInplace(double[] data)
+ {
+ return QuantileInplace(data, 0.25d);
+ }
+
+ ///
+ /// Estimates the third quartile value from the unsorted data array.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ /// WARNING: Works inplace and can thus causes the data array to be reordered.
+ ///
+ /// Sample array, no sorting is assumed. Will be reordered.
+ public static double UpperQuartileInplace(double[] data)
+ {
+ return QuantileInplace(data, 0.75d);
+ }
+
+ ///
+ /// Estimates the inter-quartile range from the unsorted data array.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ /// WARNING: Works inplace and can thus causes the data array to be reordered.
+ ///
+ /// Sample array, no sorting is assumed. Will be reordered.
+ public static double InterquartileRangeInplace(double[] data)
+ {
+ return QuantileInplace(data, 0.75d) - QuantileInplace(data, 0.25d);
+ }
+
+ ///
+ /// Estimates {min, lower-quantile, median, upper-quantile, max} from the unsorted data array.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ /// WARNING: Works inplace and can thus causes the data array to be reordered.
+ ///
+ /// Sample array, no sorting is assumed. Will be reordered.
+ 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?
+ return new[] { Minimum(data), QuantileInplace(data, 0.25), QuantileInplace(data, 0.50), QuantileInplace(data, 0.75), Maximum(data) };
+ }
+
///
/// Estimates the tau-th quantile from the unsorted data array.
/// The tau-th quantile is the data value where the cumulative distribution
- /// function crosses tau. Applies a linear interpolation, compatible with R-8.
+ /// function crosses tau.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
/// WARNING: Works inplace and can thus causes the data array to be reordered.
///
/// Sample array, no sorting is assumed. Will be reordered.
diff --git a/src/Numerics/Statistics/SortedArrayStatistics.cs b/src/Numerics/Statistics/SortedArrayStatistics.cs
index 7061ab8e..812b37b6 100644
--- a/src/Numerics/Statistics/SortedArrayStatistics.cs
+++ b/src/Numerics/Statistics/SortedArrayStatistics.cs
@@ -79,7 +79,7 @@ namespace MathNet.Numerics.Statistics
///
/// Estimates the median value from the sorted data array (ascending).
- /// Applies a linear interpolation, consistent with Quantile and R-8.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
///
/// Sample array, must be sorted ascendingly.
public static double Median(double[] data)
@@ -89,8 +89,8 @@ namespace MathNet.Numerics.Statistics
///
/// Estimates the p-Percentile value from the sorted data array (ascending).
- /// Applies a linear interpolation, consistent with Quantile and R-8.
/// If a non-integer Percentile is needed, use Quantile instead.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
///
/// Sample array, must be sorted ascendingly.
/// Percentile selector, between 0 and 100 (inclusive).
@@ -101,7 +101,7 @@ namespace MathNet.Numerics.Statistics
///
/// Estimates the first quartile value from the sorted data array (ascending).
- /// Applies a linear interpolation, consistent with Quantile and R-8.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
///
/// Sample array, must be sorted ascendingly.
public static double LowerQuartile(double[] data)
@@ -111,7 +111,7 @@ namespace MathNet.Numerics.Statistics
///
/// Estimates the third quartile value from the sorted data array (ascending).
- /// Applies a linear interpolation, consistent with Quantile and R-8.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
///
/// Sample array, must be sorted ascendingly.
public static double UpperQuartile(double[] data)
@@ -121,7 +121,7 @@ namespace MathNet.Numerics.Statistics
///
/// Estimates the inter-quartile range from the sorted data array (ascending).
- /// Applies a linear interpolation, consistent with Quantile and R-8.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
///
/// Sample array, must be sorted ascendingly.
public static double InterquartileRange(double[] data)
@@ -131,7 +131,7 @@ namespace MathNet.Numerics.Statistics
///
/// Estimates {min, lower-quantile, median, upper-quantile, max} from the sorted data array (ascending).
- /// Applies a linear interpolation, consistent with Quantile and R-8.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
///
/// Sample array, must be sorted ascendingly.
public static double[] FiveNumberSummary(double[] data)
@@ -144,7 +144,8 @@ namespace MathNet.Numerics.Statistics
///
/// Estimates the tau-th quantile from the sorted data array (ascending).
/// The tau-th quantile is the data value where the cumulative distribution
- /// function crosses tau. Applies a linear interpolation, compatible with R-8.
+ /// function crosses tau.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
///
/// Sample array, must be sorted ascendingly.
/// Quantile selector, between 0.0 and 1.0 (inclusive).
diff --git a/src/Numerics/Statistics/Statistics.cs b/src/Numerics/Statistics/Statistics.cs
index f1a41fed..d8e7405f 100644
--- a/src/Numerics/Statistics/Statistics.cs
+++ b/src/Numerics/Statistics/Statistics.cs
@@ -207,10 +207,9 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the sample median.
+ /// Estimates the sample median from the provided samples (R8).
///
- /// The data to calculate the median of.
- /// The median of the sample.
+ /// The data sample sequence.
public static double Median(this IEnumerable data)
{
if (data == null) throw new ArgumentNullException("data");
@@ -219,10 +218,9 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the sample median.
+ /// Estimates the sample median from the provided samples (R8).
///
- /// The data to calculate the median of.
- /// The median of the sample.
+ /// The data sample sequence.
public static double Median(this IEnumerable data)
{
if (data == null) throw new ArgumentNullException("data");
@@ -231,11 +229,13 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the sample tau-quantile.
+ /// 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 to calculate the median of.
+ /// The data sample sequence.
/// Quantile selector, between 0.0 and 1.0 (inclusive).
- /// The median of the sample.
public static double Quantile(this IEnumerable data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
@@ -244,11 +244,13 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the sample tau-quantile.
+ /// 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 to calculate the median of.
+ /// The data sample sequence.
/// Quantile selector, between 0.0 and 1.0 (inclusive).
- /// The median of the sample.
public static double Quantile(this IEnumerable data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
@@ -257,11 +259,10 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the empiric inverse CDF at tau (tau-quantile).
+ /// Estimates the empiric inverse CDF at tau from the provided samples.
///
- /// The data to calculate the median of.
+ /// The data sample sequence.
/// Quantile selector, between 0.0 and 1.0 (inclusive).
- /// The median of the sample.
public static double InverseCDF(this IEnumerable data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
@@ -270,11 +271,10 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the empiric inverse CDF at tau (tau-quantile).
+ /// Estimates the empiric inverse CDF at tau from the provided samples.
///
- /// The data to calculate the median of.
+ /// The data sample sequence.
/// Quantile selector, between 0.0 and 1.0 (inclusive).
- /// The median of the sample.
public static double InverseCDF(this IEnumerable data, double tau)
{
if (data == null) throw new ArgumentNullException("data");
@@ -283,11 +283,13 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the sample tau-quantile.
+ /// 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 to calculate the median of.
+ /// The data sample sequence.
/// Quantile selector, between 0.0 and 1.0 (inclusive).
- /// The median of the sample.
/// Quantile definition, to choose what product/definition it should be consistent with
public static double QuantileCustom(this IEnumerable data, double tau, QuantileDefinition definition)
{
@@ -297,11 +299,13 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Estimates the sample tau-quantile.
+ /// 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 to calculate the median of.
+ /// The data sample sequence.
/// Quantile selector, between 0.0 and 1.0 (inclusive).
- /// The median of the sample.
/// Quantile definition, to choose what product/definition it should be consistent with
public static double QuantileCustom(this IEnumerable data, double tau, QuantileDefinition definition)
{
@@ -311,11 +315,134 @@ namespace MathNet.Numerics.Statistics
}
///
- /// Returns the i-order (1..N) statistic of the provided samples.
+ /// 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 sample data.
- /// Order of the statistic to evaluate.
- /// The i'th order statistic in the sample data.
+ /// The data sample sequence.
+ /// Percentile selector, between 0 and 100 (inclusive).
+ public static double Percentile(this IEnumerable data, int p)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ 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.
+ /// Percentile selector, between 0 and 100 (inclusive).
+ public static double Percentile(this IEnumerable 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);
+ }
+
+ ///
+ /// Estimates the first quartile value from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double LowerQuartile(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ return ArrayStatistics.LowerQuartileInplace(array);
+ }
+
+ ///
+ /// Estimates the first quartile value from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double LowerQuartile(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
+ return ArrayStatistics.LowerQuartileInplace(array);
+ }
+
+ ///
+ /// Estimates the third quartile value from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double UpperQuartile(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ return ArrayStatistics.UpperQuartileInplace(array);
+ }
+
+ ///
+ /// Estimates the third quartile value from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double UpperQuartile(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
+ return ArrayStatistics.UpperQuartileInplace(array);
+ }
+
+ ///
+ /// Estimates the inter-quartile range from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double InterquartileRange(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ return ArrayStatistics.InterquartileRangeInplace(array);
+ }
+
+ ///
+ /// Estimates the inter-quartile range from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double InterquartileRange(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
+ return ArrayStatistics.InterquartileRangeInplace(array);
+ }
+
+ ///
+ /// Estimates {min, lower-quantile, median, upper-quantile, max} from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double[] FiveNumberSummary(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.ToArray();
+ return ArrayStatistics.FiveNumberSummaryInplace(array);
+ }
+
+ ///
+ /// Estimates {min, lower-quantile, median, upper-quantile, max} from the provided samples.
+ /// Approximately median-unbiased regardless of the sample distribution (R8).
+ ///
+ /// The data sample sequence.
+ public static double[] FiveNumberSummary(this IEnumerable data)
+ {
+ if (data == null) throw new ArgumentNullException("data");
+ var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
+ return ArrayStatistics.FiveNumberSummaryInplace(array);
+ }
+
+ ///
+ /// Returns the order statistic (order 1..N) from the provided samples.
+ ///
+ /// The data sample sequence.
+ /// One-based order of the statistic, must be between 1 and N (inclusive).
public static double OrderStatistic(IEnumerable data, int order)
{
if (data == null) throw new ArgumentNullException("data");