UNPKG

3.46 kBJavaScriptView Raw
1import { deepMap } from '../../utils/collection.js';
2import { factory } from '../../utils/factory.js';
3import { gammaG, gammaNumber, gammaP } from '../../plain/number/index.js';
4var name = 'gamma';
5var dependencies = ['typed', 'config', 'multiplyScalar', 'pow', 'BigNumber', 'Complex'];
6export var createGamma = /* #__PURE__ */factory(name, dependencies, (_ref) => {
7 var {
8 typed,
9 config,
10 multiplyScalar,
11 pow,
12 BigNumber: _BigNumber,
13 Complex: _Complex
14 } = _ref;
15
16 /**
17 * Compute the gamma function of a value using Lanczos approximation for
18 * small values, and an extended Stirling approximation for large values.
19 *
20 * For matrices, the function is evaluated element wise.
21 *
22 * Syntax:
23 *
24 * math.gamma(n)
25 *
26 * Examples:
27 *
28 * math.gamma(5) // returns 24
29 * math.gamma(-0.5) // returns -3.5449077018110335
30 * math.gamma(math.i) // returns -0.15494982830180973 - 0.49801566811835596i
31 *
32 * See also:
33 *
34 * combinations, factorial, permutations
35 *
36 * @param {number | Array | Matrix} n A real or complex number
37 * @return {number | Array | Matrix} The gamma of `n`
38 */
39 return typed(name, {
40 number: gammaNumber,
41 Complex: function Complex(n) {
42 if (n.im === 0) {
43 return this(n.re);
44 }
45
46 n = new _Complex(n.re - 1, n.im);
47 var x = new _Complex(gammaP[0], 0);
48
49 for (var i = 1; i < gammaP.length; ++i) {
50 var real = n.re + i; // x += p[i]/(n+i)
51
52 var den = real * real + n.im * n.im;
53
54 if (den !== 0) {
55 x.re += gammaP[i] * real / den;
56 x.im += -(gammaP[i] * n.im) / den;
57 } else {
58 x.re = gammaP[i] < 0 ? -Infinity : Infinity;
59 }
60 }
61
62 var t = new _Complex(n.re + gammaG + 0.5, n.im);
63 var twoPiSqrt = Math.sqrt(2 * Math.PI);
64 n.re += 0.5;
65 var result = pow(t, n);
66
67 if (result.im === 0) {
68 // sqrt(2*PI)*result
69 result.re *= twoPiSqrt;
70 } else if (result.re === 0) {
71 result.im *= twoPiSqrt;
72 } else {
73 result.re *= twoPiSqrt;
74 result.im *= twoPiSqrt;
75 }
76
77 var r = Math.exp(-t.re); // exp(-t)
78
79 t.re = r * Math.cos(-t.im);
80 t.im = r * Math.sin(-t.im);
81 return multiplyScalar(multiplyScalar(result, t), x);
82 },
83 BigNumber: function BigNumber(n) {
84 if (n.isInteger()) {
85 return n.isNegative() || n.isZero() ? new _BigNumber(Infinity) : bigFactorial(n.minus(1));
86 }
87
88 if (!n.isFinite()) {
89 return new _BigNumber(n.isNegative() ? NaN : Infinity);
90 }
91
92 throw new Error('Integer BigNumber expected');
93 },
94 'Array | Matrix': function ArrayMatrix(n) {
95 return deepMap(n, this);
96 }
97 });
98 /**
99 * Calculate factorial for a BigNumber
100 * @param {BigNumber} n
101 * @returns {BigNumber} Returns the factorial of n
102 */
103
104 function bigFactorial(n) {
105 if (n < 8) {
106 return new _BigNumber([1, 1, 2, 6, 24, 120, 720, 5040][n]);
107 }
108
109 var precision = config.precision + (Math.log(n.toNumber()) | 0);
110
111 var Big = _BigNumber.clone({
112 precision: precision
113 });
114
115 if (n % 2 === 1) {
116 return n.times(bigFactorial(new _BigNumber(n - 1)));
117 }
118
119 var p = n;
120 var prod = new Big(n);
121 var sum = n.toNumber();
122
123 while (p > 2) {
124 p -= 2;
125 sum += p;
126 prod = prod.times(sum);
127 }
128
129 return new _BigNumber(prod.toPrecision(_BigNumber.precision));
130 }
131});
\No newline at end of file