Re: compiler independent random_seed() (newbie)



In article <f9i2iv$jmt$1@xxxxxxxxxxxxxxxxxxxxx>,
Roland Rau <roland.rau@xxxxxxxxx> writes:

program simpleg95
implicit none
real :: x

call random_seed()
call random_number(x)

print *, x

end program simpleg95

This works great on a Computer using WinXPPro SP2 with a Pentium 4
processor and the G95 compiler (g95 0.91, gcc 4.03 on cygwin). However,
if I want to use gfortran (4.30) it compiles correctly but does always
yield the same result for 'x'. I searched for it and it seems that is
okay with the Fortran standard.

So, my actual question is:
Is there a compiler-independent quick way to obtain different random
numbers?

With regards random_seed(), the Fortran 95 standard states: "If no argument
is present, the processor assigns a processor-dependent value to the seed."
gfortran's behavior is to reset the PRNG with a specific set of the
processor-dependent values. It's not surprising you got the same result.

I searched and found a solution on the web which works somehow (I
changed it slightly and put in some additional print statements). The
random numbers are, unfortunately, not really random, although I am
taking the miliseconds from the date and do about 1e06 runs (whereas
G95 passes my own tests of randomness [1]).

program simplegfortran
implicit none
integer :: idate(8)
integer, allocatable :: iseed(:)
real :: x
call date_and_time(VALUES=idate)
print *, idate
allocate( iseed(8) )
iseed = idate(8)
print *, iseed
call random_seed(PUT=iseed)
call random_number(x)
print *, x
deallocate ( iseed )
end program simplegfortran


You need to define 'not really random'. One normally initializes
the PRNG and then draws a (large) sequence from that generator.
That sequence will be uniformly distributed over [0,1). Your test
above has at most 999 independent random seeds. With 1e6 runs using
only 999 possible seeds and reseeding the generator on each run, you
are generating at most 999 random numbers.

troutmask:kargl[227] ./z
2007 8 10 -420 10 16 24 689
689 689 689 689 689 689 689 689
0.6058535
troutmask:kargl[228] ./z
2007 8 10 -420 10 16 26 965
965 965 965 965 965 965 965 965
0.4368997
troutmask:kargl[229] ./z
2007 8 10 -420 10 16 27 728
728 728 728 728 728 728 728 728
0.3210087
troutmask:kargl[230] ./z
2007 8 10 -420 10 16 28 625
625 625 625 625 625 625 625 625
2.2209942E-02

Here's a slightly better test for randomness where 1000000
RN are drawn from a given sequence initialized by your method.

program simplegfortran
implicit none
integer, parameter :: m = 1000000
integer :: idate(8), n(10)
integer, allocatable :: iseed(:)
real :: x(m)
call date_and_time(VALUES=idate)
allocate( iseed(8) )
iseed = idate(8)
call random_seed(PUT=iseed)
call random_number(x)
deallocate ( iseed )
n(1) = count(x < 0.1)
n(2) = count(x < 0.2) - n(1)
n(3) = count(x < 0.3) - sum(n(1:2))
n(4) = count(x < 0.4) - sum(n(1:3))
n(5) = count(x < 0.5) - sum(n(1:4))
n(6) = count(x < 0.6) - sum(n(1:5))
n(7) = count(x < 0.7) - sum(n(1:6))
n(8) = count(x < 0.8) - sum(n(1:7))
n(9) = count(x < 0.9) - sum(n(1:8))
n(10) = m - sum(n(1:9))
print '(10I7)', n
end program simplegfortran

troutmask:kargl[220] ./z
100384 99801 99940 99960 99752 100404 100499 99395 100022 99843


--
Steve
http://troutmask.apl.washington.edu/~kargl/
.