// utility methods for arrays and matrices var util = require('../util/index'), Matrix = require('./Matrix'), isArray = util.array.isArray, isString = util.string.isString; /** * Convert function arguments to an array. Arguments can have the following * signature: * fn() * fn(n) * fn(m, n, p, ...) * fn([m, n, p, ...]) * @param {...Number | Array | Matrix} args * @returns {Array} array */ exports.argsToArray = function argsToArray(args) { var array; if (args.length == 0) { // fn() array = []; } else if (args.length == 1) { // fn(n) // fn([m, n, p, ...]) array = args[0]; if (array instanceof Matrix) { array = array.toVector(); } if (!isArray(array)) { array = [array]; } } else { // fn(m, n, p, ...) array = Array.prototype.slice.apply(args); } return array; }; /** * Test whether a value is a collection: an Array or Matrix * @param {*} x * @returns {boolean} isCollection */ exports.isCollection = function isCollection (x) { return (isArray(x) || (x instanceof Matrix)); }; /** * Execute the callback function element wise for each element in array and any * nested array * Returns an array with the results * @param {Array | Matrix} array * @param {function} callback The callback is called with two parameters: * value1 and value2, which contain the current * element of both arrays. * @return {Array | Matrix} res */ exports.deepMap = function deepMap(array, callback) { if (array && (typeof array.map === 'function')) { return array.map(function (x) { return deepMap(x, callback); }); } else { return callback(array); } }; /** * Execute the callback function element wise for each entry in two given arrays, * and for any nested array. Objects can also be scalar objects. * Returns an array with the results. * @param {Array | Matrix | Object} array1 * @param {Array | Matrix | Object} array2 * @param {function} callback The callback is called with two parameters: * value1 and value2, which contain the current * element of both arrays. * @return {Array | Matrix} res */ exports.deepMap2 = function deepMap2(array1, array2, callback) { var res, len, i; if (isArray(array1)) { if (isArray(array2)) { // callback(array, array) if (array1.length != array2.length) { throw new RangeError('Dimension mismatch ' + '(' + array1.length + ' != ' + array2.length + ')'); } res = []; len = array1.length; for (i = 0; i < len; i++) { res[i] = deepMap2(array1[i], array2[i], callback); } } else if (array2 instanceof Matrix) { // callback(array, matrix) res = deepMap2(array1, array2.valueOf(), callback); return new Matrix(res); } else { // callback(array, object) res = []; len = array1.length; for (i = 0; i < len; i++) { res[i] = deepMap2(array1[i], array2, callback); } } } else if (array1 instanceof Matrix) { if (array2 instanceof Matrix) { // callback(matrix, matrix) res = deepMap2(array1.valueOf(), array2.valueOf(), callback); return new Matrix(res); } else { // callback(matrix, array) // callback(matrix, object) res = deepMap2(array1.valueOf(), array2, callback); return new Matrix(res); } } else { if (isArray(array2)) { // callback(object, array) res = []; len = array2.length; for (i = 0; i < len; i++) { res[i] = deepMap2(array1, array2[i], callback); } } else { // callback(object, object) res = callback(array1, array2); } } return res; }; /** * Reduce a given matrix or array to a new matrix or * array with one less dimension, aplying the given * callback in the selected dimension. * @param {Array | Matrix} mat * @param {Integer} dimension * @param {function} callback * @return {Array | Matrix} res */ exports.reduce = function reduce (mat, dim, callback) { if (mat instanceof Matrix) { return new Matrix(_reduce(mat.valueOf(), dim, callback)); }else { return _reduce(mat, dim, callback); } } function _reduce(mat, dim, callback){ if(dim<=0){ if( !isArray(mat[0]) ){ var i; var val = mat[0]; for(i=1; i