mathjs 7.2.0 → 7.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 (159) hide show
  1. package/HISTORY.md +34 -0
  2. package/dist/math.js +3421 -2476
  3. package/dist/math.min.js +5 -5
  4. package/dist/math.min.map +1 -1
  5. package/docs/expressions/syntax.md +30 -4
  6. package/docs/reference/functions/bin.md +38 -0
  7. package/docs/reference/functions/ceil.md +10 -1
  8. package/docs/reference/functions/fix.md +10 -2
  9. package/docs/reference/functions/floor.md +12 -3
  10. package/docs/reference/functions/hex.md +38 -0
  11. package/docs/reference/functions/lsolve.md +2 -1
  12. package/docs/reference/functions/lsolveAll.md +45 -0
  13. package/docs/reference/functions/oct.md +38 -0
  14. package/docs/reference/functions/rotationMatrix.md +51 -0
  15. package/docs/reference/functions/round.md +6 -2
  16. package/docs/reference/functions/usolve.md +2 -1
  17. package/docs/reference/functions/usolveAll.md +45 -0
  18. package/docs/reference/functions.md +8 -2
  19. package/es/entry/dependenciesAny/dependenciesBin.generated.js +10 -0
  20. package/es/entry/dependenciesAny/dependenciesCeil.generated.js +4 -0
  21. package/es/entry/dependenciesAny/dependenciesFix.generated.js +2 -0
  22. package/es/entry/dependenciesAny/dependenciesFloor.generated.js +4 -0
  23. package/es/entry/dependenciesAny/dependenciesHex.generated.js +10 -0
  24. package/es/entry/dependenciesAny/dependenciesLsolveAll.generated.js +22 -0
  25. package/es/entry/dependenciesAny/dependenciesOct.generated.js +10 -0
  26. package/es/entry/dependenciesAny/dependenciesRotationMatrix.generated.js +30 -0
  27. package/es/entry/dependenciesAny/dependenciesUsolveAll.generated.js +22 -0
  28. package/es/entry/dependenciesAny.generated.js +6 -0
  29. package/es/entry/impureFunctionsAny.generated.js +63 -57
  30. package/es/entry/pureFunctionsAny.generated.js +323 -277
  31. package/es/expression/embeddedDocs/embeddedDocs.js +12 -0
  32. package/es/expression/embeddedDocs/function/algebra/lsolve.js +2 -2
  33. package/es/expression/embeddedDocs/function/algebra/lsolveAll.js +8 -0
  34. package/es/expression/embeddedDocs/function/algebra/usolve.js +2 -2
  35. package/es/expression/embeddedDocs/function/algebra/usolveAll.js +8 -0
  36. package/es/expression/embeddedDocs/function/matrix/rotationMatrix.js +8 -0
  37. package/es/expression/embeddedDocs/function/utils/bin.js +8 -0
  38. package/es/expression/embeddedDocs/function/utils/hex.js +8 -0
  39. package/es/expression/embeddedDocs/function/utils/oct.js +8 -0
  40. package/es/expression/parse.js +28 -1
  41. package/es/factoriesAny.js +6 -0
  42. package/es/function/algebra/solver/lsolve.js +42 -69
  43. package/es/function/algebra/solver/lsolveAll.js +213 -0
  44. package/es/function/algebra/solver/lusolve.js +12 -27
  45. package/es/function/algebra/solver/usolve.js +41 -64
  46. package/es/function/algebra/solver/usolveAll.js +213 -0
  47. package/es/function/algebra/solver/utils/solveValidation.js +66 -107
  48. package/es/function/arithmetic/ceil.js +88 -4
  49. package/es/function/arithmetic/fix.js +43 -6
  50. package/es/function/arithmetic/floor.js +90 -6
  51. package/es/function/arithmetic/mod.js +10 -1
  52. package/es/function/arithmetic/round.js +6 -2
  53. package/es/function/matrix/rotationMatrix.js +175 -0
  54. package/es/function/matrix/sqrtm.js +4 -0
  55. package/es/function/probability/pickRandom.js +2 -6
  56. package/es/function/statistics/variance.js +4 -4
  57. package/es/function/string/baseUtils.js +36 -0
  58. package/es/function/string/bin.js +23 -0
  59. package/es/function/string/hex.js +23 -0
  60. package/es/function/string/oct.js +23 -0
  61. package/es/type/bignumber/BigNumber.js +4 -1
  62. package/es/type/number.js +10 -0
  63. package/es/utils/object.js +3 -1
  64. package/es/version.js +1 -1
  65. package/examples/advanced/web_server/math_worker.js +1 -1
  66. package/lib/entry/dependenciesAny/dependenciesBin.generated.js +20 -0
  67. package/lib/entry/dependenciesAny/dependenciesCeil.generated.js +6 -0
  68. package/lib/entry/dependenciesAny/dependenciesFix.generated.js +3 -0
  69. package/lib/entry/dependenciesAny/dependenciesFloor.generated.js +6 -0
  70. package/lib/entry/dependenciesAny/dependenciesHex.generated.js +20 -0
  71. package/lib/entry/dependenciesAny/dependenciesLsolveAll.generated.js +38 -0
  72. package/lib/entry/dependenciesAny/dependenciesOct.generated.js +20 -0
  73. package/lib/entry/dependenciesAny/dependenciesRotationMatrix.generated.js +50 -0
  74. package/lib/entry/dependenciesAny/dependenciesUsolveAll.generated.js +38 -0
  75. package/lib/entry/dependenciesAny.generated.js +48 -0
  76. package/lib/entry/impureFunctionsAny.generated.js +65 -59
  77. package/lib/entry/pureFunctionsAny.generated.js +373 -321
  78. package/lib/expression/embeddedDocs/embeddedDocs.js +18 -0
  79. package/lib/expression/embeddedDocs/function/algebra/lsolve.js +2 -2
  80. package/lib/expression/embeddedDocs/function/algebra/lsolveAll.js +15 -0
  81. package/lib/expression/embeddedDocs/function/algebra/usolve.js +2 -2
  82. package/lib/expression/embeddedDocs/function/algebra/usolveAll.js +15 -0
  83. package/lib/expression/embeddedDocs/function/matrix/rotationMatrix.js +15 -0
  84. package/lib/expression/embeddedDocs/function/utils/bin.js +15 -0
  85. package/lib/expression/embeddedDocs/function/utils/hex.js +15 -0
  86. package/lib/expression/embeddedDocs/function/utils/oct.js +15 -0
  87. package/lib/expression/parse.js +28 -1
  88. package/lib/factoriesAny.js +48 -0
  89. package/lib/function/algebra/solver/lsolve.js +42 -69
  90. package/lib/function/algebra/solver/lsolveAll.js +223 -0
  91. package/lib/function/algebra/solver/lusolve.js +12 -27
  92. package/lib/function/algebra/solver/usolve.js +41 -64
  93. package/lib/function/algebra/solver/usolveAll.js +223 -0
  94. package/lib/function/algebra/solver/utils/solveValidation.js +65 -106
  95. package/lib/function/arithmetic/ceil.js +91 -4
  96. package/lib/function/arithmetic/fix.js +44 -6
  97. package/lib/function/arithmetic/floor.js +93 -6
  98. package/lib/function/arithmetic/mod.js +10 -1
  99. package/lib/function/arithmetic/round.js +6 -2
  100. package/lib/function/matrix/rotationMatrix.js +185 -0
  101. package/lib/function/matrix/sqrtm.js +4 -0
  102. package/lib/function/probability/pickRandom.js +3 -7
  103. package/lib/function/statistics/variance.js +4 -4
  104. package/lib/function/string/baseUtils.js +45 -0
  105. package/lib/function/string/bin.js +31 -0
  106. package/lib/function/string/hex.js +31 -0
  107. package/lib/function/string/oct.js +31 -0
  108. package/lib/header.js +2 -2
  109. package/lib/type/bignumber/BigNumber.js +3 -1
  110. package/lib/type/number.js +10 -0
  111. package/lib/utils/object.js +3 -1
  112. package/lib/version.js +1 -1
  113. package/package.json +12 -12
  114. package/src/entry/dependenciesAny/dependenciesBin.generated.js +11 -0
  115. package/src/entry/dependenciesAny/dependenciesCeil.generated.js +4 -0
  116. package/src/entry/dependenciesAny/dependenciesFix.generated.js +2 -0
  117. package/src/entry/dependenciesAny/dependenciesFloor.generated.js +4 -0
  118. package/src/entry/dependenciesAny/dependenciesHex.generated.js +11 -0
  119. package/src/entry/dependenciesAny/dependenciesLsolveAll.generated.js +23 -0
  120. package/src/entry/dependenciesAny/dependenciesOct.generated.js +11 -0
  121. package/src/entry/dependenciesAny/dependenciesRotationMatrix.generated.js +31 -0
  122. package/src/entry/dependenciesAny/dependenciesUsolveAll.generated.js +23 -0
  123. package/src/entry/dependenciesAny.generated.js +6 -0
  124. package/src/entry/impureFunctionsAny.generated.js +104 -92
  125. package/src/entry/pureFunctionsAny.generated.js +94 -82
  126. package/src/expression/embeddedDocs/embeddedDocs.js +12 -0
  127. package/src/expression/embeddedDocs/function/algebra/lsolve.js +2 -2
  128. package/src/expression/embeddedDocs/function/algebra/lsolveAll.js +17 -0
  129. package/src/expression/embeddedDocs/function/algebra/usolve.js +2 -2
  130. package/src/expression/embeddedDocs/function/algebra/usolveAll.js +15 -0
  131. package/src/expression/embeddedDocs/function/matrix/rotationMatrix.js +19 -0
  132. package/src/expression/embeddedDocs/function/utils/bin.js +12 -0
  133. package/src/expression/embeddedDocs/function/utils/hex.js +12 -0
  134. package/src/expression/embeddedDocs/function/utils/oct.js +12 -0
  135. package/src/expression/parse.js +25 -0
  136. package/src/factoriesAny.js +6 -0
  137. package/src/function/algebra/solver/lsolve.js +52 -58
  138. package/src/function/algebra/solver/lsolveAll.js +197 -0
  139. package/src/function/algebra/solver/lusolve.js +9 -19
  140. package/src/function/algebra/solver/usolve.js +52 -55
  141. package/src/function/algebra/solver/usolveAll.js +199 -0
  142. package/src/function/algebra/solver/utils/solveValidation.js +78 -86
  143. package/src/function/arithmetic/ceil.js +63 -3
  144. package/src/function/arithmetic/fix.js +45 -6
  145. package/src/function/arithmetic/floor.js +65 -5
  146. package/src/function/arithmetic/mod.js +8 -1
  147. package/src/function/arithmetic/round.js +6 -2
  148. package/src/function/matrix/rotationMatrix.js +185 -0
  149. package/src/function/matrix/sqrtm.js +4 -0
  150. package/src/function/probability/pickRandom.js +2 -6
  151. package/src/function/statistics/variance.js +4 -4
  152. package/src/function/string/baseUtils.js +29 -0
  153. package/src/function/string/bin.js +23 -0
  154. package/src/function/string/hex.js +23 -0
  155. package/src/function/string/oct.js +24 -0
  156. package/src/type/bignumber/BigNumber.js +2 -1
  157. package/src/type/number.js +9 -1
  158. package/src/utils/object.js +3 -1
  159. package/src/version.js +1 -1
