diff --git a/src/Numerics/Distributions/ChiSquared.cs b/src/Numerics/Distributions/ChiSquared.cs
index 90249767..5d7d64a7 100644
--- a/src/Numerics/Distributions/ChiSquared.cs
+++ b/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));
}
+ ///
+ /// 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.
+ ///
+ /// The location at which to compute the inverse cumulative density.
+ /// the inverse cumulative density at .
+ ///
+ public double InverseCumulativeDistribution(double p)
+ {
+ return InvCDF(_freedom, p);
+ }
+
///
/// Computes the log probability density of the distribution (lnPDF) at x, i.e. ln(∂P(X ≤ x)/∂x).
///
@@ -359,6 +371,23 @@ namespace MathNet.Numerics.Distributions
return SpecialFunctions.GammaLowerRegularized(freedom/2.0, x/2.0);
}
+ ///
+ /// 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.
+ ///
+ /// The degrees of freedom (k) of the distribution. Range: k > 0.
+ /// The location at which to compute the inverse cumulative density.
+ /// the inverse cumulative density at .
+ 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;
+ }
+
///
/// Generates a sample from the ChiSquare distribution.
///
diff --git a/src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs b/src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs
index 6bedc208..ccc2c614 100644
--- a/src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs
+++ b/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));
+ }
}
}