Browse Source

Merge pull request #305 from logophobia/master

chisquared inverse distribution
pull/688/head
Christoph Ruegg 11 years ago
parent
commit
e4dfcb16c2
  1. 29
      src/Numerics/Distributions/ChiSquared.cs
  2. 26
      src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs

29
src/Numerics/Distributions/ChiSquared.cs

@ -325,6 +325,18 @@ namespace MathNet.Numerics.Distributions
return (Math.Pow(x, (freedom/2.0) - 1.0)*Math.Exp(-x/2.0))/(Math.Pow(2.0, freedom/2.0)*SpecialFunctions.Gamma(freedom/2.0));
}
/// <summary>
/// Computes the inverse of the cumulative distribution function (InvCDF) for the distribution
/// at the given probability. This is also known as the quantile or percent point function.
/// </summary>
/// <param name="p">The location at which to compute the inverse cumulative density.</param>
/// <returns>the inverse cumulative density at <paramref name="p"/>.</returns>
/// <seealso cref="InvCDF"/>
public double InverseCumulativeDistribution(double p)
{
return InvCDF(_freedom, p);
}
/// <summary>
/// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x).
/// </summary>
@ -359,6 +371,23 @@ namespace MathNet.Numerics.Distributions
return SpecialFunctions.GammaLowerRegularized(freedom/2.0, x/2.0);
}
/// <summary>
/// Computes the inverse of the cumulative distribution function (InvCDF) for the distribution
/// at the given probability. This is also known as the quantile or percent point function.
/// </summary>
/// <param name="freedom">The degrees of freedom (k) of the distribution. Range: k > 0.</param>
/// <param name="p">The location at which to compute the inverse cumulative density.</param>
/// <returns>the inverse cumulative density at <paramref name="p"/>.</returns>
public static double InvCDF(double freedom, double p)
{
if(!IsValidParameterSet(freedom))
{
throw new ArgumentException(Resources.InvalidDistributionParameters);
}
return SpecialFunctions.GammaLowerRegularizedInv(freedom / 2.0, p) / 0.5;
}
/// <summary>
/// Generates a sample from the <c>ChiSquare</c> distribution.
/// </summary>

26
src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs

@ -318,5 +318,31 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
Assert.That(n.CumulativeDistribution(x), Is.EqualTo(expected).Within(1e-14));
Assert.That(ChiSquared.CDF(dof, x), Is.EqualTo(expected).Within(1e-14));
}
[TestCase(1.0, 0.0, 0.0)]
[TestCase(1.0, 0.24817036595415071751, 0.1)]
[TestCase(1.0, 0.68268949213708589717, 1.0)]
[TestCase(1.0, 0.98098352632769945624, 5.5)]
[TestCase(1.0, 1.0, Double.PositiveInfinity)]
[TestCase(2.0, 0.0, 0.0)]
[TestCase(2.0, 0.048770575499285990909, 0.1)]
[TestCase(2.0, 0.39346934028736657640, 1.0)]
[TestCase(2.0, 0.93607213879329242730, 5.5)]
[TestCase(2.0, 1.0, Double.PositiveInfinity)]
[TestCase(2.5, 0.0, 0.0)]
[TestCase(2.5, 0.020298266579604156571, 0.1)]
[TestCase(2.5, 0.28378995266531297417, 1.0)]
[TestCase(2.5, 0.90239512593899828629, 5.5)]
[TestCase(2.5, 1.0, Double.PositiveInfinity)]
[TestCase(10000.0, 0.0, 0.0)]
[TestCase(10000.0, 0.5, 9999.3333412343982)]
[TestCase(20000.0, 0.0, 0.0)]
[TestCase(100000, 0.1, 99427.302671875732)]
public void ValidateInverseCumulativeDistribution(double dof, double x, double expected)
{
var n = new ChiSquared(dof);
Assert.That(n.InverseCumulativeDistribution(x), Is.EqualTo(expected).Within(1e-14));
Assert.That(ChiSquared.InvCDF(dof, x), Is.EqualTo(expected).Within(1e-14));
}
}
}

Loading…
Cancel
Save