Пример #1
0
        /// <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));
            }
        }
Пример #2
0
            /// <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);
            }