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

100 lines (78 loc) 1.91 kB
'use strict'; var arraySize = require('../array').size; var isMatrix = require('../collection/isMatrix'); var 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) { var 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) { var 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) { var I = mat.length; var J = mat[0].length; var i, j; var ret = []; for (j = 0; j < J; j++) { var tmp = []; for (i = 0; i < I; i++) { tmp.push(mat[i][j]); } ret.push(tmp); } return ret; }