simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

xorwow.js (1919B)


      1 // A Javascript implementaion of the "xorwow" prng algorithm by
      2 // George Marsaglia.  See http://www.jstatsoft.org/v08/i14/paper
      3 
      4 (function(global, module, define) {
      5 
      6 function XorGen(seed) {
      7   var me = this, strseed = '';
      8 
      9   // Set up generator function.
     10   me.next = function() {
     11     var t = (me.x ^ (me.x >>> 2));
     12     me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v;
     13     return (me.d = (me.d + 362437 | 0)) +
     14        (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0;
     15   };
     16 
     17   me.x = 0;
     18   me.y = 0;
     19   me.z = 0;
     20   me.w = 0;
     21   me.v = 0;
     22 
     23   if (seed === (seed | 0)) {
     24     // Integer seed.
     25     me.x = seed;
     26   } else {
     27     // String seed.
     28     strseed += seed;
     29   }
     30 
     31   // Mix in string seed, then discard an initial batch of 64 values.
     32   for (var k = 0; k < strseed.length + 64; k++) {
     33     me.x ^= strseed.charCodeAt(k) | 0;
     34     if (k == strseed.length) {
     35       me.d = me.x << 10 ^ me.x >>> 4;
     36     }
     37     me.next();
     38   }
     39 }
     40 
     41 function copy(f, t) {
     42   t.x = f.x;
     43   t.y = f.y;
     44   t.z = f.z;
     45   t.w = f.w;
     46   t.v = f.v;
     47   t.d = f.d;
     48   return t;
     49 }
     50 
     51 function impl(seed, opts) {
     52   var xg = new XorGen(seed),
     53       state = opts && opts.state,
     54       prng = function() { return (xg.next() >>> 0) / 0x100000000; };
     55   prng.double = function() {
     56     do {
     57       var top = xg.next() >>> 11,
     58           bot = (xg.next() >>> 0) / 0x100000000,
     59           result = (top + bot) / (1 << 21);
     60     } while (result === 0);
     61     return result;
     62   };
     63   prng.int32 = xg.next;
     64   prng.quick = prng;
     65   if (state) {
     66     if (typeof(state) == 'object') copy(state, xg);
     67     prng.state = function() { return copy(xg, {}); }
     68   }
     69   return prng;
     70 }
     71 
     72 if (module && module.exports) {
     73   module.exports = impl;
     74 } else if (define && define.amd) {
     75   define(function() { return impl; });
     76 } else {
     77   this.xorwow = impl;
     78 }
     79 
     80 })(
     81   this,
     82   (typeof module) == 'object' && module,    // present in node.js
     83   (typeof define) == 'function' && define   // present with an AMD loader
     84 );
     85 
     86