public static function gammaLanczos($z)
{
// Basic integer/factorial cases
if ($z == 0) {
return \INF;
}
// Negative integer, or negative int as a float
if ((is_int($z) || is_numeric($z) && abs($z - round($z)) < 1.0E-5) && $z < 0) {
return -\INF;
}
// Positive integer, or postive int as a float (Ex: from beta(0.1, 0.9) since it will call Γ(x + y))
if ((is_int($z) || is_numeric($z) && abs($z - round($z)) < 1.0E-5) && $z > 0) {
return Combinatorics::factorial(round($z) - 1);
}
// p coefficients: g = 7, n = 9
$p = [0.9999999999998099, 676.5203681218851, -1259.1392167224028, 771.3234287776531, -176.6150291621406, 12.507343278686905, -0.13857109526572012, 9.984369578019572E-6, 1.5056327351493116E-7];
$g = 7;
$π = \M_PI;
/**
* Use reflection formula when z < 0.5
* π
* Γ(z) = -----------------
* sin πz * Γ(1 - z)
*/
if ($z < 0.5) {
$Γ⟮1 − z⟯ = self::gammaLanczos(1 - $z);
return $π / (sin($π * $z) * $Γ⟮1 − z⟯);
}
// Standard Lanczos formula when z ≥ 0.5
// Compute A(z)
$z--;
$A⟮z⟯ = $p[0];
for ($i = 1; $i < count($p); $i++) {
$A⟮z⟯ += $p[$i] / ($z + $i);
}
// Compute parts of equation
$√2π = sqrt(2 * $π);
$⟮z + g +½⟯ᶻ⁺½ = pow($z + $g + 0.5, $z + 0.5);
$ℯ^−⟮z + g +½⟯ = exp(-($z + $g + 0.5));
/**
* Put it all together:
* __ / 1 \ z+½
* √2π | z + g + - | e^-(z+g+½) A(z)
* \ 2 /
*/
return $√2π * $⟮z + g +½⟯ᶻ⁺½ * $ℯ^−⟮z + g +½⟯ * $A⟮z⟯;
}