UNPKG

vectorious-plus

Version:

A high performance linear algebra library.

397 lines (320 loc) 12.7 kB
(function() { 'use strict'; var assert = require('assert'), Vector = require('../vector'), Matrix = require('../matrix'); describe('Vector', function() { describe('Vector.randomNormal()', function() { it('should generate true normal distribution', function() { //https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.normal.html var sigma = 0.1, mu = 0; var a = Vector.randomNormal(1000, sigma, mu); var sum = a.reduce(function (sum, value) { return sum + value; }); var mean = sum / a.length; var squareDiffs = a.map(function(value){ var diff = value - mean; var sqrDiff = diff * diff; return sqrDiff; }); var avgSquareDiff = squareDiffs.reduce(function (sum, value) { return sum + value; }) / squareDiffs.length; var stdDev = Math.sqrt(avgSquareDiff); var d1 = Math.abs(mu - mean); var d2 = Math.abs(sigma - stdDev); assert(d1 < 0.01, d1 + " < 0.01"); assert(d2 < 0.01, d2 + " < 0.01"); }); }); describe('Vector.add(a, b)', function() { it('should work as the static equivalent of a.add(b)', function() { var a = new Vector([1, 1, 1]); var b = new Vector([1, 2, 3]); assert.deepEqual(new Vector(a).add(b), Vector.add(a, b)); }); }); describe('Vector.subtract(a, b)', function() { it('should work as the static equivalent of a.subtract(b)', function() { var a = new Vector([2, 3, 4]); var b = new Vector([1, 2, 3]); assert.deepEqual(new Vector(a).subtract(b), Vector.subtract(a, b)); }); }); describe('Vector.dot(a, b)', function() { it('should work as the static equivalent of a.dot(b)', function() { var a = new Vector([2, 3, 4]); var b = new Vector([1, 2, 3]); assert.deepEqual(new Vector(a).dot(b), Vector.dot(a, b)); }); }); describe('Vector.scale(a, scalar)', function() { it('should work as the static equivalent of a.scale(scalar)', function() { var a = new Vector([2, 3, 4]); assert.deepEqual(new Vector(a).scale(5), Vector.scale(a, 5)); }); }); describe('Vector.angle(a, b)', function() { it('should work as the static equivalent of a.angle(b)', function() { var a = new Vector([0, 1, 0]); var b = new Vector([1, 0, 1]); assert.deepEqual(new Vector(a).angle(b), Vector.angle(a, b)); }); }); describe('Vector.equals(a, b)', function() { it('should work as the static equivalent of a.equals(b)', function() { var a = new Vector([0, 1, 0]); var b = new Vector([1, 0, 1]); assert.deepEqual(new Vector(a).equals(b), Vector.equals(a, b)); }); }); describe('Vector.combine(a, b)', function() { it('should work as the static equivalent of a.combine(b)', function() { var a = new Vector([0, 1, 0]); var b = new Vector([1, 0, 1]); assert.deepEqual(new Vector(a).combine(b), Vector.combine(a, b)); }); }); describe('Vector.zeros()', function() { it('should throw error if argument < 0', function() { assert.throws(Vector.zeros.bind(new Vector(), -1), Error); }); it('should return empty vector if argument === 0', function() { assert.deepEqual(new Vector(), Vector.zeros(0)); }); it('should create Vector(0, 0, 0)', function() { assert.deepEqual(new Vector([0, 0, 0]), Vector.zeros(3)); }); }); describe('Vector.ones()', function() { it('should throw error if argument < 0', function() { assert.throws(Vector.ones.bind(new Vector(), -1), Error); }); it('should return empty vector if argument === 0', function() { assert.deepEqual(new Vector(), Vector.ones(0)); }); it('should create Vector(1, 1, 1)', function() { assert.deepEqual(new Vector([1, 1, 1]), Vector.ones(3)); }); }); describe('Vector.prototype', function() { describe('.add()', function() { it('should return empty vector if adding two empty vectors', function() { var a = new Vector(); var b = new Vector(); assert.deepEqual(new Vector(), a.add(b)); }); it('should throw error if sizes do not match', function() { var a = new Vector([1]); var b = new Vector([1, 2]); assert.throws(a.add.bind(a, b), Error); }); it('should produce Vector(5, 7, 9) from Vector(1, 2, 3) and Vector(4, 5, 6)', function() { var a = new Vector([1, 2, 3]); var b = new Vector([4, 5, 6]); var c = new Vector([5, 7, 9]); assert.deepEqual(c, a.add(b)); }); }); describe('.subtract()', function() { it('should return empty vector if subtracting two empty vectors', function() { var a = new Vector(); var b = new Vector(); assert.deepEqual(new Vector(), a.subtract(b)); }); it('should throw error if sizes do not match', function() { var a = new Vector([1]); var b = new Vector([1, 2]); assert.throws(a.subtract.bind(a, b), Error); }); it('should produce Vector(-3, -3, -3) from Vector(1, 2, 3) and Vector(4, 5, 6)', function() { var a = new Vector([1, 2, 3]); var b = new Vector([4, 5, 6]); var c = new Vector([-3, -3, -3]); assert.deepEqual(c, a.subtract(b)); }); }); describe('.scale()', function() { it('should scale Vector(1, 2, 3) by 2 to Vector(2, 4, 6)', function() { var a = new Vector([1, 2, 3]); var b = new Vector([2, 4, 6]); assert.deepEqual(b, a.scale(2)); }); }); describe('.normalize()', function() { it('should work as expected', function() { var a = new Vector([1, 1]); var b = new Vector([1 / Math.sqrt(2), 1 / Math.sqrt(2)]); assert.deepEqual(b, a.normalize()); }); }); describe('.project()', function() { it('should throw error if sizes do not match', function() { var a = new Vector([1]); var b = new Vector([1, 2]); assert.throws(a.project.bind(a, b), Error); }); it('should work as expected', function() { var a = new Vector([2, 1]); var b = new Vector([-3, 4]); var c = new Vector([6 / 25, -8 / 25]); assert.deepEqual(c, a.project(b)); }); }); describe('.range()', function() { it('should throw error if wrong number or arguments supplied', function() { assert.throws(Vector.range.bind(new Vector(), 1), Error); assert.throws(Vector.range.bind(new Vector(), 1, 2, 3, 4), Error); }); it('should throw error if step > start - end', function() { assert.throws(Vector.range.bind(new Vector(), 0, 0), Error); assert.throws(Vector.range.bind(new Vector(), 1, 3, 2), Error); }); it('should work as expected', function() { var a = Vector.range(0, 5); var b = Vector.range(5, 2, 10); var c = Vector.range(5, 0); var d = Vector.range(5, 2, 0); assert.deepEqual(new Vector([0, 1, 2, 3, 4]), a); assert.deepEqual(new Vector([5, 7, 9]), b); assert.deepEqual(new Vector([5, 4, 3, 2, 1]), c); assert.deepEqual(new Vector([5, 3, 1]), d); }); }); describe('.dot()', function() { it('should throw error if sizes do not match', function() { var a = new Vector([1]); var b = new Vector([1, 2]); assert.throws(a.dot.bind(a, b), Error); }); it('should work as expected', function() { var a = new Vector([1, 2, 3]); var b = new Vector([4, 5, 6]); assert.equal(32, a.dot(b)); }); }); describe('.magnitude()', function() { it('should return 0 if empty vector', function() { assert.equal(0, new Vector().magnitude()); }); it('should work as expected', function() { assert.equal(4, new Vector([1, 1, 1, 2, 3]).magnitude()); }); }); describe('.angle()', function() { it('should work as expected', function() { var a = new Vector([1, 0]); var b = new Vector([0, 1]); assert.equal(Math.PI / 2, a.angle(b)); }); }); describe('.equals()', function() { it('should work as expected', function() { assert.equal(true, new Vector([1, 3, 2]).equals(new Vector([1, 3, 2]))); assert.equal(true, new Vector().equals(new Vector())); assert.equal(false, new Vector([1, 2, 3]).equals(new Vector([1, 3, 2]))); }); }); describe('.get()', function() { it('should throw error if index out of bounds', function() { var a = new Vector([1, 2, 3]); assert.throws(a.get.bind(a, -1), Error); assert.throws(a.get.bind(a, 3), Error); }); it('should work as expected', function() { var a = new Vector([1, 3, 2, 4]); assert.equal(1, a.get(0)); assert.equal(3, a.get(1)); assert.equal(2, a.get(2)); assert.equal(4, a.get(3)); }); }); describe('.min()', function() { it('should find the minimum number in vectors', function() { var a = new Vector([1, 2, 3]); var b = new Vector([3, -1, 1]); var c = new Vector([2, 5, 1]); assert.equal(1, a.min()); assert.equal(-1, b.min()); assert.equal(1, c.min()); }); }); describe('.max()', function() { it('should find the maximum number in vectors', function() { var a = new Vector([1, 2, 3]); var b = new Vector([3, -1, 1]); var c = new Vector([2, 5, 1]); assert.equal(3, a.max()); assert.equal(3, b.max()); assert.equal(5, c.max()); }); }); describe('.set()', function() { it('should throw error if index out of bounds', function() { var a = new Vector([1, 2]); assert.throws(a.set.bind(a, -1, 0), Error); assert.throws(a.set.bind(a, 2, 0), Error); }); it('should work as expected', function() { var a = new Vector([1, 2]); a.set(0, 0); a.set(1, 1); assert.equal(0, a.get(0)); assert.equal(1, a.get(1)); }); }); describe('.combine()', function() { it('should return current vector if combined with empty vector', function() { assert.deepEqual(new Vector([1, 2, 3]), new Vector([1, 2, 3]).combine(new Vector())); }); it('should work as expected', function() { assert.deepEqual(new Vector([1, 2, 3, 0, 1]), new Vector([1, 2, 3]).combine(new Vector([0, 1]))); }); }); describe('.push()', function() { it('should start with Vector(1, 2), push(3) to get Vector(1, 2, 3)', function() { assert.deepEqual(new Vector([1, 2, 3]), new Vector([1, 2]).push(3)); }); }); describe('.map()', function() { it('should work as expected', function() { var a = new Vector([1, 2, 3]); var b = a.map(function(value) { return value * value; }); assert.deepEqual(new Vector([1, 4, 9]), b); }); }); describe('.each()', function() { it('should work as expected', function() { var a = new Vector([1, 2, 3]); var b = new Vector(); a.each(function(value, index) { b.push(value * index); }); assert.deepEqual(new Vector([0, 2, 6]), b); }); }); describe('.reduce()', function() { it('should work as expected', function() { function sum(a, b) { return a + b; } var a = new Vector([1, 2, 3]); var b = new Vector([1, 2, 3, 4, 5, 6]); assert.deepEqual(6, a.reduce(sum)); assert.deepEqual(21, b.reduce(sum)); }); }); describe('.toString()', function() { it('should work as expected', function() { assert.equal('[1, 2, 3]', new Vector([1, 2, 3]).toString()); }); }); describe('.toArray()', function() { it('should work as expected', function() { assert.deepEqual([1, 2, 3], new Vector([1, 2, 3]).toArray()); }); }); }); }); })();