# include "define.inc" module ran ! <doc> ! A wrapper module for random number generator. ! Thie module provides real function ranf ! using intrinsic random_number/random_seed or ! Mersenne Twister 19937 (see mt19937.f90). ! Note that instrinsic function appears to use ! and integer vector seed of length 2, but this ! is implementation dependent. If there is ever ! a system that uses seed integer vector of ! different length, an error message will print. ! </doc> implicit none private public :: ranf public :: get_rnd_seed_length, get_rnd_seed, init_ranf contains !------------------------------------------------------------------- function ranf(seed) ! <doc> ! returns a uniform deviate in [0., 1.) ! The generator is initialized with the given seed if exists, ! otherwise uses the default seed. ! </doc> # if RANDOM == _RANMT_ use mt19937, only: sgrnd, grnd # endif integer, intent(in), optional :: seed real :: ranf # if RANDOM == _RANMT_ if (present(seed)) call sgrnd(seed) ranf = grnd() # else integer :: l integer, allocatable :: seed_in(:) if (present(seed)) then call random_seed(size=l) allocate (seed_in(l)) seed_in(:) = seed call random_seed(put=seed_in) deallocate (seed_in) end if call random_number(ranf) # endif end function ranf !------------------------------------------------------------------- function get_rnd_seed_length() result(l) ! <doc> ! get_rnd_seed_length gets the length of the integer vector for ! the random number generator seed ! </doc> integer :: l # if RANDOM == _RANMT_ l = 1 # else call random_seed(size=l) # endif end function get_rnd_seed_length !------------------------------------------------------------------- subroutine get_rnd_seed(seed) ! <doc> ! get_rnd_seed random number seed integer vector ! </doc> integer, dimension(:), intent(out) :: seed # if RANDOM == _RANMT_ !NOTE: If MT is generator, more codding needs to be done to ! extract seed, so this should be run using only randomize seed = 0 # else call random_seed(get=seed) # endif end subroutine get_rnd_seed !------------------------------------------------------------------- subroutine init_ranf(randomize, init_seed, mult) # if RANDOM == _RANMT_ use mt19937, only: sgrnd, grnd # endif ! <doc> ! init_ranf seeds the choosen random number generator. ! if randomize=T, a random seed based on the date and time is used. ! Otherwise, it sets the seed using init_seed ! In either case, it outputs the initial seed in init_seed ! </doc> implicit none logical, intent(in) :: randomize integer, intent(inout), dimension(:) :: init_seed integer, optional, intent(in) :: mult integer :: lmult = 1, clock # if RANDOM == _RANMT_ if (present(mult)) then lmult = mult end if if (randomize) then call system_clock(COUNT=clock) init_seed(1) = clock * lmult call sgrnd(init_seed(1)) else call sgrnd(init_seed(1) * lmult) end if # else integer :: i, n integer, parameter :: prim1 = 1824261409, prim2 = 1190494759 if (present(mult)) then lmult = mult end if if (randomize) then call random_seed(size=n) call system_clock(count=clock) init_seed = clock * (/(prim1**i, i=1, n)/) + prim2 * lmult * (/(i - 1, i=1, n)/) call random_seed(put=init_seed) else call random_seed(put=init_seed * lmult) end if # endif end subroutine init_ranf end module ran