This is a very long (and not necessarily interesting) message, so

here's a summary:

- In Intel Fortran Compiler for Linux v6.0, the intrinsic subroutine

RANDOM_NUMBER appears non-trivial to initialise such that the answers

are different each run.

- The seed of 47 integers does not have the (utterly enormous) period

that you might expect.

- The behaviour doesn't violate the standard, but I find it

unwelcome. (This can therefore be taken as a criticism of the

standard. I make suggestions at the end.)

So, code was requested (which is why it's a long message). Here's the

naive version, using the intrinsic CALL RANDOM_SEED, so that "the seed

is set to a processor-dependent value" [M&R]:

program naive

implicit none

integer :: seedsize, i,j

integer, dimension(:), allocatable :: seeder

real :: rannum

call random_seed(size=seedsize)

allocate(seeder(seedsize))

call random_seed()

call random_seed(get=seeder)

print*,'Original seeder = ',seeder

do i = 1,10

do j = 1,100000

call random_number(rannum)

end do

print*,'Rannum = ',rannum,' i,j =',i,j

end do

call random_seed(get=seeder)

print*,'End seeder = ',seeder

end program naive

This gives me the same seed and the same answer every time. I accept

that this behaviour may conform with the letter of the standard.

(Also, the standard is ideally the be-all and end-all -- perhaps I

should not have mentioned the "spirit" of the standard, because

they're soulless documents ;-) However, I maintain that it's not what

I would expect (foolishly reading between the lines of the standard

again!), and it's certainly not what I want.

By the way, the output is exactly the same if you leave out the CALL

RANDOM_SEED(). If you're interested, here it is:

Original seeder =

-1601562402 169322521 394627986 -1357184995 -2081180923

56965885 1856349507 1951970996 1255567620 1915205266 454429071

924954510 1644808607 1539929981 -413943733 -1114698174 597527228

-1569563778 563091226 653517481 809353950 321723845 -584074724

536829429 319514640 1733865238 150641310 1955340372 239346851

673593628 894547138 -1209489884 1145069594 -2012690604 -661653358

940114214 1759564363 1829017686 -1617379710 948871565 -1433709711

-245005923 -880392003 42 21 0 390878531

Rannum = 0.3289424 i,j = 1 100001

Rannum = 0.5514493 i,j = 2 100001

Rannum = 0.2625967 i,j = 3 100001

Rannum = 0.4616343 i,j = 4 100001

Rannum = 0.6555513 i,j = 5 100001

Rannum = 0.7842660 i,j = 6 100001

Rannum = 0.8844690 i,j = 7 100001

Rannum = 0.9361706 i,j = 8 100001

Rannum = 0.6028984 i,j = 9 100001

Rannum = 0.5592919 i,j = 10 100001

End seeder =

-274385219 -550651214 -1067570661 -345264215 877068374

-223122815 1519069735 -1562619851 -313224430 -327784352 1065991410

57642746 -801803914 -1035118596 1120284127 76542739 758038979

165987059 -622839074 -1158575936 -2062930404 1555111375 -241208682

-1607418577 1892720787 -525665010 325623519 1344465106 1404637187

-1263651544 1332452501 -1007854268 895251141 1182948497 -1458124108

863490710 -2120323197 -1727990012 1207273287 -1268248092 344732195

282439358 -326323973 7 29 1 -567881213

Already, we can see that some of the last elements of the seed are

suspiciously low. (Suspicious if we were expecting something like

their full range to be used. If they're not, then why have so many

integers?) I snipped out some spaces above, by the way, to fit things

on lines. From now on, I'll snip out all but the last two lines of

the seeds as well.

What I want is a different set of random numbers each time. The

classic way to do this is to use the system clock in the seed somehow.

(And this may be why the standard isn't very specific on how to

initialise the seed -- because there is no guarantee that the system

clock exists.) Try putting the clock value into all element of the

array seed:

module msimpleseed

implicit none

contains

subroutine new_seed()

integer :: seedsize, i,j, clocker

integer, dimension(:), allocatable :: seeder

call random_seed(size=seedsize)

allocate(seeder(seedsize))

call system_clock(count = clocker)

do i = 1,seedsize

seeder(i) = clocker

end do

call random_seed(put=seeder)

end subroutine new_seed

end module msimpleseed

program simple

use msimpleseed

implicit none

integer :: seedsize, i,j

integer, dimension(:), allocatable :: seeder

real :: rannum

call random_seed(size=seedsize)

allocate(seeder(seedsize))

call new_seed()

[snip -- as for program naive above]

end program simple

This does indeed give different results from run to run, BUT only

slightly different if the delay between the runs is too small. Here

are some results:

Original seeder = [snip]

2031324123 2031324123 2031324123 2031324123 2031324123 2031324123

2031324123 2031324123 2031324123 2031324123 2031324123 2031324123

Rannum = 0.6493683 (but = 0.6486625 5 minutes later)

Rannum = 0.2716912 (but = 0.2709854 5 minutes later)

Rannum = 0.8940141 (but = 0.8933082 5 minutes later)

Rannum = 0.5163370 (but = 0.5156311 5 minutes later)

Rannum = 0.1386598 (but = 0.1379540 5 minutes later)

Rannum = 0.7609827 (but = 0.7602769 5 minutes later)

Rannum = 0.3833055 (but = 0.3825997 5 minutes later)

Rannum = 5.628414E-03 (but = 4.922564E-03 5 minutes later)

Rannum = 0.6279513 (but = 0.6272454 5 minutes later)

Rannum = 0.2502742 (but = 0.2495683 5 minutes later)

End seeder = [snip])

2031324123 2031324123 2031324123 2031324123 2031324123 2031324123

2031324123 -6 2030324123 2030324123 1 1072564379

where I've pasted in alongside the random numbers from five minutes

later. Note that the original (very boring) seed is almost completely

unchanged. The seed entry in the later run was 2034355727 --

noticeably different from the first run -- but the random numbers are

very similar, even after a sequence of 1 million calls.

So the simple use of system clock is not appropriate. (In case you

wondered, it doesn't help to make the seed entries unequal, for

example by

seeder(i) = clocker + i

and the overall behaviour is the same even if you have slightly

different times in each element of seeder, e.g.

call random_delay()

call system_clock( count = clocker)

seeder(i) = clocker

in a DO-loop.

I concluded that perhaps the relevant part of (some relevant element

of) the seed was the higher bits, so here is a more complicated

initialisation:

module mcomplicatedseed

implicit none

contains

subroutine new_seed()

integer :: seedsize, i,j, clocker

integer, dimension(:), allocatable :: seeder

call random_seed(size=seedsize)

allocate(seeder(seedsize))

call system_clock(count = clocker)

do i = 1,seedsize

call random_delay()

call system_clock(count = clocker)

seeder(i) = muck_bits_about(clocker)

end do

call random_seed(put=seeder)

end subroutine new_seed

subroutine random_delay()

integer :: before, after, iter, i

real :: formula

call system_clock(count=before)

iter = 1234 + modulo(before,2345)

do

do i = 1,iter ! waste time with formula

formula = EXP(1.234/i+LOG((1234./(1.+modulo(before,2345)))**0.2345))

end do

call system_clock(count=after)

if ((after-before)>10) exit

iter = iter * (1+modulo(after,20))

! iter increases a lot, so often exceed time limit by more than min.

end do ! infinite loop until time passes

return

end subroutine random_delay

function muck_bits_about(n)

integer :: muck_bits_about

integer, intent(in) :: n

integer :: nbits, i, m

m = n

nbits = bit_size(n)

do i = 0,(nbits-1)/2,2

call mvbits(n,i,1,m,(nbits-1)-i)

call mvbits(n,(nbits-1)-i,1,m,i) ! reflect half the bits

end do

muck_bits_about = m

end function muck_bits_about

end module mcomplicatedseed

program complicated

use mcomplicatedseed

implicit none

integer :: seedsize, i,j

integer, dimension(:), allocatable :: seeder

real :: rannum

call random_seed(size=seedsize)

allocate(seeder(seedsize))

call new_seed()

call random_seed(get=seeder)

print*,'Original seeder = ',seeder

do j = 1,50

call random_number(rannum)

call random_seed(get=seeder)

if (any(seeder(:)==-6)) then ! may be a suspect seed

print*,'Rannum = ',rannum,' j =',j

print*,'Seeder = ',seeder

end if

end do

! now mimic the previous tests...

i = 1

do j = j,100000 ! ie, resume previous j-loop

call random_number(rannum)

end do

print*,'Rannum = ',rannum,' i,j =',i,j

do i = 2,10

do j = 1,100000

call random_number(rannum)

end do

print*,'Rannum = ',rannum,' i,j =',i,j

end do

call random_seed(get=seeder)

print*,'End seeder = ',seeder

end program complicated

The key change is to put some low bits of the system clock value into

high bits of the seed entries (and vice versa). This does indeed

result in random numbers that (to the {*filter*} eye) bear no resemblance

to the previous run's.