A Tausworthe random number generator

terchestor terchestor at gmail.com
Wed Jan 22 06:51:45 PST 2014


On Wednesday, 22 January 2014 at 11:02:10 UTC, monarch_dodra 
wrote:
> On Wednesday, 22 January 2014 at 09:33:39 UTC, terchestor wrote:
>> My problem is the cast to integral type (line 80), downgrading 
>> performances of circa 50%.
>> Is there any possibility to avoid it?
>
> I'd suggest you get rid of "high/low" completly. There are prng 
> *adaptors* that can create a uniform distribution *from* a 
> natural prng (std.random.uniform). If you do this, you code 
> becomes (starting line 73):
>
>         auto uni = (s1 ^ s2 ^ s3);
>         static if (isFloatingPoint!result_t)
>         {
>             return uni / Tconst_tau0;
>         }
>         else
>         {
>             return uni;
>         }
>
> Heck, you could get rid of floating point support entirely, and 
> generate only integrals. Then, you just let "uniform" do the 
> tough work:
>
> auto rnd = tausworthe!(ulong, uint)(randomSeed);
>
> auto rndF    = rnd.uniform!"[)"(0.0,  1.0); //0 - 1 double range
> auto rnd1024 = rnd.uniform!"[)"(0,   1024); //[0 .. 1024) 
> integral range.
>

Actually, for the purpose I've in mind, a DSP library, which is 
time critical (and that's why I need the fastest possible PRNG), 
I'd better decoupling the range processing and create a class 
implementing the range interface to store the numbers generated 
by uniform to serve them on demand: a composite pattern is better 
than inheritance.

> Nitpick:
>         /// get seed from current time
>         auto se = Clock.currTime().stdTime;
>
> This is known to be a bad seed. If you need a "good enough" 
> seed, use "std.random.randomSeed". Although arguably (IMO), it 
> is better place the burden of seeding on the caller.

Fine remark worth adopting.



More information about the Digitalmars-d mailing list