www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - xoroshiro128+ random number generator

reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
Spotted this reddit post the other day:
https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/

... and it reminded me that I've been meaning for some time to 
follow up on the interesting RNG designs by Sebastiano Vigna and 
colleagues.  Since I had a free moment, I thought I'd knock up a 
D port of the public-domain C reference code available here:
http://xorshift.di.unimi.it/xoroshiro128plus.c

It's a first draft and obviously needs documentation, tests, etc. 
before I submit it to Phobos, but I thought I'd throw it out here 
if anyone wants to play with it and/or comment.  I'll also try to 
follow up in the next days with an xorshift1024* implementation, 
which should be similarly straightforward.

Code follows -- enjoy! :-)


struct Xoroshiro128plus
{
   public:
     enum bool isUniformRandom = true;

     /// Range primitives
     enum bool empty = false;

     /// ditto
     ulong front()  property  safe const nothrow pure
     {
         return s[0] + s[1];
     }

     /// ditto
     void popFront()  safe nothrow pure
     {
         immutable ulong s1 = s[1] ^ s[0];
         s[0] = rotateLeft(s[0], 55) ^ s1 ^ (s1 << 14);
         s[1] = rotateLeft(s1, 36);
     }

     void seed(ulong s0, ulong s1)  safe nothrow pure
     in
     {
         // seeds are not both 0
         assert(!(!s0 && !s1));
     }
     body
     {
         s[0] = s0;
         s[1] = s1;
     }

     void seed(ulong[2] s01)  safe nothrow pure
     in
     {
         // seeds are not both 0
         assert(!(!s01[0] && !s01[1]));
     }
     body
     {
         s[] = s01[];
     }

   private:
     ulong[2] s;

     static ulong rotateLeft(ulong x, int k)  safe nothrow pure
     in
     {
         assert(k <= 64);
     }
     body
     {
         return (x << k) | (x >> (64 - k));
     }
}
Apr 29 2016
parent reply =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Friday, 29 April 2016 at 21:40:49 UTC, Joseph Rushton Wakeling 
wrote:
 Spotted this reddit post the other day:
 https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/
nogc :)
Apr 30 2016
parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Saturday, 30 April 2016 at 08:54:39 UTC, Nordlöw wrote:
 On Friday, 29 April 2016 at 21:40:49 UTC, Joseph Rushton 
 Wakeling wrote:
 Spotted this reddit post the other day:
 https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/
nogc :)
Hah, nicely spotted :-)
Apr 30 2016
parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On Saturday, 30 April 2016 at 11:04:14 UTC, Joseph Rushton 
Wakeling wrote:
 On Saturday, 30 April 2016 at 08:54:39 UTC, Nordlöw wrote:
 On Friday, 29 April 2016 at 21:40:49 UTC, Joseph Rushton 
 Wakeling wrote:
 Spotted this reddit post the other day:
 https://www.reddit.com/r/programming/comments/4gtlfz/xoroshiro128_the_fastest_fullperiod_pseudorandom/
nogc :)
Hah, nicely spotted :-)
More importantly, the public fields of this generator should include: enum ulong min = ulong.min; enum ulong max = ulong.max; ... otherwise it won't work with `uniform` or anything that depends on it.
Apr 30 2016