Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

random changes

0 views
Skip to first unread message

dan

unread,
Aug 7, 2003, 2:30:55 PM8/7/03
to
just a suggestion --

next time the core RNG is changed, I think it would be useful to have
an
-oldrandom switch. It is common practice in simulation projects to
depend
on the fact that your random numbers will come out the same if you use
the same seed. In bumping to 2.3 with the new Mersenne algorithm, I
have no easy way of duplicating my old results.

Andrew Dalke

unread,
Aug 7, 2003, 3:58:02 PM8/7/03
to
dan:

> next time the core RNG is changed, I think it would be useful to have
> an -oldrandom switch. [...] In bumping to 2.3 with the new Mersenne

> algorithm, I have no easy way of duplicating my old results.

Isn't the random.WichmannHill implement the old code? If so,
what about the following untested code?

import random

random = random.WichmannHill()
random.seed(5)
print random.random()

Failing that, what about copying the old Python code as "oldrandom.py"
then doing

import oldrandom as random

Andrew
da...@dalkescientific.com


David Goodger

unread,
Aug 7, 2003, 5:11:33 PM8/7/03
to

Then don't switch to 2.3, at least for that program.
On POSIX systems, it's easy to specify which version you want:

#! /usr/bin/python2.2
# or whatever

dan

unread,
Aug 7, 2003, 6:44:53 PM8/7/03
to
I did try random.WichmannHill, which gives completely different data
to either the new or the old version.

danb...@yahoo.com (dan) wrote in message news:<fbf8d8f2.03080...@posting.google.com>...

Raymond Hettinger

unread,
Aug 7, 2003, 8:22:02 PM8/7/03
to
"dan"

> I did try random.WichmannHill, which gives completely different data
> to either the new or the old version.

It works for me:


Python 2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
IDLE 0.8 -- press F1 for help
>>> import random
>>> rng = random.Random(1492)
>>> rng.random()
0.44575247281897029


Python 2.3 (#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.

****************************************************************
Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer's internal loopback
interface. This connection is not visible on any external
interface and no data is sent to or received from the Internet.
****************************************************************

IDLE 1.0
>>> import random
>>> rng = random.WichmannHill(1492)
>>> rng.random()
0.44575247281897029

Raymond Hettinger


Tim Peters

unread,
Aug 7, 2003, 9:46:19 PM8/7/03
to
[dan]

> I did try random.WichmannHill, which gives completely different data
> to either the new or the old version.

I expect you're confused about something, then, but there aren't enough
details to guess what.

Here's a run under 2.1.3:

>>> import random
>>> random.seed(123456789)
>>> print repr(random.random())
0.095213622685816457
>>>

Here under 2.2.3:

>>> import random
>>> random.seed(123456789)
>>> print repr(random.random())
0.095213622685816457
>>>

Here under 2.3:

>>> import random
>>> random = random.WichmannHill()

>>> random.seed(123456789)
>>> print repr(random.random())
0.095213622685816457
>>>


Same thing -- results should be (and are) bit-for-bit identical. Now show
us what you do that leads to the "completely different data" conclusion.


dan

unread,
Aug 8, 2003, 1:22:04 AM8/8/03
to
"Andrew Dalke" <ada...@mindspring.com> wrote in message news:<bguanf$147$1...@slb9.atl.mindspring.net>...

> Isn't the random.WichmannHill implement the old code? If so,
> what about the following untested code?

Tried it -- something's different, see my post about this
...


> Failing that, what about copying the old Python code as "oldrandom.py"
> then doing
>
> import oldrandom as random

Aah, that did it! I love this group!! It never even occured to me
that the lib wasn't in C. Duh!

thanks - dan

Andrew Dalke

unread,
Aug 8, 2003, 4:36:42 AM8/8/03
to
dan:

> Tried it -- something's different, see my post about this

As others pointed out, it should work. Could you repeat the test
and show us what "different" means?

Glad to hear that 'from oldrandom import random' worked at
least for the interim.

Andrew
da...@dalkescientific.com


Chris Reedy

unread,
Aug 8, 2003, 10:26:35 AM8/8/03
to
Here are some interesting numbers:

>>> def printstats(rng, N=20000):
# Cribbed from random._test_generator
import math
sum = 0
sumsq = 0
for i in range(N):
x = rng()
sum += x
sumsq += x*x
avg = sum/N
stddev = math.sqrt(sumsq/N - avg*avg)
print repr(avg), repr(stddev)

Under 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)]:
>>> rng = random.Random()
>>> rng.seed(123456789)
>>> printstats(rng.random)
0.50177345778280169 0.28856727700571438
>>> rng.seed(123456789)
>>> printstats(lambda : rng.normalvariate(0.0, 1.0))
0.0021149783637115457 0.99131361156374964

