Permalink
Switch branches/tags
Find file
0b78c60 Nov 6, 2014
@ViralBShah @srikumarks @jakebolewski
434 lines (364 sloc) 10.5 KB
(function () {
'use strict';
var tmin, i, j, t, n, m, s, a, sum, a0, v, r, C;
function assert(t) { if (!t) { throw new Error("assertion failed"); } }
// recursive fib //
function fib(n) {
if (n < 2) { return n; }
return fib(n-1) + fib(n-2);
}
tmin = Number.POSITIVE_INFINITY;
for (i=0; i < 5; i++) {
t = (new Date()).getTime();
for (j=0; j < 1000; j++) {
assert(fib(20) === 6765);
}
t = (new Date()).getTime()-t;
if (t < tmin) { tmin = t; }
}
console.log("javascript,fib," + tmin/1000);
// parse int //
tmin = Number.POSITIVE_INFINITY;
for (i=0; i < 5; i++) {
t = (new Date()).getTime();
for (j=0; j < 1000*1000; j++) {
n = Math.floor(4294967295*Math.random());
s = n.toString(16);
m = parseInt(s,16);
assert(m === n);
}
t = (new Date()).getTime()-t;
if (t < tmin) { tmin = t; }
}
console.log("javascript,parse_int," + tmin/1000);
// mandelbrot set //
function Complex(real, imag) {
this.re = real;
this.im = imag;
}
function complex_abs(z) {
return Math.sqrt(z.re*z.re + z.im*z.im);
}
function complex_add(z,w) {
return new Complex(z.re+w.re, z.im+w.im);
}
function complex_multiply(z,w) {
return new Complex(z.re*w.re-z.im*w.im, z.re*w.im+z.im*w.re);
}
function mandel(z) {
var c, n, maxiter;
c = z;
maxiter = 80;
n = 0;
for (n = 0; n < maxiter; n++) {
if (complex_abs(z) > 2) { return n; }
z = complex_add(complex_multiply(z,z),c);
}
return maxiter;
}
function mandelperf() {
var a, r, re, i, im, z;
a = new Array(26*21);
r = 0;
for (r = 0; r < 26; r++) {
re = -2.0 + r*0.1;
i = 0;
for (i = 0; i < 21; i++) {
im = -1.0 + i*0.1;
z = new Complex(re,im);
a[r*21+i] = mandel(z);
}
}
return a;
}
a = mandelperf();
i = 0;
sum = 0;
for (i = 0; i < a.length; i++) { sum += a[i]; }
assert(sum === 14791);
a0 = a[0];
tmin = Number.POSITIVE_INFINITY;
for (i=0; i < 5; i++) {
t = (new Date()).getTime();
for (j=0; j < 1000; j++) {
a = mandelperf();
assert(a[0] === a0);
}
t = (new Date()).getTime()-t;
if (t < tmin) { tmin=t; }
}
console.log("javascript,mandel," + tmin/1000);
// numeric vector sort //
function rand(n) {
var v, i;
v = new Array(n);
for (i = 0; i < n; i++) {
v[i] = Math.random();
}
return v;
}
function qsort_kernel(a, lo, hi) {
var i, j, pivot, t;
i = lo;
j = hi;
while (i < hi) {
pivot = a[Math.floor((lo+hi)/2)];
while (i <= j) {
while (a[i] < pivot) {
i = i + 1;
}
while (a[j] > pivot) {
j = j - 1;
}
if (i <= j) {
t = a[i];
a[i] = a[j];
a[j] = t;
i = i + 1;
j = j - 1;
}
}
if (lo < j) {
qsort_kernel(a, lo, j);
}
lo = i;
j = hi;
}
}
function sortperf(n) {
var v = rand(n);
qsort_kernel(v, 0, n);
return v;
}
tmin = Number.POSITIVE_INFINITY;
for (i=0; i < 5; i++) {
t = (new Date()).getTime();
for (j=0; j < 100; j++) {
v = sortperf(5000);
assert(a[0] < 0.99);
}
t = (new Date()).getTime()-t;
if (t < tmin) { tmin=t; }
}
console.log("javascript,quicksort," + tmin/100);
// slow pi series //
function pisum() {
var sum, k;
sum = 0.0;
for (i=0; i < 500; i++) {
sum = 0.0;
for (k=1; k <= 10000; k++) {
sum += 1.0/(k*k);
}
}
return sum;
}
tmin = Number.POSITIVE_INFINITY;
for (i=0; i < 5; i++) {
t = (new Date()).getTime();
for (j=0; j < 10; j++) {
assert(Math.abs(pisum()-1.644834071848065) < 1e-12);
}
t = (new Date()).getTime()-t;
if (t < tmin) { tmin=t; }
}
console.log("javascript,pi_sum," + tmin/10);
// random matrix statistics //
function gaussian() {
var k, i, j;
k = 2;
do {
i = 2*Math.random()-1;
j = 2*Math.random()-1;
k = i*i+j*j;
} while (k >= 1);
return i*Math.sqrt((-2*Math.log(k))/k);
}
function randn( a, sub ) {
var subLen, len, i;
subLen = sub.length;
len = a.length;
for (i = 0; i < subLen; i++) {
a[i] = sub[i] = gaussian();
}
for (i = subLen; i < len; i++) {
a[i] = gaussian();
}
return a;
}
function transpose(dest, src,m,n) {
var i, j;
i = 0;
j = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
dest[i*n+j] = src[j*m+i];
}
}
}
function matmulCopy( dest, A,B,m,l,n) {
var i, j, k, sum;
i = 0;
j = 0;
k = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
sum = 0.0;
for (k = 0; k < l; k++) {
sum += A[i*l+k]*B[k*n+j];
}
dest[i*n+j] = sum;
}
}
}
function randmatstat(t) {
var n, P, PTransposed, PMatMul, Q, QTransposed, QMatMul,
a, b, c, d, aSub, bSub, cSub, dSub, v, w, i, j, k,
trP, trQ, v1, v2, w1, w2;
n = 5;
P = new Float64Array( 4*n*n );
Q = new Float64Array( 4*n*n );
PTransposed = new Float64Array( P.length );
QTransposed = new Float64Array( Q.length );
PMatMul = new Float64Array( n*n );
QMatMul = new Float64Array( (2*n) * (2*n) );
a = new Float64Array( n*n );
b = new Float64Array( n*n );
c = new Float64Array( n*n );
d = new Float64Array( n*n );
// the first n number of elements of a to d
aSub = new Float64Array( n );
bSub = new Float64Array( n );
cSub = new Float64Array( n );
dSub = new Float64Array( n );
v = new Float64Array( t );
w = new Float64Array( t );
i = 0;
j = 0;
k = 0;
for (i = 0; i < t; i++) {
a = randn( a, aSub );
b = randn( b, bSub );
c = randn( c, cSub );
d = randn( d, dSub );
P.set( a, 0*n*n );
P.set( b, 1*n*n );
P.set( c, 2*n*n );
P.set( d, 3*n*n );
for (j = 0; j < n; j++) {
Q.set( aSub, 2*n*j );
Q.set( bSub, 2*n*j+n );
Q.set( cSub, 2*n*(n+j) );
Q.set( dSub, 2*n*(n+j)+n );
/*
for (k = 0; k < n; k++) {
Q[ 2*n*j + k ] = a[k];
Q[ 2*n*j+n + k ] = b[k];
Q[ 2*n*(n+j) + k ] = c[k];
Q[ 2*n*(n+j)+n + k ] = d[k];
}
*/
}
transpose( PTransposed, P, n, 4*n );
matmulCopy( PMatMul, PTransposed, P, n, 4*n, n );
matmulCopy( PMatMul, P, P, n, n, n);
matmulCopy( PMatMul, P, P, n, n, n);
trP = 0;
for (j = 0; j < n; j++) {
trP += PMatMul[(n+1)*j];
}
v[i] = trP;
transpose( QTransposed, Q, 2*n, 2*n );
matmulCopy( QMatMul, QTransposed, Q, 2*n, 2*n, 2*n );
matmulCopy( QMatMul, Q, Q, 2*n, 2*n, 2*n);
matmulCopy( QMatMul, Q, Q, 2*n, 2*n, 2*n);
trQ = 0;
for (j = 0; j < 2*n; j++) {
trQ += QMatMul[(2*n+1)*j];
}
w[i] = trQ;
}
v1 = 0.0;
v2 = 0.0;
w1 = 0.0;
w2 = 0.0;
for (i = 0; i < t; i++) {
v1 += v[i]; v2 += v[i]*v[i];
w1 += w[i]; w2 += w[i]*w[i];
}
return {
s1: Math.sqrt((t*(t*v2-v1*v1))/((t-1)*v1*v1)),
s2: Math.sqrt((t*(t*w2-w1*w1))/((t-1)*w1*w1))
};
}
tmin = Number.POSITIVE_INFINITY;
for (i=0; i < 5; i++) {
t = (new Date()).getTime();
for (j=0; j < 10; j++) {
r = randmatstat(1000);
// assert(0.5 < r.s1 < 1.0);
// assert(0.5 < r.s2 < 1.0);
}
t = (new Date()).getTime()-t;
if (t < tmin) { tmin=t; }
}
console.log("javascript,rand_mat_stat," + tmin/10);
// random matrix multiply //
function randFloat64(n) {
var v, i;
v = new Float64Array(n);
for (i = 0; i < n; i++) {
v[i] = Math.random();
}
return v;
}
// Transpose mxn matrix.
function mattransp(A, m, n) {
var i, j, T;
T = new Float64Array(m * n);
for (i = 0; i < m; ++i) {
for (j = 0; j < n; ++j) {
T[j * m + i] = A[i * n + j];
}
}
return T;
}
function matmul(A,B,m,l,n) {
var C, i, j, k, total;
C = new Array(m*n);
i = 0;
j = 0;
k = 0;
// Use the transpose of B so that
// during the matrix multiplication
// we access consecutive memory locations.
// This is a fairer comparison of JS
// with the other languages which call on
// custom multiplication routines, which
// likely make use of such aligned memory.
B = mattransp(B,l,n);
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
total = 0.0;
for (k = 0; k < l; k++) {
total += A[i*l+k]*B[j*l+k];
}
C[i*n+j] = total;
}
}
return C;
}
function randmatmul(n) {
var A, B;
A = randFloat64(n*n);
B = randFloat64(n*n);
return matmul(A, B, n, n, n);
}
tmin = Number.POSITIVE_INFINITY;
t = (new Date()).getTime();
C = randmatmul(1000);
assert(0 <= C[0]);
t = (new Date()).getTime()-t;
if (t < tmin) { tmin=t; }
console.log("javascript,rand_mat_mul," + tmin);
}());