Erlang/OTP Forums

Author Message

<  Erlang bugs mailing list  ~  Bug in module random (stdlib-1.16.5, R13B04)

Guest
Posted: Fri Jun 11, 2010 3:26 pm Reply with quote
Guest
Hi,

* What steps will reproduce the problem?

random:seed({0,0,0}).
random:uniform(10000).
random:uniform(10000).
random:uniform(10000).
random:uniform(10000).

* What is the expected output? What do you see instead?

Expected output are random numbers in the range of 1..10000.
Instead all calls to uniform:random(10000) return 1.

In general: Randomness of random:uniform is restricted, when a single
element of the seed contains a 0 (which regularily is the case when
erlang:now() is used for seeding).

* What version of the product are you using? On what operating system?

stdlib-1.16.5, R13B04

* Please provide any additional information below.

stdlib-1.16.5/src/random.erl is supposed to implement the algorithm by
B. A. Wichmann and I. D. Hill See "An efficient and portable
pseudo-random number generator", Journal of Applied
Statistics. AS183. 1982. Also Byte March 1987.

In this article each element of the seed has to be a *positive*
integer in the range 1..30000.

If one element in the seed is 0, this will never change when getting
random numbers, as a multiplication with 0 always returns 0. So
randomness is broken in this case (see random:uniform()).

uniform() ->
{A1, A2, A3} = case get(random_seed) of
undefined -> seed0();
Tuple -> Tuple
end,
B1 = (A1*171) rem 30269,
B2 = (A2*172) rem 30307,
B3 = (A3*170) rem 30323,
put(random_seed, {B1,B2,B3}),
R = A1/30269 + A2/30307 + A3/30323,
R - trunc(R).

As seed commonly set using erlang:now(), and at least the third
element (milliseconds) of erlang:now() may be 0, the implementation
violates the algorithm specification.

In general: Randomness of random:uniform is broken, when a single
element of the seed contains a 0.

* How would you solve this issue?

When setting the seed via any random:seed function, 0 should be
automatically changed to 1, so erlang:now can savely be used as seed
generator.


Kind regards,

Florian Schintke
--
Florian Schintke <schintke@zib.de>, http://www.zib.de/schintke/

