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() use iso_fortran_env, only: int64 implicit none integer, allocatable :: seed(:) integer :: i, n, un, istat, dt(8), pid integer(int64) :: t 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(t) if (t == 0) then call date_and_time(values=dt) t = (dt(1) - 1970) * 365_int64 * 24 * 60 * 60 * 1000 & + dt(2) * 31_int64 * 24 * 60 * 60 * 1000 & + dt(3) * 24_int64 * 60 * 60 * 1000 & + dt(5) * 60 * 60 * 1000 & + dt(6) * 60 * 1000 + dt(7) * 1000 & + dt(8) end if pid = getpid() t = ieor(t, int(pid, kind(t))) do i = 1, n seed(i) = lcg(t) end do end if call random_seed(put=seed) contains ! This simple PRNG might not be good enough for real work, but is ! sufficient for seeding a better PRNG. function lcg(s) integer :: lcg integer(int64) :: s if (s == 0) then s = 104729 else s = mod(s, 4294967296_int64) end if s = mod(s * 279470273_int64, 4294967291_int64) lcg = int(mod(s, int(huge(0), int64)), kind(0)) end function lcg end subroutine init_random_seed
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gfortran/RANDOM_005fSEED.html