apply.js 3.0 KB

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