Reputation: 303
I have a simulation that requires the generation of N
random numbers each iteration. However, N
varies depending on the state of the simulation. Because N
varies, the following calls to numpy.random()
yield different results. However, I would like the following calls to numpy.random()
to be uninfluenced by N
.
I have been solving this by (1) generating a large random integer before the numpy.random()
call and then (2) setting the random seed as this integer following the numpy.random()
call (see below). However this seems clumsy.
Is there a better way to control numpy.random's state that is uninfluenced by the size
argument?
import numpy as np
N=10
# set seed
np.random.seed(0)
# generate N numbers
a = np.random.normal(size=N)
# check its state
print(np.random.randint(1e4))
This call to randint()
returns 2599
# set seed
N = 1
np.random.seed(0)
# generate N numbers
b = np.random.normal(size=N)
# check its state
print(np.random.randint(1e4))
This call to randint()
returns 4859
Potential solution:
N = 10
# set seed
np.random.seed(0)
# generate a large random integer
rand_int = np.random.randint(1e6)
# generate N numbers
b = np.random.normal(size=N)
# reset the seed
np.random.seed(rand_int)
# check its state
print(np.random.randint(1e4))
This call to randint()
returns 5143
, independent of N
Upvotes: 0
Views: 994
Reputation: 32878
numpy.random.*
functions use a single global instance of a PRNG (pseudorandom number generator) that is shared throughout the application. In your code examples np.random.normal
advances this PRNG a different number of times, so that the randint
call that follows outputs a different pseudorandom number.
Instead, if different parts of your simulation require a different stream of random numbers, then rather than rely on numpy.random.*
's global PRNG instance, use two or more PRNG instances, each initialized based on a common seed.
NumPy 1.17 introduces a new random number generation system and includes several facilities for this purpose. These include a SeedSequence
class for generating multiple PRNG states using a common seed, and a Generator
class that holds a PRNG. The new system was the result of a proposal to change the RNG policy, which states that numpy.random.*
functions should generally not be used anymore. This is especially because numpy.random.*
operates on global state.
The NumPy documentation now has detailed information on seeding multiple PRNGs in the new system. See also "Seeding Multiple Processes", from an article of mine about PRNGs.
Upvotes: 3