Browse Source

Distributions: more robust PDF and CDF, better unit tests (against known reference).

truncatednormal
Christoph Ruegg 11 years ago
parent
commit
4569f51ae7
  1. 26
      src/Numerics/Distributions/Chi.cs
  2. 50
      src/Numerics/Distributions/ChiSquared.cs
  3. 132
      src/UnitTests/DistributionTests/Continuous/ChiSquareTests.cs
  4. 183
      src/UnitTests/DistributionTests/Continuous/ChiTests.cs

26
src/Numerics/Distributions/Chi.cs

@ -207,7 +207,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDF"/>
public double Density(double x)
{
return (Math.Pow(2.0, 1.0 - (_freedom/2.0))*Math.Pow(x, _freedom - 1.0)*Math.Exp(-x*x/2.0))/SpecialFunctions.Gamma(_freedom/2.0);
return PDF(_freedom, x);
}
/// <summary>
@ -218,7 +218,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDFLn"/>
public double DensityLn(double x)
{
return ((1.0 - (_freedom/2.0))*Math.Log(2.0)) + ((_freedom - 1.0)*Math.Log(x)) - (x*x/2.0) - SpecialFunctions.GammaLn(_freedom/2.0);
return PDFLn(_freedom, x);
}
/// <summary>
@ -229,7 +229,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="CDF"/>
public double CumulativeDistribution(double x)
{
return SpecialFunctions.GammaLowerIncomplete(_freedom/2.0, x*x/2.0)/SpecialFunctions.Gamma(_freedom/2.0);
return CDF(_freedom, x);
}
/// <summary>
@ -317,6 +317,11 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException(Resources.InvalidDistributionParameters);
}
if (double.IsPositiveInfinity(freedom) || double.IsPositiveInfinity(x) || x == 0.0)
{
return 0.0;
}
if (freedom > 160.0)
{
return Math.Exp(PDFLn(freedom, x));
@ -339,6 +344,11 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException(Resources.InvalidDistributionParameters);
}
if (double.IsPositiveInfinity(freedom) || double.IsPositiveInfinity(x) || x == 0.0)
{
return double.NegativeInfinity;
}
return ((1.0 - (freedom/2.0))*Math.Log(2.0)) + ((freedom - 1.0)*Math.Log(x)) - (x*x/2.0) - SpecialFunctions.GammaLn(freedom/2.0);
}
@ -356,6 +366,16 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException(Resources.InvalidDistributionParameters);
}
if (double.IsPositiveInfinity(x))
{
return 1.0;
}
if (double.IsPositiveInfinity(freedom))
{
return 1.0;
}
return SpecialFunctions.GammaLowerRegularized(freedom/2.0, x*x/2.0);
}

50
src/Numerics/Distributions/ChiSquared.cs

@ -193,7 +193,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDF"/>
public double Density(double x)
{
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));
return PDF(_freedom, x);
}
/// <summary>
@ -204,7 +204,7 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="PDFLn"/>
public double DensityLn(double x)
{
return (-x/2.0) + (((_freedom/2.0) - 1.0)*Math.Log(x)) - ((_freedom/2.0)*Math.Log(2)) - SpecialFunctions.GammaLn(_freedom/2.0);
return PDFLn(_freedom, x);
}
/// <summary>
@ -215,7 +215,19 @@ namespace MathNet.Numerics.Distributions
/// <seealso cref="CDF"/>
public double CumulativeDistribution(double x)
{
return SpecialFunctions.GammaLowerRegularized(_freedom/2.0, x/2.0);
return CDF(_freedom, x);
}
/// <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>
@ -322,6 +334,11 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException(Resources.InvalidDistributionParameters);
}
if (double.IsPositiveInfinity(freedom) || double.IsPositiveInfinity(x) || x == 0.0)
{
return 0.0;
}
if (freedom > 160.0)
{
return Math.Exp(PDFLn(freedom, x));
@ -330,18 +347,6 @@ 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>
@ -356,6 +361,11 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException(Resources.InvalidDistributionParameters);
}
if (double.IsPositiveInfinity(freedom) || double.IsPositiveInfinity(x) || x == 0.0)
{
return double.NegativeInfinity;
}
return (-x/2.0) + (((freedom/2.0) - 1.0)*Math.Log(x)) - ((freedom/2.0)*Math.Log(2)) - SpecialFunctions.GammaLn(freedom/2.0);
}
@ -373,6 +383,16 @@ namespace MathNet.Numerics.Distributions
throw new ArgumentException(Resources.InvalidDistributionParameters);
}
if (double.IsPositiveInfinity(x))
{
return 1.0;
}
if (double.IsPositiveInfinity(freedom))
{
return 1.0;
}
return SpecialFunctions.GammaLowerRegularized(freedom/2.0, x/2.0);
}

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

