UNPKG

@bluemath/linalg

Version:
926 lines (871 loc) 28.4 kB
/* Copyright (C) 2017 Jayesh Salvi, Blue Math Software Inc. This file is part of bluemath. bluemath is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. bluemath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with bluemath. If not, see <http://www.gnu.org/licenses/>. */ import {isequal,NDArray,Complex} from '@bluemath/common' import * as linalg from '../src' export default function testOps() { QUnit.module('Ops', () => { QUnit.module('matmul', () => { QUnit.test("Square 3x3", assert => { let A = new NDArray([[2,2,2],[2,2,2],[2,2,2]], {datatype:'i16'}); let B = new NDArray([[5,5,5],[5,5,5],[5,5,5]], {datatype:'i16'}); let M = linalg.matmul(A,B); if(M instanceof NDArray) { assert.deepEqual(M.shape, [3,3]); for(let i=0; i<3; i++) { for(let j=0; j<3; j++) { assert.equal(M.get(i,j), 30); } } } else { assert.notOk(true); } }); QUnit.test("3x2 mul 2x3", assert => { let A = new NDArray([[1,0],[2,1],[6,9]], {datatype:'i16'}); let B = new NDArray([[1,2,3],[1,2,9]], {datatype:'i16'}); let M = linalg.matmul(A,B); if(M instanceof NDArray) { assert.deepEqual(M.shape, [3,3]); assert.equal(M.get(1,0), 3); assert.equal(M.get(1,2), 15); assert.equal(M.get(2,1), 30); assert.equal(M.get(2,2), 99); } else { assert.notOk(true); } }); QUnit.test("3x2 mul 3x3, error", assert => { let A = new NDArray([[1,0],[2,1],[6,9]], {datatype:'i16'}); let B = new NDArray([[1,2,3],[1,2,9],[4,5,3]], {datatype:'i16'}); assert.throws(() => { linalg.matmul(A,B); }); }); QUnit.test("mul by Vector (inner product)", assert => { let A = new NDArray([[1,0,2]], {datatype:'i16'}); let B = new NDArray([[4,4,9]], {datatype:'i16'}); B.reshape([3,1]); let M = linalg.matmul(A, B); assert.deepEqual(M.shape, [1,1]); assert.equal(M.get(0,0), 22); }); QUnit.test("mul by Vector, error", assert => { let A = new NDArray([[1,0,2],[3,5,6]], {datatype:'i16'}); let B = new NDArray([[4,4,9]], {datatype:'i16'}); assert.throws(() => linalg.matmul(A,B)); }); QUnit.test("mul by Vector (outer product)", assert => { let A = new NDArray([[3,3]], {datatype:'i16'}); A.reshape([2,1]); let B = new NDArray([[2,2]], {datatype:'i16'}); let M = linalg.matmul(A,B); assert.deepEqual(M.shape, [2,2]); assert.equal(M.get(0,0), 6); assert.equal(M.get(0,1), 6); assert.equal(M.get(1,0), 6); assert.equal(M.get(1,1), 6); }); }); QUnit.module('inner', () => { QUnit.test('A(3), B(3)', assert => { let A = new NDArray([3,4,5]); let B = new NDArray([1,2,5]); assert.equal(linalg.inner(A,B), 36); }); QUnit.test('A(3), B(4)', assert => { let A = new NDArray([3,4,5]); let B = new NDArray([1,2,5,7]); assert.equal(linalg.inner(A,B), 36); }); QUnit.test('A(4), B(3)', assert => { let A = new NDArray([3,4,5,6]); let B = new NDArray([1,2,5]); assert.throws(() => linalg.inner(A,B)); }); }); QUnit.module('outer', () => { QUnit.test('A(3), B(3)', assert => { let A = new NDArray([1,1,1]); let B = new NDArray([1,1,1]); assert.deepEqual(linalg.outer(A,B).toArray(),[ [1,1,1],[1,1,1],[1,1,1] ]); }); QUnit.test('A(3x1), B(1x3)', assert => { let A = new NDArray([[1],[1],[1]]); let B = new NDArray([1,1,1]); assert.deepEqual(linalg.outer(A,B).toArray(),[ [1,1,1],[1,1,1],[1,1,1] ]); }); QUnit.test('A(1x3), B(3x1)', assert => { let A = new NDArray([1,1,1]); let B = new NDArray([[1],[1],[1]]); assert.throws(() => linalg.outer(A,B)); }); }); QUnit.module('norm', () => { QUnit.module('Vector', () => { QUnit.test('0-norm', assert => { let A = new NDArray([0,3,0,5]); assert.equal(linalg.norm(A,0), 2); }); QUnit.test('1-norm', assert => { let A = new NDArray([2,3,4,5]); assert.equal(linalg.norm(A,1), 14); }); QUnit.test('2-norm', assert => { let A = new NDArray([2,3,4,5]); assert.ok(isequal(linalg.norm(A,2), 7.34847)); }); QUnit.test('3-norm', assert => { let A = new NDArray([2,3,4,5]); assert.ok(isequal(linalg.norm(A,3), 6.07318, 1e-4)); }); QUnit.test('Infinity-norm', assert => { let A = new NDArray([2,3,4,5]); assert.equal(linalg.norm(A,Infinity), 5); A = new NDArray([2,3,-48,5]); assert.equal(linalg.norm(A,Infinity), 48); }); QUnit.test('-Infinity-norm', assert => { let A = new NDArray([2,3,4,5]); assert.equal(linalg.norm(A,-Infinity), 2); A = new NDArray([2,3,-48,5]); assert.equal(linalg.norm(A,-Infinity), 2); }); }); QUnit.module('Matrix', () => { QUnit.test('Frobenius norm', assert => { let A = new NDArray([ [2,3,4], [4,2,-9], [0,3,1] ]); assert.ok(isequal(linalg.norm(A, 'fro'), 11.832159566199232, 1e-6)); }); }); }); QUnit.module('lstsq', () => { QUnit.test('Line fitting 1', assert => { let Y = new NDArray([-1,0.2,0.9,2.1]); let A = new NDArray([ [0,1], [1,1], [2,1], [3,1] ]); let {x,residuals,rank,singulars} = linalg.lstsq(A,Y); assert.ok(isequal(<number>x.get(0,0),1)); assert.ok(isequal(<number>x.get(1,0),-0.95)); assert.equal(rank, 2); assert.ok(residuals.isEqual(new NDArray([0.05]))); assert.ok(singulars.isEqual(new NDArray([4.10003045, 1.09075677]))); }); QUnit.test('Line fitting 2', assert => { let Y = new NDArray([3.9, 2.3, 2, -1.4, -1, -0.1]); let A = new NDArray([ [-3, 1], [-0.9, 1], [-1.8, 1], [3.2, 1], [1, 1], [3.3, 1] ]); let {x,residuals,rank,singulars} = linalg.lstsq(A,Y); assert.ok(isequal(<number>x.get(0, 0), -0.71853349)); assert.ok(isequal(<number>x.get(1, 0), 1.16556005)); assert.equal(rank, 2); assert.ok(residuals.isEqual(new NDArray([4.1707015]))); assert.ok(singulars.isEqual(new NDArray([5.94059051, 2.42680538]))); }); }); QUnit.module('slogdet', () => { QUnit.test('3x3', assert => { let A = new NDArray([ [4,5,6], [1,5,3], [8,4,5] ]); let [sign,logdet] = linalg.slogdet(A); assert.equal(sign,-1); assert.ok(isequal(logdet, Math.log(69))); }); QUnit.test('2x2', assert => { let A = new NDArray([ [4,5], [1,5], ]); let [sign,logdet] = linalg.slogdet(A); assert.equal(sign,1); assert.equal(logdet, Math.log(15)); }); }); QUnit.module('det', () => { QUnit.test('3x3', assert => { let A = new NDArray([ [4,5,6], [1,5,3], [8,4,5] ]); let det = linalg.det(A); assert.ok(isequal(det, -69, 1e-5)); }); QUnit.test('2x2', assert => { let A = new NDArray([ [4,5], [1,5], ]); let det = linalg.det(A); assert.equal(det, 15); }); }); QUnit.module('inv', () => { QUnit.test('2x2', assert => { let A = new NDArray([ [4,5], [1,3] ]); let invA = linalg.inv(A); assert.ok(invA.isEqual(new NDArray([ [ 0.42857143, -0.71428571], [-0.14285714, 0.57142857] ]))); }); QUnit.test('3x3 test1', assert => { let A = new NDArray([ [4,5,6], [1,5,3], [8,4,5] ]); let invA = linalg.inv(A); assert.ok(invA.isEqual(new NDArray([ [-0.1884058 , 0.01449275, 0.2173913 ], [-0.27536232, 0.4057971 , 0.08695652], [ 0.52173913, -0.34782609, -0.2173913 ] ]))); }); QUnit.test('3x3 test2', assert => { let A = new NDArray([ [4,-5,6], [1,0,3], [-8,4,5] ]); let invA = linalg.inv(A); assert.ok(invA.isEqual(new NDArray([ [-0.09917355, 0.40495868, -0.12396694], [-0.23966942, 0.56198347, -0.04958678], [ 0.03305785, 0.19834711, 0.04132231] ]))); }); }); QUnit.module('rank', () => { QUnit.test('Full rank 3x3', assert => { let A = new NDArray([ [3,5,6],[3,2,1],[7,8,16] ]); assert.equal(linalg.rank(A), 3); }); QUnit.test('Rank 2 for 3x3', assert => { let A = new NDArray([ [3,5,6],[3,2,6],[6,8,12] ]); assert.equal(linalg.rank(A), 2); }); QUnit.test('Rank 1 for 3x3', assert => { let A = new NDArray([ [3,5,6],[3,5,6],[6,10,12] ]); assert.equal(linalg.rank(A), 1); }); }); QUnit.module('SVD', () => { QUnit.test( 'svd 3x3 - full_matrices=true, complete_uv=true', assert => { let A = new NDArray([ [-3,6,-1], [11,-3,0], [0,-1,3] ], {datatype:'f32'}); let [U,S,VT] = linalg.svd(A,true,true); // Results generated from numpy assert.ok(U.isEqual(new NDArray([ [-0.42847299, -0.81649658, 0.386968], [0.90241006, -0.40824829, 0.1378021], [0.04546408, 0.40824829, 0.91173809] ]))); assert.ok(S.isEqual(new NDArray([ 12.4244289, 5.0, 2.5755711 ]))); assert.ok(VT.isEqual(new NDArray([ [0.90241006, -0.42847299, 0.04546408], [-0.40824829, -0.81649658, 0.40824829], [0.1378021, 0.386968, 0.91173809] ]))); }); QUnit.test( 'svd 3x3 - full_matrices=false, complete_uv=false', assert => { let A = new NDArray([ [-3,6,-1], [11,-3,0], [0,-1,3] ], {datatype:'f32'}); let [S] = linalg.svd(A,true,false); assert.ok(S.isEqual(new NDArray([ 12.4244289, 5.0, 2.5755711 ]))); }); QUnit.test( 'svd 4x3 - full_matrices=false, complete_uv=false', assert => { let A = new NDArray([ [-3,6,-1], [11,-3,0], [0,-1,3], [4,4,4] ], {datatype:'f32'}); let [S] = linalg.svd(A,true,false); assert.ok(S.isEqual(new NDArray([ 12.66786356, 7.40286577, 4.32698638 ]))); }); QUnit.skip( 'svd 4x3 - full_matrices=true, complete_uv=false', assert => { let A = new NDArray([ [-3,6,-1], [11,-3,0], [0,-1,3], [4,4,4] ], {datatype:'f32'}); let [U,S,VT] = linalg.svd(A,true,true); assert.ok(U.isEqual(new NDArray([ [-0.38547869, -0.56023949, 0.51437432, -0.52245282], [0.89197997, -0.02652779, 0.34920785, -0.28587041], [0.05307408, -0.03691955, -0.71131891, -0.69988963], [0.2301327, -0.82708218, -0.3278694, 0.39430402] ]))); assert.ok(S.isEqual(new NDArray([ 12.66786356, 7.40286577, 4.32698638 ]))); assert.ok(VT.isEqual(new NDArray([ [0.93849657, -0.32533941, 0.11566526], [-0.25928012, -0.88523323, -0.38618124], [0.22803071, 0.33244007, -0.91514239] ]))); }); QUnit.test( 'svd 4x3 - full_matrices=false, complete_uv=false', assert => { let A = new NDArray([ [-3,6,-1], [11,-3,0], [0,-1,3], [4,4,4] ], {datatype:'f32'}); let [U,S,VT] = linalg.svd(A,false,true); assert.ok(U.isEqual(new NDArray([ [-0.38547869, -0.56023949, 0.51437432], [0.89197997, -0.02652779, 0.34920785], [0.05307408, -0.03691955, -0.71131891], [0.2301327, -0.82708218, -0.3278694] ]))); assert.ok(S.isEqual(new NDArray([ 12.66786356, 7.40286577, 4.32698638 ]))); assert.ok(VT.isEqual(new NDArray([ [0.93849657, -0.32533941, 0.11566526], [-0.25928012, -0.88523323, -0.38618124], [0.22803071, 0.33244007, -0.91514239] ]))); }); }); /* QUnit.module("Permutation", () => { QUnit.test("Vector", assert => { let V = new NDArray([34,65,23,90]); let p = new NDArray([0,2,3,1]); linalg.permuteVector(V,p); assert.ok(V.isEqual(new NDArray([34,23,90,65]))); }); QUnit.test("Vector inverse", assert => { // Same permutation vector, but used on original let V = new NDArray([34,65,23,90]); let p = new NDArray([0,2,3,1]); linalg.ipermuteVector(V,p); assert.ok(V.isEqual(new NDArray([34,90,65,23]))); // Same permutation vector, but used on result of first test V = new NDArray([34,23,90,65]); p = new NDArray([0,2,3,1]); linalg.ipermuteVector(V,p); assert.ok(V.isEqual(new NDArray([34,65,23,90]))); }); }); */ /* QUnit.module('LU Decomposition', () => { QUnit.test('3x3', assert => { let A = new NDArray([ [3,17,10], [2,4,-2], [6,18,-12] ]); let P = linalg.lu(A); assert.ok(P.isEqual(new NDArray([2,0,1]))); assert.ok(A.isEqual(new NDArray([ [6,18,-12], [0.5,8,16], [0.3333333,-0.25,6] ]))); }); }); */ QUnit.module('Solve', () => { QUnit.test('Upper tri', assert => { let A = new NDArray([ [4,9], [0,5] ]); let x = new NDArray([32,10]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray([3.5,2]))); }); QUnit.test('Lower tri', assert => { let A = new NDArray([ [3,0], [11,5] ]); let x = new NDArray([21,99]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray([7,4.4]))); }); QUnit.module('LU Solve', () => { QUnit.test("Circuit matrix", assert => { let A = new NDArray([ [11,-3,0], [-3,6,-1], [0,-1,3] ]); let x = new NDArray([30,5,-25]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray([3,1,-8]))); }); QUnit.test("From numpy tests", assert => { let A = new NDArray([ [3,1], [1,2] ]); let x = new NDArray([9,8]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray([2,3]))); }); QUnit.test("From GSL tests", assert => { let A = new NDArray([ [0.18, 0.60, 0.57, 0.96], [0.41, 0.24, 0.99, 0.58], [0.14, 0.30, 0.97, 0.66], [0.51, 0.13, 0.19, 0.85] ],{datatype:'f64'}); let x = new NDArray([1,2,3,4]) linalg.solve(A,x); assert.ok(x.isEqual(new NDArray( [-4.05205, -12.6056, 1.66091, 8.69377],{datatype:'f64'}),1e-4)); }); QUnit.test("Random tests 1 (match with numpy)", assert => { let A = new NDArray([ [4, 7, 5, 12], [4, 3, 2, 1], [6, 2, 9, 3], [4, 1, 8, 8]]) let x = new NDArray([13, 15, 2, 90]); linalg.solve(A,x); assert.ok(x.isEqual( new NDArray([40.50877193, -39.30526316, -25.02807018, 20.93684211]),1e-4)); }); QUnit.test("Random tests 2 (match with numpy)", assert => { let A = new NDArray([ [4, 7, 5, 0.5], [4, 3, 2, 1], [6, 2, 99, 3], [4, 1, 8, 8]]) let x = new NDArray([13, 15, 2, 90]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray( [0.19644227, 1.19044879, -0.36008822, 11.36306099]))); }); QUnit.test("Random tests 3 (match with numpy)", assert => { let A = new NDArray([ [4, 0.0007, 5, 0.5], [4, 3, 2, 1], [6, 2, 9999, 3], [4, 1, 8, 8]]) let x = new NDArray([13, 15, 2, 90]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray( [1.95364698e+00, -1.07265497e+00, -3.88138726e-03, 1.04111398e+01]))); }); QUnit.test("Random tests 4 (match with numpy)", assert => { let A = new NDArray([ [4, 0.0007, 5, 0.5], [4, 3, 2, 1], [6, 2, 9999, 3], [4, 1, 8, 8]]) let x = new NDArray([13, 0.15, 2986, 90]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray( [1.51620015, -5.80949758, 0.295605, 10.92248213]),1e-5)); }); QUnit.test("Solve multiple", assert => { let A = new NDArray([ [4, 7, 5, 12], [4, 3, 2, 1], [6, 2, 9, 3], [4, 1, 8, 8]]) let x = new NDArray([ [13,45,3], [15,66,3], [2,0.02,8], [90,1,0] ]); linalg.solve(A,x); assert.ok(x.isEqual(new NDArray([ [40.50877193, 31.61561404, -1.66667], [-39.30526316, -8.06736842, 2.4], [-25.02807018, -21.58596491, 1.933333], [20.93684211, 6.91157895, -1.4] ]),1e-5)); }); }); }); QUnit.module('tri', () => { QUnit.module('tril', () => { QUnit.test('4x4', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let trilA = linalg.tril(A); assert.ok(trilA.isEqual(new NDArray([ [5,0,0,0], [5,5,0,0], [5,5,5,0], [5,5,5,5] ]))); }); QUnit.test('4x4 diag -1', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let trilA = linalg.tril(A,-1); assert.ok(trilA.isEqual(new NDArray([ [0,0,0,0], [5,0,0,0], [5,5,0,0], [5,5,5,0] ]))); }); QUnit.test('4x4 diag 1', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let trilA = linalg.tril(A,1); assert.ok(trilA.isEqual(new NDArray([ [5,5,0,0], [5,5,5,0], [5,5,5,5], [5,5,5,5] ]))); }); QUnit.test('6x4', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let trilA = linalg.tril(A); assert.ok(trilA.isEqual(new NDArray([ [5,0,0,0], [5,5,0,0], [5,5,5,0], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]))); }); QUnit.test('4x6', assert => { let A = new NDArray([ [5,5,5,5,5,5], [5,5,5,5,5,5], [5,5,5,5,5,5], [5,5,5,5,5,5] ]); let trilA = linalg.tril(A); assert.ok(trilA.isEqual(new NDArray([ [5,0,0,0,0,0], [5,5,0,0,0,0], [5,5,5,0,0,0], [5,5,5,5,0,0] ]))); }); }); QUnit.module('triu', () => { QUnit.test('4x4', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let triuA = linalg.triu(A); assert.ok(triuA.isEqual(new NDArray([ [5,5,5,5], [0,5,5,5], [0,0,5,5], [0,0,0,5] ]))); }); QUnit.test('4x4 diag -1', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let triuA = linalg.triu(A,-1); assert.ok(triuA.isEqual(new NDArray([ [5,5,5,5], [5,5,5,5], [0,5,5,5], [0,0,5,5] ]))); }); QUnit.test('4x4 diag +1', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let triuA = linalg.triu(A,1); assert.ok(triuA.isEqual(new NDArray([ [0,5,5,5], [0,0,5,5], [0,0,0,5], [0,0,0,0] ]))); }); QUnit.test('6x4', assert => { let A = new NDArray([ [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5], [5,5,5,5] ]); let triuA = linalg.triu(A); assert.ok(triuA.isEqual(new NDArray([ [5,5,5,5], [0,5,5,5], [0,0,5,5], [0,0,0,5], [0,0,0,0], [0,0,0,0] ]))); }); QUnit.test('4x6', assert => { let A = new NDArray([ [5,5,5,5,5,5], [5,5,5,5,5,5], [5,5,5,5,5,5], [5,5,5,5,5,5] ]); let triuA = linalg.triu(A); assert.ok(triuA.isEqual(new NDArray([ [5,5,5,5,5,5], [0,5,5,5,5,5], [0,0,5,5,5,5], [0,0,0,5,5,5] ]))); }); }); }); QUnit.module('QR', () => { QUnit.test('3x3', assert => { let A = new NDArray([ [3, 6, 2], [1, 7, 6], [9, 3, 2] ]); let [q,r] = linalg.qr(A); assert.ok(q.isEqual(new NDArray([ [-0.31448545, -0.53452248, -0.78446454], [-0.10482848, -0.80178373, 0.58834841], [-0.94345635, 0.26726124, 0.19611614] ]))); assert.ok(r.isEqual(new NDArray([ [-9.53939201, -5.45108115, -3.14485451], [0., -8.01783726, -5.34522484], [0., 0., 2.35339362] ]))); }); QUnit.test('2x2', assert => { let A = new NDArray([ [3,6], [9,2] ]); let [q,r] = linalg.qr(A); assert.ok(q.isEqual(new NDArray([ [-0.31622777, -0.9486833], [-0.9486833, 0.31622777] ]))); assert.ok(r.isEqual(new NDArray([ [-9.48683298, -3.79473319], [0., -5.05964426] ]))); }); QUnit.skip('3x2', assert => { let A = new NDArray([ [3,6], [9,2], [6,7] ]); let [q,r] = linalg.qr(A); assert.ok(q.isEqual(new NDArray([ [-0.26726124, 0.64927181], [-0.80178373, -0.55971708], [-0.53452248, 0.51493971] ]))); console.log(r.toString()); assert.ok(r.isEqual(new NDArray([ [-11.22497216, -6.94879229], [0., 6.3807747] ]))); }); QUnit.skip('2x4', assert => { let A = new NDArray([ [3,6,7,8], [9,2,5,5] ]); let [q,r] = linalg.qr(A); assert.ok(q.isEqual(new NDArray([ [-0.31622777, -0.9486833], [-0.9486833, 0.31622777] ]))); assert.ok(r.isEqual(new NDArray([ [-9.48683298, -3.79473319, -6.95701085, -7.27323862], [0., -5.05964426, -5.05964426, -6.00832755] ]))); }); }); QUnit.module('Eigen', () => { QUnit.test('eig 2x2', assert => { let A = new NDArray([ [3,1], [0,2] ]); let [w,vl,vr] = linalg.eig(A); !vl; // to fix the unused warning assert.ok(w.isEqual(new NDArray([3,2]))); assert.ok(vr.isEqual(new NDArray([ [1, -0.70710678], [0, 0.70710678] ]))); }); QUnit.test('eig 3x3', assert => { let A = new NDArray([ [3,6,2], [1,7,6], [9,3,2] ]); let [w,vl,vr] = linalg.eig(A); !vl; // to fix the unused warning let target_w = new NDArray({shape:[3]}); target_w.set(0, new Complex(-0.56082135, 3.66104822)); target_w.set(1, new Complex(-0.56082135, -3.66104822)); target_w.set(2, 13.12164269); assert.ok(w.isEqual(target_w)); let target_vr = new NDArray({shape:[3,3]}); target_vr.set(0, 0, new Complex(-0.06160653, 0.39509838)); target_vr.set(0, 1, new Complex(-0.06160653, -0.39509838)); target_vr.set(0, 2, -0.49774794); target_vr.set(1, 0, new Complex(-0.45396105, -0.27206987)); target_vr.set(1, 1, new Complex(-0.45396105, 0.27206987)); target_vr.set(1, 2, -0.64721249); target_vr.set(2, 0, 0.74833098); target_vr.set(2, 1, 0.74833098); target_vr.set(2, 2, -0.57737594); assert.ok(vr.isEqual(target_vr)); }); QUnit.test('eig 4x4', assert => { let A = new NDArray([ [3,6,2,1], [1,7,6,1], [9,3,2,1], [9,3,7,1] ]); let [w,vl,vr] = linalg.eig(A); !vl; // to fix the unused warning let target_w = new NDArray({shape:[4]}); target_w.set(0, 14.4616694); target_w.set(1, new Complex(-0.730834679,3.55021966)); target_w.set(2, new Complex(-0.730834679,-3.55021966)); target_w.set(3, 0); assert.ok(w.isEqual(target_w)); let target_vr = new NDArray({shape:[4,4]}); // TODO: // target_vr values at (0,0), (1,0), (2,0), (3,0) should // have opposite signs to match the numpy output target_vr.set(0,0, 0.397234093); target_vr.set(0,1, new Complex(-0.295467105,0.08333459)); target_vr.set(0,2, new Complex(-0.295467105,-0.08333459)); target_vr.set(0,3, 0.0659380473); target_vr.set(1,0, 0.503683695); target_vr.set(1,1, new Complex(-0.0629882747,-0.36737993)); target_vr.set(1,2, new Complex(-0.0629882747,0.36737993)); target_vr.set(1,3, -0.131876095); target_vr.set(2,0, 0.457555861); target_vr.set(2,1, new Complex(0.225571507,0.42219946)); target_vr.set(2,2, new Complex(0.225571507,-0.42219946)); target_vr.set(2,3, 0); target_vr.set(3,0, 0.615751934); target_vr.set(3,1, 0.733269467); target_vr.set(3,2, 0.733269467); target_vr.set(3,3, 0.989070710); assert.ok(vr.isEqual(target_vr)); }); }); QUnit.module('Cholesky', () => { QUnit.test('3x3 1', assert => { let A = new NDArray([ [4,12,-16], [12,37,-43], [-16,-43,98] ]); let chA = linalg.cholesky(A); assert.ok(chA.isEqual(new NDArray([ [2,0,0], [6,1,0], [-8,5,3] ]))) }); QUnit.test('3x3 2', assert => { let A = new NDArray([[2, -1, 0], [-1, 2, -1], [0, -1, 2]]) let chA = linalg.cholesky(A); assert.ok(chA.isEqual(new NDArray([ [1.41421356, 0., 0.], [-0.70710678, 1.22474487, 0.], [0., -0.81649658, 1.15470054] ]))) }); QUnit.test('not positive definite', assert => { let A = new NDArray([ [4, 12, -16], [12, 0, -43], [-16, -43, 98] ]); assert.throws(() => { linalg.cholesky(A); }) }); }); }); }