• Stars
    star
    162
  • Rank 232,284 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 10 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Efficient, high-performance linear algebra for node.js and browsers

linear-algebra

Build Status

NOTE: If you're serious about doing machine learning in the browser I recommend using deeplearn.js

Efficient, high-performance linear algebra library for node.js and browsers.

This is a low-level algebra library which supports basic vector and matrix operations, and has been designed with machine learning algorithms in mind.

Features:

Installation

CommonJS

Install using npm:

$ npm install linear-algebra

Browser

Include dist/linear-algebra.js script into your HTML.

In the browser the library is exposed via the linearAlgebra() function.

How to use

Since linear algebra calculations tend to be CPU-intensive it is highly recommended that you run them within a separate thread or process. For browsers this means using a web worker. For node.js there are plenty of similar solutions available.

Initialisation

The examples below assume you are running in node.js. The library needs to be initialised once loaded:

var linearAlgebra = require('linear-algebra')(),     // initialise it
    Vector = linearAlgebra.Vector,
    Matrix = linearAlgebra.Matrix;

Note that both matrices and vectors are represented by Matrix instances. The Vector object simply contains helpers to create single-row Matrix objects.

In-place methods

Matrix operations which result in a new matrix are implemented as two methods - a default method which returns a new Matrix instance and an in-place method which causes the original to be overwritten. In some cases you may obtain better performance if you switch to the in-place version, and vice versa.

The in-place version of a method is named as the original method but with an additional _ suffix:

var m = new Matrix([ [1, 2, 3], [4, 5, 6] ]);

// default
var m2 = m.mulEach(5);   // multiply every element by 5
m2 === m;  // false

// in-place
var m2 = m.mulEach_(5); // notice the _ suffix
m2 === m;  // true

Using the in-place version of a method may not always yield a performance improvement. You can run the performance benchmarks to see examples of this.

API

var m, m2, m3;  // variables we'll use below

/* Construction */

m = new Matrix([ [1, 2, 3], [4, 5, 6] ]);
console.log( m.rows );     // 2
console.log( m.cols );     // 3
console.log( m.data );     // [ [1, 2, 3], [4, 5, 6] ]

// identity matrix
m = Matrix.identity(3);
console.log( m.data );     // [ [1,0,0], [0,1,0], [0,0,1] ]

// scalar (diagonal) matrix
m = Matrix.scalar(3, 9);
console.log( m.data );     // [ [9,0,0], [0,9,0], [0,0,9] ]

// zeros
m = Matrix.zero(3, 2);
console.log( m.data );     // [ [0, 0], [0, 0], [0, 0] ]

// reshape from array
m = Matrix.reshapeFrom([1, 2, 3, 4, 5, 6], 2, 3);
console.log( m.data );     // [ [1, 2, 3,], [4, 5, 6] ]

// vector (a 1-row matrix)
m = Vector.zero(5);
console.log( m.data );     // [ [0, 0, 0, 0, 0] ]


/* Algebra */

// transpose
m = new Matrix([ [1, 2, 3], [4, 5, 6] ]);
m2 = m.trans();
console.log(m2.data);    // [ [1, 4], [2, 5], [3, 6] ]

// dot-product
m = new Matrix([ [1, 2, 3], [4, 5, 6] ]);
m2 = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m3 = m.dot(m2);
console.log(m3.data);    // [ [22, 28], [49, 64] ]

// multiply corresponding elements
m = new Matrix([ [10, 20], [30, 40], [50, 60] ]);
m2 = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m3 = m.mul(m2);
console.log(m3.data);    // [ [10, 40], [90, 160], [250, 360] ]

// divide corresponding elements
m = new Matrix([ [10, 20], [30, 40], [50, 60] ]);
m2 = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m3 = m.div(m2);
console.log(m3.data);    // [ [10, 10], [10, 10], [10, 10] ]

// add corresponding elements
m = new Matrix([ [10, 20], [30, 40], [50, 60] ]);
m2 = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m3 = m.plus(m2);
console.log(m3.data);    // [ [11, 22], [33, 44], [55, 66] ]

// subtract corresponding elements
m = new Matrix([ [10, 20], [30, 40], [50, 60] ]);
m2 = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m3 = m.minus(m2);
console.log(m3.data);    // [ [9, 18], [27, 36], [45, 54] ]


/* Math functions */

