RANDOM_SEED
— Initialize a pseudo-random number sequenceRANDOM_NUMBER
.
If RANDOM_SEED
is called without arguments, it is initialized
to a default state. The example below shows how to initialize the
random seed with a varying seed in order to ensure a different random
number sequence for each invocation of the program. Note that setting
any of the seed values to zero should be avoided as it can result in
poor quality random numbers being generated.
CALL RANDOM_SEED([SIZE, PUT, GET])
SIZE | (Optional) Shall be a scalar and of type default
INTEGER , with INTENT(OUT) . It specifies the minimum size
of the arrays used with the PUT and GET arguments.
|
PUT | (Optional) Shall be an array of type default
INTEGER and rank one. It is INTENT(IN) and the size of
the array must be larger than or equal to the number returned by the
SIZE argument.
|
GET | (Optional) Shall be an array of type default
INTEGER and rank one. It is INTENT(OUT) and the size
of the array must be larger than or equal to the number returned by
the SIZE argument.
|
subroutine init_random_seed() implicit none integer, allocatable :: seed(:) integer :: i, n, un, istat, dt(8), pid, t(2), s integer(8) :: count, tms call random_seed(size = n) allocate(seed(n)) ! First try if the OS provides a random number generator open(newunit=un, file="/dev/urandom", access="stream", & form="unformatted", action="read", status="old", iostat=istat) if (istat == 0) then read(un) seed close(un) else ! Fallback to XOR:ing the current time and pid. The PID is ! useful in case one launches multiple instances of the same ! program in parallel. call system_clock(count) if (count /= 0) then t = transfer(count, t) else call date_and_time(values=dt) tms = (dt(1) - 1970) * 365_8 * 24 * 60 * 60 * 1000 & + dt(2) * 31_8 * 24 * 60 * 60 * 1000 & + dt(3) * 24 * 60 * 60 * 60 * 1000 & + dt(5) * 60 * 60 * 1000 & + dt(6) * 60 * 1000 + dt(7) * 1000 & + dt(8) t = transfer(tms, t) end if s = ieor(t(1), t(2)) pid = getpid() + 1099279 ! Add a prime s = ieor(s, pid) if (n >= 3) then seed(1) = t(1) + 36269 seed(2) = t(2) + 72551 seed(3) = pid if (n > 3) then seed(4:) = s + 37 * (/ (i, i = 0, n - 4) /) end if else seed = s + 37 * (/ (i, i = 0, n - 1 ) /) end if end if call random_seed(put=seed) end subroutine init_random_seed