/// <summary> /// Calculates the specified Gamma function when <paramref name="a"/> is a half integer /// </summary> /// <param name="r"></param> /// <param name="a"></param> /// <param name="x"></param> /// <returns></returns> static double HalfIntegerA(Routine r, double a, double x) { Debug.Assert(a - Math.Floor(a) == 0.5); double sum = 0; if (a > 1) { sum = 1.0; double term = 1.0; for (int n = 2; n < a; ++n) { term *= x / (n - 0.5); sum += term; } } double result; double mult = 2.0 * Constants.RecipSqrtPI * Math.Sqrt(x); if (r == Routine.Q || r == Routine.Upper) { result = Math2.Erfc(Math.Sqrt(x)) + sum * mult * Math.Exp(-x); return((r == Routine.Q) ? result : result *Math2.Tgamma(a)); } else { result = Math2.Erf(Math.Sqrt(x)) - sum * mult * Math.Exp(-x); return((r == Routine.P) ? result : result *Math2.Tgamma(a)); } }
/// <summary> /// Asymptotic expansions of the incomplete gamma function P(a, x), /// used when a is large and x ~= a. /// </summary> /// <param name="a"></param> /// <param name="x"></param> /// <returns></returns> public static double GammaP(double a, double x) { double sigma = (x - a) / a; double phi = -Math2.Log1pmx(sigma); double y = a * phi; double z = Math.Sqrt(2 * phi); if (x < a) { z = -z; } double p = Polynomial.Eval(_C, z, 1 / a); double result = p * (Math.Exp(-y) * (Constants.RecipSqrt2PI / Math.Sqrt(a))); if (x < a) { result = -result; } result += Math2.Erfc(Math.Sqrt(y)) / 2; return(result); }