GithubHelp home page GithubHelp logo

joshmgrant / vectorious Goto Github PK

View Code? Open in Web Editor NEW

This project forked from mateogianolio/vectorious

0.0 2.0 0.0 1.15 MB

A high performance linear algebra library.

License: MIT License

JavaScript 100.00%

vectorious's Introduction

Vectorious

npm version npm downloads travis

Vectorious is a high performance linear algebra library written in Javascript, which can be used both in node.js and the browser.

Installation

Install with npm

$ npm install vectorious

Test with

$ npm test

Run benchmarks with

$ npm run benchmark

For the browser

Download a release and use it like this:

<script src="vectorious-3.0.0.js"></script>
<script>
  // e.g. var vector = new vectorious.Vector()
</script>

Extensions

  • SolveSolves matrix equations of the form Ax = B.
  • PlotGenerates a two-dimensional SVG plot from two input vectors.

Usage

The constructors of both Matrix and Vector are designed to be flexible, so they can be initialized using several different arguments.

Since 2.1.0 Vector implements JavaScript typed arrays for increased performance. The default Vector type is Float64Array, but this can be specified upon creation.

var vectorious = require('vectorious'),
    Vector = vectorious.Vector,
    Matrix = vectorious.Matrix;

var vector,
    matrix;

// Create an empty vector of default type Float64Array
vector = new Vector();
/* Vector { type: [Function: Float64Array], length: 0 } */

// Create an empty vector of type Uint8Array
vector = new Vector(Uint8Array);
/* Vector { type: [Function: Uint8Array], length: 0 } */

matrix = new Matrix();
/* Matrix { type: [Function: Float64Array], shape: [] } */

vector = Vector.zeros(5);
/* Vector {
  type: [Function: Float64Array],
  length: 5,
  buffer: ArrayBuffer {},
  values: Float64Array { '0': 0, '1': 0, '2': 0, '3': 0, '4': 0 } } */

vector = new Vector(1, 2, 3, 4, 5);
/* Vector {
  type: [Function: Float64Array],
  length: 5,
  buffer: ArrayBuffer {},
  values: Float64Array { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 } } */

matrix = new Matrix(vector);
/* Matrix {
  type: [Function: Float64Array],
  shape: [ 5, 1 ],
  data: Float64Array { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 } } */

matrix = Matrix.zeros(2, 2);
/* Matrix {
  shape: [ 2, 2 ],
  data: Float64Array { '0': 0, '1': 0, '2': 0, '3': 0 },
  type: [Function: Float64Array] } */

var input = [
  [1, 2],
  [3, 4]
];

matrix = new Matrix(input);
/* Matrix {
  shape: [ 2, 2 ],
  data: Float64Array { '0': 1, '1': 2, '2': 3, '3': 4 },
  type: [Function: Float64Array] } */

Now that you've got a hang of the basics, let me show you a useful application example.

var time = Vector.range(0, Math.PI / 12, Math.PI);
/* Vector {
  type: [Function: Float64Array],
  length: 12,
  buffer: ArrayBuffer {},
  values:
   Float64Array {
     '0': 0,
     '1': 0.2617993877991494,
     '2': 0.5235987755982988,
     '3': 0.7853981633974483,
     '4': 1.0471975511965976,
     '5': 1.308996938995747,
     '6': 1.5707963267948963,
     '7': 1.8325957145940457,
     '8': 2.0943951023931953,
     '9': 2.356194490192345,
     '10': 2.6179938779914944,
     '11': 2.879793265790644 } } */

var sine = time.map(Math.sin);
/* Vector {
  type: [Function: Float64Array],
  length: 12,
  buffer: ArrayBuffer {},
  values:
   Float64Array {
     '0': 0,
     '1': 0.25881904510252074,
     '2': 0.49999999999999994,
     '3': 0.7071067811865475,
     '4': 0.8660254037844386,
     '5': 0.9659258262890682,
     '6': 1,
     '7': 0.9659258262890684,
     '8': 0.8660254037844387,
     '9': 0.7071067811865476,
     '10': 0.49999999999999994,
     '11': 0.2588190451025206 } } */

For more advanced uses, check out the extensions solve and plot.

Vector

