Refactored cross, dot, size, squeeze to typed-functions

This commit is contained in:
jos 2015-04-20 21:28:17 +02:00
parent 7fee110c74
commit c5007d4bf2
8 changed files with 105 additions and 122 deletions

View File

@ -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'));

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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 () {

View File

@ -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 () {