UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.

1,245 lines (1,026 loc) 33.6 kB
var assert = require('assert'); var math = require('../../../index'); var Matrix = math.type.Matrix; var DenseMatrix = math.type.DenseMatrix; var CcsMatrix = math.type.CcsMatrix; var Complex = math.type.Complex; var index = math.index; describe('DenseMatrix', function() { describe('constructor', function() { it('should create empty matrix if called with no argument', function() { var m = new DenseMatrix(); assert.deepEqual(m._size, [0]); assert.deepEqual(m._data, []); }); it('should create a DenseMatrix from an array', function () { var m = new DenseMatrix( [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]); assert.deepEqual(m._size, [4, 3]); assert.deepEqual( m._data, [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]); }); it('should create a DenseMatrix an array containing matrices', function () { var m = new DenseMatrix([new DenseMatrix([1,2]), new DenseMatrix([3, 4])]); assert.deepEqual(m, new DenseMatrix([[1,2],[3, 4]])); }); it('should create a DenseMatrix from another DenseMatrix', function () { var m1 = new DenseMatrix( [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]); var m2 = new DenseMatrix(m1); assert.deepEqual(m1._size, m2._size); assert.deepEqual(m1._data, m2._data); }); it('should create a DenseMatrix from a CcsMatrix', function () { var m1 = new CcsMatrix( [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]); var m2 = new DenseMatrix(m1); assert.deepEqual(m1.size(), m2.size()); assert.deepEqual(m1.toArray(), m2.toArray()); }); it('should throw an error when called without new keyword', function () { assert.throws(function () { DenseMatrix(); }, /Constructor must be called with the new operator/); }); }); describe('size', function() { it('should return the expected size', function() { assert.deepEqual(new DenseMatrix().size(), [0]); assert.deepEqual(new DenseMatrix([[23]]).size(), [1,1]); assert.deepEqual(new DenseMatrix([[1,2,3],[4,5,6]]).size(), [2,3]); assert.deepEqual(new DenseMatrix([1,2,3]).size(), [3]); assert.deepEqual(new DenseMatrix([[1],[2],[3]]).size(), [3,1]); assert.deepEqual(new DenseMatrix([[[1],[2],[3]]]).size(), [1,3,1]); assert.deepEqual(new DenseMatrix([[[3]]]).size(), [1,1,1]); assert.deepEqual(new DenseMatrix([[]]).size(), [1,0]); }); }); describe('toString', function() { it('should return string representation of matrix', function() { assert.equal(new DenseMatrix([[1,2],[3,4]]).toString(), '[[1, 2], [3, 4]]'); assert.equal(new DenseMatrix([[1,2],[3,1/3]]).toString(), '[[1, 2], [3, 0.3333333333333333]]'); }); }); describe('toJSON', function () { it('should serialize Matrix', function() { assert.deepEqual( new DenseMatrix([[1,2],[3,4]]).toJSON(), { mathjs: 'DenseMatrix', data: [[1, 2], [3, 4]], size: [2, 2] }); }); }); describe('fromJSON', function () { it('should deserialize Matrix', function() { var json = { mathjs: 'DenseMatrix', data: [[1, 2], [3, 4]], size: [2, 2] }; var m = DenseMatrix.fromJSON(json); assert.ok(m instanceof Matrix); assert.deepEqual(m._size, [2, 2]); assert.strictEqual(m._data[0][0], 1); assert.strictEqual(m._data[0][1], 2); assert.strictEqual(m._data[1][0], 3); assert.strictEqual(m._data[1][1], 4); }); }); describe('format', function () { it('should format matrix', function() { assert.equal(new DenseMatrix([[1,2],[3,1/3]]).format(), '[[1, 2], [3, 0.3333333333333333]]'); assert.equal(new DenseMatrix([[1,2],[3,1/3]]).format(3), '[[1, 2], [3, 0.333]]'); assert.equal(new DenseMatrix([[1,2],[3,1/3]]).format(4), '[[1, 2], [3, 0.3333]]'); }); }); describe('resize', function() { it('should resize the matrix correctly', function() { var m = new DenseMatrix([[1,2,3],[4,5,6]]); m.resize([2,4]); assert.deepEqual(m.valueOf(), [[1,2,3,0], [4,5,6,0]]); m.resize([1,2]); assert.deepEqual(m.valueOf(), [[1,2]]); m.resize([1,2,2], 8); assert.deepEqual(m.valueOf(), [[[1,8],[2,8]]]); m.resize([2,3], 9); assert.deepEqual(m.valueOf(), [[1,2, 9], [9,9,9]]); m = new DenseMatrix(); m.resize([3,3,3], 6); assert.deepEqual(m.valueOf(), [ [[6,6,6],[6,6,6],[6,6,6]], [[6,6,6],[6,6,6],[6,6,6]], [[6,6,6],[6,6,6],[6,6,6]] ]); m.resize([2,2]); assert.deepEqual(m.valueOf(), [[6,6],[6,6]]); m.resize([0]); assert.deepEqual(m.valueOf(), []); }); it('should resize the matrix with uninitialized default value', function() { var m = new DenseMatrix([]); m.resize([3], math.uninitialized); assert.deepEqual(m.valueOf(), arr(uninit, uninit, uninit)); }); it('should return a different matrix when copy=true', function() { var m1 = new DenseMatrix( [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0] ]); var m2 = m1.resize([2, 2], 0, true); assert(m1 !== m2); // original matrix cannot be modified assert.deepEqual(m1._size, [4, 4]); assert.deepEqual( m1._data, [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0] ]); // new matrix should have correct size assert.deepEqual(m2._size, [2, 2]); assert.deepEqual( m2._data, [ [0, 0], [0, 0] ]); }); }); describe('get', function () { var m = new DenseMatrix([[0, 1], [2, 3]]); it('should get a value from the matrix', function() { assert.equal(m.get([1,0]), 2); assert.equal(m.get([0,1]), 1); }); it('should throw an error when getting a value out of range', function() { assert.throws(function () { m.get([3,0]); }); assert.throws(function () { m.get([1,5]); }); assert.throws(function () { m.get([1]); }); assert.throws(function () { m.get([]); }); }); it('should throw an error in case of dimension mismatch', function() { assert.throws(function () { m.get([0,2,0,2,0,2]); }, /Dimension mismatch/); }); it('should throw an error when getting a value given a invalid index', function() { assert.throws(function () { m.get([1.2, 2]); }); assert.throws(function () { m.get([1,-2]); }); assert.throws(function () { m.get(1,1); }); assert.throws(function () { m.get(math.index(1,1)); }); assert.throws(function () { m.get([[1,1]]); }); }); }); describe('set', function () { it('should set a value in a matrix', function() { var m = new DenseMatrix([[0, 0], [0, 0]]); m.set([1,0], 5); assert.deepEqual(m, new DenseMatrix([ [0, 0], [5, 0] ])); m.set([0, 2], 4); assert.deepEqual(m, new DenseMatrix([ [0, 0, 4], [5, 0, 0] ])); m.set([0,0,1], 3); assert.deepEqual(m, new DenseMatrix([ [[0,3], [0,0], [4,0]], [[5,0], [0,0], [0,0]] ])); }); it('should set a value in a matrix with defaultValue for new elements', function() { var m = new DenseMatrix(); var defaultValue = 0; m.set([2], 4, defaultValue); assert.deepEqual(m, new DenseMatrix([0, 0, 4])); }); it('should throw an error when setting a value given a invalid index', function() { var m = new DenseMatrix([[0, 0], [0, 0]]); assert.throws(function() { m.set([2.5,0], 5); }); assert.throws(function() { m.set([1], 5); }); assert.throws(function() { m.set([-1, 1], 5); }); assert.throws(function() { m.set(math.index([0,0]), 5); }); }); }); describe('get subset', function() { it('should get the right subset of the matrix', function() { var m; // get 1-dimensional m = new DenseMatrix(math.range(0,10)); assert.deepEqual(m.size(), [10]); assert.deepEqual(m.subset(index([2,5])).valueOf(), [2,3,4]); // get 2-dimensional m = new DenseMatrix([[1,2,3],[4,5,6],[7,8,9]]); assert.deepEqual(m.size(), [3,3]); assert.deepEqual(m.subset(index(1,1)), 5); assert.deepEqual(m.subset(index([0,2],[0,2])).valueOf(), [[1,2],[4,5]]); assert.deepEqual(m.subset(index(1, [1,3])).valueOf(), [[5,6]]); assert.deepEqual(m.subset(index(0, [1,3])).valueOf(), [[2,3]]); assert.deepEqual(m.subset(index([1,3], 1)).valueOf(), [[5],[8]]); assert.deepEqual(m.subset(index([1,3], 2)).valueOf(), [[6],[9]]); // get n-dimensional m = new DenseMatrix([[[1,2],[3,4]], [[5,6],[7,8]]]); assert.deepEqual(m.size(), [2,2,2]); assert.deepEqual(m.subset(index([0,2],[0,2],[0,2])).valueOf(), m.valueOf()); assert.deepEqual(m.subset(index(0,0,0)), 1); assert.deepEqual(m.subset(index(1,1,1)).valueOf(), 8); assert.deepEqual(m.subset(index(1,1,[0,2])).valueOf(), [[[7,8]]]); assert.deepEqual(m.subset(index(1,[0,2],1)).valueOf(), [[[6],[8]]]); assert.deepEqual(m.subset(index([0,2],1,1)).valueOf(), [[[4]],[[8]]]); }); it('should squeeze the output when index contains a scalar', function() { var m = new DenseMatrix(math.range(0,10)); assert.deepEqual(m.subset(index(1)), 1); assert.deepEqual(m.subset(index([1,2])), new DenseMatrix([1])); m = new DenseMatrix([[1,2], [3,4]]); assert.deepEqual(m.subset(index(1,1)), 4); assert.deepEqual(m.subset(index([1,2], 1)), new DenseMatrix([[4]])); assert.deepEqual(m.subset(index(1, [1,2])), new DenseMatrix([[4]])); assert.deepEqual(m.subset(index([1,2], [1,2])), new DenseMatrix([[4]])); }); it('should throw an error if the given subset is invalid', function() { var m = new DenseMatrix(); assert.throws(function () { m.subset([-1]); }); m = new DenseMatrix([[1,2,3],[4,5,6]]); assert.throws(function () { m.subset([1,2,3]); }); assert.throws(function () { m.subset([3,0]); }); assert.throws(function () { m.subset([1]); }); }); it('should throw an error in case of wrong number of arguments', function() { var m = new DenseMatrix(); assert.throws(function () { m.subset();}, /Wrong number of arguments/); assert.throws(function () { m.subset(1,2,3,4); }, /Wrong number of arguments/); }); it('should throw an error in case of dimension mismatch', function() { var m = new DenseMatrix([[1,2,3],[4,5,6]]); assert.throws(function () { m.subset(index([0,2])); }, /Dimension mismatch/); }); }); describe('set subset', function() { it('should set the given subset', function() { // set 1-dimensional var m = new DenseMatrix(math.range(0,7)); m.subset(index([2,4]), [20,30]); assert.deepEqual(m, new DenseMatrix([0,1,20,30,4,5,6])); m.subset(index(4), 40); assert.deepEqual(m, new DenseMatrix([0,1,20,30,40,5,6])); // set 2-dimensional m = new DenseMatrix(); m.resize([3,3]); assert.deepEqual(m, new DenseMatrix([ [0, 0, 0], [0, 0, 0], [0, 0, 0] ])); m.subset(index([1,3], [1,3]), [[1,2],[3,4]]); assert.deepEqual(m, new DenseMatrix([ [0, 0, 0], [0, 1, 2], [0, 3, 4]])); m.subset(index(0, [0,3]), [5,6,7]); assert.deepEqual(m, new DenseMatrix([[5,6,7],[0,1,2],[0,3,4]])); m.subset(index([0,3], 0), [8,9,10]); // unsqueezes the submatrix assert.deepEqual(m, new DenseMatrix([[8,6,7],[9,1,2],[10,3,4]])); }); it('should set the given subset with defaultValue for new elements', function() { // multiple values var m = new DenseMatrix(); var defaultValue = 0; m.subset(index([3,5]), [3, 4], defaultValue); assert.deepEqual(m, new DenseMatrix([0, 0, 0, 3, 4])); defaultValue = 1; m.subset(index([3,5],1), [5, 6], defaultValue); assert.deepEqual(m, new DenseMatrix([ [0, 1], [0, 1], [0, 1], [3, 5], [4, 6] ])); defaultValue = 2; m.subset(index([3,5],2), [7, 8], defaultValue); assert.deepEqual(m, new DenseMatrix([ [0, 1, 2], [0, 1, 2], [0, 1, 2], [3, 5, 7], [4, 6, 8] ])); // a single value var i = new DenseMatrix(); defaultValue = 0; i.subset(math.index(2, 1), 6, defaultValue); assert.deepEqual(i, new DenseMatrix([[0, 0], [0, 0], [0, 6]])); }); it('should unsqueeze the replacement subset if needed', function() { var m = new DenseMatrix([[0,0],[0,0]]); // 2x2 m.subset(index(0, [0,2]), [1,1]); // 2 assert.deepEqual(m, new DenseMatrix([[1,1],[0,0]])); m.subset(index([0,2], 0), [2,2]); // 2 assert.deepEqual(m, new DenseMatrix([[2,1],[2,0]])); m = new DenseMatrix([[[0],[0],[0]]]); // 1x3x1 m.subset(index(0, [0,3], 0), [1,2,3]); // 3 assert.deepEqual(m, new DenseMatrix([[[1],[2],[3]]])); m = new DenseMatrix([[[0,0,0]]]); // 1x1x3 m.subset(index(0, 0, [0,3]), [1,2,3]); // 3 assert.deepEqual(m, new DenseMatrix([[[1,2,3]]])); m = new DenseMatrix([[[0]],[[0]],[[0]]]); // 3x1x1 m.subset(index([0,3], 0, 0), [1,2,3]); // 3 assert.deepEqual(m, new DenseMatrix([[[1]],[[2]],[[3]]])); m = new DenseMatrix([[[0,0,0]]]); // 1x1x3 m.subset(index(0, 0, [0,3]), [[1,2,3]]); // 1x3 assert.deepEqual(m, new DenseMatrix([[[1,2,3]]])); m = new DenseMatrix([[[0]],[[0]],[[0]]]); // 3x1x1 m.subset(index([0,3], 0, 0), [[1],[2],[3]]); // 3x1 assert.deepEqual(m, new DenseMatrix([[[1]],[[2]],[[3]]])); }); it('should resize the matrix if the replacement subset is different size than selected subset', function() { // set 2-dimensional with resize var m = new DenseMatrix([[123]]); m.subset(index([1,3], [1,3]), [[1,2],[3,4]]); assert.deepEqual(m, new DenseMatrix([[123,0,0],[0,1,2],[0,3,4]])); // set resize dimensions m = new DenseMatrix([123]); assert.deepEqual(m.size(), [1]); m.subset(index([1,3], [1,3]), [[1,2],[3,4]]); assert.deepEqual(m, new DenseMatrix([[123,0,0],[0,1,2],[0,3,4]])); m.subset(index([0,2], [0,2]), [[55,55],[55,55]]); assert.deepEqual(m, new DenseMatrix([[55,55,0],[55,55,2],[0,3,4]])); m = new DenseMatrix(); m.subset(index([1,3], [1,3], [1,3]), [[[1,2],[3,4]],[[5,6],[7,8]]]); var res = new DenseMatrix([ [ [0, 0, 0], [0, 0, 0], [0, 0, 0] ], [ [0, 0, 0], [0, 1, 2], [0, 3, 4] ], [ [0, 0, 0], [0, 5, 6], [0, 7, 8] ] ]); assert.deepEqual(m, res); }); it ('should throw an error in case of wrong type of index', function () { assert.throws(function () { new DenseMatrix().subset('no index', 2); }, /Invalid index/); }); it ('should throw an error in case of wrong size of submatrix', function () { assert.throws(function () { new DenseMatrix().subset(index(0), [2,3]); }, /Scalar expected/); }); it('should throw an error in case of dimension mismatch', function() { var m = new DenseMatrix([[1,2,3],[4,5,6]]); assert.throws(function () { m.subset(index([0,2]), [100,100]); }, /Dimension mismatch/); assert.throws(function () { m.subset(index([0,2], [0,2]), [100,100]); }, /Dimension mismatch/); }); }); describe('map', function() { it('should apply the given function to all elements in the matrix', function() { var m = new DenseMatrix([ [[1,2],[3,4]], [[5,6],[7,8]], [[9,10],[11,12]], [[13,14],[15,16]] ]); var m2 = m.map(function (value) { return value * 2; }); assert.deepEqual( m2.valueOf(), [ [[2,4],[6,8]], [[10,12],[14,16]], [[18,20],[22,24]], [[26,28],[30,32]] ]); m = new DenseMatrix([1]); m2 = m.map(function (value) { return value * 2; }); assert.deepEqual(m2.valueOf(), [2]); m = new DenseMatrix([1,2,3]); m2 = m.map(function (value) { return value * 2; }); assert.deepEqual(m2.valueOf(), [2,4,6]); }); it('should work on empty matrices', function() { var m = new DenseMatrix([]); var m2 = m.map(function (value) { return value * 2; }); assert.deepEqual(m2.toArray(), []); }); it('should invoke callback with parameters value, index, obj', function() { var m = new DenseMatrix([[1,2,3], [4,5,6]]); var m2 = m.map( function (value, index, obj) { return math.clone([value, index, obj === m]); } ); assert.deepEqual( m2.toArray(), [ [ [1, [0, 0], true ], [2, [0, 1], true ], [3, [0, 2], true ] ], [ [4, [1, 0], true ], [5, [1, 1], true ], [6, [1, 2], true ] ] ]); }); }); describe('forEach', function() { it('should run on all elements of the matrix, last dimension first', function() { var m, output; m = new DenseMatrix([ [[1,2],[3,4]], [[5,6],[7,8]], [[9,10],[11,12]], [[13,14],[15,16]] ]); output = []; m.forEach(function (value) { output.push(value); }); assert.deepEqual(output, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); m = new DenseMatrix([1]); output = []; m.forEach(function (value) { output.push(value); }); assert.deepEqual(output, [1]); m = new DenseMatrix([1,2,3]); output = []; m.forEach(function (value) { output.push(value); }); assert.deepEqual(output, [1,2,3]); }); it('should work on empty matrices', function() { var m = new DenseMatrix([]); var output = []; m.forEach(function (value) { output.push(value); }); assert.deepEqual(output, []); }); it('should invoke callback with parameters value, index, obj', function() { var m = new DenseMatrix([[1,2,3], [4,5,6]]); var output = []; m.forEach( function (value, index, obj) { output.push(math.clone([value, index, obj === m])); } ); 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 ] ]); }); }); describe('clone', function() { it('should clone the matrix properly', function() { var m1 = new DenseMatrix( [ [1,2,3], [4,5,6] ]); var m2 = m1.clone(); assert.deepEqual(m1._data, m2._data); }); }); describe('toArray', function () { it('should return array', function () { var m = new DenseMatrix({ data: [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ], size: [4, 3] }); var a = m.toArray(); assert.deepEqual( a, [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]); }); it('should return array, complex numbers', function () { var m = new DenseMatrix({ data: [new Complex(1, 1), new Complex(4, 4), new Complex(5, 5), new Complex(2, 2), new Complex(3, 3), new Complex(6, 6)], size: [1, 6] }); var a = m.toArray(); assert.deepEqual(a, [new Complex(1, 1), new Complex(4, 4), new Complex(5, 5), new Complex(2, 2), new Complex(3, 3), new Complex(6, 6)]); }); }); describe('diagonal', function () { it('should create matrix (n x n)', function () { var m = DenseMatrix.diagonal([3, 3], 1); assert.deepEqual(m._size, [3, 3]); assert.deepEqual( m.toArray(), [ [1, 0, 0], [0, 1, 0], [0, 0, 1] ]); }); it('should create matrix (n x n), k > 0', function () { var m = DenseMatrix.diagonal([3, 3], 1, 1); assert.deepEqual(m._size, [3, 3]); assert.deepEqual( m.toArray(), [ [0, 1, 0], [0, 0, 1], [0, 0, 0] ]); }); it('should create matrix (n x n), k < 0', function () { var m = DenseMatrix.diagonal([3, 3], 1, -1); assert.deepEqual(m._size, [3, 3]); assert.deepEqual( m.toArray(), [ [0, 0, 0], [1, 0, 0], [0, 1, 0] ]); }); it('should create matrix (n x n), vector value', function () { var m = DenseMatrix.diagonal([3, 3], [1, 2, 3]); assert.deepEqual(m._size, [3, 3]); assert.deepEqual( m.toArray(), [ [1, 0, 0], [0, 2, 0], [0, 0, 3] ]); }); it('should create matrix (n x n), vector value, k > 0', function () { var m = DenseMatrix.diagonal([3, 3], [1, 2], 1); assert.deepEqual(m._size, [3, 3]); assert.deepEqual( m.toArray(), [ [0, 1, 0], [0, 0, 2], [0, 0, 0] ]); }); it('should create matrix (n x n), vector value, k < 0', function () { var m = DenseMatrix.diagonal([3, 3], [1, 2], -1); assert.deepEqual(m._size, [3, 3]); assert.deepEqual( m.toArray(), [ [0, 0, 0], [1, 0, 0], [0, 2, 0] ]); }); it('should create matrix (m x n), m > n', function () { var m = DenseMatrix.diagonal([4, 3], 1); assert.deepEqual(m._size, [4, 3]); assert.deepEqual( m.toArray(), [ [1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0] ]); }); it('should create matrix (m x n), m > n, k > 0', function () { var m = DenseMatrix.diagonal([4, 3], 1, 1); assert.deepEqual(m._size, [4, 3]); assert.deepEqual( m.toArray(), [ [0, 1, 0], [0, 0, 1], [0, 0, 0], [0, 0, 0] ]); }); it('should create matrix (m x n), m > n, k < 0', function () { var m = DenseMatrix.diagonal([4, 3], 1, -1); assert.deepEqual(m._size, [4, 3]); assert.deepEqual( m.toArray(), [ [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1], ]); }); it('should create matrix (m x n), m > n, vector value', function () { var m = DenseMatrix.diagonal([4, 3], [1, 2, 3]); assert.deepEqual(m._size, [4, 3]); assert.deepEqual( m.toArray(), [ [1, 0, 0], [0, 2, 0], [0, 0, 3], [0, 0, 0] ]); }); it('should create matrix (m x n), m > n, vector value, k > 0', function () { var m = DenseMatrix.diagonal([4, 3], [1, 2], 1); assert.deepEqual(m._size, [4, 3]); assert.deepEqual( m.toArray(), [ [0, 1, 0], [0, 0, 2], [0, 0, 0], [0, 0, 0] ]); }); it('should create matrix (m x n), m > n, vector value, k < 0', function () { var m = DenseMatrix.diagonal([4, 3], [1, 2, 3], -1); assert.deepEqual(m._size, [4, 3]); assert.deepEqual( m.toArray(), [ [0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3] ]); }); it('should create matrix (m x n), m < n', function () { var m = DenseMatrix.diagonal([3, 4], 1); assert.deepEqual(m._size, [3, 4]); assert.deepEqual( m.toArray(), [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0] ]); }); it('should create matrix (m x n), m < n, k > 0', function () { var m = DenseMatrix.diagonal([3, 4], 1, 1); assert.deepEqual(m._size, [3, 4]); assert.deepEqual( m.toArray(), [ [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]); }); it('should create matrix (m x n), m < n, k < 0', function () { var m = DenseMatrix.diagonal([3, 4], 1, -1); assert.deepEqual(m._size, [3, 4]); assert.deepEqual( m.toArray(), [ [0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0] ]); }); it('should create matrix (m x n), m < n, vector value', function () { var m = DenseMatrix.diagonal([3, 4], [1, 2, 3]); assert.deepEqual(m._size, [3, 4]); assert.deepEqual( m.toArray(), [ [1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0] ]); }); it('should create matrix (m x n), m < n, vector value, k > 0', function () { var m = DenseMatrix.diagonal([3, 4], [1, 2, 3], 1); assert.deepEqual(m._size, [3, 4]); assert.deepEqual( m.toArray(), [ [0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3] ]); }); it('should create matrix (m x n), m < n, vector value, k < 0', function () { var m = DenseMatrix.diagonal([3, 4], [1, 2], -1); assert.deepEqual(m._size, [3, 4]); assert.deepEqual( m.toArray(), [ [0, 0, 0, 0], [1, 0, 0, 0], [0, 2, 0, 0] ]); }); it('should get matrix diagonal (n x n)', function () { var m = new DenseMatrix( [ [1, 0, 0], [0, 1, 0], [0, 0, 1] ]); assert.deepEqual(m.diagonal(), [1, 1, 1]); }); it('should get matrix diagonal (n x n), k > 0', function () { var m = new DenseMatrix( [ [1, 2, 0], [0, 1, 3], [0, 0, 1] ]); assert.deepEqual(m.diagonal(1), [2, 3]); }); it('should get matrix diagonal (n x n), k < 0', function () { var m = new DenseMatrix( [ [1, 0, 0], [2, 1, 0], [0, 3, 1] ]); assert.deepEqual(m.diagonal(-1), [2, 3]); }); it('should get matrix diagonal (m x n), m > n', function () { var m = new DenseMatrix( [ [1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0] ]); assert.deepEqual(m.diagonal(), [1, 1, 1]); }); it('should get matrix diagonal (m x n), m > n, k > 0', function () { var m = new DenseMatrix( [ [1, 2, 0], [0, 1, 3], [0, 0, 1], [0, 0, 0] ]); assert.deepEqual(m.diagonal(1), [2, 3]); }); it('should get matrix diagonal (m x n), m > n, k < 0', function () { var m = new DenseMatrix( [ [1, 0, 0], [2, 1, 0], [0, 3, 1], [0, 0, 4] ]); assert.deepEqual(m.diagonal(-1), [2, 3, 4]); }); it('should get matrix diagonal (m x n), m < n', function () { var m = new DenseMatrix( [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0] ]); assert.deepEqual(m.diagonal(), [1, 1, 1]); }); it('should get matrix diagonal (m x n), m < n, k > 0', function () { var m = new DenseMatrix( [ [1, 2, 0, 0], [0, 1, 3, 0], [0, 0, 1, 4] ]); assert.deepEqual(m.diagonal(1), [2, 3, 4]); }); it('should get matrix diagonal (m x n), m < n, k < 0', function () { var m = new DenseMatrix( [ [1, 0, 0, 0], [2, 1, 0, 0], [4, 3, 1, 0] ]); assert.deepEqual(m.diagonal(-1), [2, 3]); assert.deepEqual(m.diagonal(-2), [4]); }); }); describe('transpose', function () { it('should transpose a 2d matrix', function() { var m = new DenseMatrix([[1,2,3],[4,5,6]]); assert.deepEqual(m.transpose().toArray(), [[1,4],[2,5],[3,6]]); m = new DenseMatrix([[1,2],[3,4]]); assert.deepEqual(m.transpose().toArray(), [[1,3],[2,4]]); m = new DenseMatrix([[1,2,3,4]]); assert.deepEqual(m.transpose().toArray(), [[1],[2],[3],[4]]); }); it('should throw an error for invalid matrix transpose', function() { var m = new DenseMatrix([[]]); assert.throws(function () { m.transpose(); }); m = new DenseMatrix([[[1],[2]],[[3],[4]]]); assert.throws(function () { m.transpose(); }); }); }); describe('trace', function () { it('should calculate trace on a square matrix', function() { var m = new DenseMatrix([ [1, 2], [4, -2] ]); assert.equal(m.trace(), -1); m = new DenseMatrix([ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0] ]); assert.equal(m.trace(), 0); m = new DenseMatrix([ [1, 0, 0, 0], [0, 0, 2, 0], [1, 0, 0, 0], [0, 0, 1, 9] ]); assert.equal(m.trace(), 10); }); it('should throw an error for invalid matrix', function() { var m = new DenseMatrix([ [1, 2, 3], [4, 5, 6] ]); assert.throws(function () { m.trace(); }); }); }); describe('multiply', function () { it('should multiply matrix x scalar', function() { var m = new DenseMatrix([ [2, 0], [4, 0] ]); var r = m.multiply(3); assert.deepEqual(r._size, m._size); assert.deepEqual(r._data, [[6, 0], [12, 0]]); r = m.multiply(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 = m.multiply(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 = m.multiply(true); assert.deepEqual(r._size, m._size); assert.deepEqual(r._data, [[2, 0], [4, 0]]); r = m.multiply(false); assert.deepEqual(r._size, m._size); assert.deepEqual(r._data, [[0, 0], [0, 0]]); }); it('should multiply matrix x matrix', function() { var m = new DenseMatrix([ [2, 0], [4, 0] ]); var r = m.multiply(new DenseMatrix([ [2, 0], [4, 0] ])); assert.deepEqual( r.valueOf(), [ [4, 0], [8, 0] ]); r = m.multiply(math.matrix([ [2, 0], [4, 0] ]), 'crs'); assert.deepEqual( r.valueOf(), [ [4, 0], [8, 0] ]); }); it('should multiply matrix x array', function() { var m = new DenseMatrix([ [2, 0], [4, 0] ]); var r = m.multiply( [ [2, 0], [4, 0] ]); assert.deepEqual( r.valueOf(), [ [4, 0], [8, 0] ]); r = m.multiply( [ [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 = new DenseMatrix([ [2, 0], [4, 0] ]); var r = m.multiply( [ [2], [4] ]); assert.deepEqual( r.valueOf(), [ [4], [8] ]); }); it ('should squeeze scalar results of matrix * matrix', function () { var a = new DenseMatrix( [ [1, 2, 3] ]); var b = new DenseMatrix( [ [4], [5], [6] ]); assert.strictEqual(a.multiply(b), 32); }); it ('should squeeze scalar results of matrix * vector', function () { var a = new DenseMatrix( [ [1, 2, 3] ]); var b = [4, 5, 6]; assert.strictEqual(a.multiply(b), 32); }); it('should throw an error when multiplying matrices with incompatible sizes', function() { // vector * vector assert.throws(function () {math.matrix([1,1], 'dense').multiply([1, 1, 1]);}); // matrix * matrix assert.throws(function () {math.matrix([[1,1]], 'dense').multiply([[1,1]]);}); assert.throws(function () {math.matrix([[1,1]], 'dense').multiply([[1,1], [1,1], [1,1]]);}); // matrix * vector assert.throws(function () {math.matrix([[1,1], [1,1]], 'dense').multiply([1,1,1]);}); // vector * matrix assert.throws(function () {math.matrix([1,1,1], 'dense').multiply([[1,1], [1,1]]);}); }); }); /** * 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; } });