________________________________________________________________
erlang-bugs (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Sat Jun 12, 2010 1:57 pm Reply with quote
Guest
Hej Florian,

I can only reproduce this result when _all_ three parameters are equal
to 0 (Using R13B04). If a single parameter is unequal to 0 the random
number generator works as advertised.
Getting {0,0,0} by erlang:now() is unlikely, but maybe updating the
documentation to reflect the preconditions for random:seed/1 would be
a good action point.

/Uwe

________________________________________________________________
erlang-bugs (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Sat Jun 12, 2010 2:09 pm Reply with quote
Guest
Hej Florian,

I have to apologize as I misunderstood your point. Your report is valid.

/Uwe

________________________________________________________________
erlang-bugs (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Mon Jun 14, 2010 12:39 pm Reply with quote
Guest
Thank you for reporting this problem. Your suggested fix to replace
0 with 1 in the seed also seems as the least bad workaround.

I am amazed nobody reported this before.

It will be fixed or at least documented in earliest feasible release
(unfortunately not R14A).



On Fri, Jun 11, 2010 at 05:26:13PM +0200, Florian Schintke wrote:
> Hi,
>
> * What steps will reproduce the problem?
>
> random:seed({0,0,0}).
> random:uniform(10000).
> random:uniform(10000).
> random:uniform(10000).
> random:uniform(10000).
>
> * What is the expected output? What do you see instead?
>
> Expected output are random numbers in the range of 1..10000.
> Instead all calls to uniform:random(10000) return 1.
>
> In general: Randomness of random:uniform is restricted, when a single
> element of the seed contains a 0 (which regularily is the case when
> erlang:now() is used for seeding).
>
> * What version of the product are you using? On what operating system?
>
> stdlib-1.16.5, R13B04
>
> * Please provide any additional information below.
>
> stdlib-1.16.5/src/random.erl is supposed to implement the algorithm by
> B. A. Wichmann and I. D. Hill See "An efficient and portable
> pseudo-random number generator", Journal of Applied
> Statistics. AS183. 1982. Also Byte March 1987.
>
> In this article each element of the seed has to be a *positive*
> integer in the range 1..30000.
>
> If one element in the seed is 0, this will never change when getting
> random numbers, as a multiplication with 0 always returns 0. So
> randomness is broken in this case (see random:uniform()).
>
> uniform() ->
> {A1, A2, A3} = case get(random_seed) of
> undefined -> seed0();
> Tuple -> Tuple
> end,
> B1 = (A1*171) rem 30269,
> B2 = (A2*172) rem 30307,
> B3 = (A3*170) rem 30323,
> put(random_seed, {B1,B2,B3}),
> R = A1/30269 + A2/30307 + A3/30323,
> R - trunc(R).
>
> As seed commonly set using erlang:now(), and at least the third
> element (milliseconds) of erlang:now() may be 0, the implementation
> violates the algorithm specification.
>
> In general: Randomness of random:uniform is broken, when a single
> element of the seed contains a 0.
>
> * How would you solve this issue?
>
> When setting the seed via any random:seed function, 0 should be
> automatically changed to 1, so erlang:now can savely be used as seed
> generator.
>
>
> Kind regards,
>
> Florian Schintke
> --
> Florian Schintke <schintke@zib.de>, http://www.zib.de/schintke/
>
> ________________________________________________________________
> erlang-bugs (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB

________________________________________________________________
erlang-bugs (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Mon Jun 14, 2010 9:17 pm Reply with quote
Guest
[Raimo Niskanen]
> Thank you for reporting this problem. Your suggested fix to replace
> 0 with 1 in the seed also seems as the least bad workaround.
>
> I am amazed nobody reported this before.
>
> It will be fixed or at least documented in earliest feasible release
> (unfortunately not R14A).

To also fix the additional problem that a 0 could be generated by the
modulo operation when numbers for a seed are larger than the prime
numbers used in the algorithm, one should do first the calculation as
currently done and then check whether the result is zero. So my
proposal for a new random:seed/3 would be something similar to this:

seed(A1, A2, A3) ->
case abs(A1) rem 30269 of 0 -> T1 = 1; T1 -> T1 end,
case abs(A2) rem 30307 of 0 -> T2 = 1; T2 -> T2 end,
case abs(A3) rem 30323 of 0 -> T3 = 1; T3 -> T3 end,
put(random_seed, {T1, T2, T3}).


Florian
--
Florian Schintke <schintke@zib.de>, http://www.zib.de/schintke/

________________________________________________________________
erlang-bugs (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

Post received from mailinglist
Guest
Posted: Tue Jun 15, 2010 7:31 am Reply with quote
Guest
On Mon, Jun 14, 2010 at 11:15:48PM +0200, Florian Schintke wrote:
> [Raimo Niskanen]
> > Thank you for reporting this problem. Your suggested fix to replace
> > 0 with 1 in the seed also seems as the least bad workaround.
> >
> > I am amazed nobody reported this before.
> >
> > It will be fixed or at least documented in earliest feasible release
> > (unfortunately not R14A).
>
> To also fix the additional problem that a 0 could be generated by the
> modulo operation when numbers for a seed are larger than the prime
> numbers used in the algorithm, one should do first the calculation as
> currently done and then check whether the result is zero. So my
> proposal for a new random:seed/3 would be something similar to this:
>
> seed(A1, A2, A3) ->
> case abs(A1) rem 30269 of 0 -> T1 = 1; T1 -> T1 end,
> case abs(A2) rem 30307 of 0 -> T2 = 1; T2 -> T2 end,
> case abs(A3) rem 30323 of 0 -> T3 = 1; T3 -> T3 end,
> put(random_seed, {T1, T2, T3}).

Great! Well spotted again. Something like that...

>
>
> Florian
> --
> Florian Schintke <schintke@zib.de>, http://www.zib.de/schintke/
>
> ________________________________________________________________
> erlang-bugs (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB

________________________________________________________________
erlang-bugs (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-bugs-unsubscribe@erlang.org

Post received from mailinglist

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum