示例#1
0
        /// <summary>
        /// Returns the Laczos approximation of Γ(z)
        /// </summary>
        public static double Tgamma(double x)
        {
            Debug.Assert(x > 0);

            // check for large x to avoid potential Inf/Inf below
            if (x > DoubleLimits.MaxGamma + 1)
            {
                return(double.PositiveInfinity);
            }

            // use the Lanczos approximation
            double xgh    = x + (Lanczos.G - 0.5);
            double result = Lanczos.Series(x);

            if (x > MaxPowerTermX)
            {
                // we're going to overflow unless this is done with care:
                double hp = Math.Pow(xgh, (x / 2) - 0.25);
                result *= (hp / Math.Exp(xgh));
                result *= hp;
            }
            else
            {
                result *= (Math.Pow(xgh, x - 0.5) / Math.Exp(xgh));
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Returns Γ(z)/Γ(z+delta) using the Lanczos approximation
        /// </summary>
        public static double TgammaDeltaRatio(double x, double delta)
        {
            Debug.Assert(x > 0 && delta + x > 0);

            // Compute Γ(x)/Γ(x+Δ), which reduces to:
            //
            // ((x+g-0.5)/(x+Δ+g-0.5))^(x-0.5) * (x+Δ+g-0.5)^-Δ * e^Δ * (Sum(x)/Sum(x+Δ))
            // = (1+Δ/(x+g-0.5))^-(x-0.5) * (x+Δ+g-0.5)^-Δ * e^Δ * (Sum(x)/Sum(x+Δ))

            double xgh  = x + (Lanczos.G - 0.5);
            double xdgh = x + delta + (Lanczos.G - 0.5);

            double mu     = delta / xgh;
            double result = Lanczos.Series(x) / Lanczos.Series(x + delta);

            result *= (Math.Abs(mu) < 0.5) ? Math.Exp((0.5 - x) * Math2.Log1p(mu)) : Math.Pow(xgh / xdgh, x - 0.5);
            result *= Math.Pow(Math.E / xdgh, delta);

            return(result);
        }