// natural log (Math.log)
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.log();
console.log(m2.data);    // [ [0.0000, 0.69315], [1.09861, 1.38629], [1.60944   1.79176] ]

// sigmoid
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.sigmoid();
console.log(m2.data);    // [ [0.73106, 0.88080], [0.95257, 0.98201], [0.99331, 0.99753] ]

// add value to each element
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.plusEach(5);
console.log(m2.data);    // [ [6, 7], [8, 9], [10, 11] ]

// multiply each element by value
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.mulEach(5);
console.log(m2.data);    // [ [5, 10], [15, 20], [25, 30] ]

// any function
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.map(function(v) {
    return v - 1;    
});
console.log(m2.data);    // [ [0, 1], [2, 3], [4, 5] ]

// any function with row and column passed-in
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.eleMap(function(v, row, col) {
    return (0 === row && 1 === col ? v : v * 2 + 1);    
});
console.log(m2.data);    // [ [1, 1], [7, 9], [11, 13] ]


/* Calculations */

// sum all elements
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
console.log(m.getSum());    // 21


/* Other methods */

// cloning
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.clone();
console.log( m2.data ); // [ [1, 2], [3, 4], [5, 6] ]

// to plain array
m = new Matrix([ [1, 2], [3, 4], [5, 6] ]);
m2 = m.toArray();
console.log( m2 ); // [ [1, 2], [3, 4], [5, 6] ]

Higher precision

When adding floating point numbers together the end result is sometimes off by a minor decimal point (to see this try 0.1 + 0.2 in your JS console).

This module allows you to supply a custom adder (e.g. add) as an option to the initialization call.

In node.js:

// we pass the 'add' function in as a parameter...
var linAlg = require('linear-algebra')({
    add: require('add')
}),
    Vector = linAlg.Vector,
    Matrix = linAlg.Matrix;

In the browser you will need to load in the higher-precision version of the library to be able to do this:

<script type="text/javascript" src="add.js" />
<script type="text/javascript" src="linear-algebra.precision.js" />
<script type="text/javascript">
var linAlg = linearAlgebra({
    add: add
}),
    Vector = linAlg.Vector,
    Matrix = linAlg.Matrix;
</script>

Note: If you use the higher-precision version of the library with a custom adder then expect performance to drop significantly for some matrix operations.

Performance

Performance vs. similar modules:

[17:23:14] Running suite vs. other modules [/Users/home/dev/js/linear-algebra/benchmark/vs-other-modules.perf.js]...
[17:23:20]    Matrix dot-product (100x100) - linear-algebra x 288 ops/sec ±1.21% (88 runs sampled)
[17:23:25]    Matrix dot-product (100x100) - sylvester x 56.77 ops/sec ±4.51% (61 runs sampled)
[17:23:25] Fastest test is Matrix dot-product (100x100) - linear-algebra at 5.1x faster than Matrix dot-product (100x100) - sylvester

To run the performance benchmarks:

$ npm install -g gulp
$ npm install
$ gulp benchmark

Matrix operations which result in a new matrix are implemented as two methods - a default method which returns a new Matrix instance and an in-place method which causes the original to be overwritten.

The in-place versions are provided because - general speaking- memory allocations and garbage collection are expensive operations you don't want happening when you're performing lots of calculations. Overwriting an existing array is twice as fast as creating a new one. And since changing the size of an array is also an expensive operation, even if a matrix operation results in a smaller matrix than before the internal array is kept at the same size:

var m = new Matrix([ [1, 2, 3], [4, 5, 6] ]);
var m2 = new Matrix([ [7], [8], [9] ]);

m.dot_(m2);

console.log( m.data );  // [ [43, 2, 3], [112, 5, 6] ]
console.log( m.rows );  // 2
console.log( m.cols );  // 1

The in-place versions attempt to limit memory allocations as much as possible and therefore ought to be faster. However, this may not be true for all the matrix operations contained in this library.

If you're dealing with large matrices (>100 rows, columns) then you're more likely to see a benefit from using the in-place versions of methods:

