From 59ff93f1b06b598b522d0eeaf2e1078b06dc8886 Mon Sep 17 00:00:00 2001 From: Jurgen Van Gael Date: Thu, 3 Sep 2009 05:07:13 +0800 Subject: [PATCH] Added incomplete Gamma functions. Added incomplete Beta functions. Signed-off-by: jvangael --- src/Numerics/Distributions/Continuous/Beta.cs | 82 +++- .../Distributions/Continuous/Gamma.cs | 6 +- src/Numerics/Numerics.csproj | 1 + src/Numerics/SpecialFunctions.cs | 235 +++++------ src/Numerics/SpecialFunctions/Gamma.cs | 386 ++++++++++++++++++ .../DistributionTests/Continuous/BetaTests.cs | 6 +- .../Continuous/GammaTests.cs | 4 +- .../SpecialFunctionsTests/GammaTests.cs | 157 +++++++ .../SpecialFunctionsTests.cs | 152 +++++-- src/UnitTests/UnitTests.csproj | 1 + 10 files changed, 858 insertions(+), 172 deletions(-) create mode 100644 src/Numerics/SpecialFunctions/Gamma.cs create mode 100644 src/UnitTests/SpecialFunctionsTests/GammaTests.cs diff --git a/src/Numerics/Distributions/Continuous/Beta.cs b/src/Numerics/Distributions/Continuous/Beta.cs index bd0653a4..69be2966 100644 --- a/src/Numerics/Distributions/Continuous/Beta.cs +++ b/src/Numerics/Distributions/Continuous/Beta.cs @@ -343,8 +343,7 @@ namespace MathNet.Numerics.Distributions { return 0.0; } - - if (Double.IsPositiveInfinity(_shapeA) && Double.IsPositiveInfinity(_shapeB)) + else if (Double.IsPositiveInfinity(_shapeA) && Double.IsPositiveInfinity(_shapeB)) { if (x == 0.5) { @@ -432,8 +431,7 @@ namespace MathNet.Numerics.Distributions { return Double.NegativeInfinity; } - - if (Double.IsPositiveInfinity(_shapeA) && Double.IsPositiveInfinity(_shapeB)) + else if (Double.IsPositiveInfinity(_shapeA) && Double.IsPositiveInfinity(_shapeB)) { if (x == 0.5) { @@ -519,7 +517,81 @@ namespace MathNet.Numerics.Distributions /// the cumulative density at . public double CumulativeDistribution(double x) { - return SpecialFunctions.BetaRegularized(_shapeA, _shapeB, x); + if (x < 0.0) + { + return 0.0; + } + else if (x >= 1.0) + { + return 1.0; + } + else if (Double.IsPositiveInfinity(_shapeA) && Double.IsPositiveInfinity(_shapeB)) + { + if (x < 0.5) + { + return 0.0; + } + else + { + return 1.0; + } + } + else if (Double.IsPositiveInfinity(_shapeA)) + { + if (x < 1.0) + { + return 0.0; + } + else + { + return 1.0; + } + } + else if (Double.IsPositiveInfinity(_shapeB)) + { + if (x >= 0.0) + { + return 1.0; + } + else + { + return 0.0; + } + } + else if (_shapeA == 0.0 && _shapeB == 0.0) + { + if (x >= 0.0 && x < 1.0) + { + return 0.5; + } + else + { + return 1.0; + } + } + else if (_shapeA == 0.0) + { + return 1.0; + } + else if (_shapeB == 0.0) + { + if (x >= 1.0) + { + return 1.0; + } + else + { + return 0.0; + } + } + else if (_shapeA == 1.0 && _shapeB == 1.0) + { + return x; + } + else + { + return SpecialFunctions.BetaRegularized(_shapeA, _shapeB, x); + } } /// diff --git a/src/Numerics/Distributions/Continuous/Gamma.cs b/src/Numerics/Distributions/Continuous/Gamma.cs index fa1f9171..d36788fb 100644 --- a/src/Numerics/Distributions/Continuous/Gamma.cs +++ b/src/Numerics/Distributions/Continuous/Gamma.cs @@ -462,9 +462,13 @@ namespace MathNet.Numerics.Distributions return 0.0; } } + else if (_shape == 0.0 && _invScale == 0.0) + { + return 0.0; + } else { - return SpecialFunctions.IncompleteGamma(_shape, x * _invScale, true); + return SpecialFunctions.GammaLowerRegularized(_shape, x * _invScale); } } diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 9869cd48..0270040b 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -118,6 +118,7 @@ + diff --git a/src/Numerics/SpecialFunctions.cs b/src/Numerics/SpecialFunctions.cs index 0e1ce812..e4f0b4d8 100644 --- a/src/Numerics/SpecialFunctions.cs +++ b/src/Numerics/SpecialFunctions.cs @@ -26,6 +26,11 @@ // OTHER DEALINGS IN THE SOFTWARE. // +// +// Cephes Math Library, Stephen L. Moshier +// ALGLIB, Sergey Bochkanov +// + namespace MathNet.Numerics { using System; @@ -37,35 +42,6 @@ namespace MathNet.Numerics /// public static partial class SpecialFunctions { - /// - /// The order of the approximation. - /// - private const int Gamma_n = 10; - - /// - /// Auxiliary variable when evaluating the function. - /// - private const double Gamma_r = 10.900511; - - /// - /// Polynomial coefficients for the approximation. - /// - private static readonly double[] Gamma_dk = - new[] - { - 2.48574089138753565546e-5, - 1.05142378581721974210, - -3.45687097222016235469, - 4.51227709466894823700, - -2.98285225323576655721, - 1.05639711577126713077, - -1.95428773191645869583e-1, - 1.70970543404441224307e-2, - -5.71926117404305781283e-4, - 4.63399473359905636708e-6, - -2.71994908488607703910e-9 - }; - /// /// Initializes static members of the SpecialFunctions class. /// @@ -87,8 +63,8 @@ namespace MathNet.Numerics /// /// Computes the logarithm of the Euler Beta function. /// - /// A positive real number. - /// A positive real number. + /// The first Beta parameter, a positive real number. + /// The second Beta parameter, a positive real number. /// The logarithm of the Euler Beta function evaluated at z,w. /// If or are not positive. public static double BetaLn(double z, double w) @@ -118,89 +94,6 @@ namespace MathNet.Numerics return System.Math.Exp(BetaLn(z, w)); } - /// - /// Computes the logarithm of the Gamma function. - /// - /// The argument of the gamma function. - /// The logarithm of the gamma function. - /// - /// This implementation of the computation of the gamma and logarithm of the gamma function follows the derivation in - /// "An Analysis Of The Lanczos Gamma Approximation", Glendon Ralph Pugh, 2004. - /// We use the implementation listed on p. 116 which achieves an accuracy of 16 floating point digits. Although 16 digit accuracy - /// should be sufficient for double values, improving accuracy is possible (see p. 126 in Pugh). - /// Our unit tests suggest that the accuracy of the Gamma function is correct up to 14 floating point digits. - /// - public static double GammaLn(double z) - { - if (z < 0.5) - { - double s = Gamma_dk[0]; - for (int i = 1; i <= Gamma_n; i++) - { - s += Gamma_dk[i] / (i - z); - } - - return Constants.LnPi - - Math.Log(Math.Sin(Math.PI * z)) - - Math.Log(s) - - Constants.LogTwoSqrtEOverPi - - ((0.5 - z) * Math.Log((0.5 - z + Gamma_r) / Math.E)); - } - else - { - double s = Gamma_dk[0]; - for (int i = 1; i <= Gamma_n; i++) - { - s += Gamma_dk[i] / (z + i - 1.0); - } - - return Math.Log(s) - + Constants.LogTwoSqrtEOverPi - + ((z - 0.5) * Math.Log((z - 0.5 + Gamma_r) / Math.E)); - } - } - - /// - /// Computes the Gamma function. - /// - /// The argument of the gamma function. - /// The logarithm of the gamma function. - /// - /// - /// This implementation of the computation of the gamma and logarithm of the gamma function follows the derivation in - /// "An Analysis Of The Lanczos Gamma Approximation", Glendon Ralph Pugh, 2004. - /// We use the implementation listed on p. 116 which should achieve an accuracy of 16 floating point digits. Although 16 digit accuracy - /// should be sufficient for double values, improving accuracy is possible (see p. 126 in Pugh). - /// - /// Our unit tests suggest that the accuracy of the Gamma function is correct up to 13 floating point digits. - /// - public static double Gamma(double z) - { - if (z < 0.5) - { - double s = Gamma_dk[0]; - for (int i = 1; i <= Gamma_n; i++) - { - s += Gamma_dk[i] / (i - z); - } - - return Math.PI / (Math.Sin(Math.PI * z) - * s - * Constants.TwoSqrtEOverPi - * Math.Pow((0.5 - z + Gamma_r) / Math.E, 0.5 - z)); - } - else - { - double s = Gamma_dk[0]; - for (int i = 1; i <= Gamma_n; i++) - { - s += Gamma_dk[i] / (z + i - 1.0); - } - - return s * Constants.TwoSqrtEOverPi * Math.Pow((z - 0.5 + Gamma_r) / Math.E, z - 0.5); - } - } - /// /// Computes the Digamma function which is mathematically defined as the derivative of the logarithm of the gamma function. /// This implementation is based on @@ -299,14 +192,122 @@ namespace MathNet.Numerics return x; } - public static double IncompleteGamma(double x, double z, bool reg) + /// + /// Returns the lower incomplete (unregularized) beta function + /// I_x(a,b) = int(t^(a-1)*(1-t)^(b-1),t=0..x) for real a > 0, b > 0, 1 >= x >= 0. + /// + /// The first Beta parameter, a positive real number. + /// The second Beta parameter, a positive real number. + /// The upper limit of the integral. + /// The lower incomplete (unregularized) beta function. + public static double BetaIncomplete(double a, double b, double x) { - throw new NotImplementedException(); + return BetaRegularized(a, b, x) * Beta(a, b); } + /// + /// Returns the regularized lower incomplete beta function + /// I_x(a,b) = 1/Beta(a,b) * int(t^(a-1)*(1-t)^(b-1),t=0..x) for real a > 0, b > 0, 1 >= x >= 0. + /// + /// The first Beta parameter, a positive real number. + /// The second Beta parameter, a positive real number. + /// The upper limit of the integral. + /// The regularized lower incomplete beta function. public static double BetaRegularized(double a, double b, double x) { - throw new NotImplementedException(); + if (a < 0.0 || b < 0.0) + { + throw new ArgumentOutOfRangeException("a,b", Properties.Resources.ArgumentNotNegative); + } + + if (x < 0.0 || x > 1.0) + { + throw new ArgumentOutOfRangeException("x", Properties.Resources.ArgumentInIntervalXYInclusive); + } + + double bt = (x == 0.0 || x == 1.0) + ? 0.0 + : Math.Exp(GammaLn(a + b) - GammaLn(a) - GammaLn(b) + (a * Math.Log(x)) + (b * Math.Log(1.0 - x))); + + bool symmetryTransformation = x >= (a + 1.0) / (a + b + 2.0); + + /* Continued fraction representation */ + + const int MaxIterations = 100; + double eps = Precision.DoubleMachinePrecision; + double fpmin = Precision.Increment(0.0) / eps; + + if (symmetryTransformation) + { + x = 1.0 - x; + double swap = a; + a = b; + b = swap; + } + + double qab = a + b; + double qap = a + 1.0; + double qam = a - 1.0; + double c = 1.0; + double d = 1.0 - (qab * x / qap); + + if (Math.Abs(d) < fpmin) + { + d = fpmin; + } + + d = 1.0 / d; + double h = d; + + for (int m = 1, m2 = 2; m <= MaxIterations; m++, m2 += 2) + { + double aa = m * (b - m) * x / ((qam + m2) * (a + m2)); + d = 1.0 + (aa * d); + + if (Math.Abs(d) < fpmin) + { + d = fpmin; + } + + c = 1.0 + (aa / c); + if (Math.Abs(c) < fpmin) + { + c = fpmin; + } + + d = 1.0 / d; + h *= d * c; + aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2)); + d = 1.0 + (aa * d); + + if (Math.Abs(d) < fpmin) + { + d = fpmin; + } + + c = 1.0 + (aa / c); + + if (Math.Abs(c) < fpmin) + { + c = fpmin; + } + + d = 1.0 / d; + double del = d * c; + h *= del; + + if (Math.Abs(del - 1.0) <= eps) + { + if (symmetryTransformation) + { + return 1.0 - (bt * h / a); + } + + return bt * h / a; + } + } + + throw new ArgumentException(Properties.Resources.ArgumentTooLargeForIterationLimit, "a,b"); } } } \ No newline at end of file diff --git a/src/Numerics/SpecialFunctions/Gamma.cs b/src/Numerics/SpecialFunctions/Gamma.cs new file mode 100644 index 00000000..6f19a5ad --- /dev/null +++ b/src/Numerics/SpecialFunctions/Gamma.cs @@ -0,0 +1,386 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Cephes Math Library, Stephen L. Moshier +// ALGLIB, Sergey Bochkanov +// + +namespace MathNet.Numerics +{ + using System; + using Properties; + + public static partial class SpecialFunctions + { + /// + /// The order of the approximation. + /// + private const int Gamma_n = 10; + + /// + /// Auxiliary variable when evaluating the function. + /// + private const double Gamma_r = 10.900511; + + /// + /// Polynomial coefficients for the approximation. + /// + private static readonly double[] Gamma_dk = + new[] + { + 2.48574089138753565546e-5, + 1.05142378581721974210, + -3.45687097222016235469, + 4.51227709466894823700, + -2.98285225323576655721, + 1.05639711577126713077, + -1.95428773191645869583e-1, + 1.70970543404441224307e-2, + -5.71926117404305781283e-4, + 4.63399473359905636708e-6, + -2.71994908488607703910e-9 + }; + + /// + /// Computes the logarithm of the Gamma function. + /// + /// The argument of the gamma function. + /// The logarithm of the gamma function. + /// + /// This implementation of the computation of the gamma and logarithm of the gamma function follows the derivation in + /// "An Analysis Of The Lanczos Gamma Approximation", Glendon Ralph Pugh, 2004. + /// We use the implementation listed on p. 116 which achieves an accuracy of 16 floating point digits. Although 16 digit accuracy + /// should be sufficient for double values, improving accuracy is possible (see p. 126 in Pugh). + /// Our unit tests suggest that the accuracy of the Gamma function is correct up to 14 floating point digits. + /// + public static double GammaLn(double z) + { + if (z < 0.5) + { + double s = Gamma_dk[0]; + for (int i = 1; i <= Gamma_n; i++) + { + s += Gamma_dk[i] / (i - z); + } + + return Constants.LnPi + - Math.Log(Math.Sin(Math.PI * z)) + - Math.Log(s) + - Constants.LogTwoSqrtEOverPi + - ((0.5 - z) * Math.Log((0.5 - z + Gamma_r) / Math.E)); + } + else + { + double s = Gamma_dk[0]; + for (int i = 1; i <= Gamma_n; i++) + { + s += Gamma_dk[i] / (z + i - 1.0); + } + + return Math.Log(s) + + Constants.LogTwoSqrtEOverPi + + ((z - 0.5) * Math.Log((z - 0.5 + Gamma_r) / Math.E)); + } + } + + /// + /// Computes the Gamma function. + /// + /// The argument of the gamma function. + /// The logarithm of the gamma function. + /// + /// + /// This implementation of the computation of the gamma and logarithm of the gamma function follows the derivation in + /// "An Analysis Of The Lanczos Gamma Approximation", Glendon Ralph Pugh, 2004. + /// We use the implementation listed on p. 116 which should achieve an accuracy of 16 floating point digits. Although 16 digit accuracy + /// should be sufficient for double values, improving accuracy is possible (see p. 126 in Pugh). + /// + /// Our unit tests suggest that the accuracy of the Gamma function is correct up to 13 floating point digits. + /// + public static double Gamma(double z) + { + if (z < 0.5) + { + double s = Gamma_dk[0]; + for (int i = 1; i <= Gamma_n; i++) + { + s += Gamma_dk[i] / (i - z); + } + + return Math.PI / (Math.Sin(Math.PI * z) + * s + * Constants.TwoSqrtEOverPi + * Math.Pow((0.5 - z + Gamma_r) / Math.E, 0.5 - z)); + } + else + { + double s = Gamma_dk[0]; + for (int i = 1; i <= Gamma_n; i++) + { + s += Gamma_dk[i] / (z + i - 1.0); + } + + return s * Constants.TwoSqrtEOverPi * Math.Pow((z - 0.5 + Gamma_r) / Math.E, z - 0.5); + } + } + + /// + /// Returns the upper incomplete regularized gamma function + /// Q(a,x) = 1/Gamma(a) * int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0. + /// + /// The argument for the gamma function. + /// The lower integral limit. + /// The upper incomplete regularized gamma function. + public static double GammaUpperRegularized(double a, double x) + { + double result = 0; + double igammaepsilon = 0; + double igammabignumber = 0; + double igammabignumberinv = 0; + double ans = 0; + double ax = 0; + double c = 0; + double yc = 0; + double r = 0; + double t = 0; + double y = 0; + double z = 0; + double pk = 0; + double pkm1 = 0; + double pkm2 = 0; + double qk = 0; + double qkm1 = 0; + double qkm2 = 0; + + igammaepsilon = 0.000000000000001; + igammabignumber = 4503599627370496.0; + igammabignumberinv = 2.22044604925031308085 * 0.0000000000000001; + if (x <= 0 | a <= 0) + { + result = 1; + return result; + } + + if (x < 1 | x < a) + { + result = 1 - GammaLowerRegularized(a, x); + return result; + } + + ax = a * Math.Log(x) - x - GammaLn(a); + if (ax < -709.78271289338399) + { + result = 0; + return result; + } + + ax = Math.Exp(ax); + y = 1 - a; + z = x + y + 1; + c = 0; + pkm2 = 1; + qkm2 = x; + pkm1 = x + 1; + qkm1 = z * x; + ans = pkm1 / qkm1; + do + { + c = c + 1; + y = y + 1; + z = z + 2; + yc = y * c; + pk = pkm1 * z - pkm2 * yc; + qk = qkm1 * z - qkm2 * yc; + if (qk != 0) + { + r = pk / qk; + t = Math.Abs((ans - r) / r); + ans = r; + } + else + { + t = 1; + } + + pkm2 = pkm1; + pkm1 = pk; + qkm2 = qkm1; + qkm1 = qk; + + if (Math.Abs(pk) > igammabignumber) + { + pkm2 = pkm2 * igammabignumberinv; + pkm1 = pkm1 * igammabignumberinv; + qkm2 = qkm2 * igammabignumberinv; + qkm1 = qkm1 * igammabignumberinv; + } + } + while (t > igammaepsilon); + + result = ans * ax; + + return result; + } + + /// + /// Returns the upper incomplete gamma function + /// Gamma(a,x) = 1/Gamma(a) * int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0. + /// + /// The argument for the gamma function. + /// The lower integral limit. + /// The upper incomplete gamma function. + public static double GammaUpperIncomplete(double a, double x) + { + return GammaUpperRegularized(a, x) * Gamma(a); + } + + /// + /// Returns the lower incomplete gamma function + /// gamma(a,x) = int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0. + /// + /// The argument for the gamma function. + /// The upper integral limit. + /// The lower incomplete gamma function. + public static double GammaLowerIncomplete(double a, double x) + { + return GammaLowerRegularized(a, x) * Gamma(a); + } + + /// + /// Returns the lower incomplete regularized gamma function + /// P(a,x) = 1/Gamma(a) * int(exp(-t)t^(a-1),t=0..x) for real a > 0, x > 0. + /// + /// The argument for the gamma function. + /// The upper integral limit. + /// The lower incomplete gamma function. + public static double GammaLowerRegularized(double a, double x) + { + const double Epsilon = 0.000000000000001; + const double BigNumber = 4503599627370496.0; + const double BigNumberInverse = 2.22044604925031308085e-16; + + if (a < 0d || x < 0d) + { + throw new ArgumentOutOfRangeException("a,x", Properties.Resources.ArgumentNotNegative); + } + + if (Precision.AlmostZero(a)) + { + if (Precision.AlmostZero(x)) + { + // either 0 or 1, depending on the limit direction + return Double.NaN; + } + + return 1d; + } + + if (Precision.AlmostZero(x)) + { + return 0d; + } + + double ax = (a * Math.Log(x)) - x - SpecialFunctions.GammaLn(a); + if (ax < -709.78271289338399) + { + return 1d; + } + + if (x <= 1 || x <= a) + { + double r2 = a; + double c2 = 1; + double ans2 = 1; + + do + { + r2 = r2 + 1; + c2 = c2 * x / r2; + ans2 += c2; + } + while ((c2 / ans2) > Epsilon); + + return Math.Exp(ax) * ans2 / a; + } + + int c = 0; + double y = 1 - a; + double z = x + y + 1; + + double p3 = 1; + double q3 = x; + double p2 = x + 1; + double q2 = z * x; + double ans = p2 / q2; + + double error = 0; + + do + { + c++; + y += 1; + z += 2; + double yc = y * c; + + double p = (p2 * z) - (p3 * yc); + double q = (q2 * z) - (q3 * yc); + + if (q != 0) + { + double nextans = p / q; + error = Math.Abs((ans - nextans) / nextans); + ans = nextans; + } + else + { + // zero div, skip + error = 1; + } + + // shift + p3 = p2; + p2 = p; + q3 = q2; + q2 = q; + + // normalize fraction when the numerator becomes large + if (Math.Abs(p) > BigNumber) + { + p3 *= BigNumberInverse; + p2 *= BigNumberInverse; + q3 *= BigNumberInverse; + q2 *= BigNumberInverse; + } + } + while (error > Epsilon); + + return 1d - (Math.Exp(ax) * ans); + } + } +} \ No newline at end of file diff --git a/src/UnitTests/DistributionTests/Continuous/BetaTests.cs b/src/UnitTests/DistributionTests/Continuous/BetaTests.cs index 39ce90b3..b6585b0d 100644 --- a/src/UnitTests/DistributionTests/Continuous/BetaTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/BetaTests.cs @@ -342,7 +342,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests AssertHelpers.AlmostEqual(pdfln, n.DensityLn(x), 14); } - [Test, Ignore("Depending on Special Functions")] + [Test] [Row(0.0, 0.0, 0.0, 0.5)] [Row(0.0, 0.0, 0.5, 0.5)] [Row(0.0, 0.0, 1.0, 1.0)] @@ -356,7 +356,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests [Row(1.0, 1.0, 0.5, 0.5)] [Row(1.0, 1.0, 1.0, 1.0)] [Row(9.0, 1.0, 0.0, 0.0)] - [Row(9.0, 1.0, 0.5, 0.00195313)] + [Row(9.0, 1.0, 0.5, 0.001953125)] [Row(9.0, 1.0, 1.0, 1.0)] [Row(5.0, 100.0, 0.0, 0.0)] [Row(5.0, 100.0, 0.5, 1.0)] @@ -376,7 +376,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests public void ValidateCumulativeDistribution(double a, double b, double x, double cdf) { var n = new Beta(a, b); - AssertHelpers.AlmostEqual(cdf, n.CumulativeDistribution(x), 15); + AssertHelpers.AlmostEqual(cdf, n.CumulativeDistribution(x), 13); } } } diff --git a/src/UnitTests/DistributionTests/Continuous/GammaTests.cs b/src/UnitTests/DistributionTests/Continuous/GammaTests.cs index 5911ce32..bbde1ce9 100644 --- a/src/UnitTests/DistributionTests/Continuous/GammaTests.cs +++ b/src/UnitTests/DistributionTests/Continuous/GammaTests.cs @@ -365,7 +365,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests var e = ied.Take(5).ToArray(); } - [Test, Ignore("Depending on Special Functions")] + [Test] [Row(0.0, 0.0, 0.0, 0.0)] [Row(0.0, 0.0, 1.0, 0.0)] [Row(0.0, 0.0, 10.0, 0.0)] @@ -387,7 +387,7 @@ namespace MathNet.Numerics.UnitTests.DistributionTests public void ValidateCumulativeDistribution(double shape, double invScale, double x, double cdf) { var n = new Gamma(shape, invScale); - AssertHelpers.AlmostEqual(cdf, n.CumulativeDistribution(x), 15); + AssertHelpers.AlmostEqual(cdf, n.CumulativeDistribution(x), 14); } } } diff --git a/src/UnitTests/SpecialFunctionsTests/GammaTests.cs b/src/UnitTests/SpecialFunctionsTests/GammaTests.cs new file mode 100644 index 00000000..419d5dc8 --- /dev/null +++ b/src/UnitTests/SpecialFunctionsTests/GammaTests.cs @@ -0,0 +1,157 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests +{ + using System; + using MbUnit.Framework; + using MathNet.Numerics; + + class GammaTests + { + [Test] + [Row(Double.NaN, Double.NaN)] + [Row(0.1, 2.2527126517342059020062379568954763844479865649307379)] + [Row(1.0, 0.0)] + [Row(1.5, -0.12078223763524522234551844578164721225185272790259947)] + [Row(Constants.Pi / 2, -0.11590380084550241329912089415904874214542604767006895)] + [Row(2.0, 0.0)] + [Row(2.5, 0.28468287047291915963249466968270192432013769555989498)] + [Row(3.0, 0.693147180559945309417232121458176568075500134360255)] + [Row(Constants.Pi, 0.82769459232343710152957855845235995115350173412073715)] + [Row(3.5, 1.2009736023470742248160218814507129957702389154681574)] + [Row(4.0, 1.7917594692280550008124773583807022727229906921830034)] + [Row(4.5, 2.4537365708424422205041425034357161573318235106897606)] + [Row(5.0, 3.1780538303479456196469416012970554088739909609035161)] + [Row(5.5, 3.9578139676187162938774008558225909985513044919750065)] + [Row(10.1, 13.02752673863323715481371189614224148681183971709386)] + public void GammaLn(double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.GammaLn(x), 14); + } + + [Test] + [Row(Double.NaN, Double.NaN)] + [Row(-1.5, 2.3632718012073547030642233111215269103967326081631802)] + [Row(-0.5, -3.544907701811032054596334966682290365595098912244773)] + [Row(0.1, 9.5135076986687312858079798958252325009137161063903012)] + [Row(1.0, 1.0)] + [Row(1.5, 0.88622692545275801364908374167057259139877472806119326)] + [Row(Constants.Pi / 2, 0.89056089038153932801065963535912100593354196288475879)] + [Row(2.0, 1.0)] + [Row(2.5, 1.3293403881791370204736256125058588870981620920917912)] + [Row(3.0, 2.0)] + [Row(Constants.Pi, 2.2880377953400324179595889090602339228896881533562229)] + [Row(3.5, 3.3233509704478425511840640312646472177454052302294767)] + [Row(4.0, 6.0)] + [Row(4.5, 11.631728396567448929144224109426265262108918305803166)] + [Row(5.0, 24.0)] + [Row(5.5, 52.342777784553520181149008492418193679490132376114268)] + [Row(10.1, 454760.75144158558537612486797710217749925965322893332)] + public void Gamma(double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.Gamma(x), 13); + } + + [Test] + [Row(double.NaN, Double.NaN, Double.NaN)] + [Row(0.1, 1.0, 0.97587265627367222115949155252812057714751052498477013)] + [Row(0.1, 2.0, 0.99432617602018847196075251078067514034772764693462125)] + [Row(0.1, 8.0, 0.99999507519205198048686442150578226823401842046310854)] + [Row(1.5, 1.0, 0.42759329552912016600095238564127189392715996802703368)] + [Row(1.5, 2.0, 0.73853587005088937779717792402407879809718939080920993)] + [Row(1.5, 8.0, 0.99886601571021467734329986257903021041757398191304284)] + [Row(2.5, 1.0, 0.15085496391539036377410688601371365034788861473418704)] + [Row(2.5, 2.0, 0.45058404864721976739416885516693969548484517509263197)] + [Row(2.5, 8.0, 0.99315592607757956900093935107222761316136944145439676)] + [Row(5.5, 1.0, 0.0015041182825838038421585211353488839717739161316985392)] + [Row(5.5, 2.0, 0.030082976121226050615171484772387355162056796585883967)] + [Row(5.5, 8.0, 0.85886911973294184646060071855669224657735916933487681)] + public void GammaLowerRegularized(double a, double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.GammaLowerRegularized(a, x), 14); + } + + [Test] + [Row(double.NaN, Double.NaN, Double.NaN)] + [Row(0.1, 1.0, 9.2839720283798852469443229940217320532607158711056334)] + [Row(0.1, 2.0, 9.4595297305559030536119885480983751098528458886962883)] + [Row(0.1, 8.0, 9.5134608464704033372127589212547718314010339263844976)] + [Row(1.5, 1.0, 0.37894469164098470380394366597039213790868855578083847)] + [Row(1.5, 2.0, 0.65451037345177732033319477475056262302270310457635612)] + [Row(1.5, 8.0, 0.88522195804210983776635107858848816480298923071075222)] + [Row(2.5, 1.0, 0.20053759629003473411039172879412733941722170263949)] + [Row(2.5, 2.0, 0.59897957413602228465664030130712917348327070206302442)] + [Row(2.5, 8.0, 1.3202422842943799358198434659248530581833764879301293)] + [Row(5.5, 1.0, 0.078729729026968321691794205337720556329618007004848672)] + [Row(5.5, 2.0, 1.5746265342113649473739798668921124454837064926448459)] + [Row(5.5, 8.0, 44.955595480196465884619737757794960132425035578313584)] + public void GammaLowerIncomplete(double a, double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.GammaLowerIncomplete(a, x), 14); + } + + [Test] + [Row(double.NaN, Double.NaN, Double.NaN)] + [Row(0.100000, 1.000000, 0.024127343726327778840508447471879422852489475015229)] + [Row(0.100000, 2.000000, 0.0056738239798115280392474892193248596522723530653781)] + [Row(0.100000, 8.000000, 0.0000049248079480195131355784942177317659815795368919702)] + [Row(1.500000, 1.000000, 0.57240670447087983399904761435872810607284003197297)] + [Row(1.500000, 2.000000, 0.26146412994911062220282207597592120190281060919079)] + [Row(1.500000, 8.000000, 0.0011339842897853226567001374209697895824260180869567)] + [Row(2.500000, 1.000000, 0.84914503608460963622589311398628634965211138526581)] + [Row(2.500000, 2.000000, 0.54941595135278023260583114483306030451515482490737)] + [Row(2.500000, 8.000000, 0.0068440739224204309990606489277723868386305585456026)] + [Row(5.500000, 1.000000, 0.9984958817174161961578414788646511160282260838683)] + [Row(5.500000, 2.000000, 0.96991702387877394938482851522761264483794320341412)] + [Row(5.500000, 8.000000, 0.14113088026705815353939928144330775342264083066512)] + public void GammaUpperRegularized(double a, double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.GammaUpperRegularized(a, x), 14); + } + + [Test] + [Row(double.NaN, Double.NaN, Double.NaN)] + [Row(0.100000, 1.000000, 0.22953567028884603886365690180350044765300023528467)] + [Row(0.100000, 2.000000, 0.053977968112828232195991347726857391060870217694027)] + [Row(0.100000, 8.000000, 0.000046852198327948595220974570460669512682180005810156)] + [Row(1.500000, 1.000000, 0.50728223381177330984514007570018045349008617228036)] + [Row(1.500000, 2.000000, 0.23171655200098069331588896692000996837607162348484)] + [Row(1.500000, 8.000000, 0.0010049674106481758827326630820844265957854973504417)] + [Row(2.500000, 1.000000, 1.1288027918891022863632338837117315476809403894523)] + [Row(2.500000, 2.000000, 0.73036081404311473581698531119872971361489139002877)] + [Row(2.500000, 8.000000, 0.0090981038847570846537821465810058289147856041616617)] + [Row(5.500000, 1.000000, 52.264048055526551859457214287080473123160514369109)] + [Row(5.500000, 2.000000, 50.768151250342155233775028625526081234006425883469)] + [Row(5.500000, 8.000000, 7.3871823043570542965292707346232335470650967978006)] + public void GammaUpperIncomplete(double a, double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.GammaUpperIncomplete(a, x), 14); + } + } +} \ No newline at end of file diff --git a/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs b/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs index 3e0d1728..727f0a0a 100644 --- a/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs +++ b/src/UnitTests/SpecialFunctionsTests/SpecialFunctionsTests.cs @@ -34,50 +34,6 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests class SpecialFunctionsTests { - [Test] - [Row(Double.NaN, Double.NaN)] - [Row(0.1, 2.2527126517342059020062379568954763844479865649307379)] - [Row(1.0, 0.0)] - [Row(1.5, -0.12078223763524522234551844578164721225185272790259947)] - [Row(Constants.Pi / 2, -0.11590380084550241329912089415904874214542604767006895)] - [Row(2.0, 0.0)] - [Row(2.5, 0.28468287047291915963249466968270192432013769555989498)] - [Row(3.0, 0.693147180559945309417232121458176568075500134360255)] - [Row(Constants.Pi, 0.82769459232343710152957855845235995115350173412073715)] - [Row(3.5, 1.2009736023470742248160218814507129957702389154681574)] - [Row(4.0, 1.7917594692280550008124773583807022727229906921830034)] - [Row(4.5, 2.4537365708424422205041425034357161573318235106897606)] - [Row(5.0, 3.1780538303479456196469416012970554088739909609035161)] - [Row(5.5, 3.9578139676187162938774008558225909985513044919750065)] - [Row(10.1, 13.02752673863323715481371189614224148681183971709386)] - public void GammaLn(double x, double f) - { - AssertHelpers.AlmostEqual(f, SpecialFunctions.GammaLn(x), 14); - } - - [Test] - [Row(Double.NaN, Double.NaN)] - [Row(-1.5, 2.3632718012073547030642233111215269103967326081631802)] - [Row(-0.5, -3.544907701811032054596334966682290365595098912244773)] - [Row(0.1, 9.5135076986687312858079798958252325009137161063903012)] - [Row(1.0, 1.0)] - [Row(1.5, 0.88622692545275801364908374167057259139877472806119326)] - [Row(Constants.Pi / 2, 0.89056089038153932801065963535912100593354196288475879)] - [Row(2.0, 1.0)] - [Row(2.5, 1.3293403881791370204736256125058588870981620920917912)] - [Row(3.0, 2.0)] - [Row(Constants.Pi, 2.2880377953400324179595889090602339228896881533562229)] - [Row(3.5, 3.3233509704478425511840640312646472177454052302294767)] - [Row(4.0, 6.0)] - [Row(4.5, 11.631728396567448929144224109426265262108918305803166)] - [Row(5.0, 24.0)] - [Row(5.5, 52.342777784553520181149008492418193679490132376114268)] - [Row(10.1, 454760.75144158558537612486797710217749925965322893332)] - public void Gamma(double x, double f) - { - AssertHelpers.AlmostEqual(f, SpecialFunctions.Gamma(x), 13); - } - [Test] [Row(Double.NaN, Double.NaN)] [Row(-1.5, 0.70315664064524318722569033366791109947350706200623256)] @@ -166,5 +122,113 @@ namespace MathNet.Numerics.UnitTests.SpecialFunctionsTests AssertHelpers.AlmostEqual(0.5, SpecialFunctions.Beta(1.0, 2.0), 14); AssertHelpers.AlmostEqual(1.0, SpecialFunctions.Beta(1.0, 1.0), 14); } + + [Test] + [Row(0.100000, 0.100000, 0.100000, 8.0117356206774655704238957309013421730449536344797)] + [Row(0.100000, 0.100000, 0.500000, 9.8573197445250802696495512442154091185464210677262)] + [Row(0.100000, 0.100000, 0.800000, 11.045931323774722512127911008108711428206559153167)] + [Row(0.100000, 1.500000, 0.100000, 7.906686887040059574762793470136627722332467302241)] + [Row(0.100000, 1.500000, 0.500000, 9.1012542128394916083902345366778109992938115490192)] + [Row(0.100000, 1.500000, 0.800000, 9.368806890135865087467208304972858639790010273545)] + [Row(0.100000, 2.500000, 0.100000, 7.8363997919172974609110616787835466667385876309684)] + [Row(0.100000, 2.500000, 0.500000, 8.7385989355952880797816267602947881842609716646237)] + [Row(0.100000, 2.500000, 0.800000, 8.8379245631995373736838511405978394101548418300997)] + [Row(0.100000, 5.500000, 0.100000, 7.6464829466025722609741358285691936422732595850987)] + [Row(0.100000, 5.500000, 0.500000, 8.0832162883698521112308593494639236817925940654185)] + [Row(0.100000, 5.500000, 0.800000, 8.089843275520988350320569916795581670946930566783)] + [Row(1.500000, 0.100000, 0.100000, 0.022303834332028031481145155068151014763064226606192)] + [Row(1.500000, 0.100000, 0.500000, 0.33465159984030260689318592198561677643426763544959)] + [Row(1.500000, 0.100000, 0.800000, 1.002080089012839104050394134134167486035896540574)] + [Row(1.500000, 1.500000, 0.100000, 0.02043763859916055001568569052740016093388906615616)] + [Row(1.500000, 1.500000, 0.500000, 0.19634954084936207740391521145496893026232308746094)] + [Row(1.500000, 1.500000, 0.800000, 0.33678717944852264351783475904713816723851995610486)] + [Row(1.500000, 2.500000, 0.100000, 0.019218819299580275673976660038794008316192763455412)] + [Row(1.500000, 2.500000, 0.500000, 0.13984143709134770536862427239415113179782821039714)] + [Row(1.500000, 2.500000, 0.800000, 0.18972692305759464976318019465615085035583828745353)] + [Row(1.500000, 5.500000, 0.100000, 0.016056550082674778556355475820652277420877772570937)] + [Row(1.500000, 5.500000, 0.500000, 0.061380263212265132490746506045997506787829048203228)] + [Row(1.500000, 5.500000, 0.800000, 0.064403479961606576649564368278872635247235510624673)] + [Row(2.500000, 0.100000, 0.100000, 0.001352753157951915161848451666929681258878645850634)] + [Row(2.500000, 0.100000, 0.500000, 0.10756276379201896635529117527407904299772826375257)] + [Row(2.500000, 0.100000, 0.800000, 0.5587192957063609402827988523062144494394362102048)] + [Row(2.500000, 1.500000, 0.100000, 0.0012188192995802743417090304886061526176963027007477)] + [Row(2.500000, 1.500000, 0.500000, 0.056508103758014372035290939060817798464494877063805)] + [Row(2.500000, 1.500000, 0.800000, 0.14706025639092799375465456439098731688268166865133)] + [Row(2.500000, 2.500000, 0.100000, 0.0011320572373426029655709496224583878329664195067652)] + [Row(2.500000, 2.500000, 0.500000, 0.036815538909255389513234102147806674424185578898927)] + [Row(2.500000, 2.500000, 0.800000, 0.067947596146597995171095886486269312250373204235372)] + [Row(2.500000, 5.500000, 0.100000, 0.00091001787485888099434748885472859856478675247779447)] + [Row(2.500000, 5.500000, 0.500000, 0.012036842116913956962302822724142322883106224614977)] + [Row(2.500000, 5.500000, 0.800000, 0.0137861171346299807272679372975664758815098236357)] + [Row(5.500000, 0.100000, 0.100000, 0.00000062268687636453588281206442354375188797585844216401)] + [Row(5.500000, 0.100000, 0.500000, 0.0066577573700032687517874433540471831930305154614716)] + [Row(5.500000, 0.100000, 0.800000, 0.15893826959760073090597940189540380779121963557728)] + [Row(5.500000, 1.500000, 0.100000, 0.00000055008267477746389601958949824166456746390970113234)] + [Row(5.500000, 1.500000, 0.500000, 0.0030469298789317991574131727126641734544957148698945)] + [Row(5.500000, 1.500000, 0.800000, 0.029928813294939917230433606365228383142081556070117)] + [Row(5.500000, 2.500000, 0.100000, 0.00000050358914459517094905570885392504304689450166185919)] + [Row(5.500000, 2.500000, 0.500000, 0.0017689849740568141051599655812851800259633674721202)] + [Row(5.500000, 2.500000, 0.800000, 0.010158231420344267874007806875642686140428489302542)] + [Row(5.500000, 5.500000, 0.100000, 0.00000038687628134504851234251462244340434107233073666673)] + [Row(5.500000, 5.500000, 0.500000, 0.00037750308451873202137593561772653328266987165863158)] + [Row(5.500000, 5.500000, 0.800000, 0.00074361660080007708142054771607396897718180545812717)] + public void BetaIncomplete(double a, double b, double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.BetaIncomplete(a, b, x), 12); + } + + [Test] + [Row(0.100000, 0.100000, 0.100000, 0.40638509393627598963947434031370208398700911383034)] + [Row(0.100000, 0.100000, 0.500000, 0.5)] + [Row(0.100000, 0.100000, 0.800000, 0.56029080977665439586092261707431380702999082404228)] + [Row(0.100000, 1.500000, 0.100000, 0.83793618164513694339361766577607270440777026543289)] + [Row(0.100000, 1.500000, 0.500000, 0.96453423693668031005965611526662377555163072304903)] + [Row(0.100000, 1.500000, 0.800000, 0.99288897919542998751072045939791723468184549496473)] + [Row(0.100000, 2.500000, 0.100000, 0.88585310309894667823419197676046986281131524104959)] + [Row(0.100000, 2.500000, 0.500000, 0.98784074184406228317625751436240720987391458581291)] + [Row(0.100000, 2.500000, 0.800000, 0.99906884630106408932550166100889714490764416359312)] + [Row(0.100000, 5.500000, 0.100000, 0.94519184147610137383076366494492317664691771837548)] + [Row(0.100000, 5.500000, 0.500000, 0.99917702583101287494949180374093750006040749104055)] + [Row(0.100000, 5.500000, 0.800000, 0.99999619645266501604882303584892931538704382134298)] + [Row(1.500000, 0.100000, 0.100000, 0.0023637194748231330327322712604688049136736986021871)] + [Row(1.500000, 0.100000, 0.500000, 0.03546576306331968994034388473337622444836927695097)] + [Row(1.500000, 0.100000, 0.800000, 0.10619861080705813882414161079467267590245761692272)] + [Row(1.500000, 1.500000, 0.100000, 0.052044019330913933551809009997594089261007490064035)] + [Row(1.500000, 1.500000, 0.500000, 0.5)] + [Row(1.500000, 1.500000, 0.800000, 0.85762151006735301922188173009147886735366387396138)] + [Row(1.500000, 2.500000, 0.100000, 0.097880642941379793645839194076629344959184516635409)] + [Row(1.500000, 2.500000, 0.500000, 0.71220659078919378102517835116335248271261286098728)] + [Row(1.500000, 2.500000, 0.800000, 0.96627128455142020796603976406510565066301101575357)] + [Row(1.500000, 5.500000, 0.100000, 0.2492200779249636429835386068413815093625886315581)] + [Row(1.500000, 5.500000, 0.500000, 0.95270739368361339952038048248181862978690743677285)] + [Row(1.500000, 5.500000, 0.800000, 0.99963193911681378117173263163355516583213310848701)] + [Row(2.500000, 0.100000, 0.100000, 0.00015291978644767572330394885397661411972523657814463)] + [Row(2.500000, 0.100000, 0.500000, 0.012159258155937716823742485637592790126085414187091)] + [Row(2.500000, 0.100000, 0.800000, 0.063159516487818477363383984899205310365144861115492)] + [Row(2.500000, 1.500000, 0.100000, 0.006207395720448073457778825918558833562830463492662)] + [Row(2.500000, 1.500000, 0.500000, 0.28779340921080621897482164883664751728738713901272)] + [Row(2.500000, 1.500000, 0.800000, 0.74897173558328583047772369611785208404431673216919)] + [Row(2.500000, 2.500000, 0.100000, 0.015374720442541245985473611768528587536206924004576)] + [Row(2.500000, 2.500000, 0.500000, 0.5)] + [Row(2.500000, 2.500000, 0.800000, 0.92281137475779334211841505067903343661808086762039)] + [Row(2.500000, 5.500000, 0.100000, 0.065915491253258347344782598110283193803051483319306)] + [Row(2.500000, 5.500000, 0.500000, 0.87186678766868243532031253918149387446781682306342)] + [Row(2.500000, 5.500000, 0.800000, 0.99857234512565487924356478796968439529913692090276)] + [Row(5.500000, 0.100000, 0.100000, 0.000000076971146008440526509370378069895435149621047562911)] + [Row(5.500000, 0.100000, 0.500000, 0.00082297416898712505050819625906249993959250895944939)] + [Row(5.500000, 0.100000, 0.800000, 0.01964656911825443767408345737200950450690987324177)] + [Row(5.500000, 1.500000, 0.100000, 0.0000085380512231662773545327104780279605728164994539023)] + [Row(5.500000, 1.500000, 0.500000, 0.047292606316386600479619517518181370213092563227146)] + [Row(5.500000, 1.500000, 0.800000, 0.46453697358156781101222907948783656601193056166297)] + [Row(5.500000, 2.500000, 0.100000, 0.000036476564661926426853537763285519105619982887967225)] + [Row(5.500000, 2.500000, 0.500000, 0.12813321233131756467968746081850612553218317693658)] + [Row(5.500000, 2.500000, 0.800000, 0.73579303531824700577792236664278017906658620718916)] + [Row(5.500000, 5.500000, 0.100000, 0.00051241472879389331855418481833750204851457778933154)] + [Row(5.500000, 5.500000, 0.500000, 0.5)] + [Row(5.500000, 5.500000, 0.800000, 0.98491460241721309518021565227501009891015897915977)] + public void BetaRegularized(double a, double b, double x, double f) + { + AssertHelpers.AlmostEqual(f, SpecialFunctions.BetaRegularized(a,b,x), 12); + } } } \ No newline at end of file diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index 8534bd45..80ea3445 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -104,6 +104,7 @@ +