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 });