Archive for February, 2009

Launching “Satellite Tracker”

Tuesday, February 24th, 2009

I’m pleased to announce the release of the DTU Space Satellite Tracker. 

The web application tracks satellites in real-time using the new Google Earth Browser Plugin. The current version is in Danish, but an English version is on it’s way.

Track the International Space Station

Mathematica 7 multi-core results

Monday, February 23rd, 2009

Wolfram and our Systems Administrator has been so kind as to give me an 8-core Mathematica 7 license, so the least I could do was to benchmark it. 

A very interesting result is that linearity as you add more CPU’s seem to be quite good, only when you activate the last available core, you see a performance drop. This is naturally explained by the fact the the system needs to run other processes then just Mathematica Kernels.

CPU vs Benchmark Results

 

 

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));