Browse Source

Statistics: quantile rank, empirical CDF, Excel percentrank

pull/194/head
Christoph Ruegg 13 years ago
parent
commit
9ea8aebf7e
  1. 7
      src/Numerics/ExcelFunctions.cs
  2. 6
      src/Numerics/Statistics/RankDefinition.cs
  3. 83
      src/Numerics/Statistics/SortedArrayStatistics.cs
  4. 204
      src/Numerics/Statistics/Statistics.cs
  5. 32
      src/UnitTests/ExcelTests.cs
  6. 65
      src/UnitTests/StatisticsTests/StatisticsTests.cs

7
src/Numerics/ExcelFunctions.cs

@ -33,6 +33,7 @@ using MathNet.Numerics.Distributions;
using MathNet.Numerics.Statistics;
// ReSharper disable InconsistentNaming
namespace MathNet.Numerics
{
/// <summary>
@ -85,6 +86,12 @@ namespace MathNet.Numerics
throw new ArgumentOutOfRangeException("quant");
}
}
public static double PERCENTRANK(double[] array, double x)
{
return array.QuantileRank(x, RankDefinition.Min);
}
}
}
// ReSharper restore InconsistentNaming

6
src/Numerics/Statistics/RankDefinition.cs

@ -44,6 +44,8 @@ namespace MathNet.Numerics.Statistics
Max = 3,
/// <summary>Permutation with increasing values at each index of ties.</summary>
First = 4
First = 4,
EmpiricalCDF = 5
}
}
}

83
src/Numerics/Statistics/SortedArrayStatistics.cs

@ -282,6 +282,89 @@ namespace MathNet.Numerics.Statistics
}
}
/// <summary>
/// Estimates the empirical cummulative distribution function (CDF) at x from the sorted data array (ascending).
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="x">The value where to estimate the CDF at.</param>
public static double EmpiricalCDF(double[] data, double x)
{
if (x < data[0]) return 0.0;
if (x >= data[data.Length - 1]) return 1.0;
int right = Array.BinarySearch(data, x);
if (right >= 0)
{
while (right < data.Length - 1 && data[right + 1] == data[right])
{
right++;
}
return (right + 1)/(double)(data.Length);
}
return (~right)/(double)(data.Length);
}
/// <summary>
/// Estimates the quantile tau from the sorted data array (ascending).
/// 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.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="x">Quantile value.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled and what product/definition it should be consistent with</param>
public static double QuantileRank(double[] data, double x, RankDefinition definition = RankDefinition.Default)
{
if (x < data[0]) return 0.0;
if (x >= data[data.Length - 1]) return 1.0;
int right = Array.BinarySearch(data, x);
if (right >= 0)
{
int left = right;
while (left > 0 && data[left - 1] == data[left])
{
left--;
}
while (right < data.Length - 1 && data[right + 1] == data[right])
{
right++;
}
switch (definition)
{
case RankDefinition.EmpiricalCDF:
return (right + 1)/(double)(data.Length);
case RankDefinition.Max:
return right/(double)(data.Length - 1);
case RankDefinition.Min:
return left/(double)(data.Length - 1);
case RankDefinition.Average:
return (left/(double)(data.Length - 1) + right/(double)(data.Length - 1))/2;
default:
throw new NotSupportedException();
}
}
else
{
right = ~right;
int left = right - 1;
switch (definition)
{
case RankDefinition.EmpiricalCDF:
return (left + 1)/(double)(data.Length);
default:
{
var a = left/(double)(data.Length - 1);
var b = right/(double)(data.Length - 1);
return ((data[right] - x)*a + (x - data[left])*b)/(data[right] - data[left]);
}
}
}
}
/// <summary>
/// Evaluates the rank of each entry of the sorted data array (ascending).
/// The rank definition can be specificed to be compatible

204
src/Numerics/Statistics/Statistics.cs

