diag.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.createDiag = void 0;
  6. var _is = require("../../utils/is.js");
  7. var _array = require("../../utils/array.js");
  8. var _number = require("../../utils/number.js");
  9. var _factory = require("../../utils/factory.js");
  10. var name = 'diag';
  11. var dependencies = ['typed', 'matrix', 'DenseMatrix', 'SparseMatrix'];
  12. var createDiag = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  13. var typed = _ref.typed,
  14. matrix = _ref.matrix,
  15. DenseMatrix = _ref.DenseMatrix,
  16. SparseMatrix = _ref.SparseMatrix;
  17. /**
  18. * Create a diagonal matrix or retrieve the diagonal of a matrix
  19. *
  20. * When `x` is a vector, a matrix with vector `x` on the diagonal will be returned.
  21. * When `x` is a two dimensional matrix, the matrixes `k`th diagonal will be returned as vector.
  22. * When k is positive, the values are placed on the super diagonal.
  23. * When k is negative, the values are placed on the sub diagonal.
  24. *
  25. * Syntax:
  26. *
  27. * math.diag(X)
  28. * math.diag(X, format)
  29. * math.diag(X, k)
  30. * math.diag(X, k, format)
  31. *
  32. * Examples:
  33. *
  34. * // create a diagonal matrix
  35. * math.diag([1, 2, 3]) // returns [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
  36. * math.diag([1, 2, 3], 1) // returns [[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]]
  37. * math.diag([1, 2, 3], -1) // returns [[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3]]
  38. *
  39. * // retrieve the diagonal from a matrix
  40. * const a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
  41. * math.diag(a) // returns [1, 5, 9]
  42. *
  43. * See also:
  44. *
  45. * ones, zeros, identity
  46. *
  47. * @param {Matrix | Array} x A two dimensional matrix or a vector
  48. * @param {number | BigNumber} [k=0] The diagonal where the vector will be filled
  49. * in or retrieved.
  50. * @param {string} [format='dense'] The matrix storage format.
  51. *
  52. * @returns {Matrix | Array} Diagonal matrix from input vector, or diagonal from input matrix.
  53. */
  54. return typed(name, {
  55. // FIXME: simplify this huge amount of signatures as soon as typed-function supports optional arguments
  56. Array: function Array(x) {
  57. return _diag(x, 0, (0, _array.arraySize)(x), null);
  58. },
  59. 'Array, number': function ArrayNumber(x, k) {
  60. return _diag(x, k, (0, _array.arraySize)(x), null);
  61. },
  62. 'Array, BigNumber': function ArrayBigNumber(x, k) {
  63. return _diag(x, k.toNumber(), (0, _array.arraySize)(x), null);
  64. },
  65. 'Array, string': function ArrayString(x, format) {
  66. return _diag(x, 0, (0, _array.arraySize)(x), format);
  67. },
  68. 'Array, number, string': function ArrayNumberString(x, k, format) {
  69. return _diag(x, k, (0, _array.arraySize)(x), format);
  70. },
  71. 'Array, BigNumber, string': function ArrayBigNumberString(x, k, format) {
  72. return _diag(x, k.toNumber(), (0, _array.arraySize)(x), format);
  73. },
  74. Matrix: function Matrix(x) {
  75. return _diag(x, 0, x.size(), x.storage());
  76. },
  77. 'Matrix, number': function MatrixNumber(x, k) {
  78. return _diag(x, k, x.size(), x.storage());
  79. },
  80. 'Matrix, BigNumber': function MatrixBigNumber(x, k) {
  81. return _diag(x, k.toNumber(), x.size(), x.storage());
  82. },
  83. 'Matrix, string': function MatrixString(x, format) {
  84. return _diag(x, 0, x.size(), format);
  85. },
  86. 'Matrix, number, string': function MatrixNumberString(x, k, format) {
  87. return _diag(x, k, x.size(), format);
  88. },
  89. 'Matrix, BigNumber, string': function MatrixBigNumberString(x, k, format) {
  90. return _diag(x, k.toNumber(), x.size(), format);
  91. }
  92. });
  93. /**
  94. * Creeate diagonal matrix from a vector or vice versa
  95. * @param {Array | Matrix} x
  96. * @param {number} k
  97. * @param {string} format Storage format for matrix. If null,
  98. * an Array is returned
  99. * @returns {Array | Matrix}
  100. * @private
  101. */
  102. function _diag(x, k, size, format) {
  103. if (!(0, _number.isInteger)(k)) {
  104. throw new TypeError('Second parameter in function diag must be an integer');
  105. }
  106. var kSuper = k > 0 ? k : 0;
  107. var kSub = k < 0 ? -k : 0;
  108. // check dimensions
  109. switch (size.length) {
  110. case 1:
  111. return _createDiagonalMatrix(x, k, format, size[0], kSub, kSuper);
  112. case 2:
  113. return _getDiagonal(x, k, format, size, kSub, kSuper);
  114. }
  115. throw new RangeError('Matrix for function diag must be 2 dimensional');
  116. }
  117. function _createDiagonalMatrix(x, k, format, l, kSub, kSuper) {
  118. // matrix size
  119. var ms = [l + kSub, l + kSuper];
  120. if (format && format !== 'sparse' && format !== 'dense') {
  121. throw new TypeError("Unknown matrix type ".concat(format, "\""));
  122. }
  123. // create diagonal matrix
  124. var m = format === 'sparse' ? SparseMatrix.diagonal(ms, x, k) : DenseMatrix.diagonal(ms, x, k);
  125. // check we need to return a matrix
  126. return format !== null ? m : m.valueOf();
  127. }
  128. function _getDiagonal(x, k, format, s, kSub, kSuper) {
  129. // check x is a Matrix
  130. if ((0, _is.isMatrix)(x)) {
  131. // get diagonal matrix
  132. var dm = x.diagonal(k);
  133. // check we need to return a matrix
  134. if (format !== null) {
  135. // check we need to change matrix format
  136. if (format !== dm.storage()) {
  137. return matrix(dm, format);
  138. }
  139. return dm;
  140. }
  141. return dm.valueOf();
  142. }
  143. // vector size
  144. var n = Math.min(s[0] - kSub, s[1] - kSuper);
  145. // diagonal values
  146. var vector = [];
  147. // loop diagonal
  148. for (var i = 0; i < n; i++) {
  149. vector[i] = x[i + kSub][i + kSuper];
  150. }
  151. // check we need to return a matrix
  152. return format !== null ? matrix(vector) : vector;
  153. }
  154. });
  155. exports.createDiag = createDiag;