@@ -9,6 +9,9 @@ import { isNegativeDocs } from './function/utils/isNegative'
9
9
  import { isIntegerDocs } from './function/utils/isInteger'
10
10
  import { isNaNDocs } from './function/utils/isNaN'
11
11
  import { formatDocs } from './function/utils/format'
12
+ import { binDocs } from './function/utils/bin'
13
+ import { octDocs } from './function/utils/oct'
14
+ import { hexDocs } from './function/utils/hex'
12
15
  import { cloneDocs } from './function/utils/clone'
13
16
  import { toDocs } from './function/units/to'
14
17
  import { tanhDocs } from './function/trigonometry/tanh'
@@ -167,11 +170,13 @@ import { addDocs } from './function/arithmetic/add'
167
170
  import { absDocs } from './function/arithmetic/abs'
168
171
  import { qrDocs } from './function/algebra/qr'
169
172
  import { usolveDocs } from './function/algebra/usolve'
173
+ import { usolveAllDocs } from './function/algebra/usolveAll'
170
174
  import { sluDocs } from './function/algebra/slu'
171
175
  import { rationalizeDocs } from './function/algebra/rationalize'
172
176
  import { simplifyDocs } from './function/algebra/simplify'
173
177
  import { lupDocs } from './function/algebra/lup'
