simple-squiggle

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

xorshift7.js (2418B)


      1 // A Javascript implementaion of the "xorshift7" algorithm by
      2 // François Panneton and Pierre L'ecuyer:
      3 // "On the Xorgshift Random Number Generators"
      4 // http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf
      5 
      6 (function(global, module, define) {
      7 
      8 function XorGen(seed) {
      9   var me = this;
     10 
     11   // Set up generator function.
     12   me.next = function() {
     13     // Update xor generator.
     14     var X = me.x, i = me.i, t, v, w;
     15     t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24);
     16     t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10);
     17     t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3);
     18     t = X[(i + 4) & 7]; v ^= t ^ (t << 7);
     19     t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9);
     20     X[i] = v;
     21     me.i = (i + 1) & 7;
     22     return v;
     23   };
     24 
     25   function init(me, seed) {
     26     var j, w, X = [];
     27 
     28     if (seed === (seed | 0)) {
     29       // Seed state array using a 32-bit integer.
     30       w = X[0] = seed;
     31     } else {
     32       // Seed state using a string.
     33       seed = '' + seed;
     34       for (j = 0; j < seed.length; ++j) {
     35         X[j & 7] = (X[j & 7] << 15) ^
     36             (seed.charCodeAt(j) + X[(j + 1) & 7] << 13);
     37       }
     38     }
     39     // Enforce an array length of 8, not all zeroes.
     40     while (X.length < 8) X.push(0);
     41     for (j = 0; j < 8 && X[j] === 0; ++j);
     42     if (j == 8) w = X[7] = -1; else w = X[j];
     43 
     44     me.x = X;
     45     me.i = 0;
     46 
     47     // Discard an initial 256 values.
     48     for (j = 256; j > 0; --j) {
     49       me.next();
     50     }
     51   }
     52 
     53   init(me, seed);
     54 }
     55 
     56 function copy(f, t) {
     57   t.x = f.x.slice();
     58   t.i = f.i;
     59   return t;
     60 }
     61 
     62 function impl(seed, opts) {
     63   if (seed == null) seed = +(new Date);
     64   var xg = new XorGen(seed),
     65       state = opts && opts.state,
     66       prng = function() { return (xg.next() >>> 0) / 0x100000000; };
     67   prng.double = function() {
     68     do {
     69       var top = xg.next() >>> 11,
     70           bot = (xg.next() >>> 0) / 0x100000000,
     71           result = (top + bot) / (1 << 21);
     72     } while (result === 0);
     73     return result;
     74   };
     75   prng.int32 = xg.next;
     76   prng.quick = prng;
     77   if (state) {
     78     if (state.x) copy(state, xg);
     79     prng.state = function() { return copy(xg, {}); }
     80   }
     81   return prng;
     82 }
     83 
     84 if (module && module.exports) {
     85   module.exports = impl;
     86 } else if (define && define.amd) {
     87   define(function() { return impl; });
     88 } else {
     89   this.xorshift7 = impl;
     90 }
     91 
     92 })(
     93   this,
     94   (typeof module) == 'object' && module,    // present in node.js
     95   (typeof define) == 'function' && define   // present with an AMD loader
     96 );
     97