lusolve.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { isArray, isMatrix } from '../../../utils/is.js';
  2. import { factory } from '../../../utils/factory.js';
  3. import { createSolveValidation } from './utils/solveValidation.js';
  4. import { csIpvec } from '../sparse/csIpvec.js';
  5. var name = 'lusolve';
  6. var dependencies = ['typed', 'matrix', 'lup', 'slu', 'usolve', 'lsolve', 'DenseMatrix'];
  7. export var createLusolve = /* #__PURE__ */factory(name, dependencies, _ref => {
  8. var {
  9. typed,
  10. matrix,
  11. lup,
  12. slu,
  13. usolve,
  14. lsolve,
  15. DenseMatrix
  16. } = _ref;
  17. var solveValidation = createSolveValidation({
  18. DenseMatrix
  19. });
  20. /**
  21. * Solves the linear system `A * x = b` where `A` is an [n x n] matrix and `b` is a [n] column vector.
  22. *
  23. * Syntax:
  24. *
  25. * math.lusolve(A, b) // returns column vector with the solution to the linear system A * x = b
  26. * math.lusolve(lup, b) // returns column vector with the solution to the linear system A * x = b, lup = math.lup(A)
  27. *
  28. * Examples:
  29. *
  30. * const m = [[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]]
  31. *
  32. * const x = math.lusolve(m, [-1, -1, -1, -1]) // x = [[-1], [-0.5], [-1/3], [-0.25]]
  33. *
  34. * const f = math.lup(m)
  35. * const x1 = math.lusolve(f, [-1, -1, -1, -1]) // x1 = [[-1], [-0.5], [-1/3], [-0.25]]
  36. * const x2 = math.lusolve(f, [1, 2, 1, -1]) // x2 = [[1], [1], [1/3], [-0.25]]
  37. *
  38. * const a = [[-2, 3], [2, 1]]
  39. * const b = [11, 9]
  40. * const x = math.lusolve(a, b) // [[2], [5]]
  41. *
  42. * See also:
  43. *
  44. * lup, slu, lsolve, usolve
  45. *
  46. * @param {Matrix | Array | Object} A Invertible Matrix or the Matrix LU decomposition
  47. * @param {Matrix | Array} b Column Vector
  48. * @param {number} [order] The Symbolic Ordering and Analysis order, see slu for details. Matrix must be a SparseMatrix
  49. * @param {Number} [threshold] Partial pivoting threshold (1 for partial pivoting), see slu for details. Matrix must be a SparseMatrix.
  50. *
  51. * @return {DenseMatrix | Array} Column vector with the solution to the linear system A * x = b
  52. */
  53. return typed(name, {
  54. 'Array, Array | Matrix': function ArrayArrayMatrix(a, b) {
  55. a = matrix(a);
  56. var d = lup(a);
  57. var x = _lusolve(d.L, d.U, d.p, null, b);
  58. return x.valueOf();
  59. },
  60. 'DenseMatrix, Array | Matrix': function DenseMatrixArrayMatrix(a, b) {
  61. var d = lup(a);
  62. return _lusolve(d.L, d.U, d.p, null, b);
  63. },
  64. 'SparseMatrix, Array | Matrix': function SparseMatrixArrayMatrix(a, b) {
  65. var d = lup(a);
  66. return _lusolve(d.L, d.U, d.p, null, b);
  67. },
  68. 'SparseMatrix, Array | Matrix, number, number': function SparseMatrixArrayMatrixNumberNumber(a, b, order, threshold) {
  69. var d = slu(a, order, threshold);
  70. return _lusolve(d.L, d.U, d.p, d.q, b);
  71. },
  72. 'Object, Array | Matrix': function ObjectArrayMatrix(d, b) {
  73. return _lusolve(d.L, d.U, d.p, d.q, b);
  74. }
  75. });
  76. function _toMatrix(a) {
  77. if (isMatrix(a)) {
  78. return a;
  79. }
  80. if (isArray(a)) {
  81. return matrix(a);
  82. }
  83. throw new TypeError('Invalid Matrix LU decomposition');
  84. }
  85. function _lusolve(l, u, p, q, b) {
  86. // verify decomposition
  87. l = _toMatrix(l);
  88. u = _toMatrix(u);
  89. // apply row permutations if needed (b is a DenseMatrix)
  90. if (p) {
  91. b = solveValidation(l, b, true);
  92. b._data = csIpvec(p, b._data);
  93. }
  94. // use forward substitution to resolve L * y = b
  95. var y = lsolve(l, b);
  96. // use backward substitution to resolve U * x = y
  97. var x = usolve(u, y);
  98. // apply column permutations if needed (x is a DenseMatrix)
  99. if (q) {
  100. x._data = csIpvec(q, x._data);
  101. }
  102. return x;
  103. }
  104. });