@ -370,51 +370,7 @@ namespace MathNet.Numerics.Statistics
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double InverseCDF(this IEnumerable<double> data, double tau)
{
var array = data.ToArray();
return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF);
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double InverseCDF(this IEnumerable<double?> data, double tau)
{
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF);
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> InverseCDFFunc(this IEnumerable<double> data)
{
var array = data.ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF);
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> InverseCDFFunc(this IEnumerable<double?> data)
{
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF);
}
/// <summary>
/// stimates the tau-th quantile from the provided samples.
/// Estimates 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.
@ -429,7 +385,7 @@ namespace MathNet.Numerics.Statistics
}
/// <summary>
/// stimates the tau-th quantile from the provided samples.
/// Estimates 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.
@ -444,7 +400,7 @@ namespace MathNet.Numerics.Statistics
}
/// <summary>
/// stimates the tau-th quantile from the provided samples.
/// Estimates 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.
@ -459,7 +415,7 @@ namespace MathNet.Numerics.Statistics
}
/// <summary>
/// stimates the tau-th quantile from the provided samples.
/// Estimates 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.
@ -635,13 +591,14 @@ namespace MathNet.Numerics.Statistics
return order => SortedArrayStatistics.OrderStatistic(array, order);
}
/// <summary>
/// Evaluates the rank of each entry of the provided samples.
/// The rank definition can be specificed to be compatible
/// with an existing system.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled and what product/definition it should be consistent with</param>
public static double[] Ranks(this IEnumerable<double> data, RankDefinition definition = RankDefinition.Default)
{
var array = data.ToArray();
@ -654,11 +611,154 @@ namespace MathNet.Numerics.Statistics
/// with an existing system.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled and what product/definition it should be consistent with</param>
public static double[] Ranks(this IEnumerable<double?> data, RankDefinition definition = RankDefinition.Default)
{
var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
return ArrayStatistics.RanksInplace(array, definition);
return Ranks(data.Where(d => d.HasValue).Select(d => d.Value), definition);
}
/// <summary>
/// Estimates the quantile tau 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.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="x">Quantile value.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled and what product/definition it should be consistent with</param>
public static double QuantileRank(this IEnumerable<double> data, double x, RankDefinition definition = RankDefinition.Default)
{
var array = data.ToArray();
Array.Sort(array);
return SortedArrayStatistics.QuantileRank(array, x, definition);
}
/// <summary>
/// Estimates the quantile tau 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.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="x">Quantile value.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled and what product/definition it should be consistent with</param>
public static double QuantileRank(this IEnumerable<double?> data, double x, RankDefinition definition = RankDefinition.Default)
{
return QuantileRank(data.Where(d => d.HasValue).Select(d => d.Value), x, definition);
}
/// <summary>
/// Estimates the quantile tau 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.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled and what product/definition it should be consistent with</param>
public static Func<double, double> QuantileRankFunc(this IEnumerable<double> data, RankDefinition definition = RankDefinition.Default)
{
var array = data.ToArray();
Array.Sort(array);
return x => SortedArrayStatistics.QuantileRank(array, x, definition);
}
/// <summary>
/// Estimates the quantile tau 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.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="definition">Rank definition, to choose how ties should be handled and what product/definition it should be consistent with</param>
public static Func<double, double> QuantileRankFunc(this IEnumerable<double?> data, RankDefinition definition = RankDefinition.Default)
{
return QuantileRankFunc(data.Where(d => d.HasValue).Select(d => d.Value), definition);
}
/// <summary>
/// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="x">The value where to estimate the CDF at.</param>
public static double EmpiricalCDF(this IEnumerable<double> data, double x)
{
var array = data.ToArray();
Array.Sort(array);
return SortedArrayStatistics.EmpiricalCDF(array, x);
}
/// <summary>
/// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="x">The value where to estimate the CDF at.</param>
public static double EmpiricalCDF(this IEnumerable<double?> data, double x)
{
return EmpiricalCDF(data.Where(d => d.HasValue).Select(d => d.Value), x);
}
/// <summary>
/// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> EmpiricalCDFFunc(this IEnumerable<double> data)
{
var array = data.ToArray();
Array.Sort(array);
return x => SortedArrayStatistics.EmpiricalCDF(array, x);
}
/// <summary>
/// Estimates the empirical cummulative distribution function (CDF) at x from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> EmpiricalCDFFunc(this IEnumerable<double?> data)
{
return EmpiricalCDFFunc(data.Where(d => d.HasValue).Select(d => d.Value));
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double InverseCDF(this IEnumerable<double> data, double tau)
{
var array = data.ToArray();
return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.InverseCDF);
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
/// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
public static double InverseCDF(this IEnumerable<double?> data, double tau)
{
return InverseCDF(data.Where(d => d.HasValue).Select(d => d.Value), tau);
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> InverseCDFFunc(this IEnumerable<double> data)
{
var array = data.ToArray();
Array.Sort(array);
return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.InverseCDF);
}
/// <summary>
/// Estimates the empirical inverse CDF at tau from the provided samples.
/// </summary>
/// <param name="data">The data sample sequence.</param>
public static Func<double, double> InverseCDFFunc(this IEnumerable<double?> data)
{
return InverseCDFFunc(data.Where(d => d.HasValue).Select(d => d.Value));
}
}
}

