mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
element wise operations
This commit is contained in:
parent
4ab8a7e248
commit
b7ea83e0f2
@ -1,7 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
function factory (type, config, load, typed) {
|
||||
var collection = load(require('../../type/collection'));
|
||||
|
||||
var matrix = load(require('../construction/matrix'));
|
||||
var elementWiseOperations = load(require('../../type/matrix/util/elementWiseOperations'));
|
||||
|
||||
/**
|
||||
* Calculates the modulus, the remainder of an integer division.
|
||||
@ -39,18 +41,100 @@ function factory (type, config, load, typed) {
|
||||
* @return {Number | BigNumber | Array | Matrix} Returns the remainder of `x` divided by `y`.
|
||||
*/
|
||||
var mod = typed('mod', {
|
||||
|
||||
'number, number': _mod,
|
||||
|
||||
'BigNumber, BigNumber': function (x, y) {
|
||||
return y.isZero() ? x : x.mod(y);
|
||||
},
|
||||
|
||||
'Matrix, Matrix': function (x, y) {
|
||||
// result
|
||||
var c;
|
||||
|
||||
'Array | Matrix, any': function (x, y) {
|
||||
return collection.deepMap2(x, y, mod);
|
||||
// process matrix storage
|
||||
switch (x.storage()) {
|
||||
case 'sparse':
|
||||
switch (y.storage()) {
|
||||
case 'sparse':
|
||||
// mod(sparse, sparse)
|
||||
c = elementWiseOperations.algorithm5(x, y, mod, false);
|
||||
break;
|
||||
default:
|
||||
// mod(sparse, dense)
|
||||
c = elementWiseOperations.algorithm2(y, x, mod, true);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
switch (y.storage()) {
|
||||
case 'sparse':
|
||||
// mod(dense, sparse)
|
||||
c = elementWiseOperations.algorithm3(x, y, mod, false);
|
||||
break;
|
||||
default:
|
||||
// mod(dense, dense)
|
||||
c = elementWiseOperations.algorithm11(x, y, mod, false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
},
|
||||
|
||||
'Array, Array': function (x, y) {
|
||||
// use matrix implementation
|
||||
return mod(matrix(x), matrix(y)).valueOf();
|
||||
},
|
||||
|
||||
'any, Array | Matrix': function (x, y) {
|
||||
return collection.deepMap2(x, y, mod);
|
||||
'Array, Matrix': function (x, y) {
|
||||
// use matrix implementation
|
||||
return mod(matrix(x), y);
|
||||
},
|
||||
|
||||
'Matrix, Array': function (x, y) {
|
||||
// use matrix implementation
|
||||
return mod(x, matrix(y));
|
||||
},
|
||||
|
||||
'Matrix, any': function (x, y) {
|
||||
// result
|
||||
var c;
|
||||
// check storage format
|
||||
switch (x.storage()) {
|
||||
case 'sparse':
|
||||
c = elementWiseOperations.algorithm9(x, y, mod, false);
|
||||
break;
|
||||
default:
|
||||
c = elementWiseOperations.algorithm12(x, y, mod, false);
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
},
|
||||
|
||||
'any, Matrix': function (x, y) {
|
||||
// result
|
||||
var c;
|
||||
// check storage format
|
||||
switch (y.storage()) {
|
||||
case 'sparse':
|
||||
c = elementWiseOperations.algorithm10(y, x, mod, true);
|
||||
break;
|
||||
default:
|
||||
c = elementWiseOperations.algorithm12(y, x, mod, true);
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
},
|
||||
|
||||
'Array, any': function (x, y) {
|
||||
// use matrix implementation
|
||||
return elementWiseOperations.algorithm12(matrix(x), y, mod, false).valueOf();
|
||||
},
|
||||
|
||||
'any, Array': function (x, y) {
|
||||
// use matrix implementation
|
||||
return elementWiseOperations.algorithm12(matrix(y), x, mod, true).valueOf();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -4,7 +4,12 @@ var isInteger = require('../../util/number').isInteger;
|
||||
var toFixed = require('../../util/number').toFixed;
|
||||
|
||||
function factory (type, config, load, typed) {
|
||||
|
||||
var collection = load(require('../../type/collection'));
|
||||
var matrix = load(require('../construction/matrix'));
|
||||
var equal = load(require('../relational/equal'));
|
||||
var zeros = load(require('../matrix/zeros'));
|
||||
var elementWiseOperations = load(require('../../type/matrix/util/elementWiseOperations'));
|
||||
|
||||
/**
|
||||
* Round a value towards the nearest integer.
|
||||
@ -38,6 +43,7 @@ function factory (type, config, load, typed) {
|
||||
* @return {Number | BigNumber | Complex | Array | Matrix} Rounded value
|
||||
*/
|
||||
var round = typed('round', {
|
||||
|
||||
'number': Math.round,
|
||||
|
||||
'number, number': function (x, n) {
|
||||
@ -84,12 +90,49 @@ function factory (type, config, load, typed) {
|
||||
return collection.deepMap(x, round, true);
|
||||
},
|
||||
|
||||
'Array | Matrix, number | BigNumber': function (x, n) {
|
||||
return collection.deepMap2(x, n, round);
|
||||
'Matrix, number | BigNumber': function (x, y) {
|
||||
// result
|
||||
var c;
|
||||
// check storage format
|
||||
switch (x.storage()) {
|
||||
case 'sparse':
|
||||
c = elementWiseOperations.algorithm9(x, y, round, false);
|
||||
break;
|
||||
default:
|
||||
c = elementWiseOperations.algorithm12(x, y, round, false);
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
},
|
||||
|
||||
'number | Complex | BigNumber, Array | Matrix': function (x, n) {
|
||||
return collection.deepMap2(x, n, round);
|
||||
'number | Complex | BigNumber, Matrix': function (x, y) {
|
||||
// check scalar is zero
|
||||
if (!equal(x, 0)) {
|
||||
// result
|
||||
var c;
|
||||
// check storage format
|
||||
switch (y.storage()) {
|
||||
case 'sparse':
|
||||
c = elementWiseOperations.algorithm10(y, x, round, true);
|
||||
break;
|
||||
default:
|
||||
c = elementWiseOperations.algorithm12(y, x, round, true);
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
// do not execute algorithm, result will be a zero matrix
|
||||
return zeros(y.size(), y.storage());
|
||||
},
|
||||
|
||||
'Array, number | BigNumber': function (x, y) {
|
||||
// use matrix implementation
|
||||
return elementWiseOperations.algorithm12(matrix(x), y, round, false).valueOf();
|
||||
},
|
||||
|
||||
'number | Complex | BigNumber, Array': function (x, y) {
|
||||
// use matrix implementation
|
||||
return elementWiseOperations.algorithm12(matrix(y), x, round, true).valueOf();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -4,10 +4,11 @@ var approx = require('../../../tools/approx');
|
||||
var math = require('../../../index');
|
||||
var bignumber = math.bignumber;
|
||||
var matrix = math.matrix;
|
||||
var range = math.range;
|
||||
var sparse = math.sparse;
|
||||
var mod = math.mod;
|
||||
|
||||
describe('mod', function() {
|
||||
|
||||
it('should calculate the modulus of booleans correctly', function () {
|
||||
assert.equal(mod(true, true), 0);
|
||||
assert.equal(mod(false, true), 0);
|
||||
@ -38,17 +39,17 @@ describe('mod', function() {
|
||||
});
|
||||
|
||||
it('should throw an error if the modulus is negative', function() {
|
||||
assert.throws(function () {mod(10, -4)});
|
||||
assert.throws(function () {mod(10, -4);});
|
||||
});
|
||||
|
||||
it('should throw an error if used with wrong number of arguments', function() {
|
||||
assert.throws(function () {mod(1)}, /TypeError: Too few arguments/);
|
||||
assert.throws(function () {mod(1,2,3)}, /TypeError: Too many arguments/);
|
||||
assert.throws(function () {mod(1);}, /TypeError: Too few arguments/);
|
||||
assert.throws(function () {mod(1,2,3);}, /TypeError: Too many arguments/);
|
||||
});
|
||||
|
||||
it('should throw an error if used with wrong type of arguments', function() {
|
||||
assert.throws(function () {mod(1, 'string')}, /TypeError: Unexpected type of argument/);
|
||||
assert.throws(function () {mod('string', bignumber(2))}, /TypeError: Unexpected type of argument/);
|
||||
assert.throws(function () {mod(1, 'string');}, /TypeError: Unexpected type of argument/);
|
||||
assert.throws(function () {mod('string', bignumber(2));}, /TypeError: Unexpected type of argument/);
|
||||
});
|
||||
|
||||
it('should calculate the modulus of bignumbers', function() {
|
||||
@ -75,8 +76,8 @@ describe('mod', function() {
|
||||
assert.deepEqual(mod(bignumber(0), 3), bignumber(0));
|
||||
assert.deepEqual(mod(bignumber(7), 0), bignumber(7));
|
||||
|
||||
assert.throws(function () {mod(7/3, bignumber(2))}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
|
||||
assert.throws(function () {mod(bignumber(7).div(3), 1/3)}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
|
||||
assert.throws(function () {mod(7/3, bignumber(2));}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
|
||||
assert.throws(function () {mod(bignumber(7).div(3), 1/3);}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
|
||||
});
|
||||
|
||||
it('should calculate the modulus of mixed booleans and bignumbers', function() {
|
||||
@ -87,24 +88,78 @@ describe('mod', function() {
|
||||
});
|
||||
|
||||
it('should throw an error if used on complex numbers', function() {
|
||||
assert.throws(function () {mod(math.complex(1,2), 3)}, TypeError);
|
||||
assert.throws(function () {mod(3, math.complex(1,2))}, TypeError);
|
||||
assert.throws(function () {mod(bignumber(3), math.complex(1,2))}, TypeError);
|
||||
assert.throws(function () {mod(math.complex(1,2), 3);}, TypeError);
|
||||
assert.throws(function () {mod(3, math.complex(1,2));}, TypeError);
|
||||
assert.throws(function () {mod(bignumber(3), math.complex(1,2));}, TypeError);
|
||||
});
|
||||
|
||||
it('should an throw an error if used on a string', function() {
|
||||
assert.throws(function () {mod('string', 3)}, TypeError);
|
||||
assert.throws(function () {mod(5, 'string')}, TypeError);
|
||||
assert.throws(function () {mod('string', 3);}, TypeError);
|
||||
assert.throws(function () {mod(5, 'string');}, TypeError);
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on a matrix', function() {
|
||||
approx.deepEqual(mod([-4,-3,-2,-1,0,1,2,3,4], 3), [2,0,1,2,0,1,2,0,1]);
|
||||
approx.deepEqual(mod(matrix([-4,-3,-2,-1,0,1,2,3,4]), 3), matrix([2,0,1,2,0,1,2,0,1]));
|
||||
describe('Array', function () {
|
||||
|
||||
it('should perform element-wise modulus on array and scalar', function() {
|
||||
approx.deepEqual(mod([[-4, -3, 0, -1], [0, 1, 2, 3]], 3), [[2, 0, 0, 2], [0, 1, 2, 0]]);
|
||||
approx.deepEqual(mod(3, [[4, 3], [2, 1]]), [[3, 0], [1, 0]]);
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on array and array', function() {
|
||||
approx.deepEqual(mod([[-40, -31], [11, -23]], [[3, 7], [1, 3]]), [[2, 4], [0, 1]]);
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on array and dense matrix', function() {
|
||||
approx.deepEqual(mod([[-40, -31], [11, -23]], matrix([[3, 7], [1, 3]])), matrix([[2, 4], [0, 1]]));
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on array and sparse matrix', function() {
|
||||
approx.deepEqual(mod([[-40, -31], [11, -23]], sparse([[3, 7], [1, 3]])), matrix([[2, 4], [0, 1]]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('DenseMatrix', function () {
|
||||
|
||||
it('should perform element-wise modulus on dense matrix and scalar', function() {
|
||||
approx.deepEqual(mod(matrix([[-4, -3, 0, -1], [0, 1, 2, 3]]), 3), matrix([[2, 0, 0, 2], [0, 1, 2, 0]]));
|
||||
approx.deepEqual(mod(3, matrix([[4, 3], [2, 1]])), matrix([[3, 0], [1, 0]]));
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on dense matrix and array', function() {
|
||||
approx.deepEqual(mod(matrix([[-40, -31], [11, -23]]), [[3, 7], [1, 3]]), matrix([[2, 4], [0, 1]]));
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on dense matrix and dense matrix', function() {
|
||||
approx.deepEqual(mod(matrix([[-40, -31], [11, -23]]), matrix([[3, 7], [1, 3]])), matrix([[2, 4], [0, 1]]));
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on dense matrix and sparse matrix', function() {
|
||||
approx.deepEqual(mod(matrix([[-40, -31], [11, -23]]), sparse([[3, 7], [1, 3]])), matrix([[2, 4], [0, 1]]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('SparseMatrix', function () {
|
||||
|
||||
it('should perform element-wise modulus on sparse matrix and scalar', function() {
|
||||
approx.deepEqual(mod(sparse([[-4, -3, 0, -1], [0, 1, 2, 3]]), 3), sparse([[2, 0, 0, 2], [0, 1, 2, 0]]));
|
||||
approx.deepEqual(mod(3, sparse([[4, 3], [2, 1]])), matrix([[3, 0], [1, 0]]));
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on sparse matrix and array', function() {
|
||||
approx.deepEqual(mod(sparse([[-40, -31], [11, -23]]), [[3, 7], [1, 3]]), sparse([[2, 4], [0, 1]]));
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on sparse matrix and dense matrix', function() {
|
||||
approx.deepEqual(mod(sparse([[-40, -31], [11, -23]]), matrix([[3, 7], [1, 3]])), sparse([[2, 4], [0, 1]]));
|
||||
});
|
||||
|
||||
it('should perform element-wise modulus on sparse matrix and sparse matrix', function() {
|
||||
approx.deepEqual(mod(sparse([[-40, -31], [11, -23]]), sparse([[3, 7], [1, 3]])), sparse([[2, 4], [0, 1]]));
|
||||
});
|
||||
});
|
||||
|
||||
it('should LaTeX mod', function () {
|
||||
var expression = math.parse('mod(11,2)');
|
||||
assert.equal(expression.toTex(), '\\left(11\\mod2\\right)');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
// test round
|
||||
var assert = require('assert'),
|
||||
approx = require('../../../tools/approx'),
|
||||
error = require('../../../lib/error/index'),
|
||||
math = require('../../../index'),
|
||||
bignumber = math.bignumber,
|
||||
matrix = math.matrix,
|
||||
sparse = math.sparse,
|
||||
round = math.round;
|
||||
|
||||
describe('round', function() {
|
||||
@ -83,6 +84,42 @@ describe('round', function() {
|
||||
assert.deepEqual(round([1.7,2.3]), [2,2]);
|
||||
assert.deepEqual(round(math.matrix([1.7,2.3])).valueOf(), [2, 2]);
|
||||
});
|
||||
|
||||
describe('Array', function () {
|
||||
|
||||
it('should round array', function () {
|
||||
assert.deepEqual(round([1.7, 2.3]), [2, 2]);
|
||||
});
|
||||
|
||||
it('should round array and scalar', function () {
|
||||
assert.deepEqual(round([1.7777, 2.3456], 3), [1.778, 2.346]);
|
||||
assert.deepEqual(round(3.12385, [2, 3]), [3.12, 3.124]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DenseMatrix', function () {
|
||||
|
||||
it('should round dense matrix', function () {
|
||||
assert.deepEqual(round(matrix([[1.7, 2.3], [8.987, -3.565]])), matrix([[2, 2], [9, -4]]));
|
||||
});
|
||||
|
||||
it('should round dense matrix and scalar', function () {
|
||||
assert.deepEqual(round(matrix([[1.7777, 2.3456],[-90.8272, 0]]), 3), matrix([[1.778, 2.346], [-90.827, 0]]));
|
||||
assert.deepEqual(round(3.12385, matrix([[2, 3], [0, 2]])), matrix([[3.12, 3.124],[3, 3.12]]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('SparseMatrix', function () {
|
||||
|
||||
it('should round sparse matrix', function () {
|
||||
assert.deepEqual(round(sparse([[1.7, 0], [8.987, -3.565]])), sparse([[2, 0], [9, -4]]));
|
||||
});
|
||||
|
||||
it('should round sparse matrix and scalar', function () {
|
||||
assert.deepEqual(round(sparse([[1.7777, 2.3456],[-90.8272, 0]]), 3), sparse([[1.778, 2.346], [-90.827, 0]]));
|
||||
assert.deepEqual(round(3.12385, sparse([[2, 3], [0, 2]])), matrix([[3.12, 3.124],[3, 3.12]]));
|
||||
});
|
||||
});
|
||||
|
||||
it('should LaTeX round', function () {
|
||||
var expr1 = math.parse('round(1.1)');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user