Hi,
By accident I came across a pseudo random number generator that I never heard off before. It is supposed to be pretty good and had a very simple implementation. So I ported it to Pharo.
<class comment>
I am RandomWELL512, a random number generator.
I use the PRNG (Pseudo Randon Number Generator) WELL (Well equidistributed long-period linear) with a 512 bit state.
�� https://en.wikipedia.org/wiki/Well_equidistributed_long-period_linear
�� http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf
Implementation algorithm (See #nextUInt32)
�� http://www.lomont.org/Math/Papers/2008/Lomont_PRNG_2008.pdf (Chris Lomont, www.lomont.org)
Usage
�� RandomWELL512 new in: [ :r | (1 to: 10) collect: [ :i | r nextUInt32 ] ].
�� RandomWELL512 new useUnixRandomGeneratorSeed; in: [ :r | (1 to: 10) collect: [ :i | r next ] ].
�� RandomWELL512 new in: [ :r | (1 to: 10) collect: [ :i | r nextInt: 1000 ] ].
�� RandomWELL512 new in: [ :random | | count all |
�� �� random useUnixRandomGeneratorSeed.
�� �� count := 1024 * 1024.
�� �� all := Array new: count streamContents: [ :out |
�� �� �� count timesRepeat: [ out nextPut: random next ] ].
�� �� { all min. all max. all average. all stdev } ].
�� [ RandomWELL512 new in: [ :random | 1 to: 1e6 do: [ :i | random next ] ] ] timeToRun.
Note that you should create one instance, seed it properly, and keep using it.
</class comment>
It is acceptably fast, generating 1M [0,1) Floats in about 0.1s. I compared the output with a fixed initial state to the C code that I started from and I got the same numbers. Maybe some people find this interesting.
I attached a file out.
Sven
| "Programs must be written for people to read, and only incidentally for machines to execute." https://twitter.com/SergeStinckwich |