UNPKG

26.4 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 = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
25 var Matrix = _ref.Matrix;
26
27 /**
28 * Dense Matrix implementation. A regular, dense matrix, supporting multi-dimensional matrices. This is the default matrix type.
29 * @class DenseMatrix
30 */
31 function DenseMatrix(data, datatype) {
32 if (!(this instanceof DenseMatrix)) {
33 throw new SyntaxError('Constructor must be called with the new operator');
34 }
35
36 if (datatype && !(0, _is.isString)(datatype)) {
37 throw new Error('Invalid datatype: ' + datatype);
38 }
39
40 if ((0, _is.isMatrix)(data)) {
41 // check data is a DenseMatrix
42 if (data.type === 'DenseMatrix') {
43 // clone data & size
44 this._data = (0, _object.clone)(data._data);
45 this._size = (0, _object.clone)(data._size);
46 this._datatype = datatype || data._datatype;
47 } else {
48 // build data from existing matrix
49 this._data = data.toArray();
50 this._size = data.size();
51 this._datatype = datatype || data._datatype;
52 }
53 } else if (data && (0, _is.isArray)(data.data) && (0, _is.isArray)(data.size)) {
54 // initialize fields from JSON representation
55 this._data = data.data;
56 this._size = data.size; // verify the dimensions of the array
57
58 (0, _array.validate)(this._data, this._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[] || Matrix} 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.isCollection)(size)) {
457 throw new TypeError('Array or Matrix expected');
458 } // SparseMatrix input is always 2d, flatten this into 1d if it's indeed a vector
459
460
461 var sizeArray = size.valueOf().map(function (value) {
462 return Array.isArray(value) && value.length === 1 ? value[0] : value;
463 }); // matrix to resize
464
465 var m = copy ? this.clone() : this; // resize matrix
466
467 return _resize(m, sizeArray, defaultValue);
468 };
469
470 function _resize(matrix, size, defaultValue) {
471 // check size
472 if (size.length === 0) {
473 // first value in matrix
474 var v = matrix._data; // go deep
475
476 while ((0, _is.isArray)(v)) {
477 v = v[0];
478 }
479
480 return v;
481 } // resize matrix
482
483
484 matrix._size = size.slice(0); // copy the array
485
486 matrix._data = (0, _array.resize)(matrix._data, matrix._size, defaultValue); // return matrix
487
488 return matrix;
489 }
490 /**
491 * Reshape the matrix to the given size. Returns a copy of the matrix when
492 * `copy=true`, otherwise return the matrix itself (reshape in place).
493 *
494 * NOTE: This might be better suited to copy by default, instead of modifying
495 * in place. For now, it operates in place to remain consistent with
496 * resize().
497 *
498 * @memberof DenseMatrix
499 * @param {number[]} size The new size the matrix should have.
500 * @param {boolean} [copy] Return a reshaped copy of the matrix
501 *
502 * @return {Matrix} The reshaped matrix
503 */
504
505
506 DenseMatrix.prototype.reshape = function (size, copy) {
507 var m = copy ? this.clone() : this;
508 m._data = (0, _array.reshape)(m._data, size);
509 m._size = size.slice(0);
510 return m;
511 };
512 /**
513 * Enlarge the matrix when it is smaller than given size.
514 * If the matrix is larger or equal sized, nothing is done.
515 * @memberof DenseMatrix
516 * @param {DenseMatrix} matrix The matrix to be resized
517 * @param {number[]} size
518 * @param {*} defaultValue Default value, filled in on new entries.
519 * @private
520 */
521
522
523 function _fit(matrix, size, defaultValue) {
524 var // copy the array
525 newSize = matrix._size.slice(0);
526
527 var changed = false; // add dimensions when needed
528
529 while (newSize.length < size.length) {
530 newSize.push(0);
531 changed = true;
532 } // enlarge size when needed
533
534
535 for (var i = 0, ii = size.length; i < ii; i++) {
536 if (size[i] > newSize[i]) {
537 newSize[i] = size[i];
538 changed = true;
539 }
540 }
541
542 if (changed) {
543 // resize only when size is changed
544 _resize(matrix, newSize, defaultValue);
545 }
546 }
547 /**
548 * Create a clone of the matrix
549 * @memberof DenseMatrix
550 * @return {DenseMatrix} clone
551 */
552
553
554 DenseMatrix.prototype.clone = function () {
555 var m = new DenseMatrix({
556 data: (0, _object.clone)(this._data),
557 size: (0, _object.clone)(this._size),
558 datatype: this._datatype
559 });
560 return m;
561 };
562 /**
563 * Retrieve the size of the matrix.
564 * @memberof DenseMatrix
565 * @returns {number[]} size
566 */
567
568
569 DenseMatrix.prototype.size = function () {
570 return this._size.slice(0); // return a clone of _size
571 };
572 /**
573 * Create a new matrix with the results of the callback function executed on
574 * each entry of the matrix.
575 * @memberof DenseMatrix
576 * @param {Function} callback The callback function is invoked with three
577 * parameters: the value of the element, the index
578 * of the element, and the Matrix being traversed.
579 *
580 * @return {DenseMatrix} matrix
581 */
582
583
584 DenseMatrix.prototype.map = function (callback) {
585 // matrix instance
586 var me = this;
587
588 var recurse = function recurse(value, index) {
589 if ((0, _is.isArray)(value)) {
590 return value.map(function (child, i) {
591 return recurse(child, index.concat(i));
592 });
593 } else {
594 return callback(value, index, me);
595 }
596 }; // determine the new datatype when the original matrix has datatype defined
597 // TODO: should be done in matrix constructor instead
598
599
600 var data = recurse(this._data, []);
601 var datatype = this._datatype !== undefined ? (0, _array.getArrayDataType)(data, _is.typeOf) : undefined;
602 return new DenseMatrix(data, datatype);
603 };
604 /**
605 * Execute a callback function on each entry of the matrix.
606 * @memberof DenseMatrix
607 * @param {Function} callback The callback function is invoked with three
608 * parameters: the value of the element, the index
609 * of the element, and the Matrix being traversed.
610 */
611
612
613 DenseMatrix.prototype.forEach = function (callback) {
614 // matrix instance
615 var me = this;
616
617 var recurse = function recurse(value, index) {
618 if ((0, _is.isArray)(value)) {
619 value.forEach(function (child, i) {
620 recurse(child, index.concat(i));
621 });
622 } else {
623 callback(value, index, me);
624 }
625 };
626
627 recurse(this._data, []);
628 };
629 /**
630 * Create an Array with a copy of the data of the DenseMatrix
631 * @memberof DenseMatrix
632 * @returns {Array} array
633 */
634
635
636 DenseMatrix.prototype.toArray = function () {
637 return (0, _object.clone)(this._data);
638 };
639 /**
640 * Get the primitive value of the DenseMatrix: a multidimensional array
641 * @memberof DenseMatrix
642 * @returns {Array} array
643 */
644
645
646 DenseMatrix.prototype.valueOf = function () {
647 return this._data;
648 };
649 /**
650 * Get a string representation of the matrix, with optional formatting options.
651 * @memberof DenseMatrix
652 * @param {Object | number | Function} [options] Formatting options. See
653 * lib/utils/number:format for a
654 * description of the available
655 * options.
656 * @returns {string} str
657 */
658
659
660 DenseMatrix.prototype.format = function (options) {
661 return (0, _string.format)(this._data, options);
662 };
663 /**
664 * Get a string representation of the matrix
665 * @memberof DenseMatrix
666 * @returns {string} str
667 */
668
669
670 DenseMatrix.prototype.toString = function () {
671 return (0, _string.format)(this._data);
672 };
673 /**
674 * Get a JSON representation of the matrix
675 * @memberof DenseMatrix
676 * @returns {Object}
677 */
678
679
680 DenseMatrix.prototype.toJSON = function () {
681 return {
682 mathjs: 'DenseMatrix',
683 data: this._data,
684 size: this._size,
685 datatype: this._datatype
686 };
687 };
688 /**
689 * Get the kth Matrix diagonal.
690 *
691 * @memberof DenseMatrix
692 * @param {number | BigNumber} [k=0] The kth diagonal where the vector will retrieved.
693 *
694 * @returns {Matrix} The matrix with the diagonal values.
695 */
696
697
698 DenseMatrix.prototype.diagonal = function (k) {
699 // validate k if any
700 if (k) {
701 // convert BigNumber to a number
702 if ((0, _is.isBigNumber)(k)) {
703 k = k.toNumber();
704 } // is must be an integer
705
706
707 if (!(0, _is.isNumber)(k) || !(0, _number.isInteger)(k)) {
708 throw new TypeError('The parameter k must be an integer number');
709 }
710 } else {
711 // default value
712 k = 0;
713 }
714
715 var kSuper = k > 0 ? k : 0;
716 var kSub = k < 0 ? -k : 0; // rows & columns
717
718 var rows = this._size[0];
719 var columns = this._size[1]; // number diagonal values
720
721 var n = Math.min(rows - kSub, columns - kSuper); // x is a matrix get diagonal from matrix
722
723 var data = []; // loop rows
724
725 for (var i = 0; i < n; i++) {
726 data[i] = this._data[i + kSub][i + kSuper];
727 } // create DenseMatrix
728
729
730 return new DenseMatrix({
731 data: data,
732 size: [n],
733 datatype: this._datatype
734 });
735 };
736 /**
737 * Create a diagonal matrix.
738 *
739 * @memberof DenseMatrix
740 * @param {Array} size The matrix size.
741 * @param {number | Matrix | Array } value The values for the diagonal.
742 * @param {number | BigNumber} [k=0] The kth diagonal where the vector will be filled in.
743 * @param {number} [defaultValue] The default value for non-diagonal
744 * @param {string} [datatype] The datatype for the diagonal
745 *
746 * @returns {DenseMatrix}
747 */
748
749
750 DenseMatrix.diagonal = function (size, value, k, defaultValue) {
751 if (!(0, _is.isArray)(size)) {
752 throw new TypeError('Array expected, size parameter');
753 }
754
755 if (size.length !== 2) {
756 throw new Error('Only two dimensions matrix are supported');
757 } // map size & validate
758
759
760 size = size.map(function (s) {
761 // check it is a big number
762 if ((0, _is.isBigNumber)(s)) {
763 // convert it
764 s = s.toNumber();
765 } // validate arguments
766
767
768 if (!(0, _is.isNumber)(s) || !(0, _number.isInteger)(s) || s < 1) {
769 throw new Error('Size values must be positive integers');
770 }
771
772 return s;
773 }); // validate k if any
774
775 if (k) {
776 // convert BigNumber to a number
777 if ((0, _is.isBigNumber)(k)) {
778 k = k.toNumber();
779 } // is must be an integer
780
781
782 if (!(0, _is.isNumber)(k) || !(0, _number.isInteger)(k)) {
783 throw new TypeError('The parameter k must be an integer number');
784 }
785 } else {
786 // default value
787 k = 0;
788 }
789
790 var kSuper = k > 0 ? k : 0;
791 var kSub = k < 0 ? -k : 0; // rows and columns
792
793 var rows = size[0];
794 var columns = size[1]; // number of non-zero items
795
796 var n = Math.min(rows - kSub, columns - kSuper); // value extraction function
797
798 var _value; // check value
799
800
801 if ((0, _is.isArray)(value)) {
802 // validate array
803 if (value.length !== n) {
804 // number of values in array must be n
805 throw new Error('Invalid value array length');
806 } // define function
807
808
809 _value = function _value(i) {
810 // return value @ i
811 return value[i];
812 };
813 } else if ((0, _is.isMatrix)(value)) {
814 // matrix size
815 var ms = value.size(); // validate matrix
816
817 if (ms.length !== 1 || ms[0] !== n) {
818 // number of values in array must be n
819 throw new Error('Invalid matrix length');
820 } // define function
821
822
823 _value = function _value(i) {
824 // return value @ i
825 return value.get([i]);
826 };
827 } else {
828 // define function
829 _value = function _value() {
830 // return value
831 return value;
832 };
833 } // discover default value if needed
834
835
836 if (!defaultValue) {
837 // check first value in array
838 defaultValue = (0, _is.isBigNumber)(_value(0)) ? _value(0).mul(0) // trick to create a BigNumber with value zero
839 : 0;
840 } // empty array
841
842
843 var data = []; // check we need to resize array
844
845 if (size.length > 0) {
846 // resize array
847 data = (0, _array.resize)(data, size, defaultValue); // fill diagonal
848
849 for (var d = 0; d < n; d++) {
850 data[d + kSub][d + kSuper] = _value(d);
851 }
852 } // create DenseMatrix
853
854
855 return new DenseMatrix({
856 data: data,
857 size: [rows, columns]
858 });
859 };
860 /**
861 * Generate a matrix from a JSON object
862 * @memberof DenseMatrix
863 * @param {Object} json An object structured like
864 * `{"mathjs": "DenseMatrix", data: [], size: []}`,
865 * where mathjs is optional
866 * @returns {DenseMatrix}
867 */
868
869
870 DenseMatrix.fromJSON = function (json) {
871 return new DenseMatrix(json);
872 };
873 /**
874 * Swap rows i and j in Matrix.
875 *
876 * @memberof DenseMatrix
877 * @param {number} i Matrix row index 1
878 * @param {number} j Matrix row index 2
879 *
880 * @return {Matrix} The matrix reference
881 */
882
883
884 DenseMatrix.prototype.swapRows = function (i, j) {
885 // check index
886 if (!(0, _is.isNumber)(i) || !(0, _number.isInteger)(i) || !(0, _is.isNumber)(j) || !(0, _number.isInteger)(j)) {
887 throw new Error('Row index must be positive integers');
888 } // check dimensions
889
890
891 if (this._size.length !== 2) {
892 throw new Error('Only two dimensional matrix is supported');
893 } // validate index
894
895
896 (0, _array.validateIndex)(i, this._size[0]);
897 (0, _array.validateIndex)(j, this._size[0]); // swap rows
898
899 DenseMatrix._swapRows(i, j, this._data); // return current instance
900
901
902 return this;
903 };
904 /**
905 * Swap rows i and j in Dense Matrix data structure.
906 *
907 * @param {number} i Matrix row index 1
908 * @param {number} j Matrix row index 2
909 * @param {Array} data Matrix data
910 */
911
912
913 DenseMatrix._swapRows = function (i, j, data) {
914 // swap values i <-> j
915 var vi = data[i];
916 data[i] = data[j];
917 data[j] = vi;
918 };
919 /**
920 * Preprocess data, which can be an Array or DenseMatrix with nested Arrays and
921 * Matrices. Replaces all nested Matrices with Arrays
922 * @memberof DenseMatrix
923 * @param {Array} data
924 * @return {Array} data
925 */
926
927
928 function preprocess(data) {
929 for (var i = 0, ii = data.length; i < ii; i++) {
930 var elem = data[i];
931
932 if ((0, _is.isArray)(elem)) {
933 data[i] = preprocess(elem);
934 } else if (elem && elem.isMatrix === true) {
935 data[i] = preprocess(elem.valueOf());
936 }
937 }
938
939 return data;
940 }
941
942 return DenseMatrix;
943}, {
944 isClass: true
945});
946exports.createDenseMatrixClass = createDenseMatrixClass;
\No newline at end of file