mathjs 7.2.0 → 7.5.1

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