UNPKG

25.9 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.createDenseMatrixClass = void 0;
7
8var _is = require("../../utils/is");
9
10var _array = require("../../utils/array");
11
12var _string = require("../../utils/string");
13
14var _number = require("../../utils/number");
15
16var _object = require("../../utils/object");
17
18var _DimensionError = require("../../error/DimensionError");
19
20var _factory = require("../../utils/factory");
21
22var name = 'DenseMatrix';
23var dependencies = ['Matrix'];
24var createDenseMatrixClass =
25/* #__PURE__ */
26(0, _factory.factory)(name, dependencies, function (_ref) {
27 var Matrix = _ref.Matrix;
28
29 /**
30 * Dense Matrix implementation. A regular, dense matrix, supporting multi-dimensional matrices. This is the default matrix type.
31 * @class DenseMatrix
32 */
33 function DenseMatrix(data, datatype) {
34 if (!(this instanceof DenseMatrix)) {
35 throw new SyntaxError('Constructor must be called with the new operator');
36 }
37
38 if (datatype && !(0, _is.isString)(datatype)) {
39 throw new Error('Invalid datatype: ' + datatype);
40 }
41
42 if ((0, _is.isMatrix)(data)) {
43 // check data is a DenseMatrix
44 if (data.type === 'DenseMatrix') {
45 // clone data & size
46 this._data = (0, _object.clone)(data._data);
47 this._size = (0, _object.clone)(data._size);
48 this._datatype = datatype || data._datatype;
49 } else {
50 // build data from existing matrix
51 this._data = data.toArray();
52 this._size = data.size();
53 this._datatype = datatype || data._datatype;
54 }
55 } else if (data && (0, _is.isArray)(data.data) && (0, _is.isArray)(data.size)) {
56 // initialize fields from JSON representation
57 this._data = data.data;
58 this._size = data.size;
59 this._datatype = datatype || data.datatype;
60 } else if ((0, _is.isArray)(data)) {
61 // replace nested Matrices with Arrays
62 this._data = preprocess(data); // get the dimensions of the array
63
64 this._size = (0, _array.arraySize)(this._data); // verify the dimensions of the array, TODO: compute size while processing array
65
66 (0, _array.validate)(this._data, this._size); // data type unknown
67
68 this._datatype = datatype;
69 } else if (data) {
70 // unsupported type
71 throw new TypeError('Unsupported type of data (' + (0, _is.typeOf)(data) + ')');
72 } else {
73 // nothing provided
74 this._data = [];
75 this._size = [0];
76 this._datatype = datatype;
77 }
78 }
79
80 DenseMatrix.prototype = new Matrix();
81 /**
82 * Create a new DenseMatrix
83 */
84
85 DenseMatrix.prototype.createDenseMatrix = function (data, datatype) {
86 return new DenseMatrix(data, datatype);
87 };
88 /**
89 * Attach type information
90 */
91
92
93 DenseMatrix.prototype.type = 'DenseMatrix';
94 DenseMatrix.prototype.isDenseMatrix = true;
95 /**
96 * Get the matrix type
97 *
98 * Usage:
99 * const matrixType = matrix.getDataType() // retrieves the matrix type
100 *
101 * @memberOf DenseMatrix
102 * @return {string} type information; if multiple types are found from the Matrix, it will return "mixed"
103 */
104
105 DenseMatrix.prototype.getDataType = function () {
106 return (0, _array.getArrayDataType)(this._data, _is.typeOf);
107 };
108 /**
109 * Get the storage format used by the matrix.
110 *
111 * Usage:
112 * const format = matrix.storage() // retrieve storage format
113 *
114 * @memberof DenseMatrix
115 * @return {string} The storage format.
116 */
117
118
119 DenseMatrix.prototype.storage = function () {
120 return 'dense';
121 };
122 /**
123 * Get the datatype of the data stored in the matrix.
124 *
125 * Usage:
126 * const format = matrix.datatype() // retrieve matrix datatype
127 *
128 * @memberof DenseMatrix
129 * @return {string} The datatype.
130 */
131
132
133 DenseMatrix.prototype.datatype = function () {
134 return this._datatype;
135 };
136 /**
137 * Create a new DenseMatrix
138 * @memberof DenseMatrix
139 * @param {Array} data
140 * @param {string} [datatype]
141 */
142
143
144 DenseMatrix.prototype.create = function (data, datatype) {
145 return new DenseMatrix(data, datatype);
146 };
147 /**
148 * Get a subset of the matrix, or replace a subset of the matrix.
149 *
150 * Usage:
151 * const subset = matrix.subset(index) // retrieve subset
152 * const value = matrix.subset(index, replacement) // replace subset
153 *
154 * @memberof DenseMatrix
155 * @param {Index} index
156 * @param {Array | Matrix | *} [replacement]
157 * @param {*} [defaultValue=0] Default value, filled in on new entries when
158 * the matrix is resized. If not provided,
159 * new matrix elements will be filled with zeros.
160 */
161
162
163 DenseMatrix.prototype.subset = function (index, replacement, defaultValue) {
164 switch (arguments.length) {
165 case 1:
166 return _get(this, index);
167 // intentional fall through
168
169 case 2:
170 case 3:
171 return _set(this, index, replacement, defaultValue);
172
173 default:
174 throw new SyntaxError('Wrong number of arguments');
175 }
176 };
177 /**
178 * Get a single element from the matrix.
179 * @memberof DenseMatrix
180 * @param {number[]} index Zero-based index
181 * @return {*} value
182 */
183
184
185 DenseMatrix.prototype.get = function (index) {
186 if (!(0, _is.isArray)(index)) {
187 throw new TypeError('Array expected');
188 }
189
190 if (index.length !== this._size.length) {
191 throw new _DimensionError.DimensionError(index.length, this._size.length);
192 } // check index
193
194
195 for (var x = 0; x < index.length; x++) {
196 (0, _array.validateIndex)(index[x], this._size[x]);
197 }
198
199 var data = this._data;
200
201 for (var i = 0, ii = index.length; i < ii; i++) {
202 var indexI = index[i];
203 (0, _array.validateIndex)(indexI, data.length);
204 data = data[indexI];
205 }
206
207 return data;
208 };
209 /**
210 * Replace a single element in the matrix.
211 * @memberof DenseMatrix
212 * @param {number[]} index Zero-based index
213 * @param {*} value
214 * @param {*} [defaultValue] Default value, filled in on new entries when
215 * the matrix is resized. If not provided,
216 * new matrix elements will be left undefined.
217 * @return {DenseMatrix} self
218 */
219
220
221 DenseMatrix.prototype.set = function (index, value, defaultValue) {
222 if (!(0, _is.isArray)(index)) {
223 throw new TypeError('Array expected');
224 }
225
226 if (index.length < this._size.length) {
227 throw new _DimensionError.DimensionError(index.length, this._size.length, '<');
228 }
229
230 var i, ii, indexI; // enlarge matrix when needed
231
232 var size = index.map(function (i) {
233 return i + 1;
234 });
235
236 _fit(this, size, defaultValue); // traverse over the dimensions
237
238
239 var data = this._data;
240
241 for (i = 0, ii = index.length - 1; i < ii; i++) {
242 indexI = index[i];
243 (0, _array.validateIndex)(indexI, data.length);
244 data = data[indexI];
245 } // set new value
246
247
248 indexI = index[index.length - 1];
249 (0, _array.validateIndex)(indexI, data.length);
250 data[indexI] = value;
251 return this;
252 };
253 /**
254 * Get a submatrix of this matrix
255 * @memberof DenseMatrix
256 * @param {DenseMatrix} matrix
257 * @param {Index} index Zero-based index
258 * @private
259 */
260
261
262 function _get(matrix, index) {
263 if (!(0, _is.isIndex)(index)) {
264 throw new TypeError('Invalid index');
265 }
266
267 var isScalar = index.isScalar();
268
269 if (isScalar) {
270 // return a scalar
271 return matrix.get(index.min());
272 } else {
273 // validate dimensions
274 var size = index.size();
275
276 if (size.length !== matrix._size.length) {
277 throw new _DimensionError.DimensionError(size.length, matrix._size.length);
278 } // validate if any of the ranges in the index is out of range
279
280
281 var min = index.min();
282 var max = index.max();
283
284 for (var i = 0, ii = matrix._size.length; i < ii; i++) {
285 (0, _array.validateIndex)(min[i], matrix._size[i]);
286 (0, _array.validateIndex)(max[i], matrix._size[i]);
287 } // retrieve submatrix
288 // TODO: more efficient when creating an empty matrix and setting _data and _size manually
289
290
291 return new DenseMatrix(_getSubmatrix(matrix._data, index, size.length, 0), matrix._datatype);
292 }
293 }
294 /**
295 * Recursively get a submatrix of a multi dimensional matrix.
296 * Index is not checked for correct number or length of dimensions.
297 * @memberof DenseMatrix
298 * @param {Array} data
299 * @param {Index} index
300 * @param {number} dims Total number of dimensions
301 * @param {number} dim Current dimension
302 * @return {Array} submatrix
303 * @private
304 */
305
306
307 function _getSubmatrix(data, index, dims, dim) {
308 var last = dim === dims - 1;
309 var range = index.dimension(dim);
310
311 if (last) {
312 return range.map(function (i) {
313 (0, _array.validateIndex)(i, data.length);
314 return data[i];
315 }).valueOf();
316 } else {
317 return range.map(function (i) {
318 (0, _array.validateIndex)(i, data.length);
319 var child = data[i];
320 return _getSubmatrix(child, index, dims, dim + 1);
321 }).valueOf();
322 }
323 }
324 /**
325 * Replace a submatrix in this matrix
326 * Indexes are zero-based.
327 * @memberof DenseMatrix
328 * @param {DenseMatrix} matrix
329 * @param {Index} index
330 * @param {DenseMatrix | Array | *} submatrix
331 * @param {*} defaultValue Default value, filled in on new entries when
332 * the matrix is resized.
333 * @return {DenseMatrix} matrix
334 * @private
335 */
336
337
338 function _set(matrix, index, submatrix, defaultValue) {
339 if (!index || index.isIndex !== true) {
340 throw new TypeError('Invalid index');
341 } // get index size and check whether the index contains a single value
342
343
344 var iSize = index.size();
345 var isScalar = index.isScalar(); // calculate the size of the submatrix, and convert it into an Array if needed
346
347 var sSize;
348
349 if ((0, _is.isMatrix)(submatrix)) {
350 sSize = submatrix.size();
351 submatrix = submatrix.valueOf();
352 } else {
353 sSize = (0, _array.arraySize)(submatrix);
354 }
355
356 if (isScalar) {
357 // set a scalar
358 // check whether submatrix is a scalar
359 if (sSize.length !== 0) {
360 throw new TypeError('Scalar expected');
361 }
362
363 matrix.set(index.min(), submatrix, defaultValue);
364 } else {
365 // set a submatrix
366 // validate dimensions
367 if (iSize.length < matrix._size.length) {
368 throw new _DimensionError.DimensionError(iSize.length, matrix._size.length, '<');
369 }
370
371 if (sSize.length < iSize.length) {
372 // calculate number of missing outer dimensions
373 var i = 0;
374 var outer = 0;
375
376 while (iSize[i] === 1 && sSize[i] === 1) {
377 i++;
378 }
379
380 while (iSize[i] === 1) {
381 outer++;
382 i++;
383 } // unsqueeze both outer and inner dimensions
384
385
386 submatrix = (0, _array.unsqueeze)(submatrix, iSize.length, outer, sSize);
387 } // check whether the size of the submatrix matches the index size
388
389
390 if (!(0, _object.deepStrictEqual)(iSize, sSize)) {
391 throw new _DimensionError.DimensionError(iSize, sSize, '>');
392 } // enlarge matrix when needed
393
394
395 var size = index.max().map(function (i) {
396 return i + 1;
397 });
398
399 _fit(matrix, size, defaultValue); // insert the sub matrix
400
401
402 var dims = iSize.length;
403 var dim = 0;
404
405 _setSubmatrix(matrix._data, index, submatrix, dims, dim);
406 }
407
408 return matrix;
409 }
410 /**
411 * Replace a submatrix of a multi dimensional matrix.
412 * @memberof DenseMatrix
413 * @param {Array} data
414 * @param {Index} index
415 * @param {Array} submatrix
416 * @param {number} dims Total number of dimensions
417 * @param {number} dim
418 * @private
419 */
420
421
422 function _setSubmatrix(data, index, submatrix, dims, dim) {
423 var last = dim === dims - 1;
424 var range = index.dimension(dim);
425
426 if (last) {
427 range.forEach(function (dataIndex, subIndex) {
428 (0, _array.validateIndex)(dataIndex);
429 data[dataIndex] = submatrix[subIndex[0]];
430 });
431 } else {
432 range.forEach(function (dataIndex, subIndex) {
433 (0, _array.validateIndex)(dataIndex);
434
435 _setSubmatrix(data[dataIndex], index, submatrix[subIndex[0]], dims, dim + 1);
436 });
437 }
438 }
439 /**
440 * Resize the matrix to the given size. Returns a copy of the matrix when
441 * `copy=true`, otherwise return the matrix itself (resize in place).
442 *
443 * @memberof DenseMatrix
444 * @param {number[]} size The new size the matrix should have.
445 * @param {*} [defaultValue=0] Default value, filled in on new entries.
446 * If not provided, the matrix elements will
447 * be filled with zeros.
448 * @param {boolean} [copy] Return a resized copy of the matrix
449 *
450 * @return {Matrix} The resized matrix
451 */
452
453
454 DenseMatrix.prototype.resize = function (size, defaultValue, copy) {
455 // validate arguments
456 if (!(0, _is.isArray)(size)) {
457 throw new TypeError('Array expected');
458 } // matrix to resize
459
460
461 var m = copy ? this.clone() : this; // resize matrix
462
463 return _resize(m, size, defaultValue);
464 };
465
466 function _resize(matrix, size, defaultValue) {
467 // check size
468 if (size.length === 0) {
469 // first value in matrix
470 var v = matrix._data; // go deep
471
472 while ((0, _is.isArray)(v)) {
473 v = v[0];
474 }
475
476 return v;
477 } // resize matrix
478
479
480 matrix._size = size.slice(0); // copy the array
481
482 matrix._data = (0, _array.resize)(matrix._data, matrix._size, defaultValue); // return matrix
483
484 return matrix;
485 }
486 /**
487 * Reshape the matrix to the given size. Returns a copy of the matrix when
488 * `copy=true`, otherwise return the matrix itself (reshape in place).
489 *
490 * NOTE: This might be better suited to copy by default, instead of modifying
491 * in place. For now, it operates in place to remain consistent with
492 * resize().
493 *
494 * @memberof DenseMatrix
495 * @param {number[]} size The new size the matrix should have.
496 * @param {boolean} [copy] Return a reshaped copy of the matrix
497 *
498 * @return {Matrix} The reshaped matrix
499 */
500
501
502 DenseMatrix.prototype.reshape = function (size, copy) {
503 var m = copy ? this.clone() : this;
504 m._data = (0, _array.reshape)(m._data, size);
505 m._size = size.slice(0);
506 return m;
507 };
508 /**
509 * Enlarge the matrix when it is smaller than given size.
510 * If the matrix is larger or equal sized, nothing is done.
511 * @memberof DenseMatrix
512 * @param {DenseMatrix} matrix The matrix to be resized
513 * @param {number[]} size
514 * @param {*} defaultValue Default value, filled in on new entries.
515 * @private
516 */
517
518
519 function _fit(matrix, size, defaultValue) {
520 var // copy the array
521 newSize = matrix._size.slice(0);
522
523 var changed = false; // add dimensions when needed
524
525 while (newSize.length < size.length) {
526 newSize.push(0);
527 changed = true;
528 } // enlarge size when needed
529
530
531 for (var i = 0, ii = size.length; i < ii; i++) {
532 if (size[i] > newSize[i]) {
533 newSize[i] = size[i];
534 changed = true;
535 }
536 }
537
538 if (changed) {
539 // resize only when size is changed
540 _resize(matrix, newSize, defaultValue);
541 }
542 }
543 /**
544 * Create a clone of the matrix
545 * @memberof DenseMatrix
546 * @return {DenseMatrix} clone
547 */
548
549
550 DenseMatrix.prototype.clone = function () {
551 var m = new DenseMatrix({
552 data: (0, _object.clone)(this._data),
553 size: (0, _object.clone)(this._size),
554 datatype: this._datatype
555 });
556 return m;
557 };
558 /**
559 * Retrieve the size of the matrix.
560 * @memberof DenseMatrix
561 * @returns {number[]} size
562 */
563
564
565 DenseMatrix.prototype.size = function () {
566 return this._size.slice(0); // return a clone of _size
567 };
568 /**
569 * Create a new matrix with the results of the callback function executed on
570 * each entry of the matrix.
571 * @memberof DenseMatrix
572 * @param {Function} callback The callback function is invoked with three
573 * parameters: the value of the element, the index
574 * of the element, and the Matrix being traversed.
575 *
576 * @return {DenseMatrix} matrix
577 */
578
579
580 DenseMatrix.prototype.map = function (callback) {
581 // matrix instance
582 var me = this;
583
584 var recurse = function recurse(value, index) {
585 if ((0, _is.isArray)(value)) {
586 return value.map(function (child, i) {
587 return recurse(child, index.concat(i));
588 });
589 } else {
590 return callback(value, index, me);
591 }
592 }; // return dense format
593
594
595 return new DenseMatrix({
596 data: recurse(this._data, []),
597 size: (0, _object.clone)(this._size),
598 datatype: this._datatype
599 });
600 };
601 /**
602 * Execute a callback function on each entry of the matrix.
603 * @memberof DenseMatrix
604 * @param {Function} callback The callback function is invoked with three
605 * parameters: the value of the element, the index
606 * of the element, and the Matrix being traversed.
607 */
608
609
610 DenseMatrix.prototype.forEach = function (callback) {
611 // matrix instance
612 var me = this;
613
614 var recurse = function recurse(value, index) {
615 if ((0, _is.isArray)(value)) {
616 value.forEach(function (child, i) {
617 recurse(child, index.concat(i));
618 });
619 } else {
620 callback(value, index, me);
621 }
622 };
623
624 recurse(this._data, []);
625 };
626 /**
627 * Create an Array with a copy of the data of the DenseMatrix
628 * @memberof DenseMatrix
629 * @returns {Array} array
630 */
631
632
633 DenseMatrix.prototype.toArray = function () {
634 return (0, _object.clone)(this._data);
635 };
636 /**
637 * Get the primitive value of the DenseMatrix: a multidimensional array
638 * @memberof DenseMatrix
639 * @returns {Array} array
640 */
641
642
643 DenseMatrix.prototype.valueOf = function () {
644 return this._data;
645 };
646 /**
647 * Get a string representation of the matrix, with optional formatting options.
648 * @memberof DenseMatrix
649 * @param {Object | number | Function} [options] Formatting options. See
650 * lib/utils/number:format for a
651 * description of the available
652 * options.
653 * @returns {string} str
654 */
655
656
657 DenseMatrix.prototype.format = function (options) {
658 return (0, _string.format)(this._data, options);
659 };
660 /**
661 * Get a string representation of the matrix
662 * @memberof DenseMatrix
663 * @returns {string} str
664 */
665
666
667 DenseMatrix.prototype.toString = function () {
668 return (0, _string.format)(this._data);
669 };
670 /**
671 * Get a JSON representation of the matrix
672 * @memberof DenseMatrix
673 * @returns {Object}
674 */
675
676
677 DenseMatrix.prototype.toJSON = function () {
678 return {
679 mathjs: 'DenseMatrix',
680 data: this._data,
681 size: this._size,
682 datatype: this._datatype
683 };
684 };
685 /**
686 * Get the kth Matrix diagonal.
687 *
688 * @memberof DenseMatrix
689 * @param {number | BigNumber} [k=0] The kth diagonal where the vector will retrieved.
690 *
691 * @returns {Matrix} The matrix with the diagonal values.
692 */
693
694
695 DenseMatrix.prototype.diagonal = function (k) {
696 // validate k if any
697 if (k) {
698 // convert BigNumber to a number
699 if ((0, _is.isBigNumber)(k)) {
700 k = k.toNumber();
701 } // is must be an integer
702
703
704 if (!(0, _is.isNumber)(k) || !(0, _number.isInteger)(k)) {
705 throw new TypeError('The parameter k must be an integer number');
706 }
707 } else {
708 // default value
709 k = 0;
710 }
711
712 var kSuper = k > 0 ? k : 0;
713 var kSub = k < 0 ? -k : 0; // rows & columns
714
715 var rows = this._size[0];
716 var columns = this._size[1]; // number diagonal values
717
718 var n = Math.min(rows - kSub, columns - kSuper); // x is a matrix get diagonal from matrix
719
720 var data = []; // loop rows
721
722 for (var i = 0; i < n; i++) {
723 data[i] = this._data[i + kSub][i + kSuper];
724 } // create DenseMatrix
725
726
727 return new DenseMatrix({
728 data: data,
729 size: [n],
730 datatype: this._datatype
731 });
732 };
733 /**
734 * Create a diagonal matrix.
735 *
736 * @memberof DenseMatrix
737 * @param {Array} size The matrix size.
738 * @param {number | Matrix | Array } value The values for the diagonal.
739 * @param {number | BigNumber} [k=0] The kth diagonal where the vector will be filled in.
740 * @param {number} [defaultValue] The default value for non-diagonal
741 * @param {string} [datatype] The datatype for the diagonal
742 *
743 * @returns {DenseMatrix}
744 */
745
746
747 DenseMatrix.diagonal = function (size, value, k, defaultValue) {
748 if (!(0, _is.isArray)(size)) {
749 throw new TypeError('Array expected, size parameter');
750 }
751
752 if (size.length !== 2) {
753 throw new Error('Only two dimensions matrix are supported');
754 } // map size & validate
755
756
757 size = size.map(function (s) {
758 // check it is a big number
759 if ((0, _is.isBigNumber)(s)) {
760 // convert it
761 s = s.toNumber();
762 } // validate arguments
763
764
765 if (!(0, _is.isNumber)(s) || !(0, _number.isInteger)(s) || s < 1) {
766 throw new Error('Size values must be positive integers');
767 }
768
769 return s;
770 }); // validate k if any
771
772 if (k) {
773 // convert BigNumber to a number
774 if ((0, _is.isBigNumber)(k)) {
775 k = k.toNumber();
776 } // is must be an integer
777
778
779 if (!(0, _is.isNumber)(k) || !(0, _number.isInteger)(k)) {
780 throw new TypeError('The parameter k must be an integer number');
781 }
782 } else {
783 // default value
784 k = 0;
785 }
786
787 var kSuper = k > 0 ? k : 0;
788 var kSub = k < 0 ? -k : 0; // rows and columns
789
790 var rows = size[0];
791 var columns = size[1]; // number of non-zero items
792
793 var n = Math.min(rows - kSub, columns - kSuper); // value extraction function
794
795 var _value; // check value
796
797
798 if ((0, _is.isArray)(value)) {
799 // validate array
800 if (value.length !== n) {
801 // number of values in array must be n
802 throw new Error('Invalid value array length');
803 } // define function
804
805
806 _value = function _value(i) {
807 // return value @ i
808 return value[i];
809 };
810 } else if ((0, _is.isMatrix)(value)) {
811 // matrix size
812 var ms = value.size(); // validate matrix
813
814 if (ms.length !== 1 || ms[0] !== n) {
815 // number of values in array must be n
816 throw new Error('Invalid matrix length');
817 } // define function
818
819
820 _value = function _value(i) {
821 // return value @ i
822 return value.get([i]);
823 };
824 } else {
825 // define function
826 _value = function _value() {
827 // return value
828 return value;
829 };
830 } // discover default value if needed
831
832
833 if (!defaultValue) {
834 // check first value in array
835 defaultValue = (0, _is.isBigNumber)(_value(0)) ? _value(0).mul(0) // trick to create a BigNumber with value zero
836 : 0;
837 } // empty array
838
839
840 var data = []; // check we need to resize array
841
842 if (size.length > 0) {
843 // resize array
844 data = (0, _array.resize)(data, size, defaultValue); // fill diagonal
845
846 for (var d = 0; d < n; d++) {
847 data[d + kSub][d + kSuper] = _value(d);
848 }
849 } // create DenseMatrix
850
851
852 return new DenseMatrix({
853 data: data,
854 size: [rows, columns]
855 });
856 };
857 /**
858 * Generate a matrix from a JSON object
859 * @memberof DenseMatrix
860 * @param {Object} json An object structured like
861 * `{"mathjs": "DenseMatrix", data: [], size: []}`,
862 * where mathjs is optional
863 * @returns {DenseMatrix}
864 */
865
866
867 DenseMatrix.fromJSON = function (json) {
868 return new DenseMatrix(json);
869 };
870 /**
871 * Swap rows i and j in Matrix.
872 *
873 * @memberof DenseMatrix
874 * @param {number} i Matrix row index 1
875 * @param {number} j Matrix row index 2
876 *
877 * @return {Matrix} The matrix reference
878 */
879
880
881 DenseMatrix.prototype.swapRows = function (i, j) {
882 // check index
883 if (!(0, _is.isNumber)(i) || !(0, _number.isInteger)(i) || !(0, _is.isNumber)(j) || !(0, _number.isInteger)(j)) {
884 throw new Error('Row index must be positive integers');
885 } // check dimensions
886
887
888 if (this._size.length !== 2) {
889 throw new Error('Only two dimensional matrix is supported');
890 } // validate index
891
892
893 (0, _array.validateIndex)(i, this._size[0]);
894 (0, _array.validateIndex)(j, this._size[0]); // swap rows
895
896 DenseMatrix._swapRows(i, j, this._data); // return current instance
897
898
899 return this;
900 };
901 /**
902 * Swap rows i and j in Dense Matrix data structure.
903 *
904 * @param {number} i Matrix row index 1
905 * @param {number} j Matrix row index 2
906 * @param {Array} data Matrix data
907 */
908
909
910 DenseMatrix._swapRows = function (i, j, data) {
911 // swap values i <-> j
912 var vi = data[i];
913 data[i] = data[j];
914 data[j] = vi;
915 };
916 /**
917 * Preprocess data, which can be an Array or DenseMatrix with nested Arrays and
918 * Matrices. Replaces all nested Matrices with Arrays
919 * @memberof DenseMatrix
920 * @param {Array} data
921 * @return {Array} data
922 */
923
924
925 function preprocess(data) {
926 for (var i = 0, ii = data.length; i < ii; i++) {
927 var elem = data[i];
928
929 if ((0, _is.isArray)(elem)) {
930 data[i] = preprocess(elem);
931 } else if (elem && elem.isMatrix === true) {
932 data[i] = preprocess(elem.valueOf());
933 }
934 }
935
936 return data;
937 }
938
939 return DenseMatrix;
940}, {
941 isClass: true
942});
943exports.createDenseMatrixClass = createDenseMatrixClass;
\No newline at end of file