[14:38:35] Running suite Default (new object) vs in-place modification [/Users/home/dev/js/linear-algebra/benchmark/default-vs-in-place.perf.js]...
[14:38:41]    Matrix dot-product (5x5) - default x 1,114,666 ops/sec ±0.94% (96 runs sampled)
[14:38:46]    Matrix dot-product (5x5) - in-place x 721,296 ops/sec ±2.95% (94 runs sampled)
[14:38:52]    Matrix dot-product (100x100) - default x 269 ops/sec ±3.75% (88 runs sampled)
[14:38:57]    Matrix dot-product (100x100) - in-place x 283 ops/sec ±0.94% (93 runs sampled)
[14:39:09]    Matrix dot-product (500x500) - default x 1.40 ops/sec ±9.96% (8 runs sampled)
[14:39:20]    Matrix dot-product (500x500) - in-place x 1.45 ops/sec ±4.30% (8 runs sampled)
[14:39:26]    Matrix transpose (1000x5) - default x 13,770 ops/sec ±3.00% (91 runs sampled)
[14:39:31]    Matrix transpose (1000x5) - in-place x 9,736 ops/sec ±2.44% (87 runs sampled)
[14:39:37]    Multiple matrix operations - default x 218 ops/sec ±2.57% (88 runs sampled)
[14:39:42]    Multiple matrix operations - in-place x 222 ops/sec ±0.71% (89 runs sampled)

Building

To build the code and run the tests:

$ npm install -g gulp
$ npm install
$ gulp

Contributing

Contributions are welcome! Please see CONTRIBUTING.md.

License

MIT - see LICENSE.md

More Repositories

1

squel

🏢 SQL query string builder for Javascript
CoffeeScript
1,566
star
2

fast-levenshtein

Efficient Javascript implementation of Levenshtein algorithm with locale-specific collator support.
JavaScript
580
star
3

google-tts

Javascript API for the Google Text-to-Speech engine
JavaScript
312
star
4

robe

MongoDB ODM for Node.js using ES6 generators. Supports schema validation, raw querying, oplog tailing, etc.
JavaScript
178
star
5

melkor

Wiki powered by Node.js and Git
JavaScript
149
star
6

ansijet

Ansible playbook automation server
CSS
110
star
7

react-native-modal-filter-picker

Cross-platform modal picker for React Native which supports keyword filtering, custom rendering, etc
JavaScript
104
star
8

gulp-server-livereload

Gulp plugin to run a local webserver with livereload enabled via socket.io. Also comes with standalone command-line interface.
JavaScript
92
star
9

cordova-plugin-filepath

Resolve native file paths from content URLs for Cordova platforms
Java
66
star
10

geth-private

Quickly setup a local, private Ethereum blockchain.
JavaScript
60
star
11

ethereum-abi-ui

Auto-generate UI form field definitions and associated validators from an Ethereum contract ABI
JavaScript
58
star
12

ethereum-event-logs

Ethereum event logs parser
JavaScript
48
star
13

browsermail

Javascript IMAP email client for browsers
JavaScript
47
star
14

mailmask

Mailmask - easy stop unwanted email. Unlimited, free temporary email addresses, all forwarding to your real email address. Beat spam, protect your privacy.
JavaScript
39
star
15

lzw-async

Asynchronous Javascript implementation of LZW compression algorithm
HTML
38
star
16

wp-flickr-embed

Insert Flickr images into your Wordpress posts using an interactive interface
PHP
19
star
17

gulp-bench

Gulp plugin for running performance benchmarks
JavaScript
17
star
18

react-image-holder

React image component with offline placeholder fallbacks
JavaScript
17
star
19

koa-session-mongo

MongoDB storage layer for Koa session middleware
JavaScript
16
star
20

ethval

Easier calculation and formatting of Ethereum values
JavaScript
16
star
21

weber

Compile scripts, stylesheets and templates on-the-fly for rapid iterations
CoffeeScript
14
star
22

ethereum-contracts

Robust Ethereum contracts wrapper for easier deployment, method invocation and automatic type conversion.
JavaScript
14
star
23

clockmaker

Flexible Javascript timers which can be paused and modified on-the-fly
JavaScript
13
star
24

react-native-advanced-forms

Flexible React Native architecture for building and managing forms
JavaScript
13
star
25

koa-session-store

Session middleware for Koa with a pluggable storage layer
JavaScript
12
star
26

simple-mongo-schema

DEPRECATED. An easy-to-write schema validator for Mongo JSON objects
JavaScript
12
star
27

sjv

🚦 An easy-to-write schema and deep validator for JSON documents
JavaScript
11
star
28

ethereum-blocks

Process blocks from Ethereum client nodes robustly. Catch-up on restart, auto-reconnect to node, etc.
JavaScript
11
star
29