@ -178,75 +178,71 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
/// <summary>
/// Validate density.
/// </summary>
/// <param name="dof">Degrees of freedom.</param>
/// <param name="x">Input X value.</param>
[TestCase(1.0, 0.0)]
[TestCase(1.0, 0.1)]
[TestCase(1.0, 1.0)]
[TestCase(1.0, 5.5)]
[TestCase(1.0, 110.1)]
[TestCase(1.0, Double.PositiveInfinity)]
[TestCase(2.0, 0.0)]
[TestCase(2.0, 0.1)]
[TestCase(2.0, 1.0)]
[TestCase(2.0, 5.5)]
[TestCase(2.0, 110.1)]
[TestCase(2.0, Double.PositiveInfinity)]
[TestCase(2.5, 0.0)]
[TestCase(2.5, 0.1)]
[TestCase(2.5, 1.0)]
[TestCase(2.5, 5.5)]
[TestCase(2.5, 110.1)]
[TestCase(2.5, Double.PositiveInfinity)]
[TestCase(Double.PositiveInfinity, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1)]
[TestCase(Double.PositiveInfinity, 1.0)]
[TestCase(Double.PositiveInfinity, 5.5)]
[TestCase(Double.PositiveInfinity, 110.1)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity)]
public void ValidateDensity(double dof, double x)
/// <remarks>Reference: N[PDF[ChiSquaredDistribution[dof],x],20]</remarks>
[TestCase(1.0, 0.0, 0.0)]
[TestCase(1.0, 0.1, 1.2000389484301359798)]
[TestCase(1.0, 1.0, 0.24197072451914334980)]
[TestCase(1.0, 5.5, 0.010874740337283141714)]
[TestCase(1.0, 110.1, 4.7000792147504127122e-26)]
[TestCase(1.0, Double.PositiveInfinity, 0.0)]
[TestCase(2.0, 0.0, 0.0)]
[TestCase(2.0, 0.1, 0.47561471225035700455)]
[TestCase(2.0, 1.0, 0.30326532985631671180)]
[TestCase(2.0, 5.5, 0.031963930603353786351)]
[TestCase(2.0, 110.1, 6.1810004550085248492e-25)]
[TestCase(2.0, Double.PositiveInfinity, 0.0)]
[TestCase(2.5, 0.0, 0.0)]
[TestCase(2.5, 0.1, 0.24812852712543073541)]
[TestCase(2.5, 1.0, 0.28134822576318228131)]
[TestCase(2.5, 5.5, 0.045412171451573920401)]
[TestCase(2.5, 110.1, 1.8574923023527248767e-24)]
[TestCase(2.5, Double.PositiveInfinity, 0.0)]
[TestCase(Double.PositiveInfinity, 0.0, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1, 0.0)]
[TestCase(Double.PositiveInfinity, 1.0, 0.0)]
[TestCase(Double.PositiveInfinity, 5.5, 0.0)]
[TestCase(Double.PositiveInfinity, 110.1, 0.0)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity, 0.0)]
public void ValidateDensity(double dof, double x, double expected)
{
var n = new ChiSquared(dof);
double expected = (Math.Pow(x, (dof / 2.0) - 1.0) * Math.Exp(-x / 2.0)) / (Math.Pow(2.0, dof / 2.0) * SpecialFunctions.Gamma(dof / 2.0));
Assert.AreEqual(expected, n.Density(x));
Assert.AreEqual(expected, ChiSquared.PDF(dof, x));
var chiSquared = new ChiSquared(dof);
Assert.That(chiSquared.Density(x), Is.EqualTo(expected).Within(13));
Assert.That(ChiSquared.PDF(dof, x), Is.EqualTo(expected).Within(13));
}
/// <summary>
/// Validate density log.
/// </summary>
/// <param name="dof">Degrees of freedom.</param>
/// <param name="x">Input X value.</param>
[TestCase(1.0, 0.0)]
[TestCase(1.0, 0.1)]
[TestCase(1.0, 1.0)]
[TestCase(1.0, 5.5)]
[TestCase(1.0, 110.1)]
[TestCase(1.0, Double.PositiveInfinity)]
[TestCase(2.0, 0.0)]
[TestCase(2.0, 0.1)]
[TestCase(2.0, 1.0)]
[TestCase(2.0, 5.5)]
[TestCase(2.0, 110.1)]
[TestCase(2.0, Double.PositiveInfinity)]
[TestCase(2.5, 0.0)]
[TestCase(2.5, 0.1)]
[TestCase(2.5, 1.0)]
[TestCase(2.5, 5.5)]
[TestCase(2.5, 110.1)]
[TestCase(2.5, Double.PositiveInfinity)]
[TestCase(Double.PositiveInfinity, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1)]
[TestCase(Double.PositiveInfinity, 1.0)]
[TestCase(Double.PositiveInfinity, 5.5)]
[TestCase(Double.PositiveInfinity, 110.1)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity)]
public void ValidateDensityLn(double dof, double x)
/// <remarks>Reference: N[Ln[PDF[ChiSquaredDistribution[dof],x]],20]</remarks>
[TestCase(1.0, 0.0, Double.NegativeInfinity)]
[TestCase(1.0, 0.1, 0.18235401329235010023)]
[TestCase(1.0, 1.0, -1.4189385332046727418)]
[TestCase(1.0, 5.5, -4.5213125793238853591)]
[TestCase(1.0, 110.1, -58.319633055068989881)]
[TestCase(1.0, Double.PositiveInfinity, Double.NegativeInfinity)]
[TestCase(2.0, 0.0, Double.NegativeInfinity)]
[TestCase(2.0, 0.1, -0.74314718055994530942)]
[TestCase(2.0, 1.0, -1.1931471805599453094)]
[TestCase(2.0, 5.5, -3.4431471805599453094)]
[TestCase(2.0, 110.1, -55.743147180559945309)]
[TestCase(2.0, Double.PositiveInfinity, Double.NegativeInfinity)]
[TestCase(2.5, 0.0, Double.NegativeInfinity)]
[TestCase(2.5, 0.1, -1.3938084125266298963)]
[TestCase(2.5, 1.0, -1.2681621392781184753)]
[TestCase(2.5, 5.5, -3.0919751162185121666)]
[TestCase(2.5, 110.1, -54.642814878345959906)]
[TestCase(2.5, Double.PositiveInfinity, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 0.0, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 0.1, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 1.0, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 5.5, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 110.1, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity, Double.NegativeInfinity)]
public void ValidateDensityLn(double dof, double x, double expected)
{
var n = new ChiSquared(dof);
double expected = (-x / 2.0) + (((dof / 2.0) - 1.0) * Math.Log(x)) - ((dof / 2.0) * Math.Log(2)) - SpecialFunctions.GammaLn(dof / 2.0);
Assert.AreEqual(expected, n.DensityLn(x));
Assert.AreEqual(expected, ChiSquared.PDFLn(dof, x));
var chiSquared = new ChiSquared(dof);
Assert.That(chiSquared.DensityLn(x), Is.EqualTo(expected).Within(13));
Assert.That(ChiSquared.PDFLn(dof, x), Is.EqualTo(expected).Within(13));
}
/// <summary>
@ -293,7 +289,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
/// </summary>
/// <param name="dof">Degrees of freedom.</param>
/// <param name="x">Input X value.</param>
/// <param name="expected">N[CDF[ChiSquare[dof], x],20]</param>
/// <param name="expected">N[CDF[ChiSquaredDistribution[dof],x],20]</param>
[TestCase(1.0, 0.0, 0.0)]
[TestCase(1.0, 0.1, 0.24817036595415071751)]
[TestCase(1.0, 1.0, 0.68268949213708589717)]
@ -314,11 +310,11 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
[TestCase(20000.0, 1.0, 0.0)]
public void ValidateCumulativeDistribution(double dof, double x, double expected)
{
var n = new ChiSquared(dof);
Assert.That(n.CumulativeDistribution(x), Is.EqualTo(expected).Within(1e-14));
var chiSquared = new ChiSquared(dof);
Assert.That(chiSquared.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)]
@ -340,8 +336,8 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
[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));
var chiSquared = new ChiSquared(dof);
Assert.That(chiSquared.InverseCumulativeDistribution(x), Is.EqualTo(expected).Within(1e-14));
Assert.That(ChiSquared.InvCDF(dof, x), Is.EqualTo(expected).Within(1e-14));
}
}

