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.
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
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
danb...@yahoo.com (dan) wrote in message news:<fbf8d8f2.03080...@posting.google.com>...
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
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.
> 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
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
>>> 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! =-----
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
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
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.
It was closer to squaring the useful seed space; merely doubling it wouldn't
have been worth the bother.
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.
> 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