32
src/UnitTests/ExcelTests.cs

@ -102,6 +102,38 @@ namespace MathNet.Numerics.UnitTests
Assert.That(ExcelFunctions.QUARTILE(array, 3), Is.EqualTo(9.25000000000).Within(1e-8));
Assert.That(ExcelFunctions.QUARTILE(array, 4), Is.EqualTo(12.00000000000).Within(1e-8));
}
[Test]
public void PERCENTRANK()
{
var array = new Double[] { 1, 8, 12, 7, 2, 9, 10, 4 };
Assert.That(ExcelFunctions.PERCENTRANK(array, 1.0), Is.EqualTo(0.00000000000).Within(1e-8), "A1");
Assert.That(ExcelFunctions.PERCENTRANK(array, 2.0), Is.EqualTo(0.14285714280).Within(1e-8), "A2");
Assert.That(ExcelFunctions.PERCENTRANK(array, 3.0), Is.EqualTo(0.21428571420).Within(1e-8), "A3");
Assert.That(ExcelFunctions.PERCENTRANK(array, 4.0), Is.EqualTo(0.28571428570).Within(1e-8), "A4");
Assert.That(ExcelFunctions.PERCENTRANK(array, 5.0), Is.EqualTo(0.33333333330).Within(1e-8), "A5");
Assert.That(ExcelFunctions.PERCENTRANK(array, 6.0), Is.EqualTo(0.38095238090).Within(1e-8), "A6");
Assert.That(ExcelFunctions.PERCENTRANK(array, 7.0), Is.EqualTo(0.42857142850).Within(1e-8), "A7");
Assert.That(ExcelFunctions.PERCENTRANK(array, 8.0), Is.EqualTo(0.57142857140).Within(1e-8), "A8");
Assert.That(ExcelFunctions.PERCENTRANK(array, 9.0), Is.EqualTo(0.71428571420).Within(1e-8), "A9");
Assert.That(ExcelFunctions.PERCENTRANK(array, 10.0), Is.EqualTo(0.85714285710).Within(1e-8), "A10");
Assert.That(ExcelFunctions.PERCENTRANK(array, 11.0), Is.EqualTo(0.92857142850).Within(1e-8), "A11");
Assert.That(ExcelFunctions.PERCENTRANK(array, 12.0), Is.EqualTo(1.00000000000).Within(1e-8), "A12");
array = new Double[] { 1, 9, 12, 7, 2, 9, 10, 2 };
Assert.That(ExcelFunctions.PERCENTRANK(array, 1.0), Is.EqualTo(0.00000000000).Within(1e-8), "B1");
Assert.That(ExcelFunctions.PERCENTRANK(array, 2.0), Is.EqualTo(0.14285714280).Within(1e-8), "B2");
Assert.That(ExcelFunctions.PERCENTRANK(array, 3.0), Is.EqualTo(0.31428571420).Within(1e-8), "B3");
Assert.That(ExcelFunctions.PERCENTRANK(array, 4.0), Is.EqualTo(0.34285714280).Within(1e-8), "B4");
Assert.That(ExcelFunctions.PERCENTRANK(array, 5.0), Is.EqualTo(0.37142857140).Within(1e-8), "B5");
Assert.That(ExcelFunctions.PERCENTRANK(array, 6.0), Is.EqualTo(0.40000000000).Within(1e-8), "B6");
Assert.That(ExcelFunctions.PERCENTRANK(array, 7.0), Is.EqualTo(0.42857142850).Within(1e-8), "B7");
Assert.That(ExcelFunctions.PERCENTRANK(array, 8.0), Is.EqualTo(0.50000000000).Within(1e-8), "B8");
Assert.That(ExcelFunctions.PERCENTRANK(array, 9.0), Is.EqualTo(0.57142857140).Within(1e-8), "B9");
Assert.That(ExcelFunctions.PERCENTRANK(array, 10.0), Is.EqualTo(0.85714285710).Within(1e-8), "B10");
Assert.That(ExcelFunctions.PERCENTRANK(array, 11.0), Is.EqualTo(0.92857142850).Within(1e-8), "B11");
Assert.That(ExcelFunctions.PERCENTRANK(array, 12.0), Is.EqualTo(1.00000000000).Within(1e-8), "B12");
}
}
}
// ReSharper restore InconsistentNaming

