My random random number generator must be called many, unspecified, times:
WRITE(*,*) Random_Number_routine([optional seed])
My random number generator has an optional integer argument, if present it uses this as the seed. If not present it calls system_clock(i) and uses i as the seed. So far so good. However if the Random_Number_routine is called too quickly, more than once a second, then system clock has not had a chance for the COUNT argument to change and the same value is returned. As an example consider an adaptation of the example given at http://ift.tt/1QbQQH4
PROGRAM test_system_clock
INTEGER :: count, count_rate, count_max
DO i = 1, 100
CALL SYSTEM_CLOCK(count, count_rate, count_max)
CALL srand(count)
WRITE(*,*) count, count_rate, count_max, rand()
END DO
END PROGRAM test_system_clock
The output of test_system_clock is
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320589 1000 2147483647 0.640894175
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
5320590 1000 2147483647 0.640901804
4928363 1000 2147483647
The count argument only takes two values: 5320589 and 5320590. If this argument is used as the seed in srand i.e.
Call srand(count)
Then the same seed is used and the same random numbers generated, which can be seen in the last column of the data. The only way around this is to generate $N$ random variables from a single seed, i.e.
CALL SYSTEM_CLOCK(count, count_rate, count_max)
Call srand(count)
DO j = 1, n
res(j) = rand()
END DO
However this assumes that one knows how many random variables are needed before the routine is called - which in this case I do not.
The only other train of through I've had is to use Fortran's save attribute and save the previous seed used - if its the first time the routine has been executed it uses SYSTEM_CLOCK to determine the seed, subsistent runs update the seed by some integer. However this does not produce random numbers as only the first in number in the sequence is used.
How do other software's get around this problem? How does a program like MATLAB do this? And how can I call the random number routine and guarantee a new random number?
Aucun commentaire:
Enregistrer un commentaire