1 | // Define series coefficients
|
2 | const COEFFICIENTS = [
|
3 | 0.99999999999999709182,
|
4 | 57.156235665862923517,
|
5 | -59.597960355475491248,
|
6 | 14.136097974741747174,
|
7 | -0.49191381609762019978,
|
8 | 0.33994649984811888699e-4,
|
9 | 0.46523628927048575665e-4,
|
10 | -0.98374475304879564677e-4,
|
11 | 0.15808870322491248884e-3,
|
12 | -0.21026444172410488319e-3,
|
13 | 0.2174396181152126432e-3,
|
14 | -0.16431810653676389022e-3,
|
15 | 0.84418223983852743293e-4,
|
16 | -0.2619083840158140867e-4,
|
17 | 0.36899182659531622704e-5
|
18 | ];
|
19 |
|
20 | const g = 607 / 128;
|
21 | const LOGSQRT2PI = Math.log(Math.sqrt(2 * Math.PI));
|
22 |
|
23 | /**
|
24 | * Compute the logarithm of the [gamma function](https://en.wikipedia.org/wiki/Gamma_function) of a value using Lanczos' approximation.
|
25 | * This function takes as input any real-value n greater than 0.
|
26 | * This function is useful for values of n too large for the normal gamma function (n > 165).
|
27 | * The code is based on Lanczo's Gamma approximation, defined [here](http://my.fit.edu/~gabdo/gamma.txt).
|
28 | *
|
29 | * @param {number} n Any real number greater than zero.
|
30 | * @returns {number} The logarithm of gamma of the input value.
|
31 | *
|
32 | * @example
|
33 | * gammaln(500); // 2605.1158503617335
|
34 | * gammaln(2.4); // 0.21685932244884043
|
35 | */
|
36 | function gammaln(n) {
|
37 | // Return infinity if value not in domain
|
38 | if (n <= 0) {
|
39 | return Infinity;
|
40 | }
|
41 |
|
42 | // Decrement n, because approximation is defined for n - 1
|
43 | n--;
|
44 |
|
45 | // Create series approximation
|
46 | let a = COEFFICIENTS[0];
|
47 |
|
48 | for (let i = 1; i < 15; i++) {
|
49 | a += COEFFICIENTS[i] / (n + i);
|
50 | }
|
51 |
|
52 | const tmp = g + 0.5 + n;
|
53 |
|
54 | // Return natural logarithm of gamma(n)
|
55 | return LOGSQRT2PI + Math.log(a) - tmp + (n + 0.5) * Math.log(tmp);
|
56 | }
|
57 |
|
58 | export default gammaln;
|