New Lagged Fib. PRNG gen and random2.d

monarch_dodra monarchdodra at gmail.com
Sun Aug 25 09:03:58 PDT 2013


Hi everyone:

I (finally) ported boost's implementation of the Lagged Fibonacci 
generator to D. I am creating this thread for review.
https://github.com/D-Programming-Language/phobos/pull/1521

The Lagged Fibonacci generator has interesting properties: For 
starters, you can generate integers or floats with it. With 
floats, it generates numbers in a 0 .. 1 range, making it a very 
nice generator for users that want simple uniform floating point 
generation in that range.

Another interesting property, is that one can easily specify bit 
depth and return type. So for example, it is possible to generate 
ubytes in the [0 .. 128] range (7 bit depth), or floats with a 
0.25 step (eg [0, 0.25, 0.5, 0.75]).

In terms of quality, I'm no expert, but supposedly, it's supposed 
to be good, when properly seeded.

Please review the design, and tell me what you think?

--------

One of the design goals with it, is that I think having a new 
PRNG is the perfect opportunity to try out the *long* discussed 
but never introduced PRNG reference-semantics. The 
LaggedFibonacciGenerator is designed the first of a new familly 
of generators: Implemented as a pimpl, and without a "save" 
primitive, it is *impossible* to accidently generate the same 
sequence twice. It does have "dup", for those that *must* have 
back tracking, but it is explicit.

Implemented as a pimpl, its pass-by-value is virtually free 
(MT19937 is an approx. 2KiB).

Seeding *must* be done explicitly, so as to provide the fastest 
possible iteration. There is no "seed()" function, so there is no 
default seed *value* either, which will prevent the newbie 
mistake of "why does random program always output the same random 
sequence", and promote the use of "seed(unpredictableSeed)".

Other than that, there is not much to say... the idea is to try 
to stress test this PRNG, and learn as much as possible, before 
we tackle random2.

--------

I'll copy pasted here the example documentation:

This is example *useage*

///
unittest
{
     //Create a new Generator.
     LaggedFibonacci!ulong lf;

     //It is not yet seeded.
     assert(!lf.isSeeded);

     //Seed with a random seed.
     lf.seed(unpredictableSeed);

     //generate a new array of 10 random numbers.
     ulong[] numbers1 = lf.take(10).array();

     //An existing array can be filled with an algorithm.
     ulong[] numbers2 = new ulong[](10);
     numbers2.fill(lf);

     //Because of the reference semantics, and since there is no 
save,
     //we can rest assured both arrays are different.
     assert(!equal(numbers1, numbers2));
}

These are various flavours of the generator.

///
unittest
{
     //Simple declatation
     LaggedFibonacci!double myFloatingPointGenerator;
     LaggedFibonacci!ulong  myIntegralGenerator;

     //Declaration with specific length
     LaggedFibonacci607!double  mySimpleFloatingPointGenerator;
     LaggedFibonacci44497!ulong myComplexIntegralGenerator;

     //Generate specific type: ubytes in the range [0 .. 256]
     LaggedFibonacci!(ubyte, 8) myByteGenerator;

     //Generate specific type: doubles with a step of 0.125
     LaggedFibonacci!(double, 3) myPieGenerator;

     //Generate with high precision reals
     LaggedFibonacci!(real, 64) myPreciseGenerator;
}

--------

Please (kindly) destroy!


More information about the Digitalmars-d mailing list