Under 2.3 (#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)]:
>>> rng = random.WichmannHill()
>>> rng.seed(123456789)
>>> printstats(rng.random)
0.50177345778280169 0.28856727700571438
>>> rng.seed(123456789)
>>> printstats(lambda : rng.normalvariate(0.0, 1.0))
0.0064296479176113733 1.0050714625654731

It appears that the numbers for random.random() are identical, however,
the numbers for normalvariate (and also lognormvariate, betavariate,
weibullvariate, and paretovariate) are different. I have no explanation
for why.

Chris

-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----

Raymond Hettinger

unread,
Aug 8, 2003, 12:13:38 PM8/8/03
to

"dan" <danb...@yahoo.com> wrote in message
news:fbf8d8f2.03080...@posting.google.com...


It would have been helpful to included a sample call, the results, and
the version of Python you were using. It looks like you were using
Py2.0 and upgraded to Py2.3. This difference you are seeing came
version Py2.1 when WichmannHill's seed method was improved
(the upgrade to the Mersenne Twister has nothing to do with it):

"""
random.py's seed() function is new. For bit-for-bit compatibility with
prior releases, use the whseed function instead. The new seed function
addresses two problems: (1) The old function couldn't produce more than
about 2**24 distinct internal states; the new one about 2**45 (the best
that can be done in the Wichmann-Hill generator). (2) The old function
sometimes produced identical internal states when passed distinct
integers, and there was no simple way to predict when that would happen;
the new one guarantees to produce distinct internal states for all
arguments in [0, 27814431486576L).
"""

So, to get your old results with Py2.3, try something like:

import random
rng = random.WichmannHill()
rng.whseed(12345)
for i in range(6):
print rng.randint(1, 10)


Raymond Hettinger


Raymond Hettinger

unread,
Aug 8, 2003, 12:35:02 PM8/8/03
to
"Chris Reedy"

> It appears that the numbers for random.random() are identical, however,
> the numbers for normalvariate (and also lognormvariate, betavariate,
> weibullvariate, and paretovariate) are different

The underlying random number generator is the same but
the formulas for producing the variates were each changed
a bit so they could handle the full range of possible inputs
(i.e. handling a random() float exactly equal to zero).

The OP's original concern was traced back to a change between
Py2.0 and Py2.1 where the WichmannHill seed routine was
improved (doubling the key space and reducing duplicate
states generated from different seeds). The whseed() method
was what he needed for backwards compatibility.


Raymond Hettinger


Tim Peters

unread,
Aug 8, 2003, 1:03:33 PM8/8/03
to
[Chris Reedy]

Odd! I don't have Python 2.2.2 anymore. Under Python 2.2.3, the results
are identical (and match the results you got for 2.3).

C:\Code>type temp.py
import random
import sys

def printstats(rng, N=20000):
# Cribbed from random._test_generator
import math
sum = 0
sumsq = 0
for i in range(N):
x = rng()
sum += x
sumsq += x*x
avg = sum/N
stddev = math.sqrt(sumsq/N - avg*avg)
print repr(avg), repr(stddev)

print sys.version_info
if sys.version_info >= (2, 3):
rng = random.WichmannHill()
else:


rng = random.Random()
rng.seed(123456789)
printstats(rng.random)

rng.seed(123456789)
printstats(lambda: rng.normalvariate(0.0, 1.0))

C:\Code>\python22\python temp.py
(2, 2, 3, 'final', 0)
0.50177345778280169 0.28856727700571438
0.0064296479176113733 1.0050714625654731

C:\Code>\python23\python temp.py
(2, 3, 0, 'final', 0)
0.50177345778280169 0.28856727700571438
0.0064296479176113733 1.0050714625654731

I have to go back to 2.1.3 to get your 2.2.2 results:

C:\Code>\python21\python temp.py
(2, 1, 3, 'final', 0)
0.50177345778280169 0.28856727700571438
0.0021149783637115457 0.99131361156374964

As Raymond pointed out in another post, the WH seed method was changed in a
bugfix release, because it had bad flaws. The old method is still available
in post-bugfix releases under the name .whseed(); use of it can't be
recommended, though.


Tim Peters

unread,
Aug 8, 2003, 1:06:24 PM8/8/03
to
[Raymond Hettinger]
> ...

> The OP's original concern was traced back to a change between
> Py2.0 and Py2.1 where the WichmannHill seed routine was
> improved (doubling the key space and reducing duplicate
> states generated from different seeds).

It was closer to squaring the useful seed space; merely doubling it wouldn't
have been worth the bother.


Chris Reedy

unread,
Aug 8, 2003, 2:56:53 PM8/8/03
to
Tim Peters wrote:
> [Chris Reedy]
>
>>Here are some interesting numbers:
>>
>> [snip example showing changes in normalvariate]

>
>
> Odd! I don't have Python 2.2.2 anymore. Under Python 2.2.3, the results
> are identical (and match the results you got for 2.3).
>
> [snip example showing no changes in normalvariate]

>
> I have to go back to 2.1.3 to get your 2.2.2 results:
>
> C:\Code>\python21\python temp.py
> (2, 1, 3, 'final', 0)
> 0.50177345778280169 0.28856727700571438
> 0.0021149783637115457 0.99131361156374964
>
> As Raymond pointed out in another post, the WH seed method was changed in a
> bugfix release, because it had bad flaws. The old method is still available
> in post-bugfix releases under the name .whseed(); use of it can't be
> recommended, though.
>
>

I checked CVS. The following change was added between 2.2.2 and 2.2.3:

Correct long standing bugs in the methods for random distributions.
The range of u=random() is [0,1), so log(u) and 1/x can fail.
Fix by setting u=1-random() or by reselecting for a usable value.

This impacted exactly the variates I noticed. I think this explains the
issue.

dan

unread,
Aug 10, 2003, 2:17:42 AM8/10/03
to
"Raymond Hettinger" <vze4...@verizon.net> wrote in message news:<S_PYa.73$pn3...@nwrdny01.gnilink.net>...

> So, to get your old results with Py2.3, try something like:
>
> import random
> rng = random.WichmannHill()
> rng.whseed(12345)
> for i in range(6):
> print rng.randint(1, 10)
>

that worked, thanks

0 new messages