The following vector operations and methods are implemented in vector.js.

// (Vector, Vector) => (Vector)
Vector.add = function(a, b)
Vector.prototype.add = function(vector)

Add two vectors together.

// (Vector, Vector) => (Vector)
Vector.subtract = function(a, b)
Vector.prototype.subtract = function(vector)

Subtract two vectors.

// (Vector, Number) => (Vector)
Vector.prototype.scale = function(scalar)

Multiply a vector by a scalar.

// (Vector) => (Vector)
Vector.prototype.normalize = function()

Normalize a vector.

// (Vector, Vector) => (Number)
Vector.dot = function(a, b)
Vector.prototype.dot = function(vector)

Get dot product of two vectors.

// (Vector) => (Number)
Vector.prototype.magnitude = function()

Get magnitude (norm) of vector.

// (Vector, Vector) => (Angle)
Vector.angle = function(a, b)
Vector.prototype.angle = function(vector)

Get the angle (in radians) between two vectors.

// (Vector, Vector) => (Vector)
Vector.project = function(a, b)
Vector.prototype.project = function(vector)

Project a vector onto another vector.

// (Number) => (Vector)
Vector.zeros = function(count, [type])

Create a vector of count zeros. type is optional and specifies the type of TypedArray used in computations.

// (Number) => (Vector)
Vector.ones = function(count, [type])

Create a vector of count ones. type is optional and specifies the type of TypedArray used in computations.

// (Number, [Number], Number) => (Vector)
Vector.range = function(start, [step], end, [type])

Create a vector containing the range from start to end in steps of step (optional). type is optional and specifies the type of TypedArray used in computations.

// (Vector, Vector) => (Boolean)
Vector.equals = function(a, b)
Vector.prototype.equals = function(vector)

Compare two vectors.

// (Vector, Number) => (Number)
Vector.prototype.get = function(index)

Get value of an element at index.

// (Vector) => (Number)
Vector.prototype.min = function()

Get the minimum value of a vector.

// (Vector) => (Number)
Vector.prototype.max = function()

Get the maximum value of a vector.

// (Vector, Number, Number) => (Vector)
Vector.prototype.set = function(index, value)

Set value of an element at index.

// (Vector, Vector) => (Vector)
Vector.combine = function(a, b)
Vector.prototype.combine = function(vector)

Combines two vectors.

// (Vector, Number) => (Vector)
Vector.prototype.push = function(value)

Pushes value into the vector.

// (Vector, Function) => (Vector)
Vector.prototype.map = function(callback)

Maps a function callback to all elements of the vector.

// (Vector, Function) => (Vector)
Vector.prototype.each = function(callback)

Calls callback(value, index) for each element in the vector.

// (Vector) => (String)
Vector.prototype.toString = function()

Convert vector to string.

// (Vector) => (Array)
Vector.prototype.toArray = function()

Convert vector to array.

Matrix

The following matrix operations and methods are implemented in matrix.js.

// (Matrix, Matrix) => (Matrix)
Matrix.add = function(a, b)
Matrix.prototype.add = function(matrix)

Add two matrices together.

// (Matrix, Matrix) => (Matrix)
Matrix.subtract = function(a, b)
Matrix.prototype.subtract = function(matrix)

Subtract two matrices.

// (Matrix, Number) => (Matrix)
Matrix.prototype.scale = function(scalar)

Multiply all elements in matrix with a scalar.

// (Matrix, Matrix) => (Matrix)
Matrix.multiply = function(a, b)
Matrix.prototype.multiply = function(matrix)

Multiply two matrices together.

// (Matrix) => (Matrix)
Matrix.prototype.transpose = function()

Transpose a matrix.

// (Matrix, Boolean) => (Matrix)
Matrix.prototype.gauss = function()

Convert a matrix to reduced row echelon (RREF) form using Gauss-Jordan eliminiation.

// (Matrix) => ([Matrix, Number])
Matrix.prototype.pivotize = function()

Get the pivot permutation matrix P and corresponding determinant sign in the form of the array [P, sign] (used in LU factorization).

// (Matrix) => ([Matrix, Matrix, [Matrix, Number]])
Matrix.prototype.lu = function()

