in samoa-api/src/main/java/org/apache/samoa/moa/core/Statistics.java [265:349]
public static double lnGamma(double x) {
double p, q, w, z;
double A[] = {
8.11614167470508450300E-4,
-5.95061904284301438324E-4,
7.93650340457716943945E-4,
-2.77777777730099687205E-3,
8.33333333333331927722E-2
};
double B[] = {
-1.37825152569120859100E3,
-3.88016315134637840924E4,
-3.31612992738871184744E5,
-1.16237097492762307383E6,
-1.72173700820839662146E6,
-8.53555664245765465627E5
};
double C[] = {
/* 1.00000000000000000000E0, */
-3.51815701436523470549E2,
-1.70642106651881159223E4,
-2.20528590553854454839E5,
-1.13933444367982507207E6,
-2.53252307177582951285E6,
-2.01889141433532773231E6
};
if (x < -34.0) {
q = -x;
w = lnGamma(q);
p = Math.floor(q);
if (p == q)
throw new ArithmeticException("lnGamma: Overflow");
z = q - p;
if (z > 0.5) {
p += 1.0;
z = p - q;
}
z = q * Math.sin(Math.PI * z);
if (z == 0.0)
throw new ArithmeticException("lnGamma: Overflow");
z = LOGPI - Math.log(z) - w;
return z;
}
if (x < 13.0) {
z = 1.0;
while (x >= 3.0) {
x -= 1.0;
z *= x;
}
while (x < 2.0) {
if (x == 0.0)
throw new ArithmeticException("lnGamma: Overflow");
z /= x;
x += 1.0;
}
if (z < 0.0)
z = -z;
if (x == 2.0)
return Math.log(z);
x -= 2.0;
p = x * polevl(x, B, 5) / p1evl(x, C, 6);
return (Math.log(z) + p);
}
if (x > 2.556348e305)
throw new ArithmeticException("lnGamma: Overflow");
q = (x - 0.5) * Math.log(x) - x + 0.91893853320467274178;
if (x > 1.0e8)
return (q);
p = 1.0 / (x * x);
if (x >= 1000.0)
q += ((7.9365079365079365079365e-4 * p
- 2.7777777777777777777778e-3) * p
+ 0.0833333333333333333333) / x;
else
q += polevl(p, A, 4) / x;
return q;
}