[erlang-questions] Implementation of a 2006 version of Wichmann-Hill random number generator for Erlang/OTP

Kenji Rikitake <>
Wed Dec 1 13:56:50 CET 2010


Richard (and all):

Your idea below looks fine to me.

I'd appreciate if I could take a look at your code for the random module
with multiple choice of algorithms.

A NIF to pick up some bytes from /dev/urandom on UNIX (and from an
equivalent API on Windows) will be a nice addition.

Just for clarification (correct me if I'm wrong):

uniform() value range: 
   0.0 =< uniform() < 1.0
uniform(N) when N = integer() value range: 
   1 =< uniform(N) <= N

I guess I can put my SFMT generators in this framework.

Regards,
Kenji Rikitake

In the message <>
dated Wed, Dec 01, 2010 at 02:57:41PM +1300,
Richard O'Keefe <> writes:
> On 1/12/2010, at 11:50 AM, Robert Virding wrote:
> 
> > What would be nice is if we could just drop the new algorithm into the old module so we avoid having to have 2 random modules. As I see it the main problem is that the old random has 3 seeds while the new has 4, which makes the seed functions incompatible. Couldn't you just have one seed be two?
> 
> Backwards compatibility would be nice, but let's think about what that
> involves.  If someone currently has a simulation program that saves random
> states in a file and reads them back, we really don't want to change what
> those states mean.  Suppose someone is currently doing
> 
> 	{F,{A1,B1,C1}} = random:uniform_s({A0,B0,C0})
> 
> If we turn 3-cycle states into 4-cycle states on the way in, what do we
> do on the way out?
> 
> The simplest change seems to me to be this.
> 
> (1) Decree that the random number module supports at least two kinds of
>     generators, the 1986 Wichmann-Hill 3-cycle generator with states
>     {A,B,C}, the 2006 Wichmann-Hill 4-cycle generator with states
>     {A,B,C,D}, and possibly other generators.
> 
> (2) Revise the existing function interfaces as follows:
> 
>     seed0()
> 	answer the default state, which might be any kind
> 	of supported state.  In particular, it might be
>         a 3-cycle state in one release and a 4-cycle one in
>         the next.
> 
>     seed() ->
> 	seed(seed0()).
> 
>     seed(State)
> 	set the state and return the old state.
> 	The State might be a 3-cycle state, a 4-cycle state,
> 	or whatever other kind of state the system supports.
> 
>     seed(A,B,C) ->		% deprecated
> 	seed({A,B,C}).  
> 
>     uniform()
> 	Generate a random float using whatever the currently
> 	selected generator/state is.
> 
>     uniform(N)
> 	Generate a random integer using whatever the currently
> 	selected generator/state is.
> 
>     uniform_s(State) ->
> 	Old_State = seed(State),
> 	Result = uniform(),
> 	New_State = seed(Old_State),
> 	{Result, New_State}.
> 
>     uniform_s(N, State) ->
> 	Old_State = seed(State),
> 	Result = uniform(N),
> 	New_State = seed(Old_State),
> 	{Result, New_State}.
> 
> (3) Currently there's a sort of pun which makes random:seed(now())
>     useful.  We don't want to lose that, and with the interface
>     above, it continues to work, but it continues to provide a 3-cycle
>     state.  So I suggest adding one more function:
> 
>     seed(Generator, Time)
> 
> 	where Generator can be wichmann_hill_1986 or
> 	wichman_hill_2006 or whatever else the module supports,
> 	and Time is an Erlang time value as returned by now().
> 
>     The 4-cycle generator really wants 124 bits of random state,
>     and erlang:now() only provides at best 40, for practical
>     purposes.  The megaseconds value changes only once every
>     twelve-and-a-bit days, so might as well be constant for
>     random number seeding purposes.
> 
> (4) Add one more function for information purposes,
> 
>     supported() -> list(atom).
> 
>     answer a list of the generators supported by the implementation,
>     with the default at the head.
> 
> I have a version of the 'random' module with this interface if anyone
> is interested.


More information about the erlang-questions mailing list