/// Returns the regularized gamma function Q(a, x) = 1 - P(a, x). /// /// The implementation of this method is based on: /// <ul> /// <li> /// <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html"> /// Regularized Gamma Function</a>, equation (1). /// </li> /// <li> /// <a href="http://functions.wolfram.com/GammaBetaErf/GammaRegularized/10/0003/"> /// Regularized incomplete gamma function: Continued fraction representations /// (formula 06.08.10.0003)</a> /// </li> /// </ul> /// /// @param a the a parameter. /// @param x the value. /// @param 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 maxIterations Maximum number of "iterations" to complete. /// @return the regularized gamma function P(a, x) /// @throws MaxCountExceededException if the algorithm fails to converge. 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 GammaContinuedFraction(a); ret = 1.0 / cf.evaluate(x, epsilon, maxIterations); ret = Math.Exp(-x + (a * MathUtil.Log(x)) - logGamma(a)) * ret; } return(ret); }
public static double regularizedGammaQ(double a, double x, double epsilon, int maxIterations) { if (((double.IsNaN(a) || double.IsNaN(x)) || (a <= 0.0)) || (x < 0.0)) { return(double.NaN); } if (x == 0.0) { return(1.0); } if (x < (a + 1.0)) { return(1.0 - regularizedGammaP(a, x, epsilon, maxIterations)); } ContinuedFraction fraction = new GammaContinuedFraction(a); double num = 1.0 / fraction.evaluate(x, epsilon, maxIterations); return(Math.Exp((-x + (a * MathUtil.Log(x))) - logGamma(a)) * num); }
/// Returns the regularized gamma function Q(a, x) = 1 - P(a, x). /// /// The implementation of this method is based on: /// <ul> /// <li> /// <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html"> /// Regularized Gamma Function</a>, equation (1). /// </li> /// <li> /// <a href="http://functions.wolfram.com/GammaBetaErf/GammaRegularized/10/0003/"> /// Regularized incomplete gamma function: Continued fraction representations /// (formula 06.08.10.0003)</a> /// </li> /// </ul> /// /// @param a the a parameter. /// @param x the value. /// @param 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 maxIterations Maximum number of "iterations" to complete. /// @return the regularized gamma function P(a, x) /// @throws MaxCountExceededException if the algorithm fails to converge. 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 GammaContinuedFraction(a); ret = 1.0 / cf.evaluate(x, epsilon, maxIterations); ret = Math.Exp(-x + (a * MathUtil.Log(x)) - logGamma(a)) * ret; } return ret; }