Get the LU factorization of a matrix in the form of the array [L, U, P], where P is the return value of pivotize().

// (Matrix) => (Matrix)
Matrix.prototype.inverse = function()

Get the inverse of any invertible square matrix using Gauss-Jordan elimination.

// (Matrix) => (Vector)
Matrix.prototype.diag = function()

Get matrix diagonal as a Vector.

// (Matrix, Matrix) => (Matrix)
Matrix.augment = function(a, b)
Matrix.prototype.augment = function(matrix)

Create an augmented matrix.

// (Matrix) => (Number)
Matrix.prototype.trace = function()

Get matrix trace (the sum of the diagonal).

// (Matrix) => (Number)
Matrix.prototype.determinant = function()

Get matrix determinant (note: inefficient for large matrices).

// (Number) => (Matrix)
Matrix.identity = function(size, [type])

Create a size x size identity matrix. type is optional and specifies the type of TypedArray used in computations.

// (Number) => (Matrix)
Matrix.magic = function(size, [type])

Create a size x size magic square matrix. type is optional and specifies the type of TypedArray used in computations.

// (Number, Number) => (Matrix)
Matrix.zeros = function(i, j, [type])

Create an i x j matrix of zeros. type is optional and specifies the type of TypedArray used in computations.

// (Number, Number) => (Matrix)
Matrix.ones = function(i, j, [type])

Create an i x j matrix of ones. type is optional and specifies the type of TypedArray used in computations.

// (Matrix, Matrix) => (Boolean)
Matrix.equals = function(a, b)
Matrix.prototype.equals = function(matrix)

Compare two matrices.

// (Matrix, Number, Number) => (Number)
Matrix.prototype.get = function(i, j)

Get element at row i, column j.

// (Matrix, Number, Number, Number) => (Matrix)
Matrix.prototype.set = function(i, j, value)

Set the value of an element at row i, column j.

// (Matrix, Number, Number) => (Matrix)
Matrix.prototype.swap = function(i, j)

Swaps the position of rows i and j.

// (Matrix, Function) => (Matrix)
Matrix.prototype.map = function(callback)

Maps a function callback to all elements of the matrix.

// (Matrix, Function) => (Matrix)
Matrix.prototype.each = function(callback)

Calls callback(row, index) for each row in the matrix.

// (Matrix) => (String)
Matrix.prototype.toString = function()

Convert matrix to string.

// (Matrix) => (Array)
Matrix.prototype.toArray = function()

Convert matrix to array.

Benchmarks

2.0.0

$ node ./benchmarks/vector.js && node ./benchmarks/matrix.js

a = Vector.ones(1024)
b = Vector.ones(1024).scale(2)

Vector.zeros(1024) x 27,400 ops/sec ±0.47% (94 runs sampled)
Vector.ones(1024) x 26,838 ops/sec ±0.45% (98 runs sampled)
Vector.range(0, 1024) x 32,830 ops/sec ±0.74% (95 runs sampled)
Vector.combine(a, b) x 27,724 ops/sec ±0.36% (99 runs sampled)
a.add(b) x 53,644 ops/sec ±0.41% (100 runs sampled)
a.subtract(b) x 53,582 ops/sec ±0.39% (100 runs sampled)
a.scale(Math.random()) x 10,452 ops/sec ±0.53% (99 runs sampled)
a.normalize() x 5,212 ops/sec ±0.54% (99 runs sampled)
a.dot(b) x 361,011 ops/sec ±0.42% (101 runs sampled)
a.magnitude() x 420,937 ops/sec ±0.44% (101 runs sampled)
a.angle(b) x 132,931 ops/sec ±0.34% (97 runs sampled)
a.project(b) x 5,661 ops/sec ±0.35% (95 runs sampled)

a = Matrix.ones(128, 128)
b = Matrix.ones(128, 128).scale(2)

