示例#1
0
        /// <summary>
        /// Upper incomplete gamma fraction
        /// <para>Γ(a,z) = (z^a * e^-z) * UpperFraction(a,z)</para>
        /// <para>Q(a,z) = (z^a * e^-z)/Γ(a) * UpperFraction(a,z)</para>
        /// </summary>
        /// <param name="a"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public static double UpperFraction(double a, double z)
        {
            double z0 = z - a + 1;
            int    k  = 0;
            Func <(double, double)> f = () => {
                k++;
                return(k * (a - k), z0 + 2 * k);
            };

            return(1.0 / ContinuedFraction.Eval(z0, f));
        }
示例#2
0
        /// <summary>
        /// Return En(x) using continued fractions:
        /// <para>En(x) = e^-x/(x + n + ContinuedFraction(-k * (k + n - 1), x + n + 2*k) k={1, ∞}</para>
        /// </summary>
        /// <param name="n"></param>
        /// <param name="x">Requires x &gt; 0</param>
        /// <returns></returns>
        /// <seealso href="http://functions.wolfram.com/GammaBetaErf/ExpIntegralE/10/0004/"/>
        public static double En_Fraction(int n, double x)
        {
            double b = n + x;
            double k = 0;
            Func <(double, double)> fracF = () => {
                ++k;
                return(-k * (k + n - 1), b + 2 * k);
            };

            double frac = ContinuedFraction.Eval(b, fracF);

            return(Math.Exp(-x) / frac);
        }
示例#3
0
        /// <summary>
        /// Evaluate the incomplete beta via the continued fraction representation
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="normalised"></param>
        /// <returns></returns>
        /// <remarks>
        /// Continued fraction for Ibeta- See: http://dlmf.nist.gov/8.17.E22
        /// Converges rapidly when x &lt; (a+1)/(a+b+2); for x &gt; (a+1)/(a+b+2) || 1-x &lt; (b+1)/(a+b+2), use I{1-x}(a, b)
        /// Continued fraction for the incomplete beta used when a &gt; 1 and b &gt; 1
        /// <para>According to NR this is O(sqrt(max(a,b))</para>
        /// </remarks>
        public static double Fraction2(double a, double b, double x, double y, bool normalised)
        {
            Debug.Assert(x <= a / (a + b) || y <= b / (a + b));

            double result = PowerTerms(a, b, x, y, normalised);

            if (result == 0)
            {
                return(result);
            }

            // Define the continued fraction function

            int m = 0;
            Func <(double an, double bn)> fracF = () => {
                double aN    = (a + m - 1) * (a + b + m - 1) * m * (b - m) * x * x;
                double denom = (a + 2 * m - 1);
                aN /= denom * denom;

                double bN = m;
                bN += (m * (b - m) * x) / (a + 2 * m - 1);
                bN += ((a + m) * (a - (a + b) * x + 1 + m * (2 - x))) / (a + 2 * m + 1);

                ++m;

                return(aN, bN);
            };


            var(_, b0) = fracF();  // get b0 - skip a0;
            double fract = ContinuedFraction.Eval(b0, fracF);

#if EXTRA_DEBUG
            double cvg = (a + 1) / (a + b + 2);
            Debug.WriteLine("CF B({0}, {1}, {2}): cvg = {3}; iterations = {4}", a, b, x, cvg, m);
#endif

            return(result / fract);
        }