Skip to content

Instantly share code, notes, and snippets.

@bellbind
Last active August 29, 2015 14:06
Show Gist options
  • Save bellbind/2695c855de084d255e5e to your computer and use it in GitHub Desktop.
Save bellbind/2695c855de084d255e5e to your computer and use it in GitHub Desktop.
[javascript]Mersenne Twister Pseudo Random Number Generator
// Mersenne Twister Random Generator
// see: http://en.wikipedia.org/wiki/Mersenne_twister
var MT = function MT(seed) {
seed = typeof seed === "number" ? seed: Date.now();
var self = Object.create(MT.prototype, {
mt: {value: new Array(MT.N)},
index: {value: 0, writable: true},
});
// initialize from a seed with LCG PRNG
var pre = self.mt[0] = seed & MT.MASK_F;
for (var i = 1; i < MT.N; i++) {
var n = (MT.I * (pre ^ (pre >> MT.Q)) + i) & MT.MASK_F;
pre = self.mt[i] = n;
}
return self;
};
// spec of this MT
MT.P = 199937 // 2^P - 1 cycle
MT.W = 32; // word size
// coefficeints for the MT199937
MT.R = 31;
MT.N = 624;
MT.M = 397;
MT.A = 0x9908b0df;
MT.B = 0x9d2c5680;
MT.C = 0xefc60000;
MT.S = 7;
MT.T = 15;
MT.U = 11;
MT.L = 18;
MT.MASK_F = 0xffffffff; // Math.pow(2, MT.W) - 1
MT.MASK_L = 0x7fffffff; // Math.pow(2, MT.R) - 1
MT.MASK_U = 0x80000000; // MT.MASK_F - MT.MASK_L
// LCG params for initialize
MT.I = 0x6c078965; // well-known better multiplier 1812433253 for LCG
MT.Q = 30; // MT.W - 2
// next random integer
MT.prototype.next = function () {
var mt = this.mt;
if (this.index === 0) {
// generate numbers
for (var k = 0; k < MT.N; k++) {
var n = (mt[k] & MT.MASK_U) | (mt[(k + 1) % MT.N] & MT.MASK_L);
mt[k] = mt[(k + MT.M) % MT.N] ^ (n >> 1) ^ (n % 2 ? MT.A : 0);
}
}
// extract number
var r = mt[this.index];
r ^= (r >> MT.U);
r ^= (r << MT.S) & MT.B;
r ^= (r << MT.T) & MT.C;
r ^= (r >> MT.L);
this.index = (this.index + 1) % MT.N;
return r;
};
// example
var mt = MT(0);
for (var i = 0; i < 10; i++) {
console.log(mt.next());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment