mathjs 10.4.2 → 10.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +36 -0
- package/docs/datatypes/matrices.md +17 -0
- package/docs/expressions/syntax.md +11 -4
- package/docs/reference/functions/fix.md +1 -0
- package/docs/reference/functions/floor.md +4 -0
- package/docs/reference/functions/lgamma.md +46 -0
- package/docs/reference/functions/pinv.md +44 -0
- package/docs/reference/functions/pow.md +8 -2
- package/docs/reference/functions/resolve.md +2 -2
- package/docs/reference/functions/simplifyConstant.md +52 -0
- package/docs/reference/functions/stirlingS2.md +5 -1
- package/docs/reference/functions.md +2 -0
- package/lib/browser/math.js +6 -6
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/entry/dependenciesAny/dependenciesCeil.generated.js +6 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesDet.generated.js +5 -2
- package/lib/cjs/entry/dependenciesAny/dependenciesFix.generated.js +9 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesFloor.generated.js +6 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesIndexNode.generated.js +0 -3
- package/lib/cjs/entry/dependenciesAny/dependenciesLgamma.generated.js +23 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesPinv.generated.js +53 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesPow.generated.js +3 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesStirlingS2.generated.js +6 -0
- package/lib/cjs/entry/dependenciesAny.generated.js +16 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesCeil.generated.js +3 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesFix.generated.js +6 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesFloor.generated.js +3 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesIndexNode.generated.js +0 -3
- package/lib/cjs/entry/dependenciesNumber/dependenciesLgamma.generated.js +20 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesStirlingS2.generated.js +3 -0
- package/lib/cjs/entry/dependenciesNumber.generated.js +8 -0
- package/lib/cjs/entry/impureFunctionsAny.generated.js +96 -95
- package/lib/cjs/entry/impureFunctionsNumber.generated.js +11 -11
- package/lib/cjs/entry/pureFunctionsAny.generated.js +227 -196
- package/lib/cjs/entry/pureFunctionsNumber.generated.js +36 -25
- package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +6 -0
- package/lib/cjs/expression/embeddedDocs/function/arithmetic/pow.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/matrix/pinv.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/probability/lgamma.js +15 -0
- package/lib/cjs/expression/node/IndexNode.js +26 -61
- package/lib/cjs/factoriesAny.js +16 -0
- package/lib/cjs/factoriesNumber.js +44 -27
- package/lib/cjs/function/algebra/resolve.js +3 -3
- package/lib/cjs/function/arithmetic/ceil.js +75 -39
- package/lib/cjs/function/arithmetic/fix.js +54 -16
- package/lib/cjs/function/arithmetic/floor.js +79 -37
- package/lib/cjs/function/arithmetic/nthRoot.js +1 -3
- package/lib/cjs/function/arithmetic/pow.js +25 -6
- package/lib/cjs/function/arithmetic/round.js +27 -47
- package/lib/cjs/function/combinatorics/stirlingS2.js +42 -12
- package/lib/cjs/function/matrix/det.js +37 -31
- package/lib/cjs/function/matrix/pinv.js +223 -0
- package/lib/cjs/function/probability/lgamma.js +146 -0
- package/lib/cjs/header.js +2 -2
- package/lib/cjs/plain/number/arithmetic.js +17 -31
- package/lib/cjs/plain/number/probability.js +43 -3
- package/lib/cjs/type/matrix/function/sparse.js +6 -0
- package/lib/cjs/utils/latex.js +6 -0
- package/lib/cjs/utils/lruQueue.js +1 -3
- package/lib/cjs/utils/number.js +17 -2
- package/lib/cjs/utils/object.js +3 -1
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesCeil.generated.js +4 -0
- package/lib/esm/entry/dependenciesAny/dependenciesDet.generated.js +4 -2
- package/lib/esm/entry/dependenciesAny/dependenciesFix.generated.js +6 -0
- package/lib/esm/entry/dependenciesAny/dependenciesFloor.generated.js +4 -0
- package/lib/esm/entry/dependenciesAny/dependenciesIndexNode.generated.js +0 -2
- package/lib/esm/entry/dependenciesAny/dependenciesLgamma.generated.js +12 -0
- package/lib/esm/entry/dependenciesAny/dependenciesPinv.generated.js +32 -0
- package/lib/esm/entry/dependenciesAny/dependenciesPow.generated.js +2 -0
- package/lib/esm/entry/dependenciesAny/dependenciesStirlingS2.generated.js +4 -0
- package/lib/esm/entry/dependenciesAny.generated.js +2 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesCeil.generated.js +2 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesFix.generated.js +4 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesFloor.generated.js +2 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesIndexNode.generated.js +0 -2
- package/lib/esm/entry/dependenciesNumber/dependenciesLgamma.generated.js +10 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesStirlingS2.generated.js +2 -0
- package/lib/esm/entry/dependenciesNumber.generated.js +1 -0
- package/lib/esm/entry/impureFunctionsAny.generated.js +90 -89
- package/lib/esm/entry/impureFunctionsNumber.generated.js +12 -12
- package/lib/esm/entry/pureFunctionsAny.generated.js +191 -162
- package/lib/esm/entry/pureFunctionsNumber.generated.js +24 -14
- package/lib/esm/expression/embeddedDocs/embeddedDocs.js +4 -0
- package/lib/esm/expression/embeddedDocs/function/arithmetic/pow.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/matrix/pinv.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/probability/lgamma.js +8 -0
- package/lib/esm/expression/node/BlockNode.js +3 -3
- package/lib/esm/expression/node/IndexNode.js +22 -59
- package/lib/esm/expression/parse.js +5 -5
- package/lib/esm/factoriesAny.js +2 -0
- package/lib/esm/factoriesNumber.js +21 -8
- package/lib/esm/function/algebra/decomposition/qr.js +2 -2
- package/lib/esm/function/algebra/resolve.js +3 -3
- package/lib/esm/function/algebra/solver/utils/solveValidation.js +5 -5
- package/lib/esm/function/algebra/sparse/csChol.js +2 -2
- package/lib/esm/function/algebra/sparse/csLeaf.js +2 -2
- package/lib/esm/function/algebra/sparse/csLu.js +3 -3
- package/lib/esm/function/arithmetic/ceil.js +61 -24
- package/lib/esm/function/arithmetic/fix.js +51 -13
- package/lib/esm/function/arithmetic/floor.js +65 -23
- package/lib/esm/function/arithmetic/nthRoot.js +1 -3
- package/lib/esm/function/arithmetic/nthRoots.js +1 -1
- package/lib/esm/function/arithmetic/pow.js +25 -6
- package/lib/esm/function/arithmetic/round.js +25 -43
- package/lib/esm/function/combinatorics/stirlingS2.js +41 -12
- package/lib/esm/function/matrix/det.js +35 -31
- package/lib/esm/function/matrix/expm.js +2 -2
- package/lib/esm/function/matrix/pinv.js +205 -0
- package/lib/esm/function/probability/gamma.js +1 -1
- package/lib/esm/function/probability/lgamma.js +137 -0
- package/lib/esm/function/string/bin.js +1 -1
- package/lib/esm/function/string/hex.js +1 -1
- package/lib/esm/function/string/oct.js +1 -1
- package/lib/esm/plain/number/arithmetic.js +16 -20
- package/lib/esm/plain/number/probability.js +33 -1
- package/lib/esm/type/complex/Complex.js +2 -2
- package/lib/esm/type/matrix/DenseMatrix.js +2 -2
- package/lib/esm/type/matrix/FibonacciHeap.js +2 -2
- package/lib/esm/type/matrix/SparseMatrix.js +13 -13
- package/lib/esm/type/matrix/function/sparse.js +6 -0
- package/lib/esm/type/unit/Unit.js +7 -7
- package/lib/esm/utils/latex.js +6 -0
- package/lib/esm/utils/lruQueue.js +1 -2
- package/lib/esm/utils/number.js +16 -4
- package/lib/esm/utils/object.js +3 -1
- package/lib/esm/version.js +1 -1
- package/package.json +20 -9
- package/types/index.d.ts +1806 -1363
- package/types/index.ts +705 -264
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { factory } from '../../utils/factory.js';
|
|
2
|
+
import { isNumber } from '../../utils/is.js';
|
|
2
3
|
var name = 'stirlingS2';
|
|
3
|
-
var dependencies = ['typed', 'addScalar', 'subtract', 'multiplyScalar', 'divideScalar', 'pow', 'factorial', 'combinations', 'isNegative', 'isInteger', 'larger'];
|
|
4
|
+
var dependencies = ['typed', 'addScalar', 'subtract', 'multiplyScalar', 'divideScalar', 'pow', 'factorial', 'combinations', 'isNegative', 'isInteger', 'number', '?bignumber', 'larger'];
|
|
4
5
|
export var createStirlingS2 = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
5
6
|
var {
|
|
6
7
|
typed,
|
|
@@ -13,16 +14,23 @@ export var createStirlingS2 = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
13
14
|
combinations,
|
|
14
15
|
isNegative,
|
|
15
16
|
isInteger,
|
|
17
|
+
number,
|
|
18
|
+
bignumber,
|
|
16
19
|
larger
|
|
17
20
|
} = _ref;
|
|
18
|
-
|
|
21
|
+
var smallCache = [];
|
|
22
|
+
var bigCache = [];
|
|
19
23
|
/**
|
|
20
24
|
* The Stirling numbers of the second kind, counts the number of ways to partition
|
|
21
25
|
* a set of n labelled objects into k nonempty unlabelled subsets.
|
|
22
26
|
* stirlingS2 only takes integer arguments.
|
|
23
27
|
* The following condition must be enforced: k <= n.
|
|
24
28
|
*
|
|
25
|
-
* If n = k or k = 1, then s(n,k) = 1
|
|
29
|
+
* If n = k or k = 1 <= n, then s(n,k) = 1
|
|
30
|
+
* If k = 0 < n, then s(n,k) = 0
|
|
31
|
+
*
|
|
32
|
+
* Note that if either n or k is supplied as a BigNumber, the result will be
|
|
33
|
+
* as well.
|
|
26
34
|
*
|
|
27
35
|
* Syntax:
|
|
28
36
|
*
|
|
@@ -40,26 +48,47 @@ export var createStirlingS2 = /* #__PURE__ */factory(name, dependencies, _ref =>
|
|
|
40
48
|
* @param {Number | BigNumber} k Number of objects in the subset
|
|
41
49
|
* @return {Number | BigNumber} S(n,k)
|
|
42
50
|
*/
|
|
51
|
+
|
|
43
52
|
return typed(name, {
|
|
44
53
|
'number | BigNumber, number | BigNumber': function numberBigNumberNumberBigNumber(n, k) {
|
|
45
54
|
if (!isInteger(n) || isNegative(n) || !isInteger(k) || isNegative(k)) {
|
|
46
55
|
throw new TypeError('Non-negative integer value expected in function stirlingS2');
|
|
47
56
|
} else if (larger(k, n)) {
|
|
48
57
|
throw new TypeError('k must be less than or equal to n in function stirlingS2');
|
|
49
|
-
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var big = !(isNumber(n) && isNumber(k));
|
|
61
|
+
var cache = big ? bigCache : smallCache;
|
|
62
|
+
var make = big ? bignumber : number;
|
|
63
|
+
var nn = number(n);
|
|
64
|
+
var nk = number(k);
|
|
65
|
+
/* See if we already have the value: */
|
|
66
|
+
|
|
67
|
+
if (cache[nn] && cache[nn].length > nk) {
|
|
68
|
+
return cache[nn][nk];
|
|
69
|
+
}
|
|
70
|
+
/* Fill the cache */
|
|
71
|
+
|
|
50
72
|
|
|
73
|
+
for (var m = 0; m <= nn; ++m) {
|
|
74
|
+
if (!cache[m]) {
|
|
75
|
+
cache[m] = [m === 0 ? make(1) : make(0)];
|
|
76
|
+
}
|
|
51
77
|
|
|
52
|
-
|
|
53
|
-
|
|
78
|
+
if (m === 0) continue;
|
|
79
|
+
var row = cache[m];
|
|
80
|
+
var prev = cache[m - 1];
|
|
54
81
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
82
|
+
for (var i = row.length; i <= m && i <= nk; ++i) {
|
|
83
|
+
if (i === m) {
|
|
84
|
+
row[i] = 1;
|
|
85
|
+
} else {
|
|
86
|
+
row[i] = addScalar(multiplyScalar(make(i), prev[i]), prev[i - 1]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
60
89
|
}
|
|
61
90
|
|
|
62
|
-
return
|
|
91
|
+
return cache[nn][nk];
|
|
63
92
|
}
|
|
64
93
|
});
|
|
65
94
|
});
|
|
@@ -3,15 +3,16 @@ import { clone } from '../../utils/object.js';
|
|
|
3
3
|
import { format } from '../../utils/string.js';
|
|
4
4
|
import { factory } from '../../utils/factory.js';
|
|
5
5
|
var name = 'det';
|
|
6
|
-
var dependencies = ['typed', 'matrix', 'subtract', 'multiply', '
|
|
6
|
+
var dependencies = ['typed', 'matrix', 'subtract', 'multiply', 'divideScalar', 'isZero', 'unaryMinus'];
|
|
7
7
|
export var createDet = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
8
8
|
var {
|
|
9
9
|
typed,
|
|
10
10
|
matrix,
|
|
11
11
|
subtract,
|
|
12
12
|
multiply,
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
divideScalar,
|
|
14
|
+
isZero,
|
|
15
|
+
unaryMinus
|
|
15
16
|
} = _ref;
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -106,42 +107,45 @@ export var createDet = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
106
107
|
// the determinant of [a11,a12;a21,a22] is det = a11*a22-a21*a12
|
|
107
108
|
return subtract(multiply(matrix[0][0], matrix[1][1]), multiply(matrix[1][0], matrix[0][1]));
|
|
108
109
|
} else {
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
var
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
110
|
+
// Bareiss algorithm
|
|
111
|
+
// this algorithm have same complexity as LUP decomposition (O(n^3))
|
|
112
|
+
// but it preserve precision of floating point more relative to the LUP decomposition
|
|
113
|
+
var negated = false;
|
|
114
|
+
var rowIndices = new Array(rows).fill(0).map((_, i) => i); // matrix index of row i
|
|
115
|
+
|
|
116
|
+
for (var k = 0; k < rows; k++) {
|
|
117
|
+
var k_ = rowIndices[k];
|
|
118
|
+
|
|
119
|
+
if (isZero(matrix[k_][k])) {
|
|
120
|
+
var _k = void 0;
|
|
121
|
+
|
|
122
|
+
for (_k = k + 1; _k < rows; _k++) {
|
|
123
|
+
if (!isZero(matrix[rowIndices[_k]][k])) {
|
|
124
|
+
k_ = rowIndices[_k];
|
|
125
|
+
rowIndices[_k] = rowIndices[k];
|
|
126
|
+
rowIndices[k] = k_;
|
|
127
|
+
negated = !negated;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
123
131
|
|
|
124
|
-
|
|
125
|
-
while (visited[i]) {
|
|
126
|
-
i++;
|
|
132
|
+
if (_k === rows) return matrix[k_][k]; // some zero of the type
|
|
127
133
|
}
|
|
128
134
|
|
|
129
|
-
|
|
130
|
-
var
|
|
131
|
-
var cycleLen = 0;
|
|
135
|
+
var piv = matrix[k_][k];
|
|
136
|
+
var piv_ = k === 0 ? 1 : matrix[rowIndices[k - 1]][k - 1];
|
|
132
137
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
j = decomp.p[j];
|
|
136
|
-
cycleLen++;
|
|
137
|
-
}
|
|
138
|
+
for (var i = k + 1; i < rows; i++) {
|
|
139
|
+
var i_ = rowIndices[i];
|
|
138
140
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
for (var j = k + 1; j < rows; j++) {
|
|
142
|
+
matrix[i_][j] = divideScalar(subtract(multiply(matrix[i_][j], piv), multiply(matrix[i_][k], matrix[k_][j])), piv_);
|
|
143
|
+
}
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
146
|
|
|
144
|
-
|
|
147
|
+
var det = matrix[rowIndices[rows - 1]][rows - 1];
|
|
148
|
+
return negated ? unaryMinus(det) : det;
|
|
145
149
|
}
|
|
146
150
|
}
|
|
147
151
|
});
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { isMatrix } from '../../utils/is.js';
|
|
2
|
+
import { arraySize } from '../../utils/array.js';
|
|
3
|
+
import { factory } from '../../utils/factory.js';
|
|
4
|
+
import { format } from '../../utils/string.js';
|
|
5
|
+
import { clone } from '../../utils/object.js';
|
|
6
|
+
var name = 'pinv';
|
|
7
|
+
var dependencies = ['typed', 'matrix', 'inv', 'deepEqual', 'equal', 'dotDivide', 'dot', 'ctranspose', 'divideScalar', 'multiply', 'add', 'Complex'];
|
|
8
|
+
export var createPinv = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
9
|
+
var {
|
|
10
|
+
typed,
|
|
11
|
+
matrix,
|
|
12
|
+
inv,
|
|
13
|
+
deepEqual,
|
|
14
|
+
equal,
|
|
15
|
+
dotDivide,
|
|
16
|
+
dot,
|
|
17
|
+
ctranspose,
|
|
18
|
+
divideScalar,
|
|
19
|
+
multiply,
|
|
20
|
+
add,
|
|
21
|
+
Complex
|
|
22
|
+
} = _ref;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Calculate the Moore–Penrose inverse of a matrix.
|
|
26
|
+
*
|
|
27
|
+
* Syntax:
|
|
28
|
+
*
|
|
29
|
+
* math.pinv(x)
|
|
30
|
+
*
|
|
31
|
+
* Examples:
|
|
32
|
+
*
|
|
33
|
+
* math.pinv([[1, 2], [3, 4]]) // returns [[-2, 1], [1.5, -0.5]]
|
|
34
|
+
* math.pinv([[1, 0], [0, 1], [0, 1]]) // returns [[1, 0, 0], [0, 0.5, 0.5]]
|
|
35
|
+
* math.pinv(4) // returns 0.25
|
|
36
|
+
*
|
|
37
|
+
* See also:
|
|
38
|
+
*
|
|
39
|
+
* inv
|
|
40
|
+
*
|
|
41
|
+
* @param {number | Complex | Array | Matrix} x Matrix to be inversed
|
|
42
|
+
* @return {number | Complex | Array | Matrix} The inverse of `x`.
|
|
43
|
+
*/
|
|
44
|
+
return typed(name, {
|
|
45
|
+
'Array | Matrix': function ArrayMatrix(x) {
|
|
46
|
+
var size = isMatrix(x) ? x.size() : arraySize(x);
|
|
47
|
+
|
|
48
|
+
switch (size.length) {
|
|
49
|
+
case 1:
|
|
50
|
+
// vector
|
|
51
|
+
if (_isZeros(x)) return ctranspose(x); // null vector
|
|
52
|
+
|
|
53
|
+
if (size[0] === 1) {
|
|
54
|
+
return inv(x); // invertible matrix
|
|
55
|
+
} else {
|
|
56
|
+
return dotDivide(ctranspose(x), dot(x, x));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
case 2:
|
|
60
|
+
// two dimensional array
|
|
61
|
+
{
|
|
62
|
+
if (_isZeros(x)) return ctranspose(x); // zero matrixx
|
|
63
|
+
|
|
64
|
+
var rows = size[0];
|
|
65
|
+
var cols = size[1];
|
|
66
|
+
|
|
67
|
+
if (rows === cols) {
|
|
68
|
+
try {
|
|
69
|
+
return inv(x); // invertible matrix
|
|
70
|
+
} catch (err) {
|
|
71
|
+
if (err instanceof Error && err.message.match(/Cannot calculate inverse, determinant is zero/)) {// Expected
|
|
72
|
+
} else {
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (isMatrix(x)) {
|
|
79
|
+
return matrix(_pinv(x.valueOf(), rows, cols), x.storage());
|
|
80
|
+
} else {
|
|
81
|
+
// return an Array
|
|
82
|
+
return _pinv(x, rows, cols);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
default:
|
|
87
|
+
// multi dimensional array
|
|
88
|
+
throw new RangeError('Matrix must be two dimensional ' + '(size: ' + format(size) + ')');
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
any: function any(x) {
|
|
92
|
+
// scalar
|
|
93
|
+
if (equal(x, 0)) return clone(x); // zero
|
|
94
|
+
|
|
95
|
+
return divideScalar(1, x);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
/**
|
|
99
|
+
* Calculate the Moore–Penrose inverse of a matrix
|
|
100
|
+
* @param {Array[]} mat A matrix
|
|
101
|
+
* @param {number} rows Number of rows
|
|
102
|
+
* @param {number} cols Number of columns
|
|
103
|
+
* @return {Array[]} pinv Pseudoinverse matrix
|
|
104
|
+
* @private
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
function _pinv(mat, rows, cols) {
|
|
108
|
+
var {
|
|
109
|
+
C,
|
|
110
|
+
F
|
|
111
|
+
} = _rankFact(mat, rows, cols); // TODO: Use SVD instead (may improve precision)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
var Cpinv = multiply(inv(multiply(ctranspose(C), C)), ctranspose(C));
|
|
115
|
+
var Fpinv = multiply(ctranspose(F), inv(multiply(F, ctranspose(F))));
|
|
116
|
+
return multiply(Fpinv, Cpinv);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Calculate the reduced row echelon form of a matrix
|
|
120
|
+
*
|
|
121
|
+
* Modified from https://rosettacode.org/wiki/Reduced_row_echelon_form
|
|
122
|
+
*
|
|
123
|
+
* @param {Array[]} mat A matrix
|
|
124
|
+
* @param {number} rows Number of rows
|
|
125
|
+
* @param {number} cols Number of columns
|
|
126
|
+
* @return {Array[]} Reduced row echelon form
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
function _rref(mat, rows, cols) {
|
|
132
|
+
var M = clone(mat);
|
|
133
|
+
var lead = 0;
|
|
134
|
+
|
|
135
|
+
for (var r = 0; r < rows; r++) {
|
|
136
|
+
if (cols <= lead) {
|
|
137
|
+
return M;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var i = r;
|
|
141
|
+
|
|
142
|
+
while (_isZero(M[i][lead])) {
|
|
143
|
+
i++;
|
|
144
|
+
|
|
145
|
+
if (rows === i) {
|
|
146
|
+
i = r;
|
|
147
|
+
lead++;
|
|
148
|
+
|
|
149
|
+
if (cols === lead) {
|
|
150
|
+
return M;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
[M[i], M[r]] = [M[r], M[i]];
|
|
156
|
+
var val = M[r][lead];
|
|
157
|
+
|
|
158
|
+
for (var j = 0; j < cols; j++) {
|
|
159
|
+
M[r][j] = dotDivide(M[r][j], val);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
for (var _i = 0; _i < rows; _i++) {
|
|
163
|
+
if (_i === r) continue;
|
|
164
|
+
val = M[_i][lead];
|
|
165
|
+
|
|
166
|
+
for (var _j = 0; _j < cols; _j++) {
|
|
167
|
+
M[_i][_j] = add(M[_i][_j], multiply(-1, multiply(val, M[r][_j])));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
lead++;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return M;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Calculate the rank factorization of a matrix
|
|
178
|
+
*
|
|
179
|
+
* @param {Array[]} mat A matrix (M)
|
|
180
|
+
* @param {number} rows Number of rows
|
|
181
|
+
* @param {number} cols Number of columns
|
|
182
|
+
* @return {{C: Array, F: Array}} rank factorization where M = C F
|
|
183
|
+
* @private
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
function _rankFact(mat, rows, cols) {
|
|
188
|
+
var rref = _rref(mat, rows, cols);
|
|
189
|
+
|
|
190
|
+
var C = mat.map((_, i) => _.filter((_, j) => j < rows && !_isZero(dot(rref[j], rref[j]))));
|
|
191
|
+
var F = rref.filter((_, i) => !_isZero(dot(rref[i], rref[i])));
|
|
192
|
+
return {
|
|
193
|
+
C,
|
|
194
|
+
F
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function _isZero(x) {
|
|
199
|
+
return equal(add(x, Complex(1, 1)), add(0, Complex(1, 1)));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function _isZeros(arr) {
|
|
203
|
+
return deepEqual(add(arr, Complex(1, 1)), add(multiply(arr, 0), Complex(1, 1)));
|
|
204
|
+
}
|
|
205
|
+
});
|
|
@@ -107,7 +107,7 @@ export var createGamma = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
107
107
|
var precision = config.precision + (Math.log(n.toNumber()) | 0);
|
|
108
108
|
|
|
109
109
|
var Big = _BigNumber.clone({
|
|
110
|
-
precision
|
|
110
|
+
precision
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
if (n % 2 === 1) {
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/* eslint-disable no-loss-of-precision */
|
|
2
|
+
// References
|
|
3
|
+
// ----------
|
|
4
|
+
// [1] Hare, "Computing the Principal Branch of log-Gamma", Journal of Algorithms, 1997.
|
|
5
|
+
// [2] https://math.stackexchange.com/questions/1338753/how-do-i-calculate-values-for-gamma-function-with-complex-arguments
|
|
6
|
+
import { lgammaNumber, lnSqrt2PI } from '../../plain/number/index.js';
|
|
7
|
+
import { factory } from '../../utils/factory.js';
|
|
8
|
+
import { copysign } from '../../utils/number.js';
|
|
9
|
+
var name = 'lgamma';
|
|
10
|
+
var dependencies = ['Complex', 'typed'];
|
|
11
|
+
export var createLgamma = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
12
|
+
var {
|
|
13
|
+
Complex: _Complex,
|
|
14
|
+
typed
|
|
15
|
+
} = _ref;
|
|
16
|
+
// Stirling series is non-convergent, we need to use the recurrence `lgamma(z) = lgamma(z+1) - log z` to get
|
|
17
|
+
// sufficient accuracy.
|
|
18
|
+
//
|
|
19
|
+
// These two values are copied from Scipy implementation:
|
|
20
|
+
// https://github.com/scipy/scipy/blob/v1.8.0/scipy/special/_loggamma.pxd#L37
|
|
21
|
+
var SMALL_RE = 7;
|
|
22
|
+
var SMALL_IM = 7;
|
|
23
|
+
/**
|
|
24
|
+
* The coefficients are B[2*n]/(2*n*(2*n - 1)) where B[2*n] is the (2*n)th Bernoulli number. See (1.1) in [1].
|
|
25
|
+
*
|
|
26
|
+
* If you cannot access the paper, can also get these values from the formula in [2].
|
|
27
|
+
*
|
|
28
|
+
* 1 / 12 = 0.00833333333333333333333333333333
|
|
29
|
+
* 1 / 360 = 0.00277777777777777777777777777778
|
|
30
|
+
* ...
|
|
31
|
+
* 3617 / 133400 = 0.02955065359477124183006535947712
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
var coeffs = [-2.955065359477124183e-2, 6.4102564102564102564e-3, -1.9175269175269175269e-3, 8.4175084175084175084e-4, -5.952380952380952381e-4, 7.9365079365079365079e-4, -2.7777777777777777778e-3, 8.3333333333333333333e-2];
|
|
35
|
+
/**
|
|
36
|
+
* Logarithm of the gamma function for real, positive numbers and complex numbers,
|
|
37
|
+
* using Lanczos approximation for numbers and Stirling series for complex numbers.
|
|
38
|
+
*
|
|
39
|
+
* Syntax:
|
|
40
|
+
*
|
|
41
|
+
* math.lgamma(n)
|
|
42
|
+
*
|
|
43
|
+
* Examples:
|
|
44
|
+
*
|
|
45
|
+
* math.lgamma(5) // returns 3.178053830347945
|
|
46
|
+
* math.lgamma(0) // returns Infinity
|
|
47
|
+
* math.lgamma(-0.5) // returns NaN
|
|
48
|
+
* math.lgamma(math.i) // returns -0.6509231993018536 - 1.8724366472624294i
|
|
49
|
+
*
|
|
50
|
+
* See also:
|
|
51
|
+
*
|
|
52
|
+
* gamma
|
|
53
|
+
*
|
|
54
|
+
* @param {number | Complex} n A real or complex number
|
|
55
|
+
* @return {number | Complex} The log gamma of `n`
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
return typed(name, {
|
|
59
|
+
number: lgammaNumber,
|
|
60
|
+
Complex: function Complex(n) {
|
|
61
|
+
var TWOPI = 6.2831853071795864769252842; // 2*pi
|
|
62
|
+
|
|
63
|
+
var LOGPI = 1.1447298858494001741434262; // log(pi)
|
|
64
|
+
|
|
65
|
+
var REFLECTION = 0.1;
|
|
66
|
+
|
|
67
|
+
if (n.isNaN()) {
|
|
68
|
+
return new _Complex(NaN, NaN);
|
|
69
|
+
} else if (n.im === 0) {
|
|
70
|
+
return new _Complex(lgammaNumber(n.re), 0);
|
|
71
|
+
} else if (n.re >= SMALL_RE || Math.abs(n.im) >= SMALL_IM) {
|
|
72
|
+
return lgammaStirling(n);
|
|
73
|
+
} else if (n.re <= REFLECTION) {
|
|
74
|
+
// Reflection formula. see Proposition 3.1 in [1]
|
|
75
|
+
var tmp = copysign(TWOPI, n.im) * Math.floor(0.5 * n.re + 0.25); // TODO: `complex.js sin` doesn't have extremely high precision, so this value `a` may lose a little precision,
|
|
76
|
+
// causing the computation results to be less accurate than the lgamma of real numbers
|
|
77
|
+
|
|
78
|
+
var a = n.mul(Math.PI).sin().log();
|
|
79
|
+
var b = this(new _Complex(1 - n.re, -n.im));
|
|
80
|
+
return new _Complex(LOGPI, tmp).sub(a).sub(b);
|
|
81
|
+
} else if (n.im >= 0) {
|
|
82
|
+
return lgammaRecurrence(n);
|
|
83
|
+
} else {
|
|
84
|
+
return lgammaRecurrence(n.conjugate()).conjugate();
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
BigNumber: function BigNumber() {
|
|
88
|
+
throw new Error("mathjs doesn't yet provide an implementation of the algorithm lgamma for BigNumber");
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
function lgammaStirling(z) {
|
|
93
|
+
// formula ref in [2]
|
|
94
|
+
// computation ref:
|
|
95
|
+
// https://github.com/scipy/scipy/blob/v1.8.0/scipy/special/_loggamma.pxd#L101
|
|
96
|
+
// left part
|
|
97
|
+
// x (log(x) - 1) + 1/2 (log(2PI) - log(x))
|
|
98
|
+
// => (x - 0.5) * log(x) - x + log(2PI) / 2
|
|
99
|
+
var leftPart = z.sub(0.5).mul(z.log()).sub(z).add(lnSqrt2PI); // right part
|
|
100
|
+
|
|
101
|
+
var rz = new _Complex(1, 0).div(z);
|
|
102
|
+
var rzz = rz.div(z);
|
|
103
|
+
var a = coeffs[0];
|
|
104
|
+
var b = coeffs[1];
|
|
105
|
+
var r = 2 * rzz.re;
|
|
106
|
+
var s = rzz.re * rzz.re + rzz.im * rzz.im;
|
|
107
|
+
|
|
108
|
+
for (var i = 2; i < 8; i++) {
|
|
109
|
+
var tmp = b;
|
|
110
|
+
b = -s * a + coeffs[i];
|
|
111
|
+
a = r * a + tmp;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
var rightPart = rz.mul(rzz.mul(a).add(b)); // plus left and right
|
|
115
|
+
|
|
116
|
+
return leftPart.add(rightPart);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function lgammaRecurrence(z) {
|
|
120
|
+
// computation ref:
|
|
121
|
+
// https://github.com/scipy/scipy/blob/v1.8.0/scipy/special/_loggamma.pxd#L78
|
|
122
|
+
var signflips = 0;
|
|
123
|
+
var sb = 0;
|
|
124
|
+
var shiftprod = z;
|
|
125
|
+
z = z.add(1);
|
|
126
|
+
|
|
127
|
+
while (z.re <= SMALL_RE) {
|
|
128
|
+
shiftprod = shiftprod.mul(z);
|
|
129
|
+
var nsb = shiftprod.im < 0 ? 1 : 0;
|
|
130
|
+
if (nsb !== 0 && sb === 0) signflips++;
|
|
131
|
+
sb = nsb;
|
|
132
|
+
z = z.add(1);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return lgammaStirling(z).sub(shiftprod.log()).sub(new _Complex(0, signflips * 2 * Math.PI * 1));
|
|
136
|
+
}
|
|
137
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cbrt, expm1, isInteger, log10, log1p, log2, sign, toFixed } from '../../utils/number.js';
|
|
2
2
|
var n1 = 'number';
|
|
3
3
|
var n2 = 'number, number';
|
|
4
4
|
export function absNumber(a) {
|
|
@@ -33,10 +33,6 @@ export function cbrtNumber(x) {
|
|
|
33
33
|
return cbrt(x);
|
|
34
34
|
}
|
|
35
35
|
cbrtNumber.signature = n1;
|
|
36
|
-
export function ceilNumber(x) {
|
|
37
|
-
return Math.ceil(x);
|
|
38
|
-
}
|
|
39
|
-
ceilNumber.signature = n1;
|
|
40
36
|
export function cubeNumber(x) {
|
|
41
37
|
return x * x * x;
|
|
42
38
|
}
|
|
@@ -49,14 +45,6 @@ export function expm1Number(x) {
|
|
|
49
45
|
return expm1(x);
|
|
50
46
|
}
|
|
51
47
|
expm1Number.signature = n1;
|
|
52
|
-
export function fixNumber(x) {
|
|
53
|
-
return x > 0 ? Math.floor(x) : Math.ceil(x);
|
|
54
|
-
}
|
|
55
|
-
fixNumber.signature = n1;
|
|
56
|
-
export function floorNumber(x) {
|
|
57
|
-
return Math.floor(x);
|
|
58
|
-
}
|
|
59
|
-
floorNumber.signature = n1;
|
|
60
48
|
/**
|
|
61
49
|
* Calculate gcd for numbers
|
|
62
50
|
* @param {number} a
|
|
@@ -112,15 +100,19 @@ export function lcmNumber(a, b) {
|
|
|
112
100
|
}
|
|
113
101
|
lcmNumber.signature = n2;
|
|
114
102
|
/**
|
|
115
|
-
* Calculate the logarithm of a value.
|
|
103
|
+
* Calculate the logarithm of a value, optionally to a given base.
|
|
116
104
|
* @param {number} x
|
|
105
|
+
* @param {number | null | undefined} base
|
|
117
106
|
* @return {number}
|
|
118
107
|
*/
|
|
119
108
|
|
|
120
|
-
export function logNumber(x) {
|
|
109
|
+
export function logNumber(x, y) {
|
|
110
|
+
if (y) {
|
|
111
|
+
return Math.log(x) / Math.log(y);
|
|
112
|
+
}
|
|
113
|
+
|
|
121
114
|
return Math.log(x);
|
|
122
115
|
}
|
|
123
|
-
logNumber.signature = n1;
|
|
124
116
|
/**
|
|
125
117
|
* Calculate the 10-base logarithm of a number
|
|
126
118
|
* @param {number} x
|
|
@@ -178,11 +170,12 @@ modNumber.signature = n2;
|
|
|
178
170
|
* Calculate the nth root of a, solve x^root == a
|
|
179
171
|
* http://rosettacode.org/wiki/Nth_root#JavaScript
|
|
180
172
|
* @param {number} a
|
|
181
|
-
* @param {number} root
|
|
173
|
+
* @param {number} [2] root
|
|
182
174
|
* @private
|
|
183
175
|
*/
|
|
184
176
|
|
|
185
|
-
export function nthRootNumber(a
|
|
177
|
+
export function nthRootNumber(a) {
|
|
178
|
+
var root = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
|
|
186
179
|
var inv = root < 0;
|
|
187
180
|
|
|
188
181
|
if (inv) {
|
|
@@ -232,7 +225,6 @@ export function nthRootNumber(a, root) {
|
|
|
232
225
|
return inv ? 1 / x : x
|
|
233
226
|
*/
|
|
234
227
|
}
|
|
235
|
-
nthRootNumber.signature = n2;
|
|
236
228
|
export function signNumber(x) {
|
|
237
229
|
return sign(x);
|
|
238
230
|
}
|
|
@@ -321,9 +313,13 @@ powNumber.signature = n2;
|
|
|
321
313
|
|
|
322
314
|
export function roundNumber(value) {
|
|
323
315
|
var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
316
|
+
|
|
317
|
+
if (!isInteger(decimals) || decimals < 0 || decimals > 15) {
|
|
318
|
+
throw new Error('Number of decimals in function round must be an integer from 0 to 15 inclusive');
|
|
319
|
+
}
|
|
320
|
+
|
|
324
321
|
return parseFloat(toFixed(value, decimals));
|
|
325
322
|
}
|
|
326
|
-
roundNumber.signature = n2;
|
|
327
323
|
/**
|
|
328
324
|
* Calculate the norm of a number, the absolute value.
|
|
329
325
|
* @param {number} x
|