![](https://secure.gravatar.com/avatar/72f994ca072df3a3d2c3db8a137790fd.jpg?s=120&d=mm&r=g)
Floris is seems you sent the response to only me. The "right" behaviour is to not use jumpahead, which does not work well enough to be part of python 3.1 (note the use of "likely" in the docstring): ''' jumpahead(self, n) method of random.Random instance Change the internal state to one that is likely far away from the current state. This method will not be in Py3.x, so it is better to simply reseed. ''' The implementation changed for python 2.4, in changeset https://hg.python.org/cpython/rev/edd056c4a40d/ as part of the adaptations to the Mersenne Twister generator that replaced WichmannHill in python 2.3 I will try to make pypy return the same values as cpython, but you should consider reseeding for each thread instead Matti On 07/03/15 14:33, Floris van Manen wrote:
On 7 Mar 2015, at 13:28, matti picus <matti.picus@gmail.com <mailto:matti.picus@gmail.com>> wrote:
What did you try that led you to suspect they are different? Matti
yes indeed. Using the jumpahead() fnction will lead to different results. I don't now which are the correct ones...
import random
random.seed(12345) for i in xrange(10): print random.random() print randomState = random.getstate() for i in xrange(10): random.setstate(randomState) random.jumpahead(1) randomState = random.getstate() print random.random()
''' standard python:
0.416619872545 0.0101691694571 0.825206509254 0.2986398552 0.368411689488 0.193661349045 0.566008168729 0.161687823929 0.124266884284 0.43293626801
jumpahead() 0.94861718596 0.466389725591 0.440309106388 0.756595610966 0.329954203719 0.207243180479 0.982769966933 0.856141036147 0.746277878413 0.304000958341
pypy
0.416619872545 0.0101691694571 0.825206509254 0.2986398552 0.368411689488 0.193661349045 0.566008168729 0.161687823929 0.124266884284 0.43293626801
jumpahead() 0.41362858709 0.482594587067 0.363386428038 0.0122210322735 0.218894401377 0.786381037234 0.535611315209 0.545681381301 0.0153701629836 0.136216130724 '''
![](https://secure.gravatar.com/avatar/aaec8862a4c7f861ffc1f105419e1805.jpg?s=120&d=mm&r=g)
Matti,
On 7 Mar 2015, at 19:37, Matti Picus <matti.picus@gmail.com> wrote:
''' jumpahead(self, n) method of random.Random instance Change the internal state to one that is likely far away from the current state. This method will not be in Py3.x, so it is better to simply reseed. '''
Thanks for pointing out. I'm using the jumpahead() to have multiple streams in parallel, derived from a single point. def jumpRandomState(self): self.random.setstate(self.randomState) self.random.jumpahead(1) self.randomState = self.random.getstate() Would this be a good alternative? def jumpRandomState(self): self.random.setstate(self.randomState) self.random.seed(self.random.random()) self.randomState = self.random.getstate() .Floris
![](https://secure.gravatar.com/avatar/aaec8862a4c7f861ffc1f105419e1805.jpg?s=120&d=mm&r=g)
On 7 Mar 2015, at 22:13, Matti Picus <matti.picus@gmail.com> wrote:
Looks OK to me, maybe someone else will chime in as well. In any case jumpahead(n) should give identical results in both cpython and pypy if you use a pypy after changeset a2a352a3b535 (in other words, a nightly from tomorrow onwards) Matti
Thanks, i'll give it a try. .F
![](https://secure.gravatar.com/avatar/5615a372d9866f203a22b2c437527bbb.jpg?s=120&d=mm&r=g)
On Sat, Mar 07, 2015 at 09:06:13PM +0100, Floris van Manen wrote:
I'm using the jumpahead() to have multiple streams in parallel, derived from a single point.
I'm afraid I don't understand what that sentence means. Do you mean derived from a single seed? If so, I think the easiest way is to just create multiple random instances. Suppose you want five streams of random numbers: create one extra "seeder" (or just use the pre-defined top-level random functions): import random seeder = random.Random(myseed) # or just use random.seed(myseed) streams = [random.Random(seeder.random()) for _ in range(5)] If you want to reset them to the initial state, just reseed the seeder stream and recreate them. Or you can just grab all their internal states: states = [s.getstate() for s in streams]
def jumpRandomState(self): self.random.setstate(self.randomState) self.random.jumpahead(1) self.randomState = self.random.getstate()
I'm afraid I don't understand the purpose of that method or why you are restoring the internal state before jumping. I tried putting it in a subclass of random.Random, but it raises an exception: py> class MyRandom(random.Random): ... def jumpRandomState(self): ... self.random.setstate(self.randomState) ... self.random.jumpahead(1) ... self.randomState = self.random.getstate() ... py> rnd = MyRandom(1000) py> rnd.jumpRandomState() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in jumpRandomState AttributeError: 'builtin_function_or_method' object has no attribute 'setstate' so your code doesn't work for me. Based just on the name, I would do this: class MyRandom(random.Random): def jumpRandomState(self): self.jumpahead(356789) If you don't trust jumpahead to reliably jump to an independent part of the PRNG sequence, re-seed with an independent pseudo-random number: class MyRandom(random.Random): _JUMPER = random.Random() def jumpRandomState(self): self.seed(self._JUMPER.random()) -- Steve
![](https://secure.gravatar.com/avatar/2f2ca3900ef33896dbd5d158c803d4bd.jpg?s=120&d=mm&r=g)
I think for multiple streams it's best to make your own instances of random.Random. Most of the functions that the random module exposes are just methods of a single global random function, see the source here: https://hg.python.org/cpython/file/2.7/Lib/random.py#l885 Cheers, Carl Friedrich On March 7, 2015 9:06:13 PM GMT+01:00, Floris van Manen <vm@klankschap.nl> wrote:
Matti,
On 7 Mar 2015, at 19:37, Matti Picus <matti.picus@gmail.com> wrote:
''' jumpahead(self, n) method of random.Random instance Change the internal state to one that is likely far away from the current state. This method will not be in Py3.x, so it is better to simply reseed. '''
Thanks for pointing out.
I'm using the jumpahead() to have multiple streams in parallel, derived from a single point.
def jumpRandomState(self): self.random.setstate(self.randomState) self.random.jumpahead(1) self.randomState = self.random.getstate()
Would this be a good alternative?
def jumpRandomState(self): self.random.setstate(self.randomState) self.random.seed(self.random.random()) self.randomState = self.random.getstate()
.Floris
------------------------------------------------------------------------
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev
participants (4)
-
Carl Friedrich Bolz
-
Floris van Manen
-
Matti Picus
-
Steven D'Aprano