You can do this by hardcoding some random integers in a subroutine and allowing the user to provide an offset that is added to each of these to get a seed, as shown in the code below, from the previously cited thread. The “varying” random numbers are generated from a seed that also depends on the time, but the “fixed” variates are generated from a seed that depends only on the offset.
module random_mod
implicit none
contains
subroutine set_random_seed(fixed,offset,nburn_random)
logical, intent(in) :: fixed ! if .true., use a fixed seed
integer, intent(in), optional :: offset ! constant added to generated seeds
integer, intent(in), optional :: nburn_random ! # of variates of RANDOM_NUMBER to burn off
integer, parameter :: nburn = 100, nseeds_max = 12, seeds_vec(nseeds_max) = [824514020,218904035,384790913, &
510442021,939900036,939295695,826403327,935378387, &
634734772,413176190,91069182,818551196]
integer :: i,iburn,nseeds,itime,offset_,nburn_random_
integer, allocatable :: seed(:)
real(kind=kind(1.0d0)) :: xran,xseed(nburn + nseeds_max)
nburn_random_ = 100
offset_ = 0
if (present(nburn_random)) nburn_random_ = nburn_random
if (present(offset)) offset_ = offset
call random_seed(size=nseeds)
allocate(seed(nseeds))
if (fixed) then
if (nseeds > nseeds_max) then
seed(:nseeds_max) = seeds_vec + offset_
seed(nseeds_max + 1:) = 0 ! NAG says to set the remaining elements of the seed array to zero to indicate zero entropy
else
seed = seeds_vec(:nseeds) + offset_
end if
else ! set seed based on current time
call system_clock(itime)
seed = itime
call random_seed(put=seed)
call random_number(xseed)
do i=1,nseeds
if (i <= nseeds_max) then
seed(i) = xseed(nburn+i)*1000000000 + offset_
else
seed(i) = 0
end if
end do
end if
call random_seed(put=seed)
do iburn=1,nburn_random_
call random_number(xran)
end do
end subroutine set_random_seed
end module random_mod
program xset_random_seed
use random_mod, only: set_random_seed
implicit none
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: n = 5, nburn_random = 100
real(kind=dp) :: xx(n)
integer :: ifix,offset,iter
character (len=10) :: labels(0:1) = ["varying","fixed "]
do offset=0,2
print*,"offset =",offset
do ifix=0,1
call set_random_seed(fixed=(ifix == 1),offset=offset,nburn_random=nburn_random)
call random_number(xx)
write (*,"(a12,100f10.4)") trim(labels(ifix)),xx
end do
end do
end program xset_random_seed
gfortran output:
c:\fortran\test>a.exe
offset = 0
varying 0.4081 0.5419 0.3093 0.6581 0.4011
fixed 0.4354 0.5414 0.0699 0.0361 0.1993
offset = 1
varying 0.6550 0.8607 0.6869 0.8850 0.5191
fixed 0.7603 0.1589 0.2190 0.9923 0.8324
offset = 2
varying 0.1805 0.6776 0.0371 0.2762 0.6915
fixed 0.6144 0.5729 0.3696 0.7675 0.8280
c:\fortran\test>a.exe
offset = 0
varying 0.9069 0.5286 0.3049 0.9302 0.5947
fixed 0.4354 0.5414 0.0699 0.0361 0.1993
offset = 1
varying 0.4250 0.4837 0.8747 0.3642 0.6122
fixed 0.7603 0.1589 0.2190 0.9923 0.8324
offset = 2
varying 0.5226 0.6213 0.4804 0.5300 0.9239
fixed 0.6144 0.5729 0.3696 0.7675 0.8280
c:\fortran\test>a.exe
offset = 0
varying 0.9680 0.1145 0.3504 0.0164 0.4973
fixed 0.4354 0.5414 0.0699 0.0361 0.1993
offset = 1
varying 0.2824 0.3550 0.8076 0.6022 0.3057
fixed 0.7603 0.1589 0.2190 0.9923 0.8324
offset = 2
varying 0.8616 0.4010 0.5278 0.4778 0.1063
fixed 0.6144 0.5729 0.3696 0.7675 0.8280