git-pull-cron

Git clone a repo into a folder and then schedule a cronjob to git pull updates
JavaScript
10
star
30

machine-learning

High-performance machine learning library for node.js and browsers
JavaScript
8
star
31

jquery.ajaxprogress

jQuery AJAX Progress plugin
JavaScript
8
star
32

drush_simpletest_command

An improved Drush SimpleTest command which allows you to run a single Drupal test from the command-line
7
star
33

elrond-voting-contract

Commit-reveal voting contract written in Rust for Elrond VM
Rust
6
star
34

page-tagger

A Wordpress plugin which lets you tag your pages just like you do with your posts
PHP
6
star
35

immutable-state-machine

Immutable state machine for Javascript with ability to associate extra data with each state. Useful for React.
JavaScript
6
star
36

askthensa

http://askthensa.com
5
star
37

ethereum-token-sales

Various Ethereum token sale contracts
5
star
38

mongo-replica-set

Command-line tool and API for setting up MongoDB replica sets on localhost
JavaScript
5
star
39

cron-async

Execute something on a schedule, using cron syntax, with async/await support.
TypeScript
4
star
40

patterns2

An improved version of the Drupal Patterns module.
PHP
4
star
41

es6-slides

Slides on the new features in Javascript ES6
JavaScript
4
star
42

react-native-extended-stylesheet-breakpoints

Smart responsive @media query generation for react-native-extended-stylesheets using configurable breakpoints
JavaScript
4
star
43

opengraph_meta

Drupal module which adds Open Graph meta tags to node pages for better social network sharing (e.g. http://developers.facebook.com/docs/share)
PHP
3
star
44

mocha-ci-slack-reporter

Slack reporter for Mocha when running in CI environments
JavaScript
2
star
45

ois-incidents-map

Officer-involved Shootings map of the USA
JavaScript
2
star
46

react-hooks

A collection of useful React hooks for async programming, web3, etc
TypeScript
2
star
47

node-generator-perf-tests

Some performance tests for when using generators in node.js
JavaScript
2
star
48

zhongwen

The source code to the zhongwen.co.uk website
JavaScript
2
star
49

ethanol

Desktop Solidity IDE **Work in progress**
JavaScript
2
star
50

react-native-xcode-packager

Custom XCode packager script for react-native which ensure bundle always gets built
Shell
2
star
51

logarama

Logging for the browser, logging levels, hierarchical child loggers, smart formatting, etc
JavaScript
2
star
52

documentation-lite

Extract JSDoc documentation from ES5/ES6 files into a JSON output structure.
JavaScript
2
star
53

us_latlng_json

JSON dataset of latitude and longitude co-ordinates for USA state counties and cities
2
star
54

abide

Base class with pub-sub and observers for JS object properties using ECMA5 getters/setters
JavaScript
2
star
55

genomatic

Utility methods for working with Generator functions, such as bind(), is(), etc
JavaScript
1
star
56

ethgoal

Goal achievement powered by Ethereum
JavaScript
1
star
57

phonegap-demo-app

CSS
1
star
58

indium

Reactive web framework for Node.js utilising RethinkDB and ReactJS
1
star
59

updates_notifier

Redmine plugin which update notifications to a callback URL when changes are made within Redmine
Ruby
1
star
60

saffronvideo

A Drupal module to make it easy to use Saffron media server assets.
PHP
1
star
61

smart-solidity-docs

Getting to grips with the Solidity programming language for the Ethereum blockchain
1
star
62

docjam

Javascript ES6 documentation extractor using markdown and jsdoc
JavaScript
1
star
63

method-mocks

Works with existing mocking and testing frameworks (e.g. Jest) to make method mocking easier.
JavaScript
1
star
64

hiddentao.com

HiddenTao website
JavaScript
1
star
65

nodejs-intro

Introduction to Node.js - building a chatroom using ExpressJS and Socket.IO
JavaScript
1
star
66

i21n

Tiny internationalization library for Node and the Browser
JavaScript
1
star
67

bulksms

BulkSMS API for TextAnywhere service
PHP
1
star
68

calc

Simple HTML5 calculator
HTML
1
star
69

uc_bulk_stock_updater

This is a Ubercart (Drupal) extension module which enables you to easily product stock levels on one page.
JavaScript
1
star
70

latlong-route-cleaner

Simple PHP script for cleaning out bad lat-long points form a driving route
PHP
1
star