183
src/UnitTests/DistributionTests/Continuous/ChiTests.cs

@ -174,75 +174,71 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
/// <summary>
/// Validate density.
/// </summary>
/// <param name="dof">Degrees of freedom.</param>
/// <param name="x">Input X value.</param>
[TestCase(1.0, 0.0)]
[TestCase(1.0, 0.1)]
[TestCase(1.0, 1.0)]
[TestCase(1.0, 5.5)]
[TestCase(1.0, 110.1)]
[TestCase(1.0, Double.PositiveInfinity)]
[TestCase(2.0, 0.0)]
[TestCase(2.0, 0.1)]
[TestCase(2.0, 1.0)]
[TestCase(2.0, 5.5)]
[TestCase(2.0, 110.1)]
[TestCase(2.0, Double.PositiveInfinity)]
[TestCase(2.5, 0.0)]
[TestCase(2.5, 0.1)]
[TestCase(2.5, 1.0)]
[TestCase(2.5, 5.5)]
[TestCase(2.5, 110.1)]
[TestCase(2.5, Double.PositiveInfinity)]
[TestCase(Double.PositiveInfinity, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1)]
[TestCase(Double.PositiveInfinity, 1.0)]
[TestCase(Double.PositiveInfinity, 5.5)]
[TestCase(Double.PositiveInfinity, 110.1)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity)]
public void ValidateDensity(double dof, double x)
/// <remarks>Reference: N[PDF[ChiDistribution[dof],x],20]</remarks>
[TestCase(1.0, 0.0, 0.0)]
[TestCase(1.0, 0.1, 0.79390509495402353102)]
[TestCase(1.0, 1.0, 0.48394144903828669960)]
[TestCase(1.0, 5.5, 2.1539520085086552718e-7)]
[TestCase(1.0, 110.1, 4.3743524642224403027e-2633)]
[TestCase(1.0, Double.PositiveInfinity, 0.0)]
[TestCase(2.0, 0.0, 0.0)]
[TestCase(2.0, 0.1, 0.099501247919268231335)]
[TestCase(2.0, 1.0, 0.60653065971263342360)]
[TestCase(2.0, 5.5, 1.4847681768496578863e-6)]
[TestCase(2.0, 110.1, 6.0361640012969793703e-2631)]
[TestCase(2.0, Double.PositiveInfinity, 0.0)]
[TestCase(2.5, 0.0, 0.0)]
[TestCase(2.5, 0.1, 0.029191065334961657461)]
[TestCase(2.5, 1.0, 0.56269645152636456261)]
[TestCase(2.5, 5.5, 3.2304380188895211768e-6)]
[TestCase(2.5, 110.1, 5.8759231594821958799e-2630)]
[TestCase(2.5, Double.PositiveInfinity, 0.0)]
[TestCase(Double.PositiveInfinity, 0.0, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1, 0.0)]
[TestCase(Double.PositiveInfinity, 1.0, 0.0)]
[TestCase(Double.PositiveInfinity, 5.5, 0.0)]
[TestCase(Double.PositiveInfinity, 110.1, 0.0)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity, 0.0)]
public void ValidateDensity(double dof, double x, double expected)
{
var n = new Chi(dof);
double expected = (Math.Pow(2.0, 1.0 - (dof / 2.0)) * Math.Pow(x, dof - 1.0) * Math.Exp(-x * (x / 2.0))) / SpecialFunctions.Gamma(dof / 2.0);
Assert.AreEqual(expected, n.Density(x));
Assert.AreEqual(expected, Chi.PDF(dof, x));
var chi = new Chi(dof);
Assert.That(chi.Density(x), Is.EqualTo(expected).Within(13));
Assert.That(Chi.PDF(dof, x), Is.EqualTo(expected).Within(13));
}
/// <summary>
/// Validate density log.
/// </summary>
/// <param name="dof">Degrees of freedom.</param>
/// <param name="x">Input X value.</param>
[TestCase(1.0, 0.0)]
[TestCase(1.0, 0.1)]
[TestCase(1.0, 1.0)]
[TestCase(1.0, 5.5)]
[TestCase(1.0, 110.1)]
[TestCase(1.0, Double.PositiveInfinity)]
[TestCase(2.0, 0.0)]
[TestCase(2.0, 0.1)]
[TestCase(2.0, 1.0)]
[TestCase(2.0, 5.5)]
[TestCase(2.0, 110.1)]
[TestCase(2.0, Double.PositiveInfinity)]
[TestCase(2.5, 0.0)]
[TestCase(2.5, 0.1)]
[TestCase(2.5, 1.0)]
[TestCase(2.5, 5.5)]
[TestCase(2.5, 110.1)]
[TestCase(2.5, Double.PositiveInfinity)]
[TestCase(Double.PositiveInfinity, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1)]
[TestCase(Double.PositiveInfinity, 1.0)]
[TestCase(Double.PositiveInfinity, 5.5)]
[TestCase(Double.PositiveInfinity, 110.1)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity)]
public void ValidateDensityLn(double dof, double x)
/// <remarks>Reference: N[Ln[PDF[ChiDistribution[dof],x]],20]</remarks>
[TestCase(1.0, 0.0, Double.NegativeInfinity)]
[TestCase(1.0, 0.1, -0.23079135264472743236)]
[TestCase(1.0, 1.0, -0.72579135264472743236)]
[TestCase(1.0, 5.5, -15.350791352644727432)]
[TestCase(1.0, 110.1, -6061.2307913526447274)]
[TestCase(1.0, Double.PositiveInfinity, Double.NegativeInfinity)]
[TestCase(2.0, 0.0, Double.NegativeInfinity)]
[TestCase(2.0, 0.1, -2.3075850929940456840)]
[TestCase(2.0, 1.0, -0.5)]
[TestCase(2.0, 5.5, -13.420251907761574765)]
[TestCase(2.0, 110.1, -6056.3036109562713657)]
[TestCase(2.0, Double.PositiveInfinity, Double.NegativeInfinity)]
[TestCase(2.5, 0.0, Double.NegativeInfinity)]
[TestCase(2.5, 0.1, -3.5338925982092416919)]
[TestCase(2.5, 1.0, -0.57501495871817316589)]
[TestCase(2.5, 5.5, -12.642892820360535314)]
[TestCase(2.5, 110.1, -6054.0279313931252217)]
[TestCase(2.5, Double.PositiveInfinity, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 0.0, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 0.1, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 1.0, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 5.5, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, 110.1, Double.NegativeInfinity)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity, Double.NegativeInfinity)]
public void ValidateDensityLn(double dof, double x, double expected)
{
var n = new Chi(dof);
double expected = ((1.0 - (dof / 2.0)) * Math.Log(2.0)) + ((dof - 1.0) * Math.Log(x)) - (x * (x / 2.0)) - SpecialFunctions.GammaLn(dof / 2.0);
Assert.AreEqual(expected, n.DensityLn(x));
Assert.AreEqual(expected, Chi.PDFLn(dof, x));
var chi = new Chi(dof);
Assert.That(chi.DensityLn(x), Is.EqualTo(expected).Within(13));
Assert.That(Chi.PDFLn(dof, x), Is.EqualTo(expected).Within(13));
}
/// <summary>
@ -269,38 +265,39 @@ namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous
/// <summary>
/// Validate cumulative distribution.
/// </summary>
/// <param name="dof">Degrees of freedom.</param>
/// <param name="x">Input X value.</param>
[TestCase(1.0, 0.0)]
[TestCase(1.0, 0.1)]
[TestCase(1.0, 1.0)]
[TestCase(1.0, 5.5)]
[TestCase(1.0, 110.1)]
[TestCase(1.0, Double.PositiveInfinity)]
[TestCase(2.0, 0.0)]
[TestCase(2.0, 0.1)]
[TestCase(2.0, 1.0)]
[TestCase(2.0, 5.5)]
[TestCase(2.0, 110.1)]
[TestCase(2.0, Double.PositiveInfinity)]
[TestCase(2.5, 0.0)]
[TestCase(2.5, 0.1)]
[TestCase(2.5, 1.0)]
[TestCase(2.5, 5.5)]
[TestCase(2.5, 110.1)]
[TestCase(2.5, Double.PositiveInfinity)]
[TestCase(Double.PositiveInfinity, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1)]
[TestCase(Double.PositiveInfinity, 1.0)]
[TestCase(Double.PositiveInfinity, 5.5)]
[TestCase(Double.PositiveInfinity, 110.1)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity)]
public void ValidateCumulativeDistribution(double dof, double x)
/// <remarks>Reference: N[CDF[ChiDistribution[dof],x],20]</remarks>
[TestCase(1.0, 0.0, 0.0)]
[TestCase(1.0, 0.1, 0.079655674554057962931)]
[TestCase(1.0, 1.0, 0.68268949213708589717)]
[TestCase(1.0, 5.5, 0.99999996202087506822)]
[TestCase(1.0, 110.1, 1.0)]
[TestCase(1.0, Double.PositiveInfinity, 1.0)]
[TestCase(2.0, 0.0, 0.0)]
[TestCase(2.0, 0.1, 0.0049875208073176866474)]
[TestCase(2.0, 1.0, 0.39346934028736657640)]
[TestCase(2.0, 5.5, 0.99999973004214966370)]
[TestCase(2.0, 110.1, 1.0)]
[TestCase(2.0, Double.PositiveInfinity, 1.0)]
[TestCase(2.5, 0.0, 0.0)]
[TestCase(2.5, 0.1, 0.0011702413714030096290)]
[TestCase(2.5, 1.0, 0.28378995266531297417)]
[TestCase(2.5, 5.5, 0.99999940337322804750)]
[TestCase(2.5, 110.1, 1.0)]
[TestCase(2.5, Double.PositiveInfinity, 1.0)]
[TestCase(Double.PositiveInfinity, 0.0, 0.0)]
[TestCase(Double.PositiveInfinity, 0.1, 0.0)]
[TestCase(Double.PositiveInfinity, 1.0, 0.0)]
[TestCase(Double.PositiveInfinity, 5.5, 0.0)]
[TestCase(Double.PositiveInfinity, 110.1, 0.0)]
[TestCase(Double.PositiveInfinity, Double.PositiveInfinity, 1.0)]
public void ValidateCumulativeDistribution(double dof, double x, double expected)
{
var n = new Chi(dof);
double expected = SpecialFunctions.GammaLowerIncomplete(dof / 2.0, x * x / 2.0) / SpecialFunctions.Gamma(dof / 2.0);
Assert.AreEqual(expected, n.CumulativeDistribution(x));
Assert.AreEqual(expected, Chi.CDF(dof, x));
var chi = new Chi(dof);
Assert.That(chi.CumulativeDistribution(x), Is.EqualTo(expected).Within(13));
Assert.That(Chi.CDF(dof, x), Is.EqualTo(expected).Within(13));
//double expected = SpecialFunctions.GammaLowerIncomplete(dof / 2.0, x * x / 2.0) / SpecialFunctions.Gamma(dof / 2.0);
//Assert.AreEqual(expected, n.CumulativeDistribution(x));
//Assert.AreEqual(expected, Chi.CDF(dof, x));
}
}
}

Loading…
Cancel
Save