mathjs 10.4.2 → 10.5.1

Sign up to get free protection for your applications and to get access to all the features.
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