concat.js (4215B)
1 import { isBigNumber, isMatrix, isNumber } from '../../utils/is.js'; 2 import { clone } from '../../utils/object.js'; 3 import { arraySize } from '../../utils/array.js'; 4 import { IndexError } from '../../error/IndexError.js'; 5 import { DimensionError } from '../../error/DimensionError.js'; 6 import { factory } from '../../utils/factory.js'; 7 var name = 'concat'; 8 var dependencies = ['typed', 'matrix', 'isInteger']; 9 export var createConcat = /* #__PURE__ */factory(name, dependencies, _ref => { 10 var { 11 typed, 12 matrix, 13 isInteger 14 } = _ref; 15 16 /** 17 * Concatenate two or more matrices. 18 * 19 * Syntax: 20 * 21 * math.concat(A, B, C, ...) 22 * math.concat(A, B, C, ..., dim) 23 * 24 * Where: 25 * 26 * - `dim: number` is a zero-based dimension over which to concatenate the matrices. 27 * By default the last dimension of the matrices. 28 * 29 * Examples: 30 * 31 * const A = [[1, 2], [5, 6]] 32 * const B = [[3, 4], [7, 8]] 33 * 34 * math.concat(A, B) // returns [[1, 2, 3, 4], [5, 6, 7, 8]] 35 * math.concat(A, B, 0) // returns [[1, 2], [5, 6], [3, 4], [7, 8]] 36 * math.concat('hello', ' ', 'world') // returns 'hello world' 37 * 38 * See also: 39 * 40 * size, squeeze, subset, transpose 41 * 42 * @param {... Array | Matrix} args Two or more matrices 43 * @return {Array | Matrix} Concatenated matrix 44 */ 45 return typed(name, { 46 // TODO: change signature to '...Array | Matrix, dim?' when supported 47 '...Array | Matrix | number | BigNumber': function ArrayMatrixNumberBigNumber(args) { 48 var i; 49 var len = args.length; 50 var dim = -1; // zero-based dimension 51 52 var prevDim; 53 var asMatrix = false; 54 var matrices = []; // contains multi dimensional arrays 55 56 for (i = 0; i < len; i++) { 57 var arg = args[i]; // test whether we need to return a Matrix (if not we return an Array) 58 59 if (isMatrix(arg)) { 60 asMatrix = true; 61 } 62 63 if (isNumber(arg) || isBigNumber(arg)) { 64 if (i !== len - 1) { 65 throw new Error('Dimension must be specified as last argument'); 66 } // last argument contains the dimension on which to concatenate 67 68 69 prevDim = dim; 70 dim = arg.valueOf(); // change BigNumber to number 71 72 if (!isInteger(dim)) { 73 throw new TypeError('Integer number expected for dimension'); 74 } 75 76 if (dim < 0 || i > 0 && dim > prevDim) { 77 // TODO: would be more clear when throwing a DimensionError here 78 throw new IndexError(dim, prevDim + 1); 79 } 80 } else { 81 // this is a matrix or array 82 var m = clone(arg).valueOf(); 83 var size = arraySize(m); 84 matrices[i] = m; 85 prevDim = dim; 86 dim = size.length - 1; // verify whether each of the matrices has the same number of dimensions 87 88 if (i > 0 && dim !== prevDim) { 89 throw new DimensionError(prevDim + 1, dim + 1); 90 } 91 } 92 } 93 94 if (matrices.length === 0) { 95 throw new SyntaxError('At least one matrix expected'); 96 } 97 98 var res = matrices.shift(); 99 100 while (matrices.length) { 101 res = _concat(res, matrices.shift(), dim, 0); 102 } 103 104 return asMatrix ? matrix(res) : res; 105 }, 106 '...string': function string(args) { 107 return args.join(''); 108 } 109 }); 110 }); 111 /** 112 * Recursively concatenate two matrices. 113 * The contents of the matrices is not cloned. 114 * @param {Array} a Multi dimensional array 115 * @param {Array} b Multi dimensional array 116 * @param {number} concatDim The dimension on which to concatenate (zero-based) 117 * @param {number} dim The current dim (zero-based) 118 * @return {Array} c The concatenated matrix 119 * @private 120 */ 121 122 function _concat(a, b, concatDim, dim) { 123 if (dim < concatDim) { 124 // recurse into next dimension 125 if (a.length !== b.length) { 126 throw new DimensionError(a.length, b.length); 127 } 128 129 var c = []; 130 131 for (var i = 0; i < a.length; i++) { 132 c[i] = _concat(a[i], b[i], concatDim, dim + 1); 133 } 134 135 return c; 136 } else { 137 // concatenate this dimension 138 return a.concat(b); 139 } 140 }