/// <summary> /// Returns the regularized gamma function Q(a, x) = 1 - P(a, x). /// The implementation of this method is based on: /// <list type="bullet"> /// <item> /// <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html"> /// Regularized Gamma Function</a>, equation (1). /// </item> /// <item> /// <a href="http://functions.wolfram.com/GammaBetaErf/GammaRegularized/10/0003/"> /// Regularized incomplete gamma function: Continued fraction representations /// (formula 06.08.10.0003)</a> /// </item> /// </list> /// </summary> /// <param name="a">the a parameter.</param> /// <param name="x">the value.</param> /// <param name="epsilon">When the absolute value of the nth item in the /// series is less than epsilon the approximation ceases to calculate /// further elements in the series.</param> /// <param name="maxIterations">Maximum number of "iterations" to complete.</param> /// <returns>the regularized gamma function P(a, x)</returns> /// <exception cref="MaxCountExceededException"> if the algorithm fails to converge. /// </exception> public static double regularizedGammaQ(double a, double x, double epsilon, int maxIterations) { double ret; if (Double.IsNaN(a) || Double.IsNaN(x) || (a <= 0.0) || (x < 0.0)) { ret = Double.NaN; } else if (x == 0.0) { ret = 1.0; } else if (x < a + 1.0) { // use regularizedGammaP because it should converge faster in this // case. ret = 1.0 - regularizedGammaP(a, x, epsilon, maxIterations); } else { // create continued fraction ContinuedFraction cf = new ContinuedFractionHelper(a); ret = 1.0 / cf.evaluate(x, epsilon, maxIterations); ret = FastMath.exp(-x + (a * FastMath.log(x)) - logGamma(a)) * ret; } return(ret); }
/// <summary> /// Returns the regularized beta function I(x, a, b).<para/> /// The implementation of this method is based on: /// <list type="bullet"> /// <item> /// <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html"> /// Regularized Beta Function</a>.</item> /// <item> /// <a href="http://functions.wolfram.com/06.21.10.0001.01"> /// Regularized Beta Function</a>.</item> /// </list> /// </summary> /// <param name="x">the value.</param> /// <param name="a">Parameter <c>a</c>.</param> /// <param name="b">Parameter <c>b</c>.</param> /// <param name="epsilon">When the absolute value of the nth item in the /// series is less than epsilon the approximation ceases to calculate /// further elements in the series.</param> /// <param name="maxIterations">Maximum number of "iterations" to complete.</param> /// <returns>the regularized beta function I(x, a, b)</returns> /// <exception cref="MaxCountExceededException"> /// if the algorithm fails to converge.</exception> public static double regularizedBeta(double x, double a, double b, double epsilon, int maxIterations) { double ret; if (Double.IsNaN(x) || Double.IsNaN(a) || Double.IsNaN(b) || x < 0 || x > 1 || a <= 0 || b <= 0) { ret = Double.NaN; } else if (x > (a + 1) / (2 + b + a) && 1 - x <= (b + 1) / (2 + b + a)) { ret = 1 - regularizedBeta(1 - x, b, a, epsilon, maxIterations); } else { ContinuedFraction fraction = new ContinuedFractionHelper(a, b); ret = FastMath.exp((a * FastMath.log(x)) + (b * FastMath.log1p(-x)) - FastMath.log(a) - logBeta(a, b)) * 1.0 / fraction.evaluate(x, epsilon, maxIterations); } return(ret); }