/// <summary> /// Computes the Gamma function. /// </summary> /// <param name="x">The argument.</param> /// <returns>The value of Γ(x).</returns> /// <remarks> /// <para>The Gamma function is a generalization of the factorial (see <see cref="AdvancedIntegerMath.Factorial"/>) to arbitrary real values.</para> /// <img src="../images/GammaIntegral.png" /> /// <para>For positive integer arguments, this integral evaluates to Γ(n+1)=n!, but it can also be evaluated for non-integer z.</para> /// <para>Like the factorial, Γ(x) grows rapidly with increasing x; Γ(x) overflows <see cref="System.Double" /> /// for all x larger than ~171. For arguments in this range, you may find it useful to work with the <see cref="LogGamma" /> method, which /// returns accurate values for ln(Γ(x)) even in the range for which Γ(x) overflows.</para> /// <para>To evaluate the Gamma function for a complex argument, use <see cref="AdvancedComplexMath.Gamma" />.</para> /// <h2>Domain, Range, and Accuracy</h2> /// <para>The function is defined for all x. It has poles at all negative integers and at zero; the method returns <see cref="Double.NaN"/> for these arguments. For positive /// arguments, the value of the function increases rapidly with increasing argument. For values of x greater than about 170, the value of the function exceeds /// <see cref="Double.MaxValue"/>; for these arguments the method returns <see cref="Double.PositiveInfinity"/>. The method is accurate to full precision over its entire /// domain.</para> /// </remarks> /// <seealso cref="AdvancedIntegerMath.Factorial" /> /// <seealso cref="LogGamma" /> /// <seealso cref="AdvancedComplexMath.Gamma" /> /// <seealso href="http://en.wikipedia.org/wiki/Gamma_function" /> /// <seealso href="http://mathworld.wolfram.com/GammaFunction.html" /> /// <seealso href="http://dlmf.nist.gov/5">DLMF on the Gamma Function</seealso> public static double Gamma(double x) { if (x < 0.5) { // Use \Gamma(x) \Gamma(1-x) = \frac{\pi}{\sin(\pi x)} to move values close to and left of origin to x > 0 return(Math.PI / MoreMath.SinPi(x) / Gamma(1.0 - x)); } else if (x < 1.5) { return(GammaSeries.GammaOnePlus(x - 1.0)); } else if (x < 2.5) { return(GammaSeries.GammaTwoPlus(x - 2.0)); } else if (x < 16.0) { return(Lanczos.Gamma(x)); } else if (x < 172.0) { return(Stirling.Gamma(x)); } else if (x <= Double.PositiveInfinity) { // For x >~ 172, Gamma(x) overflows. return(Double.PositiveInfinity); } else { return(Double.NaN); } }
/// <summary> /// Computes the Gamma function. /// </summary> /// <param name="x">The argument.</param> /// <returns>The value of Γ(x).</returns> /// <remarks> /// <para>The Gamma function is a generalization of the factorial (see <see cref="AdvancedIntegerMath.Factorial"/>) to arbitrary real values.</para> /// <img src="../images/GammaIntegral.png" /> /// <para>For positive integer arguments, this integral evaluates to Γ(n+1)=n!, but it can also be evaluated for non-integer z.</para> /// <para>Because Γ(x) grows beyond the largest value that can be represented by a <see cref="System.Double" /> at quite /// moderate values of x, you may find it useful to work with the <see cref="LogGamma" /> method, which returns ln(Γ(x)).</para> /// <para>To evaluate the Gamma function for a complex argument, use <see cref="AdvancedComplexMath.Gamma" />.</para> /// <h2>Domain, Range, and Accuracy</h2> /// <para>The function is defined for all x. It has poles at all negative integers and at zero; the method returns <see cref="Double.NaN"/> for these arguments. For positive /// arguments, the value of the function increases rapidly with increasing argument. For values of x greater than about 170, the value of the function exceeds /// <see cref="Double.MaxValue"/>; for these arguments the method returns <see cref="Double.PositiveInfinity"/>. The method is accurate to full precision over its entire /// domain.</para> /// </remarks> /// <seealso cref="AdvancedIntegerMath.Factorial" /> /// <seealso cref="LogGamma" /> /// <seealso cref="AdvancedComplexMath.Gamma" /> /// <seealso href="http://en.wikipedia.org/wiki/Gamma_function" /> /// <seealso href="http://mathworld.wolfram.com/GammaFunction.html" /> /// <seealso href="http://dlmf.nist.gov/5">DLMF on the Gamma Function</seealso> public static double Gamma(double x) { if (x <= 0.0) { if (x == Math.Ceiling(x)) { // poles at zero and negative integers return(Double.NaN); } else { return(Math.PI / Gamma(-x) / (-x) / AdvancedMath.Sin(0.0, x / 2.0)); } } else if (x < 16.0) { return(Lanczos.Gamma(x)); } else { return(Stirling.Gamma(x)); //return (Math.Exp(LogGamma_Stirling(x))); } }