Matrix.identity(128) x 1,454 ops/sec ±1.84% (92 runs sampled)
Matrix.zeros(128, 128) x 1,482 ops/sec ±2.08% (92 runs sampled)
Matrix.ones(128, 128) x 1,581 ops/sec ±1.15% (96 runs sampled)
Matrix.augment(a, b) x 1,561 ops/sec ±1.32% (96 runs sampled)
a.add(b) x 3,238 ops/sec ±1.10% (97 runs sampled)
a.subtract(b) x 3,224 ops/sec ±1.31% (97 runs sampled)
a.scale(Math.random()) x 586 ops/sec ±1.09% (92 runs sampled)
a.multiply(b) x 25.22 ops/sec ±1.65% (46 runs sampled)
a.transpose() x 817 ops/sec ±2.54% (89 runs sampled)
a.gauss() x 174 ops/sec ±4.27% (65 runs sampled)
a.diag() x 18,717 ops/sec ±2.20% (88 runs sampled)
a.trace() x 19,097 ops/sec ±1.28% (96 runs sampled)

2.1.0

$ node ./benchmarks/vector.js && node ./benchmarks/matrix.js

a = Vector.ones(1024)
b = Vector.ones(1024).scale(2)

Vector.zeros(1024) x 138,658 ops/sec ±4.84% (67 runs sampled)
Vector.ones(1024) x 140,214 ops/sec ±4.75% (66 runs sampled)
Vector.range(0, 1024) x 37,543 ops/sec ±4.80% (81 runs sampled)
Vector.combine(a, b) x 6,120 ops/sec ±2.94% (91 runs sampled)
a.add(b) x 93,725 ops/sec ±7.82% (68 runs sampled)
a.subtract(b) x 95,672 ops/sec ±7.67% (70 runs sampled)
a.scale(Math.random()) x 99,214 ops/sec ±7.74% (72 runs sampled)
a.normalize() x 84,459 ops/sec ±7.32% (72 runs sampled)
a.dot(b) x 501,345 ops/sec ±0.43% (98 runs sampled)
a.magnitude() x 623,274 ops/sec ±0.56% (94 runs sampled)
a.angle(b) x 191,828 ops/sec ±0.52% (92 runs sampled)
a.project(b) x 73,958 ops/sec ±6.82% (79 runs sampled)

a = Matrix.ones(128, 128)
b = Matrix.ones(128, 128).scale(2)

Matrix.identity(128) x 4,042 ops/sec ±5.32% (76 runs sampled)
Matrix.zeros(128, 128) x 4,573 ops/sec ±7.11% (79 runs sampled)
Matrix.ones(128, 128) x 5,480 ops/sec ±2.36% (81 runs sampled)
Matrix.augment(a, b) x 292 ops/sec ±5.06% (78 runs sampled)
a.add(b) x 3,688 ops/sec ±9.16% (68 runs sampled)
a.subtract(b) x 4,299 ops/sec ±4.08% (75 runs sampled)
a.scale(Math.random()) x 4,529 ops/sec ±3.01% (75 runs sampled)
a.multiply(b) x 28.85 ops/sec ±0.80% (52 runs sampled)
a.transpose() x 2,255 ops/sec ±5.07% (78 runs sampled)
a.gauss() x 374 ops/sec ±3.55% (86 runs sampled)
a.diag() x 893 ops/sec ±2.11% (93 runs sampled)
a.trace() x 907 ops/sec ±1.63% (95 runs sampled)

2.2.0

$ npm run benchmark

> [email protected] benchmark /path/to/vectorious
> node ./benchmarks/vector.js && node ./benchmarks/matrix.js

a = Vector.ones(1024)
b = Vector.ones(1024).scale(2)

Vector.zeros(1024) x 135,355 ops/sec ±5.22% (68 runs sampled)
Vector.ones(1024) x 146,065 ops/sec ±5.23% (72 runs sampled)
Vector.range(0, 1024) x 41,358 ops/sec ±3.29% (90 runs sampled)
Vector.combine(a, b) x 6,369 ops/sec ±2.79% (90 runs sampled)
a.add(b) x 95,535 ops/sec ±7.24% (69 runs sampled)
a.subtract(b) x 96,199 ops/sec ±7.31% (72 runs sampled)
a.scale(Math.random()) x 100,021 ops/sec ±7.21% (68 runs sampled)
a.normalize() x 85,098 ops/sec ±7.00% (73 runs sampled)
a.dot(b) x 505,057 ops/sec ±0.38% (99 runs sampled)
a.magnitude() x 627,442 ops/sec ±0.42% (94 runs sampled)
a.angle(b) x 193,797 ops/sec ±0.36% (93 runs sampled)
a.project(b) x 73,280 ops/sec ±6.85% (73 runs sampled)

