public static double LogGamma(double v0) {
// Calculate the log of the Gamma function using the Lanczos approximation
if (double.IsInfinity(v0)) {
return double.PositiveInfinity;
}
double a = Math.Abs(v0);
// Gamma is undefined on non-positive integers
if (v0 <= 0.0 && a % 1.0 == 0.0) {
return double.NaN;
}
// lim(LGamma(v0)) = -log|v0| as v0 approaches 0.0
if (a < 1e-50) {
return -Math.Log(a);
}
double res;
if (v0 < 0.0) {
// For negative values, use the reflection formula:
// Gamma(x) = pi / sin(pi * x) / Gamma(1 - x)
// ==> LGamma(x) = log(pi / |sin(pi * x)|) - LGamma(1 - x)
res = Math.Log(Math.PI / AbsSinPi(v0));
res -= PositiveLGamma(1.0 - v0);
} else {
res = PositiveLGamma(v0);
}
return res;
}