linalg.js - Linear Algebra for the web.

Linear Algebra Expressions and operator overloading on the web.. or can you ?

Since every post should start with a nice image, here’s a rank 15,10,5 and 2 approximation of an image calculated in javascript :

And here’s the script that generates it :

var img = new Image();
img.src = '../res/testimage.jpg';
img.onload = Matrix(function() {
   var U=Matrix(this), S, V, R;
     for (var i=j; i < S.rows; i++) S[i]=0;               

Hey - wait a minute .. what’s that string line inside the function ? And why is the function wrapped in a Matrix call ?

Lets look at another example to see how linalg.js will make your world easier. and more readable.

// Find the rigid transform that transforms pointset A to pointset B.
// A and B are matrices with nr_of_points rows and nr_of_dimensions columns.
// It returns a square nr_of_dimensions dimensional matrix T so that A*T=B
var findTransform = Matrix(function(A,B){
  var mA, mB, U, S, V, COV;

// Center dataset by subtracting average row..
  "mA = A-A.avg"
  "mB = B-B.avg"

// Calculate covariance matrix.
  "COV = mA'*mB"

// do SVD factorisation on covariance matrix.
  "[U,S,V] = COV.SVD"

// Find transformation that brings A to B
  "return U*V'"

That’s right .. full matrix math, factorisation and operator overloading .. just a string quote away from being javascript..

enter linalg.js

12861 bytes -

All features of linalg.js are accessed through a single global function call, appropriately named ‘Matrix’.

you use it to create matrices ..

// a skinny matrix.
  var A = Matrix([[1,2],[3,4],[5,6],[7,8]]); 

// an empty matrix.
  var B = Matrix(4,2);

// a matrix from an image, video or canvas : 
  var C = Matrix(document.getElementById('myImage'));

Or solve some simple expressions ..

// Solve (x=0,x=1,y=0)
  var solution = Matrix("[[1,0],[1,0],[0,1]]\\[0,1,0]");

// add the transpose of a to b then multiply with c
  var D = Matrix("(A'+B)*C");

// Multiply B with the inverse of A : 
  var E = Matrix("B*A^-1");

// you can store these expressions as functions.
// simpy add the arguments list as second parameter.
  var solve = Matrix("(A'*A)^-1*A'*Y","A,Y"); 
  var solution2 = solve([[1,0],[1,0],[0,1]],[0,1,0]);

or wrap your functions in it ..

.. so that you can put linear algebra expressions between string quotes on their own line ..

var sample = Matrix(function(){
  var A=[[1,0],[1,0],[0,1]];
  var Y=[0,1,0];
  "return A\Y"

var solve = Matrix(function(A,Y){
  var Ai = Matrix(A);
  "Ai = (A'*A)^-1*A'"
  "return Ai*Y"

Together with modern javascript features ..

you can write some pretty readable algebra code.

var fitCubic = Matrix(function (data) {
  var Vandermonde =>[x[0]*x[0]*x[0],x[0]*x[0],x[0],1]);
  var Rhs =>x[1]);
  "return Vandermonde\Rhs"

In just a few lines we can implement various popular least squares methods ..

// Linear Least squares, regularised linear least squares, weighted linear least squares.
var lls  = Matrix("A\\Y","A,Y");
var rlls = Matrix("(A'*A + l*I)^-1*A'*Y","A,Y,I,l");
var wlls = Matrix("(A'*W~*A)^-1*A'*W~*Y","A,Y,W");

// Find intersection of the system ( y=0, x=1, y=2, x=3 )
var A=[[0,1],[1,0],[0,1],[1,0]];
var Y=[0,1,2,3];

// Using linear least squares

// Regularised .. importance of arg size is 0.1

// Weighted .. first two more important.

List of supported operators and functions.

All operators work with Matrix,Vector and Scalar types as appropriate. All functions will upcast their arguments to Matrix objects if needed.

Operator Description Example
+ Overloaded add C=A+B
- Overloaded minus C=A-B
* Overloaded multiply C=A*B
Overloaded transpose B=A’
^ Overloaded pow B=A^-1
~ Diagonalise vector into matrix. A=V~
\ Overloaded solve X=A\Y
() Parentheses D=(A+B)*C


Decomposition Expression
Matrix.factorCholesky(A); C=A.Cholesky
Matrix.factorLU(A); LU=A.LU
Matrix.factorLUP(A); [LU,P]=A.LUP
Matrix.factorSVD(A,S,V); [U,S,V]=A.SVD


Inversion Expression
Matrix.invertLUP(A); B=A^-1


Solver Expression
Matrix.solve(A,Y); X=A\Y


Special Matrices Description
Matrix.identity(x); Identity matrix of size x
Matrix.hankel(V,c); Hankel matrix of column V and count c
Matrix.toHankel(A); Convert to Hankel form
Matrix.toeplitz(V,c); Toeplitz matrix of vector V and count c
Matrix.augment(A,B,AB); Augment A with B


Metrics/Norms Description
Matrix.equals(A,B); compare
Matrix.len(A); length matrix or vector
Matrix.normalize(A); matrix or vector
Matrix.avg(A); return average row.


Utility description
Matrix.cmul(A,B); component wise multiply
Matrix.print(A); pretty console log,htmlElement) Append a matrix as image.
Matrix.row(A,x,c); extract rows from A
Matrix.repeat(r,x); repeat row r x times.


Filters Description
Matrix.blackman(n); Generate blackman vector of size n
Matrix.hamming(n); Generate hamming vector of size n
Matrix.sinc(n,sampling,cutoff); Generate a sinc vector of size n and given sampling and cutoff

Written on April 3, 2017