65
src/UnitTests/StatisticsTests/StatisticsTests.cs

@ -65,7 +65,6 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
{
double[] data = null;
// ReSharper disable InvokeAsExtensionMethod
Assert.That(() => Statistics.Minimum(data), Throws.Exception);
Assert.That(() => Statistics.Maximum(data), Throws.Exception);
Assert.That(() => Statistics.Mean(data), Throws.Exception);
@ -77,7 +76,6 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
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>());
@ -659,6 +657,69 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
Is.EqualTo(new[] { 1.0, 5, 8, 4, 2, 6, 7, 3 }).AsCollection.Within(1e-8));
}
[Test]
public void EmpiricalCDF()
{
// R: ecdf(data)(x)
var ties = new double[] { 1, 9, 12, 7, 2, 9, 10, 2 };
Assert.That(Statistics.EmpiricalCDF(ties, -1.0), Is.EqualTo(0.0).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 0.0), Is.EqualTo(0.0).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 1.0), Is.EqualTo(0.125).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 2.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 3.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 4.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 5.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 6.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 7.0), Is.EqualTo(0.5).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 8.0), Is.EqualTo(0.5).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 9.0), Is.EqualTo(0.75).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 10.0), Is.EqualTo(0.875).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 11.0), Is.EqualTo(0.875).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 12.0), Is.EqualTo(1.0).Within(1e-8));
Assert.That(Statistics.EmpiricalCDF(ties, 13.0), Is.EqualTo(1.0).Within(1e-8));
}
[Test]
public void EmpiricalCDFSortedArray()
{
// R: ecdf(data)(x)
var ties = new double[] { 1, 9, 12, 7, 2, 9, 10, 2 };
Array.Sort(ties);
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, -1.0), Is.EqualTo(0.0).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 0.0), Is.EqualTo(0.0).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 1.0), Is.EqualTo(0.125).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 2.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 3.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 4.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 5.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 6.0), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 7.0), Is.EqualTo(0.5).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 8.0), Is.EqualTo(0.5).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 9.0), Is.EqualTo(0.75).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 10.0), Is.EqualTo(0.875).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 11.0), Is.EqualTo(0.875).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 12.0), Is.EqualTo(1.0).Within(1e-8));
Assert.That(SortedArrayStatistics.EmpiricalCDF(ties, 13.0), Is.EqualTo(1.0).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, -1.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.0).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 0.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.0).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 1.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.125).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 2.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 3.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 4.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 5.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 6.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.375).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 7.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.5).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 8.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.5).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 9.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.75).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 10.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.875).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 11.0, RankDefinition.EmpiricalCDF), Is.EqualTo(0.875).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 12.0, RankDefinition.EmpiricalCDF), Is.EqualTo(1.0).Within(1e-8));
Assert.That(SortedArrayStatistics.QuantileRank(ties, 13.0, RankDefinition.EmpiricalCDF), Is.EqualTo(1.0).Within(1e-8));
}
[Test]
public void MedianOnShortSequence()
{

Loading…
Cancel
Save