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 @@
+