Intial Commit

This commit is contained in:
valki
2020-10-17 18:42:50 +02:00
commit 664c6d8ca3
5892 changed files with 759183 additions and 0 deletions

View File

@@ -0,0 +1,389 @@
// test lup
var assert = require('assert'),
approx = require('../../../../tools/approx'),
math = require('../../../../index');
describe('lup', function () {
it('should decompose matrix, n x n, no permutations, array', function () {
var m = [[2, 1], [1, 4]];
var r = math.lup(m);
// L
assert.deepEqual(r.L.valueOf(), [[1, 0], [0.5, 1]]);
// U
assert.deepEqual(r.U.valueOf(), [[2, 1], [0, 3.5]]);
// P
assert.deepEqual(r.p, [0, 1]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, n x n, no permutations, sparse', function () {
var m = math.matrix([[2, 1], [1, 4]], 'sparse');
var r = math.lup(m);
// L
assert.deepEqual(r.L.valueOf(), [[1, 0], [0.5, 1]]);
// U
assert.deepEqual(r.U.valueOf(), [[2, 1], [0, 3.5]]);
// P
assert.deepEqual(r.p, [0, 1]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, n x n, no permutations, dense format', function () {
var m = math.matrix([[2, 1], [1, 4]], 'dense');
var r = math.lup(m);
// L
assert.deepEqual(r.L.valueOf(), [[1, 0], [0.5, 1]]);
// U
assert.deepEqual(r.U.valueOf(), [[2, 1], [0, 3.5]]);
// P
assert.deepEqual(r.p, [0, 1]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, m x n, m < n, no permutations, dense format', function () {
var m = math.matrix(
[
[2, 1, 1],
[1, 4, 5]
]
);
var r = math.lup(m);
// L
assert.deepEqual(
r.L,
math.matrix(
[
[1, 0],
[0.5, 1]
]
));
// U
assert.deepEqual(
r.U,
math.matrix(
[
[2, 1, 1],
[0, 3.5, 4.5]
]
));
// P
assert.deepEqual(r.p, [0, 1]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, m x n, m > n, no permutations, dense format', function () {
var m = math.matrix(
[
[8, 2],
[6, 4],
[4, 1]
]
);
var r = math.lup(m);
// L
assert.deepEqual(
r.L,
math.matrix(
[
[1, 0],
[0.75, 1],
[0.5, 0]
]
));
// U
assert.deepEqual(
r.U,
math.matrix(
[
[8, 2],
[0, 2.5]
]
));
// P
assert.deepEqual(r.p, [0, 1, 2]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, n x n, dense format', function () {
var m = math.matrix(
[
[16, -120, 240, -140],
[-120, 1200, -2700, 1680],
[240, -2700, 6480, -4200],
[-140, 1680, -4200, 2800]
]
);
var r = math.lup(m);
// L
approx.deepEqual(
r.L.valueOf(),
[
[1, 0, 0, 0],
[-0.5, 1, 0, 0],
[-0.5833333333333334, -0.7, 1, 0],
[0.06666666666666667, -0.4, -0.5714285714285776, 1]
]);
// U
approx.deepEqual(
r.U.valueOf(),
[
[240, -2700, 6480, -4200],
[0, -150, 540, -420],
[0, 0, -42, 56],
[0, 0, 0, 4]
]);
// P
assert.deepEqual(r.p, [3, 1, 0, 2]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 3 x 3, zero pivote value, dense format', function () {
var m = math.matrix(
[
[1, 2, 3],
[2, 4, 6],
[4, 8, 9]
]);
var r = math.lup(m);
// L
approx.deepEqual(
r.L.valueOf(),
[
[1, 0, 0],
[0.5, 1, 0],
[0.25, 0, 1.0]
]);
// U
approx.deepEqual(
r.U.valueOf(),
[
[4, 8, 9],
[0, 0, 1.5],
[0, 0, 0.75]
]);
// P
assert.deepEqual(r.p, [2, 1, 0]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 3 x 2, complex numbers, dense format', function () {
var m = math.matrix(
[
[math.complex(0, 3), 10],
[math.complex(0, 1), 1],
[math.complex(0, 1), 1]
]);
var r = math.lup(m);
// L
approx.deepEqual(
r.L.valueOf(),
[
[1, 0],
[math.complex(0.3333333, 0), 1],
[math.complex(0.3333333, 0), 1]
]);
// U
approx.deepEqual(
r.U.valueOf(),
[
[math.complex(0, 3), 10],
[0, math.complex(-2.3333333333, 0)]
]);
// P
assert.deepEqual(r.p, [0, 1, 2]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, m x n, m < n, no permutations, sparse', function () {
var m = math.matrix(
[
[2, 1, 1],
[1, 4, 5]
],
'sparse');
var r = math.lup(m);
// L
assert.deepEqual(
r.L.valueOf(),
[
[1, 0],
[0.5, 1]
]);
// U
assert.deepEqual(
r.U.valueOf(),
[
[2, 1, 1],
[0, 3.5, 4.5]
]);
// P
assert.deepEqual(r.p, [0, 1]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, m x n, m > n, no permutations, sparse', function () {
var m = math.matrix(
[
[8, 2],
[6, 4],
[4, 1]
],
'sparse');
var r = math.lup(m);
// L
assert.deepEqual(
r.L.valueOf(),
[
[1, 0],
[0.75, 1],
[0.5, 0]
]);
// U
assert.deepEqual(
r.U.valueOf(),
[
[8, 2],
[0, 2.5]
]);
// P
assert.deepEqual(r.p, [0, 1, 2]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, n x n, sparse', function () {
var m = math.matrix(
[
[16, -120, 240, -140],
[-120, 1200, -2700, 1680],
[240, -2700, 6480, -4200],
[-140, 1680, -4200, 2800]
],
'sparse');
var r = math.lup(m);
// L
approx.deepEqual(
r.L.valueOf(),
[
[1, 0, 0, 0],
[-0.5, 1, 0, 0],
[-0.5833333333333334, -0.7, 1, 0],
[0.06666666666666667, -0.4, -0.5714285714285776, 1]
]);
// U
approx.deepEqual(
r.U.valueOf(),
[
[240, -2700, 6480, -4200],
[0, -150, 540, -420],
[0, 0, -42, 56],
[0, 0, 0, 4]
]);
// P
assert.deepEqual(r.p, [3, 1, 0, 2]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 3 x 3, zero pivote value, sparse', function () {
var m = math.matrix(
[
[1, 2, 3],
[2, 4, 6],
[4, 8, 9]
],
'sparse');
var r = math.lup(m);
// L
approx.deepEqual(
r.L.valueOf(),
[
[1, 0, 0],
[0.5, 1, 0],
[0.25, 0, 1.0]
]);
// U
approx.deepEqual(
r.U.valueOf(),
[
[4, 8, 9],
[0, 0, 1.5],
[0, 0, 0.75]
]);
// P
assert.deepEqual(r.p, [2, 1, 0]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 3 x 2, complex numbers, sparse', function () {
var m = math.matrix(
[
[math.complex(0, 3), 10],
[math.complex(0, 1), 1],
[math.complex(0, 1), 1]
], 'sparse');
var r = math.lup(m);
// L
approx.deepEqual(
r.L.valueOf(),
[
[1, 0],
[math.complex(0.3333333, 0), 1],
[math.complex(0.3333333, 0), 1]
]);
// U
approx.deepEqual(
r.U.valueOf(),
[
[math.complex(0, 3), 10],
[0, math.complex(-2.3333333333, 0)]
]);
// P
assert.deepEqual(r.p, [0, 1, 2]);
// verify
approx.deepEqual(math.multiply(_p(r.p), m).valueOf(), math.multiply(r.L, r.U).valueOf());
});
/**
* Creates a Matrix out of a row permutation vector
*/
function _p(p) {
// identity matrix
var identity = math.eye(p.length);
// array
var data = [];
// loop rows
for (var i = 0, l = p.length; i < l; i++) {
// swap row
data[p[i]] = identity._data[i];
}
return data;
}
});

View File

@@ -0,0 +1,199 @@
var approx = require('../../../../tools/approx'),
math = require('../../../../index'),
market = require('../../../../tools/matrixmarket');
describe('slu', function () {
it('should decompose matrix, 4 x 4, natural ordering (order=0), partial pivoting', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// partial pivoting
var r = math.slu(m, 0, 1);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 4 x 4, amd(A+A\') (order=1)', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// partial pivoting
var r = math.slu(m, 1, 1);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 4 x 4, amd(A\'*A) (order=2), partial pivoting', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// partial pivoting
var r = math.slu(m, 2, 1);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 4 x 4, amd(A\'*A) (order=3), partial pivoting', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// partial pivoting
var r = math.slu(m, 3, 1);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 48 x 48, natural ordering (order=0), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// full pivoting
var r = math.slu(m, 0, 0.001);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should decompose matrix, 48 x 48, amd(A+A\') (order=1), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// full pivoting
var r = math.slu(m, 1, 0.001);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should decompose matrix, 48 x 48, amd(A\'*A) (order=2), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// full pivoting
var r = math.slu(m, 2, 0.001);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should decompose matrix, 48 x 48, amd(A\'*A) (order=3), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// full pivoting
var r = math.slu(m, 3, 0.001);
// verify M[p,q]=L*U
approx.deepEqual(_permute(m, r.p, r.q).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
/**
* C = A(p,q) where p is the row permutation vector and q the column permutation vector.
*/
var _permute = function (A, pinv, q) {
// matrix arrays
var values = A._values;
var index = A._index;
var ptr = A._ptr;
var size = A._size;
// columns
var n = size[1];
// c arrays
var cvalues = [];
var cindex = [];
var cptr = [];
// loop columns
for (var k = 0 ; k < n ; k++) {
cptr[k] = cindex.length;
// column in C
var j = q ? (q[k]) : k;
// values in column j
for (var t = ptr[j]; t < ptr[j + 1]; t++) {
cvalues.push(values[t]);
cindex.push(pinv ? (pinv[index[t]]) : index[t]);
}
}
cptr[n] = cindex.length;
// return matrix
return new math.type.SparseMatrix({
values: cvalues,
index: cindex,
ptr: cptr,
size: size,
datatype: A._datatype
});
};
});

View File

@@ -0,0 +1,234 @@
// test derivative
var assert = require('assert');
var math = require('../../../index');
var OperatorNode = math.expression.node.OperatorNode;
var derivative = math.derivative;
describe('derivative', function() {
function derivativeWithoutSimplify (expr, value) {
return math.derivative(expr, value, {simplify: false});
}
function compareString(left, right) {
assert.equal(left.toString(), right.toString());
}
it('should take the derivative of a constant', function() {
compareString(derivativeWithoutSimplify('1', 'x'), '0');
compareString(derivativeWithoutSimplify('10000000', 'x'), '0');
});
it('should reckon with option simplify', function() {
compareString(derivative('2x', 'x'), '2'); // default of simplify is true
compareString(derivative('2x', 'x', {simplify: true}), '2');
compareString(derivative('2x', 'x', {simplify: false}), '2 * 1');
});
it('should create a function node', function() {
compareString(derivative('sin(2x)', 'x'), '2 * cos(2 * x)');
});
it('should take the derivative of a SymbolNodes', function() {
compareString(derivativeWithoutSimplify('x', 'x'), '1');
});
it('should maintain parenthesis of ParenthesisNodes', function() {
compareString(derivativeWithoutSimplify('(1)', 'x'), '(0)');
compareString(derivativeWithoutSimplify('(x)', 'x'), '(1)');
});
it('should take the derivative of FunctionAssignmentNodes', function() {
compareString(derivativeWithoutSimplify('f(x) = 5x + x + 2', 'x'), '5 * 1 + 1 + 0');
compareString(derivativeWithoutSimplify('f(x) = 5 + 2', 'x'), '0');
compareString(derivativeWithoutSimplify('f(y) = 5y + 2', 'x'), '0');
// non-embedded example
var f_of_x = math.parse('f(x) = x + 2');
var newFunc = new OperatorNode('+', 'add', [math.parse('5x'), f_of_x]);
assert.equal(derivativeWithoutSimplify(newFunc, 'x'), '5 * 1 + 1 + 0');
});
it('should take the derivative of a OperatorNodes with ConstantNodes', function() {
compareString(derivativeWithoutSimplify('1 + 2', 'x'), '0');
compareString(derivativeWithoutSimplify('-100^2 + 3*3/2 - 12', 'x'), '0');
});
it('should take the derivative of a OperatorNodes with SymbolNodes', function() {
// d/dx(-4x) = -4*1 = -4
compareString(derivativeWithoutSimplify('-4x', 'x'), '-4 * 1');
// d/dx(+4x) = +4*1 = +4
compareString(derivativeWithoutSimplify('+4x', 'x'), '+4 * 1');
// Linearity of differentiation
// With '+': d/dx(5x + x + 2) = 5*1 + 1 + 0 = 6
compareString(derivativeWithoutSimplify('5x + x + 2', 'x'), '5 * 1 + 1 + 0');
// With '-': d/dx(5x - x - 2) = 5*1 - 1 - 0 = 4
compareString(derivativeWithoutSimplify('5x - x - 2', 'x'), '5 * 1 - 1 - 0');
// d/dx(2*(x + x)) = 2*(1 + 1)
compareString(derivativeWithoutSimplify('2(x + x)', 'x'), '2 * (1 + 1)');
compareString(derivativeWithoutSimplify('(x + x)*2', 'x'), '2 * (1 + 1)');
// Product Rule, d/dx(5x*3x) = 5*(3*1*x + x*3*1) = 30x
compareString(derivativeWithoutSimplify('5x*3x', 'x'), '3 * 5 * 1 * x + 5 x * 3 * 1');
// Basic division, d/dx(7x / 2) = 7 * 1 / 2 = 7 / 2
compareString(derivativeWithoutSimplify('7x / 2', 'x'), '7 * 1 / 2');
// Reciprocal Rule, d/dx(5 / (3x)) = -5 * (3 * 1) / (3 * x) ^ 2 = -5 / 3x^2
compareString(derivativeWithoutSimplify('5 / (3x)', 'x'), '-5 * (3 * 1) / (3 x) ^ 2');
// Quotient rule, d/dx((2x) / (3x + 2)) = ((2*1)(3x + 2) - (2x)(3*1 + 0)) / (3x + 2)^2 = 4 / (3x + 2)^2
compareString(derivativeWithoutSimplify('(2x) / (3x + 2)', 'x'), '((2 * 1) * (3 x + 2) - (2 x) * (3 * 1 + 0)) / (3 x + 2) ^ 2');
// Secret constant; 0^f(x) = 1 (in JS), 1^f(x) = 1, d/dx(1) = 0
compareString(derivativeWithoutSimplify('0^(2^x + x^3 + 2)', 'x'), '0');
compareString(derivativeWithoutSimplify('1^(2^x + x^3 + 2)', 'x'), '0');
// d/dx(10^(2x + 2)) = 10^(2x + 2)*ln(10)*(2*1 + 0)
assert.equal(derivativeWithoutSimplify('10^(2x + 2)', 'x'), '10 ^ (2 x + 2) * log(10) * (2 * 1 + 0)');
// Secret constant, f(x)^0 = 1 -> d/dx(f(x)^0) = 1
compareString(derivativeWithoutSimplify('(x^x^x^x)^0', 'x'), '0');
// Ignore powers of 1, d/dx((x + 2)^1) -> d/dx(x+2) = (1 + 0) = 1
compareString(derivativeWithoutSimplify('(x+2)^1', 'x'), '(1 + 0)');
// Elementary Power Rule, d/dx(2x^2) = 2*2*1*x^(2-1) = 4x
compareString(derivativeWithoutSimplify('2x^2', 'x'), '2 * 2 * 1 * x ^ (2 - 1)');
// Elementary Power Rule, d/dx(2x^-2) = 2*-2*1*x^(-2-1) = -4x^-3
compareString(derivativeWithoutSimplify('2x^-2', 'x'), '2 * -2 * 1 * x ^ (-2 - 1)');
// Functional Power Rule, d/dx((x^3 + x)^(5x + 2)) = (x^3 + x)^(5x + 2) * [(((3*1*x)^(3-1)+1) * ((5x + 2) / (x^3 + x))) + (5*1 + 0)log((x^3 + x))]
// = (x^3 + x)^(5x + 2) * [((3x^2 + 1)*(5x + 2) / (x^3 + x)) + 5log(x^3 + x)]
compareString(derivativeWithoutSimplify('(x^3 + x)^(5x + 2)', 'x'), '(x ^ 3 + x) ^ (5 x + 2) * ((3 * 1 * x ^ (3 - 1) + 1) * (5 x + 2) / (x ^ 3 + x) + (5 * 1 + 0) * log((x ^ 3 + x)))');
});
it('should properly take the derivative of mathematical functions', function() {
compareString(derivativeWithoutSimplify('cbrt(6x)', 'x'), '6 * 1 / (3 * (6 x) ^ (2 / 3))');
compareString(derivativeWithoutSimplify('sqrt(6x)', 'x'), '6 * 1 / (2 * sqrt(6 x))');
compareString(derivativeWithoutSimplify('nthRoot(6x)', 'x'), '6 * 1 / (2 * sqrt(6 x))');
compareString(derivativeWithoutSimplify('nthRoot(6x, 3)', 'x'), '1 / 3 * 6 * 1 * (6 x) ^ (1 / 3 - 1)');
compareString(derivativeWithoutSimplify('nthRoot((6x), (2x))', 'x'), '(6 x) ^ (1 / (2 x)) * ((6 * 1) * 1 / (2 x) / (6 x) + (0 * (2 x) - 1 * (2 * 1)) / (2 x) ^ 2 * log((6 x)))');
compareString(derivativeWithoutSimplify('log((6*x))', 'x'), '(6 * 1) / (6 * x)');
compareString(derivativeWithoutSimplify('log10((6x))', 'x'), '(6 * 1) / ((6 x) * log(10))');
compareString(derivativeWithoutSimplify('log((6x), 10)', 'x'), '(6 * 1) / ((6 x) * log(10))');
// d/dx(log(2x, 3x)) = ((2 * 1) / (2 * x) * log(3 * x) - log(2 * x) * (3 * 1) / (3 * x)) / log(3 * x) ^ 2 = (log(3x) - log(2x)) / (xlog(3x)^2)
compareString(derivativeWithoutSimplify('log((2x), (3x))', 'x'), '((2 * 1) / (2 x) * log((3 x)) - log((2 x)) * (3 * 1) / (3 x)) / log((3 x)) ^ 2');
compareString(derivativeWithoutSimplify('sin(2x)', 'x'), '2 * 1 * cos(2 x)');
compareString(derivativeWithoutSimplify('cos(2x)', 'x'), '2 * 1 * -sin(2 x)');
compareString(derivativeWithoutSimplify('tan(2x)', 'x'), '2 * 1 * sec(2 x) ^ 2');
compareString(derivativeWithoutSimplify('sec(2x)', 'x'), '2 * 1 * sec(2 x) * tan(2 x)');
compareString(derivativeWithoutSimplify('csc(2x)', 'x'), '-(2 * 1) * csc(2 x) * cot(2 x)');
compareString(derivativeWithoutSimplify('cot((2x))', 'x'), '-(2 * 1) * csc((2 x)) ^ 2');
compareString(derivativeWithoutSimplify('asin((2x))', 'x'), '(2 * 1) / sqrt(1 - (2 x) ^ 2)');
compareString(derivativeWithoutSimplify('acos((2x))', 'x'), '-(2 * 1) / sqrt(1 - (2 x) ^ 2)');
compareString(derivativeWithoutSimplify('atan((2x))', 'x'), '(2 * 1) / ((2 x) ^ 2 + 1)');
compareString(derivativeWithoutSimplify('asec((2x))', 'x'), '(2 * 1) / (abs((2 x)) * sqrt((2 x) ^ 2 - 1))');
compareString(derivativeWithoutSimplify('acsc((2x))', 'x'), '-(2 * 1) / (abs((2 x)) * sqrt((2 x) ^ 2 - 1))');
compareString(derivativeWithoutSimplify('acot((2x))', 'x'), '-(2 * 1) / ((2 x) ^ 2 + 1)');
compareString(derivativeWithoutSimplify('sinh(2x)', 'x'), '2 * 1 * cosh(2 x)');
compareString(derivativeWithoutSimplify('cosh(2x)', 'x'), '2 * 1 * sinh(2 x)');
compareString(derivativeWithoutSimplify('tanh(2x)', 'x'), '2 * 1 * sech(2 x) ^ 2');
compareString(derivativeWithoutSimplify('sech(2x)', 'x'), '-(2 * 1) * sech(2 x) * tanh(2 x)');
compareString(derivativeWithoutSimplify('csch(2x)', 'x'), '-(2 * 1) * csch(2 x) * coth(2 x)');
compareString(derivativeWithoutSimplify('coth(2x)', 'x'), '-(2 * 1) * csch(2 x) ^ 2');
compareString(derivativeWithoutSimplify('asinh((2x))', 'x'), '(2 * 1) / sqrt((2 x) ^ 2 + 1)');
compareString(derivativeWithoutSimplify('acosh((2x))', 'x'), '(2 * 1) / sqrt((2 x) ^ 2 - 1)');
compareString(derivativeWithoutSimplify('atanh((2x))', 'x'), '(2 * 1) / (1 - (2 x) ^ 2)');
compareString(derivativeWithoutSimplify('asech((2x))', 'x'), '-(2 * 1) / ((2 x) * sqrt(1 - (2 x) ^ 2))');
compareString(derivativeWithoutSimplify('acsch((2x))', 'x'), '-(2 * 1) / (abs((2 x)) * sqrt((2 x) ^ 2 + 1))');
compareString(derivativeWithoutSimplify('acoth((2x))', 'x'), '-(2 * 1) / (1 - (2 x) ^ 2)');
compareString(derivativeWithoutSimplify('exp(2x)', 'x'), '2 * 1 * exp(2 x)');
});
it('should take the partial derivative of an expression', function() {
compareString(derivativeWithoutSimplify('x + y', 'x'), '1 + 0');
compareString(derivativeWithoutSimplify('x + log(y)*y', 'x'), '1 + 0');
compareString(derivativeWithoutSimplify('x + y + z', 'x'), '1 + 0 + 0');
compareString(derivativeWithoutSimplify('x + log(y)*z', 'x'), '1 + 0');
compareString(derivativeWithoutSimplify('x + log(y)*x', 'x'), '1 + log(y) * 1');
// 2 * 1 * x ^ (2 - 1) + y * 1 + 0 = 2x + y
compareString(derivativeWithoutSimplify('x^2 + x*y + y^2', 'x'), '2 * 1 * x ^ (2 - 1) + y * 1 + 0');
});
it('should function properly even without being called within an eval', function() {
var f = math.parse('2x^3');
// 2*3*1*x^(3-1) = 6x^2
compareString(derivativeWithoutSimplify(f, 'x').toString(), '2 * 3 * 1 * x ^ (3 - 1)');
});
it('should accept string and Node input', function() {
// NOTE: we use `parse` here on purpose to see whether derivative accepts it
compareString(derivative('x^2', 'x'), '2 * x');
compareString(derivative(math.parse('x^2'), 'x'), '2 * x');
compareString(derivative('x^2', math.parse('x')), '2 * x');
compareString(derivative(math.parse('x^2'), math.parse('x')), '2 * x');
});
describe('expression parser', function() {
it('should evaluate a derivative containing string value', function() {
var res = math.eval('derivative("x^2", "x")');
assert.ok(res && res.isNode)
assert.equal(res.toString(), '2 * x');
});
it('should evaluate a derivative containing nodes', function() {
var res = math.eval('derivative(parse("x^2"), parse("x"))');
assert.ok(res && res.isNode)
assert.equal(res.toString(), '2 * x');
});
});
it('should throw error if expressions contain unsupported operators or functions', function() {
assert.throws(function () { derivative('x << 2', 'x'); }, /Error: Operator "<<" not supported by derivative/);
assert.throws(function () { derivative('subset(x)', 'x'); }, /Error: Function "subset" not supported by derivative/);
});
it('should have controlled behavior on arguments errors', function() {
assert.throws(function() {
derivative('sqrt()', 'x');
}, /TypeError: Too few arguments in function sqrt \(expected: number or Complex or BigNumber or Unit or Array or Matrix, index: 0\)/);
assert.throws(function() {
derivative('sqrt(12, 2x)', 'x');
}, /TypeError: Too many arguments in function sqrt \(expected: 1, actual: 2\)/);
});
it('should throw error for incorrect argument types', function() {
assert.throws(function () {
derivative('42', '42');
}, /TypeError: Unexpected type of argument in function derivative \(expected: string or SymbolNode, actual: ConstantNode, index: 1\)/);
assert.throws(function () {
derivative('[1, 2; 3, 4]', 'x');
}, /TypeError: Unexpected type of argument in function constTag \(expected: OperatorNode or ConstantNode or SymbolNode or ParenthesisNode or FunctionNode or FunctionAssignmentNode, actual: ArrayNode, index: 1\)/);
assert.throws(function () {
derivative('x + [1, 2; 3, 4]', 'x');
}, /TypeError: Unexpected type of argument in function constTag \(expected: OperatorNode or ConstantNode or SymbolNode or ParenthesisNode or FunctionNode or FunctionAssignmentNode, actual: ArrayNode, index: 1\)/);
});
it('should throw error if incorrect number of arguments', function() {
assert.throws(function () {
derivative('x + 2');
}, /TypeError: Too few arguments in function derivative \(expected: string or SymbolNode, index: 1\)/);
assert.throws(function () {
derivative('x + 2', 'x', {}, true, 42);
}, /TypeError: Too many arguments in function derivative \(expected: 3, actual: 5\)/);
});
});

View File

@@ -0,0 +1,95 @@
// test simplify
var assert = require('assert');
var math = require('../../../index');
describe('simplify', function() {
function simplifyAndCompare(left, right) {
assert.equal(math.simplify(left).toString(), math.parse(right).toString());
}
function simplifyAndCompareEval (left, right, scope) {
scope = scope || {};
assert.equal(math.simplify(left).eval(scope), math.parse(right).eval(scope));
}
it('should not change the value of the function', function() {
simplifyAndCompareEval('3+2/4+2*8', '39/2');
simplifyAndCompareEval('x+1+x', '2x+1', {x:7});
simplifyAndCompareEval('x+1+2x', '3x+1', {x:7});
simplifyAndCompareEval('x^2+x-3+x^2', '2x^2+x-3', {x:7});
});
it('should simplify rational expressions with no symbols to fraction', function() {
simplifyAndCompare('3*4', '12');
simplifyAndCompare('3+2/4', '7/2');
});
it('should simplify non-rational expressions with no symbols to number', function() {
simplifyAndCompare('3+sin(4)', '2.2431975046920716');
});
it('should collect like terms', function() {
simplifyAndCompare('x+x', '2*x');
simplifyAndCompare('2x+x', '3*x');
simplifyAndCompare('2(x+1)+(x+1)', '3*(x + 1)');
simplifyAndCompare('y*x^2+2*x^2', '(y+2)*x^2');
});
it('should collect separated like terms', function() {
simplifyAndCompare('x+1+x', '2*x+1');
simplifyAndCompare('x^2+x+3+x^2', '2*x^2+x+3');
simplifyAndCompare('x+1+2x', '3*x+1');
simplifyAndCompare('x-1+x', '2*x-1');
simplifyAndCompare('x-1-2x+2', '1-x');
});
it('should collect separated like factors', function() {
simplifyAndCompare('x/2*x', 'x^2/2');
simplifyAndCompare('x*2*x', '2*x^2');
simplifyAndCompare('x*y*-x/(x^2)', '-y');
});
it('should handle non-existing functions like a pro', function() {
simplifyAndCompare('foo(x)', 'foo(x)');
});
describe('expression parser' ,function () {
it('should evaluate simplify containing string value', function() {
var res = math.eval('simplify("2x + 3x")');
assert.ok(res && res.isNode)
assert.equal(res.toString(), '5 * x');
});
it('should evaluate simplify containing nodes', function() {
var res = math.eval('simplify(parse("2x + 3x"))');
assert.ok(res && res.isNode)
assert.equal(res.toString(), '5 * x');
});
it('should compute and simplify derivatives', function() {
var res = math.eval('derivative("5x*3x", "x")');
assert.ok(res && res.isNode)
assert.equal(res.toString(), '30 * x');
});
it('should compute and simplify derivatives (2)', function() {
var scope = {}
math.eval('a = derivative("5x*3x", "x")', scope)
var res = math.eval('simplify(a)', scope);
assert.ok(res && res.isNode)
assert.equal(res.toString(), '30 * x');
});
it.skip('should compute and simplify derivatives (3)', function() {
// TODO: this requires the + operator to support Nodes,
// i.e. math.add(5, math.parse('2')) => return an OperatorNode
var res = math.eval('simplify(5+derivative(5/(3x), x))');
assert.ok(res && res.isNode)
assert.equal(res.toString(), '5 - 15 / (3 * x) ^ 2');
});
});
});

View File

@@ -0,0 +1,121 @@
// test lsolve
var assert = require('assert'),
approx = require('../../../../tools/approx'),
math = require('../../../../index');
describe('lsolve', function () {
it('should solve linear system 4 x 4, arrays', function () {
var m =
[
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 1, 1, 0],
[1, 1, 1, 1]
];
var b = [1, 2, 3, 4];
var x = math.lsolve(m, b);
approx.deepEqual(x, [1, 1, 1, 1]);
});
it('should solve linear system 4 x 4, array and column array', function () {
var m =
[
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 1, 1, 0],
[1, 1, 1, 1]
];
var b = [
[1],
[2],
[3],
[4]
];
var x = math.lsolve(m, b);
approx.deepEqual(x, [[1], [1], [1], [1]]);
});
it('should solve linear system 4 x 4, matrices', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 1, 1, 0],
[1, 1, 1, 1]
]);
var b = math.matrix([1, 2, 3, 4]);
var x = math.lsolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[1], [1], [1], [1]]));
});
it('should solve linear system 4 x 4, sparse matrices', function () {
var m = math.sparse(
[
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 1, 1, 0],
[1, 1, 1, 1]
]);
var b = math.matrix([[1], [2], [3], [4]], 'sparse');
var x = math.lsolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[1], [1], [1], [1]]));
});
it('should solve linear system 4 x 4, matrix and column matrix', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 1, 1, 0],
[1, 1, 1, 1]
]);
var b = math.matrix([
[1],
[2],
[3],
[4]
]);
var x = math.lsolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[1], [1], [1], [1]]));
});
it('should solve linear system 4 x 4, sparse matrix and column matrix', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 1, 1, 0],
[1, 1, 1, 1]
], 'sparse');
var b = math.matrix([
[1],
[2],
[3],
[4]
], 'sparse');
var x = math.lsolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[1], [1], [1], [1]]));
});
it('should throw exception when matrix is singular', function () {
assert.throws(function () { math.lsolve([[1, 1], [0, 0]], [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
assert.throws(function () { math.lsolve(math.matrix([[1, 1], [0, 0]], 'dense'), [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
assert.throws(function () { math.lsolve(math.matrix([[1, 1], [0, 0]], 'sparse'), [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
});
});

View File

@@ -0,0 +1,338 @@
// test lusolve
var assert = require('assert'),
approx = require('../../../../tools/approx'),
math = require('../../../../index');
describe('lusolve', function () {
it('should solve linear system 4 x 4, arrays', function () {
var m =
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
];
var b = [-1, -1, -1, -1];
var x = math.lusolve(m, b);
approx.deepEqual(x, [-1, -0.5, -1/3, -0.25]);
});
it('should solve linear system 4 x 4, array and column array', function () {
var m =
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
];
var b = [
[-1],
[-1],
[-1],
[-1]
];
var x = math.lusolve(m, b);
approx.deepEqual(x, [[-1], [-0.5], [-1/3], [-0.25]]);
});
it('should solve linear system 4 x 4, matrices', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
]);
var b = math.matrix([-1, -1, -1, -1]);
var x = math.lusolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-0.5], [-1/3], [-0.25]]));
});
it('should solve linear system 4 x 4, sparse matrices', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
], 'sparse');
var b = math.matrix([[-1], [-1], [-1], [-1]], 'sparse');
var x = math.lusolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-0.5], [-1/3], [-0.25]]));
});
it('should solve linear system 4 x 4, matrix and column matrix', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
]);
var b = math.matrix([
[-1],
[-1],
[-1],
[-1]
]);
var x = math.lusolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-0.5], [-1/3], [-0.25]]));
});
it('should solve linear system 4 x 4, sparse matrix and column matrix', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
], 'sparse');
var b = math.matrix([
[-1],
[-1],
[-1],
[-1]
], 'sparse');
var x = math.lusolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-0.5], [-1/3], [-0.25]]));
});
it('should solve linear system 4 x 4, LUP decomposition (array)', function () {
var m =
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
];
var lup = math.lup(m);
var x = math.lusolve(lup, [-1, -1, -1, -1]);
approx.deepEqual(x, math.matrix([[-1], [-0.5], [-1/3], [-0.25]]));
var y = math.lusolve(lup, [1, 2, 1, -1]);
approx.deepEqual(y, math.matrix([[1], [1], [1/3], [-0.25]]));
});
it('should solve linear system 4 x 4, LUP decomposition (matrix)', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
]);
var lup = math.lup(m);
var x = math.lusolve(lup, [-1, -1, -1, -1]);
approx.deepEqual(x, math.matrix([[-1], [-0.5], [-1/3], [-0.25]]));
var y = math.lusolve(lup, [1, 2, 1, -1]);
approx.deepEqual(y, math.matrix([[1], [1], [1/3], [-0.25]]));
});
it('should solve linear system 4 x 4, LUP decomposition (sparse matrix)', function () {
var m = math.matrix(
[
[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]
], 'sparse');
var lup = math.lup(m);
var x = math.lusolve(lup, [-1, -1, -1, -1]);
approx.deepEqual(x, math.matrix([[-1], [-0.5], [-1/3], [-0.25]]));
var y = math.lusolve(lup, [1, 2, 1, -1]);
approx.deepEqual(y, math.matrix([[1], [1], [1/3], [-0.25]]));
});
it('should solve linear system 3 x 3, no permutations, arrays', function () {
var m =
[
[2, 1, 1],
[1, 2, -1],
[1, 2, 1]
];
var b = [-2, 4, 2];
var x = math.lusolve(m, b);
approx.deepEqual(x, [[-5/3], [7/3], [-1]]);
});
it('should solve linear system 3 x 3, no permutations, matrix', function () {
var m = math.matrix(
[
[2, 1, 1],
[1, 2, -1],
[1, 2, 1]
]);
var b = [-2, 4, 2];
var x = math.lusolve(m, b);
approx.deepEqual(x, math.matrix([[-5/3], [7/3], [-1]]));
});
it('should solve linear system 3 x 3, no permutations, sparse matrix', function () {
var m = math.matrix(
[
[2, 1, 1],
[1, 2, -1],
[1, 2, 1]
], 'sparse');
var b = [-2, 4, 2];
var x = math.lusolve(m, b);
approx.deepEqual(x, math.matrix([[-5/3], [7/3], [-1]]));
});
it('should solve linear system 3 x 3, permutations, arrays', function () {
var m =
[
[1, 2, -1],
[2, 1, 1],
[1, 2, 1]
];
var b = [4, -2, 2];
var x = math.lusolve(m, b);
approx.deepEqual(x, [[-5/3], [7/3], [-1]]);
});
it('should solve linear system 4 x 4, permutations, matrix - Issue 437', function () {
var m = math.matrix(
[
[ -1, 1, -1, 1],
[ 0, 0, 0, 1],
[ 1, 1, 1, 1],
[ 8, 4, 2, 1]
]);
var b = [0.1, 0.2, 0.15, 0.1];
var x = math.lusolve(m, b);
approx.deepEqual(x, math.matrix([[0.025], [-0.075], [0], [0.2]]));
});
it('should solve linear system 4 x 4, permutations, sparse - Issue 437', function () {
var m = math.sparse(
[
[ -1, 1, -1, 1],
[ 0, 0, 0, 1],
[ 1, 1, 1, 1],
[ 8, 4, 2, 1]
]);
var b = [0.1, 0.2, 0.15, 0.1];
var x = math.lusolve(m, b);
approx.deepEqual(x, math.matrix([[0.025], [-0.075], [0], [0.2]]));
});
it('should solve linear system 3 x 3, permutations, sparse matrix', function () {
var m = math.matrix(
[
[1, 2, -1],
[2, 1, 1],
[1, 2, 1]
], 'sparse');
var b = [4, -2, 2];
var x = math.lusolve(m, b);
approx.deepEqual(x, math.matrix([[-5/3], [7/3], [-1]]));
});
it('should solve linear system 4 x 4, natural ordering (order=0), partial pivoting, sparse matrix', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
var b = [1.000000, 1.250000, 1.500000, 1.750000];
var x = math.lusolve(m, b, 0, 1);
approx.deepEqual(x, math.matrix([[-0.186372], [-0.131621], [0.574586], [2.454950]]));
});
it('should solve linear system 4 x 4, amd(A+A\') (order=1), partial pivoting, sparse matrix', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
var b = [1.000000, 1.250000, 1.500000, 1.750000];
var x = math.lusolve(m, b, 1, 1);
approx.deepEqual(x, math.matrix([[-0.186372], [-0.131621], [0.574586], [2.454950]]));
});
it('should solve linear system 4 x 4, amd(A\'*A) (order=2), partial pivoting, sparse matrix', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
var b = [1.000000, 1.250000, 1.500000, 1.750000];
var x = math.lusolve(m, b, 2, 1);
approx.deepEqual(x, math.matrix([[-0.186372], [-0.131621], [0.574586], [2.454950]]));
});
it('should solve linear system 4 x 4, amd(A\'*A) (order=3), partial pivoting, sparse matrix', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
var b = [1.000000, 1.250000, 1.500000, 1.750000];
var x = math.lusolve(m, b, 3, 1);
approx.deepEqual(x, math.matrix([[-0.186372], [-0.131621], [0.574586], [2.454950]]));
});
it('should throw exception when matrix is singular', function () {
assert.throws(function () { math.lusolve([[1, 1], [0, 0]], [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
assert.throws(function () { math.lusolve(math.matrix([[1, 1], [0, 0]], 'dense'), [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
assert.throws(function () { math.lusolve(math.matrix([[1, 1], [0, 0]], 'sparse'), [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
});
});

View File

@@ -0,0 +1,121 @@
// test usolve
var assert = require('assert'),
approx = require('../../../../tools/approx'),
math = require('../../../../index');
describe('usolve', function () {
it('should solve linear system 4 x 4, arrays', function () {
var m =
[
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]
];
var b = [1, 2, 3, 4];
var x = math.usolve(m, b);
approx.deepEqual(x, [-1, -1, -1, 4]);
});
it('should solve linear system 4 x 4, array and column array', function () {
var m =
[
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]
];
var b = [
[1],
[2],
[3],
[4]
];
var x = math.usolve(m, b);
approx.deepEqual(x, [[-1], [-1], [-1], [4]]);
});
it('should solve linear system 4 x 4, matrices', function () {
var m = math.matrix(
[
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]
]);
var b = math.matrix([1, 2, 3, 4]);
var x = math.usolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-1], [-1], [4]]));
});
it('should solve linear system 4 x 4, sparse matrices', function () {
var m = math.sparse(
[
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]
]);
var b = math.matrix([[1], [2], [3], [4]], 'sparse');
var x = math.usolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-1], [-1], [4]]));
});
it('should solve linear system 4 x 4, matrix and column matrix', function () {
var m = math.matrix(
[
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]
]);
var b = math.matrix([
[1],
[2],
[3],
[4]
]);
var x = math.usolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-1], [-1], [4]]));
});
it('should solve linear system 4 x 4, sparse matrix and column matrix', function () {
var m = math.matrix(
[
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]
], 'sparse');
var b = math.matrix([
[1],
[2],
[3],
[4]
], 'sparse');
var x = math.usolve(m, b);
assert(x instanceof math.type.Matrix);
approx.deepEqual(x, math.matrix([[-1], [-1], [-1], [4]]));
});
it('should throw exception when matrix is singular', function () {
assert.throws(function () { math.usolve([[1, 1], [0, 0]], [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
assert.throws(function () { math.usolve(math.matrix([[1, 1], [0, 0]], 'dense'), [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
assert.throws(function () { math.usolve(math.matrix([[1, 1], [0, 0]], 'sparse'), [1, 1]); }, /Error: Linear system cannot be solved since matrix is singular/);
});
});

View File

@@ -0,0 +1,98 @@
var assert = require('assert');
var approx = require('../../../../tools/approx');
var market = require('../../../../tools/matrixmarket');
var math = require('../../../../index');
math.import(require('../../../../lib/function/algebra/sparse/cs_amd'));
var cs_amd = math.sparse.cs_amd;
describe('cs_amd', function () {
it('should approximate minimum degree ordering, 48 x 48, natural ordering (order=0), matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 0
var q = cs_amd(0, m);
// verify
assert(q === null);
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should approximate minimum degree ordering, 48 x 48, amd(A+A\') (order=1), matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 1
var q = cs_amd(1, m);
// verify
approx.deepEqual(q, [10, 28, 29, 24, 0, 11, 30, 6, 23, 22, 40, 46, 42, 18, 4, 16, 34, 5, 9, 39, 21, 44, 45, 43, 15, 25, 26, 27, 3, 33, 41, 19, 20, 2, 38, 32, 1, 14, 8, 13, 37, 31, 12, 36, 17, 47, 35, 7]);
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should approximate minimum degree ordering, 48 x 48, amd(A\'*A) (order=2), matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 2
var q = cs_amd(2, m, false);
// verify
approx.deepEqual(q, [26, 27, 25, 44, 9, 15, 21, 33, 39, 43, 45, 3, 29, 24, 28, 47, 6, 18, 36, 0, 1, 4, 20, 2, 10, 11, 12, 8, 14, 16, 7, 13, 17, 23, 30, 34, 38, 32, 31, 41, 35, 22, 19, 37, 40, 42, 46, 5]);
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should approximate minimum degree ordering, 48 x 48, amd(A\'*A) (order=3), matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 3
var q = cs_amd(3, m, false);
// verify
approx.deepEqual(q, [26, 27, 25, 44, 9, 15, 21, 33, 39, 43, 45, 3, 29, 24, 28, 47, 6, 18, 36, 0, 1, 4, 20, 2, 10, 11, 12, 8, 14, 16, 7, 13, 17, 23, 30, 34, 38, 32, 31, 41, 35, 22, 19, 37, 40, 42, 46, 5]);
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
});

View File

@@ -0,0 +1,211 @@
var assert = require('assert');
var approx = require('../../../../tools/approx');
var market = require('../../../../tools/matrixmarket');
var math = require('../../../../index');
math.import(require('../../../../lib/function/algebra/sparse/cs_permute'));
math.import(require('../../../../lib/function/algebra/sparse/cs_lu'));
math.import(require('../../../../lib/function/algebra/sparse/cs_sqr'));
var cs_permute = math.sparse.cs_permute;
var cs_lu = math.sparse.cs_lu;
var cs_sqr = math.sparse.cs_sqr;
describe('cs_lu', function () {
it('should decompose matrix, 2 x 2, no symbolic ordering and analysis, partial pivoting', function () {
var m = math.sparse([[2, 1], [1, 4]]);
// partial pivoting
var r = cs_lu(m, null, 1);
// L
assert.deepEqual(r.L.valueOf(), [[1, 0], [0.5, 1]]);
// U
assert.deepEqual(r.U.valueOf(), [[2, 1], [0, 3.5]]);
// P
assert.deepEqual(r.pinv, [0, 1]);
// verify
approx.deepEqual(cs_permute(m, r.pinv, null, true), math.multiply(r.L, r.U));
});
it('should decompose matrix, 4 x 4, natural ordering (order=0), partial pivoting', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// symbolic ordering and analysis, order = 0
var s = cs_sqr(0, m, false);
// partial pivoting
var r = cs_lu(m, s, 1);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 4 x 4, amd(A+A\') (order=1), partial pivoting', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// symbolic ordering and analysis, order = 1
var s = cs_sqr(1, m, false);
// partial pivoting
var r = cs_lu(m, s, 1);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 4 x 4, amd(A\'*A) (order=2), partial pivoting', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// symbolic ordering and analysis, order = 2
var s = cs_sqr(2, m, false);
// partial pivoting
var r = cs_lu(m, s, 1);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 4 x 4, amd(A\'*A) (order=3), partial pivoting', function () {
var m = math.sparse(
[
[4.5, 0, 3.2, 0],
[3.1, 2.9, 0, 0.9],
[0, 1.7, 3, 0],
[3.5, 0.4, 0, 1]
]);
// symbolic ordering and analysis, order = 3
var s = cs_sqr(3, m, false);
// partial pivoting
var r = cs_lu(m, s, 1);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
});
it('should decompose matrix, 48 x 48, natural ordering (order=0), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 0
var s = cs_sqr(0, m, false);
// full pivoting
var r = cs_lu(m, s, 0.001);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should decompose matrix, 48 x 48, amd(A+A\') (order=1), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 1
var s = cs_sqr(1, m, false);
// full pivoting
var r = cs_lu(m, s, 0.001);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should decompose matrix, 48 x 48, amd(A\'*A) (order=2), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 2
var s = cs_sqr(2, m, false);
// full pivoting
var r = cs_lu(m, s, 0.001);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
it('should decompose matrix, 48 x 48, amd(A\'*A) (order=3), full pivoting, matrix market', function (done) {
// import matrix
market.import('tools/matrices/bcsstk01.tar.gz', ['bcsstk01/bcsstk01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// symbolic ordering and analysis, order = 3
var s = cs_sqr(3, m, false);
// full pivoting
var r = cs_lu(m, s, 0.001);
// verify
approx.deepEqual(cs_permute(m, r.pinv, s.q, true).valueOf(), math.multiply(r.L, r.U).valueOf());
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
});

View File

@@ -0,0 +1,104 @@
// test abs
var assert = require('assert');
var math = require('../../../index');
describe('abs', function () {
it('should return the abs value of a boolean', function () {
assert.strictEqual(math.abs(true), 1);
assert.strictEqual(math.abs(false), 0);
});
it('should return the abs value of null', function () {
assert.strictEqual(math.abs(null), 0);
});
it('should return the abs value of a number', function () {
assert.strictEqual(math.abs(-4.2), 4.2);
assert.strictEqual(math.abs(-3.5), 3.5);
assert.strictEqual(math.abs(100), 100);
assert.strictEqual(math.abs(0), 0);
});
it('should return the absolute value of a big number', function () {
assert.deepEqual(math.abs(math.bignumber(-2.3)), math.bignumber(2.3));
assert.deepEqual(math.abs(math.bignumber('5e500')), math.bignumber('5e500'));
assert.deepEqual(math.abs(math.bignumber('-5e500')), math.bignumber('5e500'));
});
it('should return the absolute value of a complex number', function () {
assert.equal(math.abs(math.complex(3, -4)), 5);
assert.equal(math.abs(math.complex(1e200, -4e200)), 4.12310562561766e+200);
});
it('should return the absolute value of a fraction', function () {
var a = math.fraction('-1/3');
assert.equal(math.abs(a).toString(), '0.(3)');
assert.equal(a.toString(), '-0.(3)');
assert.equal(math.abs(math.fraction('1/3')).toString(), '0.(3)');
});
it('should convert a string to a number', function() {
assert.strictEqual(math.abs('-2'), 2);
});
it('should return the absolute value of all elements in an Array', function () {
var a1 = math.abs([1,-2,3]);
assert.ok(Array.isArray(a1));
assert.deepEqual(a1, [1,2,3]);
a1 = math.abs([-2,-1,0,1,2]);
assert.ok(Array.isArray(a1));
assert.deepEqual(a1, [2,1,0,1,2]);
});
it('should return the absolute number of a complex number with zero', function () {
assert.equal(math.abs(math.complex(1, 0)), 1);
assert.equal(math.abs(math.complex(0, 1)), 1);
assert.equal(math.abs(math.complex(0, 0)), 0);
assert.equal(math.abs(math.complex(-1, 0)), 1);
assert.equal(math.abs(math.complex(0, -1)), 1);
});
it('should return the absolute value of all elements in a matrix', function () {
var a1 = math.abs(math.matrix([1,-2,3]));
assert.ok(a1 instanceof math.type.Matrix);
assert.deepEqual(a1.size(), [3]);
assert.deepEqual(a1.valueOf(), [1,2,3]);
a1 = math.abs(math.matrix([-2,-1,0,1,2]));
assert.ok(a1 instanceof math.type.Matrix);
assert.deepEqual(a1.size(), [5]);
assert.deepEqual(a1.valueOf(), [2,1,0,1,2])
});
it('should return the absolute value of a unit', function () {
var u = math.abs(math.unit('5 m'));
assert.equal(u.toString(), '5 m');
u = math.abs(math.unit('-5 m'));
assert.equal(u.toString(), '5 m');
u = math.abs(math.unit('-283.15 degC'));
assert.equal(u.toString(), '-263.15 degC');
u = math.abs(math.unit(math.fraction(2,3), 'm'));
assert.equal(u.toString(), '2/3 m');
u = math.abs(math.unit(math.complex(-4, 3), 'in'));
assert.equal(u.toString(), '5 in');
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {math.abs()}, /TypeError: Too few arguments/);
assert.throws(function () {math.abs(1, 2)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of unsupported types', function () {
assert.throws(function () {math.abs(new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {math.abs(undefined);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX abs', function () {
var expression = math.parse('abs(-1)');
assert.equal(expression.toTex(),'\\left|-1\\right|');
});
});

View File

@@ -0,0 +1,238 @@
// test add
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var add = math.add;
// TODO: make unit tests independent of math
describe('add', function() {
describe('Array', function () {
it('should convert strings and add them element wise', function() {
assert.deepEqual(add('2', ['3', '4']), [5, 6]);
assert.deepEqual(add(['2', '3'], '4'), [6, 7]);
});
it('should add arrays correctly', function() {
var a2 = [[1,2],[3,4]];
var a3 = [[5,6],[7,8]];
var a4 = add(a2, a3);
assert.deepEqual(a4, [[6,8],[10,12]]);
});
it('should add 3 dimension arrays correctly', function() {
var a2 = [[[1,1],[2,2]],[[3,3],[4,4]]];
var a3 = [[[5,5],[6,6]],[[7,7],[8,8]]];
var a4 = add(a2, a3);
assert.deepEqual(a4, [[[6,6],[8,8]],[[10,10],[12,12]]]);
});
it('should add a scalar and an array correctly', function() {
assert.deepEqual(add(2, [3,4]), [5,6]);
assert.deepEqual(add([3,4], 2), [5,6]);
});
it('should add array and dense matrix correctly', function() {
var a = [1,2,3];
var b = math.matrix([3,2,1]);
var c = add(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([4,4,4]));
});
it('should add array and sparse matrix correctly', function() {
var a = [[1,2,3],[4,5,6]];
var b = math.sparse([[6, 5, 4],[ 3, 2, 1]]);
var c = add(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([[7,7,7],[7,7,7]]));
});
});
describe('DenseMatrix', function () {
it('should handle strings and matrices element wise', function() {
assert.deepEqual(add('2', math.matrix(['3', '4'])), math.matrix([5, 6]));
assert.deepEqual(add(math.matrix(['2', '3']), '4'), math.matrix([6, 7]));
});
it('should add matrices correctly', function() {
var a2 = math.matrix([[1,2],[3,4]]);
var a3 = math.matrix([[5,6],[7,8]]);
var a4 = add(a2, a3);
assert.ok(a4 instanceof math.type.Matrix);
assert.deepEqual(a4.size(), [2,2]);
assert.deepEqual(a4.valueOf(), [[6,8],[10,12]]);
});
it('should add 3 dimension natrices correctly', function() {
var a2 = math.matrix([[[1,1],[2,2]],[[3,3],[4,4]]]);
var a3 = math.matrix([[[5,5],[6,6]],[[7,7],[8,8]]]);
var a4 = add(a2, a3);
assert.deepEqual(a4, math.matrix([[[6,6],[8,8]],[[10,10],[12,12]]]));
});
it('should add a scalar and a matrix correctly', function() {
assert.deepEqual(add(2, math.matrix([3,4])), math.matrix([5,6]));
assert.deepEqual(add(math.matrix([3,4]), 2), math.matrix([5,6]));
});
it('should add matrix and array correctly', function() {
var a = math.matrix([1,2,3]);
var b = [3,2,1];
var c = add(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([4,4,4]));
});
it('should add dense and sparse matrices correctly', function() {
var a = math.matrix([[1,2,3],[1,0,0]]);
var b = math.sparse([[3,2,1],[0,0,1]]);
var c = add(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([[4,4,4],[1,0,1]]));
});
});
describe('SparseMatrix', function () {
it('should add matrices correctly', function() {
var a2 = math.matrix([[1,2],[3,4]], 'sparse');
var a3 = math.matrix([[5,-2],[7,-4]], 'sparse');
var a4 = add(a2, a3);
assert.ok(a4 instanceof math.type.Matrix);
assert.deepEqual(a4, math.sparse([[6,0],[10,0]]));
});
it('should add a scalar and a matrix correctly', function() {
assert.deepEqual(add(2, math.matrix([[3,4],[5,6]], 'sparse')), math.matrix([[5,6],[7,8]], 'dense'));
assert.deepEqual(add(math.matrix([[3,4],[5,6]], 'sparse'), 2), math.matrix([[5,6],[7,8]], 'dense'));
});
it('should add matrix and array correctly', function() {
var a = math.matrix([[1,2,3],[1,0,0]], 'sparse');
var b = [[3,2,1],[0,0,1]];
var c = add(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([[4,4,4],[1,0,1]]));
});
it('should add sparse and dense matrices correctly', function() {
var a = math.sparse([[1,2,3],[1,0,0]]);
var b = math.matrix([[3,2,1],[0,0,1]]);
var c = add(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([[4,4,4],[1,0,1]]));
});
it('should add sparse and sparse matrices correctly', function() {
var a = math.sparse([[1,2,3],[1,0,0]]);
var b = math.sparse([[3,2,1],[0,0,1]]);
var c = add(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.sparse([[4,4,4],[1,0,1]]));
});
it('should add two pattern matrices correctly', function() {
var a = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 0],
ptr: [0, 2, 3, 4],
size: [3, 3]
});
var b = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 1],
ptr: [0, 3, 3, 4],
size: [3, 3]
});
var c = add(a, b);
assert.deepEqual(
c,
new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 2, 0, 1],
ptr: [0, 3, 4, 6],
size: [3, 3]
}));
});
it('should add pattern and value matrices correctly', function() {
var a = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 0],
ptr: [0, 2, 3, 4],
size: [3, 3]
});
var b = new math.type.SparseMatrix({
values: [1, 2, 3, 4],
index: [0, 1, 2, 1],
ptr: [0, 3, 3, 4],
size: [3, 3]
});
var c = add(a, b);
assert.deepEqual(
c,
new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 2, 0, 1],
ptr: [0, 3, 4, 6],
size: [3, 3]
}));
});
it('should add value and pattern matrices correctly', function() {
var a = new math.type.SparseMatrix({
values: [1, 2, 3, 4],
index: [0, 1, 2, 0],
ptr: [0, 2, 3, 4],
size: [3, 3]
});
var b = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 1],
ptr: [0, 3, 3, 4],
size: [3, 3]
});
var c = add(a, b);
assert.deepEqual(
c,
new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 2, 0, 1],
ptr: [0, 3, 4, 6],
size: [3, 3]
}));
});
});
describe ('multiple arguments', function () {
it ('should add more than two arguments', function () {
assert.deepEqual(add(2, 3, 4), 9);
assert.deepEqual(add(2, 3, [5,6]), [10,11]);
});
});
});

View File

@@ -0,0 +1,151 @@
// test add
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var BigNumber = require('decimal.js');
var add = math.add;
// TODO: make unit tests independent of math
describe('add', function() {
it('should add two numbers', function() {
assert.equal(add(2, 3), 5);
assert.equal(add(-2, 3), 1);
assert.equal(add(2, -3), -1);
assert.equal(add(-5, -3), -8);
});
it('should add booleans', function() {
assert.equal(add(true, true), 2);
assert.equal(add(true, false), 1);
assert.equal(add(false, true), 1);
assert.equal(add(false, false), 0);
});
it('should add numbers and null', function () {
assert.equal(math.add(null, null), 0);
assert.equal(math.add(null, 1), 1);
assert.equal(math.add(1, null), 1);
});
it('should add mixed numbers and booleans', function() {
assert.equal(add(2, true), 3);
assert.equal(add(2, false), 2);
assert.equal(add(true, 2), 3);
assert.equal(add(false, 2), 2);
});
it('should add BigNumbers', function() {
assert.deepEqual(add(new BigNumber(0.1), new BigNumber(0.2)), new BigNumber(0.3));
assert.deepEqual(add(new BigNumber('2e5001'), new BigNumber('3e5000')), new BigNumber('2.3e5001'));
assert.deepEqual(add(new BigNumber('9999999999999999999'), new BigNumber('1')), new BigNumber('1e19'));
});
it('should add mixed numbers and BigNumbers', function() {
assert.deepEqual(add(new BigNumber(0.1), 0.2), new BigNumber(0.3));
assert.deepEqual(add(0.1, new BigNumber(0.2)), new math.type.BigNumber(0.3));
assert.throws(function () {add(1/3, new BigNumber(1));}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {add(new BigNumber(1), 1/3);}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should add mixed booleans and BigNumbers', function() {
assert.deepEqual(add(new BigNumber(0.1), true), new BigNumber(1.1));
assert.deepEqual(add(new BigNumber(0.1), false), new BigNumber(0.1));
assert.deepEqual(add(false, new BigNumber(0.2)), new math.type.BigNumber(0.2));
assert.deepEqual(add(true, new BigNumber(0.2)), new math.type.BigNumber(1.2));
});
it('should add mixed complex numbers and BigNumbers', function() {
assert.deepEqual(add(math.complex(3, -4), new BigNumber(2)), math.complex(5, -4));
assert.deepEqual(add(new BigNumber(2), math.complex(3, -4)), math.complex(5, -4));
});
it('should add two complex numbers', function() {
assert.equal(add(math.complex(3, -4), math.complex(8, 2)), '11 - 2i');
assert.equal(add(math.complex(3, -4), 10), '13 - 4i');
assert.equal(add(10, math.complex(3, -4)), '13 - 4i');
});
it('should add two fractions', function() {
var a = math.fraction(1,3);
assert.equal(add(a, math.fraction(1,6)).toString(), '0.5');
assert.equal(a.toString(), '0.(3)');
assert.equal(add(math.fraction(1,5), math.fraction(2,5)).toString(), '0.6');
assert.equal(add(math.fraction(1), math.fraction(1,3)).toString(), '1.(3)');
});
it('should add mixed fractions and numbers', function() {
assert.deepEqual(add(1, math.fraction(1,3)), math.fraction(4,3));
assert.deepEqual(add(math.fraction(1,3), 1), math.fraction(4,3));
});
it('should throw an error when converting a number with 15+ digits to fraction', function() {
assert.throws(function () {
add(math.pi, math.fraction(1,3))
}, /Cannot implicitly convert a number with >15 significant digits to Fraction/);
});
it('should add strings to numbers', function() {
assert.strictEqual(add('2', '3'), 5);
assert.strictEqual(add(2, '3'), 5);
assert.strictEqual(add('2', 3), 5);
});
it('should add strings to BigNumbers', function() {
assert.deepEqual(add('2', math.bignumber(3)), math.bignumber(5));
assert.deepEqual(add(math.bignumber(3), '2'), math.bignumber(5));
assert.throws(function () { add('foo', math.bignumber(3)) }, /Error: Cannot convert "foo" to BigNumber/)
});
it('should add strings to Fractions', function() {
assert.deepEqual(add('2', math.fraction(3)), math.fraction(5));
assert.deepEqual(add(math.fraction(3), '2'), math.fraction(5));
assert.throws(function () { add('foo', math.fraction(3)) }, /Error: Cannot convert "foo" to Fraction/)
});
it('should add strings to Complex numbers', function() {
assert.deepEqual(add('2', math.complex(0, 3)), math.complex(2, 3));
assert.deepEqual(add(math.complex(0, 3), '2'), math.complex(2, 3));
assert.throws(function () { add('foo', math.complex(0, 3)) }, /Error: Cannot convert "foo" to Complex/)
});
it('should add two measures of the same unit', function() {
approx.deepEqual(add(math.unit(5, 'km'), math.unit(100, 'mile')), math.unit(165.93, 'km'));
approx.deepEqual(add(math.unit(math.fraction(1,3), 'm'), math.unit(math.fraction(1,3), 'm')).toString(), '2/3 m');
approx.deepEqual(add(math.unit(math.complex(-3, 2), 'g'), math.unit(math.complex(5, -6), 'g')).toString(), '(2 - 4i) g');
});
it('should throw an error for two measures of different units', function() {
assert.throws(function () {
add(math.unit(5, 'km'), math.unit(100, 'gram'));
});
});
it('should throw an error when one of the two units has undefined value', function() {
assert.throws(function () {
add(math.unit('km'), math.unit('5gram'));
}, /Parameter x contains a unit with undefined value/);
assert.throws(function () {
add(math.unit('5 km'), math.unit('gram'));
}, /Parameter y contains a unit with undefined value/);
});
it('should throw an error in case of a unit and non-unit argument', function() {
assert.throws(function () {add(math.unit('5cm'), 2);}, /TypeError: Unexpected type of argument in function add/);
assert.throws(function () {add(math.unit('5cm'), new Date());}, /TypeError: Unexpected type of argument in function add/);
assert.throws(function () {add(new Date(), math.unit('5cm'));}, /TypeError: Unexpected type of argument in function add/);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {add(1);}, /TypeError: Too few arguments/);
});
it('should LaTeX add', function () {
var expression = math.parse('add(1,2)');
assert.equal(expression.toTex(), '\\left(1+2\\right)');
});
});

View File

@@ -0,0 +1,136 @@
// test cbrt
var assert = require('assert');
var approx = require('../../../tools/approx');
var error = require('../../../lib/error/index');
var math = require('../../../index');
var cbrt = math.cbrt;
var bignumber = math.bignumber;
var complex = math.complex;
describe('cbrt', function() {
it('should return the cubic root of a boolean', function () {
assert.equal(cbrt(true), 1);
assert.equal(cbrt(false), 0);
});
it('should return the cubic root of null', function () {
assert.equal(cbrt(null), 0);
});
it('should return the cubic root of a positive number', function() {
assert.equal(cbrt(0), 0);
assert.equal(cbrt(1), 1);
assert.equal(cbrt(8), 2);
assert.equal(cbrt(27), 3);
assert.equal(cbrt(64), 4);
assert.equal(cbrt(125), 5);
approx.equal(cbrt(10), 2.1544346900318834);
});
it('should return the cubic root of a negative number', function() {
assert.strictEqual(cbrt(-8), -2);
assert.strictEqual(cbrt(-64), -4);
});
it('should return the cubic root of infinity', function() {
assert.strictEqual(cbrt(Infinity), Infinity);
assert.strictEqual(cbrt(-Infinity), -Infinity);
});
it('should return all cubic roots of a number', function() {
approx.deepEqual(cbrt(8, true), math.matrix([
complex('2'),
complex('-1 + 1.7321i'),
complex('-1 - 1.7321i')
]));
approx.deepEqual(cbrt(-8, true), math.matrix([
complex('1 + 1.7321i'),
complex('-2'),
complex('1 - 1.7321i')
]));
});
it('should return the cubic root of a positive bignumber', function() {
assert.deepEqual(cbrt(bignumber(0)), bignumber(0));
assert.deepEqual(cbrt(bignumber(1)), bignumber(1));
assert.deepEqual(cbrt(bignumber(8)), bignumber(2));
assert.deepEqual(cbrt(bignumber(27)), bignumber(3));
assert.deepEqual(cbrt(bignumber(64)), bignumber(4));
assert.deepEqual(cbrt(bignumber(125)), bignumber(5));
assert.deepEqual(cbrt(bignumber(10)), bignumber('2.154434690031883721759293566519350495259344942192108582489235506'));
});
it('should return the cubic root of a negative bignumber', function() {
assert.deepEqual(cbrt(bignumber(-8)), bignumber(-2));
assert.deepEqual(cbrt(bignumber(-64)), bignumber(-4));
});
it('should return the cubic root of a complex number', function() {
approx.deepEqual(cbrt(complex('2 + 3i')), complex('1.451856618352664928164697 + 0.493403534104004716735578i'));
approx.deepEqual(cbrt(complex('-2 + 3i')), complex('1.15322830402742 + 1.01064294709397i'));
approx.deepEqual(cbrt(complex('8i')), complex('1.73205080756888 + i'));
});
it('should return all three roots of a complex number', function() {
approx.deepEqual(cbrt(complex('2 + 3i'), true), math.matrix([
complex('1.4519 + 0.4934i'),
complex('-1.1532 + 1.0106i'),
complex('-0.2986 - 1.5040i')
]));
approx.deepEqual(cbrt(complex('8i'), true), math.matrix([
complex(' 1.7321 + i'),
complex('-1.7321 + i'),
complex('-2i')
]));
math.config({matrix: 'Array'});
approx.deepEqual(cbrt(complex('8i'), true), [
complex(' 1.7321 + i'),
complex('-1.7321 + i'),
complex('-2i')
]);
math.config({matrix: 'Matrix'});
});
it('should return the cubic root of a unit', function() {
assert.equal(cbrt(math.unit('27 m^3')).toString(), math.unit('3 m').toString());
assert.equal(cbrt(math.unit('-27 m^3')).toString(), math.unit('-3 m').toString());
assert(cbrt(math.unit(math.bignumber(27), 'm^3')).value.isBigNumber);
assert.deepEqual(cbrt(math.unit(math.bignumber(27), 'm^3')).value, math.bignumber(3));
assert(cbrt(math.unit(math.bignumber(-27), 'm^3')).value.isBigNumber);
assert.deepEqual(cbrt(math.unit(math.bignumber(-27), 'm^3')).value, math.bignumber(-3));
assert(cbrt(math.unit(math.complex(-46, 9), 's^3')).value.isComplex);
approx.deepEqual(cbrt(math.unit(math.complex(-46, 9), 's^3')).value, math.complex(2, 3));
});
it('should throw an error when used with a string', function() {
assert.throws(function () {
cbrt('a string');
});
});
it('should return the cubic root of each element of a matrix', function() {
assert.deepEqual(cbrt([8,27,64,125]), [2,3,4,5]);
assert.deepEqual(cbrt([[8,27],[64,125]]), [[2,3],[4,5]]);
assert.deepEqual(cbrt(math.matrix([[8,27],[64,125]])), math.matrix([[2,3],[4,5]]));
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {cbrt()}, /TypeError: Too few arguments/);
assert.throws(function () {cbrt(1, true, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX cbrt', function () {
var expression = math.parse('cbrt(2)');
assert.equal(expression.toTex(), '\\sqrt[3]{2}');
});
});

View File

@@ -0,0 +1,98 @@
// test ceil
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var bignumber = math.bignumber;
var complex = math.complex;
var fraction = math.fraction;
var matrix = math.matrix;
var unit = math.unit;
var range = math.range;
var ceil = math.ceil;
describe('ceil', function() {
it('should return the ceil of a boolean', function () {
assert.equal(ceil(true), 1);
assert.equal(ceil(false), 0);
});
it('should return the ceil of null', function () {
assert.equal(math.ceil(null), 0);
});
it('should return the ceil of a number', function() {
approx.equal(ceil(0), 0);
approx.equal(ceil(1), 1);
approx.equal(ceil(1.3), 2);
approx.equal(ceil(1.8), 2);
approx.equal(ceil(2), 2);
approx.equal(ceil(-1), -1);
approx.equal(ceil(-1.3), -1);
approx.equal(ceil(-1.8), -1);
approx.equal(ceil(-2), -2);
approx.equal(ceil(-2.1), -2);
approx.equal(ceil(math.pi), 4);
});
it('should return the ceil of a big number', function () {
assert.deepEqual(ceil(bignumber(0)), bignumber(0));
assert.deepEqual(ceil(bignumber(1)), bignumber(1));
assert.deepEqual(ceil(bignumber(1.3)), bignumber(2));
assert.deepEqual(ceil(bignumber(1.8)), bignumber(2));
assert.deepEqual(ceil(bignumber(2)), bignumber(2));
assert.deepEqual(ceil(bignumber(-1)), bignumber(-1));
assert.deepEqual(ceil(bignumber(-1.3)), bignumber(-1));
assert.deepEqual(ceil(bignumber(-1.8)), bignumber(-1));
assert.deepEqual(ceil(bignumber(-2)), bignumber(-2));
assert.deepEqual(ceil(bignumber(-2.1)), bignumber(-2));
});
it('should return the ceil of real and imag part of a complex', function() {
approx.deepEqual(ceil(complex(0, 0)), complex(0, 0));
approx.deepEqual(ceil(complex(1.3, 1.8)), complex(2, 2));
approx.deepEqual(ceil(math.i), complex(0, 1));
approx.deepEqual(ceil(complex(-1.3, -1.8)), complex(-1, -1));
});
it('should return the ceil of a number', function() {
var a = fraction('2/3');
assert(ceil(a) instanceof math.type.Fraction);
assert.equal(a.toString(), '0.(6)');
assert.equal(ceil(fraction(0)).toString(), '0');
assert.equal(ceil(fraction(1)), '1');
assert.equal(ceil(fraction(1.3)).toString(), '2');
assert.equal(ceil(fraction(1.8)).toString(), '2');
assert.equal(ceil(fraction(2)).toString(), '2');
assert.equal(ceil(fraction(-1)).toString(), '-1');
assert.equal(ceil(fraction(-1.3)).toString(), '-1');
assert.equal(ceil(fraction(-1.8)).toString(), '-1');
assert.equal(ceil(fraction(-2)).toString(), '-2');
assert.equal(ceil(fraction(-2.1)).toString(), '-2');
});
it('should throw an error for units', function() {
assert.throws(function () {ceil(unit('5cm'))}, TypeError, 'Function ceil(unit) not supported');
});
it('should convert a string to a number', function() {
assert.strictEqual(ceil('1.8'), 2);
});
it('should ceil each element in a matrix, array or range', function() {
approx.deepEqual(ceil([1.2, 3.4, 5.6, 7.8, 10.0]), [2, 4, 6, 8, 10]);
approx.deepEqual(ceil(matrix([1.2, 3.4, 5.6, 7.8, 10.0])), matrix([2, 4, 6, 8, 10]));
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {ceil()}, /TypeError: Too few arguments/);
assert.throws(function () {ceil(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX ceil', function () {
var expression = math.parse('ceil(0.5)');
assert.equal(expression.toTex(), '\\left\\lceil0.5\\right\\rceil');
});
});

View File

@@ -0,0 +1,74 @@
// test cube
var assert = require('assert');
var math = require('../../../index');
var unit = math.unit;
var bignumber = math.bignumber;
var fraction = math.fraction;
var matrix = math.matrix;
var range = math.range;
var cube = math.cube;
describe('cube', function() {
it('should return the cube of a boolean', function () {
assert.equal(cube(true), 1);
assert.equal(cube(false), 0);
});
it('should return the cube of null', function () {
assert.equal(math.ceil(null), 0);
});
it('should return the cube of a number', function() {
assert.equal(cube(4), 64);
assert.equal(cube(-2), -8);
assert.equal(cube(0), 0);
});
it('should return the cube of a big number', function() {
assert.deepEqual(cube(bignumber(4)), bignumber(64));
assert.deepEqual(cube(bignumber(-2)), bignumber(-8));
assert.deepEqual(cube(bignumber(0)), bignumber(0));
});
it('should return the cube of a fraction', function() {
var a = fraction(0.5);
assert(cube(a) instanceof math.type.Fraction);
assert.equal(cube(a).toString(), '0.125');
assert.equal(a.toString(), '0.5');
});
it('should return the cube of a complex number', function() {
assert.deepEqual(cube(math.complex('2i')), math.complex('-8i'));
assert.deepEqual(cube(math.complex('2+3i')), math.complex('-46+9i'));
assert.deepEqual(cube(math.complex('2')), math.complex('8'));
});
it('should return the cube of a unit', function() {
assert.equal(cube(math.unit('4 cm')).toString(), '64 cm^3');
assert.equal(cube(math.unit('-2 cm')).toString(), '-8 cm^3');
assert.equal(cube(math.unit('0 cm')).toString(), '0 cm^3');
});
it('should throw an error with strings', function() {
assert.throws(function () {cube('text')});
});
it('should throw an error if there\'s wrong number of args', function() {
assert.throws(function () {cube()}, /TypeError: Too few arguments/);
assert.throws(function () {cube(1, 2)}, /TypeError: Too many arguments/);
});
it('should cube each element in a matrix, array or range', function() {
// array, matrix, range
// arrays are evaluated element wise
assert.deepEqual(cube([2,3,4,5]), [8,27,64,125]);
assert.deepEqual(cube(matrix([2,3,4,5])), matrix([8,27,64,125]));
assert.deepEqual(cube(matrix([[1,2],[3,4]])), matrix([[1,8],[27,64]]));
});
it('should LaTeX cube', function () {
var expression = math.parse('cube(2)');
assert.equal(expression.toTex(), '\\left(2\\right)^3');
});
});

View File

@@ -0,0 +1,216 @@
// test divide
var assert = require('assert');
var math = require('../../../index');
var error = require('../../../lib/error/index');
var approx = require('../../../tools/approx');
var divide = math.divide;
var bignumber = math.bignumber;
var complex = math.complex;
describe('divide', function() {
it('should divide two numbers', function() {
assert.equal(divide(4, 2), 2);
assert.equal(divide(-4, 2), -2);
assert.equal(divide(4, -2), -2);
assert.equal(divide(-4, -2), 2);
assert.equal(divide(4, 0), Infinity);
assert.equal(divide(-4, 0), -Infinity);
assert.equal(divide(0, -5), 0);
assert.ok(isNaN(divide(0, 0)));
});
it('should divide booleans', function() {
assert.equal(divide(true, true), 1);
assert.equal(divide(true, false), Infinity);
assert.equal(divide(false, true), 0);
assert.ok(isNaN(divide(false, false)));
});
it('should divide numbers and null', function () {
assert.equal(divide(1, null), Infinity);
assert.equal(divide(null, 1), 0);
assert(isNaN(divide(null, null)));
});
it('should divide mixed numbers and booleans', function() {
assert.equal(divide(2, true), 2);
assert.equal(divide(2, false), Infinity);
approx.equal(divide(true, 2), 0.5);
assert.equal(divide(false, 2), 0);
});
it('should divide bignumbers', function() {
assert.deepEqual(divide(bignumber(0.3), bignumber(0.2)), bignumber(1.5));
assert.deepEqual(divide(bignumber('2.6e5000'), bignumber('2')), bignumber('1.3e5000'));
});
it('should divide mixed numbers and bignumbers', function() {
assert.deepEqual(divide(bignumber(0.3), 0.2), bignumber(1.5));
assert.deepEqual(divide(0.3, bignumber(0.2)), bignumber(1.5));
assert.deepEqual(divide(bignumber('2.6e5000'), 2), bignumber('1.3e5000'));
assert.throws(function () {divide(1/3, bignumber(2))}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {divide(bignumber(1), 1/3)}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should divide mixed booleans and bignumbers', function() {
assert.deepEqual(divide(bignumber(0.3), true), bignumber(0.3));
assert.deepEqual(divide(bignumber(0.3), false).toString(), 'Infinity');
assert.deepEqual(divide(false, bignumber('2')), bignumber(0));
assert.deepEqual(divide(true, bignumber('2')), bignumber(0.5));
});
it('should divide two complex numbers', function() {
approx.deepEqual(divide(complex('2+3i'), 2), complex('1+1.5i'));
approx.deepEqual(divide(complex('2+3i'), complex('4i')), complex('0.75 - 0.5i'));
approx.deepEqual(divide(complex('2i'), complex('4i')), complex('0.5'));
approx.deepEqual(divide(4, complex('1+2i')), complex('0.8 - 1.6i'));
approx.deepEqual(divide(math.i, 0), complex(0, Infinity));
approx.deepEqual(divide(complex(0,1), 0), complex(0, Infinity));
approx.deepEqual(divide(complex(1,0), 0), complex(Infinity, 0));
approx.deepEqual(divide(complex(0,1), complex(0,0)), complex(0, Infinity));
approx.deepEqual(divide(complex(1,1), complex(0,0)), complex(Infinity, Infinity));
approx.deepEqual(divide(complex(1,-1), complex(0,0)), complex(Infinity, -Infinity));
approx.deepEqual(divide(complex(-1,1), complex(0,0)), complex(-Infinity, Infinity));
approx.deepEqual(divide(complex(1,1), complex(0,1)), complex(1, -1));
approx.deepEqual(divide(complex(1,1), complex(1,0)), complex(1, 1));
approx.deepEqual(divide(complex(2, 3), complex(4, 5)), complex('0.5609756097560976 + 0.0487804878048781i'));
approx.deepEqual(divide(complex(2, 3), complex(4, -5)), complex('-0.170731707317073 + 0.536585365853659i'));
approx.deepEqual(divide(complex(2, 3), complex(-4, 5)), complex('0.170731707317073 - 0.536585365853659i'));
approx.deepEqual(divide(complex(2, 3), complex(-4, -5)), complex('-0.5609756097560976 - 0.0487804878048781i'));
approx.deepEqual(divide(complex(2, -3), complex(4, 5)), complex('-0.170731707317073 - 0.536585365853659i'));
approx.deepEqual(divide(complex(2, -3), complex(4, -5)), complex('0.5609756097560976 - 0.0487804878048781i'));
approx.deepEqual(divide(complex(2, -3), complex(-4, 5)), complex('-0.5609756097560976 + 0.0487804878048781i'));
approx.deepEqual(divide(complex(2, -3), complex(-4, -5)), complex('0.170731707317073 + 0.536585365853659i'));
approx.deepEqual(divide(complex(-2, 3), complex(4, 5)), complex('0.170731707317073 + 0.536585365853659i'));
approx.deepEqual(divide(complex(-2, 3), complex(4, -5)), complex('-0.5609756097560976 + 0.0487804878048781i'));
approx.deepEqual(divide(complex(-2, 3), complex(-4, 5)), complex('0.5609756097560976 - 0.0487804878048781i'));
approx.deepEqual(divide(complex(-2, 3), complex(-4, -5)), complex('-0.170731707317073 - 0.536585365853659i'));
approx.deepEqual(divide(complex(-2, -3), complex(4, 5)), complex('-0.5609756097560976 - 0.0487804878048781i'));
approx.deepEqual(divide(complex(-2, -3), complex(4, -5)), complex('0.170731707317073 - 0.536585365853659i'));
approx.deepEqual(divide(complex(-2, -3), complex(-4, 5)), complex('-0.170731707317073 + 0.536585365853659i'));
approx.deepEqual(divide(complex(-2, -3), complex(-4, -5)), complex('0.5609756097560976 + 0.0487804878048781i'));
});
it('should divide mixed complex numbers and numbers', function() {
assert.deepEqual(divide(math.complex(6, -4), 2), math.complex(3, -2));
assert.deepEqual(divide(1, math.complex(2, 4)), math.complex(0.1, -0.2));
});
it('should divide mixed complex numbers and bignumbers', function() {
assert.deepEqual(divide(math.complex(6, -4), bignumber(2)), math.complex(3, -2));
assert.deepEqual(divide(bignumber(1), math.complex(2, 4)), math.complex(0.1, -0.2));
});
it('should divide two fractions', function() {
var a = math.fraction(1,4);
assert.equal(divide(a, math.fraction(1,2)).toString(), '0.5');
assert.equal(a.toString(), '0.25');
});
it('should divide mixed fractions and numbers', function() {
assert.deepEqual(divide(1, math.fraction(3)), math.fraction(1,3));
assert.deepEqual(divide(math.fraction(1), 3), math.fraction(1,3));
});
it('should divide units by a number', function() {
assert.equal(divide(math.unit('5 m'), 10).toString(), '0.5 m');
});
it('should divide valueless units by a number', function() {
assert.equal(divide(math.unit('m'), 2).toString(), '0.5 m');
});
it('should divide a number by a unit', function() {
assert.equal(divide(20, math.unit('4 N s')).toString(), '5 N^-1 s^-1');
assert.equal(divide(4, math.unit('W')).toString(), '4 W^-1');
assert.equal(divide(2.5, math.unit('1.25 mm')).toString(), '2 mm^-1');
assert.equal(divide(10, math.unit('4 mg/s')).toString(), '2.5 s / mg');
assert.equal(divide(10, math.unit(math.fraction(4), 'mg/s')).toString(), '5/2 s / mg');
approx.equal(math.format(divide(10, math.unit(math.complex(1,2), 'm/s')), 14), '(2 - 4i) s / m');
});
it('should divide two units', function() {
assert.equal(divide(math.unit('75 mi/h'), math.unit('40 mi/gal')).to('gal/minute').toString(), '0.03125 gal / minute');
var a = math.unit(math.fraction(75), 'mi/h');
var b = math.unit(math.fraction(40), 'mi/gal');
assert.equal(divide(a, b).to('gal/minute').toString(), '1/32 gal / minute');
var c = math.unit(math.complex(21, 1), 'kg');
var d = math.unit(math.complex(2, -3), 's');
assert.equal(divide(c, d).toString(), "(3 + 5.000000000000001i) kg / s");
});
it('should divide one valued unit by a valueless unit and vice-versa', function() {
assert.equal(divide(math.unit('4 gal'), math.unit('L')).toString(), '15.141648');
assert.equal(divide(math.unit('gal'), math.unit('4 L')).toString(), '0.946353');
assert.equal(divide(math.unit('inch'), math.unit(math.fraction(1), 'cm')).toFraction(), '127/50');
});
it('should divide (but not simplify) two valueless units', function() {
assert.equal(divide(math.unit('gal'), math.unit('L')).toString(), 'gal / L');
});
it('should divide units by a big number', function() {
assert.equal(divide(math.unit('5 m'), bignumber(10)).toString(), '0.5 m');
});
it('should divide each elements in a matrix by a number', function() {
assert.deepEqual(divide([2,4,6], 2), [1,2,3]);
a = math.matrix([[1,2],[3,4]]);
assert.deepEqual(divide(a, 2), math.matrix([[0.5,1],[1.5,2]]));
assert.deepEqual(divide(a.valueOf(), 2), [[0.5,1],[1.5,2]]);
assert.deepEqual(divide([], 2), []);
assert.deepEqual(divide([], 2), []);
});
it('should divide 1 over a matrix (matrix inverse)', function() {
approx.deepEqual(divide(1, [
[ 1, 4, 7],
[ 3, 0, 5],
[-1, 9, 11]
]), [
[ 5.625, -2.375, -2.5],
[ 4.75, -2.25, -2],
[-3.375, 1.625, 1.5]
]);
});
it('should perform matrix division', function() {
a = math.matrix([[1,2],[3,4]]);
b = math.matrix([[5,6],[7,8]]);
assert.deepEqual(divide(a, b), math.matrix([[3,-2], [2,-1]]));
});
it('should divide a matrix by a matrix containing a scalar', function() {
assert.throws(function () {divide(a, [[1]])});
});
/*
// These are supported now --ericman314
it('should throw an error if dividing a number by a unit', function() {
assert.throws(function () {divide(10, math.unit('5 m')).toString()});
});
it('should throw an error if dividing a unit by a non-number', function() {
assert.throws(function () {divide(math.unit('5 m'), math.unit('5cm')).toString()});
});
*/
it('should throw an error if there\'s wrong number of arguments', function() {
assert.throws(function () {divide(2,3,4); });
assert.throws(function () {divide(2); });
});
it('should LaTeX divide', function () {
var expression = math.parse('divide(1,2)');
assert.equal(expression.toTex(), '\\frac{1}{2}');
});
});

View File

@@ -0,0 +1,178 @@
// test dotDivide (element-wise divide)
var assert = require('assert'),
math = require('../../../index'),
approx = require('../../../tools/approx'),
dotDivide = math.dotDivide,
complex = math.complex;
describe('dotDivide', function() {
it('should divide two numbers', function() {
assert.equal(dotDivide(4, 2), 2);
assert.equal(dotDivide(-4, 2), -2);
assert.equal(dotDivide(4, -2), -2);
assert.equal(dotDivide(-4, -2), 2);
assert.equal(dotDivide(4, 0), Infinity);
assert.equal(dotDivide(0, -5), 0);
assert.ok(isNaN(dotDivide(0, 0)));
});
it('should divide booleans', function() {
assert.equal(dotDivide(true, true), 1);
assert.equal(dotDivide(true, false), Infinity);
assert.equal(dotDivide(false, true), 0);
assert.ok(isNaN(dotDivide(false, false)));
});
it('should add mixed numbers and booleans', function() {
assert.equal(dotDivide(2, true), 2);
assert.equal(dotDivide(2, false), Infinity);
approx.equal(dotDivide(true, 2), 0.5);
assert.equal(dotDivide(false, 2), 0);
});
it('should divide numbers and null', function () {
assert.equal(dotDivide(1, null), Infinity);
assert.equal(dotDivide(null, 1), 0);
});
it('should throw an error if there\'s wrong number of arguments', function() {
assert.throws(function () {dotDivide(2,3,4); });
assert.throws(function () {dotDivide(2); });
});
it('should divide two complex numbers', function() {
approx.deepEqual(dotDivide(complex('2+3i'), 2), complex('1+1.5i'));
approx.deepEqual(dotDivide(complex('2+3i'), complex('4i')), complex('0.75 - 0.5i'));
approx.deepEqual(dotDivide(complex('2i'), complex('4i')), 0.5);
approx.deepEqual(dotDivide(4, complex('1+2i')), complex('0.8 - 1.6i'));
});
it('should divide a unit by a number', function() {
assert.equal(dotDivide(math.unit('5 m'), 10).toString(), '0.5 m');
});
it('should divide a number by a unit', function() {
assert.equal(dotDivide(10, math.unit('5 m')).toString(), '2 m^-1');
});
/*
// This is supported not --ericman314
it('should throw an error if dividing a number by a unit', function() {
assert.throws(function () {dotDivide(10, math.unit('5 m')).toString();});
});
*/
describe('Array', function () {
it('should divide all the elements of a array by one number', function() {
assert.deepEqual(dotDivide([2,4,6], 2), [1,2,3]);
var a = [[1,2],[3,4]];
assert.deepEqual(dotDivide(a, 2), [[0.5,1],[1.5,2]]);
assert.deepEqual(dotDivide([], 2), []);
});
it('should divide 1 over a array element-wise', function() {
approx.deepEqual(dotDivide(1, [[1, 4, 7], [ 3, 0, 5], [-1, 9, 11]]), [[1, 0.25, 1/7],[1/3, Infinity, 0.2], [-1, 1/9, 1/11]]);
});
it('should perform (array ./ array) element-wise matrix division', function() {
var a = [[1,2],[3,4]];
var b = [[5,6],[7,8]];
assert.deepEqual(dotDivide(a, b), [[1/5, 2/6], [3/7,4/8]]);
});
it('should perform (array ./ dense matrix) element-wise matrix division', function() {
var a = [[1,2],[3,4]];
var b = math.matrix([[5,6],[7,8]]);
assert.deepEqual(dotDivide(a, b), math.matrix([[1/5, 2/6], [3/7,4/8]]));
});
it('should perform (array ./ sparse matrix) element-wise matrix division', function() {
var a = [[1,2],[3,4]];
var b = math.sparse([[5,0],[7,8]]);
assert.deepEqual(dotDivide(a, b), math.matrix([[1/5, Infinity], [3/7,4/8]]));
});
it('should throw an error when dividing element-wise with differing size', function() {
assert.throws(function () {dotDivide([[1,2],[3,4]], [[1]]);});
});
});
describe('DenseMatrix', function () {
it('should divide all the elements of a dense matrix by one number', function() {
assert.deepEqual(dotDivide(math.matrix([2,4,6]), 2), math.matrix([1,2,3]));
var a = math.matrix([[1,2],[3,4]]);
assert.deepEqual(dotDivide(a, 2), math.matrix([[0.5,1],[1.5,2]]));
assert.deepEqual(dotDivide(math.matrix([]), 2), math.matrix([]));
});
it('should divide 1 over a dense matrix element-wise', function() {
approx.deepEqual(dotDivide(1, math.matrix([[1, 4, 7], [ 3, 0, 5], [-1, 9, 11]])), math.matrix([[1, 0.25, 1/7],[1/3, Infinity, 0.2], [-1, 1/9, 1/11]]));
});
it('should perform (dense matrix ./ array) element-wise matrix division', function() {
var a = math.matrix([[1,2],[3,4]]);
var b = [[5,6],[7,8]];
assert.deepEqual(dotDivide(a, b), math.matrix([[1/5, 2/6], [3/7,4/8]]));
});
it('should perform (dense matrix ./ dense matrix) element-wise matrix division', function() {
var a = math.matrix([[1,2],[3,4]]);
var b = math.matrix([[5,6],[7,8]]);
assert.deepEqual(dotDivide(a, b), math.matrix([[1/5, 2/6], [3/7,4/8]]));
});
it('should perform (dense matrix ./ sparse matrix) element-wise matrix division', function() {
var a = math.matrix([[1,2],[3,4]]);
var b = math.sparse([[5,0],[7,8]]);
assert.deepEqual(dotDivide(a, b), math.matrix([[1/5, Infinity], [3/7,4/8]]));
});
it('should throw an error when dividing element-wise with differing size', function() {
assert.throws(function () {dotDivide(math.matrix([[1,2],[3,4]]), math.matrix([[1]]));});
});
});
describe('SparseMatrix', function () {
it('should divide all the elements of a sparse matrix by one number', function() {
assert.deepEqual(dotDivide(math.sparse([[2,0,6],[8,10,12]]), 2), math.sparse([[1,0,3],[4,5,6]]));
var a = math.sparse([[1,2],[3,4]]);
assert.deepEqual(dotDivide(a, 2), math.sparse([[0.5,1],[1.5,2]]));
assert.deepEqual(dotDivide(math.sparse(), 2), math.sparse());
});
it('should divide 1 over a sparse matrix element-wise', function() {
approx.deepEqual(dotDivide(1, math.sparse([[1, 4, 7], [ 3, 0, 5], [-1, 9, 11]])), math.matrix([[1, 0.25, 1/7],[1/3, Infinity, 0.2], [-1, 1/9, 1/11]]));
});
it('should perform (sparse matrix ./ array) element-wise matrix division', function() {
var a = math.sparse([[1,2],[3,4]]);
var b = [[5,6],[7,8]];
assert.deepEqual(dotDivide(a, b), math.sparse([[1/5, 2/6], [3/7,4/8]]));
});
it('should perform (sparse matrix ./ dense matrix) element-wise matrix division', function() {
var a = math.sparse([[1,2],[3,4]]);
var b = math.matrix([[5,6],[7,8]]);
assert.deepEqual(dotDivide(a, b), math.sparse([[1/5, 2/6], [3/7,4/8]]));
});
it('should perform (sparse matrix ./ sparse matrix) element-wise matrix division', function() {
var a = math.sparse([[1,2],[0,4]]);
var b = math.sparse([[5,0],[7,8]]);
assert.deepEqual(dotDivide(a, b), math.matrix([[1/5, Infinity], [0,4/8]]));
});
it('should throw an error when dividing element-wise with differing size', function() {
assert.throws(function () {dotDivide(math.sparse([[1,2],[3,4]]), math.sparse([[1]]));});
});
});
it('should LaTeX dotDivide', function () {
var expression = math.parse('dotDivide([1,2],[3,4])');
assert.equal(expression.toTex(), '\\left(\\begin{bmatrix}1\\\\2\\\\\\end{bmatrix}.:\\begin{bmatrix}3\\\\4\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,189 @@
// test dotMultiply (element-wise multiply)
var assert = require('assert'),
math = require('../../../index'),
approx = require('../../../tools/approx'),
error = require('../../../lib/error/index'),
dotMultiply = math.dotMultiply,
divide = math.divide,
matrix = math.matrix,
sparse = math.sparse,
complex = math.complex,
range = math.range,
i = math.i,
unit = math.unit;
describe('dotMultiply', function() {
it('should multiply 2 numbers', function() {
// number
approx.equal(dotMultiply(2, 3), 6);
approx.equal(dotMultiply(-2, 3), -6);
approx.equal(dotMultiply(-2, -3), 6);
approx.equal(dotMultiply(5, 0), 0);
approx.equal(dotMultiply(0, 5), 0);
});
it('should multiply booleans', function() {
assert.equal(dotMultiply(true, true), 1);
assert.equal(dotMultiply(true, false), 0);
assert.equal(dotMultiply(false, true), 0);
assert.equal(dotMultiply(false, false), 0);
});
it('should multiply mixed numbers and booleans', function() {
assert.equal(dotMultiply(2, true), 2);
assert.equal(dotMultiply(2, false), 0);
assert.equal(dotMultiply(true, 2), 2);
assert.equal(dotMultiply(false, 2), 0);
});
it('should multiply numbers and null', function () {
assert.equal(dotMultiply(1, null), 0);
assert.equal(dotMultiply(null, 1), 0);
});
it('should multiply 2 complex numbers', function() {
// complex
approx.deepEqual(dotMultiply(complex(2, 3), 2), complex(4, 6));
approx.deepEqual(dotMultiply(complex(2, -3), 2), complex(4, -6));
approx.deepEqual(dotMultiply(complex(0, 1), complex(2, 3)), complex(-3, 2));
approx.deepEqual(dotMultiply(complex(2, 3), complex(2, 3)), complex(-5, 12));
approx.deepEqual(dotMultiply(2, complex(2, 3)), complex(4, 6));
approx.deepEqual(divide(complex(-5, 12), complex(2, 3)), complex(2, 3));
});
it('should multiply a unit by a number', function() {
// unit
assert.equal(dotMultiply(2, unit('5 mm')).toString(), '10 mm');
assert.equal(dotMultiply(2, unit('5 mm')).toString(), '10 mm');
assert.equal(dotMultiply(unit('5 mm'), 2).toString(), '10 mm');
assert.equal(dotMultiply(unit('5 mm'), 0).toString(), '0 mm');
});
it('should throw an error with strings', function() {
// string
assert.throws(function () {dotMultiply("hello", "world")});
assert.throws(function () {dotMultiply("hello", 2)});
});
describe('Array', function () {
var a = [[1,0],[3,4]];
var b = [[5,6],[0,8]];
var c = [[5],[6]];
var d = [[5,6]];
it('should multiply a all elements in a array by a number', function() {
// matrix, array, range
approx.deepEqual(dotMultiply(a, 3), [[3,0],[9,12]]);
approx.deepEqual(dotMultiply(3, a), [[3,0],[9,12]]);
approx.deepEqual(dotMultiply([1,2,3,4], 2), [2, 4, 6, 8]);
approx.deepEqual(dotMultiply(2, [1,2,3,4]), [2, 4, 6, 8]);
});
it('should perform element-wise (array .* array) multiplication', function() {
approx.deepEqual(dotMultiply(a, b), [[5,0],[0,32]]);
approx.deepEqual(dotMultiply([[1,2],[3,4]], [[5,6],[7,8]]), [[5,12],[21,32]]);
});
it('should perform element-wise (array .* dense matrix) multiplication', function() {
approx.deepEqual(dotMultiply([[1,2],[3,4]], matrix([[5,6],[7,8]])), matrix([[5,12],[21,32]]));
});
it('should perform element-wise (array .* sparse matrix) multiplication', function() {
approx.deepEqual(dotMultiply([[1,2],[3,4]], sparse([[5,6],[7,8]])), sparse([[5,12],[21,32]]));
});
it('should throw an error if arrays are of different sizes', function() {
assert.throws(function () {dotMultiply(a, c)});
assert.throws(function () {dotMultiply(d, a)});
assert.throws(function () {dotMultiply(d, b)});
assert.throws(function () {dotMultiply(d, c)});
assert.throws(function () {dotMultiply(c, b)});
});
});
describe('DenseMatrix', function () {
var a = matrix([[1,0],[3,4]]);
var b = matrix([[5,6],[0,8]]);
var c = matrix([[5],[6]]);
var d = matrix([[5,6]]);
it('should multiply a all elements in a dense matrix by a number', function() {
// matrix, array, range
approx.deepEqual(dotMultiply(a, 3), matrix([[3,0],[9,12]]));
approx.deepEqual(dotMultiply(3, a), matrix([[3,0],[9,12]]));
approx.deepEqual(dotMultiply(matrix([1,2,3,4]), 2), matrix([2, 4, 6, 8]));
approx.deepEqual(dotMultiply(2, matrix([1,2,3,4])), matrix([2, 4, 6, 8]));
});
it('should perform element-wise (dense matrix .* array) multiplication', function() {
approx.deepEqual(dotMultiply(a, [[5,6],[0,8]]), matrix([[5,0],[0,32]]));
approx.deepEqual(dotMultiply(matrix([[1,2],[3,4]]), [[5,6],[7,8]]), matrix([[5,12],[21,32]]));
});
it('should perform element-wise (dense matrix .* dense matrix) multiplication', function() {
approx.deepEqual(dotMultiply(matrix([[1,2],[3,4]]), matrix([[5,6],[7,8]])), matrix([[5,12],[21,32]]));
});
it('should perform element-wise (dense matrix .* sparse matrix) multiplication', function() {
approx.deepEqual(dotMultiply(matrix([[1,2],[3,4]]), sparse([[5,6],[7,8]])), sparse([[5,12],[21,32]]));
});
it('should throw an error if arrays are of different sizes', function() {
assert.throws(function () {dotMultiply(a, c)});
assert.throws(function () {dotMultiply(d, a)});
assert.throws(function () {dotMultiply(d, b)});
assert.throws(function () {dotMultiply(d, c)});
assert.throws(function () {dotMultiply(c, b)});
});
});
describe('SparseMatrix', function () {
var a = sparse([[1,0],[3,4]]);
var b = sparse([[5,6],[0,8]]);
var c = sparse([[5],[6]]);
var d = sparse([[5,6]]);
it('should multiply a all elements in a sparse matrix by a number', function() {
// matrix, array, range
approx.deepEqual(dotMultiply(a, 3), sparse([[3,0],[9,12]]));
approx.deepEqual(dotMultiply(3, a), sparse([[3,0],[9,12]]));
approx.deepEqual(dotMultiply(sparse([1,2,3,4]), 2), sparse([2, 4, 6, 8]));
approx.deepEqual(dotMultiply(2, sparse([1,2,3,4])), sparse([2, 4, 6, 8]));
});
it('should perform element-wise (sparse matrix .* array) multiplication', function() {
approx.deepEqual(dotMultiply(a, [[5,6],[0,8]]), sparse([[5,0],[0,32]]));
approx.deepEqual(dotMultiply(sparse([[1,2],[3,4]]), [[5,6],[7,8]]), sparse([[5,12],[21,32]]));
});
it('should perform element-wise (sparse matrix .* dense matrix) multiplication', function() {
approx.deepEqual(dotMultiply(sparse([[1,2],[3,4]]), matrix([[5,6],[7,8]])), sparse([[5,12],[21,32]]));
});
it('should perform element-wise (sparse matrix .* sparse matrix) multiplication', function() {
approx.deepEqual(dotMultiply(sparse([[0,2],[3,4]]), sparse([[5,6],[0,8]])), sparse([[0,12],[0,32]]));
});
it('should throw an error if arrays are of different sizes', function() {
assert.throws(function () {dotMultiply(a, c)});
assert.throws(function () {dotMultiply(d, a)});
assert.throws(function () {dotMultiply(d, b)});
assert.throws(function () {dotMultiply(d, c)});
assert.throws(function () {dotMultiply(c, b)});
});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {dotMultiply(1)}, /TypeError: Too few arguments/);
assert.throws(function () {dotMultiply(1, 2, 3)}, /TypeError: Too many arguments/);
});
it('should LaTeX dotMultiply', function () {
var expression = math.parse('dotMultiply([1,2],[3,4])');
assert.equal(expression.toTex(), '\\left(\\begin{bmatrix}1\\\\2\\\\\\end{bmatrix}.\\cdot\\begin{bmatrix}3\\\\4\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,180 @@
// test exp
var assert = require('assert'),
approx = require('../../../tools/approx'),
math = require('../../../index'),
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
dotPow = math.dotPow;
describe('dotPow', function() {
it('should elevate a number to the given power', function() {
approx.deepEqual(dotPow(2,3), 8);
approx.deepEqual(dotPow(2,4), 16);
approx.deepEqual(dotPow(-2,2), 4);
approx.deepEqual(dotPow(3,3), 27);
approx.deepEqual(dotPow(3,-2), 0.111111111111111);
approx.deepEqual(dotPow(-3,-2), 0.111111111111111);
approx.deepEqual(dotPow(3,-3), 0.0370370370370370);
approx.deepEqual(dotPow(-3,-3), -0.0370370370370370);
approx.deepEqual(dotPow(2,1.5), 2.82842712474619);
approx.deepEqual(dotPow(-2,1.5), complex(0, -2.82842712474619));
});
it('should elevate booleans to the given power', function() {
assert.equal(dotPow(true, true), 1);
assert.equal(dotPow(true, false), 1);
assert.equal(dotPow(false, true), 0);
assert.equal(dotPow(false, false), 1);
});
it('should exponentiate mixed numbers and booleans', function() {
assert.equal(dotPow(2, true), 2);
assert.equal(dotPow(2, false), 1);
assert.equal(dotPow(true, 2), 1);
assert.equal(dotPow(false, 2), 0);
});
it('should exponentiate numbers and null', function () {
assert.equal(dotPow(1, null), 1);
assert.equal(dotPow(null, 1), 0);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {dotPow(1);}, /TypeError: Too few arguments/);
assert.throws(function () {dotPow(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should elevate a complex number to the given power', function() {
approx.deepEqual(dotPow(complex(-1,-1),complex(-1,-1)), complex('-0.0284750589322119 + 0.0606697332231795i'));
approx.deepEqual(dotPow(complex(-1,-1),complex(-1,1)), complex('-6.7536199239765713 + 3.1697803027015614i'));
approx.deepEqual(dotPow(complex(-1,-1),complex(0,-1)), complex('0.0891447921553914 - 0.0321946742909677i'));
approx.deepEqual(dotPow(complex(-1,-1),complex(0,1)), complex('9.92340022667813 + 3.58383962127501i'));
approx.deepEqual(dotPow(complex(-1,-1),complex(1,-1)), complex('-0.1213394664463591 - 0.0569501178644237i'));
approx.deepEqual(dotPow(complex(-1,-1),complex(1,1)), complex('-6.3395606054031211 - 13.5072398479531426i'));
approx.deepEqual(dotPow(complex(-1,1),complex(-1,-1)), complex('-6.7536199239765713 - 3.1697803027015614i'));
approx.deepEqual(dotPow(complex(-1,1),complex(-1,1)), complex('-0.0284750589322119 - 0.0606697332231795i'));
approx.deepEqual(dotPow(complex(-1,1),complex(0,-1)), complex('9.92340022667813 - 3.58383962127501i'));
approx.deepEqual(dotPow(complex(-1,1),complex(0,1)), complex('0.0891447921553914 + 0.0321946742909677i'));
approx.deepEqual(dotPow(complex(-1,1),complex(1,-1)), complex('-6.3395606054031211 + 13.5072398479531426i'));
approx.deepEqual(dotPow(complex(-1,1),complex(1,1)), complex('-0.1213394664463591 + 0.0569501178644237i'));
approx.deepEqual(dotPow(complex(0,-1),complex(-1,-1)), complex('0.000000000000000 + 0.207879576350762i'));
approx.deepEqual(dotPow(complex(0,-1),complex(-1,1)), complex('0.000000000000000 + 4.810477380965351i'));
approx.deepEqual(dotPow(complex(0,-1),complex(1,-1)), complex('0.000000000000000 - 0.207879576350762i'));
approx.deepEqual(dotPow(complex(0,-1),complex(1,1)), complex('0.000000000000000 - 4.810477380965351i'));
approx.deepEqual(dotPow(complex(0,1),complex(-1,-1)), complex('0.000000000000000 - 4.810477380965351i'));
approx.deepEqual(dotPow(complex(0,1),complex(-1,1)), complex('0.000000000000000 - 0.207879576350762i'));
approx.deepEqual(dotPow(complex(0,1),complex(1,-1)), complex('0.000000000000000 + 4.810477380965351i'));
approx.deepEqual(dotPow(complex(0,1),complex(1,1)), complex('0.000000000000000 + 0.207879576350762i'));
approx.deepEqual(dotPow(complex(1,-1),complex(-1,-1)), complex('0.2918503793793073 + 0.1369786269150605i'));
approx.deepEqual(dotPow(complex(1,-1),complex(-1,1)), complex('0.6589325864505904 + 1.4039396486303144i'));
approx.deepEqual(dotPow(complex(1,-1),complex(0,-1)), complex('0.428829006294368 - 0.154871752464247i'));
approx.deepEqual(dotPow(complex(1,-1),complex(0,1)), complex('2.062872235080905 + 0.745007062179724i'));
approx.deepEqual(dotPow(complex(1,-1),complex(1,-1)), complex('0.2739572538301211 - 0.5837007587586147i'));
approx.deepEqual(dotPow(complex(1,-1),complex(1,1)), complex('2.8078792972606288 - 1.3178651729011805i'));
approx.deepEqual(dotPow(complex(1,1),complex(-1,-1)), complex('0.6589325864505904 - 1.4039396486303144i'));
approx.deepEqual(dotPow(complex(1,1),complex(-1,1)), complex('0.2918503793793073 - 0.1369786269150605i'));
approx.deepEqual(dotPow(complex(1,1),complex(0,-1)), complex('2.062872235080905 - 0.745007062179724i'));
approx.deepEqual(dotPow(complex(1,1),complex(0,1)), complex('0.428829006294368 + 0.154871752464247i'));
approx.deepEqual(dotPow(complex(1,1),complex(1,-1)), complex('2.8078792972606288 + 1.3178651729011805i'));
approx.deepEqual(dotPow(complex(1,1),complex(1,1)), complex('0.2739572538301211 + 0.5837007587586147i'));
});
it('should throw an error with units', function() {
assert.throws(function () {dotPow(unit('5cm'));});
});
it('should throw an error with strings', function() {
assert.throws(function () {dotPow('text');});
});
describe('Array', function () {
it('should elevate array .^ scalar', function () {
approx.deepEqual(dotPow([[1,2],[0,4]], 2), [[1,4],[0,16]]);
approx.deepEqual(dotPow([[1,2],[0,4]], 2.5), [[1,5.65685424949238], [0, 32]]);
approx.deepEqual(dotPow([[1,2,3],[4,5,0]], 2), [[1,4,9],[16,25,0]]);
});
it('should elevate scalar .^ array', function () {
approx.deepEqual(dotPow(2, [[1,2],[0,4]]), [[2,4],[1,16]]);
approx.deepEqual(dotPow(2.5, [[1,2],[0,4]]), [[2.5, 6.25], [1, 39.0625]]);
approx.deepEqual(dotPow(2, [[1,2,3],[4,5,0]]), [[2,4,8],[16,32,1]]);
});
it('should elevate array .^ array', function () {
approx.deepEqual(dotPow([[1,2,0],[0,1,4]], [[2,1,0],[4,1,0]]), [[1,2,1],[0,1,1]]);
});
it('should elevate array .^ dense matrix', function () {
approx.deepEqual(dotPow([[1,2,0],[0,1,4]], matrix([[2,1,0],[4,1,0]])), matrix([[1,2,1],[0,1,1]]));
});
it('should elevate array .^ sparse matrix', function () {
approx.deepEqual(dotPow([[1,2,0],[0,1,4]], sparse([[2,1,0],[4,1,0]])), matrix([[1,2,1],[0,1,1]]));
});
});
describe('DenseMatrix', function () {
it('should elevate dense matrix .^ scalar', function () {
approx.deepEqual(dotPow(matrix([[1,2],[0,4]]), 2), matrix([[1,4],[0,16]]));
approx.deepEqual(dotPow(matrix([[1,2],[0,4]]), 2.5), matrix([[1,5.65685424949238], [0, 32]]));
approx.deepEqual(dotPow(matrix([[1,2,3],[4,5,0]]), 2), matrix([[1,4,9],[16,25,0]]));
});
it('should elevate scaler .^ dense matrix', function () {
approx.deepEqual(dotPow(2, matrix([[1,2],[0,4]])), matrix([[2,4],[1,16]]));
approx.deepEqual(dotPow(2.5, matrix([[1,2],[0,4]])), matrix([[2.5, 6.25], [1, 39.0625]]));
approx.deepEqual(dotPow(2, matrix([[1,2,3],[4,5,0]])), matrix([[2,4,8],[16,32,1]]));
});
it('should elevate dense matrix .^ array', function () {
approx.deepEqual(dotPow(matrix([[1,2,0],[0,1,4]]), [[2,1,0],[4,1,0]]), matrix([[1,2,1],[0,1,1]]));
});
it('should elevate dense matrix .^ dense matrix', function () {
approx.deepEqual(dotPow(matrix([[1,2,0],[0,1,4]]), matrix([[2,1,0],[4,1,0]])), matrix([[1,2,1],[0,1,1]]));
});
it('should elevate dense matrix .^ sparse matrix', function () {
approx.deepEqual(dotPow(matrix([[1,2,0],[0,1,4]]), sparse([[2,1,0],[4,1,0]])), matrix([[1,2,1],[0,1,1]]));
});
});
describe('SparseMatrix', function () {
it('should elevate sparse matrix .^ scalar', function () {
approx.deepEqual(dotPow(sparse([[1,2],[0,4]]), 2), sparse([[1,4],[0,16]]));
approx.deepEqual(dotPow(sparse([[1,2],[0,4]]), 2.5), sparse([[1,5.65685424949238], [0, 32]]));
approx.deepEqual(dotPow(sparse([[1,2,3],[4,5,0]]), 2), sparse([[1,4,9],[16,25,0]]));
});
it('should elevate scalar .^ sparse matrix', function () {
approx.deepEqual(dotPow(2, sparse([[1,2],[0,4]])), matrix([[2,4],[1,16]]));
approx.deepEqual(dotPow(2.5, sparse([[1,2],[0,4]])), matrix([[2.5, 6.25], [1, 39.0625]]));
approx.deepEqual(dotPow(2, sparse([[1,2,3],[4,5,0]])), matrix([[2,4,8],[16,32,1]]));
});
it('should elevate sparse matrix .^ array', function () {
approx.deepEqual(dotPow(sparse([[1,2,0],[0,1,4]]), [[2,1,0],[4,1,0]]), matrix([[1,2,1],[0,1,1]]));
});
it('should elevate sparse matrix .^ dense matrix', function () {
approx.deepEqual(dotPow(sparse([[1,2,0],[0,1,4]]), matrix([[2,1,0],[4,1,0]])), matrix([[1,2,1],[0,1,1]]));
});
it('should elevate sparse matrix .^ sparse matrix', function () {
approx.deepEqual(dotPow(sparse([[1,2,0],[0,1,4]]), sparse([[2,1,0],[4,1,0]])), matrix([[1,2,1],[0,1,1]]));
});
});
it('should LaTeX dotPow', function () {
var expression = math.parse('dotPow([1,2],[3,4])');
assert.equal(expression.toTex(), '\\left(\\begin{bmatrix}1\\\\2\\\\\\end{bmatrix}.^\\wedge\\begin{bmatrix}3\\\\4\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,89 @@
// test exp
var assert = require('assert'),
approx = require('../../../tools/approx'),
math = require('../../../index'),
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
exp = math.exp;
describe('exp', function() {
it('should exponentiate a boolean', function () {
approx.equal(exp(true), 2.71828182845905);
approx.equal(exp(false), 1);
});
it('should exponentiate null', function () {
assert.equal(exp(null), 1);
});
it('should exponentiate a number', function() {
approx.equal(exp(-3), 0.0497870683678639);
approx.equal(exp(-2), 0.1353352832366127);
approx.equal(exp(-1), 0.3678794411714423);
approx.equal(exp(0), 1);
approx.equal(exp(1), 2.71828182845905);
approx.equal(exp(2), 7.38905609893065);
approx.equal(exp(3), 20.0855369231877);
approx.equal(exp(math.log(100)), 100);
});
it('should exponentiate a bignumber', function() {
var bigmath = math.create({precision: 100});
assert.deepEqual(bigmath.exp(bigmath.bignumber(1)), bigmath.bignumber('2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427'));
});
it('should throw an error if there\'s wrong number of arguments', function() {
assert.throws(function () {exp();}, /TypeError: Too few arguments/);
assert.throws(function () {exp(1, 2);}, /TypeError: Too many arguments/);
});
it('should exponentiate a complex number correctly', function() {
approx.deepEqual(exp(math.i), complex('0.540302305868140 + 0.841470984807897i'));
approx.deepEqual(exp(complex(0, -1)), complex('0.540302305868140 - 0.841470984807897i'));
approx.deepEqual(exp(complex(1, 1)), complex('1.46869393991589 + 2.28735528717884i'));
approx.deepEqual(exp(complex(1, -1)), complex('1.46869393991589 - 2.28735528717884i'));
approx.deepEqual(exp(complex(-1, -1)), complex('0.198766110346413 - 0.309559875653112i'));
approx.deepEqual(exp(complex(-1, 1)), complex('0.198766110346413 + 0.309559875653112i'));
approx.deepEqual(exp(complex(1, 0)), complex('2.71828182845905'));
// test some logic identities
var multiply = math.multiply,
pi = math.pi,
i = math.i;
approx.deepEqual(exp(multiply( 0.5, multiply(pi, i))), complex(0, 1));
approx.deepEqual(exp(multiply( 1, multiply(pi, i))), complex(-1, 0));
approx.deepEqual(exp(multiply( 1.5, multiply(pi, i))), complex(0, -1));
approx.deepEqual(exp(multiply( 2, multiply(pi, i))), complex(1, 0));
approx.deepEqual(exp(multiply(-0.5, multiply(pi, i))), complex(0, -1));
approx.deepEqual(exp(multiply(-1, multiply(pi, i))), complex(-1, 0));
approx.deepEqual(exp(multiply(-1.5, multiply(pi, i))), complex(0, 1));
});
it('should throw an error on a unit', function() {
assert.throws(function () {exp(unit('5cm'));});
});
it('should throw an error with a string', function() {
assert.throws(function () {exp('text');});
});
it('should exponentiate matrices, arrays and ranges correctly', function() {
// array
approx.deepEqual(exp([0, 1, 2, 3]), [1, 2.71828182845905, 7.38905609893065, 20.0855369231877]);
approx.deepEqual(exp([[0, 1], [2, 3]]), [[1, 2.71828182845905], [7.38905609893065, 20.0855369231877]]);
// dense matrix
approx.deepEqual(exp(matrix([0, 1, 2, 3])), matrix([1, 2.71828182845905, 7.38905609893065, 20.0855369231877]));
approx.deepEqual(exp(matrix([[0, 1], [2, 3]])), matrix([[1, 2.71828182845905], [7.38905609893065, 20.0855369231877]]));
// sparse matrix, TODO: it should return a dense matrix
approx.deepEqual(exp(sparse([[0, 1], [2, 3]])), sparse([[1, 2.71828182845905], [7.38905609893065, 20.0855369231877]]));
});
it('should LaTeX exp', function () {
var expression = math.parse('exp(0)');
assert.equal(expression.toTex(), '\\exp\\left(0\\right)');
});
});

View File

@@ -0,0 +1,100 @@
// test fix
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var bignumber = math.bignumber;
var complex = math.complex;
var fraction = math.fraction;
var matrix = math.matrix;
var unit = math.unit;
var range = math.range;
var fix = math.fix;
describe('fix', function() {
it('should round booleans correctly', function () {
assert.equal(fix(true), 1);
assert.equal(fix(false), 0);
});
it('should round null', function () {
assert.equal(math.ceil(null), 0);
});
it('should round numbers correctly', function() {
approx.equal(fix(0), 0);
approx.equal(fix(1), 1);
approx.equal(fix(1.3), 1);
approx.equal(fix(1.8), 1);
approx.equal(fix(2), 2);
approx.equal(fix(-1), -1);
approx.equal(fix(-1.3), -1);
approx.equal(fix(-1.8), -1);
approx.equal(fix(-2), -2);
approx.equal(fix(-2.1), -2);
approx.equal(fix(math.pi), 3);
});
it('should round big numbers correctly', function() {
assert.deepEqual(fix(bignumber(0)), bignumber(0));
assert.deepEqual(fix(bignumber(1)), bignumber(1));
assert.deepEqual(fix(bignumber(1.3)), bignumber(1));
assert.deepEqual(fix(bignumber(1.8)), bignumber(1));
assert.deepEqual(fix(bignumber(2)), bignumber(2));
assert.deepEqual(fix(bignumber(-1)), bignumber(-1));
assert.deepEqual(fix(bignumber(-1.3)), bignumber(-1));
assert.deepEqual(fix(bignumber(-1.8)), bignumber(-1));
assert.deepEqual(fix(bignumber(-2)), bignumber(-2));
assert.deepEqual(fix(bignumber(-2.1)), bignumber(-2));
});
it('should round complex numbers correctly', function() {
// complex
approx.deepEqual(fix(complex(0, 0)), complex(0, 0));
approx.deepEqual(fix(complex(1.3, 1.8)), complex(1, 1));
approx.deepEqual(fix(math.i), complex(0, 1));
approx.deepEqual(fix(complex(-1.3, -1.8)), complex(-1, -1));
});
it('should round fractions correctly', function() {
var a = fraction('2/3');
assert(fix(a) instanceof math.type.Fraction);
assert.equal(a.toString(), '0.(6)');
assert.equal(fix(fraction(0)).toString(), '0');
assert.equal(fix(fraction(1)).toString(), '1');
assert.equal(fix(fraction(1.3)).toString(), '1');
assert.equal(fix(fraction(1.8)).toString(), '1');
assert.equal(fix(fraction(2)).toString(), '2');
assert.equal(fix(fraction(-1)).toString(), '-1');
assert.equal(fix(fraction(-1.3)).toString(), '-1');
assert.equal(fix(fraction(-1.8)).toString(), '-1');
assert.equal(fix(fraction(-2)).toString(), '-2');
assert.equal(fix(fraction(-2.1)).toString(), '-2');
});
it('should throw an error on unit as parameter', function() {
// unit
assert.throws(function () {fix(unit('5cm'))}, TypeError, 'Function fix(unit) not supported');
});
it('should convert a string to a number', function() {
assert.strictEqual(fix('1.8'), 1);
});
it('should correctly round all values of a matrix element-wise', function() {
// matrix, array, range
approx.deepEqual(fix([1.2, 3.4, 5.6, 7.8, 10.0]), [1, 3, 5, 7, 10]);
approx.deepEqual(fix(matrix([1.2, 3.4, 5.6, 7.8, 10.0])), matrix([1, 3, 5, 7, 10]));
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {fix()}, /TypeError: Too few arguments/);
assert.throws(function () {fix(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX fix', function () {
var expression = math.parse('fix(0.6)');
assert.equal(expression.toTex(), '\\mathrm{fix}\\left(0.6\\right)');
});
});

View File

@@ -0,0 +1,97 @@
// test floor
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var bignumber = math.bignumber;
var complex = math.complex;
var fraction = math.fraction;
var matrix = math.matrix;
var unit = math.unit;
var range = math.range;
var floor = math.floor;
describe('floor', function() {
it('should round booleans correctly', function () {
assert.equal(floor(true), 1);
assert.equal(floor(false), 0);
});
it('should round null', function () {
assert.equal(floor(null), 0);
});
it('should floor numbers correctly', function() {
approx.equal(floor(0), 0);
approx.equal(floor(1), 1);
approx.equal(floor(1.3), 1);
approx.equal(floor(1.8), 1);
approx.equal(floor(2), 2);
approx.equal(floor(-1), -1);
approx.equal(floor(-1.3), -2);
approx.equal(floor(-1.8), -2);
approx.equal(floor(-2), -2);
approx.equal(floor(-2.1), -3);
approx.equal(floor(math.pi), 3);
});
it('should floor big numbers correctly', function() {
assert.deepEqual(floor(bignumber(0)), bignumber(0));
assert.deepEqual(floor(bignumber(1)), bignumber(1));
assert.deepEqual(floor(bignumber(1.3)), bignumber(1));
assert.deepEqual(floor(bignumber(1.8)), bignumber(1));
assert.deepEqual(floor(bignumber(2)), bignumber(2));
assert.deepEqual(floor(bignumber(-1)), bignumber(-1));
assert.deepEqual(floor(bignumber(-1.3)), bignumber(-2));
assert.deepEqual(floor(bignumber(-1.8)), bignumber(-2));
assert.deepEqual(floor(bignumber(-2)), bignumber(-2));
assert.deepEqual(floor(bignumber(-2.1)), bignumber(-3));
});
it('should floor complex numbers correctly', function() {
approx.deepEqual(floor(complex(0, 0)), complex(0, 0));
approx.deepEqual(floor(complex(1.3, 1.8)), complex(1, 1));
approx.deepEqual(floor(math.i), complex(0, 1));
approx.deepEqual(floor(complex(-1.3, -1.8)), complex(-2, -2));
});
it('should floor fractions correctly', function() {
var a = fraction('2/3');
assert(floor(a) instanceof math.type.Fraction);
assert.equal(a.toString(), '0.(6)');
assert.equal(floor(fraction(0)).toString(), '0');
assert.equal(floor(fraction(1)).toString(), '1');
assert.equal(floor(fraction(1.3)).toString(), '1');
assert.equal(floor(fraction(1.8)).toString(), '1');
assert.equal(floor(fraction(2)).toString(), '2');
assert.equal(floor(fraction(-1)).toString(), '-1');
assert.equal(floor(fraction(-1.3)).toString(), '-2');
assert.equal(floor(fraction(-1.8)).toString(), '-2');
assert.equal(floor(fraction(-2)).toString(), '-2');
assert.equal(floor(fraction(-2.1)).toString(), '-3');
});
it('should throw an error with a unit', function() {
assert.throws(function () {floor(unit('5cm'))}, TypeError, 'Function floor(unit) not supported');
});
it('should convert a string to a number', function() {
assert.strictEqual(floor('1.8'), 1);
});
it('should floor all elements in a matrix', function() {
approx.deepEqual(floor([1.2, 3.4, 5.6, 7.8, 10.0]), [1, 3, 5, 7, 10]);
approx.deepEqual(floor(matrix([1.2, 3.4, 5.6, 7.8, 10.0])), matrix([1, 3, 5, 7, 10]));
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {floor()}, /TypeError: Too few arguments/);
assert.throws(function () {floor(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX floor', function () {
var expression = math.parse('floor(0.6)');
assert.equal(expression.toTex(), '\\left\\lfloor0.6\\right\\rfloor');
});
});

View File

@@ -0,0 +1,173 @@
// test gcd
var assert = require('assert'),
math = require('../../../index'),
matrix = math.matrix,
sparse = math.sparse,
gcd = math.gcd;
describe('gcd', function() {
it('should find the greatest common divisor of two or more numbers', function() {
assert.strictEqual(gcd(12, 8), 4);
assert.strictEqual(gcd(8, 12), 4);
assert.strictEqual(gcd(8, -12), 4);
assert.strictEqual(gcd(-12, 8), 4);
assert.strictEqual(gcd(12, -8), 4);
assert.strictEqual(gcd(15, 3), 3);
assert.strictEqual(gcd(25, 15, -10, 30), 5);
});
it ('should calculate gcd for edge cases around zero', function () {
assert.strictEqual(gcd(3, 0), 3);
assert.strictEqual(gcd(-3, 0), 3);
assert.strictEqual(gcd(0, 3), 3);
assert.strictEqual(gcd(0, -3), 3);
assert.strictEqual(gcd(0, 0), 0);
assert.strictEqual(gcd(1, 1), 1);
assert.strictEqual(gcd(1, 0), 1);
assert.strictEqual(gcd(1, -1), 1);
assert.strictEqual(gcd(-1, 1), 1);
assert.strictEqual(gcd(-1, 0), 1);
assert.strictEqual(gcd(-1, -1), 1);
assert.strictEqual(gcd(0, 1), 1);
assert.strictEqual(gcd(0, -1), 1);
assert.strictEqual(gcd(0, 0), 0);
});
it ('should calculate gcd for edge cases with negative values', function () {
assert.deepEqual(1, gcd(2, 5));
assert.deepEqual(1, gcd(2, -5));
assert.deepEqual(1, gcd(-2, 5));
assert.deepEqual(1, gcd(-2, -5));
assert.deepEqual(2, gcd(2, 6));
assert.deepEqual(2, gcd(2, -6));
assert.deepEqual(2, gcd(-2, 6));
assert.deepEqual(2, gcd(-2, -6));
});
it('should calculate gcd for BigNumbers', function() {
assert.deepEqual(gcd(math.bignumber(12), math.bignumber(8)), math.bignumber(4));
assert.deepEqual(gcd(math.bignumber(8), math.bignumber(12)), math.bignumber(4));
});
it('should calculate gcd for mixed BigNumbers and Numbers', function() {
assert.deepEqual(gcd(math.bignumber(12), 8), math.bignumber(4));
assert.deepEqual(gcd(8, math.bignumber(12)), math.bignumber(4));
});
it('should find the greatest common divisor of fractions', function () {
var a = math.fraction(5,8);
assert.equal(gcd(a, math.fraction(3,7)).toString(), '0.017(857142)');
assert.equal(a.toString(), '0.625');
});
it('should find the greatest common divisor of mixed numbers and fractions', function () {
assert.deepEqual(gcd(math.fraction(12), 8), math.fraction(4));
assert.deepEqual(gcd(12, math.fraction(8)), math.fraction(4));
});
it('should find the greatest common divisor of booleans', function() {
assert.equal(gcd(true, true), 1);
assert.equal(gcd(true, false), 1);
assert.equal(gcd(false, true), 1);
assert.equal(gcd(false, false), 0);
});
it('should find the greatest common divisor of numbers and null', function () {
assert.equal(gcd(1, null), 1);
assert.equal(gcd(null, 1), 1);
assert.equal(gcd(null, null), 0);
});
it('should throw an error if only one argument', function() {
assert.throws(function () {gcd(1); }, /TypeError: Too few arguments/);
});
it('should throw an error for non-integer numbers', function() {
assert.throws(function () {gcd(2, 4.1); }, /Parameters in function gcd must be integer numbers/);
assert.throws(function () {gcd(2.3, 4); }, /Parameters in function gcd must be integer numbers/);
});
it('should throw an error with complex numbers', function() {
assert.throws(function () {gcd(math.complex(1,3),2); }, /TypeError: Unexpected type of argument/);
});
it('should convert strings to numbers', function() {
assert.strictEqual(gcd('12', '8'), 4);
assert.strictEqual(gcd(12, '8'), 4);
assert.strictEqual(gcd('12', 8), 4);
assert.throws(function () {gcd('a', 8); }, /Cannot convert "a" to a number/);
});
it('should throw an error with units', function() {
assert.throws(function () { gcd(math.unit('5cm'), 2); }, /TypeError: Unexpected type of argument/);
});
describe('Array', function () {
it('should find the greatest common divisor array - scalar', function() {
assert.deepEqual(gcd([5, 18, 3], 3), [1, 3, 3]);
assert.deepEqual(gcd(3, [5, 18, 3]), [1, 3, 3]);
});
it('should find the greatest common divisor array - array', function() {
assert.deepEqual(gcd([5, 2, 3], [25, 3, 6]), [5, 1, 3]);
});
it('should find the greatest common divisor array - dense matrix', function() {
assert.deepEqual(gcd([5, 2, 3], matrix([25, 3, 6])), matrix([5, 1, 3]));
});
it('should find the greatest common divisor array - sparse matrix', function() {
assert.deepEqual(gcd([[5, 2, 3], [3, 2, 5]], sparse([[0, 3, 6], [6, 0, 25]])), matrix([[5, 1, 3], [3, 2, 5]]));
});
});
describe('DenseMatrix', function () {
it('should find the greatest common divisor dense matrix - scalar', function() {
assert.deepEqual(gcd(matrix([5, 18, 3]), 3), matrix([1, 3, 3]));
assert.deepEqual(gcd(3, matrix([5, 18, 3])), matrix([1, 3, 3]));
});
it('should find the greatest common divisor dense matrix - array', function() {
assert.deepEqual(gcd(matrix([5, 2, 3]), [25, 3, 6]), matrix([5, 1, 3]));
});
it('should find the greatest common divisor dense matrix - dense matrix', function() {
assert.deepEqual(gcd(matrix([5, 2, 3]), matrix([25, 3, 6])), matrix([5, 1, 3]));
});
it('should find the greatest common divisor dense matrix - sparse matrix', function() {
assert.deepEqual(gcd(matrix([[5, 2, 3], [3, 2, 5]]), sparse([[0, 3, 6], [6, 0, 25]])), matrix([[5, 1, 3], [3, 2, 5]]));
});
});
describe('SparseMatrix', function () {
it('should find the greatest common divisor sparse matrix - scalar', function() {
assert.deepEqual(gcd(sparse([[5, 0, 3], [0, 18, 0]]), 3), matrix([[1, 3, 3], [3, 3, 3]]));
assert.deepEqual(gcd(3, sparse([[5, 0, 3], [0, 18, 0]])), matrix([[1, 3, 3], [3, 3, 3]]));
});
it('should find the greatest common divisor sparse matrix - array', function() {
assert.deepEqual(gcd(sparse([[5, 2, 3], [3, 2, 5]]), [[0, 3, 6], [6, 0, 25]]), matrix([[5, 1, 3], [3, 2, 5]]));
});
it('should find the greatest common divisor sparse matrix - dense matrix', function() {
assert.deepEqual(gcd(sparse([[5, 2, 3], [3, 2, 5]]), matrix([[0, 3, 6], [6, 0, 25]])), matrix([[5, 1, 3], [3, 2, 5]]));
});
it('should find the greatest common divisor sparse matrix - sparse matrix', function() {
assert.deepEqual(gcd(sparse([[5, 2, 3], [3, 2, 5]]), sparse([[0, 3, 6], [6, 0, 25]])), sparse([[5, 1, 3], [3, 2, 5]]));
});
});
it('should LaTeX gcd', function () {
var expression = math.parse('gcd(2,3)');
assert.equal(expression.toTex(), '\\gcd\\left(2,3\\right)');
});
});

View File

@@ -0,0 +1,56 @@
// test hypot
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var hypot = math.hypot;
var bignumber = math.bignumber;
var fraction = math.fraction;
describe('hypot', function() {
it('should return the hypot of numbers', function () {
assert.strictEqual(hypot(3, 4), 5);
assert.strictEqual(hypot(3, -4), 5);
approx.equal(hypot(3, 4, 5), 7.0710678118654755);
assert.strictEqual(hypot(-2), 2);
assert.strictEqual(hypot(0), 0);
assert.strictEqual(hypot(Infinity), Infinity);
});
it('should return the hypot of BigNumbers', function () {
assert.deepEqual(hypot(bignumber(3), bignumber(4)), bignumber(5));
assert.deepEqual(hypot(bignumber(3), bignumber(-4)), bignumber(5));
assert.deepEqual(hypot(bignumber(3), bignumber(4), bignumber(5)),
bignumber('7.07106781186547524400844362104849039284835937688474036588339869'));
assert.deepEqual(hypot(bignumber(-2)), bignumber(2));
});
it('should return the hypot of an Array with numbers', function () {
assert.strictEqual(hypot([3, 4]), 5);
});
it('should return the hypot of an Matrix with numbers', function () {
assert.strictEqual(hypot(math.matrix([3, 4])), 5);
});
it('should return the hypot of an Array with mixed numbers and BigNumbers', function () {
assert.deepEqual(hypot([3, bignumber(4)]), bignumber(5));
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {hypot()}, /TypeError: Too few arguments/);
assert.throws(function () {hypot([], 2)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of unsupported types', function () {
assert.throws(function () {hypot(new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {hypot([new Date()]);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {hypot([2, 3, math.complex()]);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {hypot(undefined);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX hypot', function () {
var expression = math.parse('hypot(3,4)');
assert.equal(expression.toTex(),'\\hypot\\left(3,4\\right)');
});
});

View File

@@ -0,0 +1,169 @@
var assert = require('assert'),
math = require('../../../index'),
matrix = math.matrix,
sparse = math.sparse,
lcm = math.lcm;
describe('lcm', function() {
it('should find the lowest common multiple of two or more numbers', function() {
assert.equal(lcm(4, 6), 12);
assert.equal(lcm(4, -6), 12);
assert.equal(lcm(6, 4), 12);
assert.equal(lcm(-6, 4), 12);
assert.equal(lcm(-6, -4), 12);
assert.equal(lcm(21, 6), 42);
assert.equal(lcm(3, -4, 24), 24);
assert.throws(function () {lcm(1); }, /TypeError: Too few arguments/);
});
it ('should calculate lcm for edge cases around zero', function () {
assert.equal(lcm(3, 0), 0);
assert.equal(lcm(-3, 0), 0);
assert.equal(lcm(0, 3), 0);
assert.equal(lcm(0, -3), 0);
assert.equal(lcm(0, 0), 0);
assert.equal(lcm(1, 1), 1);
assert.equal(lcm(1, 0), 0);
assert.equal(lcm(1, -1), 1);
assert.equal(lcm(-1, 1), 1);
assert.equal(lcm(-1, 0), 0);
assert.equal(lcm(-1, -1), 1);
assert.equal(lcm(0, 1), 0);
assert.equal(lcm(0, -1), 0);
assert.equal(lcm(0, 0), 0);
});
it('should calculate lcm for BigNumbers', function() {
assert.deepEqual(lcm(math.bignumber(4), math.bignumber(6)), math.bignumber(12));
assert.deepEqual(lcm(math.bignumber(4), math.bignumber(6)), math.bignumber(12));
});
it('should calculate lcm for mixed BigNumbers and Numbers', function() {
assert.deepEqual(lcm(math.bignumber(4), 6), math.bignumber(12));
assert.deepEqual(lcm(4, math.bignumber(6)), math.bignumber(12));
});
it('should find the lowest common multiple of booleans', function() {
assert.equal(lcm(true, true), 1);
assert.equal(lcm(true, false), 0);
assert.equal(lcm(false, true), 0);
assert.equal(lcm(false, false), 0);
});
it('should find the lowest common multiple of numbers and null', function () {
assert.equal(lcm(1, null), 0);
assert.equal(lcm(null, 1), 0);
assert.equal(lcm(null, null), 0);
});
it('should throw an error for non-integer numbers', function() {
assert.throws(function () {lcm(2, 4.1); }, /Parameters in function lcm must be integer numbers/);
assert.throws(function () {lcm(2.3, 4); }, /Parameters in function lcm must be integer numbers/);
});
it('should throw an error with complex numbers', function() {
assert.throws(function () {lcm(math.complex(1,3),2); }, TypeError, 'Function lcm(complex, number) not supported');
});
it('should convert strings to numbers', function() {
assert.equal(lcm('4', '6'), 12);
assert.equal(lcm('4', 6), 12);
assert.equal(lcm(4, '6'), 12);
assert.throws(function () {lcm('a', 2); }, /Cannot convert "a" to a number/);
});
it('should find the least common multiple of fractions', function () {
var a = math.fraction(5,8);
assert.equal(lcm(a, math.fraction(3,7)).toString(), '15');
assert.equal(a.toString(), '0.625');
});
it('should find the least common multiple of mixed numbers and fractions', function () {
assert.deepEqual(lcm(math.fraction(12), 8), math.fraction(24));
assert.deepEqual(lcm(12, math.fraction(8)), math.fraction(24));
});
it('should find the least common even for edge cases', function () {
assert.deepEqual(lcm(math.fraction(-3), math.fraction(3)), math.fraction(3));
assert.deepEqual(lcm(math.fraction(3), math.fraction(-3)), math.fraction(3));
assert.deepEqual(lcm(math.fraction(0), math.fraction(3)), math.fraction(0));
assert.deepEqual(lcm(math.fraction(3), math.fraction(0)), math.fraction(0));
assert.deepEqual(lcm(math.fraction(0), math.fraction(0)), math.fraction(0));
assert.deepEqual(lcm(math.fraction(200), math.fraction(333)), math.fraction(66600));
assert.deepEqual(lcm(math.fraction(9999), math.fraction(8888)), math.fraction(79992));
});
it('should throw an error with units', function() {
assert.throws(function () { lcm(math.unit('5cm'), 2); }, TypeError, 'Function lcm(unit, number) not supported');
});
describe('Array', function () {
it('should find the greatest common divisor array - scalar', function() {
assert.deepEqual(lcm([5, 18, 3], 3), [15, 18, 3]);
assert.deepEqual(lcm(3, [5, 18, 3]), [15, 18, 3]);
});
it('should find the greatest common divisor array - array', function() {
assert.deepEqual(lcm([5, 2, 3], [25, 3, 6]), [25, 6, 6]);
});
it('should find the greatest common divisor array - dense matrix', function() {
assert.deepEqual(lcm([5, 2, 3], matrix([25, 3, 6])), matrix([25, 6, 6]));
});
it('should find the greatest common divisor array - sparse matrix', function() {
assert.deepEqual(lcm([[5, 2, 3], [3, 2, 5]], sparse([[0, 3, 6], [6, 0, 25]])), sparse([[0, 6, 6], [6, 0, 25]]));
});
});
describe('DenseMatrix', function () {
it('should find the greatest common divisor dense matrix - scalar', function() {
assert.deepEqual(lcm(matrix([5, 18, 3]), 3), matrix([15, 18, 3]));
assert.deepEqual(lcm(3, matrix([5, 18, 3])), matrix([15, 18, 3]));
});
it('should find the greatest common divisor dense matrix - array', function() {
assert.deepEqual(lcm(matrix([5, 2, 3]), [25, 3, 6]), matrix([25, 6, 6]));
});
it('should find the greatest common divisor dense matrix - dense matrix', function() {
assert.deepEqual(lcm(matrix([5, 2, 3]), matrix([25, 3, 6])), matrix([25, 6, 6]));
});
it('should find the greatest common divisor dense matrix - sparse matrix', function() {
assert.deepEqual(lcm(matrix([[5, 2, 3], [3, 2, 5]]), sparse([[0, 3, 6], [6, 0, 25]])), sparse([[0, 6, 6], [6, 0, 25]]));
});
});
describe('SparseMatrix', function () {
it('should find the greatest common divisor sparse matrix - scalar', function() {
assert.deepEqual(lcm(sparse([[5, 0, 3], [0, 18, 0]]), 3), sparse([[15, 0, 3], [0, 18, 0]]));
assert.deepEqual(lcm(3, sparse([[5, 0, 3], [0, 18, 0]])), sparse([[15, 0, 3], [0, 18, 0]]));
});
it('should find the greatest common divisor sparse matrix - array', function() {
assert.deepEqual(lcm(sparse([[5, 2, 3], [3, 2, 5]]), [[0, 3, 6], [6, 0, 25]]), sparse([[0, 6, 6], [6, 0, 25]]));
});
it('should find the greatest common divisor sparse matrix - dense matrix', function() {
assert.deepEqual(lcm(sparse([[5, 2, 3], [3, 2, 5]]), matrix([[0, 3, 6], [6, 0, 25]])), sparse([[0, 6, 6], [6, 0, 25]]));
});
it('should find the greatest common divisor sparse matrix - sparse matrix', function() {
assert.deepEqual(lcm(sparse([[5, 2, 3], [3, 2, 5]]), sparse([[0, 3, 6], [6, 0, 25]])), sparse([[0, 6, 6], [6, 0, 25]]));
});
});
it('should LaTeX lcm', function () {
var expression = math.parse('lcm(2,3)');
assert.equal(expression.toTex(), '\\mathrm{lcm}\\left(2,3\\right)');
});
});

View File

@@ -0,0 +1,122 @@
// test log
var assert = require('assert');
var approx = require('../../../tools/approx');
var error = require('../../../lib/error/index');
var math = require('../../../index');
var mathPredictable = math.create({predictable: true});
var complex = math.complex;
var matrix = math.matrix;
var unit = math.unit;
var range = math.range;
var log = math.log;
describe('log', function() {
it('should return the log of a boolean value', function () {
assert.equal(log(true), 0);
assert.equal(log(false), -Infinity);
assert.equal(log(1,false), 0);
});
it('should return the log of null', function () {
assert.equal(log(null), -Infinity);
assert.equal(log(1, null), 0);
});
it('should return the log of positive numbers', function() {
approx.deepEqual(log(1), 0);
approx.deepEqual(log(2), 0.693147180559945);
approx.deepEqual(log(3), 1.098612288668110);
approx.deepEqual(math.exp(log(100)), 100);
});
it('should return the log of negative numbers', function() {
approx.deepEqual(log(-1), complex('0.000000000000000 + 3.141592653589793i'));
approx.deepEqual(log(-2), complex('0.693147180559945 + 3.141592653589793i'));
approx.deepEqual(log(-3), complex('1.098612288668110 + 3.141592653589793i'));
});
it('should return the log of negative numbers with predictable: true', function() {
assert.equal(typeof mathPredictable.log(-1), 'number');
assert(isNaN(mathPredictable.log(-1)));
});
it('should return the log of zero', function() {
approx.deepEqual(log(0), -Infinity);
});
it('should return the log base N of a number', function() {
approx.deepEqual(log(100, 10), 2);
approx.deepEqual(log(1000, 10), 3);
approx.deepEqual(log(8, 2), 3);
approx.deepEqual(log(16, 2), 4);
});
it('should throw an error if invalid number of arguments', function() {
assert.throws(function () {log()}, /TypeError: Too few arguments in function log \(expected: any, index: 1\)/);
assert.throws(function () {log(1, 2, 3)}, /TypeError: Too many arguments in function log \(expected: 2, actual: 3\)/);
});
it('should return the log of positive bignumbers', function() {
var bigmath = math.create({precision: 100});
assert.deepEqual(bigmath.log(bigmath.bignumber(1)), bigmath.bignumber('0'));
assert.deepEqual(bigmath.log(bigmath.bignumber(2)), bigmath.bignumber('0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875'));
assert.deepEqual(bigmath.log(bigmath.bignumber(3)), bigmath.bignumber('1.098612288668109691395245236922525704647490557822749451734694333637494293218608966873615754813732089'));
// note: the following gives a round-off error with regular numbers
assert.deepEqual(bigmath.log(bigmath.bignumber(1000), bigmath.bignumber(10)), bigmath.bignumber(3));
});
it('should return the log of negative bignumbers', function() {
var bigmath = math.create({precision: 100});
approx.deepEqual(bigmath.log(bigmath.bignumber(-1)), complex('0.000000000000000 + 3.141592653589793i'));
approx.deepEqual(bigmath.log(bigmath.bignumber(-2)), complex('0.693147180559945 + 3.141592653589793i'));
approx.deepEqual(bigmath.log(bigmath.bignumber(-3)), complex('1.098612288668110 + 3.141592653589793i'));
});
it('should return the log of negative bignumbers with predictable:true', function() {
assert.ok(mathPredictable.log(math.bignumber(-1)).isNaN());
});
it('should return the log of a bignumber with value zero', function() {
var bigmath = math.create({precision: 100});
assert.deepEqual(bigmath.log(bigmath.bignumber(0)).toString(), '-Infinity');
});
it('should return the log of a complex number', function() {
approx.deepEqual(log(math.i), complex('1.570796326794897i'));
approx.deepEqual(log(complex(0, -1)), complex('-1.570796326794897i'));
approx.deepEqual(log(complex(1, 1)), complex('0.346573590279973 + 0.785398163397448i'));
approx.deepEqual(log(complex(1, -1)), complex('0.346573590279973 - 0.785398163397448i'));
approx.deepEqual(log(complex(-1, -1)), complex('0.346573590279973 - 2.356194490192345i'));
approx.deepEqual(log(complex(-1, 1)), complex('0.346573590279973 + 2.356194490192345i'));
approx.deepEqual(log(complex(1, 0)), complex(0, 0));
});
it('should throw an error when used on a unit', function() {
assert.throws(function () {log(unit('5cm'))});
});
it('should throw an error when used on a string', function() {
assert.throws(function () {log('text')});
});
it('should return the log of each element of a matrix', function() {
var res = [0, 0.693147180559945, 1.098612288668110, 1.386294361119891];
approx.deepEqual(log([1,2,3,4]), res);
approx.deepEqual(log(matrix([1,2,3,4])), matrix(res));
approx.deepEqual(log(matrix([[1,2],[3,4]])),
matrix([[0, 0.693147180559945], [1.098612288668110, 1.386294361119891]]));
});
it('should LaTeX log', function () {
var expr1 = math.parse('log(e)');
var expr2 = math.parse('log(32,2)');
assert.equal(expr1.toTex(), '\\ln\\left( e\\right)');
assert.equal(expr2.toTex(), '\\log_{2}\\left(32\\right)');
});
});

View File

@@ -0,0 +1,113 @@
// test exp
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var mathPredictable = math.create({predictable: true});
var complex = math.complex;
var matrix = math.matrix;
var unit = math.unit;
var range = math.range;
var log10 = math.log10;
describe('log10', function() {
it('should return the log base 10 of a boolean', function () {
assert.equal(log10(true), 0);
assert.equal(log10(false), -Infinity);
});
it('should return the log base 10 of null', function () {
assert.equal(log10(null), -Infinity);
});
it('should return the log base 10 of positive numbers', function() {
approx.deepEqual(log10(1), 0);
approx.deepEqual(log10(2), 0.301029995663981);
approx.deepEqual(log10(3), 0.477121254719662);
approx.deepEqual(log10(0.01), -2);
approx.deepEqual(log10(0.1), -1);
approx.deepEqual(log10(1), 0);
approx.deepEqual(log10(10), 1);
approx.deepEqual(log10(100), 2);
approx.deepEqual(log10(1000), 3);
});
it('should return the log base 10 of negative numbers', function() {
approx.deepEqual(log10(-1), complex('0.000000000000000 + 1.364376353841841i'));
approx.deepEqual(log10(-2), complex('0.301029995663981 + 1.364376353841841i'));
approx.deepEqual(log10(-3), complex('0.477121254719662 + 1.364376353841841i'));
});
it('should return the log base 10 of negative numbers with predicable:true', function() {
assert.equal(typeof mathPredictable.log10(-1), 'number');
assert(isNaN(mathPredictable.log10(-1)));
});
it('should return the log base 10 of zero', function() {
approx.deepEqual(log10(0), -Infinity);
});
it('should return the log of positive bignumbers', function() {
var bigmath = math.create({precision: 100});
assert.deepEqual(bigmath.log10(bigmath.bignumber(1)), bigmath.bignumber(0));
assert.deepEqual(bigmath.log10(bigmath.bignumber(10)), bigmath.bignumber(1));
assert.deepEqual(bigmath.log10(bigmath.bignumber(100)), bigmath.bignumber(2));
assert.deepEqual(bigmath.log10(bigmath.bignumber(1000)), bigmath.bignumber(3)); // note: this gives a round-off error with regular numbers
assert.deepEqual(bigmath.log10(bigmath.bignumber(10000)), bigmath.bignumber(4));
assert.deepEqual(bigmath.log10(bigmath.bignumber('1e500')), bigmath.bignumber(500));
});
it('should return the log of negative bignumbers', function() {
var bigmath = math.create({precision: 100});
approx.deepEqual(bigmath.log10(bigmath.bignumber(-1)), bigmath.complex('0.000000000000000 + 1.364376353841841i'));
approx.deepEqual(bigmath.log10(bigmath.bignumber(-2)), bigmath.complex('0.301029995663981 + 1.364376353841841i'));
approx.deepEqual(bigmath.log10(bigmath.bignumber(-3)), bigmath.complex('0.477121254719662 + 1.364376353841841i'));
});
it('should return the log of a bignumber with value zero', function() {
var bigmath = math.create({precision: 100});
assert.deepEqual(bigmath.log10(bigmath.bignumber(0)).toString(), '-Infinity');
});
it('should throw an error if used with a wrong number of arguments', function() {
assert.throws(function () {log10()}, /TypeError: Too few arguments/);
assert.throws(function () {log10(1, 2)}, /TypeError: Too many arguments/);
});
it('should return the log base 10 of a complex number', function() {
approx.deepEqual(log10(complex(0, 1)), complex('0.000000000000000 + 0.682188176920921i'));
approx.deepEqual(log10(complex(0, -1)), complex('0.000000000000000 - 0.682188176920921i'));
approx.deepEqual(log10(complex(1, 1)), complex('0.150514997831991 + 0.341094088460460i'));
approx.deepEqual(log10(complex(1, -1)), complex('0.150514997831991 - 0.341094088460460i'));
approx.deepEqual(log10(complex(-1, -1)), complex('0.150514997831991 - 1.023282265381381i'));
approx.deepEqual(log10(complex(-1, 1)), complex('0.150514997831991 + 1.023282265381381i'));
approx.deepEqual(log10(complex(1, 0)), complex(0, 0));
});
it('should throw an error when used on a unit', function() {
assert.throws(function () {log10(unit('5cm'))});
});
it('should throw an error when used on a string', function() {
assert.throws(function () {log10('text')});
});
it('should return the log base 10 of each element of a matrix', function() {
var res = [0, 0.301029995663981, 0.477121254719662, 0.602059991327962];
approx.deepEqual(log10([1,2,3,4]), res);
approx.deepEqual(log10(matrix([1,2,3,4])), matrix(res));
approx.deepEqual(math.divide(log10(matrix([1,2,3,4])), math.LOG10E),
matrix([0, 0.693147180559945, 1.098612288668110, 1.386294361119891]));
approx.deepEqual(log10(matrix([[1,2],[3,4]])),
matrix([[0, 0.301029995663981], [0.477121254719662, 0.602059991327962]]));
});
it('should LaTeX log10', function () {
var expression = math.parse('log10(10)');
assert.equal(expression.toTex(), '\\log_{10}\\left(10\\right)');
});
});

View File

@@ -0,0 +1,182 @@
// test mod
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var bignumber = math.bignumber;
var matrix = math.matrix;
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);
assert.equal(mod(true, false), 1);
assert.equal(mod(false, false), 0);
});
it('should calculate the modulus of numbers and null', function () {
assert.equal(mod(null, null), 0);
assert.equal(mod(null, 1), 0);
assert.equal(mod(1, null), 1);
});
it('should calculate the modulus of two numbers', function() {
assert.equal(mod(1, 1), 0);
assert.equal(mod(0, 1), 0);
assert.equal(mod(1, 0), 1);
assert.equal(mod(0, 0), 0);
assert.equal(mod(7, 0), 7);
approx.equal(mod(7, 2), 1);
approx.equal(mod(9, 3), 0);
approx.equal(mod(10, 4), 2);
approx.equal(mod(-10, 4), 2);
approx.equal(mod(8.2, 3), 2.2);
approx.equal(mod(4, 1.5), 1);
approx.equal(mod(0, 3), 0);
});
it('should throw an error if the modulus is negative', function() {
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/);
});
it('should throw an error if used with wrong type of arguments', function() {
assert.throws(function () {mod(1, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {mod(new Date(), bignumber(2));}, /TypeError: Unexpected type of argument/);
});
it('should calculate the modulus of bignumbers', function() {
assert.deepEqual(mod(bignumber(7), bignumber(2)), bignumber(1));
assert.deepEqual(mod(bignumber(7), bignumber(0)), bignumber(7));
assert.deepEqual(mod(bignumber(0), bignumber(3)), bignumber(0));
assert.deepEqual(mod(bignumber(7), bignumber(2)), bignumber(1));
assert.deepEqual(mod(bignumber(8), bignumber(3)).valueOf(), bignumber(2).valueOf());
});
it.skip('should calculate the modulus of bignumbers for fractions', function () {
assert.deepEqual(mod(bignumber(7).div(3), bignumber(1).div(3)), bignumber(0));
});
it.skip('should calculate the modulus of bignumbers for negative values', function () {
assert.deepEqual(mod(bignumber(-10), bignumber(4)), bignumber(2));
});
it('should calculate the modulus of mixed numbers and bignumbers', function() {
assert.deepEqual(mod(bignumber(7), 2), bignumber(1));
assert.deepEqual(mod(bignumber(7), 0), bignumber(7));
assert.deepEqual(mod(8, bignumber(3)), bignumber(2));
assert.deepEqual(mod(7, bignumber(0)), bignumber(7));
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/);
});
it('should calculate the modulus of mixed booleans and bignumbers', function() {
assert.deepEqual(mod(bignumber(7), true), bignumber(0));
assert.deepEqual(mod(bignumber(7), false), bignumber(7));
assert.deepEqual(mod(true, bignumber(3)), bignumber(1));
assert.deepEqual(mod(false, bignumber(3)), bignumber(0));
});
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);
});
it('should convert string to number', function() {
assert.strictEqual(mod('8', '3'), 2);
assert.strictEqual(mod('8', 3), 2);
assert.strictEqual(mod(8, '3'), 2);
assert.throws(function () {mod(5, 'a');}, /Cannot convert "a" to a number/);
});
it('should calculate modulus of two fractions', function() {
var b = math.fraction(8);
var a = mod(b, math.fraction(3));
assert.equal(a.toString(), '2');
assert.equal(b.toString(), '8');
assert(a instanceof math.type.Fraction);
assert.equal(mod(math.fraction(4.55), math.fraction(0.05)).toString(), '0');
});
it('should calculate modulus of mixed fractions and numbers', function() {
assert.deepEqual(mod(8, math.fraction(3)), math.fraction(2));
assert.deepEqual(mod(math.fraction(8), 3), math.fraction(2));
});
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)');
});
});

View File

@@ -0,0 +1,892 @@
// test multiply
var assert = require('assert'),
math = require('../../../index'),
approx = require('../../../tools/approx'),
market = require('../../../tools/matrixmarket'),
multiply = math.multiply,
divide = math.divide,
matrix = math.matrix,
complex = math.complex,
bignumber = math.bignumber,
i = math.i,
unit = math.unit;
describe('multiply', function() {
describe('Scalar', function () {
it('should multiply two numbers correctly', function() {
approx.equal(multiply(2, 3), 6);
approx.equal(multiply(-2, 3), -6);
approx.equal(multiply(-2, -3), 6);
approx.equal(multiply(5, 0), 0);
approx.equal(multiply(0, 5), 0);
approx.deepEqual(multiply(0, Infinity), NaN);
approx.deepEqual(multiply(2, Infinity), Infinity);
approx.deepEqual(multiply(-2, Infinity), -Infinity);
});
it('should multiply booleans', function() {
assert.equal(multiply(true, true), 1);
assert.equal(multiply(true, false), 0);
assert.equal(multiply(false, true), 0);
assert.equal(multiply(false, false), 0);
});
it('should multiply mixed numbers and booleans', function() {
assert.equal(multiply(2, true), 2);
assert.equal(multiply(2, false), 0);
assert.equal(multiply(true, 2), 2);
assert.equal(multiply(false, 2), 0);
});
it('should multiply numbers and null', function () {
assert.equal(multiply(1, null), 0);
assert.equal(multiply(null, 1), 0);
});
it('should multiply bignumbers', function() {
assert.deepEqual(multiply(bignumber(1.5), bignumber(0.2)), bignumber(0.3));
assert.deepEqual(multiply(bignumber('1.3e5000'), bignumber('2')), bignumber('2.6e5000'));
});
it('should multiply mixed numbers and bignumbers', function() {
assert.deepEqual(multiply(bignumber(1.5), 0.2), bignumber(0.3));
assert.deepEqual(multiply(1.5, bignumber(0.2)), bignumber(0.3));
assert.deepEqual(multiply(bignumber('1.3e5000'), 2), bignumber('2.6e5000'));
assert.throws(function () {multiply(1/3, bignumber(1).div(3));}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {multiply(bignumber(1).div(3), 1/3);}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should throw an error when multipling mixed fractions and bignumbers', function() {
assert.throws(function () {multiply(math.bignumber('2'), math.fraction(1,3))}, /Cannot implicitly convert a Fraction to BigNumber/);
assert.throws(function () {multiply(math.fraction(1,3), math.bignumber('2'))}, /Cannot implicitly convert a Fraction to BigNumber/);
});
it('should multiply mixed booleans and bignumbers', function() {
assert.deepEqual(multiply(bignumber(0.3), true), bignumber(0.3));
assert.deepEqual(multiply(bignumber(0.3), false), bignumber(0));
assert.deepEqual(multiply(false, bignumber('2')), bignumber(0));
assert.deepEqual(multiply(true, bignumber('2')), bignumber(2));
});
it('should multiply two complex numbers correctly', function() {
approx.deepEqual(multiply(complex(2, 3), 2), complex(4, 6));
approx.deepEqual(multiply(complex(2, -3), -2), complex(-4, 6));
approx.deepEqual(multiply(complex(2, -3), 2), complex(4, -6));
approx.deepEqual(multiply(complex(-2, 3), 2), complex(-4, 6));
approx.deepEqual(multiply(complex(-2, -3), 2), complex(-4, -6));
approx.deepEqual(multiply(2, complex(2, 3)), complex(4, 6));
approx.deepEqual(multiply(i, complex(2, 3)), complex(-3, 2));
approx.deepEqual(multiply(complex(0, 1), complex(2, 3)), complex(-3, 2));
approx.deepEqual(multiply(complex(1, 1), complex(2, 3)), complex(-1, 5));
approx.deepEqual(multiply(complex(2, 3), complex(1, 1)), complex(-1, 5));
approx.deepEqual(multiply(complex(2, 3), complex(2, 3)), complex(-5, 12));
approx.deepEqual(divide(complex(-5, 12), complex(2, 3)), complex(2, 3));
approx.deepEqual(multiply(complex(2, 3), 0), complex(0, 0));
approx.deepEqual(multiply(complex(0, 3), complex(0, -4)), complex(12, 0));
approx.deepEqual(multiply(multiply(3, i), multiply(-4, i)), complex(12, 0));
approx.deepEqual(multiply(math.i, Infinity), complex(NaN, Infinity));
approx.deepEqual(multiply(Infinity, math.i), complex(NaN, Infinity));
approx.deepEqual(multiply(complex(2,0), complex(0,2)), complex(0, 4));
approx.deepEqual(multiply(complex(0,2), complex(0,2)), -4);
approx.deepEqual(multiply(complex(2,2), complex(0,2)), complex(-4, 4));
approx.deepEqual(multiply(complex(2,0), complex(2,2)), complex(4, 4));
approx.deepEqual(multiply(complex(0,2), complex(2,2)), complex(-4, 4));
approx.deepEqual(multiply(complex(2,2), complex(2,2)), complex(0, 8));
approx.deepEqual(multiply(complex(2,0), complex(2,0)), 4);
approx.deepEqual(multiply(complex(0,2), complex(2,0)), complex(0, 4));
approx.deepEqual(multiply(complex(2,2), complex(2,0)), complex(4, 4));
approx.deepEqual(multiply(complex(2, 3), complex(4, 5)), complex(-7, 22));
approx.deepEqual(multiply(complex(2, 3), complex(4, -5)), complex(23, 2));
approx.deepEqual(multiply(complex(2, 3), complex(-4, 5)), complex(-23, -2));
approx.deepEqual(multiply(complex(2, 3), complex(-4, -5)), complex(7, -22));
approx.deepEqual(multiply(complex(2, -3), complex(4, 5)), complex(23, -2));
approx.deepEqual(multiply(complex(2, -3), complex(4, -5)), complex(-7, -22));
approx.deepEqual(multiply(complex(2, -3), complex(-4, 5)), complex(7, 22));
approx.deepEqual(multiply(complex(2, -3), complex(-4, -5)), complex(-23, 2));
approx.deepEqual(multiply(complex(-2, 3), complex(4, 5)), complex(-23, 2));
approx.deepEqual(multiply(complex(-2, 3), complex(4, -5)), complex(7, 22));
approx.deepEqual(multiply(complex(-2, 3), complex(-4, 5)), complex(-7, -22));
approx.deepEqual(multiply(complex(-2, 3), complex(-4, -5)), complex(23, -2));
approx.deepEqual(multiply(complex(-2, -3), complex(4, 5)), complex(7, -22));
approx.deepEqual(multiply(complex(-2, -3), complex(4, -5)), complex(-23, -2));
approx.deepEqual(multiply(complex(-2, -3), complex(-4, 5)), complex(23, 2));
approx.deepEqual(multiply(complex(-2, -3), complex(-4, -5)), complex(-7, 22));
});
it('should multiply mixed complex numbers and numbers', function() {
assert.deepEqual(multiply(math.complex(6, -4), 2), math.complex(12, -8));
assert.deepEqual(multiply(2, math.complex(2, 4)), math.complex(4, 8));
});
it('should multiply mixed complex numbers and big numbers', function() {
assert.deepEqual(multiply(math.complex(6, -4), math.bignumber(2)), math.complex(12, -8));
assert.deepEqual(multiply(math.bignumber(2), math.complex(2, 4)), math.complex(4, 8));
});
it('should multiply two fractions', function() {
var a = math.fraction(1,4);
assert.equal(multiply(a, math.fraction(1,2)).toString(), '0.125');
assert.equal(a.toString(), '0.25');
assert.equal(multiply(math.fraction(2), math.fraction(1,3)).toString(), '0.(6)');
});
it('should multiply mixed fractions and numbers', function() {
assert.deepEqual(multiply(2, math.fraction(1,3)), math.fraction(2,3));
assert.deepEqual(multiply(math.fraction(1,3), 2), math.fraction(2,3));
});
it('should multiply a number and a unit correctly', function() {
assert.equal(multiply(2, unit('5 mm')).toString(), '10 mm');
assert.equal(multiply(2, unit('5 mm')).toString(), '10 mm');
assert.equal(multiply(10, unit('celsius')).toString(), '10 celsius');
assert.equal(multiply(unit('5 mm'), 2).toString(), '10 mm');
assert.equal(multiply(unit('5 mm'), 0).toString(), '0 mm');
assert.equal(multiply(unit('celsius'), 10).toString(), '10 celsius');
assert.equal(multiply(unit(math.fraction(1,4), 'm'), 3).toString(), '3/4 m');
assert.equal(multiply(3, unit(math.fraction(1,4), 'm')).toString(), '3/4 m');
assert.equal(multiply(math.fraction(1,4), unit(3, 'm')).toString(), '3/4 m');
assert.equal(multiply(unit(3, 'm'), math.fraction(1,4)).toString(), '3/4 m');
assert.equal(multiply(unit(math.complex(9, 8), 'm'), 2).toString(), '(18 + 16i) m');
assert.equal(math.format(multiply(unit(math.complex(2, 3), 'g'), math.complex(4, 5)), 14), '(-7 + 22i) g');
});
it('should multiply a number and a unit without value correctly', function() {
assert.equal(multiply(2, unit('mm')).toString(), '2 mm');
assert.equal(multiply(2, unit('km')).toString(), '2 km');
assert.equal(multiply(2, unit('inch')).toString(), '2 inch');
assert.equal(multiply(unit('mm'), 2).toString(), '2 mm');
assert.equal(multiply(unit('km'), 2).toString(), '2 km');
assert.equal(multiply(unit('inch'), 2).toString(), '2 inch');
});
it('should multiply two units correctly', function() {
assert.equal(multiply(unit('2 m'), unit('4 m')).toString(), '8 m^2');
assert.equal(multiply(unit('2 ft'), unit('4 ft')).toString(), '8 ft^2');
assert.equal(multiply(unit('65 mi/h'), unit('2 h')).to('mi').toString(), '130 mi');
assert.equal(multiply(unit('2 L'), unit('1 s^-1')).toString(), '2 L / s');
assert.equal(multiply(unit('2 m/s'), unit('0.5 s/m')).toString(), '1');
assert.equal(multiply(unit(math.complex(3,-4), 'N'), unit(math.complex(7,-2), 'm')).toString(), '(13 - 34i) J');
});
it('should multiply valueless units correctly', function() {
assert.equal(multiply(unit('m'), unit('4 m')).toString(), '4 m^2');
assert.equal(multiply(unit('ft'), unit('4 ft')).format(5), '4 ft^2');
assert.equal(multiply(unit('65 mi/h'), unit('h')).to('mi').toString(), '65 mi');
assert.equal(multiply(unit('2 L'), unit('s^-1')).toString(), '2 L / s');
assert.equal(multiply(unit('m/s'), unit('h/m')).toString(), '(m h) / (s m)');
});
// TODO: cleanup once decided to not downgrade BigNumber to number
it.skip('should multiply a bignumber and a unit correctly', function() {
assert.equal(multiply(bignumber(2), unit('5 mm')).toString(), '10 mm');
assert.equal(multiply(bignumber(2), unit('5 mm')).toString(), '10 mm');
assert.equal(multiply(unit('5 mm'), bignumber(2)).toString(), '10 mm');
assert.equal(multiply(unit('5 mm'), bignumber(0)).toString(), '0 m');
});
// TODO: cleanup once decided to not downgrade BigNumber to number
it.skip('should multiply a bignumber and a unit without value correctly', function() {
assert.equal(multiply(bignumber(2), unit('mm')).toString(), '2 mm');
assert.equal(multiply(bignumber(2), unit('km')).toString(), '2 km');
assert.equal(multiply(bignumber(2), unit('inch')).toString(), '2 inch');
assert.equal(multiply(unit('mm'), bignumber(2)).toString(), '2 mm');
assert.equal(multiply(unit('km'), bignumber(2)).toString(), '2 km');
assert.equal(multiply(unit('inch'), bignumber(2)).toString(), '2 inch');
});
it('should throw an error in case of unit non-numeric argument', function() {
// Multiplying two units is supported now
//assert.throws(function () {multiply(math.unit('5cm'), math.unit('4cm'));}, /TypeError: Unexpected type/);
// Complex units are supported now
//assert.throws(function () {multiply(math.unit('5cm'), math.complex('2+3i'));}, /TypeError: Unexpected type/);
//assert.throws(function () {multiply(math.complex('2+3i'), math.unit('5cm'));}, /TypeError: Unexpected type/);
});
it('should throw an error if used with strings', function() {
assert.throws(function () {multiply("hello", "world");});
assert.throws(function () {multiply("hello", 2);});
});
});
it('should multiply mixed array and matrix', function () {
var a = [[1, 2], [3, 4]];
var b = [[2, 0], [0, 2]];
approx.deepEqual(multiply(a, matrix(b)), matrix([[2, 4], [6, 8]]));
approx.deepEqual(multiply(matrix(a), b), matrix([[2, 4], [6, 8]]));
// test with vectors, returning a scalar
var c = [1, 2, 3];
var d = [4, 5, 6];
assert.strictEqual(multiply(c, matrix(d)), 32);
assert.strictEqual(multiply(matrix(c), d), 32);
});
describe('squeeze', function () {
// math.js v1 and v2 did squeeze output being a vector. Changed in v3
it ('should NOT squeeze scalar results of matrix * matrix', function () {
var a = [[1, 2, 3]];
var b = [[4], [5], [6]];
assert.deepEqual(multiply(a, b), [[32]]);
});
it ('should NOT squeeze scalar results of vector * matrix', function () {
var a = [1, 2, 3];
var b = [[4], [5], [6]];
assert.deepEqual(multiply(a, b), [32]);
});
it ('should NOT squeeze scalar results of matrix * vector', function () {
var a = [[1, 2, 3]];
var b = [4, 5, 6];
assert.deepEqual(multiply(a, b), [32]);
});
});
it('should throw an error when multiplying matrices with incompatible sizes', function() {
// vector * vector
assert.throws(function () {multiply([1,1], [1,1, 1]);});
// matrix * matrix
assert.throws(function () {multiply([[1,1]], [[1,1]]);});
assert.throws(function () {multiply([[1,1]], [[1,1], [1,1], [1,1]]);});
// matrix * vector
assert.throws(function () {multiply([[1,1], [1,1]], [1,1,1]);});
// vector * matrix
assert.throws(function () {multiply([1,1,1], [[1,1], [1,1]]);});
});
it('should throw an error when multiplying multi dimensional matrices', function() {
assert.throws(function () {multiply([[[1]]], [1]);});
assert.throws(function () {multiply([[[1]]], [[1]]);});
assert.throws(function () {multiply([1], [[[1]]]);});
assert.throws(function () {multiply([[1]], [[[1]]]);});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {multiply(1);}, /TypeError: Too few arguments/);
});
describe('Vector', function () {
it('should multiply vectors correctly (dot product)', function () {
var a = [1, 2, 3];
var b = [4, 5, 6];
approx.deepEqual(multiply(a, b), 32);
approx.deepEqual(multiply(matrix(a), matrix(b)), 32);
});
it('should multiply row vector x column vector', function () {
var v = [[1, 2, 3, 0, 0, 5, 6]];
var r = multiply(v, [[3], [4], [6], [0], [1], [2], [0]]);
assert.deepEqual(r, [[39]]);
r = multiply(v, math.matrix([[3], [4], [6], [0], [1], [2], [0]], 'dense'));
assert.deepEqual(r, math.matrix([[39]], 'dense'));
r = multiply(v, math.matrix([[3], [4], [6], [0], [1], [2], [0]], 'sparse'));
assert.deepEqual(r, math.matrix([[39]], 'sparse'));
});
it('should multiply dense row vector x column vector', function () {
var v = math.matrix([[1, 2, 3, 0, 0, 5, 6]], 'dense');
var r = multiply(v, [[3], [4], [6], [0], [1], [2], [0]]);
assert.deepEqual(r, math.matrix([[39]]));
r = multiply(v, math.matrix([[3], [4], [6], [0], [1], [2], [0]], 'dense'));
assert.deepEqual(r, math.matrix([[39]]));
r = multiply(v, math.matrix([[3], [4], [6], [0], [1], [2], [0]], 'sparse'));
assert.deepEqual(r, math.matrix([[39]], 'sparse'));
});
it('should throw an error when multiplying empty vectors', function () {
assert.throws(function () {multiply([], []);}, /Cannot multiply two empty vectors/);
});
it('should multiply a vector with a matrix correctly', function () {
var a = [1, 2, 3];
var b = [
[8, 1, 6],
[3, 5, 7],
[4, 9, 2]
];
approx.deepEqual(multiply(a, b), [26, 38, 26]);
approx.deepEqual(multiply(b, a), [28, 34, 28]);
approx.deepEqual(multiply(matrix(a), matrix(b)), matrix([26, 38, 26]));
approx.deepEqual(multiply(matrix(b), matrix(a)), matrix([28, 34, 28]));
});
});
describe('Dense Matrix', function () {
it('should multiply matrix x scalar', function() {
var m = math.matrix([
[2, 0],
[4, 0]
]);
var r = multiply(m, 3);
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._data, [[6, 0], [12, 0]]);
r = multiply(m, math.complex(3, 3));
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._data, [[math.complex(6, 6), math.complex(0, 0)], [math.complex(12, 12), math.complex(0, 0)]]);
r = multiply(m, math.bignumber(3));
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._data, [[math.bignumber(6), math.bignumber(0)], [math.bignumber(12), math.bignumber(0)]]);
r = multiply(m, true);
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._data, [[2, 0], [4, 0]]);
r = multiply(m, false);
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._data, [[0, 0], [0, 0]]);
});
it('should multiply matrix x matrix with zeros', function() {
var m = math.matrix([
[2, 0],
[4, 0]
]);
var r = multiply(m, math.matrix([
[2, 0],
[4, 0]
]));
assert.deepEqual(
r.valueOf(),
[
[4, 0],
[8, 0]
]);
r = multiply(m, math.matrix([
[2, 0],
[4, 0]
], 'sparse'));
assert.deepEqual(
r.valueOf(),
[
[4, 0],
[8, 0]
]);
});
it('should multiply matrix x matrix', function() {
var m = math.matrix([[1, 2], [3, 4]], 'dense');
var r = multiply(m, math.matrix([[5, 6], [7, 8]], 'sparse'));
assert.deepEqual(
r.valueOf(),
[
[19, 22],
[43, 50]
]);
r = multiply(m, math.matrix([[5, 6], [7, 8]], 'dense'));
assert.deepEqual(
r.valueOf(),
[
[19, 22],
[43, 50]
]);
});
it('should multiply matrix x matrix, number datatype', function() {
var m1 = math.matrix([[1, 2], [3, 4]], 'dense', 'number');
var m2 = math.matrix([[5, 6], [7, 8]], 'dense', 'number');
var r = multiply(m1, m2);
assert(r.datatype() === 'number');
assert.deepEqual(
r.valueOf(),
[
[19, 22],
[43, 50]
]);
});
it('should multiply matrix x array', function() {
var m = math.matrix([
[2, 0],
[4, 0]
]);
var r = multiply(
m,
[
[2, 0],
[4, 0]
]);
assert.deepEqual(
r.valueOf(),
[
[4, 0],
[8, 0]
]);
r = multiply(
m,
[
[2, 0, 1],
[4, 0, 1]
]);
assert.deepEqual(
r.valueOf(),
[
[4, 0, 2],
[8, 0, 4]
]);
});
it('should multiply matrix x vector array', function() {
var m = math.matrix([
[2, 0],
[4, 0]
]);
var r = multiply(
m,
[
[2],
[4]
]);
assert.deepEqual(
r.valueOf(),
[
[4],
[8]
]);
});
it ('should NOT squeeze scalar results of matrix * matrix', function () {
var a = math.matrix(
[
[1, 2, 3]
]);
var b = math.matrix(
[
[4],
[5],
[6]
]);
assert.deepEqual(multiply(a, b), math.matrix([[32]]));
});
it ('should NOT squeeze scalar results of matrix * vector', function () {
var a = math.matrix(
[
[1, 2, 3]
]);
var b = [4, 5, 6];
assert.deepEqual(multiply(a, b), math.matrix([32]));
});
it('should throw an error when multiplying matrices with incompatible sizes', function() {
// vector * vector
assert.throws(function () {multiply(math.matrix([1,1], 'dense'), [1, 1, 1]);});
// matrix * matrix
assert.throws(function () {multiply(math.matrix([[1,1]], 'dense'), [[1,1]]);});
assert.throws(function () {multiply(math.matrix([[1,1]], 'dense'), [[1,1], [1,1], [1,1]]);});
// matrix * vector
assert.throws(function () {multiply(math.matrix([[1,1], [1,1]], 'dense'), [1,1,1]);});
// vector * matrix
assert.throws(function () {multiply(math.matrix([1,1,1], 'dense'), [[1,1], [1,1]]);});
});
it('should multiply triangular matrices', function () {
var l = [
[1, 0, 0, 0],
[-0.5, 1, 0, 0],
[0, -0.7, 1, 0],
[0.0666667, -0.4, -0.5714286, 1]
];
var u = [
[240, -2700, 6480, -4200],
[0, -150, 540, -420],
[0, 0, -42, 56],
[0, 0, 0, 4]
];
var r = multiply(l, u);
approx.deepEqual(
r.valueOf(),
[
[240, -2700, 6480, -4200],
[-120, 1200, -2700, 1680],
[0, 105, -420, 350],
[16, -120, 240, -140]
]);
});
var a = matrix([[1,2],[3,4]]);
var b = matrix([[5,6],[7,8]]);
var c = matrix([[5],[6]]);
var d = matrix([[5,6]]);
it('should perform element-wise multiplication if multiplying a matrix and a number', function() {
approx.deepEqual(multiply(a, 3), matrix([[3,6],[9,12]]));
approx.deepEqual(multiply(3, a), matrix([[3,6],[9,12]]));
});
it('should perform matrix multiplication', function () {
approx.deepEqual(multiply(a, b), matrix([[19,22],[43,50]]));
approx.deepEqual(multiply(a, c), matrix([[17],[39]]));
approx.deepEqual(multiply(d, a), matrix([[23,34]]));
approx.deepEqual(multiply(d, b), matrix([[67,78]]));
approx.deepEqual(multiply(d, c), matrix([[61]]));
approx.deepEqual(multiply([[1,2],[3,4]], [[5,6],[7,8]]), [[19,22],[43,50]]);
approx.deepEqual(multiply([1,2,3,4], 2), [2, 4, 6, 8]);
approx.deepEqual(multiply(matrix([1,2,3,4]), 2), matrix([2, 4, 6, 8]));
});
});
describe('Sparse Matrix', function () {
it('should multiply matrix x scalar', function() {
var m = math.matrix([[2, 0], [4, 0]], 'sparse');
var r = multiply(m, 3);
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._values, [6, 12]);
assert.deepEqual(r._index, m._index);
assert.deepEqual(r._ptr, m._ptr);
r = multiply(m, math.complex(3, 3));
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._values, [math.complex(6, 6), math.complex(12, 12)]);
assert.deepEqual(r._index, m._index);
assert.deepEqual(r._ptr, m._ptr);
r = multiply(m, math.bignumber(3));
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._values, [math.bignumber(6), math.bignumber(12)]);
assert.deepEqual(r._index, m._index);
assert.deepEqual(r._ptr, m._ptr);
r = multiply(m, true);
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._values, [2, 4]);
assert.deepEqual(r._index, m._index);
assert.deepEqual(r._ptr, m._ptr);
r = multiply(m, false);
assert.deepEqual(r._size, m._size);
assert.deepEqual(r._values, []);
assert.deepEqual(r._index, []);
assert.deepEqual(r._ptr, [0, 0, 0]);
});
it('should multiply matrix x matrix with zeros', function() {
var m = math.matrix([[2, 0], [4, 0]], 'sparse');
var r = multiply(m, math.matrix([[2, 0], [4, 0]], 'sparse'));
assert.deepEqual(
r.valueOf(),
[
[4, 0],
[8, 0]
]);
r = multiply(m, math.matrix([[2, 0], [4, 0]], 'dense'));
assert.deepEqual(
r.valueOf(),
[
[4, 0],
[8, 0]
]);
});
it('should multiply matrix x matrix', function() {
var m = math.matrix([[1, 2], [3, 4]], 'sparse');
var r = multiply(m, math.matrix([[5, 6], [7, 8]], 'sparse'));
assert.deepEqual(
r.valueOf(),
[
[19, 22],
[43, 50]
]);
r = multiply(m, math.matrix([[5, 6], [7, 8]], 'dense'));
assert.deepEqual(
r.valueOf(),
[
[19, 22],
[43, 50]
]);
});
it('should multiply matrix x matrix, number datatype', function() {
var m1 = math.matrix([[1, 2], [3, 4]], 'sparse', 'number');
var m2 = math.matrix([[5, 6], [7, 8]], 'sparse', 'number');
var r = multiply(m1, m2);
assert(r.datatype() === 'number');
assert.deepEqual(
r.valueOf(),
[
[19, 22],
[43, 50]
]);
});
it('should multiply matrix x array', function() {
var m = math.matrix([[2, 0], [4, 0]], 'sparse');
var r = multiply(m,
[
[2, 0],
[4, 0]
]);
assert.deepEqual(
r.valueOf(),
[
[4, 0],
[8, 0]
]);
r = multiply(m,
[
[2, 0, 1],
[4, 0, 1]
]);
assert.deepEqual(
r.valueOf(),
[
[4, 0, 2],
[8, 0, 4]
]);
});
it('should multiply matrix x vector array', function() {
var m = math.matrix([[2, 0], [4, 0]], 'sparse');
var r = multiply(m,
[
[2],
[4]
]);
assert.deepEqual(
r.valueOf(),
[
[4],
[8]
]);
});
it ('should NOT squeeze scalar results of matrix * matrix', function () {
var a = math.matrix([[1, 2, 3]], 'sparse');
var b = math.matrix([[4], [5], [6]], 'sparse');
assert.deepEqual(multiply(a, b), math.matrix([[32]], 'sparse'));
});
it ('should NOT squeeze scalar results of matrix * vector', function () {
var a = math.matrix([[1, 2, 3]], 'sparse');
var b = [4, 5, 6];
assert.deepEqual(multiply(a, b), math.matrix([32], 'sparse'));
});
it('should throw an error when multiplying matrices with incompatible sizes', function() {
// vector * vector
assert.throws(function () {math.matrix([1,1], 'sparse').multiply([1, 1, 1]);});
// matrix * matrix
assert.throws(function () {math.matrix([[1,1]], 'sparse').multiply([[1,1]]);});
assert.throws(function () {math.matrix([[1,1]], 'sparse').multiply([[1,1], [1,1], [1,1]]);});
// matrix * vector
assert.throws(function () {math.matrix([[1,1], [1,1]], 'sparse').multiply([1,1,1]);});
// vector * matrix
assert.throws(function () {math.matrix([1,1,1], 'sparse').multiply([[1,1], [1,1]]);});
});
it('should multiply triangular matrices', function () {
var l = math.matrix([
[1, 0, 0, 0],
[-0.5, 1, 0, 0],
[0, -0.7, 1, 0],
[0.0666667, -0.4, -0.5714286, 1]
], 'sparse');
var u = math.matrix([
[240, -2700, 6480, -4200],
[0, -150, 540, -420],
[0, 0, -42, 56],
[0, 0, 0, 4]
], 'sparse');
var r = multiply(l, u);
assert(r.storage(), 'sparse');
approx.deepEqual(
r.valueOf(),
[
[240, -2700, 6480, -4200],
[-120, 1200, -2700, 1680],
[0, 105, -420, 350],
[16, -120, 240, -140]
]);
});
var a = matrix([[1,2],[3,4]], 'sparse');
var b = matrix([[5,6],[7,8]], 'sparse');
var c = matrix([[5],[6]], 'sparse');
var d = matrix([[5,6]], 'sparse');
it('should perform element-wise multiplication if multiplying a matrix and a number', function() {
approx.deepEqual(multiply(a, 3), matrix([[3,6],[9,12]], 'sparse'));
approx.deepEqual(multiply(3, a), matrix([[3,6],[9,12]], 'sparse'));
});
it('should perform matrix multiplication', function () {
approx.deepEqual(multiply(a, b), matrix([[19,22],[43,50]], 'sparse'));
approx.deepEqual(multiply(a, c), matrix([[17],[39]], 'sparse'));
approx.deepEqual(multiply(d, a), matrix([[23,34]], 'sparse'));
approx.deepEqual(multiply(d, b), matrix([[67,78]], 'sparse'));
approx.deepEqual(multiply(d, c), matrix([[61]], 'sparse'));
});
it('should multiply two pattern matrices correctly', function() {
var a = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 0],
ptr: [0, 2, 3, 4],
size: [3, 3]
});
var b = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 1],
ptr: [0, 3, 3, 4],
size: [3, 3]
});
var c = multiply(a, b);
assert.deepEqual(
c.valueOf(),
[
[1, 0, 0],
[1, 0, 0],
[1, 0, 1]
]);
});
it('should multiply pattern and value matrices correctly', function() {
var a = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 0],
ptr: [0, 2, 3, 4],
size: [3, 3]
});
var b = new math.type.SparseMatrix({
values: [1, 2, 3, 4],
index: [0, 1, 2, 1],
ptr: [0, 3, 3, 4],
size: [3, 3]
});
var c = multiply(a, b);
assert.deepEqual(
c.valueOf(),
[
[1, 0, 0],
[1, 0, 0],
[1, 0, 1]
]);
});
it('should multiply value and pattern matrices correctly', function() {
var a = new math.type.SparseMatrix({
values: [1, 2, 3, 4],
index: [0, 1, 2, 0],
ptr: [0, 2, 3, 4],
size: [3, 3]
});
var b = new math.type.SparseMatrix({
values: undefined,
index: [0, 1, 2, 1],
ptr: [0, 3, 3, 4],
size: [3, 3]
});
var c = multiply(a, b);
assert.deepEqual(
c.valueOf(),
[
[1, 0, 0],
[1, 0, 0],
[1, 0, 1]
]);
});
});
describe('Matrix Market', function () {
it('should multiply matrix x matrix 1220 x 1220, Matrix Market, sparse x sparse', function (done) {
// import matrix
market.import('tools/matrices/fpga_dcop_01.tar.gz', ['fpga_dcop_01/fpga_dcop_01.mtx'])
.then(function (matrices) {
// matrix
var m = matrices[0];
// multiply matrices, used to compare performance in different implementations
math.multiply(m, m);
// indicate test has completed
done();
})
.fail(function (error) {
// indicate test has completed
done(error);
});
});
});
describe ('multiple arguments', function () {
it ('should multiply more than two arguments', function () {
assert.deepEqual(multiply(2, 3, 4), 24);
assert.deepEqual(multiply(2, 3, [5,6]), [30,36]);
});
});
it('should LaTeX multiply', function () {
var expression = math.parse('multiply(2,3)');
assert.equal(expression.toTex(), '\\left(2\\cdot3\\right)');
});
});

View File

@@ -0,0 +1,113 @@
// test norm
var assert = require('assert'),
math = require('../../../index');
describe('norm', function () {
it('should return the absolute value of a boolean', function () {
assert.equal(math.norm(true), 1);
assert.equal(math.norm(true, 10), 1);
assert.equal(math.norm(false), 0);
assert.equal(math.norm(false, 10), 0);
});
it('should return the absolute value of null', function () {
assert.equal(math.norm(null), 0);
assert.equal(math.norm(null, 10), 0);
});
it('should return the absolute value of a number', function () {
assert.equal(math.norm(-4.2), 4.2);
assert.equal(math.norm(-3.5), 3.5);
assert.equal(math.norm(100), 100);
assert.equal(math.norm(0), 0);
assert.equal(math.norm(100, 10), 100);
});
it('should return the absolute value of a big number', function () {
assert.deepEqual(math.norm(math.bignumber(-2.3)), math.bignumber(2.3));
assert.deepEqual(math.norm(math.bignumber('5e500')), math.bignumber('5e500'));
assert.deepEqual(math.norm(math.bignumber('-5e500')), math.bignumber('5e500'));
});
it('should return the norm of a complex number', function () {
assert.equal(math.norm(math.complex(3, -4)), 5);
assert.equal(math.norm(math.complex(1e200, -4e200)), 4.12310562561766e+200);
assert.equal(math.norm(math.complex(-4e200, 1e200)), 4.12310562561766e+200);
});
it('should return the norm of a vector', function () {
// empty vector
assert.equal(math.norm([]), 0.0);
assert.equal(math.norm(math.matrix([])), 0.0);
// p = Infinity
assert.equal(math.norm([1, 2, -3], Number.POSITIVE_INFINITY), 3);
assert.equal(math.norm(math.matrix([1, 2, -3]), Number.POSITIVE_INFINITY), 3);
assert.equal(math.norm([1, 2, -3], 'inf'), 3);
assert.equal(math.norm(math.matrix([1, 2, -3]), 'inf'), 3);
// p = -Infinity
assert.equal(math.norm([1, 2, -3], Number.NEGATIVE_INFINITY), 1);
assert.equal(math.norm(math.matrix([1, 2, -3]), Number.NEGATIVE_INFINITY), 1);
assert.equal(math.norm([1, 2, -3], '-inf'), 1);
assert.equal(math.norm(math.matrix([1, 2, -3]), '-inf'), 1);
// p == 1
assert.equal(math.norm([-3, -4], 1), 7.0);
assert.equal(math.norm(math.matrix([-3, -4]), 1), 7.0);
// p - positive
assert.equal(math.norm([3, 4], 2), 5.0);
assert.equal(math.norm(math.matrix([3, 4]), 2), 5.0);
// p - negative
assert.equal(math.norm([3, 4], -2), 2.4);
assert.equal(math.norm(math.matrix([3, 4]), -2), 2.4);
// missing p (defaults to 2)
assert.equal(math.norm([3, 4]), 5.0);
assert.equal(math.norm(math.matrix([3, 4])), 5.0);
// p == 'fro'
assert.equal(math.norm([3, 4], 'fro'), 5.0);
assert.equal(math.norm(math.matrix([3, 4]), 'fro'), 5.0);
// p == 0
assert.equal(math.norm([3, 4], 0), Number.POSITIVE_INFINITY);
assert.equal(math.norm(math.matrix([3, 4]), 0), Number.POSITIVE_INFINITY);
});
it('should return the norm of a matrix', function () {
// p = 1
assert.equal(math.norm([[1, 2], [3, 4]], 1), 6);
assert.equal(math.norm(math.matrix([[1, 2], [3, 4]]), 1), 6);
assert.equal(math.norm(math.matrix([[1, 2], [3, 4]], 'sparse'), 1), 6);
// p = Infinity
assert.equal(math.norm([[1, 2], [3, 4]], Number.POSITIVE_INFINITY), 7);
assert.equal(math.norm(math.matrix([[1, 2], [3, 4]]), Number.POSITIVE_INFINITY), 7);
assert.equal(math.norm(math.matrix([[1, 2], [3, 4]], 'sparse'), Number.POSITIVE_INFINITY), 7);
assert.equal(math.norm([[1, 2], [3, 4]], 'inf'), 7);
assert.equal(math.norm(math.matrix([[1, 2], [3, 4]]), 'inf'), 7);
assert.equal(math.norm(math.matrix([[1, 2], [3, 4]], 'sparse'), 'inf'), 7);
// p = 'fro'
assert.equal(math.norm([[1, 2], [-3, -4]], 'fro'), math.sqrt(30));
assert.equal(math.norm(math.matrix([[1, 2], [-3, -4]]), 'fro'), math.sqrt(30));
assert.equal(math.norm(math.matrix([[1, 2], [-3, -4]], 'sparse'), 'fro'), math.sqrt(30));
// p - not implemented yet!
assert.throws(function() {
math.norm(math.norm([[1, 2], [3, 4]], 2), 6);
});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {math.norm();}, /TypeError: Too few arguments/);
assert.throws(function () {math.norm(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error with a string', function () {
assert.throws(function () {
math.norm('a string');
});
});
it('should LaTeX norm', function () {
var expr1 = math.parse('norm(a)');
var expr2 = math.parse("norm(a,2)");
assert.equal(expr1.toTex(), '\\left\\| a\\right\\|');
assert.equal(expr2.toTex(), '\\mathrm{norm}\\left( a,2\\right)');
});
});

View File

@@ -0,0 +1,210 @@
// test nthRoot
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var matrix = math.matrix;
var sparse = math.sparse;
var unit = math.unit;
var nthRoot = math.nthRoot;
var big = math.bignumber;
var complex = math.complex;
describe('nthRoot', function() {
it('should return the nthRoot of a boolean value', function () {
assert.equal(nthRoot(true), 1);
assert.equal(nthRoot(false), 0);
assert.equal(nthRoot(1,true), 1);
});
it('should return the nthRoot of null', function () {
assert.equal(nthRoot(null), 0);
});
it('should return the nthRoot for numbers', function() {
approx.equal(nthRoot(4), 2);
approx.equal(nthRoot(9), 3);
approx.equal(nthRoot(8, 3), 2);
approx.equal(nthRoot(64, 3), 4);
approx.equal(nthRoot(2, 2.5), 1.31950791077289);
approx.equal(nthRoot(2.5, 2), 1.58113883008419);
approx.equal(nthRoot(0.1+0.2), 0.5477225575051662); // a value containing a round-off error
approx.equal(nthRoot(0, 3), 0);
approx.equal(nthRoot(0, 2), 0);
approx.equal(nthRoot(0.0001, 3), 0.0464158883361278);
});
it('should return the nthRoot for very large numbers', function() {
approx.equal(nthRoot(2e150 * 2e150), 2e150);
approx.equal(nthRoot(Math.pow(2, 1000)), 3.273390607896142e+150);
});
it('should return the nthRoot for small large numbers', function() {
approx.equal(nthRoot(4e-300), 2e-150);
});
it('should return the nthRoot for negative numbers', function() {
approx.equal(nthRoot(-64, 3), -4);
approx.equal(nthRoot(-8, 3), -2);
// Newton's method fails in this particular case: --ericman314
approx.equal(nthRoot(-2, 3), -1.2599210498949);
});
it('should return the nthRoot for negative roots', function() {
approx.equal(nthRoot(64, -3), 0.25);
approx.equal(nthRoot(-64, -3), -0.25);
});
it('should return the nthRoot for zero', function() {
assert.equal(nthRoot(0, 2), 0);
assert.equal(nthRoot(0, -2), Infinity);
});
it('should return the nthRoot for infinity', function() {
approx.equal(nthRoot(Infinity, 2), Infinity);
approx.equal(nthRoot(-Infinity, 3), -Infinity);
approx.equal(nthRoot(Infinity, -3), 0);
});
it('should throw an error when n is zero', function() {
assert.throws(function () {nthRoot(4, 0);}, /Root must be non-zero/);
});
it('should throw an error when value is negative and root is even', function() {
assert.throws(function () {nthRoot(-27, 2);}, /Root must be odd when a is negative/);
assert.throws(function () {nthRoot(-27, 2.5);}, /Root must be odd when a is negative/);
});
it('should throw an error if invalid number of arguments', function() {
assert.throws(function () {nthRoot();}, /TypeError: Too few arguments/);
assert.throws(function () {nthRoot(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should return the nthRoot of bignumbers', function() {
assert.deepEqual(nthRoot(big(4)), big(2));
assert.deepEqual(nthRoot(big(9)), big(3));
assert.deepEqual(nthRoot(big(8), big(3)), big(2));
assert.deepEqual(nthRoot(big(64), big(3)), big(4));
});
it('should return the nthRoot of negative bignumber values', function() {
assert.deepEqual(nthRoot(big(-2), big(3)), big('-1.259921049894873164767210607278228350570251464701507980081975112'));
assert.deepEqual(nthRoot(big(-64), big(3)), big(-4));
});
it('should return the nthRoot of negative bignumber roots', function() {
assert.deepEqual(nthRoot(big(64), big(-3)), big(0.25));
assert.deepEqual(nthRoot(big(-64), big(3)), big(-4));
assert.deepEqual(nthRoot(big(-64), big(-3)), big(-0.25));
});
it('should return the nthRoot for bignumber zero', function() {
assert.deepEqual(nthRoot(big(0), big(2)).toString(), '0');
assert.deepEqual(nthRoot(big(0), big(-2)).toString(), 'Infinity');
});
it('should return the nthRoot for bignumber infinity', function() {
assert.deepEqual(nthRoot(big(Infinity), big(2)).toString(), 'Infinity');
assert.deepEqual(nthRoot(big(-Infinity), big(3)).toString(), '-Infinity');
assert.deepEqual(nthRoot(big(Infinity), big(-3)), big(0));
});
it('should return an array of Complex Roots in Polar form', function() {
var roots = nthRoot(complex("-1"), 6);
var roots1 = [
{r: 1, phi: Math.PI/6},
{r: 1, phi: Math.PI/2},
{r: 1, phi: (5 * Math.PI)/6},
{r: 1, phi: (7 * Math.PI)/6},
{r: 1, phi: (9 * Math.PI)/6},
{r: 1, phi: (11 * Math.PI)/6}
];
roots.forEach(function (value, index, array) {
assert.equal(value.r, roots1[index].r);
assert.equal(value.phi, roots1[index].phi);
});
});
it('should throw an error when used with a complex number and root is less than 0', function() {
assert.throws(function () {nthRoot(complex("-1"), -1);});
});
it('should throw an error when used with a complex number and root is not an integer', function() {
assert.throws(function() {nthRoot(complex("-1 + 2i"), 0.5);});
});
it('should throw an error when used on a unit', function() {
assert.throws(function () {nthRoot(unit('5cm'));});
});
it('should throw an error when used on a string', function() {
assert.throws(function () {nthRoot('text');});
});
describe('Array', function () {
it('should return the nthRoot for array - scalar', function () {
approx.deepEqual(nthRoot([8, 27, 64], 3), [2, 3, 4]);
approx.deepEqual(nthRoot(64, [2, 3, 8]), [8, 4, 1.6817928305074290860622509524664]);
});
it('should return the nthRoot for array - array', function () {
approx.deepEqual(nthRoot([[64, 3125], [0, -1]], [[3, 5], [1, 3]]), [[4, 5], [0, -1]]);
});
it('should return the nthRoot for array - dense matrix', function () {
approx.deepEqual(nthRoot([[64, 3125], [0, -1]], matrix([[3, 5], [1, 3]])), matrix([[4, 5], [0, -1]]));
});
it('should return the nthRoot for array - sparse matrix', function () {
approx.deepEqual(nthRoot([[64, 3125], [0, -1]], sparse([[3, 5], [1, 3]])), matrix([[4, 5], [0, -1]]));
});
});
describe('DenseMatrix', function () {
it('should return the nthRoot for dense matrix - scalar', function () {
approx.deepEqual(nthRoot(matrix([8, 27, 64]), 3), matrix([2, 3, 4]));
approx.deepEqual(nthRoot(64, matrix([2, 3, 8])), matrix([8, 4, 1.6817928305074290860622509524664]));
});
it('should return the nthRoot for dense matrix - array', function () {
approx.deepEqual(nthRoot(matrix([[64, 3125], [0, -1]]), [[3, 5], [1, 3]]), matrix([[4, 5], [0, -1]]));
});
it('should return the nthRoot for dense matrix - dense matrix', function () {
approx.deepEqual(nthRoot(matrix([[64, 3125], [0, -1]]), matrix([[3, 5], [1, 3]])), matrix([[4, 5], [0, -1]]));
});
it('should return the nthRoot for dense matrix - sparse matrix', function () {
approx.deepEqual(nthRoot(matrix([[64, 3125], [0, -1]]), sparse([[3, 5], [1, 3]])), matrix([[4, 5], [0, -1]]));
});
});
describe('SparseMatrix', function () {
it('should return the nthRoot for sparse matrix - scalar', function () {
approx.deepEqual(nthRoot(sparse([[8, 27], [0, 64]]), 3), sparse([[2, 3], [0, 4]]));
approx.deepEqual(nthRoot(64, sparse([[2, 3], [1, 8]])), sparse([[8, 4], [64, 1.6817928305074290860622509524664]]));
});
it('should return the nthRoot for sparse matrix - array', function () {
approx.deepEqual(nthRoot(sparse([[64, 3125], [0, -1]]), [[3, 5], [1, 3]]), sparse([[4, 5], [0, -1]]));
});
it('should return the nthRoot for sparse matrix - dense matrix', function () {
approx.deepEqual(nthRoot(sparse([[64, 3125], [0, -1]]), matrix([[3, 5], [1, 3]])), sparse([[4, 5], [0, -1]]));
});
it('should return the nthRoot for sparse matrix - sparse matrix', function () {
approx.deepEqual(nthRoot(sparse([[64, 3125], [0, -1]]), sparse([[3, 5], [1, 3]])), sparse([[4, 5], [0, -1]]));
});
});
it('should LaTeX nthRoot', function () {
var expression = math.parse('nthRoot(8,3)');
assert.equal(expression.toTex(), '\\sqrt[3]{8}');
});
});

View File

@@ -0,0 +1,243 @@
// test exp
var assert = require('assert');
var approx = require('../../../tools/approx');
var error = require('../../../lib/error/index');
var math = require('../../../index');
var mathPredictable = math.create({predictable: true});
var bignumber = math.bignumber;
var fraction = math.fraction;
var complex = math.complex;
var matrix = math.matrix;
var unit = math.unit;
var range = math.range;
var pow = math.pow;
describe('pow', function() {
it('should exponentiate a number to the given power', function() {
approx.deepEqual(pow(2,3), 8);
approx.deepEqual(pow(2,4), 16);
approx.deepEqual(pow(-2,2), 4);
approx.deepEqual(pow(3,3), 27);
approx.deepEqual(pow(3,-2), 0.111111111111111);
approx.deepEqual(pow(-3,-2), 0.111111111111111);
approx.deepEqual(pow(3,-3), 0.0370370370370370);
approx.deepEqual(pow(-3,-3), -0.0370370370370370);
approx.deepEqual(pow(2,1.5), 2.82842712474619);
});
it('should exponentiate a negative number to a non-integer power', function() {
approx.deepEqual(pow(-2,1.5), complex(0, -2.82842712474619));
});
it('should exponentiate a negative number to a non-integer power with predictable:true', function() {
var res = mathPredictable.pow(-2,1.5);
assert.equal(typeof res, 'number');
assert(isNaN(res));
});
it('should return a real-valued root if one exists with predictable:true', function() {
approx.equal(mathPredictable.pow(-8, 1/3), -2);
approx.equal(mathPredictable.pow(-8, 2/3), 4);
approx.equal(mathPredictable.pow(-8, 3/3), -8);
approx.equal(mathPredictable.pow(-8, 4/3), 16);
approx.equal(mathPredictable.pow(-8, 5/3), -32);
approx.equal(mathPredictable.pow(-8, -5/3), -0.03125);
approx.equal(mathPredictable.pow(-1, 2/3), 1);
approx.equal(mathPredictable.pow(-1, 50/99), 1);
approx.equal(mathPredictable.pow(-1, 49/99), -1);
approx.equal(mathPredictable.pow(-17, 29/137), -1.8216292479175);
approx.equal(mathPredictable.pow(-1, 0), 1);
approx.equal(mathPredictable.pow(-1, 0.2), -1);
approx.equal(mathPredictable.pow(-1, 1), -1);
approx.equal(mathPredictable.pow(4, 2), 16);
approx.equal(mathPredictable.pow(4, 0.5), 2);
approx.equal(mathPredictable.pow(-4, 2), 16);
assert(isNaN(mathPredictable.pow(-1, 49/100)));
assert(isNaN(mathPredictable.pow(-17, 29/138)));
assert(isNaN(mathPredictable.pow(-17, 3.14159265358979323)));
});
it('should exponentiate booleans to the given power', function() {
assert.equal(pow(true, true), 1);
assert.equal(pow(true, false), 1);
assert.equal(pow(false, true), 0);
assert.equal(pow(false, false), 1);
});
it('should exponentiate mixed numbers and booleans', function() {
assert.equal(pow(2, true), 2);
assert.equal(pow(2, false), 1);
assert.equal(pow(true, 2), 1);
assert.equal(pow(false, 2), 0);
});
it('should exponentiate numbers and null', function () {
assert.equal(pow(1, null), 1);
assert.equal(pow(null, 1), 0);
});
it('should exponentiate bignumbers', function() {
assert.deepEqual(pow(bignumber(2), bignumber(3)), bignumber(8));
assert.deepEqual(pow(bignumber(100), bignumber(500)), bignumber('1e1000'));
assert.deepEqual(pow(bignumber(-1), bignumber(2)), bignumber('1'));
assert.deepEqual(pow(bignumber(2), bignumber(1.5)), bignumber('2.828427124746190097603377448419396157139343750753896146353359476'));
});
it('should exponentiate a negative bignumber to a non-integer power', function() {
approx.deepEqual(pow(bignumber(-2), bignumber(1.5)), complex(0, -2.82842712474619));
approx.deepEqual(pow(-2, bignumber(1.5)), complex(0, -2.82842712474619));
approx.deepEqual(pow(bignumber(-2), 1.5), complex(0, -2.82842712474619));
});
it('should exponentiate a negative bignumber to a non-integer power', function() {
assert.ok(mathPredictable.pow(bignumber(-2), bignumber(1.5)).isNaN());
});
it('should exponentiate mixed numbers and bignumbers', function() {
assert.deepEqual(pow(bignumber(2), 3), bignumber(8));
assert.deepEqual(pow(2, bignumber(3)), bignumber(8));
assert.throws(function () {pow(1/3, bignumber(2))}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {pow(bignumber(1), 1/3)}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should exponentiate mixed booleans and bignumbers', function() {
assert.deepEqual(pow(true, bignumber(3)), bignumber(1));
assert.deepEqual(pow(false, bignumber(3)), bignumber(0));
assert.deepEqual(pow(bignumber(3), false), bignumber(1));
assert.deepEqual(pow(bignumber(3), true), bignumber(3));
});
it('should exponentiate a fraction to an integer power', function() {
assert.deepEqual(math.pow(fraction(3), fraction(2)), fraction(9));
assert.deepEqual(math.pow(fraction(1.5), fraction(2)), fraction(2.25));
assert.deepEqual(math.pow(fraction(1.5), fraction(-2)), fraction(4, 9));
assert.deepEqual(math.pow(fraction(1.5), 2), fraction(2.25));
});
it('should exponentiate a fraction to an non-integer power', function() {
assert.throws(function () {mathPredictable.pow(fraction(3), fraction(1.5))}, /Function pow does not support non-integer exponents for fractions/);
assert.strictEqual(math.pow(fraction(4), 1.5), 8);
assert.strictEqual(math.pow(fraction(4), fraction(1.5)), 8);
});
it('should throw an error if used with wrong number of arguments', function() {
assert.throws(function () {pow(1)}, /TypeError: Too few arguments in function pow/);
assert.throws(function () {pow(1, 2, 3)}, /TypeError: Too many arguments in function pow \(expected: 2, actual: 3\)/);
});
it('should exponentiate a complex number to the given power', function() {
approx.deepEqual(pow(complex(3, 0), 2), complex(9, 0));
approx.deepEqual(pow(complex(0, 2), 2), complex(-4, 0));
approx.deepEqual(pow(complex(-1,-1),complex(-1,-1)), complex('-0.0284750589322119 + 0.0606697332231795i'));
approx.deepEqual(pow(complex(-1,-1),complex(-1,1)), complex('-6.7536199239765713 + 3.1697803027015614i'));
approx.deepEqual(pow(complex(-1,-1),complex(0,-1)), complex('0.0891447921553914 - 0.0321946742909677i'));
approx.deepEqual(pow(complex(-1,-1),complex(0,1)), complex('9.92340022667813 + 3.58383962127501i'));
approx.deepEqual(pow(complex(-1,-1),complex(1,-1)), complex('-0.1213394664463591 - 0.0569501178644237i'));
approx.deepEqual(pow(complex(-1,-1),complex(1,1)), complex('-6.3395606054031211 - 13.5072398479531426i'));
approx.deepEqual(pow(complex(-1,1),complex(-1,-1)), complex('-6.7536199239765713 - 3.1697803027015614i'));
approx.deepEqual(pow(complex(-1,1),complex(-1,1)), complex('-0.0284750589322119 - 0.0606697332231795i'));
approx.deepEqual(pow(complex(-1,1),complex(0,-1)), complex('9.92340022667813 - 3.58383962127501i'));
approx.deepEqual(pow(complex(-1,1),complex(0,1)), complex('0.0891447921553914 + 0.0321946742909677i'));
approx.deepEqual(pow(complex(-1,1),complex(1,-1)), complex('-6.3395606054031211 + 13.5072398479531426i'));
approx.deepEqual(pow(complex(-1,1),complex(1,1)), complex('-0.1213394664463591 + 0.0569501178644237i'));
approx.deepEqual(pow(complex(0,-1),complex(-1,-1)), complex('0.000000000000000 + 0.207879576350762i'));
approx.deepEqual(pow(complex(0,-1),complex(-1,1)), complex('0.000000000000000 + 4.810477380965351i'));
approx.deepEqual(pow(complex(0,-1),complex(1,-1)), complex('0.000000000000000 - 0.207879576350762i'));
approx.deepEqual(pow(complex(0,-1),complex(1,1)), complex('0.000000000000000 - 4.810477380965351i'));
approx.deepEqual(pow(complex(0,1),complex(-1,-1)), complex('0.000000000000000 - 4.810477380965351i'));
approx.deepEqual(pow(complex(0,1),complex(-1,1)), complex('0.000000000000000 - 0.207879576350762i'));
approx.deepEqual(pow(complex(0,1),complex(1,-1)), complex('0.000000000000000 + 4.810477380965351i'));
approx.deepEqual(pow(complex(0,1),complex(1,1)), complex('0.000000000000000 + 0.207879576350762i'));
approx.deepEqual(pow(complex(1,-1),complex(-1,-1)), complex('0.2918503793793073 + 0.1369786269150605i'));
approx.deepEqual(pow(complex(1,-1),complex(-1,1)), complex('0.6589325864505904 + 1.4039396486303144i'));
approx.deepEqual(pow(complex(1,-1),complex(0,-1)), complex('0.428829006294368 - 0.154871752464247i'));
approx.deepEqual(pow(complex(1,-1),complex(0,1)), complex('2.062872235080905 + 0.745007062179724i'));
approx.deepEqual(pow(complex(1,-1),complex(1,-1)), complex('0.2739572538301211 - 0.5837007587586147i'));
approx.deepEqual(pow(complex(1,-1),complex(1,1)), complex('2.8078792972606288 - 1.3178651729011805i'));
approx.deepEqual(pow(complex(1,1),complex(-1,-1)), complex('0.6589325864505904 - 1.4039396486303144i'));
approx.deepEqual(pow(complex(1,1),complex(-1,1)), complex('0.2918503793793073 - 0.1369786269150605i'));
approx.deepEqual(pow(complex(1,1),complex(0,-1)), complex('2.062872235080905 - 0.745007062179724i'));
approx.deepEqual(pow(complex(1,1),complex(0,1)), complex('0.428829006294368 + 0.154871752464247i'));
approx.deepEqual(pow(complex(1,1),complex(1,-1)), complex('2.8078792972606288 + 1.3178651729011805i'));
approx.deepEqual(pow(complex(1,1),complex(1,1)), complex('0.2739572538301211 + 0.5837007587586147i'));
});
it('should exponentiate a complex number to the given bignumber power', function() {
approx.deepEqual(pow(complex(3, 0), math.bignumber(2)), complex(9, 0));
approx.deepEqual(pow(complex(0, 2), math.bignumber(2)), complex(-4, 0));
});
it('should correctly calculate unit ^ number', function() {
assert.equal(pow(unit('4 N'), 2).toString(), "16 N^2");
assert.equal(pow(unit('0.25 m/s'), -0.5).toString(), "2 s^0.5 / m^0.5");
assert.equal(pow(unit('123 hogshead'), 0).toString(), "1");
});
it('should return a cloned value and not affect the argument', function() {
var unit1 = unit('2 m');
var unit2 = pow(unit1, 2);
assert.equal(unit1.toString(), '2 m');
assert.equal(unit2.toString(), '4 m^2');
});
it('should return a valuelessUnit when calculating valuelessUnit ^ number', function() {
assert.equal(pow(unit('kg^0.5 m^0.5 s^-1'), 2).toString(), "(kg m) / s^2");
});
it('should throw an error when doing number ^ unit', function() {
assert.throws(function () {pow(2, unit('5cm'))});
});
it('should throw an error if used with a string', function() {
assert.throws(function () {pow('text', 2)});
assert.throws(function () {pow(2, 'text')});
});
it('should raise a square matrix to the power 2', function() {
var a = [[1,2],[3,4]];
var res = [[7,10],[15,22]];
approx.deepEqual(pow(a, 2), res);
approx.deepEqual(pow(matrix(a), 2), matrix(res));
});
it('should return identity matrix for power 0', function() {
var a = [[1,2],[3,4]];
var res = [[1,0],[0,1]];
approx.deepEqual(pow(a, 0), res);
approx.deepEqual(pow(matrix(a), 0), matrix(res));
});
it('should compute large size of square matrix', function() {
var a = math.eye(30).valueOf();
approx.deepEqual(pow(a, 1000), a);
approx.deepEqual(pow(matrix(a), 1000), matrix(a));
});
it('should throw an error when calculating the power of a non square matrix', function() {
assert.throws(function () {pow([1,2,3,4],2);});
assert.throws(function () {pow([[1,2,3],[4,5,6]],2);});
assert.throws(function () {pow([[1,2,3],[4,5,6]],2);});
});
it('should throw an error when raising a matrix to a non-integer power', function() {
var a = [[1,2],[3,4]];
assert.throws(function () {pow(a, 2.5);});
assert.throws(function () {pow(a, [2,3]);});
});
it('should LaTeX pow', function () {
var expression = math.parse('pow(2,10)');
assert.equal(expression.toTex(), '\\left(2\\right)^{10}');
});
});

View File

@@ -0,0 +1,145 @@
// test round
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var bignumber = math.bignumber;
var fraction = math.fraction;
var matrix = math.matrix;
var sparse = math.sparse;
var round = math.round;
describe('round', function() {
it('should round a number to te given number of decimals', function() {
approx.equal(round(math.pi), 3);
approx.equal(round(math.pi * 1000), 3142);
approx.equal(round(math.pi, 3), 3.142);
approx.equal(round(math.pi, 6), 3.141593);
approx.equal(round(1234.5678, 2), 1234.57);
approx.equal(round(2.135, 2), 2.14);
});
it('should round booleans (yeah, not really useful but it should be supported)', function() {
approx.equal(round(true), 1);
approx.equal(round(false), 0);
approx.equal(round(true, 2), 1);
approx.equal(round(false, 2), 0);
});
it('should round null', function () {
assert.equal(round(null), 0);
assert.equal(round(null, 2), 0);
});
it('should throw an error on invalid type of value', function() {
assert.throws(function () {round(new Date());}, /TypeError: Unexpected type of argument/);
});
it('should throw an error on invalid type of n', function() {
assert.throws(function () {round(math.pi, new Date());}, /TypeError: Unexpected type of argument/);
});
it('should throw an error on invalid value of n', function() {
assert.throws(function () {round(math.pi, -2);}, /Number of decimals in function round must be in te range of 0-15/);
assert.throws(function () {round(math.pi, 20);}, /Number of decimals in function round must be in te range of 0-15/);
assert.throws(function () {round(math.pi, 2.5);}, /Number of decimals in function round must be an integer/);
});
it('should throw an error if used with wrong number of arguments', function() {
assert.throws(function () {round();}, /TypeError: Too few arguments/);
assert.throws(function () {round(1,2,3);}, /TypeError: Too many arguments/);
});
it('should round bignumbers', function() {
assert.deepEqual(round(bignumber(2.7)), bignumber(3));
assert.deepEqual(round(bignumber(2.1)), bignumber(2));
assert.deepEqual(round(bignumber(2.123456), bignumber(3)), bignumber(2.123));
assert.deepEqual(round(bignumber(2.123456), 3), bignumber(2.123));
assert.deepEqual(round(2.1234567, bignumber(3)), bignumber(2.123));
assert.deepEqual(round(true, bignumber(3)), bignumber(1));
assert.deepEqual(round(bignumber(1.23), true), bignumber(1.2));
});
it('should round fractions', function() {
var a = fraction('2/3');
assert(round(a) instanceof math.type.Fraction);
assert.equal(a.toString(), '0.(6)');
assert.equal(round(fraction('2/3')).toString(), '1');
assert.equal(round(fraction('1/3')).toString(), '0');
assert.equal(round(fraction('1/2')).toString(), '1');
});
it('should round real and imag part of a complex number', function() {
assert.deepEqual(round(math.complex(2.2, math.pi)), math.complex(2,3));
});
it('should round a complex number with a bignumber as number of decimals', function() {
assert.deepEqual(round(math.complex(2.157, math.pi), bignumber(2)), math.complex(2.16, 3.14));
});
it('should throw an error if used with a unit', function() {
assert.throws(function () { round(math.unit('5cm')); }, TypeError, 'Function round(unit) not supported');
assert.throws(function () { round(math.unit('5cm'), 2); }, TypeError, 'Function round(unit) not supported');
assert.throws(function () { round(math.unit('5cm'), bignumber(2)); }, TypeError, 'Function round(unit) not supported');
});
it('should convert to a number when used with a string', function() {
assert.strictEqual(round('3.6'), 4);
assert.strictEqual(round('3.12345', '3'), 3.123);
assert.throws(function () {round('hello world'); }, /Cannot convert "hello world" to a number/);
});
it('should round each element in a matrix, array, range', function() {
assert.deepEqual(round(math.range(0,2.1,1/3), 2), math.matrix([0,0.33,0.67,1,1.33,1.67,2]));
assert.deepEqual(round(math.range(0,2.1,1/3)), math.matrix([0,0,1,1,1,2,2]));
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)');
var expr2 = math.parse('round(1.1,2)');
assert.equal(expr1.toTex(), '\\left\\lfloor1.1\\right\\rceil');
assert.equal(expr2.toTex(), '\\mathrm{round}\\left(1.1,2\\right)');
});
});

View File

@@ -0,0 +1,81 @@
// test sign
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var bignumber = math.bignumber;
var fraction = math.fraction;
var complex = math.complex;
describe('sign', function() {
it('should calculate the sign of a boolean', function () {
assert.equal(math.sign(true), 1);
assert.equal(math.sign(false), 0);
});
it('should calculate the sign of null', function () {
assert.equal(math.sign(null), 0);
});
it('should calculate the sign of a number', function() {
assert.equal(math.sign(3), 1);
assert.equal(math.sign(-3), -1);
assert.equal(math.sign(0), 0);
});
it('should calculate the sign of a big number', function() {
assert.deepEqual(math.sign(bignumber(3)), bignumber(1));
assert.deepEqual(math.sign(bignumber(-3)), bignumber(-1));
assert.deepEqual(math.sign(bignumber(0)), bignumber(0));
});
it('should calculate the sign of a fraction', function() {
var a = fraction(0.5);
assert(math.sign(a) instanceof math.type.Fraction);
assert.equal(math.sign(a).toString(), '1');
assert.equal(math.sign(fraction(-0.5)).toString(), '-1');
assert.equal(a.toString(), '0.5');
});
it('should calculate the sign of a complex value', function() {
approx.deepEqual(math.sign(math.complex(2,-3)), math.complex(0.554700196225229, -0.832050294337844));
});
it('should calculate the sign of a unit', function() {
assert.equal(math.sign(math.unit('5 cm')), 1);
assert.equal(math.sign(math.unit('-5 kg')), -1);
assert.equal(math.sign(math.unit('0 mol/s')), 0);
assert.equal(math.sign(math.unit('-283.15 degC')), -1);
assert.equal(math.sign(math.unit('-273.15 degC')), 0);
assert.equal(math.sign(math.unit('-263.15 degC')), 1);
assert.deepEqual(math.sign(math.unit(bignumber(5), 'cm')), bignumber(1));
assert.deepEqual(math.sign(math.unit(bignumber(-5), 'cm')), bignumber(-1));
assert.deepEqual(math.sign(math.unit(fraction(5), 'cm')), fraction(1));
assert.deepEqual(math.sign(math.unit(fraction(-5), 'cm')), fraction(-1));
assert.deepEqual(math.sign(math.unit(complex(3,4), 'mi')), complex(0.6,0.8));
});
it('should throw an error when used with a string', function() {
assert.throws(function () { math.sign("hello world"); });
});
it('should return a matrix of the signs of each elements in the given array', function() {
assert.deepEqual(math.sign([-2,-1,0,1,2]), [-1,-1,0,1,1]);
});
it('should return a matrix of the signs of each elements in the given matrix', function() {
assert.deepEqual(math.sign(math.matrix([-2,-1,0,1,2])), math.matrix([-1,-1,0,1,1]));
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {math.sign()}, /TypeError: Too few arguments/);
assert.throws(function () {math.sign(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX sign', function () {
var expression = math.parse('sign(-4)');
assert.equal(expression.toTex(), '\\mathrm{sign}\\left(-4\\right)');
});
});

View File

@@ -0,0 +1,100 @@
// test sqrt
var assert = require('assert');
var approx = require('../../../tools/approx');
var error = require('../../../lib/error/index');
var math = require('../../../index');
var mathPredictable = math.create({predictable: true});
var sqrt = math.sqrt;
var bignumber = math.bignumber;
describe('sqrt', function() {
it('should return the square root of a boolean', function () {
assert.equal(sqrt(true), 1);
assert.equal(sqrt(false), 0);
});
it('should return the square root of null', function () {
assert.equal(sqrt(null), 0);
});
it('should return the square root of a positive number', function() {
assert.equal(sqrt(0), 0);
assert.equal(sqrt(1), 1);
assert.equal(sqrt(4), 2);
assert.equal(sqrt(9), 3);
assert.equal(sqrt(16), 4);
assert.equal(sqrt(25), 5);
});
it('should return the square root of a negative number', function() {
assert.deepEqual(sqrt(-4), math.complex(0, 2));
assert.deepEqual(sqrt(-16), math.complex(0, 4));
});
it('should return the square root of a negative number when predictable:true', function() {
assert.strictEqual(mathPredictable.sqrt(4), 2);
assert(typeof mathPredictable.sqrt(-4), 'number');
assert(isNaN(mathPredictable.sqrt(-4)));
});
it('should return the square root of a positive bignumber', function() {
assert.deepEqual(sqrt(bignumber(0)), bignumber(0));
assert.deepEqual(sqrt(bignumber(1)), bignumber(1));
assert.deepEqual(sqrt(bignumber(4)), bignumber(2));
assert.deepEqual(sqrt(bignumber(9)), bignumber(3));
assert.deepEqual(sqrt(bignumber(16)), bignumber(4));
assert.deepEqual(sqrt(bignumber(25)), bignumber(5));
// validate whether we are really working at high precision
var bigmath = math.create({precision: 100});
assert.deepEqual(bigmath.sqrt(bigmath.bignumber(2)), bigmath.bignumber('1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573'));
});
it('should return the square root of a negative bignumber', function() {
assert.deepEqual(sqrt(bignumber(-4)), math.complex(0, 2));
});
it('should return the square root of a negative bignumber when predictable:true', function() {
assert.deepEqual(mathPredictable.sqrt(bignumber(4)), bignumber(2));
assert.ok(mathPredictable.sqrt(bignumber(-4)).isNaN());
});
it('should return the square root of a complex number', function() {
assert.deepEqual(sqrt(math.complex(3, -4)), math.complex(2, -1));
assert.deepEqual(sqrt(math.complex(1e10, 1e-10)), math.complex(1e5, 5e-16));
});
it('should return the square root of a unit', function() {
assert.equal(sqrt(math.unit('25 m^2/s^2')).toString(), '5 m / s');
assert.equal(sqrt(math.unit('4 kg')).toString(), '2 kg^0.5');
});
it('should return a Unit with a Complex value when computing the square root of a negative unit', function() {
// Update this when support for complex units is added
//assert.equal(sqrt(math.unit('-25 m^2/s^2')).toString(), 'NaN m / s');
assert.equal(math.format(sqrt(math.unit('-25 m^2/s^2')), 14), '(5i) m / s');
});
it('should throw an error when used with a string', function() {
assert.throws(function () {
sqrt('a string');
});
});
it('should return the square root of each element of a matrix', function() {
assert.deepEqual(sqrt([4,9,16,25]), [2,3,4,5]);
assert.deepEqual(sqrt([[4,9],[16,25]]), [[2,3],[4,5]]);
assert.deepEqual(sqrt(math.matrix([[4,9],[16,25]])), math.matrix([[2,3],[4,5]]));
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {sqrt()}, /TypeError: Too few arguments/);
assert.throws(function () {sqrt(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX sqrt', function () {
var expression = math.parse('sqrt(2)');
assert.equal(expression.toTex(), '\\sqrt{2}');
});
});

View File

@@ -0,0 +1,72 @@
// test square
var assert = require('assert');
var math = require('../../../index');
var unit = math.unit;
var bignumber = math.bignumber;
var fraction = math.fraction;
var matrix = math.matrix;
var range = math.range;
var square = math.square;
describe('square', function() {
it('should return the square of a boolean', function () {
assert.equal(square(true), 1);
assert.equal(square(false), 0);
});
it('should return the square of null', function () {
assert.equal(square(null), 0);
});
it('should return the square of a number', function() {
assert.equal(square(4), 16);
assert.equal(square(-2), 4);
assert.equal(square(0), 0);
});
it('should return the square of a big number', function() {
assert.deepEqual(square(bignumber(4)), bignumber(16));
assert.deepEqual(square(bignumber(-2)), bignumber(4));
assert.deepEqual(square(bignumber(0)), bignumber(0));
});
it('should return the square of a fraction', function() {
var a = fraction(0.5);
assert(square(a) instanceof math.type.Fraction);
assert.equal(square(a).toString(), '0.25');
assert.equal(a.toString(), '0.5');
});
it('should throw an error if used with wrong number of arguments', function() {
assert.throws(function () {square()}, /TypeError: Too few arguments/);
assert.throws(function () {square(1, 2)}, /TypeError: Too many arguments/);
});
it('should return the square of a complex number', function() {
assert.deepEqual(square(math.complex('2i')), math.complex('-4'));
assert.deepEqual(square(math.complex('2+3i')), math.complex('-5+12i'));
assert.deepEqual(square(math.complex('2')), math.complex('4'));
});
it('should return the square of a unit', function() {
assert.equal(square(math.unit('4 cm')).toString(), '16 cm^2');
assert.equal(square(math.unit('-2 cm')).toString(), '4 cm^2');
assert.equal(square(math.unit('0 cm')).toString(), '0 cm^2');
});
it('should throw an error when used with a string', function() {
assert.throws(function () {square('text')});
});
it('should return the square of each element in a matrix', function() {
assert.deepEqual(square([2,3,4,5]), [4,9,16,25]);
assert.deepEqual(square(matrix([2,3,4,5])), matrix([4,9,16,25]));
assert.deepEqual(square(matrix([[1,2],[3,4]])), matrix([[1,4],[9,16]]));
});
it('should LaTeX square', function () {
var expression = math.parse('square(4)');
assert.equal(expression.toTex(), '\\left(4\\right)^2');
});
});

View File

@@ -0,0 +1,248 @@
// test subtract
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var bignumber = math.bignumber;
var subtract = math.subtract;
describe('subtract', function() {
it('should subtract two numbers correctly', function() {
assert.deepEqual(subtract(4, 2), 2);
assert.deepEqual(subtract(4, -4), 8);
assert.deepEqual(subtract(-4, -4), 0);
assert.deepEqual(subtract(-4, 4), -8);
assert.deepEqual(subtract(2, 4), -2);
assert.deepEqual(subtract(3, 0), 3);
assert.deepEqual(subtract(0, 3), -3);
assert.deepEqual(subtract(0, 3), -3);
assert.deepEqual(subtract(0, 3), -3);
});
it('should subtract booleans', function() {
assert.equal(subtract(true, true), 0);
assert.equal(subtract(true, false), 1);
assert.equal(subtract(false, true), -1);
assert.equal(subtract(false, false), 0);
});
it('should subtract mixed numbers and booleans', function() {
assert.equal(subtract(2, true), 1);
assert.equal(subtract(2, false), 2);
assert.equal(subtract(true, 2), -1);
assert.equal(subtract(false, 2), -2);
});
it('should subtract numbers and null', function () {
assert.equal(subtract(1, null), 1);
assert.equal(subtract(null, 1), -1);
});
it('should subtract bignumbers', function() {
assert.deepEqual(subtract(bignumber(0.3), bignumber(0.2)), bignumber(0.1));
assert.deepEqual(subtract(bignumber('2.3e5001'), bignumber('3e5000')), bignumber('2e5001'));
assert.deepEqual(subtract(bignumber('1e19'), bignumber('1')), bignumber('9999999999999999999'));
});
it('should subtract mixed numbers and bignumbers', function() {
assert.deepEqual(subtract(bignumber(0.3), 0.2), bignumber(0.1));
assert.deepEqual(subtract(0.3, bignumber(0.2)), bignumber(0.1));
assert.throws(function () {subtract(1/3, bignumber(1).div(3));}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {subtract(bignumber(1).div(3), 1/3);}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should subtract mixed booleans and bignumbers', function() {
assert.deepEqual(subtract(bignumber(1.1), true), bignumber(0.1));
assert.deepEqual(subtract(bignumber(1.1), false), bignumber(1.1));
assert.deepEqual(subtract(false, bignumber(0.2)), bignumber(-0.2));
assert.deepEqual(subtract(true, bignumber(0.2)), bignumber(0.8));
});
it('should subtract two complex numbers correctly', function() {
assert.deepEqual(subtract(math.complex(3, 2), math.complex(8, 4)), math.complex('-5 - 2i'));
assert.deepEqual(subtract(math.complex(6, 3), math.complex(-2, -2)), math.complex('8 + 5i'));
assert.deepEqual(subtract(math.complex(3, 4), 10), math.complex('-7 + 4i'));
assert.deepEqual(subtract(math.complex(3, 4), -2), math.complex('5 + 4i'));
assert.deepEqual(subtract(math.complex(-3, -4), 10), math.complex('-13 - 4i'));
assert.deepEqual(subtract(10, math.complex(3, 4)), math.complex('7 - 4i'));
assert.deepEqual(subtract(10, math.i), math.complex('10 - i'));
assert.deepEqual(subtract(0, math.i), math.complex('-i'));
assert.deepEqual(subtract(10, math.complex(0, 1)), math.complex('10 - i'));
});
it('should throw an error for mixed complex numbers and big numbers', function() {
assert.deepEqual(subtract(math.complex(3, 4), math.bignumber(10)), math.complex(-7, 4));
assert.deepEqual(subtract(math.bignumber(10), math.complex(3, 4)), math.complex(7, -4));
});
it('should subtract two fractions', function() {
var a = math.fraction(1,3);
assert.equal(subtract(a, math.fraction(1,6)).toString(), '0.1(6)');
assert.equal(a.toString(), '0.(3)');
assert.equal(subtract(math.fraction(3,5), math.fraction(1,5)).toString(), '0.4');
assert.equal(subtract(math.fraction(1), math.fraction(1,3)).toString(), '0.(6)');
});
it('should subtract mixed fractions and numbers', function() {
assert.deepEqual(subtract(1, math.fraction(1,3)), math.fraction(2,3));
assert.deepEqual(subtract(math.fraction(1,3), 1), math.fraction(-2,3));
});
it('should subtract two quantities of the same unit', function() {
approx.deepEqual(subtract(math.unit(5, 'km'), math.unit(100, 'mile')), math.unit(-155.93, 'km'));
assert.deepEqual(subtract(math.unit(math.bignumber(5), 'km'), math.unit(math.bignumber(2), 'km')), math.unit(math.bignumber(3), 'km'));
assert.deepEqual(subtract(math.unit(math.complex(10,10), 'K'), math.unit(math.complex(3,4), 'K')), math.unit(math.complex(7,6), 'K'));
assert.deepEqual(subtract(math.unit(math.complex(10,10), 'K'), math.unit(3, 'K')), math.unit(math.complex(7,10), 'K'));
});
it('should throw an error if subtracting two quantities of different units', function() {
assert.throws(function () {
subtract(math.unit(5, 'km'), math.unit(100, 'gram'));
});
});
it('should throw an error when one of the two units has undefined value', function() {
assert.throws(function () {
subtract(math.unit('km'), math.unit('5gram'));
}, /Parameter x contains a unit with undefined value/);
assert.throws(function () {
subtract(math.unit('5 km'), math.unit('gram'));
}, /Parameter y contains a unit with undefined value/);
});
it('should throw an error if subtracting numbers from units', function() {
assert.throws(function () { subtract(math.unit(5, 'km'), 2); }, TypeError);
assert.throws(function () { subtract(2, math.unit(5, 'km')); }, TypeError);
});
it('should throw an error if subtracting numbers from units', function() {
assert.throws(function () { subtract(math.unit(5, 'km'), bignumber(2)); }, TypeError);
assert.throws(function () { subtract(bignumber(2), math.unit(5, 'km')); }, TypeError);
});
it('should throw an error when used with a string', function() {
assert.throws(function () {subtract('hello ', 'world'); });
assert.throws(function () {subtract('str', 123);});
assert.throws(function () {subtract(123, 'str');});
});
describe('Array', function () {
it('should subtract arrays correctly', function() {
var a2 = [[10,20],[30,40]];
var a3 = [[5,6],[7,8]];
var a4 = subtract(a2, a3);
assert.deepEqual(a4, [[5,14],[23,32]]);
});
it('should subtract a scalar and an array correctly', function() {
assert.deepEqual(subtract(2, [3,4]), [-1,-2]);
assert.deepEqual(subtract(2, [3,0]), [-1,2]);
assert.deepEqual(subtract([3,4], 2), [1,2]);
assert.deepEqual(subtract([3,0], 2), [1,-2]);
});
it('should subtract array and dense matrix correctly', function() {
var a = [1,2,3];
var b = math.matrix([3,2,1]);
var c = subtract(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([-2,0,2]));
});
it('should subtract array and dense matrix correctly', function() {
var a = [[1,2,3],[4,5,6]];
var b = math.sparse([[6,5,4],[ 3, 2, 1]]);
var c = subtract(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([[-5,-3,-1],[1,3,5]]));
});
});
describe('DenseMatrix', function () {
it('should subtract matrices correctly', function() {
var a2 = math.matrix([[10,20],[30,40]]);
var a3 = math.matrix([[5,6],[7,8]]);
var a4 = subtract(a2, a3);
assert.ok(a4 instanceof math.type.Matrix);
assert.deepEqual(a4.size(), [2,2]);
assert.deepEqual(a4.valueOf(), [[5,14],[23,32]]);
});
it('should subtract a scalar and a matrix correctly', function() {
assert.deepEqual(subtract(2, math.matrix([3,4])), math.matrix([-1,-2]));
assert.deepEqual(subtract(math.matrix([3,4]), 2), math.matrix([1,2]));
});
it('should subtract matrix and array correctly', function() {
var a = math.matrix([1,2,3]);
var b = [3,2,1];
var c = subtract(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([-2,0,2]));
});
it('should subtract dense and sparse matrices correctly', function() {
var a = math.matrix([[1,2,3],[1,0,0]]);
var b = math.sparse([[3,2,1],[0,0,1]]);
var c = subtract(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([[-2,0,2],[1,0,-1]]));
});
});
describe('SparseMatrix', function () {
it('should subtract matrices correctly', function() {
var a2 = math.matrix([[10,20],[30,0]], 'sparse');
var a3 = math.matrix([[5,6],[30,8]], 'sparse');
var a4 = subtract(a2, a3);
assert.ok(a4 instanceof math.type.Matrix);
assert.deepEqual(a4, math.sparse([[5,14],[0,-8]]));
});
it('should subtract a scalar and a matrix correctly', function() {
assert.deepEqual(subtract(2, math.matrix([[3,4],[5,6]], 'sparse')).valueOf(), [[-1,-2],[-3,-4]]);
assert.deepEqual(subtract(2, math.matrix([[3,4],[0,6]], 'sparse')).valueOf(), [[-1,-2],[2,-4]]);
assert.deepEqual(subtract(math.matrix([[3,4],[5,6]], 'sparse'), 2).valueOf(), [[1,2],[3,4]]);
assert.deepEqual(subtract(math.matrix([[3,4],[0,6]], 'sparse'), 2).valueOf(), [[1,2],[-2,4]]);
});
it('should subtract matrix and array correctly', function() {
var a = math.matrix([[1,2,3],[1,0,0]], 'sparse');
var b = [[3,2,1],[0,0,1]];
var c = subtract(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c.valueOf(), [[-2,0,2],[1,0,-1]]);
});
it('should subtract sparse and dense matrices correctly', function() {
var a = math.sparse([[1,2,3],[1,0,0]]);
var b = math.matrix([[3,2,1],[0,0,1]]);
var c = subtract(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([[-2,0,2],[1,0,-1]]));
});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {subtract(1);}, /TypeError: Too few arguments/);
assert.throws(function () {subtract(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should LaTeX subtract', function () {
var expression = math.parse('subtract(2,1)');
assert.equal(expression.toTex(), '\\left(2-1\\right)');
});
});

View File

@@ -0,0 +1,82 @@
// test unary minus
var assert = require('assert');
var math = require('../../../index');
var bignumber = math.bignumber;
var fraction = math.fraction;
var complex = math.complex;
describe('unaryMinus', function() {
it('should return unary minus of a boolean', function () {
assert.equal(math.unaryMinus(true), -1);
assert.equal(math.unaryMinus(false), 0);
});
// TODO: unary minus should return bignumber on boolean input when configured for bignumber
it.skip('should return bignumber unary minus of a boolean', function () {
var bigmath = math.create({number: 'BigNumber'});
assert.deepEqual(bigmath.unaryMinus(true), bigmath.bignumber(-1));
assert.deepEqual(bigmath.unaryMinus(false), bigmath.bignumber(0));
});
it('should return unary minus of null', function () {
assert.equal(math.unaryMinus(null), 0);
});
it('should perform unary minus of a number', function() {
assert.deepEqual(math.unaryMinus(2), -2);
assert.deepEqual(math.unaryMinus(-2), 2);
assert.deepEqual(math.unaryMinus(0), 0);
});
it('should perform unary minus of a big number', function() {
assert.deepEqual(math.unaryMinus(bignumber(2)), bignumber(-2));
assert.deepEqual(math.unaryMinus(bignumber(-2)), bignumber(2));
assert.deepEqual(math.unaryMinus(bignumber(0)).toString(), '0');
});
it('should perform unary minus of a fraction', function() {
var a = fraction(0.5);
assert(math.unaryMinus(a) instanceof math.type.Fraction);
assert.equal(a.toString(), '0.5');
assert.equal(math.unaryMinus(fraction(0.5)).toString(), '-0.5');
assert.equal(math.unaryMinus(fraction(-0.5)).toString(), '0.5');
});
it('should perform unary minus of a complex number', function() {
assert.equal(math.unaryMinus(math.complex(3, 2)), '-3 - 2i');
assert.equal(math.unaryMinus(math.complex(3, -2)), '-3 + 2i');
assert.equal(math.unaryMinus(math.complex(-3, 2)), '3 - 2i');
assert.equal(math.unaryMinus(math.complex(-3, -2)), '3 + 2i');
});
it('should perform unary minus of a unit', function() {
assert.equal(math.unaryMinus(math.unit(5, 'km')).toString(), '-5 km');
assert.equal(math.unaryMinus(math.unit(fraction(2/3), 'km')).toString(), '-2/3 km');
assert.equal(math.unaryMinus(math.unit(complex(2,-4), 'gal')).toString(), '(-2 + 4i) gal');
});
it('should perform element-wise unary minus on a matrix', function() {
a2 = math.matrix([[1,2],[3,4]]);
var a7 = math.unaryMinus(a2);
assert.ok(a7 instanceof math.type.Matrix);
assert.deepEqual(a7.size(), [2,2]);
assert.deepEqual(a7.valueOf(), [[-1,-2],[-3,-4]]);
assert.deepEqual(math.unaryMinus([[1,2],[3,4]]), [[-1,-2],[-3,-4]]);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {math.unaryMinus()}, /TypeError: Too few arguments/);
assert.throws(function () {math.unaryMinus(1, 2)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of argument', function() {
assert.throws(function () {math.unaryMinus(new Date())}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX unaryMinus', function () {
var expression = math.parse('unaryMinus(1)');
assert.equal(expression.toTex(), '-\\left(1\\right)');
});
});

View File

@@ -0,0 +1,114 @@
// test unary plus
var assert = require('assert');
var math = require('../../../index');
var error = require('../../../lib/error/index');
var bignumber = math.bignumber;
var fraction = math.fraction;
describe('unaryPlus', function() {
it('should return unary plus of a boolean', function () {
assert.equal(math.unaryPlus(true), 1);
assert.equal(math.unaryPlus(false), 0);
});
it('should return unary plus of null', function () {
assert.equal(math.unaryPlus(null), 0);
});
it.skip('should return bignumber unary plus of a boolean', function () {
var bigmath = math.create({number: 'BigNumber'});
assert.deepEqual(bigmath.unaryPlus(true), bigmath.bignumber(1));
assert.deepEqual(bigmath.unaryPlus(false), bigmath.bignumber(0));
});
// TODO: this is temporary until the test above works again
it('should return bignumber unary plus of a boolean', function () {
var bigmath = math.create({number: 'BigNumber'});
var a = bigmath.unaryPlus(true);
assert(a instanceof math.type.BigNumber);
assert.deepEqual(a.toString(), '1');
var b = bigmath.unaryPlus(false);
assert(b instanceof math.type.BigNumber);
assert.deepEqual(b.toString(), '0');
});
it('should return unary plus on a string', function() {
assert.equal(math.unaryPlus('2'), 2);
assert.equal(math.unaryPlus('-2'), -2);
});
it.skip('should return bignumber unary plus on a string', function() {
var bigmath = math.create({number: 'BigNumber'});
assert.deepEqual(bigmath.unaryPlus('2'), bigmath.bignumber(2));
assert.deepEqual(bigmath.unaryPlus('-2'), bigmath.bignumber(-2));
});
// TODO: this is temporary until the test above works again
it('should return bignumber unary plus on a string', function() {
var bigmath = math.create({number: 'BigNumber'});
var a = bigmath.unaryPlus('2');
assert(a instanceof math.type.BigNumber);
assert.deepEqual(a.toString(), '2');
var b = bigmath.unaryPlus('-2');
assert(b instanceof math.type.BigNumber);
assert.deepEqual(b.toString(), '-2');
});
it('should perform unary plus of a number', function() {
assert.deepEqual(math.unaryPlus(2), 2);
assert.deepEqual(math.unaryPlus(-2), -2);
assert.deepEqual(math.unaryPlus(0), 0);
});
it('should perform unary plus of a big number', function() {
assert.deepEqual(math.unaryPlus(bignumber(2)), bignumber(2));
assert.deepEqual(math.unaryPlus(bignumber(-2)), bignumber(-2));
assert.deepEqual(math.unaryPlus(bignumber(0)).valueOf(), bignumber(0).valueOf());
});
it('should perform unary plus of a fraction', function() {
var a = fraction(0.5);
assert(math.unaryPlus(a) instanceof math.type.Fraction);
assert.equal(a.toString(), '0.5');
assert.equal(math.unaryPlus(fraction(0.5)).toString(), '0.5');
assert.equal(math.unaryPlus(fraction(-0.5)).toString(), '-0.5');
});
it('should perform unary plus of a complex number', function() {
assert.equal(math.unaryPlus(math.complex(3, 2)), '3 + 2i');
assert.equal(math.unaryPlus(math.complex(3, -2)), '3 - 2i');
assert.equal(math.unaryPlus(math.complex(-3, 2)), '-3 + 2i');
assert.equal(math.unaryPlus(math.complex(-3, -2)), '-3 - 2i');
});
it('should perform unary plus of a unit', function() {
assert.equal(math.unaryPlus(math.unit(5, 'km')).toString(), '5 km');
});
it('should perform element-wise unary plus on a matrix', function() {
a2 = math.matrix([[1,2],[3,4]]);
var a7 = math.unaryPlus(a2);
assert.ok(a7 instanceof math.type.Matrix);
assert.deepEqual(a7.size(), [2,2]);
assert.deepEqual(a7.valueOf(), [[1,2],[3,4]]);
assert.deepEqual(math.unaryPlus([[1,2],[3,4]]), [[1,2],[3,4]]);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {math.unaryPlus()}, /TypeError: Too few arguments/);
assert.throws(function () {math.unaryPlus(1, 2)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of argument', function() {
assert.throws(function () {math.unaryPlus(new Date())}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX unaryPlus', function () {
var expression = math.parse('unaryPlus(1)');
assert.equal(expression.toTex(), '+\\left(1\\right)');
});
});

View File

@@ -0,0 +1,129 @@
// test xgcd
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index').create({matrix: 'Array'}),
gcd = math.gcd,
xgcd = math.xgcd;
describe('xgcd', function() {
it('should return extended greatest common divisor of two numbers', function() {
// xgcd(36163, 21199) = 1247 => -7(36163) + 12(21199) = 1247
assert.deepEqual([1247, -7, 12], xgcd(36163, 21199));
// xgcd(120, 23) = 1 => -9(120) + 47(23) = 1
assert.deepEqual([1, -9, 47], xgcd(120, 23));
// some unit tests from: https://github.com/sjkaliski/numbers.js/blob/master/test/basic.test.js
assert.deepEqual([5, -3, 5], xgcd(65, 40));
assert.deepEqual([5, 5, -3], xgcd(40, 65));
assert.deepEqual([21, -16, 27], xgcd(1239, 735));
assert.deepEqual([21, 5, -2], xgcd(105, 252));
assert.deepEqual([21, -2, 5], xgcd(252, 105));
});
it ('should calculate xgcd for edge cases around zero', function () {
assert.deepEqual([3, 1, 0], xgcd(3, 0));
assert.deepEqual([3, -1, 0], xgcd(-3, 0));
assert.deepEqual([3, 0, 1], xgcd(0, 3));
assert.deepEqual([3, 0, -1], xgcd(0, -3));
assert.deepEqual([1, 0, 1], xgcd(1, 1));
assert.deepEqual([1, 1, 0], xgcd(1, 0));
assert.deepEqual([1, 0, -1], xgcd(1, -1));
assert.deepEqual([1, 0, 1], xgcd(-1, 1));
assert.deepEqual([1, -1, 0], xgcd(-1, 0));
assert.deepEqual([1, 0, -1], xgcd(-1, -1));
assert.deepEqual([1, 0, 1], xgcd(0, 1));
assert.deepEqual([1, 0, -1], xgcd(0, -1));
assert.deepEqual([0, 0, 0], xgcd(0, 0));
});
it('should calculate xgcd of booleans', function() {
assert.deepEqual(xgcd(true, true), [1, 0, 1]);
assert.deepEqual(xgcd(true, false), [1, 1, 0]);
assert.deepEqual(xgcd(false, true), [1, 0, 1]);
assert.deepEqual(xgcd(false, false), [0, 0, 0]);
});
it('should calculate xgcd of numbers and null', function () {
assert.deepEqual(xgcd(1, null), [1, 1, 0]);
assert.deepEqual(xgcd(null, 1), [1, 0, 1]);
assert.deepEqual(xgcd(null, null), [0, 0, 0]);
});
it('should calculate xgcd for BigNumbers', function() {
assert.deepEqual(xgcd(math.bignumber(65), math.bignumber(40)), [math.bignumber(5), math.bignumber(-3), math.bignumber(5)]);
assert.deepEqual(xgcd(math.bignumber(65), math.bignumber(40)), [math.bignumber(5), math.bignumber(-3), math.bignumber(5)]);
});
it('should calculate xgcd for mixed BigNumbers and Numbers', function() {
assert.deepEqual(xgcd(math.bignumber(65), 40), [math.bignumber(5), math.bignumber(-3), math.bignumber(5)]);
assert.deepEqual(xgcd(65, math.bignumber(40)), [math.bignumber(5), math.bignumber(-3), math.bignumber(5)]);
});
// FIXME: xgcd for negative values
it.skip('should calculate xgcd for edge cases with negative values', function () {
assert.deepEqual([1, -2, 1], xgcd(2, 5));
assert.deepEqual([1, -2, -1], xgcd(2, -5));
assert.deepEqual([1, 2, 1], xgcd(-2, 5));
assert.deepEqual([1, 2, -1], xgcd(-2, -5));
assert.deepEqual([2, 1, 0], xgcd(2, 6));
assert.deepEqual([2, 1, 0], xgcd(2, -6));
assert.deepEqual([2, -1, 0], xgcd(-2, 6));
assert.deepEqual([2, -1, 0], xgcd(-2, -6));
});
it('should find the greatest common divisor of booleans', function() {
assert.deepEqual([1, 0, 1], xgcd(true, true));
assert.deepEqual([1, 1, 0], xgcd(true, false));
assert.deepEqual([1, 0, 1], xgcd(false, true));
assert.deepEqual([0, 0, 0], xgcd(false, false));
});
it('should give same results as gcd', function() {
assert.equal(gcd(1239, 735), xgcd(1239, 735)[0]);
assert.equal(gcd(105, 252), xgcd(105, 252)[0]);
assert.equal(gcd(7, 13), xgcd(7, 13)[0]);
});
it('should return a matrix when configured to use matrices', function() {
var math1 = math.create({matrix: 'Matrix'});
assert.deepEqual(math1.xgcd(65, 40), math.matrix([5, -3, 5]));
var math2 = math.create({matrix: 'Array'});
assert.deepEqual(math2.xgcd(65, 40), [5, -3, 5]);
});
it('should throw an error if used with wrong number of arguments', function() {
assert.throws(function () {xgcd(1)});
assert.throws(function () {xgcd(1, 2, 3)});
});
it('should throw an error for non-integer numbers', function() {
assert.throws(function () {xgcd(2, 4.1); }, /Parameters in function xgcd must be integer numbers/);
assert.throws(function () {xgcd(2.3, 4); }, /Parameters in function xgcd must be integer numbers/);
})
it('should throw an error when used with a complex number', function() {
assert.throws(function () {xgcd(math.complex(1,3),2); }, TypeError, 'Function xgcd(complex, number) not supported');
});
it('should convert to a number when used with a string', function() {
assert.deepEqual(xgcd('65', '40'), [5, -3, 5]);
assert.throws(function () {xgcd(2, 'a'); }, /Cannot convert "a" to a number/);
});
it('should throw an error when used with a unit', function() {
assert.throws(function () { xgcd(math.unit('5cm'), 2); }, TypeError, 'Function xgcd(unit, number) not supported');
});
it('should throw an error when used with a matrix', function() {
assert.throws(function () { xgcd([5,2,3], [25,3,6]); }, TypeError, 'Function xgcd(array, array) not supported');
});
it('should LaTeX xgcd', function () {
var expression = math.parse('xgcd(2,3)');
assert.equal(expression.toTex(), '\\mathrm{xgcd}\\left(2,3\\right)');
});
});

View File

@@ -0,0 +1,221 @@
// test bitAnd
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
bitAnd = math.bitAnd;
describe('bitAnd', function () {
it('should bitwise and two numbers', function () {
assert.equal(bitAnd(53, 131), 1);
assert.equal(bitAnd(2, 3), 2);
assert.equal(bitAnd(-2, 3), 2);
assert.equal(bitAnd(2, -3), 0);
assert.equal(bitAnd(-5, -3), -7);
});
it('should bitwise and booleans', function () {
assert.equal(bitAnd(true, true), 1);
assert.equal(bitAnd(true, false), 0);
assert.equal(bitAnd(false, true), 0);
assert.equal(bitAnd(false, false), 0);
});
it('should bitwise and numbers and null', function () {
assert.equal(math.bitAnd(null, null), 0);
assert.equal(math.bitAnd(null, 1), 0);
assert.equal(math.bitAnd(1, null), 0);
});
it('should bitwise and mixed numbers and booleans', function () {
assert.equal(bitAnd(1, true), 1);
assert.equal(bitAnd(1, false), 0);
assert.equal(bitAnd(true, 1), 1);
assert.equal(bitAnd(false, 1), 0);
});
it('should bitwise and bignumbers', function () {
assert.deepEqual(bitAnd(bignumber(1), bignumber(2)), bignumber(0));
assert.deepEqual(bitAnd(bignumber('-1.0e+31'), bignumber('-1.0e+32')), bignumber('-101273397985285317082036849082368'));
assert.deepEqual(bitAnd(bignumber('1.0e+31'), bignumber('1.0e+32')), bignumber('8726602014714682917961003433984'));
assert.deepEqual(bitAnd(bignumber('-1.0e+31'), bignumber('1.0e+32')), bignumber('91273397985285317082038996566016'));
assert.deepEqual(bitAnd(bignumber('1.0e+31'), bignumber('-1.0e+32')), bignumber('1273397985285317082036849082368'));
assert.deepEqual(bitAnd(bignumber('2.1877409333271352879E+75'), bignumber('-3.220131224058161211554E+42')), bignumber('2187740933327135287899999999999996863578490213829130431270426161710498840576'));
});
it('should bitwise and mixed numbers and bignumbers', function () {
assert.deepEqual(bitAnd(bignumber(1), 2), bignumber(0));
assert.deepEqual(bitAnd(1, bignumber(2)), bignumber(0));
assert.deepEqual(bitAnd(bignumber(7), 9), bignumber(1));
assert.deepEqual(bitAnd(7, bignumber(9)), bignumber(1));
});
it('should bitwise and mixed booleans and bignumbers', function () {
assert.deepEqual(bitAnd(bignumber(1), true), bignumber(1));
assert.deepEqual(bitAnd(bignumber(1), false), bignumber(0));
assert.deepEqual(bitAnd(false, bignumber(3)), bignumber(0));
assert.deepEqual(bitAnd(true, bignumber(3)), bignumber(1));
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {bitAnd(math.unit('5cm'), 2);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitAnd(2, math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitAnd(math.unit('2cm'), math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
});
it('should throw an error if the parameters are not integers', function () {
assert.throws(function () {
bitAnd(1.1, 1);
}, /Integers expected in function bitAnd/);
assert.throws(function () {
bitAnd(1, 1.1);
}, /Integers expected in function bitAnd/);
assert.throws(function () {
bitAnd(1.1, 1.1);
}, /Integers expected in function bitAnd/);
assert.throws(function () {
bitAnd(bignumber(1.1), 1);
}, /Integers expected in function bitAnd/);
assert.throws(function () {
bitAnd(1, bignumber(1.1));
}, /Integers expected in function bitAnd/);
assert.throws(function () {
bitAnd(bignumber(1.1), bignumber(1));
}, /Integers expected in function bitAnd/);
assert.throws(function () {
bitAnd(bignumber(1), bignumber(1.1));
}, /Integers expected in function bitAnd/);
});
it('should bitwise and arrays correctly', function () {
var a = [[1,4],[3,2]];
// array - array
var b = [[5,8],[7,6]];
var c = bitAnd(a, b);
assert.deepEqual(c, [[1,0],[3,2]]);
// array - dense
b = math.matrix([[5,8],[7,6]]);
c = bitAnd(a, b);
assert.deepEqual(c, math.matrix([[1,0],[3,2]]));
// array - sparse
b = math.sparse([[5,8],[7,6]]);
c = bitAnd(a, b);
assert.deepEqual(c, math.sparse([[1,0],[3,2]]));
});
it('should bitwise and dense matrix correctly', function () {
var a = math.matrix([[1,4],[3,2]]);
// dense - array
var b = [[5,8],[7,6]];
var c = bitAnd(a, b);
assert.deepEqual(c, math.matrix([[1,0],[3,2]]));
// dense - dense
b = math.matrix([[5,8],[7,6]]);
c = bitAnd(a, b);
assert.deepEqual(c, math.matrix([[1,0],[3,2]]));
// dense - sparse
b = math.sparse([[5,8],[7,6]]);
c = bitAnd(a, b);
assert.deepEqual(c, math.sparse([[1,0],[3,2]]));
});
it('should bitwise and sparse matrix correctly', function () {
var a = math.sparse([[1,4],[3,2]]);
// sparse - array
var b = [[5,8],[7,6]];
var c = bitAnd(a, b);
assert.deepEqual(c, math.sparse([[1,0],[3,2]]));
// sparse - dense
b = math.matrix([[5,8],[7,6]]);
c = bitAnd(a, b);
assert.deepEqual(c, math.sparse([[1,0],[3,2]]));
// sparse - sparse
b = math.sparse([[5,8],[7,6]]);
c = bitAnd(a, b);
assert.deepEqual(c, math.sparse([[1,0],[3,2]]));
// sparse - sparse pattern
b = new math.type.SparseMatrix({
index: [ 0, 1],
ptr: [ 0, 1, 2 ],
size: [ 2, 2 ]
});
c = bitAnd(a, b);
assert.deepEqual(
c,
new math.type.SparseMatrix({
index: [ 0, 1],
ptr: [ 0, 1, 2 ],
size: [ 2, 2 ]
}));
// sparse pattern - sparse
c = bitAnd(b, a);
assert.deepEqual(
c,
new math.type.SparseMatrix({
index: [ 0, 1],
ptr: [ 0, 1, 2 ],
size: [ 2, 2 ]
}));
});
it('should bitwise and matrices correctly', function () {
var a2 = math.matrix([[1,2],[3,4]]);
var a3 = math.matrix([[5,6],[7,8]]);
var a4 = bitAnd(a2, a3);
assert.ok(a4 instanceof math.type.Matrix);
assert.deepEqual(a4.size(), [2,2]);
assert.deepEqual(a4.valueOf(), [[1,2],[3,0]]);
var a5 = math.pow(a2, 2);
assert.ok(a5 instanceof math.type.Matrix);
assert.deepEqual(a5.size(), [2,2]);
assert.deepEqual(a5.valueOf(), [[7,10],[15,22]]);
});
it('should bitwise and a scalar and a matrix correctly', function () {
assert.deepEqual(bitAnd(12, math.matrix([3,9])), math.matrix([0,8]));
assert.deepEqual(bitAnd(math.matrix([3,9]), 12), math.matrix([0,8]));
});
it('should bitwise and a scalar and an array correctly', function () {
assert.deepEqual(bitAnd(12, [3,9]), [0,8]);
assert.deepEqual(bitAnd([3,9], 12), [0,8]);
});
it('should bitwise and a matrix and an array correctly', function () {
var a = [6,4,28];
var b = math.matrix([13,92,101]);
var c = bitAnd(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([4,4,4]));
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {bitAnd(1);}, /TypeError: Too few arguments/);
assert.throws(function () {bitAnd(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {bitAnd(new Date(), true);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitAnd(true, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitAnd(true, undefined);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitAnd(undefined, true);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX bitAnd', function () {
var expression = math.parse('bitAnd(4,2)');
assert.equal(expression.toTex(), '\\left(4\\&2\\right)');
});
});

View File

@@ -0,0 +1,69 @@
// test bitNot
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
bitNot = math.bitNot;
describe('bitNot', function () {
it('should return bitwise not of a boolean', function () {
assert.equal(bitNot(true), -2);
assert.equal(bitNot(false), -1);
});
it('should return bitwise not of null', function () {
assert.equal(bitNot(null), -1);
});
it('should perform bitwise not of a number', function () {
assert.deepEqual(bitNot(2), -3);
assert.deepEqual(bitNot(-2), 1);
assert.deepEqual(bitNot(0), -1);
});
it('should perform bitwise not of a bignumber', function() {
assert.deepEqual(bitNot(bignumber(2)), bignumber(-3));
assert.deepEqual(bitNot(bignumber(-2)), bignumber(1));
assert.deepEqual(bitNot(bignumber('1.2345e30')), bignumber('-1234500000000000000000000000001'));
});
it('should throw an error if the parameters are not integers', function () {
assert.throws(function () {
bitNot(1.1);
}, /Integer expected in function bitNot/);
assert.throws(function () {
bitNot(bignumber(1.1));
}, /Integer expected in function bitNot/);
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {bitNot(math.unit('5cm'))}, /TypeError: Unexpected type of argument/);
});
it('should perform element-wise bitwise not on a matrix', function () {
a2 = math.matrix([[1,2],[3,4]]);
var a7 = bitNot(a2);
assert.ok(a7 instanceof math.type.Matrix);
assert.deepEqual(a7.size(), [2,2]);
assert.deepEqual(a7.valueOf(), [[-2,-3],[-4,-5]]);
});
it('should perform element-wise bitwise not on an array', function () {
assert.deepEqual(bitNot([[1,2],[3,4]]), [[-2,-3],[-4,-5]]);
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {bitNot()}, /TypeError: Too few arguments/);
assert.throws(function () {bitNot(1, 2)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of argument', function () {
assert.throws(function () {bitNot(new Date())}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitNot(undefined)}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX bitNot', function () {
var expression = math.parse('bitNot(4)');
assert.equal(expression.toTex(), '~\\left(4\\right)');
});
});

View File

@@ -0,0 +1,220 @@
// test bitOr
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
bitOr = math.bitOr;
describe('bitOr', function () {
it('should bitwise or two numbers', function () {
assert.equal(bitOr(53, 131), 183);
assert.equal(bitOr(2, 3), 3);
assert.equal(bitOr(-2, 3), -1);
assert.equal(bitOr(2, -3), -1);
assert.equal(bitOr(-5, -3), -1);
});
it('should bitwise or booleans', function () {
assert.equal(bitOr(true, true), 1);
assert.equal(bitOr(true, false), 1);
assert.equal(bitOr(false, true), 1);
assert.equal(bitOr(false, false), 0);
});
it('should bitwise or numbers and null', function () {
assert.equal(math.bitOr(null, null), 0);
assert.equal(math.bitOr(null, 1), 1);
assert.equal(math.bitOr(1, null), 1);
});
it('should bitwise or mixed numbers and booleans', function () {
assert.equal(bitOr(0, true), 1);
assert.equal(bitOr(0, false), 0);
assert.equal(bitOr(true, 0), 1);
assert.equal(bitOr(false, 0), 0);
});
it('should bitwise or bignumbers', function () {
assert.deepEqual(bitOr(bignumber(1), bignumber(2)), bignumber(3));
assert.deepEqual(bitOr(bignumber('-1.0e+31'), bignumber('-1.0e+32')), bignumber('-8726602014714682917963150917632'));
assert.deepEqual(bitOr(bignumber('1.0e+31'), bignumber('1.0e+32')), bignumber('101273397985285317082038996566016'));
assert.deepEqual(bitOr(bignumber('-1.0e+31'), bignumber('1.0e+32')), bignumber('-1273397985285317082038996566016'));
assert.deepEqual(bitOr(bignumber('1.0e+31'), bignumber('-1.0e+32')), bignumber('-91273397985285317082036849082368'));
});
it('should bitwise or mixed numbers and bignumbers', function () {
assert.deepEqual(bitOr(bignumber(1), 2), bignumber(3));
assert.deepEqual(bitOr(1, bignumber(2)), bignumber(3));
assert.deepEqual(bitOr(bignumber(7), 9), bignumber(15));
assert.deepEqual(bitOr(7, bignumber(9)), bignumber(15));
});
it('should bitwise or mixed booleans and bignumbers', function () {
assert.deepEqual(bitOr(bignumber(1), false), bignumber(1));
assert.deepEqual(bitOr(bignumber(2), true), bignumber(3));
assert.deepEqual(bitOr(false, bignumber(1)), bignumber(1));
assert.deepEqual(bitOr(true, bignumber(2)), bignumber(3));
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {bitOr(math.unit('5cm'), 2);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitOr(2, math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitOr(math.unit('2cm'), math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
});
it('should throw an error if the parameters are not integers', function () {
assert.throws(function () {
bitOr(1.1, 1);
}, /Integers expected in function bitOr/);
assert.throws(function () {
bitOr(1, 1.1);
}, /Integers expected in function bitOr/);
assert.throws(function () {
bitOr(1.1, 1.1);
}, /Integers expected in function bitOr/);
assert.throws(function () {
bitOr(bignumber(1.1), 1);
}, /Integers expected in function bitOr/);
assert.throws(function () {
bitOr(1, bignumber(1.1));
}, /Integers expected in function bitOr/);
assert.throws(function () {
bitOr(bignumber(1.1), bignumber(1));
}, /Integers expected in function bitOr/);
assert.throws(function () {
bitOr(bignumber(1), bignumber(1.1));
}, /Integers expected in function bitOr/);
});
it('should bitwise or arrays correctly', function () {
var a = [[1,4],[3,2]];
// array - array
var b = [[5,8],[7,6]];
var c = bitOr(a, b);
assert.deepEqual(c, [[5,12],[7,6]]);
// array - dense
b = math.matrix([[5,8],[7,6]]);
c = bitOr(a, b);
assert.deepEqual(c, math.matrix([[5,12],[7,6]]));
// array - sparse
b = math.sparse([[5,8],[7,6]]);
c = bitOr(a, b);
assert.deepEqual(c, math.matrix([[5,12],[7,6]]));
});
it('should bitwise or dense matrix correctly', function () {
var a = math.matrix([[1,4],[3,2]]);
// dense - array
var b = [[5,8],[7,6]];
var c = bitOr(a, b);
assert.deepEqual(c, math.matrix([[5,12],[7,6]]));
// dense - dense
b = math.matrix([[5,8],[7,6]]);
c = bitOr(a, b);
assert.deepEqual(c, math.matrix([[5,12],[7,6]]));
// dense - sparse
b = math.sparse([[5,8],[7,6]]);
c = bitOr(a, b);
assert.deepEqual(c, math.matrix([[5,12],[7,6]]));
});
it('should bitwise or sparse matrix correctly', function () {
var a = math.sparse([[1,4],[3,2]]);
// sparse - array
var b = [[5,8],[7,6]];
var c = bitOr(a, b);
assert.deepEqual(c, math.matrix([[5,12],[7,6]]));
// sparse - dense
b = math.matrix([[5,8],[7,6]]);
c = bitOr(a, b);
assert.deepEqual(c, math.matrix([[5,12],[7,6]]));
// sparse - sparse
b = math.sparse([[5,8],[7,6]]);
c = bitOr(a, b);
assert.deepEqual(c, math.sparse([[5,12],[7,6]]));
// sparse - sparse pattern
a = math.sparse([[1,1],[0,0]]);
b = new math.type.SparseMatrix({
index: [ 0, 1],
ptr: [ 0, 1, 2 ],
size: [ 2, 2 ]
});
c = bitOr(a, b);
assert.deepEqual(
c,
new math.type.SparseMatrix({
index: [0, 0, 1],
ptr: [0, 1, 3],
size: [2, 2]
}));
// sparse pattern - sparse
c = bitOr(b, a);
assert.deepEqual(
c,
new math.type.SparseMatrix({
index: [0, 1, 0], // row index not in order, not a problem!
ptr: [0, 1, 3],
size: [2, 2]
}));
});
it('should bitwise or matrices correctly', function () {
var a2 = math.matrix([[1,2],[3,4]]);
var a3 = math.matrix([[5,6],[7,8]]);
var a4 = bitOr(a2, a3);
assert.ok(a4 instanceof math.type.Matrix);
assert.deepEqual(a4.size(), [2,2]);
assert.deepEqual(a4.valueOf(), [[5,6],[7,12]]);
var a5 = math.pow(a2, 2);
assert.ok(a5 instanceof math.type.Matrix);
assert.deepEqual(a5.size(), [2,2]);
assert.deepEqual(a5.valueOf(), [[7,10],[15,22]]);
});
it('should bitwise or a scalar and a matrix correctly', function () {
assert.deepEqual(bitOr(12, math.matrix([3,9])), math.matrix([15,13]));
assert.deepEqual(bitOr(math.matrix([3,9]), 12), math.matrix([15,13]));
});
it('should bitwise or a scalar and an array correctly', function () {
assert.deepEqual(bitOr(12, [3,9]), [15,13]);
assert.deepEqual(bitOr([3,9], 12), [15,13]);
});
it('should bitwise or a matrix and an array correctly', function () {
var a = [6,4,28];
var b = math.matrix([13,92,101]);
var c = bitOr(a, b);
assert.ok(c instanceof math.type.Matrix);
assert.deepEqual(c, math.matrix([15,92,125]));
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {bitOr(1);}, /TypeError: Too few arguments/);
assert.throws(function () {bitOr(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {bitOr(new Date(), true);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitOr(true, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitOr(true, undefined);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitOr(undefined, true);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX bitOr', function () {
var expression = math.parse('bitOr(2,3)');
assert.equal(expression.toTex(), '\\left(2|3\\right)');
});
});

View File

@@ -0,0 +1,169 @@
// test bitXor
var assert = require('assert'),
math = require('../../../index'),
matrix = math.matrix,
sparse = math.sparse,
bignumber = math.bignumber,
bitXor = math.bitXor;
describe('bitXor', function () {
it('should xor two numbers', function () {
assert.equal(bitXor(53, 131), 182);
assert.equal(bitXor(2, 3), 1);
assert.equal(bitXor(-2, 3), -3);
assert.equal(bitXor(2, -3), -1);
assert.equal(bitXor(-5, -3), 6);
});
it('should xor booleans', function () {
assert.equal(bitXor(true, true), 0);
assert.equal(bitXor(true, false), 1);
assert.equal(bitXor(false, true), 1);
assert.equal(bitXor(false, false), 0);
});
it('should xor numbers and null', function () {
assert.equal(math.bitXor(null, null), 0);
assert.equal(math.bitXor(null, 1), 1);
assert.equal(math.bitXor(1, null), 1);
});
it('should xor mixed numbers and booleans', function () {
assert.equal(bitXor(0, true), 1);
assert.equal(bitXor(0, false), 0);
assert.equal(bitXor(true, 0), 1);
assert.equal(bitXor(false, 0), 0);
assert.equal(bitXor(true, 1), 0);
assert.equal(bitXor(false, 1), 1);
});
it('should bitwise xor bignumbers', function () {
assert.deepEqual(bitXor(bignumber(1), bignumber(2)), bignumber(3));
assert.deepEqual(bitXor(bignumber('-1.0e+31'), bignumber('-1.0e+32')), bignumber('92546795970570634164073698164736'));
assert.deepEqual(bitXor(bignumber('1.0e+31'), bignumber('1.0e+32')), bignumber('92546795970570634164077993132032'));
assert.deepEqual(bitXor(bignumber('-1.0e+31'), bignumber('1.0e+32')), bignumber('-92546795970570634164077993132032'));
assert.deepEqual(bitXor(bignumber('1.0e+31'), bignumber('-1.0e+32')), bignumber('-92546795970570634164073698164736'));
});
it('should bitwise xor mixed numbers and bignumbers', function () {
assert.deepEqual(bitXor(bignumber(1), 2), bignumber(3));
assert.deepEqual(bitXor(1, bignumber(2)), bignumber(3));
assert.deepEqual(bitXor(bignumber(7), 9), bignumber(14));
assert.deepEqual(bitXor(7, bignumber(9)), bignumber(14));
});
it('should bitwise xor mixed booleans and bignumbers', function () {
assert.deepEqual(bitXor(bignumber(1), true), bignumber(0));
assert.deepEqual(bitXor(bignumber(1), false), bignumber(1));
assert.deepEqual(bitXor(true, bignumber(3)), bignumber(2));
assert.deepEqual(bitXor(false, bignumber(3)), bignumber(3));
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {bitXor(math.unit('5cm'), 2);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitXor(2, math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitXor(math.unit('2cm'), math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
});
it('should throw an error if the parameters are not integers', function () {
assert.throws(function () {
bitXor(1.1, 1);
}, /Integers expected in function bitXor/);
assert.throws(function () {
bitXor(1, 1.1);
}, /Integers expected in function bitXor/);
assert.throws(function () {
bitXor(1.1, 1.1);
}, /Integers expected in function bitXor/);
assert.throws(function () {
bitXor(bignumber(1.1), 1);
}, /Integers expected in function bitXor/);
assert.throws(function () {
bitXor(1, bignumber(1.1));
}, /Integers expected in function bitXor/);
assert.throws(function () {
bitXor(bignumber(1.1), bignumber(1));
}, /Integers expected in function bitXor/);
assert.throws(function () {
bitXor(bignumber(1), bignumber(1.1));
}, /Integers expected in function bitXor/);
});
describe('Array', function () {
it('should bitwise xor array - scalar', function () {
assert.deepEqual(bitXor(12, [3, 9]), [15, 5]);
assert.deepEqual(bitXor([3, 9], 12), [15, 5]);
});
it('should bitwise xor array - array', function () {
assert.deepEqual(bitXor([[1, 2], [3, 4]], [[5, 6], [7, 8]]), [[4, 4],[4, 12]]);
});
it('should bitwise xor array - dense matrix', function () {
assert.deepEqual(bitXor([[1, 2], [3, 4]], matrix([[5, 6], [7, 8]])), matrix([[4, 4],[4, 12]]));
});
it('should bitwise xor array - sparse matrix', function () {
assert.deepEqual(bitXor([[1, 2], [3, 4]], sparse([[5, 6], [7, 8]])), matrix([[4, 4],[4, 12]]));
});
});
describe('DenseMatrix', function () {
it('should bitwise xor dense matrix - scalar', function () {
assert.deepEqual(bitXor(12, matrix([3, 9])), matrix([15, 5]));
assert.deepEqual(bitXor(matrix([3, 9]), 12), matrix([15, 5]));
});
it('should bitwise xor dense matrix - array', function () {
assert.deepEqual(bitXor(matrix([[1, 2], [3, 4]]), [[5, 6], [7, 8]]), matrix([[4, 4],[4, 12]]));
});
it('should bitwise xor dense matrix - dense matrix', function () {
assert.deepEqual(bitXor(matrix([[1, 2], [3, 4]]), matrix([[5, 6], [7, 8]])), matrix([[4, 4],[4, 12]]));
});
it('should bitwise xor dense matrix - sparse matrix', function () {
assert.deepEqual(bitXor(matrix([[1, 2], [3, 4]]), sparse([[5, 6], [7, 8]])), matrix([[4, 4],[4, 12]]));
});
});
describe('SparseMatrix', function () {
it('should bitwise xor sparse matrix - scalar', function () {
assert.deepEqual(bitXor(12, sparse([[3, 9], [9, 3]])), matrix([[15, 5], [5, 15]]));
assert.deepEqual(bitXor(sparse([[3, 9], [9, 3]]), 12), matrix([[15, 5], [5, 15]]));
});
it('should bitwise xor sparse matrix - array', function () {
assert.deepEqual(bitXor(sparse([[1, 2], [3, 4]]), [[5, 6], [7, 8]]), matrix([[4, 4],[4, 12]]));
});
it('should bitwise xor sparse matrix - dense matrix', function () {
assert.deepEqual(bitXor(sparse([[1, 2], [3, 4]]), matrix([[5, 6], [7, 8]])), matrix([[4, 4],[4, 12]]));
});
it('should bitwise xor sparse matrix - sparse matrix', function () {
assert.deepEqual(bitXor(sparse([[1, 2], [3, 4]]), sparse([[5, 6], [7, 8]])), matrix([[4, 4],[4, 12]]));
});
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {bitXor(1);}, /TypeError: Too few arguments/);
assert.throws(function () {bitXor(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {bitXor(new Date(), true);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitXor(true, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitXor(true, undefined);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {bitXor(undefined, true);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX bitXor', function () {
var expression = math.parse('bitXor(2,3)');
assert.equal(expression.toTex(), '\\left(2\\underline{|}3\\right)');
});
});

View File

@@ -0,0 +1,182 @@
// test leftShift
var assert = require('assert'),
math = require('../../../index'),
matrix = math.matrix,
sparse = math.sparse,
bignumber = math.bignumber,
leftShift = math.leftShift;
describe('leftShift', function () {
it('should left shift a number by a given amount', function () {
assert.equal(leftShift(0, 1000), 0);
assert.equal(leftShift(2, 0), 2);
assert.equal(leftShift(2, 3), 16);
assert.equal(leftShift(2, 4), 32);
assert.equal(leftShift(-2, 2), -8);
assert.equal(leftShift(3, 3), 24);
assert.equal(leftShift(-3, 2), -12);
assert.equal(leftShift(-3, 3), -24);
});
it('should left shift booleans by a boolean amount', function () {
assert.equal(leftShift(true, true), 2);
assert.equal(leftShift(true, false), 1);
assert.equal(leftShift(false, true), 0);
assert.equal(leftShift(false, false), 0);
});
it('should left shift with a mix of numbers and booleans', function () {
assert.equal(leftShift(2, true), 4);
assert.equal(leftShift(2, false), 2);
assert.equal(leftShift(true, 2), 4);
assert.equal(leftShift(false, 2), 0);
});
it('should left shift numbers and null', function () {
assert.equal(leftShift(1, null), 1);
assert.equal(leftShift(null, 1), 0);
});
it('should left shift bignumbers', function () {
assert.deepEqual(leftShift(bignumber(2), bignumber(3)), bignumber(16));
assert.deepEqual(leftShift(bignumber(500), bignumber(100)), bignumber('633825300114114700748351602688000'));
assert.deepEqual(leftShift(bignumber(-1), bignumber(2)), bignumber(-4));
assert.equal(leftShift(bignumber(0), bignumber(-2)).isNaN(), true);
assert.deepEqual(leftShift(bignumber(Infinity), bignumber(2)).toString(), 'Infinity');
assert.equal(leftShift(bignumber(Infinity), bignumber(Infinity)).isNaN(), true);
});
it('should left shift mixed numbers and bignumbers', function () {
assert.deepEqual(leftShift(bignumber(2), 3), bignumber(16));
assert.deepEqual(leftShift(bignumber(500), 100), bignumber('633825300114114700748351602688000'));
assert.deepEqual(leftShift(2, bignumber(3)), bignumber(16));
assert.deepEqual(leftShift(-1, bignumber(2)), bignumber(-4));
assert.deepEqual(leftShift(bignumber(-1), 2), bignumber(-4));
assert.equal(leftShift(bignumber(0), -2).isNaN(), true);
assert.equal(leftShift(bignumber(Infinity), Infinity).isNaN(), true);
});
it('should left shift mixed booleans and bignumbers', function () {
assert.deepEqual(leftShift(true, bignumber(3)), bignumber(8));
assert.deepEqual(leftShift(false, bignumber(3)), bignumber(0));
assert.deepEqual(leftShift(bignumber(3), false), bignumber(3));
assert.deepEqual(leftShift(bignumber(3), true), bignumber(6));
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {leftShift(math.unit('5cm'), 2);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {leftShift(2, math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
assert.throws(function () {leftShift(math.unit('2cm'), math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
});
it('should throw an error if the parameters are not integers', function () {
assert.throws(function () {
leftShift(1.1, 1);
}, /Integers expected in function leftShift/);
assert.throws(function () {
leftShift(1, 1.1);
}, /Integers expected in function leftShift/);
assert.throws(function () {
leftShift(1.1, 1.1);
}, /Integers expected in function leftShift/);
assert.throws(function () {
leftShift(bignumber(1.1), 1);
}, /Integers expected in function leftShift/);
assert.throws(function () {
leftShift(1, bignumber(1.1));
}, /Integers expected in function leftShift/);
assert.throws(function () {
leftShift(bignumber(1.1), bignumber(1));
}, /Integers expected in function leftShift/);
assert.throws(function () {
leftShift(bignumber(1), bignumber(1.1));
}, /Integers expected in function leftShift/);
});
describe('Array', function () {
it('should left shift array and scalar', function () {
assert.deepEqual(leftShift([[1, 2], [8, 0]], 2), [[4, 8], [32, 0]]);
assert.deepEqual(leftShift(2, [[1, 2], [8, 0]]), [[4, 8], [512, 2]]);
});
it('should left shift array - array', function () {
assert.deepEqual(leftShift([[1, 2], [8, 0]], [[4, 8], [32, 0]]), [[16, 512], [8, 0]]);
assert.deepEqual(leftShift([[4, 8], [32, 0]], [[1, 2], [8, 0]]), [[8, 32], [8192, 0]]);
});
it('should left shift array - dense matrix', function () {
assert.deepEqual(leftShift([[1, 2], [8, 0]], matrix([[4, 8], [32, 0]])), matrix([[16, 512], [8, 0]]));
assert.deepEqual(leftShift([[4, 8], [32, 0]], matrix([[1, 2], [8, 0]])), matrix([[8, 32], [8192, 0]]));
});
it('should left shift array - sparse matrix', function () {
assert.deepEqual(leftShift([[1, 2], [8, 0]], sparse([[4, 8], [32, 0]])), matrix([[16, 512], [8, 0]]));
assert.deepEqual(leftShift([[4, 8], [32, 0]], sparse([[1, 2], [8, 0]])), matrix([[8, 32], [8192, 0]]));
});
});
describe('DenseMatrix', function () {
it('should left shift dense matrix and scalar', function () {
assert.deepEqual(leftShift(matrix([[1, 2], [8, 0]]), 2), matrix([[4, 8], [32, 0]]));
assert.deepEqual(leftShift(2, matrix([[1, 2], [8, 0]])), matrix([[4, 8], [512, 2]]));
});
it('should left shift dense matrix - array', function () {
assert.deepEqual(leftShift(matrix([[1, 2], [8, 0]]), [[4, 8], [32, 0]]), matrix([[16, 512], [8, 0]]));
assert.deepEqual(leftShift(matrix([[4, 8], [32, 0]]), [[1, 2], [8, 0]]), matrix([[8, 32], [8192, 0]]));
});
it('should left shift dense matrix - dense matrix', function () {
assert.deepEqual(leftShift(matrix([[1, 2], [8, 0]]), matrix([[4, 8], [32, 0]])), matrix([[16, 512], [8, 0]]));
assert.deepEqual(leftShift(matrix([[4, 8], [32, 0]]), matrix([[1, 2], [8, 0]])), matrix([[8, 32], [8192, 0]]));
});
it('should left shift dense matrix - sparse matrix', function () {
assert.deepEqual(leftShift(matrix([[1, 2], [8, 0]]), sparse([[4, 8], [32, 0]])), matrix([[16, 512], [8, 0]]));
assert.deepEqual(leftShift(matrix([[4, 8], [32, 0]]), sparse([[1, 2], [8, 0]])), matrix([[8, 32], [8192, 0]]));
});
});
describe('SparseMatrix', function () {
it('should left shift sparse matrix and scalar', function () {
assert.deepEqual(leftShift(sparse([[1, 2], [8, 0]]), 2), sparse([[4, 8], [32, 0]]));
assert.deepEqual(leftShift(2, sparse([[1, 2], [8, 0]])), matrix([[4, 8], [512, 2]]));
});
it('should left shift sparse matrix - array', function () {
assert.deepEqual(leftShift(sparse([[1, 2], [8, 0]]), [[4, 8], [32, 0]]), sparse([[16, 512], [8, 0]]));
assert.deepEqual(leftShift(sparse([[4, 8], [32, 0]]), [[1, 2], [8, 0]]), sparse([[8, 32], [8192, 0]]));
});
it('should left shift sparse matrix - dense matrix', function () {
assert.deepEqual(leftShift(sparse([[1, 2], [8, 0]]), matrix([[4, 8], [32, 0]])), sparse([[16, 512], [8, 0]]));
assert.deepEqual(leftShift(sparse([[4, 8], [32, 0]]), matrix([[1, 2], [8, 0]])), sparse([[8, 32], [8192, 0]]));
});
it('should left shift sparse matrix - sparse matrix', function () {
assert.deepEqual(leftShift(sparse([[1, 2], [8, 0]]), sparse([[4, 8], [32, 0]])), sparse([[16, 512], [8, 0]]));
assert.deepEqual(leftShift(sparse([[4, 8], [32, 0]]), sparse([[1, 2], [8, 0]])), sparse([[8, 32], [8192, 0]]));
});
});
it('should throw an error if used with wrong number of arguments', function () {
assert.throws(function () {leftShift(1);}, /TypeError: Too few arguments/);
assert.throws(function () {leftShift(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {leftShift(new Date(), true);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {leftShift(true, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {leftShift(true, undefined);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {leftShift(undefined, true);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX leftShift', function () {
var expression = math.parse('leftShift(2,3)');
assert.equal(expression.toTex(), '\\left(2<<3\\right)');
});
});

View File

@@ -0,0 +1,186 @@
// test rightArithShift
var assert = require('assert'),
math = require('../../../index'),
matrix = math.matrix,
sparse = math.sparse,
bignumber = math.bignumber,
rightArithShift = math.rightArithShift;
describe('rightArithShift', function () {
it('should right arithmetically shift a number by a given amount', function () {
assert.equal(rightArithShift(0, 1000), 0);
assert.equal(rightArithShift(2, 0), 2);
assert.equal(rightArithShift(12, 3), 1);
assert.equal(rightArithShift(32, 4), 2);
assert.equal(rightArithShift(-1, 1000), -1);
assert.equal(rightArithShift(-12, 2), -3);
assert.equal(rightArithShift(122, 3), 15);
assert.equal(rightArithShift(-13, 2), -4);
assert.equal(rightArithShift(-13, 3), -2);
});
it('should right arithmetically shift booleans by a boolean amount', function () {
assert.equal(rightArithShift(true, true), 0);
assert.equal(rightArithShift(true, false), 1);
assert.equal(rightArithShift(false, true), 0);
assert.equal(rightArithShift(false, false), 0);
});
it('should right arithmetically shift with a mix of numbers and booleans', function () {
assert.equal(rightArithShift(2, true), 1);
assert.equal(rightArithShift(2, false), 2);
assert.equal(rightArithShift(true, 0), 1);
assert.equal(rightArithShift(true, 1), 0);
assert.equal(rightArithShift(false, 2), 0);
});
it('should right arithmetically shift numbers and null', function () {
assert.equal(rightArithShift(1, null), 1);
assert.equal(rightArithShift(null, 1), 0);
});
it('should right arithmetically shift bignumbers', function () {
assert.deepEqual(rightArithShift(bignumber(17), bignumber(3)), bignumber(2));
assert.deepEqual(rightArithShift(bignumber('633825300114114700748351602688000'), bignumber(100)), bignumber(500));
assert.deepEqual(rightArithShift(bignumber(-17), bignumber(3)), bignumber(-3));
assert.equal(rightArithShift(bignumber(-17), bignumber(-3)).isNaN(), true);
assert.equal(rightArithShift(bignumber(Infinity), bignumber(Infinity)).isNaN(), true);
assert.deepEqual(rightArithShift(bignumber(-Infinity), bignumber(Infinity)), bignumber(-1));
});
it('should right arithmetically shift mixed numbers and bignumbers', function () {
assert.deepEqual(rightArithShift(bignumber(17), 3), bignumber(2));
assert.deepEqual(rightArithShift(bignumber('-633825300114114700748351602688000'), 100), bignumber(-500));
assert.equal(rightArithShift(bignumber(-17), -3).isNaN(), true);
assert.deepEqual(rightArithShift(17, bignumber(3)), bignumber(2));
assert.deepEqual(rightArithShift(-17, bignumber(3)), bignumber(-3));
assert.equal(rightArithShift(-3, bignumber(-17)).isNaN(), true);
assert.deepEqual(rightArithShift(bignumber(-Infinity), Infinity), bignumber(-1));
assert.equal(rightArithShift(bignumber(Infinity), Infinity).isNaN(), true);
assert.equal(rightArithShift(Infinity, bignumber(Infinity)).isNaN(), true);
});
it('should right arithmetically shift mixed booleans and bignumbers', function () {
assert.deepEqual(rightArithShift(true, bignumber(0)), bignumber(1));
assert.deepEqual(rightArithShift(false, bignumber('1000000')), bignumber(0));
assert.deepEqual(rightArithShift(bignumber(3), false), bignumber(3));
assert.deepEqual(rightArithShift(bignumber(3), true), bignumber(1));
});
it('should throw an error if the parameters are not integers', function () {
assert.throws(function () {
rightArithShift(1.1, 1);
}, /Integers expected in function rightArithShift/);
assert.throws(function () {
rightArithShift(1, 1.1);
}, /Integers expected in function rightArithShift/);
assert.throws(function () {
rightArithShift(1.1, 1.1);
}, /Integers expected in function rightArithShift/);
assert.throws(function () {
rightArithShift(bignumber(1.1), 1);
}, /Integers expected in function rightArithShift/);
assert.throws(function () {
rightArithShift(1, bignumber(1.1));
}, /Integers expected in function rightArithShift/);
assert.throws(function () {
rightArithShift(bignumber(1.1), bignumber(1));
}, /Integers expected in function rightArithShift/);
assert.throws(function () {
rightArithShift(bignumber(1), bignumber(1.1));
}, /Integers expected in function rightArithShift/);
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {rightArithShift(math.unit('5cm'), 2)}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightArithShift(2, math.unit('5cm'))}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightArithShift(math.unit('2cm'), math.unit('5cm'))}, /TypeError: Unexpected type of argument/);
});
describe('Array', function () {
it('should right arithmetically shift array - scalar', function () {
assert.deepEqual(rightArithShift([[1, 2], [8, 0]], 2), [[0, 0], [2, 0]]);
assert.deepEqual(rightArithShift(2, [[1, 2], [8, 0]]), [[1, 0], [0, 2]]);
});
it('should right arithmetically shift array - array', function () {
assert.deepEqual(rightArithShift([[1, 2], [8, 0]], [[4, 8], [32, 0]]), [[0, 0], [8, 0]]);
assert.deepEqual(rightArithShift([[4, 8], [32, 0]], [[1, 2], [8, 0]]), [[2, 2], [0, 0]]);
});
it('should right arithmetically shift array - dense matrix', function () {
assert.deepEqual(rightArithShift([[1, 2], [8, 0]], matrix([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift([[4, 8], [32, 0]], matrix([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
it('should right arithmetically shift array - sparse matrix', function () {
assert.deepEqual(rightArithShift([[1, 2], [8, 0]], sparse([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift([[4, 8], [32, 0]], sparse([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
});
describe('DenseMatrix', function () {
it('should right arithmetically shift dense matrix - scalar', function () {
assert.deepEqual(rightArithShift(matrix([[1, 2], [8, 0]]), 2), matrix([[0, 0], [2, 0]]));
assert.deepEqual(rightArithShift(2, matrix([[1, 2], [8, 0]])), matrix([[1, 0], [0, 2]]));
});
it('should right arithmetically shift dense matrix - array', function () {
assert.deepEqual(rightArithShift(matrix([[1, 2], [8, 0]]), [[4, 8], [32, 0]]), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift(matrix([[4, 8], [32, 0]]), [[1, 2], [8, 0]]), matrix([[2, 2], [0, 0]]));
});
it('should right arithmetically shift dense matrix - dense matrix', function () {
assert.deepEqual(rightArithShift(matrix([[1, 2], [8, 0]]), matrix([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift(matrix([[4, 8], [32, 0]]), matrix([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
it('should right arithmetically shift dense matrix - sparse matrix', function () {
assert.deepEqual(rightArithShift(matrix([[1, 2], [8, 0]]), sparse([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift(matrix([[4, 8], [32, 0]]), sparse([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
});
describe('SparseMatrix', function () {
it('should right arithmetically shift sparse matrix - scalar', function () {
assert.deepEqual(rightArithShift(sparse([[1, 2], [8, 0]]), 2), sparse([[0, 0], [2, 0]]));
assert.deepEqual(rightArithShift(2, sparse([[1, 2], [8, 0]])), matrix([[1, 0], [0, 2]]));
});
it('should right arithmetically shift sparse matrix - array', function () {
assert.deepEqual(rightArithShift(sparse([[1, 2], [8, 0]]), [[4, 8], [32, 0]]), sparse([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift(sparse([[4, 8], [32, 0]]), [[1, 2], [8, 0]]), sparse([[2, 2], [0, 0]]));
});
it('should right arithmetically shift sparse matrix - dense matrix', function () {
assert.deepEqual(rightArithShift(sparse([[1, 2], [8, 0]]), matrix([[4, 8], [32, 0]])), sparse([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift(sparse([[4, 8], [32, 0]]), matrix([[1, 2], [8, 0]])), sparse([[2, 2], [0, 0]]));
});
it('should right arithmetically shift sparse matrix - sparse matrix', function () {
assert.deepEqual(rightArithShift(sparse([[1, 2], [8, 0]]), sparse([[4, 8], [32, 0]])), sparse([[0, 0], [8, 0]]));
assert.deepEqual(rightArithShift(sparse([[4, 8], [32, 0]]), sparse([[1, 2], [8, 0]])), sparse([[2, 2], [0, 0]]));
});
});
it('should throw an error if used with wrong number of arguments', function () {
assert.throws(function () {rightArithShift(1)}, /TypeError: Too few arguments/);
assert.throws(function () {rightArithShift(1, 2, 3)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {rightArithShift(new Date(), true)}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightArithShift(true, new Date())}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightArithShift(true, undefined)}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightArithShift(undefined, true)}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX rightArithShift', function () {
var expression = math.parse('rightArithShift(3,2)');
assert.equal(expression.toTex(), '\\left(3>>2\\right)');
});
});

View File

@@ -0,0 +1,149 @@
// test rightLogShift
var assert = require('assert'),
math = require('../../../index'),
matrix = math.matrix,
sparse = math.sparse,
rightLogShift = math.rightLogShift;
describe('rightLogShift', function () {
it('should right logically shift a number by a given amount', function () {
assert.equal(rightLogShift(0, 1000), 0);
assert.equal(rightLogShift(2, 0), 2);
assert.equal(rightLogShift(12, 3), 1);
assert.equal(rightLogShift(32, 4), 2);
assert.equal(rightLogShift(-1, 1000), 16777215);
assert.equal(rightLogShift(-12, 2), 1073741821);
assert.equal(rightLogShift(122, 3), 15);
assert.equal(rightLogShift(-13, 2), 1073741820);
assert.equal(rightLogShift(-13, 3), 536870910);
});
it('should right logically shift booleans by a boolean amount', function () {
assert.equal(rightLogShift(true, true), 0);
assert.equal(rightLogShift(true, false), 1);
assert.equal(rightLogShift(false, true), 0);
assert.equal(rightLogShift(false, false), 0);
});
it('should right logically shift with a mix of numbers and booleans', function () {
assert.equal(rightLogShift(2, true), 1);
assert.equal(rightLogShift(2, false), 2);
assert.equal(rightLogShift(true, 0), 1);
assert.equal(rightLogShift(true, 1), 0);
assert.equal(rightLogShift(false, 2), 0);
});
it('should right logically shift numbers and null', function () {
assert.equal(rightLogShift(1, null), 1);
assert.equal(rightLogShift(null, 1), 0);
});
it('should throw an error if the parameters are not integers', function () {
assert.throws(function () {
rightLogShift(1.1, 1);
}, /Integers expected in function rightLogShift/);
assert.throws(function () {
rightLogShift(1, 1.1);
}, /Integers expected in function rightLogShift/);
assert.throws(function () {
rightLogShift(1.1, 1.1);
}, /Integers expected in function rightLogShift/);
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {rightLogShift(math.unit('5cm'), 2);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightLogShift(2, math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightLogShift(math.unit('2cm'), math.unit('5cm'));}, /TypeError: Unexpected type of argument/);
});
describe('Array', function () {
it('should right arithmetically shift array - scalar', function () {
assert.deepEqual(rightLogShift([[4, 8], [8, 0]], 2), [[1, 2], [2, 0]]);
assert.deepEqual(rightLogShift([[4, 8], [12, 16]], 2), [[1, 2], [3, 4]]);
assert.deepEqual(rightLogShift(2, [[1, 2], [8, 0]]), [[1, 0], [0, 2]]);
});
it('should right arithmetically shift array - array', function () {
assert.deepEqual(rightLogShift([[1, 2], [8, 0]], [[4, 8], [32, 0]]), [[0, 0], [8, 0]]);
assert.deepEqual(rightLogShift([[4, 8], [32, 0]], [[1, 2], [8, 0]]), [[2, 2], [0, 0]]);
});
it('should right arithmetically shift array - dense matrix', function () {
assert.deepEqual(rightLogShift([[1, 2], [8, 0]], matrix([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift([[4, 8], [32, 0]], matrix([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
it('should right arithmetically shift array - sparse matrix', function () {
assert.deepEqual(rightLogShift([[1, 2], [8, 0]], sparse([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift([[4, 8], [32, 0]], sparse([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
});
describe('DenseMatrix', function () {
it('should right arithmetically shift dense matrix - scalar', function () {
assert.deepEqual(rightLogShift(matrix([[4, 8], [8, 0]]), 2), matrix([[1, 2], [2, 0]]));
assert.deepEqual(rightLogShift(matrix([[4, 8], [12, 16]]), 2), matrix([[1, 2], [3, 4]]));
assert.deepEqual(rightLogShift(2, matrix([[1, 2], [8, 0]])), matrix([[1, 0], [0, 2]]));
});
it('should right arithmetically shift dense matrix - array', function () {
assert.deepEqual(rightLogShift(matrix([[1, 2], [8, 0]]), [[4, 8], [32, 0]]), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift(matrix([[4, 8], [32, 0]]), [[1, 2], [8, 0]]), matrix([[2, 2], [0, 0]]));
});
it('should right arithmetically shift dense matrix - dense matrix', function () {
assert.deepEqual(rightLogShift(matrix([[1, 2], [8, 0]]), matrix([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift(matrix([[4, 8], [32, 0]]), matrix([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
it('should right arithmetically shift dense matrix - sparse matrix', function () {
assert.deepEqual(rightLogShift(matrix([[1, 2], [8, 0]]), sparse([[4, 8], [32, 0]])), matrix([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift(matrix([[4, 8], [32, 0]]), sparse([[1, 2], [8, 0]])), matrix([[2, 2], [0, 0]]));
});
});
describe('SparseMatrix', function () {
it('should right arithmetically shift sparse matrix - scalar', function () {
assert.deepEqual(rightLogShift(sparse([[4, 8], [8, 0]]), 2), sparse([[1, 2], [2, 0]]));
assert.deepEqual(rightLogShift(sparse([[4, 8], [12, 16]]), 2), sparse([[1, 2], [3, 4]]));
assert.deepEqual(rightLogShift(2, sparse([[1, 2], [8, 0]])), matrix([[1, 0], [0, 2]]));
});
it('should right arithmetically shift sparse matrix - array', function () {
assert.deepEqual(rightLogShift(sparse([[1, 2], [8, 0]]), [[4, 8], [32, 0]]), sparse([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift(sparse([[4, 8], [32, 0]]), [[1, 2], [8, 0]]), sparse([[2, 2], [0, 0]]));
});
it('should right arithmetically shift sparse matrix - dense matrix', function () {
assert.deepEqual(rightLogShift(sparse([[1, 2], [8, 0]]), matrix([[4, 8], [32, 0]])), sparse([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift(sparse([[4, 8], [32, 0]]), matrix([[1, 2], [8, 0]])), sparse([[2, 2], [0, 0]]));
});
it('should right arithmetically shift sparse matrix - sparse matrix', function () {
assert.deepEqual(rightLogShift(sparse([[1, 2], [8, 0]]), sparse([[4, 8], [32, 0]])), sparse([[0, 0], [8, 0]]));
assert.deepEqual(rightLogShift(sparse([[4, 8], [32, 0]]), sparse([[1, 2], [8, 0]])), sparse([[2, 2], [0, 0]]));
});
});
it('should throw an error if used with wrong number of arguments', function () {
assert.throws(function () {rightLogShift(1);}, /TypeError: Too few arguments/);
assert.throws(function () {rightLogShift(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {rightLogShift(new Date(), true);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightLogShift(true, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightLogShift(true, undefined);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {rightLogShift(undefined, true);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX rightLogShift', function () {
var expression = math.parse('rightLogShift(1,2)');
assert.equal(expression.toTex(), '\\left(1>>>2\\right)');
});
});

View File

@@ -0,0 +1,44 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
bellNumbers = math.bellNumbers;
describe('bellNumbers', function() {
it('should calculate the number of partitions of a set', function() {
assert.equal(bellNumbers(3), 5);
assert.equal(bellNumbers(0), 1);
assert.equal(bellNumbers(8), 4140);
});
it('should calculate the bellNumbers of n items with BigNumbers', function(){
assert.deepEqual(bellNumbers(math.bignumber(2)), math.bignumber(2));
assert.deepEqual(bellNumbers(math.bignumber(3)), math.bignumber(5));
});
it('should not work with non-integer and negative input', function() {
assert.throws(function() {bellNumbers(0.5)}, TypeError);
assert.throws(function() {bellNumbers(-1)}, TypeError);
assert.throws(function() {bellNumbers(math.bignumber(-3))}, TypeError);
assert.throws(function() {bellNumbers(math.bignumber(3.5))}, TypeError);
});
it('should throw an error in case of non-integer input', function() {
assert.throws(function() {bellNumbers(5.2)}, /Non-negative integer value expected/);
});
it('should throw an error in case of negative input', function() {
assert.throws(function() {bellNumbers(-2)}, /Non-negative integer value expected/);
});
it('should throw an error in case of wrong number or type of arguments', function() {
assert.throws(function() {bellNumbers(5, 3, 2)});
assert.throws(function() {bellNumbers(true, "hello world")});
});
it('should LaTeX bellNumbers', function () {
var expression = math.parse('bellNumbers(3)');
assert.equal(expression.toTex(), '\\mathrm{B}_{3}');
});
});

View File

@@ -0,0 +1,44 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
catalan = math.catalan;
describe('catalan', function() {
it('should calculate the nth catalan number', function() {
assert.equal(catalan(3), 5);
assert.equal(catalan(0), 1);
assert.equal(catalan(8), 1430);
});
it('should calculate the nth catalan number with BigNumbers', function(){
assert.deepEqual(catalan(math.bignumber(7)), math.bignumber(429));
assert.deepEqual(catalan(math.bignumber(13)), math.bignumber(742900));
});
it('should not work with non-integer and negative input', function() {
assert.throws(function() {catalan(0.5)}, TypeError);
assert.throws(function() {catalan(-1)}, TypeError);
assert.throws(function() {catalan(math.bignumber(-3))}, TypeError);
assert.throws(function() {catalan(math.bignumber(3.5))}, TypeError);
});
it('should throw an error in case of non-integer input', function() {
assert.throws(function() {catalan(5.2)}, /Non-negative integer value expected/);
});
it('should throw an error in case of negative input', function() {
assert.throws(function() {catalan(-2)}, /Non-negative integer value expected/);
});
it('should throw an error in case of wrong number or type of arguments', function() {
assert.throws(function() {catalan(5, 3, 2)});
assert.throws(function() {catalan(true, "hello world")});
});
it('should LaTeX catalan', function () {
var expression = math.parse('catalan(3)');
assert.equal(expression.toTex(), '\\mathrm{C}_{3}');
});
});

View File

@@ -0,0 +1,34 @@
var assert = require('assert');
var error = require('../../../lib/error/index');
var math = require('../../../index');
var composition = math.composition;
describe('composition', function() {
it('should calculate the number of ways to compose a set of n objects into k non-empty subsets', function() {
assert.equal(composition(5,3), 6);
assert.equal(composition(1,1), 1);
assert.equal(composition(8,3), 21);
});
it('should calculate the composition of n items taken k at a time with BigNumbers', function(){
assert.deepEqual(composition(math.bignumber(7), math.bignumber(5)), math.bignumber(15));
assert.deepEqual(composition(math.bignumber(70), math.bignumber(3)), math.bignumber(2346));
assert.deepEqual(composition(math.bignumber(56), math.bignumber(11)), math.bignumber(29248649430));
});
it('should not work with non-integer and negative input', function() {
assert.throws(function() {composition(0.5, 3)}, /TypeError: Positive integer value expected in function composition/);
assert.throws(function() {composition(-2, 3)}, /TypeError: Positive integer value expected in function composition/);
assert.throws(function() {composition(6, -2)}, /TypeError: Positive integer value expected in function composition/);
assert.throws(function() {composition(3, 5)}, /TypeError: k must be less than or equal to n in function composition/);
assert.throws(function() {composition(math.bignumber(3), math.bignumber(5))}, /TypeError: k must be less than or equal to n in function composition/);
assert.throws(function() {composition(math.bignumber(3.5), math.bignumber(-3))}, /TypeError: Positive integer value expected in function composition/);
assert.throws(function() {composition(math.bignumber(3.5), 0.25)}, /TypeError: Positive integer value expected in function composition/);
});
it('should not work with the wrong number or type of arguments', function() {
assert.throws(function() {composition(5, 3, 2)});
assert.throws(function() {composition(true, "hello world")});
});
});

View File

@@ -0,0 +1,39 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
stirlingS2 = math.stirlingS2;
describe('stirlingS2', function() {
it('should calculate the number of ways to partition a set of n objects into k non-empty subsets', function() {
assert.equal(stirlingS2(5,3), 25);
assert.equal(stirlingS2(0,0), 1);
assert.equal(stirlingS2(8,7), 28);
});
it('should calculate the stirlingS2 of n items taken k at a time with BigNumbers', function(){
assert.deepEqual(stirlingS2(math.bignumber(7), math.bignumber(5)),math.bignumber(140));
assert.deepEqual(stirlingS2(math.bignumber(8), math.bignumber(6)),math.bignumber(266));
});
it('should not work with non-integer and negative input', function() {
assert.throws(function() {stirlingS2(0.5, 3)}, /Non-negative integer value expected/);
assert.throws(function() {stirlingS2(-2, 3)}, /Non-negative integer value expected/);
assert.throws(function() {stirlingS2(3, 5)}, /k must be less than or equal to n in function stirlingS2/);
assert.throws(function() {stirlingS2(math.bignumber(3), math.bignumber(5))}, /k must be less than or equal to n in function stirlingS2/);
assert.throws(function() {stirlingS2(math.bignumber(3.5), math.bignumber(-3))}, /Non-negative integer value expected/);
assert.throws(function() {stirlingS2(math.bignumber(3.5), 1/3)}, /Non-negative integer value expected/);
});
it('should not work with the wrong number or type of arguments', function() {
assert.throws(function() {stirlingS2(5, 3, 2)});
assert.throws(function() {stirlingS2(true, "hello world")});
});
it('should LaTeX stirlingS2', function () {
var expression = math.parse('stirlingS2(3,2)');
assert.equal(expression.toTex(), '\\mathrm{S}\\left(3,2\\right)');
});
});

View File

@@ -0,0 +1,78 @@
var assert = require('assert');
var approx = require('../../../tools/approx');
var math = require('../../../index');
var arg = math.arg;
describe('arg', function() {
it('should compute the argument of a boolean', function () {
assert.equal(arg(true), 0);
assert.equal(arg(false), 0);
});
it('should compute the argument of null', function () {
assert.equal(arg(null), 0);
});
it('should compute the argument of a number', function () {
assert.equal(arg(1), 0);
assert.equal(arg(2), 0);
assert.equal(arg(0), 0);
approx.equal(arg(-2), 3.141592653589793);
});
it('should compute the argument of a bignumber', function () {
assert.deepEqual(arg(math.bignumber(1)), math.bignumber(0));
assert.deepEqual(arg(math.bignumber(-2)),
math.bignumber('3.141592653589793238462643383279502884197169399375105820974944592'));
});
it('should compute the argument of a complex number correctly', function() {
assert.equal(arg(math.complex('0')) / math.pi, 0);
assert.equal(arg(math.complex('1 + 0i')) / math.pi, 0);
assert.equal(arg(math.complex('1 + i')) / math.pi, 0.25);
assert.equal(arg(math.complex('0 + i')) / math.pi, 0.5);
assert.equal(arg(math.complex('-1 + i')) / math.pi, 0.75);
assert.equal(arg(math.complex('-1 + 0i')) / math.pi, 1);
assert.equal(arg(math.complex('-1 - i')) / math.pi, -0.75);
assert.equal(arg(math.complex('0 - i')) / math.pi, -0.5);
assert.equal(arg(math.complex('1 - i')) / math.pi, -0.25);
assert.equal(arg(math.i) / math.pi, 0.5);
});
it('should calculate the argument for each element in a matrix', function() {
assert.deepEqual(math.divide(arg([
math.i, math.unaryMinus(math.i), math.add(1,math.i)
]), math.pi), [
0.5, -0.5, 0.25
]);
assert.deepEqual(math.matrix(math.divide(arg([
math.i, math.unaryMinus(math.i), math.add(1,math.i)
]), math.pi)).valueOf(), [
0.5, -0.5, 0.25
]);
});
it('should compute the argument of a real number correctly', function() {
assert.equal(arg(2) / math.pi, 0);
assert.equal(arg(-2) / math.pi, 1);
});
it('should throw an error if used with a string', function() {
assert.throws(function () {arg('string')});
});
it('should throw an error if used with a unit', function() {
assert.throws(function () {arg(math.unit('5cm'))});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {arg()}, /TypeError: Too few arguments/);
assert.throws(function () {arg(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX arg', function () {
var expression = math.parse('arg(1+i)');
assert.equal(expression.toTex(), '\\arg\\left(1+ i\\right)');
});
});

View File

@@ -0,0 +1,56 @@
var assert = require('assert');
var math = require('../../../index');
var conj = math.conj;
describe('conj', function() {
it('should compute the conjugate of a boolean', function () {
assert.strictEqual(conj(true), 1);
assert.strictEqual(conj(false), 0);
});
it('should compute the conjugate of null', function () {
assert.strictEqual(conj(null), 0);
});
it('should compute the conjugate of a number', function () {
assert.equal(conj(1), 1);
assert.equal(conj(2), 2);
assert.equal(conj(0), 0);
assert.equal(conj(-2), -2);
});
it('should compute the conjugate of a bignumber', function () {
assert.deepEqual(conj(math.bignumber(2)), math.bignumber(2));
});
it('should calculate the conjugate of a complex number correctly', function() {
assert.equal(conj(math.complex('2 + 3i')).toString(), '2 - 3i');
assert.equal(conj(123).toString(), '123');
assert.equal(conj(math.complex('2 - 3i')).toString(), '2 + 3i');
assert.equal(conj(math.complex('2')).toString(), '2');
assert.equal(conj(math.complex('-4i')).toString(), '4i');
assert.equal(conj(math.i).toString(), '-i');
});
it('should calculate the conjugate for each element in a matrix', function() {
assert.equal(math.format(conj([math.complex('2+3i'), math.complex('3-4i')])),
'[2 - 3i, 3 + 4i]');
assert.equal(conj(math.matrix([math.complex('2+3i'), math.complex('3-4i')])).toString(),
'[2 - 3i, 3 + 4i]');
});
it('should throw an error when called with an unsupported type of argument', function() {
assert.throws(function () {conj(new Date())}, /TypeError: Unexpected type of argument/);
assert.throws(function () {conj(math.unit('5cm'))}, /TypeError: Unexpected type of argument/);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {conj()}, /TypeError: Too few arguments/);
assert.throws(function () {conj(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX conj', function () {
var expression = math.parse('conj(1+i)');
assert.equal(expression.toTex(), '\\left(1+ i\\right)^*');
});
});

View File

@@ -0,0 +1,54 @@
var assert = require('assert');
var math = require('../../../index');
describe('im', function() {
it('should return the imaginary part of a complex number', function() {
assert.equal(math.im(math.complex(2,3)), 3);
assert.equal(math.im(math.complex(-2,-3)), -3);
assert.equal(math.im(math.i), 1);
});
it('should return the imaginary part of a real number', function() {
assert.equal(math.im(2), 0);
});
it('should return the imaginary part of a big number', function() {
assert.deepEqual(math.im(math.bignumber(2)), math.bignumber(0));
});
it('should return the imaginary part of a boolean', function() {
assert.equal(math.im(true), 0);
assert.equal(math.im(false), 0);
});
it('should return the imaginary part of null', function() {
assert.equal(math.im(null), 0);
});
it('should return the imaginary part of a boolean', function() {
assert.equal(math.im(true), 0);
assert.equal(math.im(false), 0);
});
it('should return the imaginary part for each element in a matrix', function() {
assert.deepEqual(math.im([2, math.complex('3-6i')]), [0, -6]);
assert.deepEqual(math.im(math.matrix([2, math.complex('3-6i')])).valueOf(), [0, -6]);
});
it('should throw an error when called with an unsupported type of argument', function() {
assert.throws(function () {math.im(new Date())}, /TypeError: Unexpected type of argument/);
assert.throws(function () {math.im(math.unit('5cm'))}, /TypeError: Unexpected type of argument/);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {math.im()}, /TypeError: Too few arguments/);
assert.throws(function () {math.im(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX im', function () {
var expression = math.parse('im(1+i)');
assert.equal(expression.toTex(), '\\Im\\left\\lbrace1+ i\\right\\rbrace');
});
});

View File

@@ -0,0 +1,49 @@
var assert = require('assert');
var math = require('../../../index');
describe('re', function() {
it('should return the real part of a complex number', function() {
assert.equal(math.re(math.complex(2,3)), 2);
assert.equal(math.re(math.complex(-2,-3)), -2);
assert.equal(math.re(math.i), 0);
});
it('should return the real part of a real number', function() {
assert.equal(math.re(2), 2);
});
it('should return the real part of a big number', function() {
assert.deepEqual(math.re(math.bignumber(2)), math.bignumber(2));
});
it('should return the real part of a boolean', function() {
assert.strictEqual(math.re(true), 1);
assert.strictEqual(math.re(false), 0);
});
it('should return the real part of null', function() {
assert.strictEqual(math.re(null), 0);
});
it('should return the real part for each element in a matrix', function() {
assert.deepEqual(math.re([2, math.complex('3-6i')]), [2, 3]);
assert.deepEqual(math.re(math.matrix([2, math.complex('3-6i')])).valueOf(), [2, 3]);
});
it('should throw an error when called with an unsupported type of argument', function() {
assert.throws(function () {math.re(new Date())}, /TypeError: Unexpected type of argument/);
assert.throws(function () {math.re(math.unit('5cm'))}, /TypeError: Unexpected type of argument/);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {math.re()}, /TypeError: Too few arguments/);
assert.throws(function () {math.re(1, 2)}, /TypeError: Too many arguments/);
});
it('should LaTeX re', function () {
var expression = math.parse('re(1+i)');
assert.equal(expression.toTex(), '\\Re\\left\\lbrace1+ i\\right\\rbrace');
});
});

View File

@@ -0,0 +1,92 @@
var assert = require('assert');
var error = require('../../../lib/error/index');
var math = require('../../../index');
describe('distance', function() {
it('should calculate the distance of two 2D points', function() {
assert.equal(math.distance([0, 0], [10, 10]), 14.142135623730951);
assert.equal(math.distance(math.matrix([0,0]),math.matrix([10,10])), 14.142135623730951);
assert.equal(math.distance(math.matrix([0,0,0]),math.matrix([10,10,0])), 14.142135623730951);
assert.equal(math.distance({pointOneX: 0, pointOneY: 0}, {pointTwoX: 10, pointTwoY: 10}), 14.142135623730951);
});
it('should calculate distance between two 3d points', function(){
assert.equal(math.distance([4, 5, 8], [2, 7, 9]), 3);
assert.equal(math.distance(math.matrix([0, 0, 0]), math.matrix([10, 10, 0])), 14.142135623730951);
assert.equal(math.distance(math.matrix([0.31, 0.2, -0.21]), [0.4234, -0.212, -0.2342]), 0.42800607472324503);
assert.equal(math.distance([67435, 654667, 3545567], [53467, 34567, 654356]), 2956995.1236931384);
assert.equal(math.distance([-21, -230, -2141], math.matrix([-1234, -3122, -1242])), 3262.396971553278);
assert.equal(math.distance({pointOneX: 4, pointOneY: 5, pointOneZ: 8}, {pointTwoX: 2, pointTwoY: 7, pointTwoZ: 9}), 3);
});
it('should calculate distance for inputs passed as objects', function(){
assert.deepEqual(math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 6, lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8}), 2.720549372624744);
assert.deepEqual(math.distance({pointX: 10, pointY: 10}, {xCoeffLine: 8, yCoeffLine: 1, constant: 3}), 11.535230316796387);
assert.equal(math.distance({pointOneX: 0, pointOneY: 0}, {pointTwoX: 10, pointTwoY: 10}), 14.142135623730951);
assert.throws(function() {math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 'l', lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8})}, TypeError);
assert.equal(math.distance({pointOneX: 4, pointOneY: 5, pointOneZ: 8}, {pointTwoX: 2, pointTwoY: 7, pointTwoZ: 9}), 3);
});
it('should calculate distance for all non-zero values', function() {
assert.equal(math.distance([1, 1], [10,10]), 12.727922061357855);
assert.equal(math.distance([-1, -1], [10,10]), 15.556349186104045);
assert.equal(math.distance(math.matrix([-1, 8]), [5,10]), 6.324555320336759);
assert.equal(math.distance([-100, 60], [0,500]), 451.22056690713913);
assert.equal(math.distance([-100.78, 60.04], [0.3,500.09]), 451.5098768576386);
assert.equal(math.distance([74, -34, -0.5], math.matrix([34, 100, -4.33])), 139.89520685141431);
assert.deepEqual(math.distance([1, -1, -1], [2, 2, 0.1, 1, 2, 2]), 1.3437096247164249);
});
it('should throw an error for incompatible parameter types', function() {
assert.throws(function() {math.distance(0.5)}, TypeError);
assert.throws(function() {math.distance('1')}, TypeError);
assert.throws(function() {math.distance(["abc", "def"], [1, 3])}, TypeError);
assert.throws(function() {math.distance(['2', '3'], math.matrix(["a", "c"]), [1, -0.445364786543434])}, TypeError);
assert.throws(function() {math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 'l', lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8})}, TypeError);
assert.throws(function() {math.distance({wrongkeyname: 2, english: 3, pointZ: 1}, {x0: 1, y0: 1, z0: 2, a: 5, b: 0, c: 1})}, TypeError);
});
it('should throw an error for unsupported number of parameters', function() {
assert.throws(function() {math.distance([0, 0])}, TypeError);
assert.throws(function() {math.distance([9, 4, 3.6])}, TypeError);
assert.throws(function() {math.distance([[1, 2, 4],math.matrix([1, 2]),[8, 1, 3]])}, TypeError);
assert.throws(function() {math.distance([-0.5, 4.3],[3.2, -4.654323, 3.3, 6.5, 3.4])}, TypeError);
});
it('should calculate pairwise distance between more than two 2D points accurately', function(){
assert.deepEqual(math.distance([[1,2],[1,2],[1,3]]), [0, 1, 1]);
assert.deepEqual(math.distance([[0,2],[-2,0],[0,2]]), [ 2.8284271247461903, 0, 2.8284271247461903 ]);
assert.deepEqual(math.distance([[1,2], [2,3], [2,4], [3,0]]),
[1.4142135623730951,2.23606797749979,2.8284271247461903,1,3.1622776601683795,4.123105625617661]);
});
it('should calculate pairwise distance between more than two 3D points accurately', function(){
assert.deepEqual(math.distance([[0,0,0],[1,0,0],[0,1,0],[0,0,1]]), [1,1,1,1.4142135623730951,1.4142135623730951,1.4142135623730951]);
assert.deepEqual(math.distance([[1,2,4],[1,2,6],[8,1,3]]), [2, 7.14142842854285, 7.681145747868608]);
assert.deepEqual(math.distance([[-41,52,24],[61,-28,60],[-38,11,53]]), [134.5362404707371, 50.309044912421065, 106.63489110042735]);
assert.deepEqual(math.distance([[3.1,5.2,4.5],[4.1,0.2,6.4],[-5.8,-4.1,3021]]), [5.441507144165116,3016.527465480797,3014.6193225679426]);
});
it('should calculate distance between a point and a line segment given by an equation in 2D accurately', function(){
assert.deepEqual(math.distance([0.1123, -0.242], [0.1316, -0.2421, 0.122135]), 0.7094821347343443);
assert.deepEqual(math.distance([10, 10], [8, 1, 3]), 11.535230316796387);
assert.deepEqual(math.distance([12.5, -0.5], [8.5, -1, 3.75]), 12.91095785619739);
assert.deepEqual(math.distance([-34510, -1032], [8996, -10599, 34653]), 21542.094604263482);
assert.deepEqual(math.distance({pointX: 10, pointY: 10}, {xCoeffLine: 8, yCoeffLine: 1, constant: 3}), 11.535230316796387);
});
it('should calculate distance between a point and a line segment given by two points in 2D accurately', function(){
assert.deepEqual(math.distance(math.matrix([10, 10]), math.matrix([2, 3]), math.matrix([-8, 0])), 8.759953130362847);
assert.deepEqual(math.distance([0.23, -0.1240], [-0.232, 13.292], [-0.34, 0.346]), 10.658908662088363);
assert.deepEqual(math.distance([-10, 0.54], [38, 12.8], [94.33, -239]), 10.012171799590002);
assert.deepEqual(math.distance({pointX: 1, pointY: 4}, {lineOnePtX: 6, lineOnePtY: 3}, {lineTwoPtX: 2, lineTwoPtY: 8}), 2.720549372624744);
});
it('should calculate distance between point and line segment(with parametric co-ordinates) in 3D accurately', function(){
assert.deepEqual(math.distance([2, 3, 1], [1, 1, 2, 5, 0, 1]), 2.3204774044612857);
assert.deepEqual(math.distance(math.matrix([1, -1, -1]), math.matrix([2, 2, 0, 1, 2, 2])), 1.414213562373095);
assert.deepEqual(math.distance([-341, 12, 84.34], [-3.2, 212, 1.240, -51241, 22.2, -4652]), 229.9871046141146);
assert.deepEqual(math.distance({pointX: 2, pointY: 3, pointZ: 1}, {x0: 1, y0: 1, z0: 2, a: 5, b: 0, c: 1}), 2.3204774044612857);
});
});

View File

@@ -0,0 +1,42 @@
var assert = require('assert');
var error = require('../../../lib/error/index');
var math = require('../../../index');
describe('intersect', function() {
it('should calculate the intersection point of two 2D lines', function() {
assert.deepEqual(math.intersect([0, 0], [10, 10], [10, 0], [0, 10]), [5, 5]);
assert.deepEqual(math.intersect(math.matrix([0, 0]), [10, 10], math.matrix([10, 0]), math.matrix([0, 10])), math.matrix([5, 5]));
assert.deepEqual(math.intersect(math.matrix([0, 0]), math.matrix([10, 10]), math.matrix([10, 0]), math.matrix([0, 10])), math.matrix([5, 5]));
assert.deepEqual(math.intersect([300, 90], [400, 97], [300, 130], [400, 125]), [633.3333333333334, 113.33333333333334]);
});
it('should calculate the intersection point of two 3D lines', function() {
assert.deepEqual(math.intersect([0, 0, 0], [10, 10, 0], [10, 0, 0], [0, 10, 0]), [5, 5, 0]);
assert.deepEqual(math.intersect(math.matrix([0, 0, 0]), [10, 10, 0], [10, 0, 0], math.matrix([0, 10, 0])), math.matrix([5, 5, 0]));
assert.deepEqual(math.intersect(math.matrix([0, 0, 0]), math.matrix([10, 10, 0]), math.matrix([10, 0, 0]), math.matrix([0, 10, 0])), math.matrix([5, 5, 0]));
});
it('should calculate the intersection point of a line and a plane', function() {
assert.deepEqual(math.intersect([1, 0, 1], [4, -2, 2], [1, 1, 1, 6]), [7, -4, 3]);
assert.deepEqual(math.intersect(math.matrix([1, 0, 1]), [4, -2, 2], math.matrix([1, 1, 1, 6])), math.matrix([7, -4, 3]));
assert.deepEqual(math.intersect(math.matrix([1, 0, 1]), math.matrix([4, -2, 2]), math.matrix([1, 1, 1, 6])), math.matrix([7, -4, 3]));
});
it('should return null if the points do not intersect', function() {
assert.deepEqual(math.intersect([0, 1, 0], [0, 0, 0], [1, 1, 0], [1, 0, 0]), null);
assert.deepEqual(math.intersect([0, 1], [0, 0], [1, 1], [1, 0]), null);
});
it('should throw an error when number of arguments are other than 3 or 4', function() {
assert.throws(function () {math.intersect([2, 0, 1], [1, 1, 1, 6])}, /TypeError: Too few arguments in function intersect/);
assert.throws(function () {math.intersect([2, 0, 1], [1, 1, 6], [2, 0, 1], [1, 1, 6], [0, 8, 1])}, /TypeError: Too many arguments in function intersect/);
});
it('should throw an error for incompatible parameter types', function() {
assert.throws(function () {math.intersect(2, 3, 6)}, /TypeError: Unexpected type of argument in function intersect/);
assert.throws(function () {math.intersect([2, 0, 1], [1, 1, 1], [5, 1, 10])}, /TypeError: Array with 4 numbers expected as third argument/);
assert.throws(function () {math.intersect([], [], [], [])}, /TypeError: Arrays with two or thee dimensional points expected/);
assert.throws(function () {math.intersect([2, 8, 9], 3, 6)}, /TypeError: Unexpected type of argument in function intersect/);
assert.throws(function () {math.intersect('a', 'b', 'c', 'd')}, /TypeError: Unexpected type of argument in function intersect/);
});
});

View File

@@ -0,0 +1,196 @@
// test and
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
and = math.and;
describe('and', function () {
it('should and two numbers correctly', function () {
assert.strictEqual(and(1, 1), true);
assert.strictEqual(and(-1, 1), true);
assert.strictEqual(and(-1, -1), true);
assert.strictEqual(and(0, -1), false);
assert.strictEqual(and(1, 0), false);
assert.strictEqual(and(1, NaN), false);
assert.strictEqual(and(NaN, 1), false);
assert.strictEqual(and(1e10, 0.019209), true);
assert.strictEqual(and(-1.0e-100, 1.0e-100), true);
assert.strictEqual(and(Infinity, -Infinity), true);
});
it('should and two complex numbers', function () {
assert.strictEqual(and(complex(1, 1), complex(1, 1)), true);
assert.strictEqual(and(complex(0, 1), complex(1, 1)), true);
assert.strictEqual(and(complex(1, 0), complex(1, 1)), true);
assert.strictEqual(and(complex(1, 1), complex(0, 1)), true);
assert.strictEqual(and(complex(1, 1), complex(1, 0)), true);
assert.strictEqual(and(complex(1, 0), complex(1, 0)), true);
assert.strictEqual(and(complex(0, 1), complex(0, 1)), true);
assert.strictEqual(and(complex(0, 0), complex(1, 1)), false);
assert.strictEqual(and(complex(0, 0), complex(0, 1)), false);
assert.strictEqual(and(complex(0, 0), complex(1, 0)), false);
assert.strictEqual(and(complex(1, 1), complex(0, 0)), false);
assert.strictEqual(and(complex(0, 1), complex(0, 0)), false);
assert.strictEqual(and(complex(1, 0), complex(0, 0)), false);
assert.strictEqual(and(complex(), complex(1, 1)), false);
assert.strictEqual(and(complex(0), complex(1, 1)), false);
assert.strictEqual(and(complex(1), complex(1, 1)), true);
assert.strictEqual(and(complex(1, 1), complex()), false);
assert.strictEqual(and(complex(1, 1), complex(0)), false);
assert.strictEqual(and(complex(1, 1), complex(1)), true);
});
it('should and mixed numbers and complex numbers', function () {
assert.strictEqual(and(complex(1, 1), 1), true);
assert.strictEqual(and(complex(1, 1), 0), false);
assert.strictEqual(and(1, complex(1, 1)), true);
assert.strictEqual(and(0, complex(1, 1)), false);
assert.strictEqual(and(complex(0, 0), 1), false);
assert.strictEqual(and(1, complex(0, 0)), false);
});
it('should and two booleans', function () {
assert.strictEqual(and(true, true), true);
assert.strictEqual(and(true, false), false);
assert.strictEqual(and(false, true), false);
assert.strictEqual(and(false, false), false);
});
it('should and mixed numbers and booleans', function () {
assert.strictEqual(and(2, true), true);
assert.strictEqual(and(2, false), false);
assert.strictEqual(and(0, true), false);
assert.strictEqual(and(true, 2), true);
assert.strictEqual(and(false, 2), false);
});
it('should and mixed numbers and null', function () {
assert.strictEqual(and(2, null), false);
assert.strictEqual(and(null, 2), false);
});
it('should and bignumbers', function () {
assert.strictEqual(and(bignumber(1), bignumber(1)), true);
assert.strictEqual(and(bignumber(-1), bignumber(1)), true);
assert.strictEqual(and(bignumber(-1), bignumber(-1)), true);
assert.strictEqual(and(bignumber(0), bignumber(-1)), false);
assert.strictEqual(and(bignumber(1), bignumber(0)), false);
assert.strictEqual(and(bignumber(1), bignumber(NaN)), false);
assert.strictEqual(and(bignumber(NaN), bignumber(1)), false);
assert.strictEqual(and(bignumber('1e+10'), bignumber(0.19209)), true);
assert.strictEqual(and(bignumber('-1.0e-100'), bignumber('1.0e-100')), true);
assert.strictEqual(and(bignumber(Infinity), bignumber(-Infinity)), true);
});
it('should and mixed numbers and bignumbers', function () {
assert.strictEqual(and(bignumber(2), 3), true);
assert.strictEqual(and(2, bignumber(2)), true);
assert.strictEqual(and(0, bignumber(2)), false);
assert.strictEqual(and(2, bignumber(0)), false);
assert.strictEqual(and(bignumber(0), 2), false);
assert.strictEqual(and(bignumber(2), 0), false);
});
it('should and two units', function () {
assert.strictEqual(and(unit('100cm'), unit('10inch')), true);
assert.strictEqual(and(unit('100cm'), unit('0 inch')), false);
assert.strictEqual(and(unit('0cm'), unit('1m')), false);
assert.strictEqual(and(unit('m'), unit('1m')), false);
assert.strictEqual(and(unit('1dm'), unit('m')), false);
assert.strictEqual(and(unit('-100cm'), unit('-10inch')), true);
assert.strictEqual(and(unit(5, 'km'), unit(100, 'gram')), true);
assert.strictEqual(and(unit(5, 'km'), unit(0, 'gram')), false);
assert.strictEqual(and(unit(0, 'km'), unit(100, 'gram')), false);
assert.strictEqual(and(unit(bignumber(0), 'm'), unit(bignumber(0), 'm')), false);
assert.strictEqual(and(unit(bignumber(1), 'm'), unit(bignumber(0), 'm')), false);
assert.strictEqual(and(unit(bignumber(0), 'm'), unit(bignumber(1), 'm')), false);
assert.strictEqual(and(unit(bignumber(1), 'm'), unit(bignumber(1), 'm')), true);
});
describe('Array', function () {
it('should and array - scalar', function () {
assert.deepEqual(and(10, [0, 2]), [false, true]);
assert.deepEqual(and([0, 2], 10), [false, true]);
});
it('should and array - array', function () {
assert.deepEqual(and([0, 1, 0, 12], [0, 0, 1, 22]), [false, false, false, true]);
assert.deepEqual(and([], []), []);
});
it('should and array - dense matrix', function () {
assert.deepEqual(and([0, 1, 0, 12], matrix([0, 0, 1, 22])), matrix([false, false, false, true]));
assert.deepEqual(and([], matrix([])), matrix([]));
});
it('should and array - sparse matrix', function () {
assert.deepEqual(and([[0, 1], [0, 12]], sparse([[0, 0], [1, 22]])), sparse([[false, false], [false, true]]));
});
});
describe('DenseMatrix', function () {
it('should and dense matrix - scalar', function () {
assert.deepEqual(and(10, matrix([0, 2])), matrix([false, true]));
assert.deepEqual(and(matrix([0, 2]), 10), matrix([false, true]));
});
it('should and dense matrix - array', function () {
assert.deepEqual(and(matrix([0, 1, 0, 12]), [0, 0, 1, 22]), matrix([false, false, false, true]));
assert.deepEqual(and(matrix([]), []), matrix([]));
});
it('should and dense matrix - dense matrix', function () {
assert.deepEqual(and(matrix([0, 1, 0, 12]), matrix([0, 0, 1, 22])), matrix([false, false, false, true]));
assert.deepEqual(and(matrix([]), matrix([])), matrix([]));
});
it('should and dense matrix - sparse matrix', function () {
assert.deepEqual(and(matrix([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), sparse([[false, false], [false, true]]));
});
});
describe('SparseMatrix', function () {
it('should and sparse matrix - scalar', function () {
assert.deepEqual(and(10, sparse([[0], [2]])), sparse([[false], [true]]));
assert.deepEqual(and(sparse([[0], [2]]), 10), sparse([[false], [true]]));
});
it('should and sparse matrix - array', function () {
assert.deepEqual(and(sparse([[0, 1], [0, 12]]), [[0, 0], [1, 22]]), sparse([[false, false], [false, true]]));
});
it('should and sparse matrix - dense matrix', function () {
assert.deepEqual(and(sparse([[0, 1], [0, 12]]), matrix([[0, 0], [1, 22]])), sparse([[false, false], [false, true]]));
});
it('should and sparse matrix - sparse matrix', function () {
assert.deepEqual(and(sparse([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), sparse([[false, false], [false, true]]));
});
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {and(1);}, /TypeError: Too few arguments/);
assert.throws(function () {and(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {and(new Date(), true);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {and(true, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {and(true, undefined);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {and(undefined, true);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX and', function () {
var expression = math.parse('and(1,2)');
assert.equal(expression.toTex(), '\\left(1\\wedge2\\right)');
});
});

View File

@@ -0,0 +1,95 @@
// test not
var assert = require('assert');
var math = require('../../../index');
var bignumber = math.bignumber;
var complex = math.complex;
var matrix = math.matrix;
var unit = math.unit;
var not = math.not;
var FunctionNode = math.expression.node.FunctionNode;
var ConstantNode = math.expression.node.ConstantNode;
var SymbolNode = math.expression.node.SymbolNode;
describe('not', function () {
it('should not numbers correctly', function () {
assert.strictEqual(not(1), false);
assert.strictEqual(not(-1), false);
assert.strictEqual(not(1.23e+100), false);
assert.strictEqual(not(-1.0e-100), false);
assert.strictEqual(not(1.0e-100), false);
assert.strictEqual(not(Infinity), false);
assert.strictEqual(not(-Infinity), false);
assert.strictEqual(not(0), true);
assert.strictEqual(not(NaN), true);
});
it('should not complex numbers', function () {
assert.strictEqual(not(complex(1, 1)), false);
assert.strictEqual(not(complex(0, 1)), false);
assert.strictEqual(not(complex(1, 0)), false);
assert.strictEqual(not(complex(0, 0)), true);
assert.strictEqual(not(complex()), true);
assert.strictEqual(not(complex(0)), true);
assert.strictEqual(not(complex(1)), false);
});
it('should not booleans', function () {
assert.strictEqual(not(true), false);
assert.strictEqual(not(false), true);
});
it('should not null', function () {
assert.strictEqual(not(null), true);
});
it('should not bignumbers', function () {
assert.strictEqual(not(bignumber(1)), false);
assert.strictEqual(not(bignumber(-1)), false);
assert.strictEqual(not(bignumber(0)), true);
assert.strictEqual(not(bignumber(NaN)), true);
assert.strictEqual(not(bignumber('1e+10')), false);
assert.strictEqual(not(bignumber('-1.0e-100')), false);
assert.strictEqual(not(bignumber('1.0e-100')), false);
assert.strictEqual(not(bignumber(Infinity)), false);
assert.strictEqual(not(bignumber(-Infinity)), false);
});
it('should not units', function () {
assert.strictEqual(not(unit('100cm')), false);
assert.strictEqual(not(unit('0 inch')), true);
assert.strictEqual(not(unit('1m')), false);
assert.strictEqual(not(unit('m')), true);
assert.strictEqual(not(unit('-10inch')), false);
assert.strictEqual(not(unit(bignumber(1), 'm')), false);
assert.strictEqual(not(unit(bignumber(0), 'm')), true);
});
it('should not arrays', function () {
assert.deepEqual(not([0, 10]), [true, false]);
assert.deepEqual(not([]), []);
});
it('should not matrices', function () {
assert.deepEqual(not(matrix([0, 10])), matrix([true, false]));
assert.deepEqual(not(matrix([])), matrix([]));
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {not()}, /TypeError: Too few arguments/);
assert.throws(function () {not(1, 2)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type if arguments', function () {
assert.throws(function () {not(new Date())}, /TypeError: Unexpected type of argument/);
assert.throws(function () {not({})}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX not', function () {
var c = new ConstantNode(1);
var node = new FunctionNode(new SymbolNode('not'), [c]);
assert.equal(node.toTex(), '\\neg\\left(1\\right)');
});
});

View File

@@ -0,0 +1,227 @@
// test or
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
or = math.or;
describe('or', function () {
it('should or two numbers correctly', function () {
assert.strictEqual(or(1, 1), true);
assert.strictEqual(or(-1, 1), true);
assert.strictEqual(or(-1, -1), true);
assert.strictEqual(or(0, -1), true);
assert.strictEqual(or(1, 0), true);
assert.strictEqual(or(1, NaN), true);
assert.strictEqual(or(NaN, 1), true);
assert.strictEqual(or(1e10, 0.019209), true);
assert.strictEqual(or(-1.0e-100, 1.0e-100), true);
assert.strictEqual(or(Infinity, -Infinity), true);
assert.strictEqual(or(NaN, NaN), false);
assert.strictEqual(or(NaN, 0), false);
assert.strictEqual(or(0, NaN), false);
assert.strictEqual(or(0, 0), false);
});
it('should or two complex numbers', function () {
assert.strictEqual(or(complex(1, 1), complex(1, 1)), true);
assert.strictEqual(or(complex(0, 1), complex(1, 1)), true);
assert.strictEqual(or(complex(1, 0), complex(1, 1)), true);
assert.strictEqual(or(complex(1, 1), complex(0, 1)), true);
assert.strictEqual(or(complex(1, 1), complex(1, 0)), true);
assert.strictEqual(or(complex(1, 0), complex(1, 0)), true);
assert.strictEqual(or(complex(0, 1), complex(0, 1)), true);
assert.strictEqual(or(complex(0, 0), complex(1, 1)), true);
assert.strictEqual(or(complex(0, 0), complex(0, 1)), true);
assert.strictEqual(or(complex(0, 0), complex(1, 0)), true);
assert.strictEqual(or(complex(1, 1), complex(0, 0)), true);
assert.strictEqual(or(complex(0, 1), complex(0, 0)), true);
assert.strictEqual(or(complex(1, 0), complex(0, 0)), true);
assert.strictEqual(or(complex(), complex(1, 1)), true);
assert.strictEqual(or(complex(0), complex(1, 1)), true);
assert.strictEqual(or(complex(1), complex(1, 1)), true);
assert.strictEqual(or(complex(1, 1), complex()), true);
assert.strictEqual(or(complex(1, 1), complex(0)), true);
assert.strictEqual(or(complex(1, 1), complex(1)), true);
assert.strictEqual(or(complex(0, 0), complex(0, 0)), false);
assert.strictEqual(or(complex(), complex()), false);
});
it('should or mixed numbers and complex numbers', function () {
assert.strictEqual(or(complex(1, 1), 1), true);
assert.strictEqual(or(complex(1, 1), 0), true);
assert.strictEqual(or(1, complex(1, 1)), true);
assert.strictEqual(or(0, complex(1, 1)), true);
assert.strictEqual(or(complex(0, 0), 1), true);
assert.strictEqual(or(1, complex(0, 0)), true);
assert.strictEqual(or(0, complex(0, 0)), false);
assert.strictEqual(or(complex(0, 0), 0), false);
});
it('should or two booleans', function () {
assert.strictEqual(or(true, true), true);
assert.strictEqual(or(true, false), true);
assert.strictEqual(or(false, true), true);
assert.strictEqual(or(false, false), false);
});
it('should or mixed numbers and booleans', function () {
assert.strictEqual(or(2, true), true);
assert.strictEqual(or(2, false), true);
assert.strictEqual(or(0, true), true);
assert.strictEqual(or(0, false), false);
assert.strictEqual(or(true, 2), true);
assert.strictEqual(or(false, 2), true);
assert.strictEqual(or(false, 0), false);
});
it('should or mixed numbers and null', function () {
assert.strictEqual(or(2, null), true);
assert.strictEqual(or(null, 2), true);
assert.strictEqual(or(null, null), false);
});
it('should or bignumbers', function () {
assert.strictEqual(or(bignumber(1), bignumber(1)), true);
assert.strictEqual(or(bignumber(-1), bignumber(1)), true);
assert.strictEqual(or(bignumber(-1), bignumber(-1)), true);
assert.strictEqual(or(bignumber(0), bignumber(-1)), true);
assert.strictEqual(or(bignumber(1), bignumber(0)), true);
assert.strictEqual(or(bignumber(1), bignumber(NaN)), true);
assert.strictEqual(or(bignumber(NaN), bignumber(1)), true);
assert.strictEqual(or(bignumber('1e+10'), bignumber(0.19209)), true);
assert.strictEqual(or(bignumber('-1.0e-100'), bignumber('1.0e-100')), true);
assert.strictEqual(or(bignumber(Infinity), bignumber(-Infinity)), true);
assert.strictEqual(or(bignumber(NaN), bignumber(NaN)), false);
assert.strictEqual(or(bignumber(NaN), bignumber(0)), false);
assert.strictEqual(or(bignumber(0), bignumber(NaN)), false);
assert.strictEqual(or(bignumber(0), bignumber(0)), false);
});
it('should or mixed numbers and bignumbers', function () {
assert.strictEqual(or(bignumber(2), 3), true);
assert.strictEqual(or(2, bignumber(2)), true);
assert.strictEqual(or(0, bignumber(2)), true);
assert.strictEqual(or(2, bignumber(0)), true);
assert.strictEqual(or(bignumber(0), 2), true);
assert.strictEqual(or(bignumber(0), 0), false);
assert.strictEqual(or(bignumber(2), 0), true);
assert.strictEqual(or(bignumber(0), 0), false);
});
it('should or two units', function () {
assert.strictEqual(or(unit('100cm'), unit('10inch')), true);
assert.strictEqual(or(unit('100cm'), unit('0 inch')), true);
assert.strictEqual(or(unit('0cm'), unit('1m')), true);
assert.strictEqual(or(unit('m'), unit('1m')), true);
assert.strictEqual(or(unit('1dm'), unit('m')), true);
assert.strictEqual(or(unit('dm'), unit('m')), false);
assert.strictEqual(or(unit('-100cm'), unit('-10inch')), true);
assert.strictEqual(or(unit(5, 'km'), unit(100, 'gram')), true);
assert.strictEqual(or(unit(5, 'km'), unit(0, 'gram')), true);
assert.strictEqual(or(unit(0, 'km'), unit(100, 'gram')), true);
assert.strictEqual(or(unit(0, 'km'), unit(0, 'gram')), false);
assert.strictEqual(or(unit(bignumber(0), 'm'), unit(bignumber(0), 'm')), false);
assert.strictEqual(or(unit(bignumber(1), 'm'), unit(bignumber(0), 'm')), true);
assert.strictEqual(or(unit(bignumber(0), 'm'), unit(bignumber(1), 'm')), true);
assert.strictEqual(or(unit(bignumber(1), 'm'), unit(bignumber(1), 'm')), true);
});
it('should or two arrays', function () {
assert.deepEqual(or([0, 1, 0, 12], [0, 0, 1, 22]), [false, true, true, true]);
assert.deepEqual(or([], []), []);
});
it('should or mixed numbers and arrays', function () {
assert.deepEqual(or(10, [0, 2]), [true, true]);
assert.deepEqual(or([0, 2], 10), [true, true]);
assert.deepEqual(or(0, [0, 2]), [false, true]);
assert.deepEqual(or([0, 2], 0), [false, true]);
});
describe('Array', function () {
it('should or array - scalar', function () {
assert.deepEqual(or(10, [0, 2]), [true, true]);
assert.deepEqual(or([0, 2], 10), [true, true]);
});
it('should or array - array', function () {
assert.deepEqual(or([0, 1, 0, 12], [0, 0, 1, 22]), [false, true, true, true]);
assert.deepEqual(or([], []), []);
});
it('should or array - dense matrix', function () {
assert.deepEqual(or([0, 1, 0, 12], matrix([0, 0, 1, 22])), matrix([false, true, true, true]));
assert.deepEqual(or([], matrix([])), matrix([]));
});
it('should or array - sparse matrix', function () {
assert.deepEqual(or([[0, 1], [0, 12]], sparse([[0, 0], [1, 22]])), matrix([[false, true], [true, true]]));
});
});
describe('DenseMatrix', function () {
it('should or dense matrix - scalar', function () {
assert.deepEqual(or(10, matrix([0, 2])), matrix([true, true]));
assert.deepEqual(or(matrix([0, 2]), 10), matrix([true, true]));
});
it('should or dense matrix - array', function () {
assert.deepEqual(or(matrix([0, 1, 0, 12]), [0, 0, 1, 22]), matrix([false, true, true, true]));
assert.deepEqual(or(matrix([]), []), matrix([]));
});
it('should or dense matrix - dense matrix', function () {
assert.deepEqual(or(matrix([0, 1, 0, 12]), matrix([0, 0, 1, 22])), matrix([false, true, true, true]));
assert.deepEqual(or(matrix([]), matrix([])), matrix([]));
});
it('should or dense matrix - sparse matrix', function () {
assert.deepEqual(or(matrix([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), matrix([[false, true], [true, true]]));
});
});
describe('SparseMatrix', function () {
it('should or sparse matrix - scalar', function () {
assert.deepEqual(or(10, sparse([[0], [2]])), matrix([[true], [true]]));
assert.deepEqual(or(sparse([[0], [2]]), 10), matrix([[true], [true]]));
});
it('should or sparse matrix - array', function () {
assert.deepEqual(or(sparse([[0, 1], [0, 12]]), [[0, 0], [1, 22]]), matrix([[false, true], [true, true]]));
});
it('should or sparse matrix - dense matrix', function () {
assert.deepEqual(or(sparse([[0, 1], [0, 12]]), matrix([[0, 0], [1, 22]])), matrix([[false, true], [true, true]]));
});
it('should or sparse matrix - sparse matrix', function () {
assert.deepEqual(or(sparse([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), sparse([[false, true], [true, true]]));
});
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {or(1);}, /TypeError: Too few arguments/);
assert.throws(function () {or(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {or(new Date(), true);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {or(true, new Date());}, /TypeError: Unexpected type of argument/);
assert.throws(function () {or(true, undefined);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {or(undefined, true);}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX or', function () {
var expression = math.parse('or(1,2)');
assert.equal(expression.toTex(), '\\left(1\\vee2\\right)');
});
});

View File

@@ -0,0 +1,216 @@
// test xor
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
xor = math.xor;
describe('xor', function () {
it('should xor two numbers correctly', function () {
assert.strictEqual(xor(1, 1), false);
assert.strictEqual(xor(-1, 1), false);
assert.strictEqual(xor(-1, -1), false);
assert.strictEqual(xor(0, -1), true);
assert.strictEqual(xor(1, 0), true);
assert.strictEqual(xor(1, NaN), true);
assert.strictEqual(xor(NaN, 1), true);
assert.strictEqual(xor(1e10, 0.019209), false);
assert.strictEqual(xor(-1.0e-100, 1.0e-100), false);
assert.strictEqual(xor(Infinity, -Infinity), false);
assert.strictEqual(xor(NaN, NaN), false);
assert.strictEqual(xor(NaN, 0), false);
assert.strictEqual(xor(0, NaN), false);
assert.strictEqual(xor(0, 0), false);
});
it('should xor two complex numbers', function () {
assert.strictEqual(xor(complex(1, 1), complex(1, 1)), false);
assert.strictEqual(xor(complex(0, 1), complex(1, 1)), false);
assert.strictEqual(xor(complex(1, 0), complex(1, 1)), false);
assert.strictEqual(xor(complex(1, 1), complex(0, 1)), false);
assert.strictEqual(xor(complex(1, 1), complex(1, 0)), false);
assert.strictEqual(xor(complex(1, 0), complex(1, 0)), false);
assert.strictEqual(xor(complex(0, 1), complex(0, 1)), false);
assert.strictEqual(xor(complex(0, 0), complex(1, 1)), true);
assert.strictEqual(xor(complex(0, 0), complex(0, 1)), true);
assert.strictEqual(xor(complex(0, 0), complex(1, 0)), true);
assert.strictEqual(xor(complex(1, 1), complex(0, 0)), true);
assert.strictEqual(xor(complex(0, 1), complex(0, 0)), true);
assert.strictEqual(xor(complex(1, 0), complex(0, 0)), true);
assert.strictEqual(xor(complex(), complex(1, 1)), true);
assert.strictEqual(xor(complex(0), complex(1, 1)), true);
assert.strictEqual(xor(complex(1), complex(1, 1)), false);
assert.strictEqual(xor(complex(1, 1), complex()), true);
assert.strictEqual(xor(complex(1, 1), complex(0)), true);
assert.strictEqual(xor(complex(1, 1), complex(1)), false);
assert.strictEqual(xor(complex(0, 0), complex(0, 0)), false);
assert.strictEqual(xor(complex(), complex()), false);
});
it('should xor mixed numbers and complex numbers', function () {
assert.strictEqual(xor(complex(1, 1), 1), false);
assert.strictEqual(xor(complex(1, 1), 0), true);
assert.strictEqual(xor(1, complex(1, 1)), false);
assert.strictEqual(xor(0, complex(1, 1)), true);
assert.strictEqual(xor(complex(0, 0), 1), true);
assert.strictEqual(xor(1, complex(0, 0)), true);
assert.strictEqual(xor(0, complex(0, 0)), false);
assert.strictEqual(xor(complex(0, 0), 0), false);
});
it('should xor two booleans', function () {
assert.strictEqual(xor(true, true), false);
assert.strictEqual(xor(true, false), true);
assert.strictEqual(xor(false, true), true);
assert.strictEqual(xor(false, false), false);
});
it('should xor mixed numbers and booleans', function () {
assert.strictEqual(xor(2, true), false);
assert.strictEqual(xor(2, false), true);
assert.strictEqual(xor(0, true), true);
assert.strictEqual(xor(true, 2), false);
assert.strictEqual(xor(false, 2), true);
assert.strictEqual(xor(false, 0), false);
});
it('should xor mixed numbers and null', function () {
assert.strictEqual(xor(2, null), true);
assert.strictEqual(xor(null, 2), true);
});
it('should xor bignumbers', function () {
assert.strictEqual(xor(bignumber(1), bignumber(1)), false);
assert.strictEqual(xor(bignumber(-1), bignumber(1)), false);
assert.strictEqual(xor(bignumber(-1), bignumber(-1)), false);
assert.strictEqual(xor(bignumber(0), bignumber(-1)), true);
assert.strictEqual(xor(bignumber(1), bignumber(0)), true);
assert.strictEqual(xor(bignumber(1), bignumber(NaN)), true);
assert.strictEqual(xor(bignumber(NaN), bignumber(1)), true);
assert.strictEqual(xor(bignumber('1e+10'), bignumber(0.19209)), false);
assert.strictEqual(xor(bignumber('-1.0e-400'), bignumber('1.0e-400')), false);
assert.strictEqual(xor(bignumber(Infinity), bignumber(-Infinity)), false);
assert.strictEqual(xor(bignumber(NaN), bignumber(NaN)), false);
assert.strictEqual(xor(bignumber(NaN), bignumber(0)), false);
assert.strictEqual(xor(bignumber(0), bignumber(NaN)), false);
assert.strictEqual(xor(bignumber(0), bignumber(0)), false);
});
it('should xor mixed numbers and bignumbers', function () {
assert.strictEqual(xor(bignumber(2), 3), false);
assert.strictEqual(xor(2, bignumber(2)), false);
assert.strictEqual(xor(0, bignumber(2)), true);
assert.strictEqual(xor(2, bignumber(0)), true);
assert.strictEqual(xor(bignumber(0), 2), true);
assert.strictEqual(xor(bignumber(2), 0), true);
assert.strictEqual(xor(bignumber(0), 0), false);
});
it('should xor two units', function () {
assert.strictEqual(xor(unit('100cm'), unit('10inch')), false);
assert.strictEqual(xor(unit('100cm'), unit('0 inch')), true);
assert.strictEqual(xor(unit('0cm'), unit('1m')), true);
assert.strictEqual(xor(unit('m'), unit('1m')), true);
assert.strictEqual(xor(unit('1dm'), unit('m')), true);
assert.strictEqual(xor(unit('-100cm'), unit('-10inch')), false);
assert.strictEqual(xor(unit(5, 'km'), unit(100, 'gram')), false);
assert.strictEqual(xor(unit(5, 'km'), unit(0, 'gram')), true);
assert.strictEqual(xor(unit(0, 'km'), unit(100, 'gram')), true);
assert.strictEqual(xor(unit(0, 'km'), unit(0, 'gram')), false);
assert.strictEqual(xor(unit(bignumber(0), 'm'), unit(bignumber(0), 'm')), false);
assert.strictEqual(xor(unit(bignumber(1), 'm'), unit(bignumber(0), 'm')), true);
assert.strictEqual(xor(unit(bignumber(0), 'm'), unit(bignumber(1), 'm')), true);
assert.strictEqual(xor(unit(bignumber(1), 'm'), unit(bignumber(1), 'm')), false);
});
it('should xor two arrays', function () {
assert.deepEqual(xor([0, 1, 0, 12], [0, 0, 1, 22]), [false, true, true, false]);
assert.deepEqual(xor([], []), []);
});
describe('Array', function () {
it('should xor array - scalar', function () {
assert.deepEqual(xor(10, [0, 2]), [true, false]);
assert.deepEqual(xor([0, 2], 10), [true, false]);
});
it('should xor array - array', function () {
assert.deepEqual(xor([0, 1, 0, 12], [0, 0, 1, 22]), [false, true, true, false]);
assert.deepEqual(xor([], []), []);
});
it('should xor array - dense matrix', function () {
assert.deepEqual(xor([0, 1, 0, 12], matrix([0, 0, 1, 22])), matrix([false, true, true, false]));
assert.deepEqual(xor([], matrix([])), matrix([]));
});
it('should xor array - sparse matrix', function () {
assert.deepEqual(xor([[0, 1], [0, 12]], sparse([[0, 0], [1, 22]])), matrix([[false, true], [true, false]]));
});
});
describe('DenseMatrix', function () {
it('should xor dense matrix - scalar', function () {
assert.deepEqual(xor(10, matrix([0, 2])), matrix([true, false]));
assert.deepEqual(xor(matrix([0, 2]), 10), matrix([true, false]));
});
it('should xor dense matrix - array', function () {
assert.deepEqual(xor(matrix([0, 1, 0, 12]), [0, 0, 1, 22]), matrix([false, true, true, false]));
assert.deepEqual(xor(matrix([]), []), matrix([]));
});
it('should xor dense matrix - dense matrix', function () {
assert.deepEqual(xor(matrix([0, 1, 0, 12]), matrix([0, 0, 1, 22])), matrix([false, true, true, false]));
assert.deepEqual(xor(matrix([]), matrix([])), matrix([]));
});
it('should xor dense matrix - sparse matrix', function () {
assert.deepEqual(xor(matrix([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), matrix([[false, true], [true, false]]));
});
});
describe('SparseMatrix', function () {
it('should xor sparse matrix - scalar', function () {
assert.deepEqual(xor(10, sparse([[0], [2]])), matrix([[true], [false]]));
assert.deepEqual(xor(sparse([[0], [2]]), 10), matrix([[true], [false]]));
});
it('should xor sparse matrix - array', function () {
assert.deepEqual(xor(sparse([[0, 1], [0, 12]]), [[0, 0], [1, 22]]), matrix([[false, true], [true, false]]));
});
it('should xor sparse matrix - dense matrix', function () {
assert.deepEqual(xor(sparse([[0, 1], [0, 12]]), matrix([[0, 0], [1, 22]])), matrix([[false, true], [true, false]]));
});
it('should xor sparse matrix - sparse matrix', function () {
assert.deepEqual(xor(sparse([[0, 1], [0, 12]]), sparse([[0, 0], [1, 22]])), matrix([[false, true], [true, false]]));
});
});
it('should throw an error in case of invalid number of arguments', function () {
assert.throws(function () {xor(1)}, /TypeError: Too few arguments/);
assert.throws(function () {xor(1, 2, 3)}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function () {
assert.throws(function () {xor(new Date(), true)}, /TypeError: Unexpected type of argument/);
assert.throws(function () {xor(true, new Date())}, /TypeError: Unexpected type of argument/);
assert.throws(function () {xor(true, undefined)}, /TypeError: Unexpected type of argument/);
assert.throws(function () {xor(undefined, true)}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX xor', function () {
var expression = math.parse('xor(1,2)');
assert.equal(expression.toTex(), '\\left(1\\veebar2\\right)');
});
});

View File

@@ -0,0 +1,114 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
bignumber = math.bignumber;
describe('concat', function() {
var a = [[1,2],[3,4]];
var b = [[5,6],[7,8]];
var c = [[9,10],[11,12]];
var d = [
[ [1,2], [3,4] ],
[ [5,6], [7,8] ]
];
var e = [
[ [9,10], [11,12] ],
[ [13,14], [15,16] ]
];
it('should concatenate compatible matrices on the last dimension by default', function() {
assert.deepEqual(math.concat([1,2,3], [4, 5]), [1,2,3,4,5]);
assert.deepEqual(math.concat(
[bignumber(1),bignumber(2),bignumber(3)],
[bignumber(4)]),
[bignumber(1),bignumber(2),bignumber(3),bignumber(4)]);
assert.deepEqual(math.concat([[1],[2],[3]], [[4]], 0), [[1],[2],[3],[4]]);
assert.deepEqual(math.concat([[],[]], [[1,2],[3,4]]), [[1,2],[3,4]]);
assert.deepEqual(math.concat(math.matrix(a), math.matrix(b)), math.matrix([
[1,2,5,6],
[3,4,7,8]
]));
assert.deepEqual(math.concat(a, b, c), [
[1,2,5,6,9,10],
[3,4,7,8,11,12]
]);
assert.deepEqual(math.concat(d,e), [
[ [1,2,9,10], [3,4,11,12] ],
[ [5,6,13,14], [7,8,15,16] ]
]);
});
it('should concatenate compatible matrices on the given dimension', function() {
assert.deepEqual(math.concat([[1]], [[2]], 1), [[1,2]]);
assert.deepEqual(math.concat([[1]], [[2]], 0), [[1],[2]]);
assert.deepEqual(math.concat([[1]], [[2]], 0), [[1],[2]]);
assert.deepEqual(math.concat(a, b, 0), [
[1,2],
[3,4],
[5,6],
[7,8]
]);
assert.deepEqual(math.concat(a, b, c, 0), [
[1,2],
[3,4],
[5,6],
[7,8],
[9,10],
[11,12]
]);
assert.deepEqual(math.concat(d,e,0), [
[ [1,2], [3,4] ],
[ [5,6], [7,8] ],
[ [9,10], [11,12] ],
[ [13,14], [15,16] ]
]);
assert.deepEqual(math.concat(d,e,1), [
[ [1,2], [3,4], [9,10], [11,12] ],
[ [5,6], [7,8], [13,14], [15,16] ]
]);
assert.deepEqual(math.concat(d,e, bignumber(1)), [
[ [1,2], [3,4], [9,10], [11,12] ],
[ [5,6], [7,8], [13,14], [15,16] ]
]);
});
it('should concatenate strings', function() {
assert.strictEqual(math.concat('a', 'b'), 'ab');
assert.strictEqual(math.concat('a', 'b', 'c'), 'abc');
});
it('should throw an error in case of invalid requested dimension number', function() {
assert.throws(function () {math.concat([1, 2], [3,4], 2.3)}, /Integer number expected for dimension/);
assert.throws(function () {math.concat([1, 2], [3,4], 1)}, /Index out of range \(1 > 0\)/);
});
it('should throw an error in case dimension mismatch', function() {
assert.throws(function () {math.concat([1, 2], [[1,2], [3,4]])}, RangeError);
assert.throws(function () {math.concat([[1, 2]], [[1,2], [3,4]])}, /Dimension mismatch/);
});
it('should throw an error in case of invalid type of argument', function() {
assert.throws(function () {math.concat(math.complex(2,3))}, /TypeError: Unexpected type of argument/);
});
it('should throw an error when called without matrices as argument', function() {
assert.throws(function () {math.concat(2)}, /At least one matrix expected/);
});
it('should LaTeX concat', function () {
var expression = math.parse('concat([1],[2])');
assert.equal(expression.toTex(), '\\mathrm{concat}\\left(\\begin{bmatrix}1\\\\\\end{bmatrix},\\begin{bmatrix}2\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,52 @@
var assert = require('assert');
var error = require('../../../lib/error/index');
var math = require('../../../index');
describe('cross', function() {
it('should calculate cross product for two arrays', function() {
assert.deepEqual(math.cross([1, 1, 0], [0, 1, 1]), [1, -1, 1]);
assert.deepEqual(math.cross([3, -3, 1], [4, 9, 2]), [-15, -2, 39]);
assert.deepEqual(math.cross([2, 3, 4], [5, 6, 7]), [-3, 6, -3]);
});
it('should calculate cross product for two matrices', function() {
assert.deepEqual(math.cross(math.matrix([1, 1, 0]), math.matrix([0, 1, 1])),
math.matrix([1, -1, 1]));
});
it('should calculate cross product for mixed arrays and matrices', function() {
assert.deepEqual(math.cross([1, 1, 0], math.matrix([0, 1, 1])),
math.matrix([1, -1, 1]));
assert.deepEqual(math.cross(math.matrix([1, 1, 0]), [0, 1, 1]),
math.matrix([1, -1, 1]));
});
it('should calculate cross product for n-d arrays and matrices', function () {
assert.deepEqual(math.cross([[1, 2, 3]], [[4, 5, 6]]), [[-3, 6, -3]]);
assert.deepEqual(math.cross([[1], [2], [3]], [4, 5, 6]), [[-3, 6, -3]]);
assert.deepEqual(math.cross([[[[1, 2, 3]]]], [[4, 5, 6]]), [[-3, 6, -3]]);
});
it('should throw an error for unsupported types of arguments', function() {
assert.throws(function () {math.cross([2, 4, 1], 2)}, TypeError);
});
it('should throw an error for multi dimensional matrix input', function() {
assert.throws(function () {math.cross([[1,2],[3,4]], [[1,2],[3,4]])}, /Vectors with length 3 expected/);
});
it('should throw an error in case of vectors with unequal length', function() {
assert.throws(function () {math.cross([2, 3], [1,2,3])}, /Vectors with length 3 expected/);
});
it('should throw an error in case of empty vectors', function() {
assert.throws(function () {math.cross([], [])}, /Vectors with length 3 expected/);
});
it('should LaTeX cross', function () {
var expression = math.parse('cross([1],[2])');
assert.equal(expression.toTex(), '\\left(\\begin{bmatrix}1\\\\\\end{bmatrix}\\right)\\times\\left(\\begin{bmatrix}2\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,141 @@
var assert = require('assert');
var approx = require('../../../tools/approx');
var error = require('../../../lib/error/index');
var math = require('../../../index');
var BigNumber = math.type.BigNumber;
var Complex = math.type.Complex;
var DenseMatrix = math.type.DenseMatrix;
var det = math.det;
var diag = math.diag;
var eye = math.eye;
describe('det', function() {
it('should calculate correctly the determinant of a NxN matrix', function() {
assert.equal(det([5]), 5);
assert.equal(det([[1,2],[3,4]]), -2);
assert.equal(det(new DenseMatrix([[1,2],[3,4]])), -2);
approx.equal(det([
[-2, 2, 3],
[-1, 1, 3],
[ 2, 0, -1]
]), 6);
approx.equal(det([
[ 1, 4, 7],
[ 3, 0, 5],
[-1, 9, 11]
]), -8);
approx.equal(det([
[1,7,4,3,7],
[0,7,0,3,7],
[0,7,4,3,0],
[1,7,5,9,7],
[2,7,4,3,7]
]), -1176);
approx.equal(det(diag([4,-5,6])), -120);
});
it('should return 1 for the identity matrix',function() {
assert.equal(det(eye(7)), 1);
assert.equal(det(eye(2)), 1);
assert.equal(det(eye(1)), 1);
});
it('should return 0 for a singular matrix',function() {
assert.equal(det([
[1, 0],
[0, 0]
]), 0);
assert.equal(det([
[1, 0],
[1, 0]
]), 0);
assert.equal(det([
[2, 6],
[1, 3]
]), 0);
assert.equal(det([
[1, 0, 0],
[0, 0, 0],
[1, 0, 0]
]), 0);
});
it('should calculate the determinant for a scalar',function() {
assert.equal(det(7), 7);
var c1 = new Complex(2, 3);
var c2 = det(c1);
assert.deepEqual(c1, c2);
// c2 should be a clone
c1.re = 0;
assert.equal(c1.re, 0);
assert.equal(c2.re, 2);
});
it('should calculate the determinant for a 1x1 matrix',function() {
var c1 = new Complex(2, 3);
var c2 = det([[c1]]);
assert.deepEqual(c1, c2);
// c2 should be a clone
c1.re = 0;
assert.equal(c1.re, 0);
assert.equal(c2.re, 2);
});
it('should calculate correctly the determinant of a matrix with bignumbers', function() {
// 1x1
assert.deepEqual(det([new BigNumber(5)]), new BigNumber(5));
// 2x2
assert.deepEqual(det([
[new BigNumber(1), new BigNumber(2)],
[new BigNumber(3), new BigNumber(4)]
]), new BigNumber(-2));
// 3x3
assert.deepEqual(det([
[new BigNumber(-2), new BigNumber(2), new BigNumber( 3)],
[new BigNumber(-1), new BigNumber(1), new BigNumber( 3)],
[new BigNumber( 2), new BigNumber(0), new BigNumber(-1)]
]), new math.type.BigNumber(6));
// the following would fail with regular Numbers due to a precision overflow
assert.deepEqual(det([
[new BigNumber(1e10+1), new BigNumber(1e10)],
[new BigNumber(1e10), new BigNumber(1e10-1)]
]), new BigNumber(-1));
});
it('should calculate the determinant of a matrix with mixed numbers and bignumbers', function() {
assert.deepEqual(det([
[1, new BigNumber(2)],
[new BigNumber(3), 4]
]), new math.type.BigNumber(-2));
});
it('should not change the value of the initial matrix', function() {
var m_test = [[1,2,3],[4,5,6],[7,8,9]];
det(m_test);
assert.deepEqual(m_test, [[1,2,3],[4,5,6],[7,8,9]]);
});
it('should not accept a non-square matrix', function() {
assert.throws(function() { det([1,2]); });
assert.throws(function() { det([[1,2,3],[1,2,3]]); });
assert.throws(function() { det([0,1],[0,1],[0,1]); });
});
it('should not accept arrays with dimensions higher than 2', function() {
assert.throws(function() { det([[[1]]]); }, RangeError);
assert.throws(function() { det(new DenseMatrix([[[1]]])); }, RangeError);
});
it('should LaTeX det', function () {
var expression = math.parse('det([1])');
assert.equal(expression.toTex(), '\\det\\left(\\begin{bmatrix}1\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,129 @@
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber;
describe('diag', function() {
it('should return a diagonal matrix on the default diagonal', function() {
assert.deepEqual(math.diag([1,2,3]), [[1,0,0],[0,2,0],[0,0,3]]);
assert.deepEqual(math.diag([[1,2,3],[4,5,6]]), [1,5]);
});
it('should return a diagonal matrix on the default diagonal, dense matrix', function() {
assert.deepEqual(math.diag([1,2,3], 'dense'), math.matrix([[1,0,0],[0,2,0],[0,0,3]], 'dense'));
assert.deepEqual(math.diag(math.matrix([[1,2,3],[4,5,6]], 'dense')), math.matrix([1,5], 'dense'));
});
it('should return a diagonal matrix on the default diagonal, sparse matrix', function() {
assert.deepEqual(math.diag([1,2,3], 'sparse'), math.matrix([[1,0,0],[0,2,0],[0,0,3]], 'sparse'));
assert.deepEqual(math.diag(math.matrix([[1,2,3],[4,5,6]], 'sparse')), math.matrix([1,5], 'sparse'));
});
it('should return a array output on array input', function() {
assert.deepEqual(math.diag([1,2]), [[1,0],[0,2]]);
});
it('should return a matrix output on matrix input', function() {
assert.deepEqual(math.diag(math.matrix([1,2])), math.matrix([[1,0],[0,2]]));
assert.deepEqual(math.diag(math.matrix([[1,2], [3,4]])), math.matrix([1,4]));
});
it('should put vector on given diagonal k in returned matrix', function() {
assert.deepEqual(math.diag([1,2,3], 1), [[0,1,0,0],[0,0,2,0],[0,0,0,3]]);
assert.deepEqual(math.diag([1,2,3], -1), [[0,0,0],[1,0,0],[0,2,0],[0,0,3]]);
});
it('should return diagonal k from a matrix', function() {
assert.deepEqual(math.diag([[1,2,3],[4,5,6]], 1), [2,6]);
assert.deepEqual(math.diag([[1,2,3],[4,5,6]],-1), [4]);
assert.deepEqual(math.diag([[1,2,3],[4,5,6]],-2), []);
});
it('should throw an error in case of invalid k', function() {
assert.throws(function () {math.diag([[1,2,3],[4,5,6]], 2.4);}, /Second parameter in function diag must be an integer/);
});
describe('bignumber', function () {
var array123 = [bignumber(1),bignumber(2),bignumber(3)];
var array123456 = [
[bignumber(1),bignumber(2),bignumber(3)],
[bignumber(4),bignumber(5),bignumber(6)]
];
it('should return a diagonal matrix on the default diagonal', function() {
assert.deepEqual(math.diag(array123),
[
[bignumber(1),bignumber(0),bignumber(0)],
[bignumber(0),bignumber(2),bignumber(0)],
[bignumber(0),bignumber(0),bignumber(3)]
]);
assert.deepEqual(math.diag(array123456), [bignumber(1),bignumber(5)]);
});
it('should return a array output on array input', function() {
assert.deepEqual(math.diag([bignumber(1),bignumber(2)]),
[
[bignumber(1),bignumber(0)],
[bignumber(0),bignumber(2)]
]);
});
it('should return a matrix output on matrix input', function() {
assert.deepEqual(math.diag(math.matrix([bignumber(1),bignumber(2)])),
math.matrix([
[bignumber(1),bignumber(0)],
[bignumber(0),bignumber(2)]
]));
assert.deepEqual(math.diag(math.matrix([
[bignumber(1),bignumber(2)],
[bignumber(3),bignumber(4)]
])), math.matrix([bignumber(1),bignumber(4)]));
});
it('should put vector on given diagonal k in returned matrix', function() {
assert.deepEqual(math.diag(array123, bignumber(1)), [
[bignumber(0),bignumber(1),bignumber(0),bignumber(0)],
[bignumber(0),bignumber(0),bignumber(2),bignumber(0)],
[bignumber(0),bignumber(0),bignumber(0),bignumber(3)]
]);
assert.deepEqual(math.diag(array123, bignumber(-1)), [
[bignumber(0),bignumber(0),bignumber(0)],
[bignumber(1),bignumber(0),bignumber(0)],
[bignumber(0),bignumber(2),bignumber(0)],
[bignumber(0),bignumber(0),bignumber(3)]
]);
});
it('should return diagonal k from a matrix', function() {
assert.deepEqual(math.diag(array123456, bignumber(1)), [bignumber(2),bignumber(6)]);
assert.deepEqual(math.diag(array123456, bignumber(-1)), [bignumber(4)]);
assert.deepEqual(math.diag(array123456, bignumber(-2)), []);
});
});
it('should throw an error of the input matrix is not valid', function() {
assert.throws(function () {math.diag([[[1],[2]],[[3],[4]]]);});
// TODO: test diag for all types of input (also scalar)
});
it('should throw an error in case of wrong number of arguments', function() {
assert.throws(function () {math.diag();}, /TypeError: Too few arguments/);
assert.throws(function () {math.diag([], 2, 3, 4);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function() {
assert.throws(function () {math.diag(2);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {math.diag([], new Date());}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX diag', function () {
var expr1 = math.parse('diag([1,2,3])');
var expr2 = math.parse('diag([1,2,3],1)');
assert.equal(expr1.toTex(), '\\mathrm{diag}\\left(\\begin{bmatrix}1\\\\2\\\\3\\\\\\end{bmatrix}\\right)');
assert.equal(expr2.toTex(), '\\mathrm{diag}\\left(\\begin{bmatrix}1\\\\2\\\\3\\\\\\end{bmatrix},1\\right)');
});
});

View File

@@ -0,0 +1,43 @@
var assert = require('assert');
var error = require('../../../lib/error/index');
var math = require('../../../index');
describe('dot', function() {
it('should calculate dot product for two arrays', function() {
assert.equal(math.dot([2, 4, 1], [2, 2, 3]), 15);
assert.equal(math.dot([7, 3], [2, 4]), 26);
});
it('should calculate dot product for two matrices', function() {
assert.equal(math.dot(math.matrix([2, 4, 1]), math.matrix([2, 2, 3])), 15);
assert.equal(math.dot(math.matrix([7, 3]), math.matrix([2, 4])), 26);
});
it('should calculate dot product for mixed arrays and matrices', function() {
assert.equal(math.dot([2, 4, 1], math.matrix([2, 2, 3])), 15);
assert.equal(math.dot(math.matrix([7, 3]), [2, 4]), 26);
});
it('should throw an error for unsupported types of arguments', function() {
assert.throws(function () {math.dot([2, 4, 1], 2)}, TypeError);
});
it('should throw an error for multi dimensional matrix input', function() {
assert.throws(function () {math.dot([[1,2],[3,4]], [[1,2],[3,4]])}, /Vector expected/);
});
it('should throw an error in case of vectors with unequal length', function() {
assert.throws(function () {math.dot([2, 3], [1,2,3])}, /Vectors must have equal length \(2 != 3\)/);
});
it('should throw an error in case of empty vectors', function() {
assert.throws(function () {math.dot([], [])}, /Cannot calculate the dot product of empty vectors/);
});
it('should LaTeX dot', function () {
var expression = math.parse('dot([1,2],[3,4])');
assert.equal(expression.toTex(), '\\left(\\begin{bmatrix}1\\\\2\\\\\\end{bmatrix}\\cdot\\begin{bmatrix}3\\\\4\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,72 @@
var assert = require('assert'),
math = require('../../../index'),
matrix = math.matrix,
eye = math.eye;
describe('eye', function() {
it('should create an empty matrix', function () {
assert.deepEqual(eye(), matrix());
assert.deepEqual(eye([]), []);
assert.deepEqual(eye(matrix([])), matrix());
});
it('should create an empty sparse matrix', function () {
assert.deepEqual(eye('sparse'), matrix('sparse'));
assert.deepEqual(eye(matrix([], 'sparse')), matrix('sparse'));
});
it('should create an identity matrix of the given size', function() {
assert.deepEqual(eye(1), matrix([[1]]));
assert.deepEqual(eye(2), matrix([[1,0],[0,1]]));
assert.deepEqual(eye([2]), [[1,0],[0,1]]);
assert.deepEqual(eye(2,3), matrix([[1,0,0],[0,1,0]]));
assert.deepEqual(eye(3,2), matrix([[1,0],[0,1],[0,0]]));
assert.deepEqual(eye([3,2]), [[1,0],[0,1],[0,0]]);
assert.deepEqual(eye(math.matrix([3,2])), matrix([[1,0],[0,1],[0,0]]));
assert.deepEqual(eye(3,3), matrix([[1,0,0],[0,1,0],[0,0,1]]));
});
it('should create an identity matrix with storage type css of the given size', function() {
assert.deepEqual(eye(1, 'sparse'), matrix([[1]], 'sparse'));
assert.deepEqual(eye(2, 'sparse'), matrix([[1,0],[0,1]], 'sparse'));
assert.deepEqual(eye(2,3, 'sparse'), matrix([[1,0,0],[0,1,0]], 'sparse'));
assert.deepEqual(eye(3,2, 'sparse'), matrix([[1,0],[0,1],[0,0]], 'sparse'));
assert.deepEqual(eye(3,3, 'sparse'), matrix([[1,0,0],[0,1,0],[0,0,1]], 'sparse'));
});
it('should create an identity matrix with bignumbers', function() {
var zero = math.bignumber(0);
var one = math.bignumber(1);
var two = math.bignumber(2);
var three = math.bignumber(3);
assert.deepEqual(eye(two), matrix([[one,zero],[zero,one]]));
//assert.deepEqual(eye(two, 'sparse'), matrix([[one,zero],[zero,one]], 'sparse')); // FIXME: eye css
assert.deepEqual(eye(two, three), matrix([[one,zero,zero],[zero,one,zero]]));
//assert.deepEqual(eye(two, three, 'sparse'), matrix([[one,zero,zero],[zero,one,zero]], 'sparse')); // FIXME: eye css
});
it('should return an array when setting matrix=="array"', function() {
var math2 = math.create({matrix: 'Array'});
assert.deepEqual(math2.eye(2), [[1,0],[0,1]]);
});
it('should throw an error with an invalid input', function() {
assert.throws(function () {eye(3, 3, 2);});
assert.throws(function () {eye([3, 3, 2]);});
assert.throws(function () {eye([3, 3], 2);});
assert.throws(function () {eye([3.2, 3]);});
assert.throws(function () {eye([3, 3.2]);});
assert.throws(function () {eye([3.2, 3.2]);});
assert.throws(function () {eye([2, 'str']);});
assert.throws(function () {eye(['str', 2]);});
assert.throws(function () {eye([-2, 2]);});
assert.throws(function () {eye([2, -2]);});
});
it('should LaTeX eye', function () {
var expression = math.parse('eye(2)');
assert.equal(expression.toTex(), '\\mathrm{eye}\\left(2\\right)');
});
});

View File

@@ -0,0 +1,101 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index');
describe('filter', function() {
it('should filter an array with a filter function', function() {
function isPositive (x) {
return x > 0;
}
assert.deepEqual(math.filter([6, -2, -1, 4, 3], isPositive), [6, 4, 3]);
});
it('should filter a Matrix with a filter function', function() {
function isPositive (x) {
return x > 0;
}
assert.deepEqual(math.filter(math.matrix([6, -2, -1, 4, 3]), isPositive), math.matrix([6, 4, 3]));
});
it('should invoke callback with parameters value, index, obj', function() {
var arr = [1,2,3];
var log = [];
math.filter(arr, function (value, index, obj) {
log.push([value, index, obj === arr]);
return true;
}).valueOf();
assert.deepEqual(log, [
[1, [0], true ],
[2, [1], true ],
[3, [2], true ]
]);
});
it('should invoke a typed function with correct number of arguments (1)', function() {
var output = [];
math.filter([1,2,3], math.typed('callback', {
'number': function (value) {
output.push(value + 2)
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should invoke a typed function with correct number of arguments (2)', function() {
var output = [];
math.filter([1,2,3], math.typed('callback', {
'number, Array': function (value, index) {
output.push(value + 2)
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should invoke a typed function with correct number of arguments (3)', function() {
var output = [];
math.filter([1,2,3], math.typed('callback', {
'number, Array, Array': function (value, index, array) {
output.push(value + 2)
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should filter an array with a regexp', function() {
assert.deepEqual(math.filter(["23", "foo", "100", "55", "bar"], /[0-9]+/), ["23", "100", "55"]);
});
it('should filter a Matrix with a regexp', function() {
assert.deepEqual(math.filter(math.matrix(["23", "foo", "100", "55", "bar"]), /[0-9]+/), math.matrix(["23", "100", "55"]));
});
it('should throw an error if called with a multi dimensional matrix', function() {
function isPositive (x) {
return x > 0;
}
assert.throws(function() { math.filter(math.matrix([[6, -2],[-1, 4]]), isPositive) }, /Only one dimensional matrices supported/);
});
it('should throw an error if called with unsupported type', function() {
assert.throws(function() { math.filter(2, /regexp/) });
assert.throws(function() { math.filter('string', /regexp/) });
assert.throws(function() { math.filter([], 'string') });
assert.throws(function() { math.filter([], {}) });
});
it('should throw an error if called with invalid number of arguments', function() {
assert.throws(function() { math.filter([], /reg/, 'foo') });
assert.throws(function() { math.filter([]) });
});
it('should LaTeX filter', function () {
var expression = math.parse('filter(1,test)');
assert.equal(expression.toTex(), '\\mathrm{filter}\\left(1, test\\right)');
});
});

View File

@@ -0,0 +1,55 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
matrix = math.matrix,
flatten = math.flatten;
describe('flatten', function() {
it('should flatten an empty array', function () {
assert.deepEqual(flatten([]), []);
});
it('should clone the flattened array', function () {
var c = math.complex();
var flat = flatten([c]);
assert.deepEqual(flat, [c]);
assert(c !== flat[0]);
});
it('should flatten a 1 dimensional array', function () {
assert.deepEqual(flatten([1,2,3]), [1,2,3]);
});
it('should flatten a 2 dimensional array', function () {
assert.deepEqual(flatten([[1,2],[3,4]]), [1,2,3,4]);
});
it('should flatten a 3 dimensional array', function () {
assert.deepEqual(flatten([[[1,2],[3,4]],[[5,6],[7,8]]]), [1,2,3,4,5,6,7,8]);
});
it('should flatten a 1 dimensional matrix', function () {
assert.deepEqual(flatten(matrix([1,2,3])), matrix([1,2,3]));
});
it('should flatten a 2 dimensional matrix', function () {
assert.deepEqual(flatten(matrix([[1,2],[3,4]])), matrix([1,2,3,4]));
});
it('should flatten a 3 dimensional matrix', function () {
assert.deepEqual(flatten(matrix([[[1,2],[3,4]],[[5,6],[7,8]]])), matrix([1,2,3,4,5,6,7,8]));
});
it('should throw an error on invalid arguments', function () {
assert.throws(function () {flatten()}, /TypeError: Too few arguments/);
assert.throws(function () {flatten([],2)}, /TypeError: Too many arguments/);
assert.throws(function () {flatten("str")}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX flatten', function () {
var expression = math.parse('flatten([[1,2],[3,4]])');
assert.equal(expression.toTex(), '\\mathrm{flatten}\\left(\\begin{bmatrix}1&2\\\\3&4\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,83 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index');
describe('forEach', function() {
it('should iterate over all elements of the matrix', function() {
var m = math.matrix([1,2,3]);
var output = [];
math.forEach(m, function (value) { output.push(value); });
assert.deepEqual(output, [1,2,3]);
});
it('should iterate deep over all elements in the array', function() {
var arr = [1,2,3];
var output = [];
math.forEach(arr, function (value) { output.push(value); });
assert.deepEqual(output, [1,2,3]);
});
it('should invoke a typed function with correct number of arguments (1)', function() {
var output = [];
math.forEach([1,2,3], math.typed('callback', {
'number': function (value) {
output.push(value + 2)
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should invoke a typed function with correct number of arguments (2)', function() {
var output = [];
math.forEach([1,2,3], math.typed('callback', {
'number, Array': function (value, index) {
output.push(value + 2)
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should invoke a typed function with correct number of arguments (3)', function() {
var output = [];
math.forEach([1,2,3], math.typed('callback', {
'number, Array, Array': function (value, index, array) {
output.push(value + 2)
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should invoke callback with parameters value, index, obj', function() {
var arr = [[1,2,3], [4,5,6]];
var output = [];
math.forEach(arr, function (value, index, obj) {
// note: we don't copy index, it should be a copy with each iteration
output.push([value, index, obj === arr]);
});
assert.deepEqual(output, [
[1, [0, 0], true ],
[2, [0, 1], true ],
[3, [0, 2], true ],
[4, [1, 0], true ],
[5, [1, 1], true ],
[6, [1, 2], true ]
]);
});
it('should throw an error if called with unsupported type', function() {
assert.throws(function() { math.forEach(1, function() {}) });
assert.throws(function() { math.forEach('arr', function() {}) });
});
it('should throw an error if called with invalid number of arguments', function() {
assert.throws(function() { math.forEach([1, 2, 3]) });
});
it('should LaTeX forEach', function () {
var expression = math.parse('forEach([1,2,3],callback)');
assert.equal(expression.toTex(), '\\mathrm{forEach}\\left(\\begin{bmatrix}1\\\\2\\\\3\\\\\\end{bmatrix}, callback\\right)');
});
});

View File

@@ -0,0 +1,92 @@
// test inv
var assert = require('assert'),
approx = require('../../../tools/approx'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
inv = math.inv;
describe('inv', function() {
it('should return the inverse of a number', function() {
assert.deepEqual(inv(4), 1/4);
assert.deepEqual(inv(math.bignumber(4)), math.bignumber(1/4));
});
it('should return the inverse of a matrix with just one value', function() {
assert.deepEqual(inv([4]), [1/4]);
assert.deepEqual(inv([[4]]), [[1/4]]);
});
it('should return the inverse for each element in an array', function() {
assert.deepEqual(inv([4]), [1/4]);
assert.deepEqual(inv([[4]]), [[1/4]]);
approx.deepEqual(inv([
[ 1, 4, 7],
[ 3, 0, 5],
[-1, 9, 11]
]), [
[ 5.625, -2.375, -2.5],
[ 4.75, -2.25, -2],
[-3.375, 1.625, 1.5]
]);
approx.deepEqual(inv([
[ 2, -1, 0],
[-1, 2, -1],
[ 0, -1, 2]
]), [
[3/4, 1/2, 1/4],
[1/2, 1, 1/2],
[1/4, 1/2, 3/4]
]);
// the following will force swapping of empty rows in the middle of the matrix
approx.deepEqual(inv([
[1, 0, 0],
[0, 0, 1],
[0, 1, 0]
]), [
[1, 0, 0],
[0, 0, 1],
[0, 1, 0]
]);
});
it('should return the inverse for each element in a matrix', function() {
assert.deepEqual(inv(math.matrix([4])), math.matrix([1/4]));
assert.deepEqual(inv(math.matrix([[4]])), math.matrix([[1/4]]));
assert.deepEqual(inv(math.matrix([[4]], 'sparse')), math.matrix([[1/4]], 'sparse'));
assert.deepEqual(inv(math.matrix([[1,2],[3,4]], 'sparse')), math.matrix([[-2, 1],[1.5, -0.5]], 'sparse'));
});
it('should throw an error in case of non-square matrices', function() {
assert.throws(function () {inv([1,2,3])}, /Matrix must be square/);
assert.throws(function () {inv([[1,2,3], [4,5,6]])}, /Matrix must be square/);
});
it('should throw an error in case of multi dimensional matrices', function() {
assert.throws(function () {inv([[[1,2,3], [4,5,6]]])}, /Matrix must be two dimensional/);
});
it('should throw an error in case of non-invertable matrices', function() {
assert.throws(function () {inv([[0]])}, /Cannot calculate inverse, determinant is zero/);
assert.throws(function () {inv([[1,0], [0,0]])}, /Cannot calculate inverse, determinant is zero/);
assert.throws(function () {inv([[1,1,1], [1,0,0], [0,0,0]])}, /Cannot calculate inverse, determinant is zero/);
});
it('should throw an error in case of wrong number of arguments', function() {
assert.throws(function () {inv()}, /TypeError: Too few arguments/);
assert.throws(function () {inv([], [])}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function() {
assert.throws(function () {math.concat(inv(new Date()))}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX inv', function () {
var expression = math.parse('inv([[1,2],[3,4]])');
assert.equal(expression.toTex(), '\\left(\\begin{bmatrix}1&2\\\\3&4\\\\\\end{bmatrix}\\right)^{-1}');
});
});

View File

@@ -0,0 +1,103 @@
// test kronecker product
var assert = require('assert'),
math = require('../../../index');
describe('kron', function() {
it('should calculate the kronecker product of two arrays', function() {
assert.deepEqual(math.kron([
[1, -2, 1],
[1, 1, 0]
], [
[1, 0],
[0, 1]
]), [
[1, 0, -2, -0, 1, 0],
[0, 1, -0, -2, 0, 1],
[1, 0, 1, 0, 0, 0],
[0, 1, 0, 1, 0, 0]
]);
assert.deepEqual(math.kron([
[53, 12, -9, 0],
[2, 2, 5, 2]
], [
[99, 56, 22, 7]
]), [
[5247, 2968, 1166, 371, 1188, 672, 264, 84, -891, -504, -198, -63, 0, 0, 0, 0],
[198, 112, 44, 14, 198, 112, 44, 14, 495, 280, 110, 35, 198, 112, 44, 14]
]);
});
it('should calculate product for empty 2D Arrays', function() {
assert.deepEqual(math.kron([[]], [[]]), [[]]);
});
it('should calculate product for 1D Arrays', function() {
assert.deepEqual(math.kron([1,1], [[1,0],[0,1]]), [[1, 0, 1, 0],[0, 1, 0, 1]]);
assert.deepEqual(math.kron([[1,0],[0,1]], [1,1]), [[1, 1, 0, 0],[0, 0, 1, 1]]);
assert.deepEqual(math.kron([1,2,6,8], [12,1,2,3]), [[12,1,2,3,24,2,4,6,72,6,12,18,96,8,16,24]]);
});
it('should support complex numbers', function() {
assert.deepEqual(math.kron([
[1,math.complex(0,1)],
[math.complex(0,1),2]
],
[
[2,2],
[2,2]
]),
[
[2,2,math.complex(0,2),math.complex(0,2)],
[2,2,math.complex(0,2),math.complex(0,2)],
[math.complex(0,2),math.complex(0,2),4,4],
[math.complex(0,2),math.complex(0,2),4,4]
]);
});
it('should throw an error for greater then 2 dimensions', function() {
assert.throws(function () {
math.kron([[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 2, 3], [4, 5, 6]], [[6, 7, 8], [9, 10, 11]]]);
});
});
it('should throw an error if called with an invalid number of arguments', function() {
assert.throws(function () {math.kron();}, TypeError);
assert.throws(function () {math.kron([[1,2]]);}, TypeError);
});
describe('DenseMatrix', function () {
it('should calculate the kronecker product of a 2d matrix', function() {
var y = math.matrix([[1, 1], [1, 1]]);
var x = math.matrix([[1, 0], [0, 1]]);
var product = math.kron(x, y);
assert.deepEqual(product.valueOf(), [[1,1,0,0],[1,1,0,0],[0,0,1,1],[0,0,1,1]]);
var y = math.matrix([[1, 2], [55, -1]]);
var x = math.matrix([[13, 0], [0, -1]]);
var product = math.kron(x, y);
assert.deepEqual(product.toArray(), [[13,26,0,0],[715,-13,0,-0],[0,0,-1,-2],[0,0,-55,1]]);
});
it('should throw an error for invalid kronecker product of matrix', function() {
y = math.matrix([[[]]]);
x = math.matrix([[[1,1], [1,1]], [[1,1], [1,1]]]);
assert.throws(function () { math.kron(y, x) });
});
});
describe('SparseMatrix', function () {
it('should calculate the kronecker product of a 2d matrix', function() {
var y = math.sparse([[1, 1], [1, 1]]);
var x = math.sparse([[1, 0], [0, 1]]);
var product = math.kron(x, y);
assert.deepEqual(product.valueOf(), [[1,1,0,0],[1,1,0,0],[0,0,1,1],[0,0,1,1]]);
var y = math.matrix([[1, 2], [55, -1]], 'sparse');
var x = math.matrix([[13, 0], [0, -1]], 'sparse');
var product = math.kron(x, y);
assert.deepEqual(product.toArray(), [[13,26,0,0],[715,-13,0,-0],[0,0,-1,-2],[0,0,-55,1]]);
});
});
});

View File

@@ -0,0 +1,83 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index');
describe('map', function() {
it('should apply map to all elements of the matrix', function() {
var m = math.matrix([[1,2,3], [4,5,6]]);
var m2 = math.map(m, function (value) { return value * 2; });
assert.deepEqual(m2.valueOf(), [[2,4,6],[8,10,12]]);
assert.ok(m2 instanceof math.type.Matrix);
});
it('should apply deep-map to all elements in the array', function() {
var arr = [[1,2,3], [4,5,6]];
var arr2 = math.map(arr, function (value) { return value * 2; });
assert.deepEqual(arr2, [[2,4,6],[8,10,12]]);
assert.ok(Array.isArray(arr2));
});
it('should invoke callback with parameters value, index, obj', function() {
var arr = [[1,2,3], [4,5,6]];
assert.deepEqual(math.map(arr, function (value, index, obj) {
// we don't clone index here, this should return a copy with every iteration
return [value, index, obj === arr];
}).valueOf(), [
[
[1, [0, 0], true ],
[2, [0, 1], true ],
[3, [0, 2], true ]
],
[
[4, [1, 0], true ],
[5, [1, 1], true ],
[6, [1, 2], true ]
]
]);
});
it('should invoke a typed function with correct number of arguments (1)', function() {
var output = math.map([1,2,3], math.typed('callback', {
'number': function (value) {
return value + 2
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should invoke a typed function with correct number of arguments (2)', function() {
var output = math.map([1,2,3], math.typed('callback', {
'number, Array': function (value, index) {
return value + 2
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should invoke a typed function with correct number of arguments (3)', function() {
var output = math.map([1,2,3], math.typed('callback', {
'number, Array, Array': function (value, index, array) {
return value + 2
}
}));
assert.deepEqual(output, [3,4,5]);
});
it('should throw an error if called with unsupported type', function() {
assert.throws(function() { math.map(1, function() {}) });
assert.throws(function() { math.map('arr', function() {}) });
});
it('should throw an error if called with invalid number of arguments', function() {
assert.throws(function() { math.map([1, 2, 3]) });
});
it('should LaTeX map', function () {
var expression = math.parse('map([1,2,3],callback)');
assert.equal(expression.toTex(), '\\mathrm{map}\\left(\\begin{bmatrix}1\\\\2\\\\3\\\\\\end{bmatrix}, callback\\right)');
});
});

View File

@@ -0,0 +1,79 @@
// test ones
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
ones = math.ones,
matrix = math.matrix;
describe('ones', function() {
it('should create an empty matrix', function () {
assert.deepEqual(ones(), matrix());
assert.deepEqual(ones([]), []);
assert.deepEqual(ones(matrix([])), matrix());
});
it('should create an empty matrix, sparse', function () {
assert.deepEqual(ones('sparse'), matrix('sparse'));
assert.deepEqual(ones([], 'sparse'), matrix([], 'sparse'));
assert.deepEqual(ones(matrix([]), 'sparse'), matrix('sparse'));
});
it('should create a vector with ones', function () {
assert.deepEqual(ones(3), matrix([1,1,1]));
assert.deepEqual(ones(matrix([4])), matrix([1,1,1,1]));
assert.deepEqual(ones([4]), [1,1,1,1]);
assert.deepEqual(ones(0), matrix([]));
});
it('should create a 2D matrix with ones', function () {
assert.deepEqual(ones(2,3), matrix([[1,1,1],[1,1,1]]));
assert.deepEqual(ones(3,2), matrix([[1,1],[1,1],[1,1]]));
assert.deepEqual(ones([3,2]), [[1,1],[1,1],[1,1]]);
});
it('should create a matrix with ones from a matrix', function () {
assert.deepEqual(ones(matrix([3])), matrix([1,1,1]));
assert.deepEqual(ones(matrix([3,2])), matrix([[1,1],[1,1],[1,1]]));
});
it('should create a matrix with bignumber ones', function () {
var one = math.bignumber(1);
var three = math.bignumber(3);
assert.deepEqual(ones(three), matrix([one,one,one]));
assert.deepEqual(ones([three]), [one,one,one]);
});
it('should create a 3D matrix with ones', function () {
var res = [
[
[1,1,1,1],
[1,1,1,1],
[1,1,1,1]
],
[
[1,1,1,1],
[1,1,1,1],
[1,1,1,1]
]
];
assert.deepEqual(ones(2,3,4), matrix(res));
assert.deepEqual(ones(matrix([2,3,4])), matrix(res));
assert.deepEqual(ones([2,3,4]), res);
});
// TODO: test setting `matrix`
it('should create a matrix with ones with the same size as original matrix', function () {
var a = matrix([[1, 2, 3], [4, 5, 6]]);
assert.deepEqual(ones(math.size(a)).size(), a.size());
});
// TODO: test with invalid input
it('should LaTeX ones', function () {
var expression = math.parse('ones(2)');
assert.equal(expression.toTex(), '\\mathrm{ones}\\left(2\\right)');
});
});

View File

@@ -0,0 +1,109 @@
var assert = require('assert');
var error = require('../../../lib/error/index');
var math = require('../../../index');
var matrix = math.matrix;
var partitionSelect = math.partitionSelect;
describe('partitionSelect', function() {
it('should sort an array with numbers', function() {
assert.equal(partitionSelect([5,10,1], 0), 1);
assert.equal(partitionSelect([5,10,1], 1), 5);
assert.equal(partitionSelect([5,10,1], 2), 10);
});
it('should sort an array with strings', function() {
assert.equal(partitionSelect(['C', 'B', 'A', 'D'], 0), 'A');
assert.equal(partitionSelect(['C', 'B', 'A', 'D'], 1), 'B');
assert.equal(partitionSelect(['C', 'B', 'A', 'D'], 2), 'C');
assert.equal(partitionSelect(['C', 'B', 'A', 'D'], 3), 'D');
});
it('should sort a Matrix', function() {
assert.equal(partitionSelect(matrix([5,10,1]), 0), 1);
assert.equal(partitionSelect(matrix([5,10,1]), 1), 5);
assert.equal(partitionSelect(matrix([5,10,1]), 2), 10);
});
it('should sort an array in ascending order', function() {
assert.equal(partitionSelect([5,10,1], 0, 'asc'), 1);
assert.equal(partitionSelect([5,10,1], 1, 'asc'), 5);
assert.equal(partitionSelect([5,10,1], 2, 'asc'), 10);
});
it('should sort an array in descending order', function() {
assert.equal(partitionSelect([5,10,1], 0, 'desc'), 10);
assert.equal(partitionSelect([5,10,1], 1, 'desc'), 5);
assert.equal(partitionSelect([5,10,1], 2, 'desc'), 1);
});
it('should sort an array with a custom compare function', function() {
function sortByLength (a, b) {
return a.length - b.length;
}
assert.equal(partitionSelect(['Langdon', 'Tom', 'Sara'], 0, sortByLength), 'Tom');
assert.equal(partitionSelect(['Langdon', 'Tom', 'Sara'], 1, sortByLength), 'Sara');
assert.equal(partitionSelect(['Langdon', 'Tom', 'Sara'], 2, sortByLength), 'Langdon');
});
it('should mutate the input array, leaving it partitioned at k', function() {
var arr = [3, 2, 4, 6, -2, 5];
partitionSelect(arr, 3);
for (var i = 0; i < 3; ++i) {
assert.ok(arr[i] <= arr[3]);
}
assert.ok(arr[3] === 4);
for (var i = 4; i < arr.length; ++i) {
assert.ok(arr[3] <= arr[i]);
}
});
it('should mutate the input matrix, leaving it partitioned at k', function() {
var m = matrix([3, 2, 4, 6, -2, 5]);
partitionSelect(m, 3);
m.forEach(function (value, index, matrix) {
if (index[0] < 3) {
assert.ok(value <= 4);
} else if (index[0] === 3) {
assert.ok(value === 4);
} else {
assert.ok(value >= 4);
}
});
});
it('should throw an error if called with a multi dimensional matrix', function() {
assert.throws(function() { partitionSelect(matrix([[1,2],[3,4]]), 2) }, /Only one dimensional matrices supported/);
});
it('should throw an error if called with a non-negative k, within the bounds of the array', function() {
assert.throws(function() { partitionSelect([1], -2) }, /k must be a non-negative integer/);
assert.throws(function() { partitionSelect([3, 2, 1], 1.2) }, /k must be a non-negative integer/);
assert.throws(function() { partitionSelect([3, 2, 1], 3) }, /k out of bounds/);
assert.throws(function() { partitionSelect([], 0) }, /k out of bounds/);
});
it('should throw an error if called with unsupported type', function() {
assert.throws(function() { partitionSelect(2, 2) }, /TypeError: Unexpected type of argument/);
assert.throws(function() { partitionSelect('string', 2) }, /TypeError: Unexpected type of argument/);
assert.throws(function() { partitionSelect([1], new Date()) }, /TypeError: Unexpected type of argument/);
assert.throws(function() { partitionSelect([1], 1, 'function') }, /Error: Compare string must be "asc" or "desc"/);
assert.throws(function() { partitionSelect([1], 1, {}) }, /TypeError: Unexpected type of argument/);
});
it('should throw an error if called with invalid number of arguments', function() {
assert.throws(function() { partitionSelect() }, /TypeError: Too few arguments/);
assert.throws(function() { partitionSelect([]) }, /TypeError: Too few arguments/);
assert.throws(function() { partitionSelect([], 2, 'foo', 3) }, /TypeError: Too many arguments/);
});
/*
it('should LaTeX sort', function () {
var expression = math.parse('sort([3,2,1])');
assert.equal(expression.toTex(), '\\mathrm{sort}\\left(\\begin{bmatrix}3\\\\2\\\\1\\\\\\end{bmatrix}\\right)');
});
*/
});

View File

@@ -0,0 +1,155 @@
var assert = require('assert'),
approx = require('../../../tools/approx'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
range = math.range,
matrix = math.matrix,
bignumber = math.bignumber;
describe('range', function() {
it('should parse a valid string correctly', function() {
assert.deepEqual(range('1:6'), matrix([1,2,3,4,5]));
assert.deepEqual(range('0:2:10'), matrix([0,2,4,6,8]));
assert.deepEqual(range('5:-1:0'), matrix([5,4,3,2,1]));
assert.deepEqual(range('2:-2:-3'), matrix([2,0,-2]));
});
it('should throw an error in case of invalid string', function() {
assert.throws(function () {range('1:2:6:4')}, /is no valid range/);
assert.throws(function () {range('1')}, /is no valid range/);
assert.throws(function () {range('1,3:4')}, /is no valid range/);
assert.throws(function () {range('1:2,4')}, /is no valid range/);
assert.throws(function () {range('1:a')}, /is no valid range/);
});
it('should create a range start:1:end if called with 2 numbers', function() {
assert.deepEqual(range(3,6), matrix([3,4,5]));
assert.deepEqual(range(1,6), matrix([1,2,3,4,5]));
assert.deepEqual(range(1,6.1), matrix([1,2,3,4,5,6]));
assert.deepEqual(range(1,5.9), matrix([1,2,3,4,5]));
assert.deepEqual(range(6,1), matrix([]));
});
it('should create a range start:step:end if called with 3 numbers', function() {
assert.deepEqual(range(0,10,2), matrix([0,2,4,6,8]));
assert.deepEqual(range(5,0,-1), matrix([5,4,3,2,1]));
assert.deepEqual(range(2,-4,-2), matrix([2,0,-2]));
});
it('should create an empty range when step==0', function() {
assert.deepEqual(range(0,10,0), matrix([]));
assert.deepEqual(range(0,10,0, true), matrix([]));
});
it('should output an array when setting matrix==="array"', function() {
var math2 = math.create({
matrix: 'Array'
});
assert.deepEqual(math2.range(0,10,2), [0,2,4,6,8]);
assert.deepEqual(math2.range(5,0,-1), [5,4,3,2,1]);
});
it('should create a range with bignumbers', function() {
assert.deepEqual(range(bignumber(1), bignumber(3)), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(bignumber(3), bignumber(1), bignumber(-1)), matrix([bignumber(3),bignumber(2)]));
});
it('should create an empty range from bignumbers when step==0', function() {
assert.deepEqual(range(bignumber(0),bignumber(10),bignumber(0)), matrix([]));
assert.deepEqual(range(bignumber(0),bignumber(10),bignumber(0), true), matrix([]));
});
it('should create a range with mixed numbers and bignumbers', function() {
assert.deepEqual(range(bignumber(1), 3), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(1, bignumber(3)), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(1, bignumber(3), bignumber(1)), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(bignumber(1), 3, bignumber(1)), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(bignumber(1), bignumber(3), 1), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(bignumber(1), 3, 1), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(1, bignumber(3), 1), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(range(1, 3, bignumber(1)), matrix([bignumber(1),bignumber(2)]));
});
it('should parse a range with bignumbers', function() {
var bigmath = math.create({number: 'BigNumber'});
var bignumber = bigmath.bignumber;
assert.deepEqual(bigmath.range('1:3'), matrix([bignumber(1),bignumber(2)]));
assert.deepEqual(bigmath.range('3:-1:0'), matrix([bignumber(3),bignumber(2),bignumber(1)]));
});
it('should throw an error when parsing a an invalid string to a bignumber range', function() {
var bigmath = math.create({number: 'BigNumber'});
assert.throws(function () {bigmath.range('1:a')}, /is no valid range/);
});
describe ('option includeEnd', function () {
it('should parse a string and include end', function () {
assert.deepEqual(range('1:6', false), matrix([1,2,3,4,5]));
assert.deepEqual(range('1:2:6', false), matrix([1,3,5]));
assert.deepEqual(range('1:6', true), matrix([1,2,3,4,5,6]));
});
it('should create a range start:1:end and include end', function () {
assert.deepEqual(range(3,6, false), matrix([3,4,5]));
assert.deepEqual(range(3,6, true), matrix([3,4,5,6]));
});
it('should create a range start:step:end and include end', function () {
assert.deepEqual(range(0,10,2, false), matrix([0,2,4,6,8]));
assert.deepEqual(range(0,10,2, true), matrix([0,2,4,6,8,10]));
});
it('should create a range with bignumbers and include end', function() {
assert.deepEqual(range(bignumber(1), bignumber(3), true), matrix([bignumber(1),bignumber(2),bignumber(3)]));
assert.deepEqual(range(bignumber(3), bignumber(1), bignumber(-1), true), matrix([bignumber(3),bignumber(2),bignumber(1)]));
});
it('should throw an error in case of invalid type of include end', function () {
assert.throws(function () {range(0,10,2, 0)}, /TypeError: Unexpected type of argument/);
assert.throws(function () {range(0,10,2, 1)}, /TypeError: Unexpected type of argument/);
assert.throws(function () {range(0,10,2, 'str')}, /TypeError: Unexpected type of argument/);
});
});
it('should throw an error if called with an invalid string', function() {
assert.throws(function () {range('invalid range')}, SyntaxError);
});
it('should throw an error if called with a unit', function() {
assert.throws(function () {range(math.unit('5cm'))}, TypeError);
});
it('should throw an error if called with a complex number', function() {
assert.throws(function () {range(math.complex(2,3))}, TypeError);
});
it('should throw an error if called with one invalid argument', function() {
assert.throws(function () {range(math.unit('5cm'), 2)}, TypeError);
assert.throws(function () {range(2, math.complex(2,3))}, TypeError);
assert.throws(function () {range(2, new Date(), 3)}, TypeError);
assert.throws(function () {range(2, 1, math.unit('5cm'))}, TypeError);
assert.throws(function () {range(math.complex(2,3), 1, 3)}, TypeError);
});
it('should throw an error if called with an invalid number of arguments', function() {
assert.throws(function () {range()}, /TypeError: Too few arguments/);
assert.throws(function () {range(1,2,3,true,5)}, /TypeError: Too many arguments/);
});
// FIXME: should give the right error
it.skip('should not cast a single number or boolean to string', function() {
assert.throws(function () {range(2)}, /TypeError: Too few arguments/);
assert.throws(function () {range(boolean)}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX range', function () {
var expression = math.parse('range(1,10)');
assert.equal(expression.toTex(), '\\mathrm{range}\\left(1,10\\right)');
});
});

View File

@@ -0,0 +1,146 @@
// test resize
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
Matrix = math.type.Matrix;
describe('resize', function() {
it('should resize an array', function() {
var array = [[0,1,2],[3,4,5]];
assert.deepEqual(math.resize(array, [3, 2]), [[0,1], [3,4], [0, 0]]);
// content should be cloned
var x = math.complex(2, 3);
var a = [x];
var b = math.resize(a, [2], 4);
assert.deepEqual(b, [x, 4]);
assert.notStrictEqual(b[0], x);
});
it('should resize an array with a default value', function() {
var array = [[0,1,2],[3,4,5]];
assert.deepEqual(math.resize(array, [3, 2], 5), [[0,1], [3,4], [5,5]]);
assert.deepEqual(math.resize(array, [2]), arr(0,3));
});
it('should resize an array with uninitialized as default value', function() {
var array = [];
assert.deepEqual(math.resize(array, [3], math.uninitialized), arr(uninit, uninit, uninit));
});
it('should resize an array with bignumbers', function() {
var zero = math.bignumber(0);
var one = math.bignumber(1);
var two = math.bignumber(2);
var three = math.bignumber(3);
var array = [one, two, three];
assert.deepEqual(math.resize(array, [three, two], zero),
[[one,zero], [two, zero], [three, zero]]);
});
it('should resize a matrix', function() {
var matrix = math.matrix([[0,1,2],[3,4,5]]);
assert.deepEqual(math.resize(matrix, [3, 2]),
math.matrix([[0,1], [3,4], [0,0]]));
assert.deepEqual(math.resize(matrix, math.matrix([3, 2])),
math.matrix([[0,1], [3,4], [0,0]]));
// content should be cloned
var x = math.complex(2, 3);
var a = math.matrix([x]);
var b = math.resize(a, [2], 4);
assert.deepEqual(b, math.matrix([x, 4]));
assert.notStrictEqual(b.valueOf()[0], x);
});
it('should resize an array into a scalar', function() {
var array = [[0,1,2],[3,4,5]];
assert.deepEqual(math.resize(array, []), 0);
});
it('should resize a matrix into a scalar', function() {
var matrix = math.matrix([[0,1,2],[3,4,5]]);
assert.deepEqual(math.resize(matrix, []), 0);
});
it('should resize a scalar into an array when array is specified in settings', function() {
var math2 = math.create({matrix: 'Array'});
assert.deepEqual(math2.resize(2, [3], 4), [2, 4, 4]);
assert.deepEqual(math2.resize(2, [2,2], 4), [[2,4], [4,4]]);
});
it('should resize a vector into a 2d matrix', function() {
var math2 = math.create({matrix: 'Array'});
assert.deepEqual(math2.resize([1,2,3], [3,2], 0), [[1, 0], [2, 0], [3, 0]]);
});
it('should resize 2d matrix into a vector', function() {
var math2 = math.create({matrix: 'Array'});
assert.deepEqual(math2.resize([[1,2],[3,4],[5,6]], [3], 0), [1,3,5]);
});
it('should resize a scalar into a matrix', function() {
assert.deepEqual(math.resize(2, [3], 4), math.matrix([2, 4, 4]));
assert.deepEqual(math.resize(2, [2,2], 4), math.matrix([[2,4], [4,4]]));
});
it('should resize a scalar into a scalar', function() {
var x = math.complex(2, 3);
var y = math.resize(x, []);
assert.deepEqual(x, y);
assert.notStrictEqual(x, y);
});
it('should resize a string', function() {
assert.equal(math.resize('hello', [2]), 'he');
assert.equal(math.resize('hello', [8]), 'hello ');
assert.equal(math.resize('hello', [5]), 'hello');
assert.equal(math.resize('hello', [8], '!'), 'hello!!!');
});
it('should throw an error on invalid arguments', function() {
assert.throws(function () {math.resize()});
assert.throws(function () {math.resize([])});
assert.throws(function () {math.resize([], 2)});
assert.throws(function () {math.resize([], [], 4, 555)});
assert.throws(function () {math.resize([], ['no number'])}, /Invalid size/);
assert.throws(function () {math.resize([], [2.3])}, /Invalid size/);
assert.throws(function () {math.resize('hello', [])});
assert.throws(function () {math.resize('hello', [2,3])});
assert.throws(function () {math.resize('hello', [8], 'charzzz')});
assert.throws(function () {math.resize('hello', [8], 2)});
assert.throws(function () {math.resize('hello', ['no number'])}, /Invalid size/);
assert.throws(function () {math.resize('hello', [2.3])}, /Invalid size/);
});
it('should LaTeX resize', function () {
var expression = math.parse('resize([1,2],1)');
assert.equal(expression.toTex(), '\\mathrm{resize}\\left(\\begin{bmatrix}1\\\\2\\\\\\end{bmatrix},1\\right)');
});
});
/**
* Helper function to create an Array containing uninitialized values
* Example: arr(uninit, uninit, 2); // [ , , 2 ]
*/
var uninit = {};
function arr() {
var array = [];
array.length = arguments.length;
for (var i = 0; i < arguments.length; i++) {
var value = arguments[i];
if (value !== uninit) {
array[i] = value;
}
}
return array;
}

View File

@@ -0,0 +1,68 @@
// test size
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
size = math.size,
matrix = math.matrix;
describe('size', function() {
it('should calculate the size of an array', function() {
assert.deepEqual(size([[1,2,3],[4,5,6]]), [2,3]);
assert.deepEqual(size([[[1,2],[3,4]],[[5,6],[7,8]]]), [2,2,2]);
assert.deepEqual(size([1,2,3]), [3]);
assert.deepEqual(size([[1],[2],[3]]), [3,1]);
assert.deepEqual(size([100]), [1]);
assert.deepEqual(size([[100]]), [1,1]);
assert.deepEqual(size([[[100]]]), [1,1,1]);
assert.deepEqual(size([]), [0]);
assert.deepEqual(size([[]]), [1,0]);
assert.deepEqual(size([[[]]]), [1,1,0]);
assert.deepEqual(size([[[],[]]]), [1,2,0]);
});
it('should calculate the size of a matrix', function() {
assert.deepEqual(size(matrix()), matrix([0]));
assert.deepEqual(size(matrix([[1,2,3], [4,5,6]])), matrix([2,3]));
assert.deepEqual(size(matrix([[], []])), matrix([2,0]));
});
it('should calculate the size of a range', function() {
assert.deepEqual(size(math.range(2,6)), matrix([4]));
});
it('should calculate the size of a scalar', function() {
assert.deepEqual(size(2), matrix([]));
assert.deepEqual(size(math.bignumber(2)), matrix([]));
assert.deepEqual(size(math.complex(2,3)), matrix([]));
assert.deepEqual(size(true), matrix([]));
assert.deepEqual(size(null), matrix([]));
});
it('should calculate the size of a scalar with setting matrix=="array"', function() {
var math2 = math.create({matrix: 'Array'});
assert.deepEqual(math2.size(2), []);
assert.deepEqual(math2.size(math2.bignumber(2)), []);
assert.deepEqual(math2.size(math2.complex(2,3)), []);
assert.deepEqual(math2.size('string'), [6]);
});
it('should calculate the size of a string', function() {
assert.deepEqual(size('hello'), matrix([5]));
assert.deepEqual(size(''), matrix([0]));
});
it('should throw an error if called with an invalid number of arguments', function() {
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())}, /TypeError: Unexpected type of argument/);
});
it('should LaTeX size', function () {
var expression = math.parse('size(1)');
assert.equal(expression.toTex(), '\\mathrm{size}\\left(1\\right)');
});
});

View File

@@ -0,0 +1,56 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index');
describe('sort', function() {
it('should sort an array with numbers', function() {
assert.deepEqual(math.sort([5,10,1]), [1,5, 10]);
});
it('should sort an array with strings', function() {
assert.deepEqual(math.sort(['C', 'B', 'A', 'D']), ['A', 'B', 'C', 'D']);
});
it('should sort a Matrix', function() {
assert.deepEqual(math.sort(math.matrix([5,10,1])), math.matrix([1,5, 10]));
});
it('should sort an array in ascending order', function() {
assert.deepEqual(math.sort([5,10,1], 'asc'), [1,5,10]);
});
it('should sort an array in descending order', function() {
assert.deepEqual(math.sort([5,10,1], 'desc'), [10,5,1]);
});
it('should sort an array with a custom compare function', function() {
function sortByLength (a, b) {
return a.length - b.length;
}
assert.deepEqual(math.sort(['Langdon', 'Tom', 'Sara'], sortByLength),
['Tom', 'Sara', 'Langdon']);
});
it('should throw an error if called with a multi dimensional matrix', function() {
assert.throws(function() { math.sort(math.matrix([[1,2],[3,4]])) }, /One dimensional matrix expected/);
});
it('should throw an error if called with unsupported type', function() {
assert.throws(function() { math.sort(2) });
assert.throws(function() { math.sort('string') });
assert.throws(function() { math.sort([], 'string') }, /String "asc" or "desc" expected/);
assert.throws(function() { math.sort([], {}) });
});
it('should throw an error if called with invalid number of arguments', function() {
assert.throws(function() { math.sort([], 'asc', 'foo') });
assert.throws(function() { math.sort() });
});
it('should LaTeX sort', function () {
var expression = math.parse('sort([3,2,1])');
assert.equal(expression.toTex(), '\\mathrm{sort}\\left(\\begin{bmatrix}3\\\\2\\\\1\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,39 @@
// test squeeze
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
squeeze = math.squeeze,
size = math.size,
matrix = math.matrix;
describe('squeeze', function() {
it('should squeeze an matrix', function() {
var m = math.ones(matrix([1,3,2]));
assert.deepEqual(size(m), matrix([1,3,2]));
assert.deepEqual(size(m.valueOf()), [1,3,2]);
assert.deepEqual(size(squeeze(m)), matrix([3,2]));
m = math.ones(matrix([1,1,3]));
assert.deepEqual(size(m), matrix([1,1,3]));
assert.deepEqual(size(squeeze(m)), matrix([3]));
assert.deepEqual(size(squeeze(math.range(1,6))), matrix([5]));
assert.deepEqual(squeeze(2.3), 2.3);
assert.deepEqual(squeeze(matrix([[5]])), 5);
});
it('should squeeze an array', function() {
assert.deepEqual(squeeze([[2,3]]), [2,3]);
});
it('should throw an error if called with an invalid number of arguments', function() {
assert.throws(function () {squeeze()}, /TypeError: Too few arguments/);
assert.throws(function () {squeeze(1,2)}, /TypeError: Too many arguments/);
});
it('should LaTeX squeeze', function () {
var expression = math.parse('squeeze([[0],[0]])');
assert.equal(expression.toTex(), '\\mathrm{squeeze}\\left(\\begin{bmatrix}0\\\\0\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,191 @@
var assert = require('assert'),
math = require('../../../index'),
subset = math.subset,
matrix = math.matrix,
Range = math.type.Range,
Set = math.type.Set,
index = math.index;
describe('subset', function() {
var a = [[1,2], [3,4]];
var b = math.matrix(a);
it('should get the right subset of an array', function() {
assert.deepEqual(subset(a, index(new Range(0,2), 1)), [[2],[4]]);
assert.deepEqual(subset(a, index(1,0)), 3);
});
it('should throw an error if trying to access an invalid subset of an array', function() {
assert.throws(function () {subset(a, index(6, 0));}, RangeError);
assert.throws(function () {subset(a, index(1));}, RangeError);
assert.throws(function () {subset(a, index(1,0,0));}, RangeError);
assert.throws(function () {subset(a, index(1.3, 0));}, TypeError);
});
it('should get the right subset of an object', function() {
var obj = {'foo': 'bar'};
assert.deepEqual(subset(obj, index('foo')), 'bar');
assert.deepEqual(subset(obj, index('bla')), undefined);
});
it('should throw an error in case of an invalid subset for an object', function() {
var obj = {'foo': 'bar'};
var i = index('a', 'b');
assert.throws(function () {subset(obj, i);}, /DimensionError/);
});
it('should get the right subset of a matrix', function() {
assert.deepEqual(subset(b, index(new Range(0,2), 1)), matrix([[2],[4]]));
assert.deepEqual(subset(b, index(1, 0)), 3);
});
it('should get a subset of a matrix returning a null or undefined value', function() {
assert.deepEqual(subset([0], index(0)), 0);
assert.deepEqual(subset([null], index(0)), null);
assert.deepEqual(subset([undefined], index(0)), undefined);
assert.deepEqual(subset([null, undefined], index(new Range(0,2))), [null, undefined]);
});
it('should throw an error if trying to access an invalid subset of a matrix', function() {
assert.throws(function () {subset(b, index(6, 0));}, RangeError);
assert.throws(function () {subset(b, index(1));}, RangeError);
assert.throws(function () {subset(b, index(1,0,0));}, RangeError);
assert.throws(function () {subset(b, index(1.3, 0));}, TypeError);
});
var d = [[1,2], [3,4]];
var g = matrix([[1,2], [3,4]]);
// TODO: test getting subset of an array and matrix
it('should set the right subset of an array', function() {
assert.deepEqual(d, [[1,2], [3,4]]);
assert.deepEqual(subset(d, index(new Range(0,2), 1), [[-2],[-4]]), [[1,-2], [3,-4]]);
assert.deepEqual(d, [[1,2], [3,4]]);
assert.deepEqual(subset(d, index(2, new Range(0,2)), [[5,6]]), [[1,2], [3,4], [5,6]]);
assert.deepEqual(d, [[1,2], [3,4]]);
assert.deepEqual(subset(d, index(0,0), 123), [[123,2], [3,4]]);
});
it('should set a subset of an array with uninitialized default value', function() {
var a = [];
assert.deepEqual(subset(a, index(2), 1), [0,0,1]);
assert.deepEqual(subset(a, index(2), 1, math.uninitialized), arr(uninit, uninit,1));
});
it('should throw an error if setting the subset of an array with an invalid replacement', function() {
assert.throws(function () {subset(d, index(1), 123);}, RangeError);
assert.throws(function () {subset(d, index(1.3,0), 123);}, TypeError);
});
it('should set the right subset of a matrix', function() {
assert.deepEqual(g, matrix([[1,2], [3,4]]));
assert.deepEqual(subset(g, index(new Range(0,2), 1), [[-2],[-4]]), matrix([[1,-2], [3,-4]]));
assert.deepEqual(g, matrix([[1,2], [3,4]]));
assert.deepEqual(subset(g, index(2, new Range(0,2)), [[5,6]]), matrix([[1,2], [3,4], [5,6]]));
});
it('should throw an error if setting the subset of a matrix with an invalid replacement', function() {
assert.throws(function () {subset(d, index(1), 123);}, RangeError);
assert.throws(function () {subset(d, index(1.3,0), 123);}, TypeError);
});
describe('string', function () {
it('should get the right subset of a string', function() {
assert.deepEqual(subset('hello', index(1)), 'e');
assert.deepEqual(subset('hello', index(new Range(4,-1,-1))), 'olleh');
});
it('should throw an error if trying to access an invalid subset of a string', function() {
//assert.throws(function () {subset('hello', 1);}, TypeError);
assert.throws(function () {subset('hello', index([6]));}, RangeError);
assert.throws(function () {subset('hello', index([-2]));}, RangeError);
assert.throws(function () {subset('hello', index([1.3]));}, TypeError);
});
it('should set the right subset of a string', function() {
var j = 'hello';
assert.deepEqual(subset(j, index(0), 'H'), 'Hello');
assert.deepEqual(j, 'hello');
assert.deepEqual(subset(j, index(5), '!'), 'hello!');
assert.deepEqual(j, 'hello');
assert.deepEqual(subset(j, index(new Range(5,11)), ' world'), 'hello world');
assert.deepEqual(j, 'hello');
});
it('should throw an error when index is out of range for a string', function() {
assert.throws(function () {subset('hello', index(5));}, /Index out of range/);
assert.throws(function () {subset('hello', index(-1));}, /Index out of range/);
});
it('should set the right subset of a string with resizing', function() {
var j = '';
var defaultValue = 'i';
assert.deepEqual(subset(j, index(5), '!', defaultValue), 'iiiii!');
});
it('should set a property of an object', function() {
var obj = {};
var res = subset(obj, index('foo'), 'bar');
assert.deepEqual(res, {foo: 'bar'});
assert.deepEqual(obj, {}); // should leave the original object untouched
});
it('should throw an error if setting the subset of a string with an invalid replacement', function() {
assert.throws(function () {subset('hello', index([1,2]), '1234');}, RangeError);
assert.throws(function () {subset('hello', index(1,2), 'a');}, RangeError);
});
it('should throw an error if in case of dimensions mismatch', function() {
assert.throws(function () {subset('hello', index(1,2));}, /Dimension mismatch/);
assert.throws(function () {subset('hello', index(1,2), 'a');}, /Dimension mismatch/);
});
it('should throw an error if in case of a default value with length > 0', function() {
assert.throws(function () {subset('hello', index(10), '!', 'foo');}, /Single character expected as defaultValue/);
});
it('should throw an error if in case of an invalid index type', function() {
assert.throws(function () {subset('hello', 2);}, /TypeError: Unexpected type of argument/);
assert.throws(function () {subset('hello', 2, 'A');}, /TypeError: Unexpected type of argument/);
});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {subset();}, /TypeError: Too few arguments/);
assert.throws(function () {subset(d);}, /TypeError: Too few arguments/);
assert.throws(function () {subset(d, index(0,0), 1, 0, 5);}, /TypeError: Too many arguments/);
});
it('should throw an error in case of invalid type of arguments', function() {
assert.throws(function () {subset([1,2], [0]);}, /TypeError: Unexpected type of argument/);
//assert.throws(function () {subset(new Date(), index(0));}, /TypeError: Unexpected type of argument/); // FIXME: should fail too. Problem is, Date is also an Object
// assert.throws(function () {subset(/foo/, index(0));}, /TypeError: Unexpected type of argument/); // FIXME: should fail too. Problem is, Date is also an Object
});
it('should LaTeX subset', function () {
var expression = math.parse('subset([1],index(0,0))');
assert.equal(expression.toTex(), '\\mathrm{subset}\\left(\\begin{bmatrix}1\\\\\\end{bmatrix},\\mathrm{index}\\left(0,0\\right)\\right)');
});
});
/**
* Helper function to create an Array containing uninitialized values
* Example: arr(uninit, uninit, 2); // [ , , 2 ]
*/
var uninit = {};
function arr() {
var array = [];
array.length = arguments.length;
for (var i = 0; i < arguments.length; i++) {
var value = arguments[i];
if (value !== uninit) {
array[i] = value;
}
}
return array;
}

View File

@@ -0,0 +1,282 @@
var assert = require('assert'),
approx = require('../../../tools/approx'),
math = require('../../../index');
describe('trace', function() {
it('should calculate correctly the trace of a NxN array', function() {
assert.equal(math.trace([5]), 5);
assert.equal(math.trace([[1,2],[3,4]]), 5);
approx.equal(math.trace([
[-2, 2, 3],
[-1, 1, 3],
[ 2, 0, -1]
]), -2);
approx.equal(math.trace([
[ 1, 4, 7],
[ 3, 0, 5],
[-1, 9, 11]
]), 12);
approx.equal(math.trace([
[1,7,4,3,7],
[0,7,0,3,7],
[0,7,4,3,0],
[1,7,5,9,7],
[2,7,4,3,7]
]), 28);
});
it('should calculate correctly the trace of a NxN matrix', function() {
assert.equal(math.trace(math.matrix([5])), 5);
assert.equal(math.trace(math.matrix([[1,2],[3,4]])), 5);
assert.equal(math.trace(math.matrix([[1,2],[3,4]])), 5);
approx.equal(
math.trace(
math.matrix(
[
[-2, 2, 3],
[-1, 1, 3],
[ 2, 0, -1]
])),
-2);
approx.equal(
math.trace(
math.matrix(
[
[ 1, 4, 7],
[ 3, 0, 5],
[-1, 9, 11]
])),
12);
approx.equal(
math.trace(
math.matrix(
[
[1, 7, 4, 3, 7],
[0, 7, 0, 3, 7],
[0, 7, 4, 3, 0],
[1, 7, 5, 9, 7],
[2, 7, 4, 3, 7]
])),
28);
approx.equal(math.trace(math.diag([4, -5, 6])), 5);
});
it('should calculate correctly the trace of a NxN matrix, sparse', function() {
assert.equal(math.trace(math.matrix([5], 'sparse')), 5);
assert.equal(math.trace(math.matrix([[1,2],[3,4]], 'sparse')), 5);
assert.equal(math.trace(math.matrix([[1,2],[3,4]], 'sparse')), 5);
approx.equal(
math.trace(
math.matrix(
[
[-2, 2, 3],
[-1, 1, 3],
[ 2, 0, -1]
],
'sparse')),
-2);
approx.equal(
math.trace(
math.matrix(
[
[ 1, 4, 7],
[ 3, 0, 5],
[-1, 9, 11]
],
'sparse')),
12);
approx.equal(
math.trace(
math.matrix(
[
[1, 7, 4, 3, 7],
[0, 7, 0, 3, 7],
[0, 7, 4, 3, 0],
[1, 7, 5, 9, 7],
[2, 7, 4, 3, 7]
],
'sparse')),
28);
});
it('should return N for the identity matrix',function() {
assert.equal(math.trace(math.eye(7)), 7);
assert.equal(math.trace(math.eye(2)), 2);
assert.equal(math.trace(math.eye(1)), 1);
});
it('should calculate the trace for a scalar',function() {
assert.equal(math.trace(7), 7);
var c1 = math.complex(2, 3);
var c2 = math.trace(c1);
assert.deepEqual(c1, c2);
// c2 should be a clone
c1.re = 0;
assert.equal(c1.re, 0);
assert.equal(c2.re, 2);
});
it('should calculate the trace for a 1x1 array',function() {
var c1 = math.complex(2, 3);
var c2 = math.trace([[c1]]);
assert.deepEqual(c1, c2);
// c2 should be a clone
c1.re = 0;
assert.equal(c1.re, 0);
assert.equal(c2.re, 2);
});
it('should calculate the trace for a 1x1 matrix',function() {
var c1 = math.complex(2, 3);
var c2 = math.trace(math.matrix([[c1]]));
assert.deepEqual(c1, c2);
// c2 should be a clone
c1.re = 0;
assert.equal(c1.re, 0);
assert.equal(c2.re, 2);
});
it('should calculate the trace for a 1x1 matrix, sparse',function() {
var c1 = math.complex(2, 3);
var c2 = math.trace(math.matrix([[c1]], 'sparse'));
assert.deepEqual(c1, c2);
// c2 should be a clone
c1.re = 0;
assert.equal(c1.re, 0);
assert.equal(c2.re, 2);
});
it('should calculate correctly the trace of a matrix with bignumbers', function() {
var bignumber = math.bignumber;
// 1x1
assert.deepEqual(math.trace([bignumber(5)]), bignumber(5));
// 2x2
assert.deepEqual(math.trace([
[bignumber(1), bignumber(2)],
[bignumber(3), bignumber(4)]
]), bignumber(5));
// 3x3
assert.deepEqual(math.trace([
[bignumber(-2), bignumber(2), bignumber( 3)],
[bignumber(-1), bignumber(1), bignumber( 3)],
[bignumber( 2), bignumber(0), bignumber(-1)]
]), bignumber(-2));
// the following would fail with regular Numbers due to a precision overflow
assert.deepEqual(math.trace([
[bignumber(1e10+1), bignumber(1e10)],
[bignumber(1e10), bignumber(-1e10)]
]), bignumber(1));
});
it('should calculate the trace of a matrix with mixed numbers and bignumbers', function() {
var bignumber = math.bignumber;
assert.deepEqual(math.trace([
[bignumber(2), 1],
[bignumber(3), 4]
]), bignumber(6));
});
it('should not change the value of the initial matrix', function() {
var m_test = [[1,2,3],[4,5,6],[7,8,9]];
math.trace(m_test);
assert.deepEqual(m_test, [[1,2,3],[4,5,6],[7,8,9]]);
});
it('should not accept a non-square matrix', function() {
assert.throws(function() { math.trace([1,2]); });
assert.throws(function() { math.trace([[1,2,3],[1,2,3]]); });
assert.throws(function() { math.trace([0,1],[0,1],[0,1]); });
assert.throws(function() { math.trace(math.matrix([[1,2,3],[1,2,3]])); });
assert.throws(function() { math.trace(math.matrix([[1,2,3],[1,2,3]], 'sparse')); });
});
it('should not accept arrays with dimensions higher than 2', function() {
assert.throws(function() { math.trace([[[1]]]); }, RangeError);
assert.throws(function() { math.trace(math.matrix([[[1]]])); }, RangeError);
});
it('should LaTeX trace', function () {
var expression = math.parse('trace([[1,2],[3,4]])');
assert.equal(expression.toTex(), '\\mathrm{tr}\\left(\\begin{bmatrix}1&2\\\\3&4\\\\\\end{bmatrix}\\right)');
});
describe('DenseMatrix', function () {
it('should calculate trace on a square matrix', function() {
var m = math.matrix([
[1, 2],
[4, -2]
]);
assert.equal(math.trace(m), -1);
m = math.matrix([
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]);
assert.equal(math.trace(m), 0);
m = math.matrix([
[1, 0, 0, 0],
[0, 0, 2, 0],
[1, 0, 0, 0],
[0, 0, 1, 9]
]);
assert.equal(math.trace(m), 10);
});
it('should throw an error for invalid matrix', function() {
var m = math.matrix([
[1, 2, 3],
[4, 5, 6]
]);
assert.throws(function () { math.trace(m); });
});
});
describe('SparseMatrix', function () {
it('should calculate trace on a square matrix', function() {
var m = math.matrix([
[1, 2],
[4, -2]
], 'sparse');
assert.equal(math.trace(m), -1);
m = math.matrix([
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
], 'sparse');
assert.equal(math.trace(m), 0);
m = math.matrix([
[1, 0, 0, 0],
[0, 0, 2, 0],
[1, 0, 0, 0],
[0, 0, 1, 9]
], 'sparse');
assert.equal(math.trace(m), 10);
});
it('should throw an error for invalid matrix', function() {
var m = math.matrix([
[1, 2, 3],
[4, 5, 6]
], 'sparse');
assert.throws(function () { math.trace(m); });
});
});
});

View File

@@ -0,0 +1,103 @@
// test transpose
var assert = require('assert'),
math = require('../../../index'),
transpose = math.transpose;
describe('transpose', function() {
it('should transpose a scalar', function() {
assert.deepEqual(transpose(3), 3);
});
it('should transpose a vector', function() {
assert.deepEqual(transpose([1,2,3]), [1,2,3]);
assert.deepEqual(transpose(math.matrix([1,2,3]).toArray()), [1,2,3]);
});
it('should transpose a 2d matrix', function() {
assert.deepEqual(transpose([[1,2,3],[4,5,6]]), [[1,4],[2,5],[3,6]]);
assert.deepEqual(transpose(math.matrix([[1,2,3],[4,5,6]]).toArray()), [[1,4],[2,5],[3,6]]);
assert.deepEqual(transpose([[1,2],[3,4]]), [[1,3],[2,4]]);
assert.deepEqual(transpose([[1,2,3,4]]), [[1],[2],[3],[4]]);
});
it('should throw an error for invalid matrix transpose', function() {
assert.throws(function () {
assert.deepEqual(transpose([[]]), [[]]); // size [2,0]
});
assert.throws(function () {
transpose([[[1],[2]],[[3],[4]]]); // size [2,2,1]
});
});
it('should throw an error if called with an invalid number of arguments', function() {
assert.throws(function () {transpose();}, /TypeError: Too few arguments/);
assert.throws(function () {transpose([1,2],2);}, /TypeError: Too many arguments/);
});
describe('DenseMatrix', function () {
it('should transpose a 2d matrix', function() {
var m = math.matrix([[1,2,3],[4,5,6]]);
var t = transpose(m);
assert.deepEqual(t.valueOf(), [[1,4],[2,5],[3,6]]);
m = math.matrix([[1,4],[2,5],[3,6]]);
t = transpose(m);
assert.deepEqual(t.toArray(), [[1,2,3],[4,5,6]]);
m = math.matrix([[1,2],[3,4]]);
t = transpose(m);
assert.deepEqual(t.valueOf(), [[1,3],[2,4]]);
m = math.matrix([[1,2,3,4]]);
t = transpose(m);
assert.deepEqual(t.valueOf(), [[1],[2],[3],[4]]);
m = math.matrix([[1,2,3,4]], 'dense', 'number');
t = transpose(m);
assert.deepEqual(t.valueOf(), [[1],[2],[3],[4]]);
assert.ok(t.datatype() === 'number');
});
it('should throw an error for invalid matrix transpose', function() {
var m = math.matrix([[]]);
assert.throws(function () { transpose(m); });
m = math.matrix([[[1],[2]],[[3],[4]]]);
assert.throws(function () { transpose(m); });
});
});
describe('SparseMatrix', function () {
it('should transpose a 2d matrix', function() {
var m = math.sparse([[1,2,3],[4,5,6]]);
var t = transpose(m);
assert.deepEqual(t.valueOf(), [[1,4],[2,5],[3,6]]);
m = math.sparse([[1,4],[2,5],[3,6]]);
t = transpose(m);
assert.deepEqual(t.toArray(), [[1,2,3],[4,5,6]]);
m = math.sparse([[1,2],[3,4]]);
t = transpose(m);
assert.deepEqual(t.valueOf(), [[1,3],[2,4]]);
m = math.sparse([[1,2,3,4]], 'number');
t = transpose(m);
assert.deepEqual(t.valueOf(), [[1],[2],[3],[4]]);
assert.ok(t.datatype() === 'number');
});
it('should throw an error for invalid matrix transpose', function() {
var m = math.matrix([[]], 'sparse');
assert.throws(function () { transpose(m); });
});
});
it('should LaTeX transpose', function () {
var expression = math.parse('transpose([[1,2],[3,4]])');
assert.equal(expression.toTex(), '\\left(\\begin{bmatrix}1&2\\\\3&4\\\\\\end{bmatrix}\\right)^\\top');
});
});

View File

@@ -0,0 +1,78 @@
// test zeros
var assert = require('assert'),
math = require('../../../index'),
zeros = math.zeros,
matrix = math.matrix;
describe('zeros', function() {
it('should create an empty matrix', function () {
assert.deepEqual(zeros(), matrix());
assert.deepEqual(zeros([]), []);
assert.deepEqual(zeros(matrix([])), matrix());
});
it('should create an empty matrix, sparse', function () {
assert.deepEqual(zeros('sparse'), matrix('sparse'));
assert.deepEqual(zeros([], 'sparse'), matrix([], 'sparse'));
assert.deepEqual(zeros(matrix([]), 'sparse'), matrix('sparse'));
});
it('should create a vector with zeros', function () {
assert.deepEqual(zeros(3), matrix([0,0,0]));
assert.deepEqual(zeros(matrix([4])), matrix([0,0,0,0]));
assert.deepEqual(zeros([4]), [0,0,0,0]);
assert.deepEqual(zeros(0), matrix([]));
});
it('should create a matrix with bignumber zeros', function () {
var zero = math.bignumber(0);
var three = math.bignumber(3);
assert.deepEqual(zeros(three), matrix([zero,zero,zero]));
assert.deepEqual(zeros([three]), [zero,zero,zero]);
});
it('should create a 2D matrix with zeros from an array', function () {
assert.deepEqual(zeros(2,3), matrix([[0,0,0],[0,0,0]]));
assert.deepEqual(zeros(3,2), matrix([[0,0],[0,0],[0,0]]));
assert.deepEqual(zeros([3,2]), [[0,0],[0,0],[0,0]]);
});
it('should create a matrix with zeros from a matrix', function () {
assert.deepEqual(zeros(matrix([3])), matrix([0,0,0]));
assert.deepEqual(zeros(matrix([3,2])), matrix([[0,0],[0,0],[0,0]]));
});
it('should create a 3D matrix with zeros', function () {
var res = [
[
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]
],
[
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]
]
];
assert.deepEqual(zeros(2,3,4), matrix(res));
assert.deepEqual(zeros(matrix([2,3,4])), matrix(res));
assert.deepEqual(zeros([2,3,4]), res);
});
// TODO: test setting `matrix`
it('should create a matrix with zeros with the same size as original matrix', function () {
var a = matrix([[1, 2, 3], [4, 5, 6]]);
assert.deepEqual(zeros(math.size(a)).size(), a.size());
});
// TODO: test with invalid input
it('should LaTeX zeros', function () {
var expression = math.parse('zeros(2,3)');
assert.equal(expression.toTex(), '\\mathrm{zeros}\\left(2,3\\right)');
});
});

View File

@@ -0,0 +1,44 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
combinations = math.combinations;
describe('combinations', function() {
it('should calculate the combinations of a number taking k at a time', function() {
assert.equal(combinations(0, 0), 1);
assert.equal(combinations(7, 5), 21);
assert.equal(combinations(20, 15), 15504);
assert.equal(combinations(63, 7), 553270671);
assert.equal(combinations(25, 6), 177100);
});
it('should calculate the combinations of n items taken k at a time with BigNumbers', function() {
assert.deepEqual(combinations(math.bignumber(7), math.bignumber(5)), math.bignumber(21));
assert.deepEqual(combinations(math.bignumber(20), math.bignumber(15)), math.bignumber(15504));
assert.deepEqual(combinations(math.bignumber(63), math.bignumber(7)), math.bignumber(553270671));
assert.deepEqual(combinations(math.bignumber(25), math.bignumber(6)), math.bignumber(177100));
});
it('should not work with non-integer and negative input', function() {
assert.throws(function() {combinations(-12, 6)}, TypeError);
assert.throws(function() {combinations(12, -6)}, TypeError);
assert.throws(function() {combinations(0.5, 3)}, TypeError);
assert.throws(function() {combinations(4, 0.5)}, TypeError);
assert.throws(function() {combinations(3, 5)}, TypeError);
assert.throws(function() {combinations(math.bignumber(3), math.bignumber(5))}, TypeError);
assert.throws(function() {combinations(math.bignumber(3.5), math.bignumber(-3))}, TypeError);
assert.throws(function() {combinations(math.bignumber(3.5), 1/3)}, TypeError);
});
it('should not work with the wrong number or type of arguments', function() {
assert.throws(function() {combinations(5, 3, 2)});
assert.throws(function() {combinations(true, "hello world")});
});
it('should LaTeX combinations', function () {
var expression = math.parse('combinations(3,2)');
assert.equal(expression.toTex(), '\\binom{3}{2}');
});
});

View File

@@ -0,0 +1,632 @@
var assert = require('assert');
var error = require('../../../lib/error/index');
var seed = require('seed-random');
var _ = require('underscore');
var math = require('../../../index');
math.import(require('../../../lib/function/probability/distribution'));
var Matrix = math.type.Matrix;
var distribution = math.distribution;
var assertApproxEqual = function(testVal, val, tolerance) {
var diff = Math.abs(val - testVal);
if (diff > tolerance) assert.equal(testVal, val);
else assert.ok(diff <= tolerance)
};
var assertUniformDistribution = function(values, min, max) {
var interval = (max - min) / 10
, count, i;
count = _.filter(values, function(val) { return val < min }).length;
assert.equal(count, 0);
count = _.filter(values, function(val) { return val > max }).length;
assert.equal(count, 0);
for (i = 0; i < 10; i++) {
count = _.filter(values, function(val) {
return val >= (min + i * interval) && val < (min + (i + 1) * interval)
}).length;
assertApproxEqual(count/values.length, 0.1, 0.02);
}
};
var assertUniformDistributionInt = function(values, min, max) {
var range = _.range(Math.floor(min), Math.floor(max)), count;
values.forEach(function(val) {
assert.ok(_.contains(range, val));
});
range.forEach(function(val) {
count = _.filter(values, function(testVal) { return testVal === val }).length;
assertApproxEqual(count/values.length, 1/range.length, 0.03);
});
};
describe('distribution', function () {
var originalRandom, uniformDistrib;
before(function () {
// replace the original Math.random with a reproducible one
originalRandom = Math.random;
Math.random = seed('key');
});
after(function () {
// restore the original random function
Math.random = originalRandom;
});
beforeEach(function() {
uniformDistrib = distribution('uniform')
});
describe('random', function() {
var originalRandom;
it('should pick uniformly distributed numbers in [0, 1]', function() {
var picked = [];
_.times(1000, function() {
picked.push(uniformDistrib.random())
});
assertUniformDistribution(picked, 0, 1);
});
it('should pick uniformly distributed numbers in [min, max]', function() {
var picked = [];
_.times(1000, function() {
picked.push(uniformDistrib.random(-10, 10));
});
assertUniformDistribution(picked, -10, 10);
});
it('should pick uniformly distributed random array, with elements in [0, 1]', function() {
var picked = [],
matrices = [],
size = [2, 3, 4];
_.times(100, function() {
matrices.push(uniformDistrib.random(size));
});
// Collect all values in one array
matrices.forEach(function(matrix) {
assert(Array.isArray(matrix));
assert.deepEqual(math.size(matrix), size);
math.forEach(matrix, function(val) {
picked.push(val);
})
});
assert.equal(picked.length, 2 * 3 * 4 * 100);
assertUniformDistribution(picked, 0, 1);
});
it('should pick uniformly distributed random array, with elements in [0, max]', function() {
var picked = [],
matrices = [],
size = [2, 3, 4];
_.times(100, function() {
matrices.push(uniformDistrib.random(size, 8));
});
// Collect all values in one array
matrices.forEach(function(matrix) {
assert(Array.isArray(matrix));
assert.deepEqual(math.size(matrix), size);
math.forEach(matrix, function(val) {
picked.push(val);
})
});
assert.equal(picked.length, 2 * 3 * 4 * 100);
assertUniformDistribution(picked, 0, 8);
});
it('should pick uniformly distributed random matrix, with elements in [0, 1]', function() {
var picked = [],
matrices = [],
size = math.matrix([2, 3, 4]);
_.times(100, function() {
matrices.push(uniformDistrib.random(size));
});
// Collect all values in one array
matrices.forEach(function(matrix) {
assert(matrix instanceof Matrix);
assert.deepEqual(matrix.size(), size.valueOf());
matrix.forEach(function(val) {
picked.push(val);
})
});
assert.equal(picked.length, 2 * 3 * 4 * 100);
assertUniformDistribution(picked, 0, 1);
});
it('should pick uniformly distributed random array, with elements in [min, max]', function() {
var picked = [],
matrices = [],
size = [2, 3, 4];
_.times(100, function() {
matrices.push(uniformDistrib.random(size, -103, 8));
});
// Collect all values in one array
matrices.forEach(function(matrix) {
assert.deepEqual(math.size(matrix), size);
math.forEach(matrix, function(val) {
picked.push(val);
})
});
assert.equal(picked.length, 2 * 3 * 4 * 100);
assertUniformDistribution(picked, -103, 8);
});
it ('should throw an error if called with invalid arguments', function() {
assert.throws(function() { uniformDistrib.random(1, 2, [4, 8]); });
assert.throws(function() { uniformDistrib.random(1, 2, 3, 6); });
assert.throws( function () {uniformDistrib.random('str', 10)} );
assert.throws( function () {uniformDistrib.random(math.bignumber(-10), 10)} );
});
});
describe('randomInt', function() {
it('should pick uniformly distributed integers in [min, max)', function() {
var picked = [];
_.times(10000, function() {
picked.push(uniformDistrib.randomInt(-15, -5));
});
assertUniformDistributionInt(picked, -15, -5);
});
it('should pick uniformly distributed random array, with elements in [min, max)', function() {
var picked = [],
matrices = [],
size = [2, 3, 4];
_.times(1000, function() {
matrices.push(uniformDistrib.randomInt(size, -14.9, -2));
});
// Collect all values in one array
matrices.forEach(function(matrix) {
assert.deepEqual(math.size(matrix), size);
math.forEach(matrix, function(val) {
picked.push(val)
});
});
assert.equal(picked.length, 2 * 3 * 4 * 1000);
assertUniformDistributionInt(picked, -14.9, -2);
});
it('should throw an error if called with invalid arguments', function() {
assert.throws(function() {
uniformDistrib.randomInt(1, 2, [4, 8]);
});
assert.throws(function() {
uniformDistrib.randomInt(1, 2, 3, 6);
});
});
});
describe('pickRandom', function() {
it('should throw an error when providing a multi dimensional matrix', function() {
assert.throws(function () {
uniformDistrib.pickRandom(math.matrix([[1,2], [3,4]]));
}, /Only one dimensional vectors supported/);
});
it('should throw an error if the length of the weights does not match the length of the possibles', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, 4],
number = 2;
assert.throws(function() {
uniformDistrib.pickRandom(possibles, weights);
}, /Weights must have the same length as possibles/);
assert.throws(function() {
uniformDistrib.pickRandom(possibles, number, weights);
}, /Weights must have the same length as possibles/);
assert.throws(function() {
uniformDistrib.pickRandom(possibles, weights, number);
}, /Weights must have the same length as possibles/);
});
it('should throw an error if the weights array contains a non number or negative value', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, -1, 6],
number = 2;
assert.throws(function() {
uniformDistrib.pickRandom(possibles, weights);
}, /Weights must be an array of positive numbers/);
weights = [1, 5, 2, "stinky", 6];
assert.throws(function() {
uniformDistrib.pickRandom(possibles, weights);
}, /Weights must be an array of positive numbers/);
});
it('should return a single value if no number argument was passed', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, 4, 6];
assert.notEqual(possibles.indexOf(uniformDistrib.pickRandom(possibles)), -1);
assert.notEqual(possibles.indexOf(uniformDistrib.pickRandom(possibles, weights)), -1);
});
it('should return the given array if the given number is equal its length', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, 4, 6],
number = 5;
assert.equal(uniformDistrib.pickRandom(possibles, number), possibles);
assert.equal(uniformDistrib.pickRandom(possibles, number, weights), possibles);
assert.equal(uniformDistrib.pickRandom(possibles, weights, number), possibles);
});
it('should return the given array if the given number is greater than its length', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, 4, 6],
number = 6;
assert.equal(uniformDistrib.pickRandom(possibles, number), possibles);
assert.equal(uniformDistrib.pickRandom(possibles, number, weights), possibles);
assert.equal(uniformDistrib.pickRandom(possibles, weights, number), possibles);
});
it('should return an empty array if the given number is 0', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, 4, 6],
number = 0;
assert.equal(uniformDistrib.pickRandom(possibles, number).length, 0);
assert.equal(uniformDistrib.pickRandom(possibles, number, weights).length, 0);
assert.equal(uniformDistrib.pickRandom(possibles, weights, number).length, 0);
});
it('should return an array of length 1 if the number passed is 1', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, 4, 6],
number = 1;
assert(Array.isArray(uniformDistrib.pickRandom(possibles, number)));
assert(Array.isArray(uniformDistrib.pickRandom(possibles, number, weights)));
assert(Array.isArray(uniformDistrib.pickRandom(possibles, weights, number)));
assert.equal(uniformDistrib.pickRandom(possibles, number).length, 1);
assert.equal(uniformDistrib.pickRandom(possibles, number, weights).length, 1);
assert.equal(uniformDistrib.pickRandom(possibles, weights, number).length, 1);
});
it('should pick the given number of values from the given array', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 5, 2, 4, 6],
number = 3;
assert.equal(uniformDistrib.pickRandom(possibles, number).length, number);
assert.equal(uniformDistrib.pickRandom(possibles, number, weights).length, number);
assert.equal(uniformDistrib.pickRandom(possibles, weights, number).length, number);
});
it('should pick a value from the given array following an uniform distribution if only possibles are passed', function() {
var possibles = [11, 22, 33, 44, 55],
picked = [],
count;
_.times(1000, function() {
picked.push(uniformDistrib.pickRandom(possibles));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
});
it('should pick a value from the given matrix following an uniform distribution', function() {
var possibles = math.matrix([11, 22, 33, 44, 55]),
picked = [],
count;
_.times(1000, function() {
picked.push(uniformDistrib.pickRandom(possibles));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
});
it('should pick a given number of values from the given array following an uniform distribution if no weights were passed', function() {
var possibles = [11, 22, 33, 44, 55],
number = 2,
picked = [],
count;
_.times(1000, function() {
picked.push.apply(picked, uniformDistrib.pickRandom(possibles, number));
});
assert.equal(picked.length, 2000);
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
});
it('should pick numbers from the given matrix following an uniform distribution', function() {
var possibles = math.matrix([11, 22, 33, 44, 55]),
number = 3,
picked = [],
count;
_.times(1000, function() {
picked.push.apply(picked, uniformDistrib.pickRandom(possibles, number));
});
assert.equal(picked.length, 3000);
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
});
it('should pick a value from the given array following a weighted distribution', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 4, 0, 2, 3],
picked = [],
count;
_.times(1000, function() {
picked.push(uniformDistrib.pickRandom(possibles, weights));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.1);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round((count)/picked.length, 1), 0.4);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.3);
});
it('should pick a value from the given matrix following a weighted distribution', function() {
var possibles = math.matrix([11, 22, 33, 44, 55]),
weights = [1, 4, 0, 2, 3],
picked = [],
count;
_.times(1000, function() {
picked.push(uniformDistrib.pickRandom(possibles, weights));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.1);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round((count)/picked.length, 1), 0.4);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.3);
});
it('should return an array of values from the given array following a weighted distribution', function() {
var possibles = [11, 22, 33, 44, 55],
weights = [1, 4, 0, 2, 3],
number = 2,
picked = [],
count;
_.times(1000, function() {
picked.push.apply(picked, uniformDistrib.pickRandom(possibles, number, weights));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.1);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round((count)/picked.length, 1), 0.4);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.3);
_.times(1000, function() {
picked.push.apply(picked, uniformDistrib.pickRandom(possibles, weights, number));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.1);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round((count)/picked.length, 1), 0.4);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.3);
});
it('should return an array of values from the given matrix following a weighted distribution', function() {
var possibles = math.matrix([11, 22, 33, 44, 55]),
weights = [1, 4, 0, 2, 3],
number = 2,
picked = [],
count;
_.times(1000, function() {
picked.push.apply(picked, uniformDistrib.pickRandom(possibles, number, weights));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.1);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round((count)/picked.length, 1), 0.4);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.3);
_.times(1000, function() {
picked.push.apply(picked, uniformDistrib.pickRandom(possibles, weights, number));
});
count = _.filter(picked, function(val) { return val === 11 }).length;
assert.equal(math.round(count/picked.length, 1), 0.1);
count = _.filter(picked, function(val) { return val === 22 }).length;
assert.equal(math.round((count)/picked.length, 1), 0.4);
count = _.filter(picked, function(val) { return val === 33 }).length;
assert.equal(math.round(count/picked.length, 1), 0);
count = _.filter(picked, function(val) { return val === 44 }).length;
assert.equal(math.round(count/picked.length, 1), 0.2);
count = _.filter(picked, function(val) { return val === 55 }).length;
assert.equal(math.round(count/picked.length, 1), 0.3);
});
});
describe('distribution.normal', function() {
it('should pick numbers in [0, 1] following a normal distribution', function() {
var picked = [], count, dist = distribution('normal');
_.times(100000, function() {
picked.push(dist.random())
});
count = _.filter(picked, function(val) { return val < 0 }).length;
assert.equal(count, 0);
count = _.filter(picked, function(val) { return val > 1 }).length;
assert.equal(count, 0);
count = _.filter(picked, function(val) { return val < 0.25 }).length;
assertApproxEqual(count/picked.length, 0.07, 0.01);
count = _.filter(picked, function(val) { return val < 0.4 }).length;
assertApproxEqual(count/picked.length, 0.27, 0.01);
count = _.filter(picked, function(val) { return val < 0.5 }).length;
assertApproxEqual(count/picked.length, 0.5, 0.01);
count = _.filter(picked, function(val) { return val < 0.6 }).length;
assertApproxEqual(count/picked.length, 0.73, 0.01);
count = _.filter(picked, function(val) { return val < 0.75 }).length;
assertApproxEqual(count/picked.length, 0.93, 0.01);
});
});
it('should throw an error in case of unknown distribution name', function() {
assert.throws(function () {
distribution('non-existing');
}, /Unknown distribution/)
});
it('created random functions should throw an error in case of wrong number of arguments', function() {
var dist = distribution('uniform');
assert.throws(function () {dist.random([2,3], 10, 100, 12); }, error.ArgumentsError);
assert.throws(function () {dist.randomInt([2,3], 10, 100, 12); }, error.ArgumentsError);
assert.throws(function () {dist.pickRandom(); }, error.ArgumentsError);
assert.throws(function () {dist.pickRandom([], 23, [], 9); }, error.ArgumentsError);
});
it('created random functions should throw an error in case of wrong type of arguments', function() {
var dist = distribution('uniform');
assert.throws(function () {dist.pickRandom(23); }, error.TypeError);
// TODO: more type testing...
});
it('should LaTeX distribution', function () {
var expression = math.parse('distribution("normal")');
assert.equal(expression.toTex(), '\\mathrm{distribution}\\left(\\mathtt{"normal"}\\right)');
});
});

View File

@@ -0,0 +1,101 @@
var assert = require('assert'),
approx = require('../../../tools/approx'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
factorial = math.factorial;
describe('factorial', function() {
it('should calculate the factorial of a number', function() {
assert.equal(factorial(0), 1);
assert.equal(factorial(1), 1);
assert.equal(factorial(2), 2);
assert.equal(factorial(3), 6);
assert.equal(factorial(4), 24);
assert.equal(factorial(5), 120);
assert.ok(!isFinite(factorial(Number.MAX_VALUE))); // shouldn't stall
assert.ok(!isFinite(factorial(Infinity)));
});
it('should calculate the factorial of a bignumber', function() {
var bigmath = math.create({number: 'BigNumber', precision: 5});
var bigfactorial = bigmath.factorial;
var bignumber = bigmath.bignumber;
assert.deepEqual(bigfactorial(bignumber(0)), bignumber(1));
assert.deepEqual(bigfactorial(bignumber(Infinity)).toString(), 'Infinity');
assert.deepEqual(bigfactorial(bignumber(11)), bignumber(39917000));
assert.deepEqual(bigfactorial(bignumber(22)), bignumber(1.124e+21));
bigmath.config({precision: 20});
assert.deepEqual(bigfactorial(bignumber(5)), bignumber(120));
assert.deepEqual(bigfactorial(bignumber(19)), bignumber(121645100408832000));
assert.deepEqual(bigfactorial(bignumber(20)), bignumber(2432902008176640000));
assert.deepEqual(bigfactorial(bignumber(21)), bignumber('51090942171709440000'));
assert.deepEqual(bigfactorial(bignumber(25)), bignumber('1.5511210043330985984e+25'));
assert.deepEqual(bigfactorial(bignumber(24)), bignumber('6.2044840173323943936e+23'));
assert.deepEqual(bigfactorial(bignumber(22)), bignumber('1124000727777607680000'));
bigmath.config({precision: 5});
assert.deepEqual(bigfactorial(bignumber(11)), bignumber(39917000));
assert.deepEqual(bigfactorial(bignumber(22)), bignumber(1.124e+21));
assert.deepEqual(bigfactorial(bignumber(24)), bignumber(6.2045e+23));
assert.deepEqual(bigfactorial(bignumber(21)), bignumber(5.1091e+19));
assert.deepEqual(bigfactorial(bignumber(26)), bignumber(4.0329e+26));
bigmath.config({precision: 20});
assert.deepEqual(bigfactorial(bignumber(3000)), bignumber('4.1493596034378540856e+9130'));
});
it('should calculate the factorial of a boolean', function() {
assert.equal(factorial(true), 1);
assert.equal(factorial(false), 1);
});
it('should calculate the factorial of null', function() {
assert.equal(factorial(null), 1);
});
it('should calculate the factorial of each element in a matrix', function() {
assert.deepEqual(factorial(math.matrix([0,1,2,3,4,5])), math.matrix([1,1,2,6,24,120]));
});
it('should calculate the factorial of each element in an array', function() {
assert.deepEqual(factorial([0,1,2,3,4,5]), [1,1,2,6,24,120]);
});
it('should calculate the factorial of a non-integer', function() {
approx.equal(factorial(1.5), 1.32934038817913702047362561);
approx.equal(factorial(7.5), 14034.40729348);
});
it('should throw error if called with negative number', function() {
assert.throws(function() { factorial(-1); }, /Value must be non-negative/);
assert.throws(function() { factorial(-1.5); }, /Value must be non-negative/);
assert.throws(function() { factorial(math.bignumber(-1)); }, /Value must be non-negative/);
assert.throws(function() { factorial(math.bignumber(-1.5)); }, /Value must be non-negative/);
assert.throws(function() { factorial(math.bignumber(-Infinity)); }, /Value must be non-negative/);
});
it('should throw an error if called with non-integer bignumber', function() {
assert.throws(function() { factorial(math.bignumber(1.5)); });
});
it('should throw en error if called with invalid number of arguments', function() {
assert.throws(function() { factorial(); });
assert.throws(function() { factorial(1,3); });
});
it('should throw en error if called with invalid type of argument', function() {
assert.throws(function() { factorial(new Date()); });
assert.throws(function() { factorial('a string'); });
});
it('should LaTeX factorial', function () {
var expression = math.parse('factorial(6)');
assert.equal(expression.toTex(), '\\left(6\\right)!');
});
});

View File

@@ -0,0 +1,164 @@
var assert = require('assert'),
approx = require('../../../tools/approx'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
bigUtil = require('../../../lib/utils/index').bignumber,
bignumber = math.bignumber,
gamma = math.gamma;
describe('gamma', function () {
it('should calculate the gamma of an integer number', function () {
assert.equal(gamma(1), 1);
assert.equal(gamma(2), 1);
assert.equal(gamma(3), 2);
assert.equal(gamma(4), 6);
assert.equal(gamma(5), 24);
assert.equal(gamma(6), 120);
assert.equal(gamma(Infinity), Infinity); // shouldn't stall
});
it('should calculate the gamma of a nonpositive integer', function () {
assert.equal(gamma(0), Infinity);
assert.equal(gamma(-1), Infinity);
assert.equal(gamma(-2), Infinity);
assert.equal(gamma(-100000), Infinity);
assert.ok(isNaN(gamma(-Infinity)));
});
it('should calculate the gamma of a rational number', function () {
approx.equal(gamma(0.125), 7.5339415987976119046992);
approx.equal(gamma(0.25), 3.625609908221908311930685);
approx.equal(gamma(0.5), 1.77245385090551602729816748);
approx.equal(gamma(1.5), 0.88622692545275801364908374);
approx.equal(gamma(2.5), 1.32934038817913702047362561);
approx.equal(gamma(3.5), 3.32335097044784255118406403);
approx.equal(gamma(30.5), 4.8226969334909086010917483e+31);
approx.equal(gamma(144.9), 3.37554680943478639050191e+249);
approx.equal(gamma(-0.5), -3.54490770181103205459633);
approx.equal(gamma(-1.5), 2.3632718012073547030642233);
approx.equal(gamma(-2.5), -0.945308720482941881225689);
approx.equal(gamma(-144.9), -2.078523735791760166777e-251);
});
it('should calculate the gamma of an irrational number', function () {
approx.equal(gamma(Math.SQRT2), 0.8865814287192591250809176);
approx.equal(gamma(Math.PI), 2.2880377953400324179595889);
approx.equal(gamma(Math.E), 1.56746825577405307486334);
approx.equal(gamma(-Math.SQRT2), 2.599459907524570073533756846);
approx.equal(gamma(-Math.PI), 1.01569714446021834110892259347);
approx.equal(gamma(-Math.E), -0.952681729748073099220537210195);
});
it('should calculate the gamma of an integer bignumber', function () {
assert.deepEqual(gamma(bignumber(1)), bignumber(1));
assert.deepEqual(gamma(bignumber(2)), bignumber(1));
assert.deepEqual(gamma(bignumber(3)), bignumber(2));
assert.deepEqual(gamma(bignumber(4)), bignumber(6));
assert.deepEqual(gamma(bignumber(5)), bignumber(24));
assert.deepEqual(gamma(bignumber(6)), bignumber(120));
assert.deepEqual(gamma(bignumber(31)), bignumber('265252859812191058636308480000000'));
assert.deepEqual(gamma(bignumber(Infinity)).toString(), 'Infinity');
});
it('should calculate the gamma of a nonpositive integer bignumber', function () {
assert.deepEqual(gamma(bignumber(0)).toString(), 'Infinity');
assert.deepEqual(gamma(bignumber(-1)).toString(), 'Infinity');
assert.deepEqual(gamma(bignumber(-2)).toString(), 'Infinity');
assert.ok(gamma(bignumber(-Infinity)).isNaN());
});
/*
it('should calculate the gamma of a rational bignumber', function () {
assert.deepEqual(gamma(bignumber(0.125)), bignumber('7.5339415987976'));
assert.deepEqual(gamma(bignumber(0.25)), bignumber('3.62560990822191'));
assert.deepEqual(gamma(bignumber(0.5)), bignumber('1.77245385090552'));
assert.deepEqual(gamma(bignumber(1.5)), bignumber('0.886226925452758'));
assert.deepEqual(gamma(bignumber(2.5)), bignumber('1.32934038817914'));
var bigmath = math.create({ precision: 15 });
assert.deepEqual(bigmath.gamma(bignumber(30.5)), '4.82269693349091e+31');
bigmath.config({ precision: 13 });
assert.deepEqual(bigmath.gamma(bignumber(-1.5)), bigmath.bignumber('2.363271801207'));
assert.deepEqual(gamma(bignumber(-2.5)), bignumber('-0.9453087205'));
});
it('should calculate the gamma of an irrational bignumber', function () {
assert.deepEqual(gamma(bigUtil.phi(math.precision).neg()), bignumber('2.3258497469'));
assert.deepEqual(gamma(bigUtil.phi(math.precision)), bignumber('0.895673151705288'));
assert.deepEqual(gamma(bigUtil.pi(20)), bignumber('2.28803779534003'));
assert.deepEqual(gamma(bigUtil.e(math.precision)), bignumber('1.56746825577405'));
var bigmath = math.create({ number: 'BigNumber' });
assert.deepEqual(gamma(bigmath.SQRT2), bignumber('0.886581428719259'));
assert.deepEqual(gamma(bigmath.SQRT2.neg()), bignumber('2.59945990753'));
});
*/
it('should calculate the gamma of an imaginary unit', function () {
approx.deepEqual(gamma(math.i), math.complex(-0.154949828301810685124955130,
-0.498015668118356042713691117));
});
it('should calculate the gamma of a complex number', function () {
approx.deepEqual(gamma(math.complex(1, 1)), math.complex( 0.498015668118356,
-0.154949828301810));
approx.deepEqual(gamma(math.complex(1, -1)), math.complex(0.498015668118356,
0.154949828301810));
approx.deepEqual(gamma(math.complex(-1, 1)), math.complex(-0.17153291990827,
0.32648274821008));
approx.deepEqual(gamma(math.complex(-1, -1)), math.complex(-0.1715329199082,
-0.3264827482100));
approx.deepEqual(gamma(math.complex(0.5, 0.5)), math.complex( 0.81816399954,
-0.76331382871));
approx.deepEqual(gamma(math.complex(0.5, -0.5)), math.complex(0.81816399954,
0.76331382871));
approx.deepEqual(gamma(math.complex(-0.5, 0.5)), math.complex(-1.5814778282,
-0.0548501708));
approx.deepEqual(gamma(math.complex(-0.5, -0.5)), math.complex(-1.581477828,
0.054850170));
approx.deepEqual(gamma(math.complex(5, 3)), math.complex( 0.016041882741652,
-9.433293289755986));
approx.deepEqual(gamma(math.complex(5, -3)), math.complex(0.016041882741652,
9.433293289755986));
approx.deepEqual(math.multiply(gamma(math.complex(-5, 3)), 1e6),
math.complex(7.896487481239, 4.756173836597));
approx.deepEqual(math.multiply(gamma(math.complex(-5, -3)), 1e6),
math.complex(7.8964874812, -4.7561738365));
});
it('should calculate the gamma of a boolean', function () {
assert.equal(gamma(true), 1);
assert.equal(gamma(false), Infinity);
});
it('should calculate the gamma of null', function () {
assert.equal(gamma(null), Infinity);
});
it('should calculate the gamma of each element in a matrix', function () {
assert.deepEqual(gamma(math.matrix([0,1,2,3,4,5])), math.matrix([Infinity,1,1,2,6,24]));
});
it('should calculate the gamma of each element in an array', function () {
assert.deepEqual(gamma([0,1,2,3,4,5]), [Infinity,1,1,2,6,24]);
});
it('should throw en error if called with invalid number of arguments', function() {
assert.throws(function() { gamma(); });
assert.throws(function() { gamma(1,3); });
});
it('should throw en error if called with invalid type of argument', function() {
assert.throws(function() { gamma(new Date()); });
assert.throws(function() { gamma('a string'); });
});
it('should LaTeX gamma', function () {
var expression = math.parse('gamma(2.5)');
assert.equal(expression.toTex(), '\\Gamma\\left(2.5\\right)');
});
});

View File

@@ -0,0 +1,47 @@
var assert = require('assert');
var math = require('../../../index');
describe('kldivergence', function(){
it('should return 0, cause distributions is equals', function(){
var q = [0.1,0.4,0.5,0.2];
assert.equal(math.kldivergence(q, q), 0);
assert.equal(math.kldivergence(math.matrix(q), q), 0);
assert.equal(math.kldivergence(q, math.matrix(q)), 0);
assert.equal(math.kldivergence(math.matrix(q), math.matrix(q)), 0);
});
it('should return distance between two distrubutions', function(){
var q = [0.5,0.6,0.7];
var p = [0.4,0.5,0.6];
assert.equal(math.kldivergence(q, p), 0.00038410187968898266);
var q2 = [0.9,0.2,0.8,0.4];
var p2 = [0.1,0.8,0.7,0.6];
assert.equal(math.kldivergence(q2, p2), 0.6707144627487189);
});
it('should return normalized distance between two distributions', function(){
var q = [1,2,3,4,5,6,7,8];
var p = [2,3,4,5,6,7,8,9];
assert.equal(math.kldivergence(q, p), 0.006970870019248255);
});
it('should return infinity', function(){
var q = [1,2];
var p = [0,1];
assert.equal(math.kldivergence(q, p), Infinity);
});
it('should return NaN', function(){
var q = [-1,2];
var p = [0.4,1];
assert.equal(isNaN(parseFloat(math.kldivergence(q, p))), true);
});
it('should return bignumber', function(){
var result = math.kldivergence([math.bignumber(4),math.bignumber(7)], [math.bignumber(1), math.bignumber(4)]);
assert.equal(result.toString(), '0.0717688178200499468328227075658945850681301640503275280115029999');
});
});

View File

@@ -0,0 +1,32 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
multinomial = math.multinomial,
_ = require('underscore');
describe('multinomial', function() {
it('should calculate the multinomial of an array of numbers', function() {
assert.equal(multinomial([1,2,1]), 12);
assert.equal(multinomial([4,2,1]), 105);
assert.equal(multinomial([4,4]), 70);
});
it('should calculate the multinomial of n items taken k at a time with BigNumbers', function() {
assert.equal(_.isEqual(multinomial([math.bignumber(3), math.bignumber(4), math.bignumber(5)]), math.bignumber(27720)),true);
assert.deepEqual(multinomial([math.bignumber(10), math.bignumber(1), math.bignumber(2)]), math.bignumber(858));
});
it('should not work with non-integer and negative input', function() {
assert.throws(function() {multinomial([0.5,3])}, TypeError);
assert.throws(function() {multinomial([math.bignumber(3), math.bignumber(0.5)])}, TypeError);
assert.throws(function() {multinomial([math.bignumber(3.5), math.bignumber(-3)])}, TypeError);
assert.throws(function() {multinomial([math.bignumber(3.5), 1/3])}, TypeError);
});
it('should not work with the wrong number or type of arguments', function() {
assert.throws(function() {multinomial(5, 3, 2)});
assert.throws(function() {multinomial(true, "hello world")});
});
});

View File

@@ -0,0 +1,65 @@
var assert = require('assert'),
error = require('../../../lib/error/index'),
math = require('../../../index'),
permutations = math.permutations;
describe('permutations', function() {
it('should calculate the permutations of a number', function() {
assert.equal(permutations(0), 1);
assert.equal(permutations(1), 1);
assert.equal(permutations(2), 2);
assert.equal(permutations(3), 6);
assert.equal(permutations(4), 24);
assert.equal(permutations(5), 120);
});
it('should calculate the permutations of a BigNumber', function() {
assert.deepEqual(permutations(math.bignumber(4)), math.bignumber(24));
assert.deepEqual(permutations(math.bignumber(5)), math.bignumber(120));
assert.deepEqual(permutations(math.bignumber(8)), math.bignumber(40320));
});
it('should calculate the permutations of a BigNumber, taking k at a time', function() {
assert.deepEqual(permutations(math.bignumber(5), math.bignumber(4)), math.bignumber(120));
assert.deepEqual(permutations(math.bignumber(6), math.bignumber(3)), math.bignumber(120));
assert.deepEqual(permutations(math.bignumber(9), math.bignumber(8)), math.bignumber(362880));
});
it('should calculate the permutations of a number, taking k at a time', function() {
assert.equal(permutations(5, 4), 120);
assert.equal(permutations(9, 8), 362880);
assert.equal(permutations(7, 5), 2520);
});
it('should fail loudly when k is larger than x', function() {
assert.throws(function(){permutations(5, 6);}, TypeError);
assert.throws(function(){permutations(math.bignumber(5), math.bignumber(6));}, TypeError);
});
it('should not accept negative or non-integer arguments', function() {
assert.throws(function(){permutations(12, -6);}, TypeError);
assert.throws(function(){permutations(-12, 6);}, TypeError);
assert.throws(function(){permutations(4.5, 2);}, TypeError);
assert.throws(function(){permutations(4, 0.5);}, TypeError);
assert.throws(function(){permutations(math.bignumber(-12), -6);}, TypeError);
assert.throws(function(){permutations(math.bignumber(12.5), math.bignumber(6));}, TypeError);
assert.throws(function(){permutations(math.bignumber(12.5), math.pi);}, TypeError);
});
it('should not accept more than two arguments', function() {
assert.throws(function(){permutations(12, 6, 13);});
assert.throws(function(){permutations(-12, 6, 13);});
});
it('should not accept arguments of the wrong type', function() {
assert.throws(function(){permutations("baa baa black sheep", true);});
assert.throws(function(){permutations(new Array(12));});
});
it('should LaTeX permutations', function () {
var expression = math.parse('permutations(2)');
assert.equal(expression.toTex(), '\\mathrm{permutations}\\left(2\\right)');
});
});

View File

@@ -0,0 +1,17 @@
var assert = require('assert'),
math = require('../../../index');
describe('pickRandom', function () {
// Note: pickRandom is a convenience function generated by distribution
// it is tested in distribution.test.js
it('should have a function pickRandom', function () {
assert.equal(typeof math.pickRandom, 'function');
})
it('should LaTeX pickRandom', function () {
var expression = math.parse('pickRandom([1,2,3])');
assert.equal(expression.toTex(), '\\mathrm{pickRandom}\\left(\\begin{bmatrix}1\\\\2\\\\3\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,16 @@
var assert = require('assert'),
math = require('../../../index');
describe('random', function () {
// Note: random is a convenience function generated by distribution
// it is tested in distribution.test.js
it('should have a function random', function () {
assert.equal(typeof math.random, 'function');
})
it('should LaTeX random', function () {
var expression = math.parse('random(0,1)');
assert.equal(expression.toTex(), '\\mathrm{random}\\left(0,1\\right)');
});
});

View File

@@ -0,0 +1,16 @@
var assert = require('assert'),
math = require('../../../index');
describe('randomInt', function () {
// Note: randomInt is a convenience function generated by distribution
// it is tested in distribution.test.js
it('should have a function randomInt', function () {
assert.equal(typeof math.randomInt, 'function');
})
it('should LaTeX randomInt', function () {
var expression = math.parse('randomInt(0,100)');
assert.equal(expression.toTex(), '\\mathrm{randomInt}\\left(0,100\\right)');
});
});

View File

@@ -0,0 +1,216 @@
// test compare
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
compare = math.compare;
describe('compare', function() {
it('should compare two numbers correctly', function() {
assert.equal(compare(2, 3), -1);
assert.equal(compare(2, 2), 0);
assert.equal(compare(2, 1), 1);
assert.equal(compare(0, 0), 0);
assert.equal(compare(-2, 2), -1);
assert.equal(compare(-2, -3), 1);
assert.equal(compare(-3, -2), -1);
});
it('should compare two floating point numbers correctly', function() {
// Infinity
assert.equal(compare(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), 0);
assert.equal(compare(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), 0);
assert.equal(compare(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), 1);
assert.equal(compare(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), -1);
assert.equal(compare(Number.POSITIVE_INFINITY, 2.0), 1);
assert.equal(compare(2.0, Number.POSITIVE_INFINITY), -1);
assert.equal(compare(Number.NEGATIVE_INFINITY, 2.0), -1);
assert.equal(compare(2.0, Number.NEGATIVE_INFINITY), 1);
// floating point numbers
assert.equal(compare(0.3 - 0.2, 0.1), 0);
});
it('should compare two booleans', function() {
assert.equal(compare(true, true), 0);
assert.equal(compare(true, false), 1);
assert.equal(compare(false, true), -1);
assert.equal(compare(false, false), 0);
});
it('should compare mixed numbers and booleans', function() {
assert.equal(compare(2, true), 1);
assert.equal(compare(0, true), -1);
assert.equal(compare(true, 2), -1);
assert.equal(compare(false, 2), -1);
});
it('should compare mixed numbers and null', function() {
assert.equal(compare(2, null), 1);
assert.equal(compare(0, null), 0);
assert.equal(compare(null, 2), -1);
});
it('should compare bignumbers', function() {
assert.deepEqual(compare(bignumber(2), bignumber(3)), bignumber(-1));
assert.deepEqual(compare(bignumber(2), bignumber(2)), bignumber(0));
assert.deepEqual(compare(bignumber(3), bignumber(2)), bignumber(1));
assert.deepEqual(compare(bignumber(0), bignumber(0)), bignumber(0));
assert.deepEqual(compare(bignumber(-2), bignumber(2)), bignumber(-1));
});
it('should compare mixed numbers and bignumbers', function() {
assert.deepEqual(compare(bignumber(2), 3), bignumber(-1));
assert.deepEqual(compare(2, bignumber(2)), bignumber(0));
});
it('should compare mixed booleans and bignumbers', function() {
assert.deepEqual(compare(bignumber(0.1), true), bignumber(-1));
assert.deepEqual(compare(bignumber(1), true), bignumber(0));
assert.deepEqual(compare(bignumber(1), false), bignumber(1));
assert.deepEqual(compare(false, bignumber(0)), bignumber(0));
assert.deepEqual(compare(true, bignumber(0)), bignumber(1));
});
it('should compare two fractions', function() {
var a = math.fraction(1,3);
var b = math.fraction(1,6);
assert(compare(a, b) instanceof math.type.Fraction);
assert.equal(a.toString(), '0.(3)');
assert.equal(b.toString(), '0.1(6)');
assert.equal(compare(math.fraction(3), math.fraction(2)).valueOf(), 1);
assert.equal(compare(math.fraction(2), math.fraction(3)).valueOf(), -1);
assert.equal(compare(math.fraction(3), math.fraction(3)).valueOf(), 0);
assert.strictEqual(compare(math.add(math.fraction(0.1), math.fraction(0.2)), math.fraction(0.3)).valueOf(), 0); // this would fail with numbers
});
it('should compare mixed fractions and numbers', function() {
assert.deepEqual(compare(1, math.fraction(1,3)), math.fraction(1));
assert.deepEqual(compare(math.fraction(1,3), 1), math.fraction(-1));
});
it('should add two measures of the same unit', function() {
assert.equal(compare(unit('100cm'), unit('10inch')), 1);
assert.equal(compare(unit('99cm'), unit('1m')), -1);
assert.equal(compare(unit('1m'), unit('1m')), bignumber(0));
assert.equal(compare(unit('101cm'), unit('1m')), 1);
});
it('should throw an error if comparing a unit with a number', function() {
assert.throws(function () {compare(unit('100cm'), 22);});
});
it('should throw an error for two measures of different units', function() {
assert.throws(function () {compare(math.unit(5, 'km'), math.unit(100, 'gram'));});
});
it('should throw an error if comparing a unit with a bignumber', function() {
assert.throws(function () {compare(unit('100cm'), bignumber(22));});
});
it('should perform lexical comparison for two strings', function() {
assert.equal(compare('0', 0), 0);
assert.equal(compare('abd', 'abc'), 1);
assert.equal(compare('abc', 'abc'), 0);
assert.equal(compare('abc', 'abd'), -1);
});
describe('Array', function () {
it('should compare array - scalar', function () {
assert.deepEqual(compare('B', ['A', 'B', 'C']), [1, 0, -1]);
assert.deepEqual(compare(['A', 'B', 'C'], 'B'), [-1, 0, 1]);
});
it('should compare array - array', function () {
assert.deepEqual(compare([[1, 2, 0], [-1, 0, 2]], [[3, -1, 0], [-2, 1, 0]]), [[-1, 1, 0], [1, -1, 1]]);
});
it('should compare array - dense matrix', function () {
assert.deepEqual(compare([[1, 2, 0], [-1, 0, 2]], matrix([[3, -1, 0], [-2, 1, 0]])), matrix([[-1, 1, 0], [1, -1, 1]]));
});
it('should compare array - sparse matrix', function () {
assert.deepEqual(compare([[1, 2, 0], [-1, 0, 2]], sparse([[3, -1, 0], [-2, 1, 0]])), matrix([[-1, 1, 0], [1, -1, 1]]));
});
});
describe('DenseMatrix', function () {
it('should compare dense matrix - scalar', function () {
assert.deepEqual(compare('B', matrix(['A', 'B', 'C'])), matrix([1, 0, -1]));
assert.deepEqual(compare(matrix(['A', 'B', 'C']), 'B'), matrix([-1, 0, 1]));
});
it('should compare dense matrix - array', function () {
assert.deepEqual(compare(matrix([[1, 2, 0], [-1, 0, 2]]), [[3, -1, 0], [-2, 1, 0]]), matrix([[-1, 1, 0], [1, -1, 1]]));
});
it('should compare dense matrix - dense matrix', function () {
assert.deepEqual(compare(matrix([[1, 2, 0], [-1, 0, 2]]), matrix([[3, -1, 0], [-2, 1, 0]])), matrix([[-1, 1, 0], [1, -1, 1]]));
});
it('should compare dense matrix - sparse matrix', function () {
assert.deepEqual(compare(matrix([[1, 2, 0], [-1, 0, 2]]), sparse([[3, -1, 0], [-2, 1, 0]])), matrix([[-1, 1, 0], [1, -1, 1]]));
});
});
describe('SparseMatrix', function () {
it('should compare sparse matrix - scalar', function () {
assert.deepEqual(compare('B', sparse([['A', 'B'], ['C', 'X']])), matrix([[1, 0], [-1, -1]]));
assert.deepEqual(compare(sparse([['A', 'B'], ['C', 'X']]), 'B'), matrix([[-1, 0], [1, 1]]));
});
it('should compare sparse matrix - array', function () {
assert.deepEqual(compare(sparse([[1, 2, 0], [-1, 0, 2]]), [[3, -1, 0], [-2, 1, 0]]), matrix([[-1, 1, 0], [1, -1, 1]]));
});
it('should compare sparse matrix - dense matrix', function () {
assert.deepEqual(compare(sparse([[1, 2, 0], [-1, 0, 2]]), matrix([[3, -1, 0], [-2, 1, 0]])), matrix([[-1, 1, 0], [1, -1, 1]]));
});
it('should compare sparse matrix - sparse matrix', function () {
assert.deepEqual(compare(sparse([[1, 2, 0], [-1, 0, 2]]), sparse([[3, -1, 0], [-2, 1, 0]])), sparse([[-1, 1, 0], [1, -1, 1]]));
});
});
it('should apply configuration option epsilon', function() {
var mymath = math.create();
assert.equal(mymath.compare(1, 0.991), 1);
assert.equal(mymath.compare(math.bignumber(1), math.bignumber(0.991)).valueOf(), 1);
mymath.config({epsilon: 1e-2});
assert.equal(mymath.compare(1, 0.991), 0);
assert.equal(mymath.compare(math.bignumber(1), math.bignumber(0.991)), 0);
});
it('should throw an error when comparing complex numbers', function() {
assert.throws(function () {compare(complex(1,1), complex(1,2));}, TypeError);
assert.throws(function () {compare(complex(2,1), 3);}, TypeError);
assert.throws(function () {compare(3, complex(2,4));}, TypeError);
assert.throws(function () {compare(math.bignumber(3), complex(2,4));}, TypeError);
assert.throws(function () {compare(complex(2,4), math.bignumber(3));}, TypeError);
});
it('should throw an error if matrices are different sizes', function() {
assert.throws(function () {compare([1,4,6], [3,4]);});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {compare(1);}, /TypeError: Too few arguments/);
assert.throws(function () {compare(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should LaTeX compare', function () {
var expression = math.parse('compare(1,2)');
assert.equal(expression.toTex(), '\\mathrm{compare}\\left(1,2\\right)');
});
});

View File

@@ -0,0 +1,60 @@
// test deepEqual
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
unit = math.unit,
deepEqual = math.deepEqual;
describe('deepEqual', function() {
it('should compare scalars correctly', function() {
assert.equal(deepEqual(2, 3), false);
assert.equal(deepEqual(2, 2), true);
assert.equal(deepEqual(0, 0), true);
assert.equal(deepEqual(-2, 2), false);
assert.equal(deepEqual(true, 1), true);
});
it('should compare two matrices', function() {
assert.deepEqual(deepEqual([1,4,5], [3,4,5]), false);
assert.deepEqual(deepEqual([1,4,5], [1,4,5]), true);
assert.deepEqual(deepEqual([1,4,5], [1,4]), false);
assert.deepEqual(deepEqual([1,4], [1,4,5]), false);
assert.deepEqual(deepEqual([1,4,5], matrix([3,4,5])), false);
assert.deepEqual(deepEqual([1,4,5], matrix([1,4,5])), true);
assert.deepEqual(deepEqual(matrix([1,4,5]), matrix([1,4,5])), true);
assert.deepEqual(deepEqual(matrix([[1,2], [3,4]]), matrix([[1,2], [3,4]])), true);
assert.deepEqual(deepEqual(matrix([[1,2], [3,4]]), matrix([[1,2], [3,5]])), false);
assert.deepEqual(deepEqual(matrix([[1,2], [3,4]]), matrix([[1,2], [3,4], [5,6]])), false);
assert.deepEqual(deepEqual(matrix([[1,2], [3,4], [5,6]]), matrix([[1,2], [3,4]])), false);
});
it('should compare mixed scalars and matrices', function() {
assert.deepEqual(deepEqual([1,2,3], 2), false);
assert.deepEqual(deepEqual(2, [1,2,3]), false);
assert.deepEqual(deepEqual(matrix([1,2,3]), 2), false);
assert.deepEqual(deepEqual(2, matrix([1,2,3])), false);
});
it('should compare two matrices with mixed types', function() {
assert.deepEqual(deepEqual([1,4,5], [true,4,5]), true);
assert.deepEqual(deepEqual([2,3], [2, bignumber(3)]), true);
assert.deepEqual(deepEqual([2,3], [2, bignumber(4)]), false);
assert.deepEqual(deepEqual([complex(2,3),3], [complex(2,3),3]), true);
assert.deepEqual(deepEqual([complex(2,3),3], [complex(2,4),3]), false);
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {deepEqual(1)}, /TypeError: Too few arguments/);
assert.throws(function () {deepEqual(1, 2, 3)}, /TypeError: Too many arguments/);
});
it('should LaTeX deepEqual', function () {
var expression = math.parse('deepEqual([1,2],[1,3])');
assert.equal(expression.toTex(), '\\mathrm{deepEqual}\\left(\\begin{bmatrix}1\\\\2\\\\\\end{bmatrix},\\begin{bmatrix}1\\\\3\\\\\\end{bmatrix}\\right)');
});
});

View File

@@ -0,0 +1,241 @@
// test equal
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
equal = math.equal;
describe('equal', function() {
it('should compare two numbers correctly', function() {
assert.equal(equal(2, 3), false);
assert.equal(equal(2, 2), true);
assert.equal(equal(0, 0), true);
assert.equal(equal(-2, 2), false);
});
it('should compare two floating point numbers correctly', function() {
// NaN
assert.equal(equal(Number.NaN, Number.NaN), false);
// Infinity
assert.equal(equal(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), true);
assert.equal(equal(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), true);
assert.equal(equal(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), false);
assert.equal(equal(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), false);
assert.equal(equal(Number.POSITIVE_INFINITY, 2.0), false);
assert.equal(equal(2.0, Number.POSITIVE_INFINITY), false);
assert.equal(equal(Number.NEGATIVE_INFINITY, 2.0), false);
assert.equal(equal(2.0, Number.NEGATIVE_INFINITY), false);
assert.equal(equal(Number.NaN, Number.POSITIVE_INFINITY), false);
assert.equal(equal(Number.POSITIVE_INFINITY, Number.NaN), false);
assert.equal(equal(Number.NaN, Number.NEGATIVE_INFINITY), false);
assert.equal(equal(Number.NEGATIVE_INFINITY, Number.NaN), false);
// floating point numbers
assert.equal(equal(0.3 - 0.2, 0.1), true);
});
it('should compare two booleans', function() {
assert.equal(equal(true, true), true);
assert.equal(equal(true, false), false);
assert.equal(equal(false, true), false);
assert.equal(equal(false, false), true);
});
it('should compare mixed numbers and booleans', function() {
assert.equal(equal(2, true), false);
assert.equal(equal(1, true), true);
assert.equal(equal(0, true), false);
assert.equal(equal(true, 2), false);
assert.equal(equal(true, 1), true);
assert.equal(equal(false, 2), false);
assert.equal(equal(false, 0), true);
});
it('should compare bignumbers', function() {
assert.equal(equal(bignumber(2), bignumber(3)), false);
assert.equal(equal(bignumber(2), bignumber(2)), true);
assert.equal(equal(bignumber(3), bignumber(2)), false);
assert.equal(equal(bignumber(0), bignumber(0)), true);
assert.equal(equal(bignumber(-2), bignumber(2)), false);
});
it('should compare mixed numbers and bignumbers', function() {
assert.deepEqual(equal(bignumber(2), 3), false);
assert.deepEqual(equal(2, bignumber(2)), true);
assert.throws(function () {equal(1/3, bignumber(1).div(3));}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {equal(bignumber(1).div(3), 1/3);}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should compare mixed booleans and bignumbers', function() {
assert.equal(equal(bignumber(0.1), true), false);
assert.equal(equal(bignumber(1), true), true);
assert.equal(equal(bignumber(1), false), false);
assert.equal(equal(false, bignumber(0)), true);
assert.equal(equal(true, bignumber(0)), false);
});
it('should compare two complex numbers correctly', function() {
assert.equal(equal(complex(2,3), complex(2,4)), false);
assert.equal(equal(complex(2,3), complex(2,3)), true);
assert.equal(equal(complex(1,3), complex(2,3)), false);
assert.equal(equal(complex(1,3), complex(2,4)), false);
assert.equal(equal(complex(2,0), 2), true);
assert.equal(equal(complex(2,1), 2), false);
assert.equal(equal(2, complex(2, 0)), true);
assert.equal(equal(2, complex(2, 1)), false);
assert.equal(equal(complex(2,0), 3), false);
});
it('should compare mixed complex numbers and bignumbers (downgrades to numbers)', function() {
assert.deepEqual(equal(math.complex(6, 0), bignumber(6)), true);
assert.deepEqual(equal(math.complex(6, -2), bignumber(6)), false);
assert.deepEqual(equal(bignumber(6), math.complex(6, 0)), true);
assert.deepEqual(equal(bignumber(6), math.complex(6, 4)), false);
});
it('should compare two fractions', function() {
var a = math.fraction(3);
assert.strictEqual(equal(a, math.fraction(2)).valueOf(), false);
assert.equal(a.toString(), '3');
assert.strictEqual(equal(math.fraction(2), math.fraction(3)).valueOf(), false);
assert.strictEqual(equal(math.fraction(3), math.fraction(3)).valueOf(), true);
assert.strictEqual(equal(math.add(math.fraction(0.1), math.fraction(0.2)), math.fraction(0.3)).valueOf(), true); // this would fail with numbers
});
it('should compare mixed fractions and numbers', function() {
assert.strictEqual(equal(1, math.fraction(1,3)), false);
assert.strictEqual(equal(math.fraction(2), 2), true);
});
it('should compare two units correctly', function() {
assert.equal(equal(unit('100cm'), unit('10inch')), false);
assert.equal(equal(unit('100cm'), unit('1m')), true);
assert.equal(equal(unit('12inch'), unit('1foot')), true); // round-off error should be no issue
assert.equal(equal(unit('2.54cm'), unit('1inch')), true); // round-off error should be no issue
});
it('should compare null', function() {
assert.equal(equal(null, null), true);
assert.equal(equal(null, undefined), false);
assert.equal(equal(undefined, null), false);
assert.equal(equal(0, null), false);
assert.equal(equal(null, 0), false);
assert.equal(equal('null', null), false);
});
it('should compare undefined', function() {
assert.equal(equal(undefined, undefined), true);
assert.equal(equal(undefined, 'undefined'), false);
assert.equal(equal(undefined, null), false);
assert.equal(equal(undefined, 0), false);
assert.equal(equal(2, undefined), false);
});
it('should apply configuration option epsilon', function() {
var mymath = math.create();
assert.equal(mymath.equal(1, 0.991), false);
assert.equal(mymath.equal(math.bignumber(1), math.bignumber(0.991)), false);
mymath.config({epsilon: 1e-2});
assert.equal(mymath.equal(1, 0.991), true);
assert.equal(mymath.equal(math.bignumber(1), math.bignumber(0.991)), true);
});
it('should throw an error when comparing a unit with a big number', function() {
assert.throws( function () {equal(math.unit('5 m'), bignumber(10)).toString(); });
});
it('should throw an error when comparing a unit with a number', function() {
assert.throws(function () {equal(unit('100cm'), 22);});
});
it('should throw an error for two measures of different units', function() {
assert.throws(function () {equal(math.unit(5, 'km'), math.unit(100, 'gram'));});
});
it('should compare two strings correctly', function() {
assert.equal(equal('0', 0), true);
assert.equal(equal('Hello', 'hello'), false);
assert.equal(equal('hello', 'hello'), true);
});
describe('Array', function () {
it('should compare array - scalar', function () {
assert.deepEqual(equal('B', ['A', 'B', 'C']), [false, true, false]);
assert.deepEqual(equal(['A', 'B', 'C'], 'B'), [false, true, false]);
});
it('should compare array - array', function () {
assert.deepEqual(equal([[1, 2, 0], [-1, 0, 2]], [[1, -1, 0], [-1, 1, 0]]), [[true, false, true], [true, false, false]]);
});
it('should compare array - dense matrix', function () {
assert.deepEqual(equal([[1, 2, 0], [-1, 0, 2]], matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, false, false]]));
});
it('should compare array - sparse matrix', function () {
assert.deepEqual(equal([[1, 2, 0], [-1, 0, 2]], sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, false, false]]));
});
it('should throw an error if arrays have different sizes', function() {
assert.throws(function () {equal([1,4,5], [3,4]);});
});
});
describe('DenseMatrix', function () {
it('should compare dense matrix - scalar', function () {
assert.deepEqual(equal('B', matrix(['A', 'B', 'C'])), matrix([false, true, false]));
assert.deepEqual(equal(matrix(['A', 'B', 'C']), 'B'), matrix([false, true, false]));
});
it('should compare dense matrix - array', function () {
assert.deepEqual(equal(matrix([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[true, false, true], [true, false, false]]));
});
it('should compare dense matrix - dense matrix', function () {
assert.deepEqual(equal(matrix([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, false, false]]));
});
it('should compare dense matrix - sparse matrix', function () {
assert.deepEqual(equal(matrix([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, false, false]]));
});
});
describe('SparseMatrix', function () {
it('should compare sparse matrix - scalar', function () {
assert.deepEqual(equal('B', sparse([['A', 'B'], ['C', 'D']])), matrix([[false, true], [false, false]]));
assert.deepEqual(equal(sparse([['A', 'B'], ['C', 'D']]), 'B'), matrix([[false, true], [false, false]]));
});
it('should compare sparse matrix - array', function () {
assert.deepEqual(equal(sparse([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[true, false, true], [true, false, false]]));
});
it('should compare sparse matrix - dense matrix', function () {
assert.deepEqual(equal(sparse([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, false, false]]));
});
it('should compare sparse matrix - sparse matrix', function () {
assert.deepEqual(equal(sparse([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, false, false]]));
});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {equal(1);}, /Too few arguments/);
assert.throws(function () {equal(1, 2, 3);}, /Too many arguments/);
});
it('should LaTeX equal', function () {
var expression = math.parse('equal(1,2)');
assert.equal(expression.toTex(), '\\left(1=2\\right)');
});
});

View File

@@ -0,0 +1,215 @@
// test larger
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
larger = math.larger;
describe('larger', function() {
it('should compare two numbers correctly', function() {
assert.equal(larger(2, 3), false);
assert.equal(larger(2, 2), false);
assert.equal(larger(2, 1), true);
assert.equal(larger(0, 0), false);
assert.equal(larger(-2, 2), false);
assert.equal(larger(-2, -3), true);
assert.equal(larger(-3, -2), false);
});
it('should compare two floating point numbers correctly', function() {
// Infinity
assert.equal(larger(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), false);
assert.equal(larger(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), false);
assert.equal(larger(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), true);
assert.equal(larger(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), false);
assert.equal(larger(Number.POSITIVE_INFINITY, 2.0), true);
assert.equal(larger(2.0, Number.POSITIVE_INFINITY), false);
assert.equal(larger(Number.NEGATIVE_INFINITY, 2.0), false);
assert.equal(larger(2.0, Number.NEGATIVE_INFINITY), true);
// floating point numbers
assert.equal(larger(0.3 - 0.2, 0.1), false);
});
it('should compare two booleans', function() {
assert.equal(larger(true, true), false);
assert.equal(larger(true, false), true);
assert.equal(larger(false, true), false);
assert.equal(larger(false, false), false);
});
it('should compare mixed numbers and booleans', function() {
assert.equal(larger(2, true), true);
assert.equal(larger(0, true), false);
assert.equal(larger(true, 2), false);
assert.equal(larger(false, 2), false);
});
it('should compare mixed numbers and null', function() {
assert.equal(larger(1, null), true);
assert.equal(larger(0, null), false);
assert.equal(larger(null, 1), false);
assert.equal(larger(null, 0), false);
});
it('should compare bignumbers', function() {
assert.equal(larger(bignumber(2), bignumber(3)), false);
assert.equal(larger(bignumber(2), bignumber(2)), false);
assert.equal(larger(bignumber(3), bignumber(2)), true);
assert.equal(larger(bignumber(0), bignumber(0)), false);
assert.equal(larger(bignumber(-2), bignumber(2)), false);
});
it('should compare mixed numbers and bignumbers', function() {
assert.equal(larger(bignumber(2), 3), false);
assert.equal(larger(2, bignumber(2)), false);
assert.throws(function () {larger(1/3, bignumber(1).div(3));}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {larger(bignumber(1).div(3), 1/3);}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should compare mixed booleans and bignumbers', function() {
assert.equal(larger(bignumber(0.1), true), false);
assert.equal(larger(bignumber(1), true), false);
assert.equal(larger(bignumber(1), false), true);
assert.equal(larger(false, bignumber(0)), false);
assert.equal(larger(true, bignumber(0)), true);
});
it('should compare two fractions', function() {
assert.strictEqual(larger(math.fraction(3), math.fraction(2)).valueOf(), true);
assert.strictEqual(larger(math.fraction(2), math.fraction(3)).valueOf(), false);
assert.strictEqual(larger(math.fraction(3), math.fraction(3)).valueOf(), false);
});
it('should compare mixed fractions and numbers', function() {
assert.strictEqual(larger(1, math.fraction(1,3)), true);
assert.strictEqual(larger(math.fraction(2), 2), false);
});
it('should add two measures of the same unit', function() {
assert.equal(larger(unit('100cm'), unit('10inch')), true);
assert.equal(larger(unit('99cm'), unit('1m')), false);
//assert.equal(larger(unit('100cm'), unit('1m')), false); // dangerous, round-off errors
assert.equal(larger(unit('101cm'), unit('1m')), true);
});
it('should apply configuration option epsilon', function() {
var mymath = math.create();
assert.equal(mymath.larger(1, 0.991), true);
assert.equal(mymath.larger(math.bignumber(1), math.bignumber(0.991)), true);
mymath.config({epsilon: 1e-2});
assert.equal(mymath.larger(1, 0.991), false);
assert.equal(mymath.larger(math.bignumber(1), math.bignumber(0.991)), false);
});
it('should throw an error if comparing a unit with a number', function() {
assert.throws(function () {larger(unit('100cm'), 22);});
});
it('should throw an error for two measures of different units', function() {
assert.throws(function () {larger(math.unit(5, 'km'), math.unit(100, 'gram'));});
});
it('should throw an error if comparing a unit with a bignumber', function() {
assert.throws(function () {larger(unit('100cm'), bignumber(22));});
});
it('should perform lexical comparison for two strings', function() {
assert.equal(larger('0', 0), false);
assert.equal(larger('abd', 'abc'), true);
assert.equal(larger('abc', 'abc'), false);
assert.equal(larger('abc', 'abd'), false);
});
describe('Array', function () {
it('should compare array - scalar', function () {
assert.deepEqual(larger('B', ['A', 'B', 'C']), [true, false, false]);
assert.deepEqual(larger(['A', 'B', 'C'], 'B'), [false, false, true]);
});
it('should compare array - array', function () {
assert.deepEqual(larger([[1, 2, 0], [-1, 0, 2]], [[1, -1, 0], [-1, 1, 0]]), [[false, true, false], [false, false, true]]);
});
it('should compare array - dense matrix', function () {
assert.deepEqual(larger([[1, 2, 0], [-1, 0, 2]], matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[false, true, false], [false, false, true]]));
});
it('should compare array - sparse matrix', function () {
assert.deepEqual(larger([[1, 2, 0], [-1, 0, 2]], sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[false, true, false], [false, false, true]]));
});
it('should throw an error if arrays have different sizes', function() {
assert.throws(function () {larger([1,4,5], [3,4]);});
});
});
describe('DenseMatrix', function () {
it('should compare dense matrix - scalar', function () {
assert.deepEqual(larger('B', matrix(['A', 'B', 'C'])), matrix([true, false, false]));
assert.deepEqual(larger(matrix(['A', 'B', 'C']), 'B'), matrix([false, false, true]));
});
it('should compare dense matrix - array', function () {
assert.deepEqual(larger(matrix([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[false, true, false], [false, false, true]]));
});
it('should compare dense matrix - dense matrix', function () {
assert.deepEqual(larger(matrix([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[false, true, false], [false, false, true]]));
});
it('should compare dense matrix - sparse matrix', function () {
assert.deepEqual(larger(matrix([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[false, true, false], [false, false, true]]));
});
});
describe('SparseMatrix', function () {
it('should compare sparse matrix - scalar', function () {
assert.deepEqual(larger('B', sparse([['A', 'B'], ['C', 'D']])), matrix([[true, false], [false, false]]));
assert.deepEqual(larger(sparse([['A', 'B'], ['C', 'D']]), 'B'), matrix([[false, false], [true, true]]));
});
it('should compare sparse matrix - array', function () {
assert.deepEqual(larger(sparse([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[false, true, false], [false, false, true]]));
});
it('should compare sparse matrix - dense matrix', function () {
assert.deepEqual(larger(sparse([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[false, true, false], [false, false, true]]));
});
it('should compare sparse matrix - sparse matrix', function () {
assert.deepEqual(larger(sparse([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[false, true, false], [false, false, true]]));
});
});
it('should throw an error when comparing complex numbers', function() {
assert.throws(function () {larger(complex(1,1), complex(1,2));}, TypeError);
assert.throws(function () {larger(complex(2,1), 3);}, TypeError);
assert.throws(function () {larger(3, complex(2,4));}, TypeError);
assert.throws(function () {larger(math.bignumber(3), complex(2,4));}, TypeError);
assert.throws(function () {larger(complex(2,4), math.bignumber(3));}, TypeError);
});
it('should throw an error if matrices are different sizes', function() {
assert.throws(function () {larger([1,4,6], [3,4]);});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {larger(1);}, /Too few arguments/);
assert.throws(function () {larger(1, 2, 3);}, /Too many arguments/);
});
it('should LaTeX larger', function () {
var expression = math.parse('larger(1,2)');
assert.equal(expression.toTex(), '\\left(1>2\\right)');
});
});

View File

@@ -0,0 +1,217 @@
// test largerEq
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
largerEq = math.largerEq;
describe('largerEq', function() {
it('should compare two numbers correctly', function() {
assert.equal(largerEq(2, 3), false);
assert.equal(largerEq(2, 2), true);
assert.equal(largerEq(2, 1), true);
assert.equal(largerEq(0, 0), true);
assert.equal(largerEq(-2, 2), false);
assert.equal(largerEq(-2, -3), true);
assert.equal(largerEq(-3, -2), false);
});
it('should compare two floating point numbers correctly', function() {
// Infinity
assert.equal(largerEq(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), true);
assert.equal(largerEq(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), true);
assert.equal(largerEq(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), true);
assert.equal(largerEq(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), false);
assert.equal(largerEq(Number.POSITIVE_INFINITY, 2.0), true);
assert.equal(largerEq(2.0, Number.POSITIVE_INFINITY), false);
assert.equal(largerEq(Number.NEGATIVE_INFINITY, 2.0), false);
assert.equal(largerEq(2.0, Number.NEGATIVE_INFINITY), true);
// floating point numbers
assert.equal(largerEq(0.3 - 0.2, 0.1), true);
});
it('should compare two booleans', function() {
assert.equal(largerEq(true, true), true);
assert.equal(largerEq(true, false), true);
assert.equal(largerEq(false, true), false);
assert.equal(largerEq(false, false), true);
});
it('should compare mixed numbers and booleans', function() {
assert.equal(largerEq(2, true), true);
assert.equal(largerEq(0, true), false);
assert.equal(largerEq(true, 2), false);
assert.equal(largerEq(true, 1), true);
assert.equal(largerEq(false, 0), true);
});
it('should compare mixed numbers and null', function() {
assert.equal(largerEq(1, null), true);
assert.equal(largerEq(0, null), true);
assert.equal(largerEq(null, 1), false);
assert.equal(largerEq(null, 0), true);
});
it('should compare bignumbers', function() {
assert.equal(largerEq(bignumber(2), bignumber(3)), false);
assert.equal(largerEq(bignumber(2), bignumber(2)), true);
assert.equal(largerEq(bignumber(3), bignumber(2)), true);
assert.equal(largerEq(bignumber(0), bignumber(0)), true);
assert.equal(largerEq(bignumber(-2), bignumber(2)), false);
});
it('should compare mixed numbers and bignumbers', function() {
assert.equal(largerEq(bignumber(2), 3), false);
assert.equal(largerEq(2, bignumber(2)), true);
assert.throws(function () {largerEq(1/3, bignumber(1).div(3));}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {largerEq(bignumber(1).div(3), 1/3);}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should compare mixed booleans and bignumbers', function() {
assert.equal(largerEq(bignumber(0.1), true), false);
assert.equal(largerEq(bignumber(1), true), true);
assert.equal(largerEq(bignumber(1), false), true);
assert.equal(largerEq(false, bignumber(0)), true);
assert.equal(largerEq(true, bignumber(0)), true);
assert.equal(largerEq(true, bignumber(1)), true);
});
it('should compare two fractions', function() {
assert.strictEqual(largerEq(math.fraction(3), math.fraction(2)).valueOf(), true);
assert.strictEqual(largerEq(math.fraction(2), math.fraction(3)).valueOf(), false);
assert.strictEqual(largerEq(math.fraction(3), math.fraction(3)).valueOf(), true);
});
it('should compare mixed fractions and numbers', function() {
assert.strictEqual(largerEq(1, math.fraction(1,3)), true);
assert.strictEqual(largerEq(math.fraction(2), 2), true);
});
it('should compare two units correctly', function() {
assert.equal(largerEq(unit('100cm'), unit('10inch')), true);
assert.equal(largerEq(unit('99cm'), unit('1m')), false);
//assert.equal(largerEq(unit('100cm'), unit('1m')), true); // dangerous, round-off errors
assert.equal(largerEq(unit('101cm'), unit('1m')), true);
});
it('should apply configuration option epsilon', function() {
var mymath = math.create();
assert.equal(mymath.largerEq(1, 1.01), false);
assert.equal(mymath.largerEq(math.bignumber(1), math.bignumber(1.01)), false);
mymath.config({epsilon: 1e-2});
assert.equal(mymath.largerEq(1, 1.01), true);
assert.equal(mymath.largerEq(math.bignumber(1), math.bignumber(1.01)), true);
});
it('should throw an error if comparing a unit with a number', function() {
assert.throws(function () {largerEq(unit('100cm'), 22);});
});
it('should throw an error for two measures of different units', function() {
assert.throws(function () {largerEq(math.unit(5, 'km'), math.unit(100, 'gram')); });
});
it('should throw an error if comparing a unit with a bignumber', function() {
assert.throws(function () {largerEq(unit('100cm'), bignumber(22));});
});
it('should perform lexical comparison for 2 strings', function() {
assert.equal(largerEq('0', 0), true);
assert.equal(largerEq('abd', 'abc'), true);
assert.equal(largerEq('abc', 'abc'), true);
assert.equal(largerEq('abc', 'abd'), false);
});
describe('Array', function () {
it('should compare array - scalar', function () {
assert.deepEqual(largerEq('B', ['A', 'B', 'C']), [true, true, false]);
assert.deepEqual(largerEq(['A', 'B', 'C'], 'B'), [false, true, true]);
});
it('should compare array - array', function () {
assert.deepEqual(largerEq([[1, 2, 0], [-1, 0, 2]], [[1, -1, 0], [-1, 1, 0]]), [[true, true, true], [true, false, true]]);
});
it('should compare array - dense matrix', function () {
assert.deepEqual(largerEq([[1, 2, 0], [-1, 0, 2]], matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, true, true], [true, false, true]]));
});
it('should compare array - sparse matrix', function () {
assert.deepEqual(largerEq([[1, 2, 0], [-1, 0, 2]], sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, true, true], [true, false, true]]));
});
it('should throw an error if arrays have different sizes', function() {
assert.throws(function () {largerEq([1,4,5], [3,4]);});
});
});
describe('DenseMatrix', function () {
it('should compare dense matrix - scalar', function () {
assert.deepEqual(largerEq('B', matrix(['A', 'B', 'C'])), matrix([true, true, false]));
assert.deepEqual(largerEq(matrix(['A', 'B', 'C']), 'B'), matrix([false, true, true]));
});
it('should compare dense matrix - array', function () {
assert.deepEqual(largerEq(matrix([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[true, true, true], [true, false, true]]));
});
it('should compare dense matrix - dense matrix', function () {
assert.deepEqual(largerEq(matrix([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, true, true], [true, false, true]]));
});
it('should compare dense matrix - sparse matrix', function () {
assert.deepEqual(largerEq(matrix([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, true, true], [true, false, true]]));
});
});
describe('SparseMatrix', function () {
it('should compare sparse matrix - scalar', function () {
assert.deepEqual(largerEq('B', sparse([['A', 'B'], ['C', 'D']])), matrix([[true, true], [false, false]]));
assert.deepEqual(largerEq(sparse([['A', 'B'], ['C', 'D']]), 'B'), matrix([[false, true], [true, true]]));
});
it('should compare sparse matrix - array', function () {
assert.deepEqual(largerEq(sparse([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[true, true, true], [true, false, true]]));
});
it('should compare sparse matrix - dense matrix', function () {
assert.deepEqual(largerEq(sparse([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, true, true], [true, false, true]]));
});
it('should compare sparse matrix - sparse matrix', function () {
assert.deepEqual(largerEq(sparse([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, true, true], [true, false, true]]));
});
});
it('should throw an error when comparing complex numbers', function() {
assert.throws(function () {largerEq(complex(1,1), complex(1,2));}, TypeError);
assert.throws(function () {largerEq(complex(2,1), 3);}, TypeError);
assert.throws(function () {largerEq(3, complex(2,4));}, TypeError);
assert.throws(function () {largerEq(math.bignumber(3), complex(2,4));}, TypeError);
assert.throws(function () {largerEq(complex(2,4), math.bignumber(3));}, TypeError);
});
it('should throw an error if comparing two matrices of different sizes', function() {
assert.throws(function () {largerEq([1,4,6], [3,4]);});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {largerEq(1);}, /TypeError: Too few arguments/);
assert.throws(function () {largerEq(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should LaTeX largerEq', function () {
var expression = math.parse('largerEq(1,2)');
assert.equal(expression.toTex(), '\\left(1\\geq2\\right)');
});
});

View File

@@ -0,0 +1,222 @@
// test smaller
var assert = require('assert'),
math = require('../../../index'),
bignumber = math.bignumber,
complex = math.complex,
matrix = math.matrix,
sparse = math.sparse,
unit = math.unit,
smaller = math.smaller;
describe('smaller', function() {
it('should compare two numbers correctly', function() {
assert.equal(smaller(2, 3), true);
assert.equal(smaller(2, 2), false);
assert.equal(smaller(2, 1), false);
assert.equal(smaller(0, 0), false);
assert.equal(smaller(-2, 2), true);
assert.equal(smaller(-2, -3), false);
assert.equal(smaller(-3, -2), true);
});
it('should compare two floating point numbers correctly', function() {
// Infinity
assert.equal(smaller(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), false);
assert.equal(smaller(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), false);
assert.equal(smaller(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), false);
assert.equal(smaller(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), true);
assert.equal(smaller(Number.POSITIVE_INFINITY, 2.0), false);
assert.equal(smaller(2.0, Number.POSITIVE_INFINITY), true);
assert.equal(smaller(Number.NEGATIVE_INFINITY, 2.0), true);
assert.equal(smaller(2.0, Number.NEGATIVE_INFINITY), false);
// floating point numbers
assert.equal(smaller(0.3 - 0.2, 0.1), false);
});
it('should compare two booleans', function() {
assert.equal(smaller(true, true), false);
assert.equal(smaller(true, false), false);
assert.equal(smaller(false, true), true);
assert.equal(smaller(false, false), false);
});
it('should compare mixed numbers and booleans', function() {
assert.equal(smaller(2, true), false);
assert.equal(smaller(1, true), false);
assert.equal(smaller(0, true), true);
assert.equal(smaller(true, 2), true);
assert.equal(smaller(true, 1), false);
assert.equal(smaller(false, 2), true);
});
it('should compare mixed numbers and null', function() {
assert.equal(smaller(1, null), false);
assert.equal(smaller(0, null), false);
assert.equal(smaller(null, 1), true);
assert.equal(smaller(null, 0), false);
});
it('should compare bignumbers', function() {
assert.deepEqual(smaller(bignumber(2), bignumber(3)), true);
assert.deepEqual(smaller(bignumber(2), bignumber(2)), false);
assert.deepEqual(smaller(bignumber(3), bignumber(2)), false);
assert.deepEqual(smaller(bignumber(0), bignumber(0)), false);
assert.deepEqual(smaller(bignumber(-2), bignumber(2)), true);
});
it('should compare mixed numbers and bignumbers', function() {
assert.deepEqual(smaller(bignumber(2), 3), true);
assert.deepEqual(smaller(2, bignumber(2)), false);
//assert.equal(smaller(1/3, bignumber(1).div(3)), false);
//assert.equal(smaller(bignumber(1).div(3), 1/3), false);
assert.throws(function () {smaller(1/3, bignumber(1).div(3));}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
assert.throws(function () {smaller(bignumber(1).div(3), 1/3);}, /Cannot implicitly convert a number with >15 significant digits to BigNumber/);
});
it('should compare mixed booleans and bignumbers', function() {
assert.deepEqual(smaller(bignumber(0.1), true), true);
assert.deepEqual(smaller(bignumber(1), true), false);
assert.deepEqual(smaller(bignumber(1), false), false);
assert.deepEqual(smaller(bignumber(0), false), false);
assert.deepEqual(smaller(false, bignumber(0)), false);
assert.deepEqual(smaller(true, bignumber(0)), false);
assert.deepEqual(smaller(true, bignumber(1)), false);
});
it('should compare two fractions', function() {
assert.strictEqual(smaller(math.fraction(3), math.fraction(2)).valueOf(), false);
assert.strictEqual(smaller(math.fraction(2), math.fraction(3)).valueOf(), true);
assert.strictEqual(smaller(math.fraction(3), math.fraction(3)).valueOf(), false);
});
it('should compare mixed fractions and numbers', function() {
assert.strictEqual(smaller(1, math.fraction(1,3)), false);
assert.strictEqual(smaller(math.fraction(2), 2), false);
});
it('should compare two measures of the same unit correctly', function() {
assert.equal(smaller(unit('100cm'), unit('10inch')), false);
assert.equal(smaller(unit('99cm'), unit('1m')), true);
//assert.equal(smaller(unit('100cm'), unit('1m')), false); // dangerous, round-off errors
assert.equal(smaller(unit('101cm'), unit('1m')), false);
});
it('should apply configuration option epsilon', function() {
var mymath = math.create();
assert.equal(mymath.smaller(0.991, 1), true);
assert.equal(mymath.smaller(math.bignumber(0.991), math.bignumber(1)), true);
mymath.config({epsilon: 1e-2});
assert.equal(mymath.smaller(0.991, 1), false);
assert.equal(mymath.smaller(math.bignumber(0.991), math.bignumber(1)), false);
});
it('should throw an error if comparing a unit and a number', function() {
assert.throws(function () {smaller(unit('100cm'), 22);});
});
it('should throw an error for two measures of different units', function() {
assert.throws(function () {smaller(math.unit(5, 'km'), math.unit(100, 'gram'));});
});
it('should throw an error if comparing a unit and a bignumber', function() {
assert.throws(function () {smaller(unit('100cm'), bignumber(22));});
});
it('should perform lexical comparison on two strings', function() {
assert.equal(smaller('0', 0), false);
assert.equal(smaller('abd', 'abc'), false);
assert.equal(smaller('abc', 'abc'), false);
assert.equal(smaller('abc', 'abd'), true);
});
describe('Array', function () {
it('should compare array - scalar', function () {
assert.deepEqual(smaller('B', ['A', 'B', 'C']), [false, false, true]);
assert.deepEqual(smaller(['A', 'B', 'C'], 'B'), [true, false, false]);
});
it('should compare array - array', function () {
assert.deepEqual(smaller([[1, 2, 0], [-1, 0, 2]], [[1, -1, 0], [-1, 1, 0]]), [[false, false, false], [false, true, false]]);
});
it('should compare array - dense matrix', function () {
assert.deepEqual(smaller([[1, 2, 0], [-1, 0, 2]], matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[false, false, false], [false, true, false]]));
});
it('should compare array - sparse matrix', function () {
assert.deepEqual(smaller([[1, 2, 0], [-1, 0, 2]], sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[false, false, false], [false, true, false]]));
});
it('should throw an error if arrays have different sizes', function() {
assert.throws(function () {smaller([1,4,5], [3,4]);});
});
});
describe('DenseMatrix', function () {
it('should compare dense matrix - scalar', function () {
assert.deepEqual(smaller('B', matrix(['A', 'B', 'C'])), matrix([false, false, true]));
assert.deepEqual(smaller(matrix(['A', 'B', 'C']), 'B'), matrix([true, false, false]));
});
it('should compare dense matrix - array', function () {
assert.deepEqual(smaller(matrix([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[false, false, false], [false, true, false]]));
});
it('should compare dense matrix - dense matrix', function () {
assert.deepEqual(smaller(matrix([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[false, false, false], [false, true, false]]));
});
it('should compare dense matrix - sparse matrix', function () {
assert.deepEqual(smaller(matrix([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[false, false, false], [false, true, false]]));
});
});
describe('SparseMatrix', function () {
it('should compare sparse matrix - scalar', function () {
assert.deepEqual(smaller('B', sparse([['A', 'B'], ['C', 'D']])), matrix([[false, false], [true, true]]));
assert.deepEqual(smaller(sparse([['A', 'B'], ['C', 'D']]), 'B'), matrix([[true, false], [false, false]]));
});
it('should compare sparse matrix - array', function () {
assert.deepEqual(smaller(sparse([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[false, false, false], [false, true, false]]));
});
it('should compare sparse matrix - dense matrix', function () {
assert.deepEqual(smaller(sparse([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[false, false, false], [false, true, false]]));
});
it('should compare sparse matrix - sparse matrix', function () {
assert.deepEqual(smaller(sparse([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[false, false, false], [false, true, false]]));
});
});
it('should throw an error when comparing complex numbers', function() {
assert.throws(function () {smaller(complex(1,1), complex(1,2));}, TypeError);
assert.throws(function () {smaller(complex(2,1), 3);}, TypeError);
assert.throws(function () {smaller(3, complex(2,4));}, TypeError);
assert.throws(function () {smaller(math.bignumber(3), complex(2,4));}, TypeError);
assert.throws(function () {smaller(complex(2,4), math.bignumber(3));}, TypeError);
});
it('should throw an error with two matrices of different sizes', function () {
assert.throws(function () {smaller([1,4,6], [3,4]);});
});
it('should throw an error in case of invalid number of arguments', function() {
assert.throws(function () {smaller(1);}, /TypeError: Too few arguments/);
assert.throws(function () {smaller(1, 2, 3);}, /TypeError: Too many arguments/);
});
it('should LaTeX smaller', function () {
var expression = math.parse('smaller(1,2)');
assert.equal(expression.toTex(), '\\left(1<2\\right)');
});
});

Some files were not shown because too many files have changed in this diff Show More