diff --git a/index.js b/index.js index 57c16afc5..3a343d655 100644 --- a/index.js +++ b/index.js @@ -129,18 +129,18 @@ function create (config) { // functions - matrix require('./lib/function/matrix/concat')(math, _config); - require('./lib/function/matrix/cross')(math, _config); + math.import(require('./lib/function/matrix/cross')); math.import(require('./lib/function/matrix/det')); math.import(require('./lib/function/matrix/diag')); - require('./lib/function/matrix/dot')(math, _config); + math.import(require('./lib/function/matrix/dot')); math.import(require('./lib/function/matrix/eye')); require('./lib/function/matrix/flatten')(math, _config); math.import(require('./lib/function/matrix/inv')); require('./lib/function/matrix/ones')(math, _config); require('./lib/function/matrix/range')(math, _config); require('./lib/function/matrix/resize')(math, _config); - require('./lib/function/matrix/size')(math, _config); - require('./lib/function/matrix/squeeze')(math, _config); + math.import(require('./lib/function/matrix/size')); + math.import(require('./lib/function/matrix/squeeze')); require('./lib/function/matrix/subset')(math, _config); require('./lib/function/matrix/trace')(math, _config); math.import(require('./lib/function/matrix/transpose')); diff --git a/lib/function/matrix/cross.js b/lib/function/matrix/cross.js index ac65e48ee..fc71126e5 100644 --- a/lib/function/matrix/cross.js +++ b/lib/function/matrix/cross.js @@ -1,8 +1,11 @@ 'use strict'; -module.exports = function(math) { - var array = require('../../util/array'); - var Matrix = math.type.Matrix; +var size = require('../../util/array').size; + +function factory (type, config, load, typed) { + var matrix = load(require('../construction/matrix')); + var subtract = load(require('../arithmetic/subtract')); + var multiply = load(require('../arithmetic/multiply')); /** * Calculate the cross product for two vectors in three dimensional space. @@ -33,26 +36,21 @@ module.exports = function(math) { * @param {Array | Matrix} y Second vector * @return {Array | Matrix} Returns the cross product of `x` and `y` */ - math.cross = function cross(x, y) { - if (x instanceof Matrix) { - if (y instanceof Matrix) { - return math.matrix(_cross(x.toArray(), y.toArray())); - } - else if (Array.isArray(y)) { - return math.matrix(_cross(x.toArray(), y)); - } - } - else if (Array.isArray(x)) { - if (y instanceof Matrix) { - return math.matrix(_cross(x, y.toArray())); - } - else if (Array.isArray(y)) { - return _cross(x, y); - } - } + return typed('cross', { + 'Matrix, Matrix': function (x, y) { + return matrix(_cross(x.toArray(), y.toArray())); + }, - throw new math.error.UnsupportedTypeError('cross', math['typeof'](x), math['typeof'](y)); - }; + 'Matrix, Array': function (x, y) { + return matrix(_cross(x.toArray(), y)); + }, + + 'Array, Matrix': function (x, y) { + return matrix(_cross(x, y.toArray())); + }, + + 'Array, Array': _cross + }); /** * Calculate the cross product for two arrays @@ -62,8 +60,8 @@ module.exports = function(math) { * @private */ function _cross(x, y) { - var xSize= array.size(x); - var ySize = array.size(y); + var xSize= size(x); + var ySize = size(y); if (xSize.length != 1 || ySize.length != 1 || xSize[0] != 3 || ySize[0] != 3) { throw new RangeError('Vectors with length 3 expected ' + @@ -71,9 +69,12 @@ module.exports = function(math) { } return [ - math.subtract(math.multiply(x[1], y[2]), math.multiply(x[2], y[1])), - math.subtract(math.multiply(x[2], y[0]), math.multiply(x[0], y[2])), - math.subtract(math.multiply(x[0], y[1]), math.multiply(x[1], y[0])) + subtract(multiply(x[1], y[2]), multiply(x[2], y[1])), + subtract(multiply(x[2], y[0]), multiply(x[0], y[2])), + subtract(multiply(x[0], y[1]), multiply(x[1], y[0])) ]; } -}; +} + +exports.name = 'cross'; +exports.factory = factory; diff --git a/lib/function/matrix/dot.js b/lib/function/matrix/dot.js index 91ae29200..65f82a4c0 100644 --- a/lib/function/matrix/dot.js +++ b/lib/function/matrix/dot.js @@ -1,8 +1,10 @@ 'use strict'; -module.exports = function(math) { - var array = require('../../util/array'); - var Matrix = math.type.Matrix; +var size = require('../../util/array').size; + +function factory (type, config, load, typed) { + var add = load(require('../arithmetic/add')); + var multiply = load(require('../arithmetic/multiply')); /** * Calculate the dot product of two vectors. The dot product of @@ -27,26 +29,21 @@ module.exports = function(math) { * @param {Array | Matrix} y Second vector * @return {Number} Returns the dot product of `x` and `y` */ - math.dot = function dot(x, y) { - if (x instanceof Matrix) { - if (y instanceof Matrix) { - return _dot(x.toArray(), y.toArray()); - } - else if (Array.isArray(y)) { - return _dot(x.toArray(), y); - } - } - else if (Array.isArray(x)) { - if (y instanceof Matrix) { - return _dot(x, y.toArray()); - } - else if (Array.isArray(y)) { - return _dot(x, y); - } - } + return typed('dot', { + 'Matrix, Matrix': function (x, y) { + return _dot(x.toArray(), y.toArray()); + }, - throw new math.error.UnsupportedTypeError('dot', math['typeof'](x), math['typeof'](y)); - }; + 'Matrix, Array': function (x, y) { + return _dot(x.toArray(), y); + }, + + 'Array, Matrix': function (x, y) { + return _dot(x, y.toArray()); + }, + + 'Array, Array': _dot + }); /** * Calculate the dot product for two arrays @@ -57,8 +54,8 @@ module.exports = function(math) { */ // TODO: double code with math.multiply function _dot(x, y) { - var xSize= array.size(x); - var ySize = array.size(y); + var xSize= size(x); + var ySize = size(y); var len = xSize[0]; if (xSize.length !== 1 || ySize.length !== 1) throw new RangeError('Vector expected'); // TODO: better error message @@ -67,9 +64,12 @@ module.exports = function(math) { var prod = 0; for (var i = 0; i < len; i++) { - prod = math.add(prod, math.multiply(x[i], y[i])); + prod = add(prod, multiply(x[i], y[i])); } return prod; } -}; +} + +exports.name = 'dot'; +exports.factory = factory; diff --git a/lib/function/matrix/size.js b/lib/function/matrix/size.js index e8cd66131..7d232bec3 100644 --- a/lib/function/matrix/size.js +++ b/lib/function/matrix/size.js @@ -1,19 +1,9 @@ 'use strict'; -module.exports = function (math, config) { - var util = require('../../util/index'), +var array = require('../../util/array'); - BigNumber = math.type.BigNumber, - Complex = require('../../type/Complex'), - Unit = require('../../type/Unit'), - Matrix = math.type.Matrix, - - array = util.array, - isNumber = util.number.isNumber, - isBoolean = util['boolean'].isBoolean, - isString = util.string.isString, - isComplex = Complex.isComplex, - isUnit = Unit.isUnit; +function factory (type, config, load, typed) { + var matrix = load(require('../construction/matrix')); /** * Calculate the size of a matrix or scalar. @@ -38,30 +28,24 @@ module.exports = function (math, config) { * @param {Boolean | Number | Complex | Unit | String | Array | Matrix} x A matrix * @return {Array | Matrix} A vector with size of `x`. */ - math.size = function size (x) { - if (arguments.length != 1) { - throw new math.error.ArgumentsError('size', arguments.length, 1); + return typed('size', { + 'Matrix': function (x) { + // TODO: return the same matrix type as the input + return matrix(x.size()); + }, + + 'Array': array.size, + + 'string': function (x) { + return (config.matrix === 'array') ? [x.length] : matrix([x.length]); + }, + + 'number | Complex | BigNumber | Unit | boolean | null': function (x) { + // scalar + return (config.matrix === 'array') ? [] : matrix([]); } + }); +} - var asArray = (config.matrix === 'array'); - - if (isNumber(x) || isComplex(x) || isUnit(x) || isBoolean(x) || - x == null || x instanceof BigNumber) { - return asArray ? [] : math.matrix([]); - } - - if (isString(x)) { - return asArray ? [x.length] : math.matrix([x.length]); - } - - if (Array.isArray(x)) { - return array.size(x); - } - - if (x instanceof Matrix) { - return math.matrix(x.size()); - } - - throw new math.error.UnsupportedTypeError('size', math['typeof'](x)); - }; -}; +exports.name = 'size'; +exports.factory = factory; diff --git a/lib/function/matrix/squeeze.js b/lib/function/matrix/squeeze.js index 8ce30900a..4f5124806 100644 --- a/lib/function/matrix/squeeze.js +++ b/lib/function/matrix/squeeze.js @@ -1,13 +1,10 @@ 'use strict'; -module.exports = function (math) { - var util = require('../../util/index'), +var object = require('../../util/object'); +var array = require('../../util/array'); - Matrix = math.type.Matrix, - - object = util.object, - array = util.array, - isArray = Array.isArray; +function factory (type, config, load, typed) { + var matrix = load(require('../construction/matrix')); /** * Squeeze a matrix, remove inner and outer singleton dimensions from a matrix. @@ -38,21 +35,23 @@ module.exports = function (math) { * @param {Matrix | Array} x Matrix to be squeezed * @return {Matrix | Array} Squeezed matrix */ - math.squeeze = function squeeze (x) { - if (arguments.length != 1) { - throw new math.error.ArgumentsError('squeeze', arguments.length, 1); - } - - if (isArray(x)) { + return typed('squeeze', { + 'Array': function (x) { return array.squeeze(object.clone(x)); - } - else if (x instanceof Matrix) { + }, + + 'Matrix': function (x) { var res = array.squeeze(x.toArray()); - return isArray(res) ? math.matrix(res) : res; - } - else { + // FIXME: return the same type of matrix as the input + return Array.isArray(res) ? matrix(res) : res; + }, + + 'any': function (x) { // scalar return object.clone(x); } - }; -}; + }); +} + +exports.name = 'squeeze'; +exports.factory = factory; diff --git a/lib/util/array.js b/lib/util/array.js index cf0aca01c..94f710923 100644 --- a/lib/util/array.js +++ b/lib/util/array.js @@ -228,7 +228,6 @@ function _resize (array, size, dim, defaultValue) { * @param {Array} array * @param {Array} [size] * @returns {Array} returns the array itself - * @private */ exports.squeeze = function(array, size) { var s = size || exports.size(array); diff --git a/test/function/matrix/size.test.js b/test/function/matrix/size.test.js index 4c0198b2f..7dfd77973 100644 --- a/test/function/matrix/size.test.js +++ b/test/function/matrix/size.test.js @@ -53,12 +53,12 @@ describe('size', function() { }); it('should throw an error if called with an invalid number of arguments', function() { - assert.throws(function () {size()}, error.ArgumentsError); - assert.throws(function () {size(1,2)}, error.ArgumentsError); + assert.throws(function () {size()}, /TypeError: Too few arguments/); + assert.throws(function () {size(1,2)}, /TypeError: Too many arguments/); }); it('should throw an error if called with invalid type of arguments', function() { - assert.throws(function () {size(new Date())}, math.error.UnsupportedTypeError); + assert.throws(function () {size(new Date())}, /TypeError: Unexpected type of argument/); }); it('should LaTeX size', function () { diff --git a/test/function/matrix/squeeze.test.js b/test/function/matrix/squeeze.test.js index 60daa277b..cba2868f7 100644 --- a/test/function/matrix/squeeze.test.js +++ b/test/function/matrix/squeeze.test.js @@ -28,8 +28,8 @@ describe('squeeze', function() { }); it('should throw an error if called with an invalid number of arguments', function() { - assert.throws(function () {squeeze()}, error.ArgumentsError); - assert.throws(function () {squeeze(1,2)}, error.ArgumentsError); + assert.throws(function () {squeeze()}, /TypeError: Too few arguments/); + assert.throws(function () {squeeze(1,2)}, /TypeError: Too many arguments/); }); it('should LaTeX squeeze', function () {