simple-squiggle

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

cumsum.js (4011B)


      1 import { containsCollections } from '../../utils/collection.js';
      2 import { factory } from '../../utils/factory.js';
      3 import { _switch } from '../../utils/switch.js';
      4 import { improveErrorMessage } from './utils/improveErrorMessage.js';
      5 import { arraySize } from '../../utils/array.js';
      6 import { IndexError } from '../../error/IndexError.js';
      7 var name = 'cumsum';
      8 var dependencies = ['typed', 'add', 'unaryPlus'];
      9 export var createCumSum = /* #__PURE__ */factory(name, dependencies, _ref => {
     10   var {
     11     typed,
     12     add,
     13     unaryPlus
     14   } = _ref;
     15 
     16   /**
     17    * Compute the cumulative sum of a matrix or a list with values.
     18    * In case of a (multi dimensional) array or matrix, the cumulative sums
     19    * along a specified dimension (defaulting to the first) will be calculated.
     20    *
     21    * Syntax:
     22    *
     23    *     math.cumsum(a, b, c, ...)
     24    *     math.cumsum(A)
     25    *
     26    * Examples:
     27    *
     28    *     math.cumsum(2, 1, 4, 3)               // returns [2, 3, 7, 10]
     29    *     math.cumsum([2, 1, 4, 3])             // returns [2, 3, 7, 10]
     30    *     math.cumsum([[1, 2], [3, 4]])         // returns [[1, 2], [4, 6]]
     31    *     math.cumsum([[1, 2], [3, 4]], 0)      // returns [[1, 2], [4, 6]]
     32    *     math.cumsum([[1, 2], [3, 4]], 1)      // returns [[1, 3], [3, 7]]
     33    *     math.cumsum([[2, 5], [4, 3], [1, 7]]) // returns [[2, 5], [6, 8], [7, 15]]
     34    *
     35    * See also:
     36    *
     37    *    mean, median, min, max, prod, std, variance, sum
     38    *
     39    * @param {... *} args  A single matrix or or multiple scalar values
     40    * @return {*} The cumulative sum of all values
     41    */
     42   return typed(name, {
     43     // sum([a, b, c, d, ...])
     44     Array: _cumsum,
     45     Matrix: function Matrix(matrix) {
     46       return matrix.create(_cumsum(matrix.valueOf()));
     47     },
     48     // sum([a, b, c, d, ...], dim)
     49     'Array, number | BigNumber': _ncumSumDim,
     50     'Matrix, number | BigNumber': function MatrixNumberBigNumber(matrix, dim) {
     51       return matrix.create(_ncumSumDim(matrix.valueOf(), dim));
     52     },
     53     // cumsum(a, b, c, d, ...)
     54     '...': function _(args) {
     55       if (containsCollections(args)) {
     56         throw new TypeError('All values expected to be scalar in function cumsum');
     57       }
     58 
     59       return _cumsum(args);
     60     }
     61   });
     62   /**
     63      * Recursively calculate the cumulative sum of an n-dimensional array
     64      * @param {Array} array
     65      * @return {number} cumsum
     66      * @private
     67      */
     68 
     69   function _cumsum(array) {
     70     try {
     71       return _cumsummap(array);
     72     } catch (err) {
     73       throw improveErrorMessage(err, name);
     74     }
     75   }
     76 
     77   function _cumsummap(array) {
     78     if (array.length === 0) {
     79       return [];
     80     }
     81 
     82     var sums = [unaryPlus(array[0])]; // unaryPlus converts to number if need be
     83 
     84     for (var i = 1; i < array.length; ++i) {
     85       // Must use add below and not addScalar for the case of summing a
     86       // 2+-dimensional array along the 0th dimension (the row vectors,
     87       // or higher-d analogues, are literally added to each other).
     88       sums.push(add(sums[i - 1], array[i]));
     89     }
     90 
     91     return sums;
     92   }
     93 
     94   function _ncumSumDim(array, dim) {
     95     var size = arraySize(array);
     96 
     97     if (dim < 0 || dim >= size.length) {
     98       // TODO: would be more clear when throwing a DimensionError here
     99       throw new IndexError(dim, size.length);
    100     }
    101 
    102     try {
    103       return _cumsumDimensional(array, dim);
    104     } catch (err) {
    105       throw improveErrorMessage(err, name);
    106     }
    107   }
    108   /* Possible TODO: Refactor _reduce in collection.js to be able to work here as well */
    109 
    110 
    111   function _cumsumDimensional(mat, dim) {
    112     var i, ret, tran;
    113 
    114     if (dim <= 0) {
    115       var initialValue = mat[0][0];
    116 
    117       if (!Array.isArray(initialValue)) {
    118         return _cumsummap(mat);
    119       } else {
    120         tran = _switch(mat);
    121         ret = [];
    122 
    123         for (i = 0; i < tran.length; i++) {
    124           ret[i] = _cumsumDimensional(tran[i], dim - 1);
    125         }
    126 
    127         return ret;
    128       }
    129     } else {
    130       ret = [];
    131 
    132       for (i = 0; i < mat.length; i++) {
    133         ret[i] = _cumsumDimensional(mat[i], dim - 1);
    134       }
    135 
    136       return ret;
    137     }
    138   }
    139 });