random_seed() gives same seed every time 
Author Message
 random_seed() gives same seed every time

In Intel fortran Compiler for Linux, version 6.0, the call to
random_seed() gives the same seed (and hence the same random_number
sequence) on repeated calls.  This is unwelcome behaviour -- contrary
to the spirit of the standard, surely?  I'll report it as a bug to
Intel.

It's even more unwelcome if you can't initialise the sequence easily
and nicely.  This is true here, because I get very non-random results
when I use some straightforward ways of concocting a seed from the
system clock.  The results can stay similar (even after a delay of 5
minutes and after a sequence of 5000 random_number calls).  The
algorithm seems to depend strongly on the highest digits of the seed,
and _very_ weakly on the smallest digits -- BAD doggie!

AND... when I get some seeds that don't obviously{*filter*}up -- by
reversing some of the bits of the system_clock results -- the seed
sometimes collapses until most values are -6.  This happens more
frequently than you'd expect if all 47 integers were part of the cycle
;-).

But hey! enough whingeing!  I like the price of the compiler, and I
can find my own generator.  And Fortran 95 is very jolly -- optional
arguments, whizzy arrays -- I used a pointer the other day.

Ed Wynn



Wed, 20 Oct 2004 03:16:21 GMT  
 random_seed() gives same seed every time

Quote:

> In Intel Fortran Compiler for Linux, version 6.0, the call to
> random_seed() gives the same seed (and hence the same random_number
> sequence) on repeated calls.  This is unwelcome behaviour -- contrary
> to the spirit of the standard, surely?

I see nothing in either the letter or the spirit of the standard that
disallows this behavior.  I have heard one of the people involved in
writing the original specs for this stuff explain what he intended,
but not even a hint of the intention made its way into the actual
words of the standard.  This was nearly a decade after the standard
was released; it was even after the next standard (f95) was released.
To tell the truth, I don't even recall what he said his intent was, my
attitude being that it didn't really matter - one person's unverified
memory of what he intended to write doesn't constitute an official
interpretation of the standard.  If I recall correctly, mine echoed
a pretty widespread reaction to an attempt to rewrite the standard
along the lines that he recalled as intended - that the actual words
of the standard would stand as written.  They weren't, after all
obviously wrong or inconsistent - just different from what he recalled
as intending.

Be that a lesson: precision of exposition does matter; if you don't
actually express what you mean, sometimes the message won't come across.

--
Richard Maine                       |  Good judgment comes from experience;
email: my last name at host.domain  |  experience comes from bad judgment.
host: altair, domain: dfrc.nasa.gov |        -- Mark Twain



Wed, 20 Oct 2004 04:39:48 GMT  
 random_seed() gives same seed every time


Quote:
>In Intel Fortran Compiler for Linux, version 6.0, the call to
>random_seed() gives the same seed (and hence the same random_number
>sequence) on repeated calls.  This is unwelcome behaviour -- contrary
>to the spirit of the standard, surely?  I'll report it as a bug to
>Intel.

        Can you post some code.  There are aspects to random_seed() that
I find "non-intuitive" (much like the current discussion of the
result of MAXLOC() for a 1-D array :-).  There are "gotchas" if you don't
follow the documentation rigorously.

Quote:
>It's even more unwelcome if you can't initialise the sequence easily
>and nicely.  This is true here, because I get very non-random results
>when I use some straightforward ways of concocting a seed from the
>system clock.

        For example, you do realise that the "seed" is an array, oder?

Quote:
>AND... when I get some seeds that don't obviously{*filter*}up -- by
>reversing some of the bits of the system_clock results -- the seed
>sometimes collapses until most values are -6.  This happens more
>frequently than you'd expect if all 47 integers were part of the cycle
>;-).

        Code, again -- I don't understand this comment!  Tho' perhaps
it implies that call random_seed(size=i) sets i to 47 and my comments
above are unwarranted.

--

        KotPT -- "for stupidity above and beyond the call of duty".



Wed, 20 Oct 2004 06:10:04 GMT  
 random_seed() gives same seed every time
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.

However, there is more strange behaviour to come, hence the fiddly
checks in the main program above.  Quite often, one of the later
elements of the array acquires the value -6 and keeps it
...

read more »



Sat, 23 Oct 2004 01:14:53 GMT  
 random_seed() gives same seed every time


Quote:
>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.

        OK, you've convinced me that you know how to call the intrinsics
and that the behaviour you are seeing is undesireable.  For what it's
worth, here's what Digital F90 on UNIX returns for three successive
runs of your naive program:

idr_ax9> ./a.out
 Original seeder =    167984345   540266122
 Rannum =   0.7779190         i,j =           1      100001
 Rannum =   0.6423636         i,j =           2      100001
 Rannum =   0.7967523         i,j =           3      100001
 Rannum =   0.9125864         i,j =           4      100001
 Rannum =   0.7511169         i,j =           5      100001
 Rannum =   9.2068158E-02     i,j =           6      100001
 Rannum =   0.2078296         i,j =           7      100001
 Rannum =   0.7795051         i,j =           8      100001
 Rannum =   0.4234307         i,j =           9      100001
 Rannum =   0.2548643         i,j =          10      100001
 End seeder =   1543415778   996098854
idr_ax9> ./a.out
 Original seeder =    168049881   541314698
 Rannum =   0.9735197         i,j =           1      100001
 Rannum =   0.3752931         i,j =           2      100001
 Rannum =   0.7585759         i,j =           3      100001
 Rannum =   0.5238660         i,j =           4      100001
 Rannum =   0.4741749         i,j =           5      100001
 Rannum =   0.3157667         i,j =           6      100001
 Rannum =   0.6956461         i,j =           7      100001
 Rannum =   1.8549249E-02     i,j =           8      100001
 Rannum =   0.5730729         i,j =           9      100001
 Rannum =   0.9580694         i,j =          10      100001
 End seeder =   1243688753  1333733940
idr_ax9> ./a.out
 Original seeder =    168115417   542363274
 Rannum =   0.1691206         i,j =           1      100001
 Rannum =   0.1082226         i,j =           2      100001
 Rannum =   0.7203994         i,j =           3      100001
 Rannum =   0.1351456         i,j =           4      100001
 Rannum =   0.1972328         i,j =           5      100001
 Rannum =   0.5394652         i,j =           6      100001
 Rannum =   0.1834626         i,j =           7      100001
 Rannum =   0.2575934         i,j =           8      100001
 Rannum =   0.7227153         i,j =           9      100001
 Rannum =   0.6612746         i,j =          10      100001
 End seeder =    943961728  1671369026

        You should probably take this up with Intel. IIRC they do offer
support for their trial version.

--

        KotPT -- "for stupidity above and beyond the call of duty".



Sun, 24 Oct 2004 19:25:35 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Newbie questions: real-to->int, getting time for seed

2. Seeding SRAND() with time of day

3. Strange link error every 2. time

4. Processing every time a record is read.

5. GPF in Clarion every time i do this

6. Clarion Rewrites CLW file Every time I load it

7. How do I acquire 1 image every time an external trigger fires

8. execute code every set time

9. VI that gets bigger every time it runs

10. update every second or every resched()?

11. $recordset->Close() fails every time

12. I catch nimda every time I surf

 

 
Powered by phpBB® Forum Software