Archive for the ‘Uncategorized’ Category

Linear Algebra in Javascript

Friday, February 20th, 2009

Update: The following code is now part of the jMath library. The implementation has changed into a structure more like the one described for vectors here. Download

Things have gotten serious for Javascript, too serious for this simple language it seems, but nevertheless it still amazes me what people use it for. One of my next projects need a bit of matrix manipulation, and since I couldn’t find any framework for this, I made a few simple functions:


//  A 2d matrix with dim [n,m] with undefined values
function empty(dim) {
	var a = new Array(dim[0]);
	for (var i=0; i < a.length; i++) {
		a[i] = new Array(dim[1]);
	};
	return new matrix(a);
}

// a 2d matrix with dim [n,m] with zeros on all places
function zeros(dim) {
	var a = new empty(dim);
	for (var i=0; i < a.rowlength; i++) {
		for (var j=0; j < a.columnlength; j++) {
			a.mat[i][j] = 0.0;
		};
	};
	return a;
}

// a 2d matrix with ones on all places [n,m]
function ones(dim) {
	var a = new empty(dim);
	for (var i=0; i < a.rowlength; i++) {
		for (var j=0; j < a.columnlength; j++) {
			a.mat[i][j] = 1.0;
		};
	};
	return a;
}

// The square identity matrix of rank dim
function eye(dim) {
	var a = new zeros([dim, dim]);
	for (var i=0; i < a.rowlength; i++) {
		a.mat[i][i] = 1
	};
	return a;
}
function matrix (m) {
	// console.log(m.constructor);
	if (m.constructor == Array) {

		// Get row dimension
		this.rowlength = m.length; 

		// Get column dimension
		this.columnlength = m[0].length;
		for (var i = m.length - 1; i >= 0; i--){
			if (!(m[i].constructor == Array) || !(this.columnlength == m[i].length)) {
				console.log("fail");
				return "Fail, row: " + i + " not valid.";
			};
		};

		// console.log("The matix has the form: " + this.rowlength + "x" + this.columnlength);

		// isSquare?
		if (this.rowlength == this.columnlength) this.isSquare = true;

		this.mat = m;

		// Get Transpose matrix
		this.transpose = function() {
		var ta = new empty([this.columnlength, this.rowlength]);

		for (var i=0; i < this.rowlength; i++) {
			for (var j=0; j < this.columnlength; j++) {
				ta.mat[j][i] = this.mat[i][j];
			};
		};
			return ta;
		};

		// Row exchange
		this.rowex = function(i,j) {
			var tmp = this.mat[i];
			this.mat[i] = this.mat[j];
			this.mat[j] = tmp;
		};

		// Row multiplication
		this.rowmul = function(row,scalar) {
			for (var i=0; i < this.mat[row].length; i++) {
				this.mat[row][i] = scalar * this.mat[row][i];
			};
		};

		// Row addition
		this.rowadd = function(row,other,scalar) {
			for (var i=0; i < this.mat[row].length; i++) {
				this.mat[row][i] = this.mat[row][i] +  scalar*this.mat[other][i];
			};
		};

	};

}

function print (matrix) {
	var html = "|table|";
	for (var i=0; i < matrix.rowlength; i++) {
		html+= "|tr|";
		for (var j=0; j < matrix.columnlength; j++) {
			html+= "|td|" + matrix.mat[i][j] + "|/td|";
		};
		html+="|tr|";
	};
	html += "|table|";
	return html;
}
// Matrix multiplication
function mul (A,B) {

	if (B.constructor == matrix && A.constructor == matrix)
	if (A.columnlength == B.rowlength) {

		var C = new zeros([A.rowlength, B.columnlength]);

		// naive alg.
		for (var i=0; i < C.rowlength; i++) {
			for (var j=0; j < C.columnlength; j++) {
				for (var k=0; k < A.columnlength; k++) {
					C.mat[i][j] = C.mat[i][j] + A.mat[i][k] * B.mat[k][j];
				};
			};
		};
		return C;

	} else if (A.constructor == matrix && B.constructor == Number) {
		console.log("Warning doing scalar multiplication of A*b");
		return scalar(A,B);
	} else {
		return -1;
	}
}

function scalar (A,b) {
	var B = new empty([A.rowlength, A.columnlength]);
	for (var i=0; i < A.rowlength; i++) {
		for (var j=0; j < A.columnlength; j++) {
			B.mat[i][j] = A.mat[i][j]*b;
		};
	};
	return B;
}

function add (A,B) {
	if (A.columnlength == B.columnlength && A.rowlength == B.rowlength) {
		// Add A + B
		var C = new empty([A.rowlength, B.columnlength]);
		for (var i=0; i < C.rowlength; i++) {
			for (var j=0; j < C.columnlength; j++) {
				C.mat[i][j] = A.mat[i][j] + B.mat[i][j];
			};
		};
		return C;
	} else {
		return -1;
	}
}
function sub (A,B) {
	if (A.columnlength == B.columnlength && A.rowlength == B.rowlength) {
		// Add A + B
		var C = new empty([A.rowlength, B.columnlength]);
		for (var i=0; i < C.rowlength; i++) {
			for (var j=0; j < C.columnlength; j++) {
				C.mat[i][j] = A.mat[i][j] - B.mat[i][j];
			};
		};
		return C;
	} else {
		return -1;
	}
}

////////// Examples ////////////////

// 2 x 2 Matrix
var  A = new matrix([[1,2],
			      [3,4]]);

console.log(A.mat);

//// Elementary Matrix operations ////

// Exchange row 0 and 1
A.rowex(0,1);
console.log(A.mat);

// Scalar multiply row 0 with 2
A.rowmul(0,2);
console.log(A.mat);

// Add row 1 times -4 to row 0
A.rowadd(0,1,-4);
console.log(A.mat);

// Matrix operations

var  B = new matrix([[2,6],
			      [4,3]]);

// Matrix multiply A and B
var C = mul(A,B)
console.log(C.mat);

// Identity matrix 2x2
var D = eye(2);
console.log(D.mat);

// Transpose A
var B = A.transpose();
console.log(B.mat);

// Matrix multiply A times 2*B
var k = mul(A,scalar(D,2));
console.log(k.mat);

// Html table of A
console.log(print(A));

Christmas after Christmas, Or: My New Workstation

Wednesday, January 7th, 2009

I have a very interesting relationship with the Danish Space Institute. I’m not hired but serve as an external consultant in development and multimedia projects. One of the perks in this tight relationship is that I have office space close to the university which came in handy before I started my Master studies (now I have a desk anyway). Now this office is part of the communication department where, lately, HD video have become the new hotness, and just before christmas I was tasked to figure out what kind of platform would be nice for some semi-serious video editing. Low and behold, they listend, bought and placed the following on my desk this morning:

Apple Pro

2 x 2.8 GHz Quad Xeon
10 GB FB-RAM 
4 x 1TB SATA
Apple Hardware RAID Controller (256 MB cache)
ATI Radeon HD 3870 (512 MB Framebuffer)
2 x 24″ Dell 2408WFP LCD

And a couple of boxes containing Logic Studio and Final Cut Studio. (CS4 Master suite should be on its way)

What can I say, I’m a nerd and like shining things, this is both :D

 


The Difference [xkcd]

Saturday, December 13th, 2008

The Difference between a normal person and a Scientist.

The state of the world

Friday, December 12th, 2008

I know this isn’t new, but it captures all my ramblings in a near perfect composition.
If you know me, nearly every single point in this movie is something I have been thinking about quite a lot doing the last 10 years, so it’s amazing to see others agreeing at such a level!

Zeitgeist

And here is a link free of charge: The Venus Project