UNPKG

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