Home > Net >  Function that generates random numbers calls other function that generates random numbers with a see
Function that generates random numbers calls other function that generates random numbers with a see

Time:10-29

I am trying to generate a function which generate random numbers from a uniform distribution Number_Rand() and another one which generates a random number given a certain seed Number_Rand_Seed() - so that it will always be the same for a fixed seed. However, I call the function Number_Rand_Seed() inside Number_Rand(), and for some reason the seed is also used to generate random numbers in Number_Rand(), so that its output is always the same. Shouldn't the seed be a local variable inside Number_Rand_Seed()? And shouldn't the seed be "renewed" everytime I call a np.random function (see, e.g., this answer)? What should I do then to "renew" the seed inside Number_Rand() and ignore the seed of Number_Rand_Seed()?

Here is an example:

def Number_Rand_Seed():
    np.random.seed(300121)
    a = np.random.uniform(0, 10)
    return a

def Number_Rand():
    a = Number_Rand_Seed()
    b = np.random.uniform(0, 10)
    return a, b

for i in range(3):
    print(Number_Rand()) 

The output is

(9.354120260352017, 2.552916103146633)
(9.354120260352017, 2.552916103146633)
(9.354120260352017, 2.552916103146633)

but I wanted something like

(9.354120260352017, 8.823425849537022)
(9.354120260352017, 5.950595370176398)
(9.354120260352017, 9.992406389398592)

CodePudding user response:

If you want to reset the seed after setting it, you can use the function:

numpy.random.seed()

Which changes the seed to a random value, something like this:

def Number_Rand_Seed():
    np.random.seed(300121)
    a = np.random.uniform(0, 10)
    return a

def Number_Rand():
    a = Number_Rand_Seed()
    np.random.seed()
    b = np.random.uniform(0, 10)
    return a, b

for i in range(3):
    print(Number_Rand()) 

CodePudding user response:

In recent numpy versions, you can create separate random number generators using np.random.default_rng.

In the following I use that for a, while retaining the default for b:

In [35]: def Number_Rand_Seed():
    ...:     rng = np.random.default_rng(300121)
    ...:     a = rng.uniform(0, 10)
    ...:     return a
    ...: 
    ...: def Number_Rand():
    ...:     a = Number_Rand_Seed()
    ...:     b = np.random.uniform(0, 10)
    ...:     return a, b
    ...: 
    ...: for i in range(3):
    ...:     print(Number_Rand())
    ...: 
(9.98668624527619, 2.7036401003521817)
(9.98668624527619, 9.154952983315784)
(9.98668624527619, 1.413705001678095)
In [36]: Number_Rand()
Out[36]: (9.98668624527619, 5.274283695955279)

Or define a "default" rng outside the function. The rng in Number_Rand_Seed is local, and doesn't interfere with the rng defined outside it. Of course the code would be clearer to humans if I used different names.

...: rng = np.random.default_rng()
...: def Number_Rand():
...:     a = Number_Rand_Seed()
...:     b = rng.uniform(0, 10)
...:     return a, b
  • Related