simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

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 }