a = Matrix.ones(128, 128)
b = Matrix.ones(128, 128).scale(2)

Matrix.identity(128) x 4,806 ops/sec ±2.37% (86 runs sampled)
Matrix.magic(128) x 1,161 ops/sec ±5.96% (61 runs sampled)
Matrix.zeros(128, 128) x 5,406 ops/sec ±2.15% (77 runs sampled)
Matrix.ones(128, 128) x 5,495 ops/sec ±2.54% (67 runs sampled)
Matrix.augment(a, b) x 288 ops/sec ±7.03% (75 runs sampled)
a.add(b) x 4,512 ops/sec ±3.26% (78 runs sampled)
a.subtract(b) x 4,539 ops/sec ±3.09% (79 runs sampled)
a.scale(Math.random()) x 4,681 ops/sec ±3.29% (78 runs sampled)
a.multiply(b) x 30.17 ops/sec ±1.01% (54 runs sampled)
a.transpose() x 2,455 ops/sec ±3.29% (83 runs sampled)
a.gauss() x 396 ops/sec ±2.72% (89 runs sampled)
a.diag() x 945 ops/sec ±1.66% (89 runs sampled)
a.trace() x 940 ops/sec ±1.74% (94 runs sampled)

3.0.0

$ npm run benchmark

> [email protected] benchmark /Users/mg/Projects/javascript/vectorious
> node ./benchmarks/vector.js && node ./benchmarks/matrix.js

a = Vector.ones(1024)
b = Vector.ones(1024).scale(2)

Vector.zeros(1024) x 175,737 ops/sec ±3.88% (74 runs sampled)
Vector.ones(1024) x 176,791 ops/sec ±3.55% (75 runs sampled)
Vector.range(0, 1024) x 51,848 ops/sec ±2.50% (85 runs sampled)
Vector.combine(a, b) x 12,330 ops/sec ±2.19% (89 runs sampled)
a.add(b) x 102,070 ops/sec ±8.98% (70 runs sampled)
a.subtract(b) x 101,471 ops/sec ±9.76% (67 runs sampled)
a.scale(Math.random()) x 98,315 ops/sec ±18.46% (62 runs sampled)
a.normalize() x 90,807 ops/sec ±11.18% (68 runs sampled)
a.dot(b) x 675,131 ops/sec ±0.64% (95 runs sampled)
a.magnitude() x 780,969 ops/sec ±4.75% (72 runs sampled)
a.angle(b) x 262,190 ops/sec ±2.46% (90 runs sampled)
a.project(b) x 82,436 ops/sec ±9.08% (70 runs sampled)

data = randomArray(128, 128)
a = Matrix(data)
b = Matrix(data).scale(2)

Matrix.identity(128) x 9,410 ops/sec ±6.46% (77 runs sampled)
Matrix.magic(128) x 2,113 ops/sec ±6.80% (81 runs sampled)
Matrix.zeros(128, 128) x 9,431 ops/sec ±6.51% (80 runs sampled)
Matrix.ones(128, 128) x 9,533 ops/sec ±6.19% (83 runs sampled)
Matrix.augment(a, b) x 3,324 ops/sec ±6.00% (80 runs sampled)
a.add(b) x 9,160 ops/sec ±6.62% (79 runs sampled)
a.subtract(b) x 9,350 ops/sec ±6.23% (85 runs sampled)
a.scale(Math.random()) x 9,605 ops/sec ±6.50% (80 runs sampled)
a.multiply(b) x 207 ops/sec ±1.00% (88 runs sampled)
a.transpose() x 7,366 ops/sec ±4.43% (83 runs sampled)
a.gauss() x 103 ops/sec ±2.37% (54 runs sampled)
a.diag() x 513,075 ops/sec ±7.01% (60 runs sampled)
a.trace() x 412,940 ops/sec ±7.39% (68 runs sampled)

vectorious's People

Contributors

mateogianolio avatar metabench avatar waylonflinn avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.