cumsum.js 3.9 KB

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