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.
Files changed (130) hide show
  1. package/HISTORY.md +36 -0
  2. package/docs/datatypes/matrices.md +17 -0
  3. package/docs/expressions/syntax.md +11 -4
  4. package/docs/reference/functions/fix.md +1 -0
  5. package/docs/reference/functions/floor.md +4 -0
  6. package/docs/reference/functions/lgamma.md +46 -0
  7. package/docs/reference/functions/pinv.md +44 -0
  8. package/docs/reference/functions/pow.md +8 -2
  9. package/docs/reference/functions/resolve.md +2 -2
  10. package/docs/reference/functions/simplifyConstant.md +52 -0
  11. package/docs/reference/functions/stirlingS2.md +5 -1
  12. package/docs/reference/functions.md +2 -0
  13. package/lib/browser/math.js +6 -6
  14. package/lib/browser/math.js.map +1 -1
  15. package/lib/cjs/entry/dependenciesAny/dependenciesCeil.generated.js +6 -0
  16. package/lib/cjs/entry/dependenciesAny/dependenciesDet.generated.js +5 -2
  17. package/lib/cjs/entry/dependenciesAny/dependenciesFix.generated.js +9 -0
  18. package/lib/cjs/entry/dependenciesAny/dependenciesFloor.generated.js +6 -0
  19. package/lib/cjs/entry/dependenciesAny/dependenciesIndexNode.generated.js +0 -3
  20. package/lib/cjs/entry/dependenciesAny/dependenciesLgamma.generated.js +23 -0
  21. package/lib/cjs/entry/dependenciesAny/dependenciesPinv.generated.js +53 -0
  22. package/lib/cjs/entry/dependenciesAny/dependenciesPow.generated.js +3 -0
  23. package/lib/cjs/entry/dependenciesAny/dependenciesStirlingS2.generated.js +6 -0
  24. package/lib/cjs/entry/dependenciesAny.generated.js +16 -0
  25. package/lib/cjs/entry/dependenciesNumber/dependenciesCeil.generated.js +3 -0
  26. package/lib/cjs/entry/dependenciesNumber/dependenciesFix.generated.js +6 -0
  27. package/lib/cjs/entry/dependenciesNumber/dependenciesFloor.generated.js +3 -0
  28. package/lib/cjs/entry/dependenciesNumber/dependenciesIndexNode.generated.js +0 -3
  29. package/lib/cjs/entry/dependenciesNumber/dependenciesLgamma.generated.js +20 -0
  30. package/lib/cjs/entry/dependenciesNumber/dependenciesStirlingS2.generated.js +3 -0
  31. package/lib/cjs/entry/dependenciesNumber.generated.js +8 -0
  32. package/lib/cjs/entry/impureFunctionsAny.generated.js +96 -95
  33. package/lib/cjs/entry/impureFunctionsNumber.generated.js +11 -11
  34. package/lib/cjs/entry/pureFunctionsAny.generated.js +227 -196
  35. package/lib/cjs/entry/pureFunctionsNumber.generated.js +36 -25
  36. package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +6 -0
  37. package/lib/cjs/expression/embeddedDocs/function/arithmetic/pow.js +1 -1
  38. package/lib/cjs/expression/embeddedDocs/function/matrix/pinv.js +15 -0
  39. package/lib/cjs/expression/embeddedDocs/function/probability/lgamma.js +15 -0
  40. package/lib/cjs/expression/node/IndexNode.js +26 -61
  41. package/lib/cjs/factoriesAny.js +16 -0
  42. package/lib/cjs/factoriesNumber.js +44 -27
  43. package/lib/cjs/function/algebra/resolve.js +3 -3
  44. package/lib/cjs/function/arithmetic/ceil.js +75 -39
  45. package/lib/cjs/function/arithmetic/fix.js +54 -16
  46. package/lib/cjs/function/arithmetic/floor.js +79 -37
  47. package/lib/cjs/function/arithmetic/nthRoot.js +1 -3
  48. package/lib/cjs/function/arithmetic/pow.js +25 -6
  49. package/lib/cjs/function/arithmetic/round.js +27 -47
  50. package/lib/cjs/function/combinatorics/stirlingS2.js +42 -12
  51. package/lib/cjs/function/matrix/det.js +37 -31
  52. package/lib/cjs/function/matrix/pinv.js +223 -0
  53. package/lib/cjs/function/probability/lgamma.js +146 -0
  54. package/lib/cjs/header.js +2 -2
  55. package/lib/cjs/plain/number/arithmetic.js +17 -31
  56. package/lib/cjs/plain/number/probability.js +43 -3
  57. package/lib/cjs/type/matrix/function/sparse.js +6 -0
  58. package/lib/cjs/utils/latex.js +6 -0
  59. package/lib/cjs/utils/lruQueue.js +1 -3
  60. package/lib/cjs/utils/number.js +17 -2
  61. package/lib/cjs/utils/object.js +3 -1
  62. package/lib/cjs/version.js +1 -1
  63. package/lib/esm/entry/dependenciesAny/dependenciesCeil.generated.js +4 -0
  64. package/lib/esm/entry/dependenciesAny/dependenciesDet.generated.js +4 -2
  65. package/lib/esm/entry/dependenciesAny/dependenciesFix.generated.js +6 -0
  66. package/lib/esm/entry/dependenciesAny/dependenciesFloor.generated.js +4 -0
  67. package/lib/esm/entry/dependenciesAny/dependenciesIndexNode.generated.js +0 -2
  68. package/lib/esm/entry/dependenciesAny/dependenciesLgamma.generated.js +12 -0
  69. package/lib/esm/entry/dependenciesAny/dependenciesPinv.generated.js +32 -0
  70. package/lib/esm/entry/dependenciesAny/dependenciesPow.generated.js +2 -0
  71. package/lib/esm/entry/dependenciesAny/dependenciesStirlingS2.generated.js +4 -0
  72. package/lib/esm/entry/dependenciesAny.generated.js +2 -0
  73. package/lib/esm/entry/dependenciesNumber/dependenciesCeil.generated.js +2 -0
  74. package/lib/esm/entry/dependenciesNumber/dependenciesFix.generated.js +4 -0
  75. package/lib/esm/entry/dependenciesNumber/dependenciesFloor.generated.js +2 -0
  76. package/lib/esm/entry/dependenciesNumber/dependenciesIndexNode.generated.js +0 -2
  77. package/lib/esm/entry/dependenciesNumber/dependenciesLgamma.generated.js +10 -0
  78. package/lib/esm/entry/dependenciesNumber/dependenciesStirlingS2.generated.js +2 -0
  79. package/lib/esm/entry/dependenciesNumber.generated.js +1 -0
  80. package/lib/esm/entry/impureFunctionsAny.generated.js +90 -89
  81. package/lib/esm/entry/impureFunctionsNumber.generated.js +12 -12
  82. package/lib/esm/entry/pureFunctionsAny.generated.js +191 -162
  83. package/lib/esm/entry/pureFunctionsNumber.generated.js +24 -14
  84. package/lib/esm/expression/embeddedDocs/embeddedDocs.js +4 -0
  85. package/lib/esm/expression/embeddedDocs/function/arithmetic/pow.js +1 -1
  86. package/lib/esm/expression/embeddedDocs/function/matrix/pinv.js +8 -0
  87. package/lib/esm/expression/embeddedDocs/function/probability/lgamma.js +8 -0
  88. package/lib/esm/expression/node/BlockNode.js +3 -3
  89. package/lib/esm/expression/node/IndexNode.js +22 -59
  90. package/lib/esm/expression/parse.js +5 -5
  91. package/lib/esm/factoriesAny.js +2 -0
  92. package/lib/esm/factoriesNumber.js +21 -8
  93. package/lib/esm/function/algebra/decomposition/qr.js +2 -2
  94. package/lib/esm/function/algebra/resolve.js +3 -3
  95. package/lib/esm/function/algebra/solver/utils/solveValidation.js +5 -5
  96. package/lib/esm/function/algebra/sparse/csChol.js +2 -2
  97. package/lib/esm/function/algebra/sparse/csLeaf.js +2 -2
  98. package/lib/esm/function/algebra/sparse/csLu.js +3 -3
  99. package/lib/esm/function/arithmetic/ceil.js +61 -24
  100. package/lib/esm/function/arithmetic/fix.js +51 -13
  101. package/lib/esm/function/arithmetic/floor.js +65 -23
  102. package/lib/esm/function/arithmetic/nthRoot.js +1 -3
  103. package/lib/esm/function/arithmetic/nthRoots.js +1 -1
  104. package/lib/esm/function/arithmetic/pow.js +25 -6
  105. package/lib/esm/function/arithmetic/round.js +25 -43
  106. package/lib/esm/function/combinatorics/stirlingS2.js +41 -12
  107. package/lib/esm/function/matrix/det.js +35 -31
  108. package/lib/esm/function/matrix/expm.js +2 -2
  109. package/lib/esm/function/matrix/pinv.js +205 -0
  110. package/lib/esm/function/probability/gamma.js +1 -1
  111. package/lib/esm/function/probability/lgamma.js +137 -0
  112. package/lib/esm/function/string/bin.js +1 -1
  113. package/lib/esm/function/string/hex.js +1 -1
  114. package/lib/esm/function/string/oct.js +1 -1
  115. package/lib/esm/plain/number/arithmetic.js +16 -20
  116. package/lib/esm/plain/number/probability.js +33 -1
  117. package/lib/esm/type/complex/Complex.js +2 -2
  118. package/lib/esm/type/matrix/DenseMatrix.js +2 -2
  119. package/lib/esm/type/matrix/FibonacciHeap.js +2 -2
  120. package/lib/esm/type/matrix/SparseMatrix.js +13 -13
  121. package/lib/esm/type/matrix/function/sparse.js +6 -0
  122. package/lib/esm/type/unit/Unit.js +7 -7
  123. package/lib/esm/utils/latex.js +6 -0
  124. package/lib/esm/utils/lruQueue.js +1 -2
  125. package/lib/esm/utils/number.js +16 -4
  126. package/lib/esm/utils/object.js +3 -1
  127. package/lib/esm/version.js +1 -1
  128. package/package.json +20 -9
  129. package/types/index.d.ts +1806 -1363
  130. 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
