sylvester.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.createSylvester = void 0;
  6. var _factory = require("../../utils/factory.js");
  7. var name = 'sylvester';
  8. var dependencies = ['typed', 'schur', 'matrixFromColumns', 'matrix', 'multiply', 'range', 'concat', 'transpose', 'index', 'subset', 'add', 'subtract', 'identity', 'lusolve', 'abs'];
  9. var createSylvester = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  10. var typed = _ref.typed,
  11. schur = _ref.schur,
  12. matrixFromColumns = _ref.matrixFromColumns,
  13. matrix = _ref.matrix,
  14. multiply = _ref.multiply,
  15. range = _ref.range,
  16. concat = _ref.concat,
  17. transpose = _ref.transpose,
  18. index = _ref.index,
  19. subset = _ref.subset,
  20. add = _ref.add,
  21. subtract = _ref.subtract,
  22. identity = _ref.identity,
  23. lusolve = _ref.lusolve,
  24. abs = _ref.abs;
  25. /**
  26. *
  27. * Solves the real-valued Sylvester equation AX+XB=C for X, where A, B and C are
  28. * matrices of appropriate dimensions, being A and B squared. Notice that other
  29. * equivalent definitions for the Sylvester equation exist and this function
  30. * assumes the one presented in the original publication of the the Bartels-
  31. * Stewart algorithm, which is implemented by this function.
  32. * https://en.wikipedia.org/wiki/Sylvester_equation
  33. *
  34. * Syntax:
  35. *
  36. * math.sylvester(A, B, C)
  37. *
  38. * Examples:
  39. *
  40. * const A = [[-1, -2], [1, 1]]
  41. * const B = [[2, -1], [1, -2]]
  42. * const C = [[-3, 2], [3, 0]]
  43. * math.sylvester(A, B, C) // returns DenseMatrix [[-0.25, 0.25], [1.5, -1.25]]
  44. *
  45. * See also:
  46. *
  47. * schur, lyap
  48. *
  49. * @param {Matrix | Array} A Matrix A
  50. * @param {Matrix | Array} B Matrix B
  51. * @param {Matrix | Array} C Matrix C
  52. * @return {Matrix | Array} Matrix X, solving the Sylvester equation
  53. */
  54. return typed(name, {
  55. 'Matrix, Matrix, Matrix': _sylvester,
  56. 'Array, Matrix, Matrix': function ArrayMatrixMatrix(A, B, C) {
  57. return _sylvester(matrix(A), B, C);
  58. },
  59. 'Array, Array, Matrix': function ArrayArrayMatrix(A, B, C) {
  60. return _sylvester(matrix(A), matrix(B), C);
  61. },
  62. 'Array, Matrix, Array': function ArrayMatrixArray(A, B, C) {
  63. return _sylvester(matrix(A), B, matrix(C));
  64. },
  65. 'Matrix, Array, Matrix': function MatrixArrayMatrix(A, B, C) {
  66. return _sylvester(A, matrix(B), C);
  67. },
  68. 'Matrix, Array, Array': function MatrixArrayArray(A, B, C) {
  69. return _sylvester(A, matrix(B), matrix(C));
  70. },
  71. 'Matrix, Matrix, Array': function MatrixMatrixArray(A, B, C) {
  72. return _sylvester(A, B, matrix(C));
  73. },
  74. 'Array, Array, Array': function ArrayArrayArray(A, B, C) {
  75. return _sylvester(matrix(A), matrix(B), matrix(C)).toArray();
  76. }
  77. });
  78. function _sylvester(A, B, C) {
  79. var n = B.size()[0];
  80. var m = A.size()[0];
  81. var sA = schur(A);
  82. var F = sA.T;
  83. var U = sA.U;
  84. var sB = schur(multiply(-1, B));
  85. var G = sB.T;
  86. var V = sB.U;
  87. var D = multiply(multiply(transpose(U), C), V);
  88. var all = range(0, m);
  89. var y = [];
  90. var hc = function hc(a, b) {
  91. return concat(a, b, 1);
  92. };
  93. var vc = function vc(a, b) {
  94. return concat(a, b, 0);
  95. };
  96. for (var k = 0; k < n; k++) {
  97. if (k < n - 1 && abs(subset(G, index(k + 1, k))) > 1e-5) {
  98. var RHS = vc(subset(D, index(all, k)), subset(D, index(all, k + 1)));
  99. for (var j = 0; j < k; j++) {
  100. RHS = add(RHS, vc(multiply(y[j], subset(G, index(j, k))), multiply(y[j], subset(G, index(j, k + 1)))));
  101. }
  102. var gkk = multiply(identity(m), multiply(-1, subset(G, index(k, k))));
  103. var gmk = multiply(identity(m), multiply(-1, subset(G, index(k + 1, k))));
  104. var gkm = multiply(identity(m), multiply(-1, subset(G, index(k, k + 1))));
  105. var gmm = multiply(identity(m), multiply(-1, subset(G, index(k + 1, k + 1))));
  106. var LHS = vc(hc(add(F, gkk), gmk), hc(gkm, add(F, gmm)));
  107. var yAux = lusolve(LHS, RHS);
  108. y[k] = yAux.subset(index(range(0, m), 0));
  109. y[k + 1] = yAux.subset(index(range(m, 2 * m), 0));
  110. k++;
  111. } else {
  112. var _RHS = subset(D, index(all, k));
  113. for (var _j = 0; _j < k; _j++) {
  114. _RHS = add(_RHS, multiply(y[_j], subset(G, index(_j, k))));
  115. }
  116. var _gkk = subset(G, index(k, k));
  117. var _LHS = subtract(F, multiply(_gkk, identity(m)));
  118. y[k] = lusolve(_LHS, _RHS);
  119. }
  120. }
  121. var Y = matrix(matrixFromColumns.apply(void 0, y));
  122. var X = multiply(U, multiply(Y, transpose(V)));
  123. return X;
  124. }
  125. });
  126. exports.createSylvester = createSylvester;