UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with dif

85 lines (78 loc) 1.89 kB
'use strict' const arraySize = require('../array').size const isMatrix = require('../collection/isMatrix') const IndexError = require('../../error/IndexError') /** * Reduce a given matrix or array to a new matrix or * array with one less dimension, applying the given * callback in the selected dimension. * @param {Array | Matrix} mat * @param {number} dim * @param {Function} callback * @return {Array | Matrix} res */ module.exports = function (mat, dim, callback) { const size = Array.isArray(mat) ? arraySize(mat) : mat.size() if (dim < 0 || (dim >= size.length)) { // TODO: would be more clear when throwing a DimensionError here throw new IndexError(dim, size.length) } if (isMatrix(mat)) { return mat.create(_reduce(mat.valueOf(), dim, callback)) } else { return _reduce(mat, dim, callback) } } /** * Recursively reduce a matrix * @param {Array} mat * @param {number} dim * @param {Function} callback * @returns {Array} ret * @private */ function _reduce (mat, dim, callback) { let i, ret, val, tran if (dim <= 0) { if (!Array.isArray(mat[0])) { val = mat[0] for (i = 1; i < mat.length; i++) { val = callback(val, mat[i]) } return val } else { tran = _switch(mat) ret = [] for (i = 0; i < tran.length; i++) { ret[i] = _reduce(tran[i], dim - 1, callback) } return ret } } else { ret = [] for (i = 0; i < mat.length; i++) { ret[i] = _reduce(mat[i], dim - 1, callback) } return ret } } /** * Transpose a matrix * @param {Array} mat * @returns {Array} ret * @private */ function _switch (mat) { const I = mat.length const J = mat[0].length let i, j const ret = [] for (j = 0; j < J; j++) { const tmp = [] for (i = 0; i < I; i++) { tmp.push(mat[i][j]) } ret.push(tmp) } return ret }