simple-squiggle

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

apply.js (3045B)


      1 import { factory } from '../../utils/factory.js';
      2 import { arraySize } from '../../utils/array.js';
      3 import { isMatrix } from '../../utils/is.js';
      4 import { IndexError } from '../../error/IndexError.js';
      5 var name = 'apply';
      6 var dependencies = ['typed', 'isInteger'];
      7 export var createApply = /* #__PURE__ */factory(name, dependencies, _ref => {
      8   var {
      9     typed,
     10     isInteger
     11   } = _ref;
     12 
     13   /**
     14    * Apply a function that maps an array to a scalar
     15    * along a given axis of a matrix or array.
     16    * Returns a new matrix or array with one less dimension than the input.
     17    *
     18    * Syntax:
     19    *
     20    *     math.apply(A, dim, callback)
     21    *
     22    * Where:
     23    *
     24    * - `dim: number` is a zero-based dimension over which to concatenate the matrices.
     25    *
     26    * Examples:
     27    *
     28    *    const A = [[1, 2], [3, 4]]
     29    *    const sum = math.sum
     30    *
     31    *    math.apply(A, 0, sum)             // returns [4, 6]
     32    *    math.apply(A, 1, sum)             // returns [3, 7]
     33    *
     34    * See also:
     35    *
     36    *    map, filter, forEach
     37    *
     38    * @param {Array | Matrix} array   The input Matrix
     39    * @param {number} dim             The dimension along which the callback is applied
     40    * @param {Function} callback      The callback function that is applied. This Function
     41    *                                 should take an array or 1-d matrix as an input and
     42    *                                 return a number.
     43    * @return {Array | Matrix} res    The residual matrix with the function applied over some dimension.
     44    */
     45   return typed(name, {
     46     'Array | Matrix, number | BigNumber, function': function ArrayMatrixNumberBigNumberFunction(mat, dim, callback) {
     47       if (!isInteger(dim)) {
     48         throw new TypeError('Integer number expected for dimension');
     49       }
     50 
     51       var size = Array.isArray(mat) ? arraySize(mat) : mat.size();
     52 
     53       if (dim < 0 || dim >= size.length) {
     54         throw new IndexError(dim, size.length);
     55       }
     56 
     57       if (isMatrix(mat)) {
     58         return mat.create(_apply(mat.valueOf(), dim, callback));
     59       } else {
     60         return _apply(mat, dim, callback);
     61       }
     62     }
     63   });
     64 });
     65 /**
     66  * Recursively reduce a matrix
     67  * @param {Array} mat
     68  * @param {number} dim
     69  * @param {Function} callback
     70  * @returns {Array} ret
     71  * @private
     72  */
     73 
     74 function _apply(mat, dim, callback) {
     75   var i, ret, tran;
     76 
     77   if (dim <= 0) {
     78     if (!Array.isArray(mat[0])) {
     79       return callback(mat);
     80     } else {
     81       tran = _switch(mat);
     82       ret = [];
     83 
     84       for (i = 0; i < tran.length; i++) {
     85         ret[i] = _apply(tran[i], dim - 1, callback);
     86       }
     87 
     88       return ret;
     89     }
     90   } else {
     91     ret = [];
     92 
     93     for (i = 0; i < mat.length; i++) {
     94       ret[i] = _apply(mat[i], dim - 1, callback);
     95     }
     96 
     97     return ret;
     98   }
     99 }
    100 /**
    101  * Transpose a matrix
    102  * @param {Array} mat
    103  * @returns {Array} ret
    104  * @private
    105  */
    106 
    107 
    108 function _switch(mat) {
    109   var I = mat.length;
    110   var J = mat[0].length;
    111   var i, j;
    112   var ret = [];
    113 
    114   for (j = 0; j < J; j++) {
    115     var tmp = [];
    116 
    117     for (i = 0; i < I; i++) {
    118       tmp.push(mat[i][j]);
    119     }
    120 
    121     ret.push(tmp);
    122   }
    123 
    124   return ret;
    125 }