174
178
  import { lsolveDocs } from './function/algebra/lsolve'
179
+ import { lsolveAllDocs } from './function/algebra/lsolveAll'
175
180
  import { derivativeDocs } from './function/algebra/derivative'
176
181
  import { versionDocs } from './constants/version'
177
182
  import { trueDocs } from './constants/true'
@@ -209,6 +214,7 @@ import { sinDocs } from './function/trigonometry/sin'
209
214
  import { numericDocs } from './function/utils/numeric'
210
215
  import { columnDocs } from './function/matrix/column'
211
216
  import { rowDocs } from './function/matrix/row'
217
+ import { rotationMatrixDocs } from './function/matrix/rotationMatrix'
212
218
 
213
219
  export const embeddedDocs = {
214
220
 
@@ -310,12 +316,14 @@ export const embeddedDocs = {
310
316
  // functions - algebra
311
317
  derivative: derivativeDocs,
312
318
  lsolve: lsolveDocs,
319
+ lsolveAll: lsolveAllDocs,
313
320
  lup: lupDocs,
314
321
  lusolve: lusolveDocs,
315
322
  simplify: simplifyDocs,
316
323
  rationalize: rationalizeDocs,
317
324
  slu: sluDocs,
318
325
  usolve: usolveDocs,
326
+ usolveAll: usolveAllDocs,
319
327
  qr: qrDocs,
320
328
 
321
329
  // functions - arithmetic
@@ -419,6 +427,7 @@ export const embeddedDocs = {
419
427
  range: rangeDocs,
420
428
  resize: resizeDocs,
421
429
  reshape: reshapeDocs,
430
+ rotationMatrix: rotationMatrixDocs,
422
431
  row: rowDocs,
423
432
  size: sizeDocs,
424
433
  sort: sortDocs,
@@ -515,6 +524,9 @@ export const embeddedDocs = {
515
524
  // functions - utils
516
525
  clone: cloneDocs,
517
526
  format: formatDocs,
527
+ bin: binDocs,
528
+ oct: octDocs,
529
+ hex: hexDocs,
518
530
  isNaN: isNaNDocs,
519
531
  isInteger: isIntegerDocs,
520
532
  isNegative: isNegativeDocs,
@@ -5,13 +5,13 @@ export const lsolveDocs = {
5
5
  'x=lsolve(L, b)'
6
6
  ],
7
7
  description:
8
- 'Solves the linear system L * x = b where L is an [n x n] lower triangular matrix and b is a [n] column vector.',
8
+ 'Finds one solution of the linear system L * x = b where L is an [n x n] lower triangular matrix and b is a [n] column vector.',
9
9
  examples: [
10
10
  'a = [-2, 3; 2, 1]',
11
11
  'b = [11, 9]',
12
12
  'x = lsolve(a, b)'
13
13
  ],
14
14
  seealso: [
15
- 'lup', 'lusolve', 'usolve', 'matrix', 'sparse'
15
+ 'lsolveAll', 'lup', 'lusolve', 'usolve', 'matrix', 'sparse'
16
16
  ]
17
17
  }
@@ -0,0 +1,17 @@
1
+ export const lsolveAllDocs = {
2
+ name: 'lsolveAll',
3
+ category: 'Algebra',
4
+ syntax: [
5
+ 'x=lsolveAll(L, b)'
6
+ ],
7
+ description:
8
+ 'Finds all solutions of the linear system L * x = b where L is an [n x n] lower triangular matrix and b is a [n] column vector.',
9
+ examples: [
10
+ 'a = [-2, 3; 2, 1]',
11
+ 'b = [11, 9]',
12
+ 'x = lsolve(a, b)'
13
+ ],
14
+ seealso: [
15
+ 'lsolve', 'lup', 'lusolve', 'usolve', 'matrix', 'sparse'
16
+ ]
17
+ }
@@ -5,11 +5,11 @@ export const usolveDocs = {
5
5
  'x=usolve(U, b)'
6
6
  ],
7
7
  description:
8
- 'Solves the linear system U * x = b where U is an [n x n] upper triangular matrix and b is a [n] column vector.',
8
+ 'Finds one solution of the linear system U * x = b where U is an [n x n] upper triangular matrix and b is a [n] column vector.',
9
9
  examples: [
10
10
  'x=usolve(sparse([1, 1, 1, 1; 0, 1, 1, 1; 0, 0, 1, 1; 0, 0, 0, 1]), [1; 2; 3; 4])'
11
11
  ],
12
12
  seealso: [
13
- 'lup', 'lusolve', 'lsolve', 'matrix', 'sparse'
13
+ 'usolveAll', 'lup', 'lusolve', 'lsolve', 'matrix', 'sparse'
14
14
  ]
15
15
  }
@@ -0,0 +1,15 @@
1
+ export const usolveAllDocs = {
2
+ name: 'usolveAll',
3
+ category: 'Algebra',
4
+ syntax: [
5
+ 'x=usolve(U, b)'
6
+ ],
7
+ description:
8
+ 'Finds all solutions of the linear system U * x = b where U is an [n x n] upper triangular matrix and b is a [n] column vector.',
9
+ examples: [
10
+ 'x=usolve(sparse([1, 1, 1, 1; 0, 1, 1, 1; 0, 0, 1, 1; 0, 0, 0, 1]), [1; 2; 3; 4])'
11
+ ],
12
+ seealso: [
13
+ 'usolve', 'lup', 'lusolve', 'lsolve', 'matrix', 'sparse'
14
+ ]
15
+ }
@@ -0,0 +1,19 @@
1
+ export const rotationMatrixDocs = {
2
+ name: 'rotationMatrix',
3
+ category: 'Matrix',
4
+ syntax: [
5
+ 'rotationMatrix(theta)',
6
+ 'rotationMatrix(theta, v)',
7
+ 'rotationMatrix(theta, v, format)'
8
+ ],
9
+ description: 'Returns a 2-D rotation matrix (2x2) for a given angle (in radians). ' +
10
+ 'Returns a 2-D rotation matrix (3x3) of a given angle (in radians) around given axis.',
11
+ examples: [
12
+ 'rotationMatrix(pi / 2)',
13
+ 'rotationMatrix(unit("45deg"), [0, 0, 1])',
14
+ 'rotationMatrix(1, matrix([0, 0, 1]), "sparse")'
15
+ ],
16
+ seealso: [
17
+ 'cos', 'sin'
18
+ ]
19
+ }
@@ -0,0 +1,12 @@
1
+ export const binDocs = {
2
+ name: 'bin',
3
+ category: 'Utils',
4
+ syntax: [
5
+ 'bin(value)'
6
+ ],
7
+ description: 'Format a number as binary',
8
+ examples: [
9
+ 'bin(2)'
10
+ ],
11
+ seealso: ['oct', 'hex']
12
+ }
@@ -0,0 +1,12 @@
1
+ export const hexDocs = {
2
+ name: 'hex',
3
+ category: 'Utils',
4
+ syntax: [
5
+ 'hex(value)'
6
+ ],
7
+ description: 'Format a number as hexadecimal',
8
+ examples: [
9
+ 'hex(240)'
10
+ ],
11
+ seealso: ['bin', 'oct']
12
+ }
@@ -0,0 +1,12 @@
1
+ export const octDocs = {
2
+ name: 'oct',
3
+ category: 'Utils',
4
+ syntax: [
5
+ 'oct(value)'
6
+ ],
7
+ description: 'Format a number as octal',
8
+ examples: [
9
+ 'oct(56)'
10
+ ],
11
+ seealso: ['bin', 'hex']
12
+ }
@@ -321,6 +321,20 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
321
321
  if (parse.isDigitDot(c1)) {
322
322
  state.tokenType = TOKENTYPE.NUMBER
323
323
 
324
+ // check for binary, octal, or hex
325
+ const c2 = currentString(state, 2)
326
+ if (c2 === '0b' || c2 === '0o' || c2 === '0x') {
327
+ state.token += currentCharacter(state)
328
+ next(state)
329
+ state.token += currentCharacter(state)
330
+ next(state)
331
+ while (parse.isHexDigit(currentCharacter(state))) {
332
+ state.token += currentCharacter(state)
333
+ next(state)
334
+ }
335
+ return
336
+ }
337
+
324
338
  // get number, can have a single dot
325
339
  if (currentCharacter(state) === '.') {
326
340
  state.token += currentCharacter(state)
@@ -522,6 +536,17 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
522
536
  return (c >= '0' && c <= '9')
523
537
  }
524
538
 
539
+ /**
540
+ * checks if the given char c is a hex digit
541
+ * @param {string} c a string with one character
542
+ * @return {boolean}
543
+ */
544
+ parse.isHexDigit = function isHexDigit (c) {
545
+ return ((c >= '0' && c <= '9') ||
546
+ (c >= 'a' && c <= 'f') ||
547
+ (c >= 'A' && c <= 'F'))
548
+ }
549
+
525
550
  /**
526
551
  * Start of the parse levels below, in order of precedence
527
552
  * @return {Node} node
@@ -78,6 +78,7 @@ export { createOnes } from './function/matrix/ones'
78
78
  export { createRange } from './function/matrix/range'
79
79
  export { createReshape } from './function/matrix/reshape'
80
80
  export { createResize } from './function/matrix/resize'
81
+ export { createRotationMatrix } from './function/matrix/rotationMatrix'
81
82
  export { createRow } from './function/matrix/row'
82
83
  export { createSize } from './function/matrix/size'
83
84
  export { createSqueeze } from './function/matrix/squeeze'
@@ -89,6 +90,9 @@ export { createErf } from './function/special/erf'
89
90
  export { createMode } from './function/statistics/mode'
90
91
  export { createProd } from './function/statistics/prod'
91
92
  export { createFormat } from './function/string/format'
93
+ export { createBin } from './function/string/bin'
94
+ export { createOct } from './function/string/oct'
95
+ export { createHex } from './function/string/hex'
92
96
  export { createPrint } from './function/string/print'
93
97
  export { createTo } from './function/unit/to'
94
98
  export { createIsPrime } from './function/utils/isPrime'
@@ -103,6 +107,8 @@ export { createDotPow } from './function/arithmetic/dotPow'
103
107
  export { createDotDivide } from './function/arithmetic/dotDivide'
104
108
  export { createLsolve } from './function/algebra/solver/lsolve'
105
109
  export { createUsolve } from './function/algebra/solver/usolve'
110
+ export { createLsolveAll } from './function/algebra/solver/lsolveAll'
111
+ export { createUsolveAll } from './function/algebra/solver/usolveAll'
106
112
  export { createLeftShift } from './function/bitwise/leftShift'
107
113
  export { createRightArithShift } from './function/bitwise/rightArithShift'
108
114
  export { createRightLogShift } from './function/bitwise/rightLogShift'
@@ -16,7 +16,7 @@ export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed
16
16
  const solveValidation = createSolveValidation({ DenseMatrix })
17
17
 
18
18
  /**
19
- * Solves the linear equation system by forwards substitution. Matrix must be a lower triangular matrix.
19
+ * Finds one solution of a linear equation system by forwards substitution. Matrix must be a lower triangular matrix. Throws an error if there's no solution.
20
20
  *
21
21
  * `L * x = b`
22
22
  *
@@ -32,7 +32,7 @@ export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed
32
32
  *
33
33
  * See also:
34
34
  *
35
- * lup, slu, usolve, lusolve
35
+ * lsolveAll, lup, slu, usolve, lusolve
36
36
  *
37
37
  * @param {Matrix, Array} L A N x N matrix or array (L)
38
38
  * @param {Matrix, Array} b A column vector with the b values
@@ -42,21 +42,16 @@ export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed
42
42
  return typed(name, {
43
43
 
44
44
  'SparseMatrix, Array | Matrix': function (m, b) {
45
- // process matrix
46
45
  return _sparseForwardSubstitution(m, b)
47
46
  },
48
47
 
49
48
  'DenseMatrix, Array | Matrix': function (m, b) {
50
- // process matrix
51
49
  return _denseForwardSubstitution(m, b)
52
50
  },
53
51
 
54
52
  'Array, Array | Matrix': function (a, b) {
55
- // create dense matrix from array
56
53
  const m = matrix(a)
57
- // use matrix implementation
58
54
  const r = _denseForwardSubstitution(m, b)
59
- // result
60
55
  return r.valueOf()
61
56
  }
62
57
  })
@@ -64,45 +59,44 @@ export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed
64
59
  function _denseForwardSubstitution (m, b) {
65
60
  // validate matrix and vector, return copy of column vector b
66
61
  b = solveValidation(m, b, true)
67
- // column vector data
68
62
  const bdata = b._data
69
- // rows & columns
63
+
70
64
  const rows = m._size[0]
71
65
  const columns = m._size[1]
66
+
72
67
  // result
73
68
  const x = []
74
- // data
75
- const data = m._data
76
- // forward solve m * x = b, loop columns
69
+
70
+ const mdata = m._data
71
+
72
+ // loop columns
77
73
  for (let j = 0; j < columns; j++) {
78
- // b[j]
79
74
  const bj = bdata[j][0] || 0
80
- // x[j]
81
75
  let xj
82
- // forward substitution (outer product) avoids inner looping when bj === 0
76
+
83
77
  if (!equalScalar(bj, 0)) {
84
- // value @ [j, j]
85
- const vjj = data[j][j]
86
- // check vjj
78
+ // non-degenerate row, find solution
79
+
80
+ const vjj = mdata[j][j]
81
+
87
82
  if (equalScalar(vjj, 0)) {
88
- // system cannot be solved
89
83
  throw new Error('Linear system cannot be solved since matrix is singular')
90
84
  }
91
- // calculate xj
85
+
92
86
  xj = divideScalar(bj, vjj)
87
+
93
88
  // loop rows
94
89
  for (let i = j + 1; i < rows; i++) {
95
- // update copy of b
96
- bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, data[i][j]))]
90
+ bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, mdata[i][j]))]
97
91
  }
98
92
  } else {
99
- // zero @ j
93
+ // degenerate row, we can choose any value
100
94
  xj = 0
101
95
  }
102
- // update x
96
+
103
97
  x[j] = [xj]
104
98
  }
105
- // return vector
99
+
106
100
  return new DenseMatrix({
107
101
  data: x,
108
102
  size: [rows, 1]
@@ -112,68 +106,68 @@ export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed
112
106
  function _sparseForwardSubstitution (m, b) {
113
107
  // validate matrix and vector, return copy of column vector b
114
108
  b = solveValidation(m, b, true)
115
- // column vector data
109
+
116
110
  const bdata = b._data
117
- // rows & columns
111
+
118
112
  const rows = m._size[0]
119
113
  const columns = m._size[1]
120
- // matrix arrays
114
+
121
115
  const values = m._values
122
116
  const index = m._index
123
117
  const ptr = m._ptr
124
- // vars
125
- let i, k
118
+
126
119
  // result
127
120
  const x = []
128
- // forward solve m * x = b, loop columns
121
+
122
+ // loop columns
129
123
  for (let j = 0; j < columns; j++) {
130
- // b[j]
131
124
  const bj = bdata[j][0] || 0
132
- // forward substitution (outer product) avoids inner looping when bj === 0
125
+
133
126
  if (!equalScalar(bj, 0)) {
134
- // value @ [j, j]
127
+ // non-degenerate row, find solution
128
+
135
129
  let vjj = 0
136
- // lower triangular matrix values & index (column j)
137
- const jvalues = []
138
- const jindex = []
139
- // last index in column
140
- let l = ptr[j + 1]
141
- // values in column, find value @ [j, j]
142
- for (k = ptr[j]; k < l; k++) {
143
- // row
144
- i = index[k]
130
+ // matrix values & indices (column j)
131
+ const jValues = []
132
+ const jIndices = []
133
+
134
+ // first and last index in the column
135
+ const firstIndex = ptr[j]
136
+ const lastIndex = ptr[j + 1]
137
+
138
+ // values in column, find value at [j, j]
139
+ for (let k = firstIndex; k < lastIndex; k++) {
140
+ const i = index[k]
141
+
145
142
  // check row (rows are not sorted!)
146
143
  if (i === j) {
147
- // update vjj
148
144
  vjj = values[k]
149
145
  } else if (i > j) {
150
146
  // store lower triangular
151
- jvalues.push(values[k])
152
- jindex.push(i)
147
+ jValues.push(values[k])
148
+ jIndices.push(i)
153
149
  }
154
150
  }
155
- // at this point we must have a value @ [j, j]
151
+
152
+ // at this point we must have a value in vjj
156
153
  if (equalScalar(vjj, 0)) {
157
- // system cannot be solved, there is no value @ [j, j]
158
154
  throw new Error('Linear system cannot be solved since matrix is singular')
159
155
  }
160
- // calculate xj
156
+
161
157
  const xj = divideScalar(bj, vjj)
162
- // loop lower triangular
163
- for (k = 0, l = jindex.length; k < l; k++) {
164
- // row
165
- i = jindex[k]
166
- // update copy of b
167
- bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, jvalues[k]))]
158
+
159
+ for (let k = 0, l = jIndices.length; k < l; k++) {
160
+ const i = jIndices[k]
161
+ bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, jValues[k]))]
168
162
  }
169
- // update x
163
+
170
164
  x[j] = [xj]
171
165
  } else {
172
- // update x
166
+ // degenerate row, we can choose any value
173
167
  x[j] = [0]
174
168
  }
175
169
  }
176
- // return vector
170
+
177
171
  return new DenseMatrix({
178
172
  data: x,
179
173
  size: [rows, 1]
@@ -0,0 +1,197 @@
1
+ import { factory } from '../../../utils/factory'
2
+ import { createSolveValidation } from './utils/solveValidation'
3
+
4
+ const name = 'lsolveAll'
5
+ const dependencies = [
6
+ 'typed',
7
+ 'matrix',
8
+ 'divideScalar',
9
+ 'multiplyScalar',
10
+ 'subtract',
11
+ 'equalScalar',
12
+ 'DenseMatrix'
13
+ ]
14
+
15
+ export const createLsolveAll = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, divideScalar, multiplyScalar, subtract, equalScalar, DenseMatrix }) => {
16
+ const solveValidation = createSolveValidation({ DenseMatrix })
17
+
18
+ /**
19
+ * Finds all solutions of a linear equation system by forwards substitution. Matrix must be a lower triangular matrix.
20
+ *
21
+ * `L * x = b`
22
+ *
23
+ * Syntax:
24
+ *
25
+ * math.lsolve(L, b)
26
+ *
27
+ * Examples:
28
+ *
29
+ * const a = [[-2, 3], [2, 1]]
30
+ * const b = [11, 9]
31
+ * const x = lsolve(a, b) // [ [[-5.5], [20]] ]
32
+ *
33
+ * See also:
34
+ *
35
+ * lsolve, lup, slu, usolve, lusolve
36
+ *
37
+ * @param {Matrix, Array} L A N x N matrix or array (L)
38
+ * @param {Matrix, Array} b A column vector with the b values
39
+ *
40
+ * @return {DenseMatrix[] | Array[]} An array of affine-independent column vectors (x) that solve the linear system
41
+ */
42
+ return typed(name, {
43
+
44
+ 'SparseMatrix, Array | Matrix': function (m, b) {
45
+ return _sparseForwardSubstitution(m, b)
46
+ },
47
+
48
+ 'DenseMatrix, Array | Matrix': function (m, b) {
49
+ return _denseForwardSubstitution(m, b)
50
+ },
51
+
52
+ 'Array, Array | Matrix': function (a, b) {
53
+ const m = matrix(a)
54
+ const R = _denseForwardSubstitution(m, b)
55
+ return R.map(r => r.valueOf())
56
+ }
57
+ })
58
+
59
+ function _denseForwardSubstitution (m, b_) {
60
+ // the algorithm is derived from
61
+ // https://www.overleaf.com/project/5e6c87c554a3190001a3fc93
62
+
63
+ // array of right-hand sides
64
+ const B = [solveValidation(m, b_, true)._data.map(e => e[0])]
65
+
66
+ const M = m._data
67
+ const rows = m._size[0]
68
+ const columns = m._size[1]
69
+
70
+ // loop columns
71
+ for (let i = 0; i < columns; i++) {
72
+ let L = B.length
73
+
74
+ // loop right-hand sides
75
+ for (let k = 0; k < L; k++) {
76
+ const b = B[k]
77
+
78
+ if (!equalScalar(M[i][i], 0)) {
79
+ // non-singular row
80
+
81
+ b[i] = divideScalar(b[i], M[i][i])
82
+
83
+ for (let j = i + 1; j < columns; j++) {
84
+ // b[j] -= b[i] * M[j,i]
85
+ b[j] = subtract(b[j], multiplyScalar(b[i], M[j][i]))
86
+ }
87
+ } else if (!equalScalar(b[i], 0)) {
88
+ // singular row, nonzero RHS
89
+
90
+ if (k === 0) {
91
+ // There is no valid solution
92
+ return []
93
+ } else {
94
+ // This RHS is invalid but other solutions may still exist
95
+ B.splice(k, 1)
96
+ k -= 1
97
+ L -= 1
98
+ }
99
+ } else if (k === 0) {
100
+ // singular row, RHS is zero
101
+
102
+ const bNew = [...b]
103
+ bNew[i] = 1
104
+
105
+ for (let j = i + 1; j < columns; j++) {
106
+ bNew[j] = subtract(bNew[j], M[j][i])
107
+ }
108
+
109
+ B.push(bNew)
110
+ }
111
+ }
112
+ }
113
+
114
+ return B.map(x => new DenseMatrix({ data: x.map(e => [e]), size: [rows, 1] }))
115
+ }
116
+
117
+ function _sparseForwardSubstitution (m, b_) {
118
+ // array of right-hand sides
119
+ const B = [solveValidation(m, b_, true)._data.map(e => e[0])]
120
+
121
+ const rows = m._size[0]
122
+ const columns = m._size[1]
123
+
124
+ const values = m._values
125
+ const index = m._index
126
+ const ptr = m._ptr
127
+
128
+ // loop columns
129
+ for (let i = 0; i < columns; i++) {
130
+ let L = B.length
131
+
132
+ // loop right-hand sides
133
+ for (let k = 0; k < L; k++) {
134
+ const b = B[k]
135
+
136
+ // values & indices (column i)
137
+ const iValues = []
138
+ const iIndices = []
139
+
140
+ // first & last indeces in column
141
+ const firstIndex = ptr[i]
142
+ const lastIndex = ptr[i + 1]
143
+
144
+ // find the value at [i, i]
145
+ let Mii = 0
146
+ for (let j = firstIndex; j < lastIndex; j++) {
147
+ const J = index[j]
148
+ // check row
149
+ if (J === i) {
150
+ Mii = values[j]
151
+ } else if (J > i) {
152
+ // store lower triangular
153
+ iValues.push(values[j])
154
+ iIndices.push(J)
155
+ }
156
+ }
157
+
158
+ if (!equalScalar(Mii, 0)) {
159
+ // non-singular row
160
+
161
+ b[i] = divideScalar(b[i], Mii)
162
+
163
+ for (let j = 0, lastIndex = iIndices.length; j < lastIndex; j++) {
164
+ const J = iIndices[j]
165
+ b[J] = subtract(b[J], multiplyScalar(b[i], iValues[j]))
166
+ }
167
+ } else if (!equalScalar(b[i], 0)) {
168
+ // singular row, nonzero RHS
169
+
170
+ if (k === 0) {
171
+ // There is no valid solution
172
+ return []
173
+ } else {
174
+ // This RHS is invalid but other solutions may still exist
175
+ B.splice(k, 1)
176
+ k -= 1
177
+ L -= 1
178
+ }
179
+ } else if (k === 0) {
180
+ // singular row, RHS is zero
181
+
182
+ const bNew = [...b]
183
+ bNew[i] = 1
184
+
185
+ for (let j = 0, lastIndex = iIndices.length; j < lastIndex; j++) {
186
+ const J = iIndices[j]
187
+ bNew[J] = subtract(bNew[J], iValues[j])
188
+ }
189
+
190
+ B.push(bNew)
191
+ }
192
+ }
193
+ }
194
+
195
+ return B.map(x => new DenseMatrix({ data: x.map(e => [e]), size: [rows, 1] }))
196
+ }
197
+ })