2017-04-06 13:49:58 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2017-04-06 10:22:57 +00:00
|
|
|
|
|
|
|
/*
|
2017-04-06 13:49:58 +00:00
|
|
|
* JavaScript version of Mersenne Twister
|
|
|
|
*
|
|
|
|
* @author Yasuharu Okada
|
|
|
|
*
|
|
|
|
*/
|
2017-04-06 10:22:57 +00:00
|
|
|
|
2017-04-06 13:49:58 +00:00
|
|
|
function MersenneTwister()
|
2017-04-06 10:22:57 +00:00
|
|
|
{
|
|
|
|
const N = 624;
|
|
|
|
const M = 397;
|
2017-04-06 13:49:58 +00:00
|
|
|
const UPPER_MASK = 0x80000000;
|
|
|
|
const LOWER_MASK = 0x7fffffff;
|
2017-04-06 10:22:57 +00:00
|
|
|
const MAG01 = new Int32Array([0, 0x9908b0df]);
|
|
|
|
|
2017-04-10 17:36:38 +00:00
|
|
|
let mt = new Int32Array(N); /* the array for the state vector */
|
|
|
|
let mti = 625;
|
2017-04-06 10:22:57 +00:00
|
|
|
|
|
|
|
this.seed = function (s) {
|
|
|
|
mt[0] = s | 0;
|
2017-04-06 13:49:58 +00:00
|
|
|
for (mti = 1; mti < N; mti++) {
|
|
|
|
mt[mti] = Math.imul(1812433253, mt[mti - 1] ^ (mt[mti - 1] >>> 30)) + mti;
|
2017-04-06 10:22:57 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-04-06 13:49:58 +00:00
|
|
|
this.export_state = function() {
|
|
|
|
return [mt, mti];
|
|
|
|
};
|
2017-04-06 10:22:57 +00:00
|
|
|
|
2017-04-06 13:49:58 +00:00
|
|
|
this.import_state = function(s) {
|
|
|
|
mt = s[0];
|
|
|
|
mti = s[1];
|
|
|
|
};
|
|
|
|
|
|
|
|
this.export_mta = function() {
|
|
|
|
return mt;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.import_mta = function(_mta) {
|
|
|
|
mt = _mta;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.export_mti = function() {
|
|
|
|
return mti;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.import_mti = function(_mti) {
|
|
|
|
mti = _mti;
|
|
|
|
};
|
2017-04-06 10:22:57 +00:00
|
|
|
|
|
|
|
this.int32 = function () {
|
2017-04-10 17:36:38 +00:00
|
|
|
let y, kk;
|
2017-04-06 10:22:57 +00:00
|
|
|
|
|
|
|
if (mti >= N) { /* generate N words at one time */
|
2017-04-06 13:49:58 +00:00
|
|
|
for (kk = 0; kk < N-M; kk++) {
|
|
|
|
y = ((mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK));
|
|
|
|
mt[kk] = (mt[kk+M] ^ (y >>> 1) ^ MAG01[y & 0x1]);
|
2017-04-06 10:22:57 +00:00
|
|
|
}
|
2017-04-06 13:49:58 +00:00
|
|
|
for (; kk < N-1; kk++) {
|
|
|
|
y = ((mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK));
|
|
|
|
mt[kk] = (mt[kk+(M-N)] ^ (y >>> 1) ^ MAG01[y & 0x1]);
|
2017-04-06 10:22:57 +00:00
|
|
|
}
|
2017-04-06 13:49:58 +00:00
|
|
|
y = ((mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK));
|
|
|
|
mt[N-1] = (mt[M-1] ^ (y >>> 1) ^ MAG01[y & 0x1]);
|
2017-04-06 10:22:57 +00:00
|
|
|
mti = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
y = mt[mti++];
|
|
|
|
|
|
|
|
/* Tempering */
|
|
|
|
y = y ^ (y >>> 11);
|
|
|
|
y = y ^ ((y << 7) & 0x9d2c5680);
|
|
|
|
y = y ^ ((y << 15) & 0xefc60000);
|
|
|
|
y = y ^ (y >>> 18);
|
|
|
|
|
2017-04-11 21:43:09 +00:00
|
|
|
return y >>> 0;
|
2017-04-06 10:22:57 +00:00
|
|
|
};
|
2017-04-06 13:49:58 +00:00
|
|
|
|
2017-04-06 14:32:07 +00:00
|
|
|
this.real2 = function () {
|
2017-04-06 14:18:36 +00:00
|
|
|
return this.int32() * (1.0 / 4294967296.0);
|
2017-04-11 21:43:09 +00:00
|
|
|
};
|
2017-04-06 10:22:57 +00:00
|
|
|
}
|