- } // 1/k! Sum(i=0 -> k) [(-1)^(k-i)*C(k,j)* i^n]
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
- var kFactorial = factorial(k);
53
- var result = 0;
78
+ if (m === 0) continue;
79
+ var row = cache[m];
80
+ var prev = cache[m - 1];
54
81
 
55
- for (var i = 0; i <= k; i++) {
56
- var negativeOne = pow(-1, subtract(k, i));
57
- var kChooseI = combinations(k, i);
58
- var iPower = pow(i, n);
59
- result = addScalar(result, multiplyScalar(multiplyScalar(kChooseI, iPower), negativeOne));
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 divideScalar(result, kFactorial);
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', 'unaryMinus', 'lup'];
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
- unaryMinus,
14
- lup
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
- // Compute the LU decomposition
110
- var decomp = lup(matrix); // The determinant is the product of the diagonal entries of U (and those of L, but they are all 1)
111
-
112
- var det = decomp.U[0][0];
113
-
114
- for (var _i = 1; _i < rows; _i++) {
115
- det = multiply(det, decomp.U[_i][_i]);
116
- } // The determinant will be multiplied by 1 or -1 depending on the parity of the permutation matrix.
117
- // This can be determined by counting the cycles. This is roughly a linear time algorithm.
118
-
119
-
120
- var evenCycles = 0;
121
- var i = 0;
122
- var visited = [];
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
- while (true) {
125
- while (visited[i]) {
126
- i++;
132
+ if (_k === rows) return matrix[k_][k]; // some zero of the type
127
133
  }
128
134
 
129
- if (i >= rows) break;
130
- var j = i;
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
- while (!visited[decomp.p[j]]) {
134
- visited[decomp.p[j]] = true;
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
- if (cycleLen % 2 === 0) {
140
- evenCycles++;
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
- return evenCycles % 2 === 0 ? det : unaryMinus(det);
147
+ var det = matrix[rowIndices[rows - 1]][rows - 1];
148
+ return negated ? unaryMinus(det) : det;
145
149
  }
146
150
  }
147
151
  });
@@ -132,8 +132,8 @@ export var createExpm = /* #__PURE__ */factory(name, dependencies, _ref => {
132
132
 
133
133
  if (errorEstimate(infNorm, q, j) < eps) {
134
134
  return {
135
- q: q,
136
- j: j
135
+ q,
136
+ j
137
137
  };
138
138
  }
139
139
  }
@@ -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: 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
+ });
@@ -37,7 +37,7 @@ export var createBin = factory(name, dependencies, _ref => {
37
37
  'number | BigNumber, number': function numberBigNumberNumber(n, wordSize) {
38
38
  return format(n, {
39
39
  notation: 'bin',
40
- wordSize: wordSize
40
+ wordSize
41
41
  });
42
42
  }
43
43
  });
@@ -37,7 +37,7 @@ export var createHex = factory(name, dependencies, _ref => {
37
37
  'number | BigNumber, number': function numberBigNumberNumber(n, wordSize) {
38
38
  return format(n, {
39
39
  notation: 'hex',
40
- wordSize: wordSize
40
+ wordSize
41
41
  });
42
42
  }
43
43
  });
@@ -37,7 +37,7 @@ export var createOct = factory(name, dependencies, _ref => {
37
37
  'number | BigNumber, number': function numberBigNumberNumber(n, wordSize) {
38
38
  return format(n, {
39
39
  notation: 'oct',
40
- wordSize: wordSize
40
+ wordSize
41
41
  });
42
42
  }
43
43
  });
@@ -1,4 +1,4 @@
1
- import { isInteger, log2, log10, cbrt, expm1, sign, toFixed, log1p } from '../../utils/number.js';
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, root) {
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