Why do I need to call rng () twice in Matlab

This seems like a mistake to me. It seems like it needs to be called twice in Matlab rng()

to get the desired seeding. Consider the following experiments:

>> sd = rng(3) % THIS DOES NOT WORK

sd = 

     Type: 'twister'
     Seed: 0
    State: [625x1 uint32]

>> sd = rng(3) % BUT NOW IT DOES

sd = 

     Type: 'twister'
     Seed: 3
    State: [625x1 uint32]

>> sd = rng(3) % AND AGAIN, TO CONFIRM

sd = 

     Type: 'twister'
     Seed: 3
    State: [625x1 uint32]

>> sd = rng('shuffle') % BUT THIS FAILS

sd = 

     Type: 'twister'
     Seed: 3
    State: [625x1 uint32]

>> sd = rng('shuffle') % BUT ON THE SECOND GO IT WORKS

sd = 

     Type: 'twister'
     Seed: 87326715
    State: [625x1 uint32]

>> sd = rng('shuffle') % AND ON THE THIRD

sd = 

     Type: 'twister'
     Seed: 87326802
    State: [625x1 uint32]

>> sd = rng(4) % BUT AGAIN THIS FAILS

sd = 

     Type: 'twister'
     Seed: 87326987
    State: [625x1 uint32]

>> sd = rng(4) % BUT ON THE SECOND GO IT WORKS AGAIN

sd = 

     Type: 'twister'
     Seed: 4
    State: [625x1 uint32]

>> sd = rng(4) % AND SO ON

sd = 

     Type: 'twister'
     Seed: 4
    State: [625x1 uint32]

      

+3


source to share


1 answer


Short answer:  According to the documentation, the return value rng

is the previous state:

sprev = rng (...) returns the previous random number generator settings used by rand, randi and randn before changing the settings.

So the answer is no, this is not a mistake. The random number generator was correctly initialized on the first call.

However, in my opinion this is quite unexpected behavior.


Longer answer: I suggest using objects instead RandStream

, which are much easier to understand for those with a basic knowledge of object-oriented programming. For example:

s1 = RandStream.create('mrg32k3a');
r1 = rand(s1,100000,1);

      

I highly recommend avoiding setting a global thread as it has all the disadvantages of global variables.



%Not recommended! (Due to global variable)
s = RandStream('mt19937ar','Seed',1);
RandStream.setGlobalStream(s);

      

Edit (1) I would like to explain my opinion on why installing a global random number generator is not good practice. Basically, the goal of any good software is to reduce the size of any variable in order to reduce communication and increase cohesion . A global variable has the highest possible concatenation (any routine can use it) and the least concatenation possible. A global random number generator is even more risky than a normal variable because it is much more likely to be someone else.

Re-sorting the global random number generator can lead to some bizarre errors. Consider the following example: You are writing a program that loops for

and generates a random number.

 for i=1:N
     k = randn(1,1); 
     %... Do something
 end

      

Everything seems perfect. Now you want to add a third party function Foo

in the middle of your loop that does some things. The code developer decided to reseed the global number generator before 1

.

 for i=1:N
     k = randn(1,1); 
     %... Do something
     Foo();
 end

 function Foo()
     %Do some stuff
     rng(1);
 end

      

Surprise! Now your program generates a completely non-random sequence of numbers, namely the exact same number in every call to the loop.

Some more data to read if you're still unsure - Here , here and here

+5


source







All Articles