RANDOM_SEED - The GNU Fortran Compiler
Description: The GNU Fortran Compiler

Next: RANGE, Previous: RANDOM_NUMBER, Up: Intrinsic Procedures

### 8.201 `RANDOM_SEED` — Initialize a pseudo-random number sequence

Description:
  Restarts or queries the state of the pseudorandom number generator used by `RANDOM_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.

Standard:
  Fortran 95 and later
Class:
  Subroutine
Syntax:
  `CALL RANDOM_SEED([SIZE, PUT, GET])`
Arguments:

  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.

Example:

                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

See also:
  RANDOM_NUMBER