Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Seeding fails in GNU Fortran ?

61 views
Skip to first unread message

Athanasios Migdalas

unread,
Apr 4, 2012, 11:25:51 AM4/4/12
to
Hi all.

Is anybody else experiencing that seeding in gfortran does not affect the
series of the random numbers generated?

I'm experiencing it both with GNU Fortran (GCC) 4.6.3 20120127 (prerelease),
with
GNU Fortran (GCC) 4.7.0 20120218 (experimental) and with GNU Fortran (SUSE
Linux) 4.4.1 [gcc-4_4-branch revision 150839] !!


/Sakis


--
-------

A.M.

robin....@gmail.com

unread,
Apr 4, 2012, 12:29:24 PM4/4/12
to hera2...@gmail.nada
You really do need to post your code.

Steven G. Kargl

unread,
Apr 4, 2012, 12:44:03 PM4/4/12
to
On Wed, 04 Apr 2012 18:25:51 +0300, Athanasios Migdalas wrote:

> Hi all.
>
> Is anybody else experiencing that seeding in gfortran does not affect the
> series of the random numbers generated?
>

No.

Of course, the above is an extremely poor description.
<hint> Show us the code and expected results </hint>

--
steve

abrsvc

unread,
Apr 4, 2012, 2:26:11 PM4/4/12
to
The apparent effectiveness of the seed value will depend upon a number of factors:

1) The random function being used
2) The range of the random numbers expected (having a choice of 1 or 2 will severely limit the effectiveness of the seed)
3) The values used for the seed.

With no information provided, we can't really comment about your results. Please either address the above or provide a snippet of the actual code that you are using giving the reported results. Please also rpovide the actual seed values and the resultant values from the call to the random number generator. It might also be helpful to report the raw value from the generator PRIOR to the limiting choice list.

Dan

Athanasios Migdalas

unread,
Apr 4, 2012, 5:11:09 PM4/4/12
to
Well, guys,
nothing strange actually (and this works with all other compilers I have
tested). Here it is the seeding I'm attempting:

:
:
CALL RANDOM_SEED(SIZE=seed_size)
ALLOCATE(new_seed(1:seed_size))
CALL DATE_AND_TIME(VALUES=date)
new_seed(1) = SUM(date(1:3)) + SUM(date(5:8))
CALL RANDOM_SEED(PUT=new_seed)
DEALLOCATE(new_seed)
:
:

Now CALL RANDOM_NUMBER(r) will generate the same r:s for every run with
gfortran (versions given previously) and only with gfortran.

/Sakis



--
-------
e-mail: replace <nada> by <com>
A.M.

Steven G. Kargl

unread,
Apr 4, 2012, 5:19:22 PM4/4/12
to
On Thu, 05 Apr 2012 00:11:09 +0300, Athanasios Migdalas wrote:

> Well, guys,
> nothing strange actually (and this works with all other compilers I have
> tested). Here it is the seeding I'm attempting:
>
> :
> :
> CALL RANDOM_SEED(SIZE=seed_size)
> ALLOCATE(new_seed(1:seed_size))
> CALL DATE_AND_TIME(VALUES=date)
> new_seed(1) = SUM(date(1:3)) + SUM(date(5:8))
> CALL RANDOM_SEED(PUT=new_seed)
> DEALLOCATE(new_seed)
> :
> :
>
> Now CALL RANDOM_NUMBER(r) will generate the same r:s for every run with
> gfortran (versions given previously) and only with gfortran.
>

Well, the code is invalid. seed_size does not equal 1. So, you have
assigned 'SUM(date(1:3)) + SUM(date(5:8))' to new_seed(1) and
left new_seed(2:seed_size) uninitialized.


program foo

implicit none

integer fd, s
integer, allocatable :: i(:)
real x

call random_seed(size=s)

allocate(i(s))

fd = 23
open(unit=fd, file='/dev/random', access='stream', &
& status='old', iostat=s)
if (s /= 0) then
stop 'Install a better OS'
end if

read(fd) i

call random_seed() ! Set seeds to default values
call random_number(x)
print *, x

do s = 1, 5
call random_seed(put=i)
call random_number(x)
print *, x
read(fd) i
end do

call random_seed() ! (Re)set seeds to default values
call random_number(x)
print *, x

end program foo

troutmask:sgk[206] gfc4x -o foo foo.f90 && ./foo
0.997559547
0.121315241
0.208814085
0.886431217
4.66393232E-02
0.721068799
0.997559547

Looks like it works to me.

--
steve


Athanasios Migdalas

unread,
Apr 4, 2012, 8:15:16 PM4/4/12
to
Steven,

I don't mean that. I mean, that a second run of the program will generate
the same sequence! Retry foo, a second time, what will you get. And
concerning the "invalidity" of the code, you don not need to put a new value
in every element of the seed. So, no, I don't think that the code is
invalid.

Richard Maine

unread,
Apr 4, 2012, 10:03:08 PM4/4/12
to
Athanasios Migdalas <hera2...@gmail.nada> wrote:

> Steven G. Kargl wrote:

> > Well, the code is invalid. seed_size does not equal 1. So, you have
> > assigned 'SUM(date(1:3)) + SUM(date(5:8))' to new_seed(1) and
> > left new_seed(2:seed_size) uninitialized.

> I don't mean that. I mean, that a second run of the program will generate
> the same sequence! Retry foo, a second time, what will you get. And
> concerning the "invalidity" of the code, you don not need to put a new value
> in every element of the seed. So, no, I don't think that the code is
> invalid.

That's not what the standard says, as far as I can see. Whether it might
happen to work on any particular compiler is another matter, but I'd say
that the standard is pretty explicit that you *DO* have to give a value
to every element. Without every element having a value, the array is not
defined, and a reference to it is invalid. The PUT argument to
random_seed is explicitly described in the standard as having INTENT(IN)
- not INTENT(INOUT), as would be required to retain previous values.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

steve

unread,
Apr 4, 2012, 10:14:05 PM4/4/12
to
If you print out the "value" of new_seed after you've
set new_seed(1), I bet you get something like "2145 0
0 0 0 0 0 0 0 0 0 0". Guess what all those zeros do?
Try changing the code to only initialize new_seed(12).

--
steve

steve

unread,
Apr 4, 2012, 10:19:11 PM4/4/12
to
On Apr 4, 5:15 pm, Athanasios Migdalas <hera2011...@gmail.nada> wrote:
I forgot to include this in my other reply.

If I re-run the program 'foo' that I posted (which
I encourage you to try), it will generate a different
output on each execution except for the first and
last number, which I've shown to show you that gfortran
sets the PRNG to the same default sequence if you
call random_seed() without an argument or if you
never call random_seed().

--
steve

glen herrmannsfeldt

unread,
Apr 4, 2012, 10:54:03 PM4/4/12
to
steve <kar...@comcast.net> wrote:

(snip, someone wrote)
>> I don't mean that. I mean, that a second run of the program
>> will generate the same sequence! Retry foo, a second time,
>> what will you get. And concerning the "invalidity" of the code,
>> you don not need to put a new value in every element of the
>> seed. So, no, I don't think that the code is invalid.

> If you print out the "value" of new_seed after you've
> set new_seed(1), I bet you get something like "2145 0
> 0 0 0 0 0 0 0 0 0 0". Guess what all those zeros do?
> Try changing the code to only initialize new_seed(12).

I did comment before about how it would be nice for the
standard to specify how to get a good seed if you have less
than a full seed worth of array elements.

It is certainly possible that a single integer seed followed
by zeros gives a poor seed, or even random numbers that don't
depend on the first element. Putting the same value in all
array elements might be better, or might be worse. (I believe
that is more common, but the effect is still not known.)

I do agree, though, that leaving the array elements undefined
is not a valid seed.

-- glen

Ron Shepard

unread,
Apr 5, 2012, 3:09:52 AM4/5/12
to
In article <1333584326.99265@athprx03>,
Athanasios Migdalas <hera2...@gmail.nada> wrote:

> And
> concerning the "invalidity" of the code, you don not need to put a new value
> in every element of the seed. So, no, I don't think that the code is
> invalid.

The fix is simple enough.

new_seed(:) = SUM(date(1:3)) + SUM(date(5:8))

or something equally arbitrary. Why argue about the validity of
using uninitialized values?

$.02 -Ron Shepard

Dan Nagle

unread,
Apr 5, 2012, 8:29:29 AM4/5/12
to
Hello,

On 2012-04-05 02:54:03 +0000, glen herrmannsfeldt said:
>
> I did comment before about how it would be nice for the
> standard to specify how to get a good seed if you have less
> than a full seed worth of array elements.

That would be difficult, given that it's processor-dependent
(because the underlying RNG is) and it's an art form anyway.

Sizes of seeds range from ones, to tens, to hundreds.

--
--
Cheers!

Dan Nagle

robin....@gmail.com

unread,
Apr 5, 2012, 8:59:41 AM4/5/12
to hera2...@gmail.nada
On Thursday, 5 April 2012 10:15:16 UTC+10, Athanasios Migdalas wrote:

> I don't mean that. I mean, that a second run of the program will generate
> the same sequence! Retry foo, a second time, what will you get. And
> concerning the "invalidity" of the code, you don not need to put a new value
> in every element of the seed. So, no, I don't think that the code is
> invalid.

Every element passed to RANDOM_DEED must have a value.
Garbage in any uninitialized locations could cause a crash.

robin....@gmail.com

unread,
Apr 5, 2012, 9:10:51 AM4/5/12
to
On Thursday, 5 April 2012 07:19:22 UTC+10, Steven G. Kargl wrote:

> Well, the code is invalid. seed_size does not equal 1. So, you have
> assigned 'SUM(date(1:3)) + SUM(date(5:8))' to new_seed(1) and
> left new_seed(2:seed_size) uninitialized.

In general, seed_size can be any value including 1.
When it is 1, the code would be valid --
but ONLY on that particular compiler.

glen herrmannsfeldt

unread,
Apr 5, 2012, 9:51:52 AM4/5/12
to
Dan Nagle <danl...@me.com> wrote:

(snip, I wrote)
>> I did comment before about how it would be nice for the
>> standard to specify how to get a good seed if you have less
>> than a full seed worth of array elements.

> That would be difficult, given that it's processor-dependent
> (because the underlying RNG is) and it's an art form anyway.

Yes, but it is even harder this way.

Well, the easy way is to have a call option for a single integer,
so that the routine itself can figure it out.

Another way is to specify, for example, that the user zero
pad the array, the routine would know that, check for the zeros,
and process appropriately.

> Sizes of seeds range from ones, to tens, to hundreds.

Yes. And bad seeds give bad results.

-- glen

Ron Shepard

unread,
Apr 5, 2012, 10:27:10 AM4/5/12
to
In article <jlk81o$557$1...@speranza.aioe.org>,
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Well, the easy way is to have a call option for a single integer,
> so that the routine itself can figure it out.

That is already simple enough to achieve. For example

new_seed(:) = int

>> Sizes of seeds range from ones, to tens, to hundreds.

> Yes. And bad seeds give bad results.

In principle, that should not happen. The seed only determines the
starting point in the predetermined cyclic sequence of random
numbers. With a good underlying PRNG, there should be no bad
starting points. Of course, actual implementations can be flawed.

$.02 -Ron Shepard

glen herrmannsfeldt

unread,
Apr 5, 2012, 11:41:54 AM4/5/12
to
Ron Shepard <ron-s...@nospam.comcast.net> wrote:

(snip, I wrote)
>> Well, the easy way is to have a call option for a single integer,
>> so that the routine itself can figure it out.

> That is already simple enough to achieve. For example

> new_seed(:) = int

That assumes that such makes a good seed. It might, but then again
it might not. For some PRNGs that might make a very poor seed.
Likely to be better than zero padded, but you can't be sure
of that. One that did a lot of subtracting of array elements
might give bad results.

>>> Sizes of seeds range from ones, to tens, to hundreds.

>> Yes. And bad seeds give bad results.

> In principle, that should not happen. The seed only determines
> the starting point in the predetermined cyclic sequence of random
> numbers. With a good underlying PRNG, there should be no bad
> starting points. Of course, actual implementations can be flawed.

Some people run off some number of random numbers before using
the actual results. But also some do give poor results with some
seeds, even if they give good results for the vast majority of seeds.

What I would have liked to see was separate calls for saving the
state and for seeding the sequence. The latter would allow the
routine to generate a good seed from whatever the user supplied,
in a manner appropriate for the given generator.

-- glen

Athanasios Migdalas

unread,
Apr 5, 2012, 5:26:29 PM4/5/12
to
I'm sorry, I wrote the code by heart and I missed the GET. The true code is
here:

SUBROUTINE Set_Random_Seed()
IMPLICIT NONE
INTEGER, DIMENSION(:), ALLOCATABLE :: new_seed
INTEGER seed_size, date(8)
CALL RANDOM_SEED(SIZE=seed_size)
ALLOCATE(new_seed(1:seed_size))
CALL RANDOM_SEED(GET=new_seed)
CALL DATE_AND_TIME(VALUES=date)
new_seed(1) = new_seed(1) + SUM(date(1:3)) + SUM(date(5:8))
CALL RANDOM_SEED(PUT=new_seed)
DEALLOCATE(new_seed)
END SUBROUTINE Set_Random_Seed

So, does this code leave *anything* uninitialized that would motivate the
same sequence of numbers? That is, is the *default* seed, the one obtained
using GET, uninitialized? If not, why changing it first element will not be
enough in order to get different sequences of numbers with different runs?

In any case, changing to

new_seed(:) = SUM(date(1:3)) + SUM(date(5:8))

solves the problem.

Thank you all who contributed. I see the light!

Gib Bogle

unread,
Apr 5, 2012, 5:30:29 PM4/5/12
to
On 6/04/2012 9:26 a.m., Athanasios Migdalas wrote:
> robin....@gmail.com wrote:
>
>>
>> On Thursday, 5 April 2012 07:19:22 UTC+10, Steven G. Kargl wrote:
>>
>>> Well, the code is invalid. seed_size does not equal 1. So, you have
>>> assigned 'SUM(date(1:3)) + SUM(date(5:8))' to new_seed(1) and
>>> left new_seed(2:seed_size) uninitialized.
>>
>> In general, seed_size can be any value including 1.
>> When it is 1, the code would be valid --
>> but ONLY on that particular compiler.
>
> I'm sorry, I wrote the code by heart and I missed the GET.

In situations like this it is really necessary to use copy-and-paste.

Richard Maine

unread,
Apr 5, 2012, 5:35:38 PM4/5/12
to
Gib Bogle <g.b...@auckland.ac.nz> wrote:

> On 6/04/2012 9:26 a.m., Athanasios Migdalas wrote:
> >>
> >> On Thursday, 5 April 2012 07:19:22 UTC+10, Steven G. Kargl wrote:
> >>
> >>> Well, the code is invalid. seed_size does not equal 1. So, you have
> >>> assigned 'SUM(date(1:3)) + SUM(date(5:8))' to new_seed(1) and
> >>> left new_seed(2:seed_size) uninitialized.

> > I'm sorry, I wrote the code by heart and I missed the GET.
>
> In situations like this it is really necessary to use copy-and-paste.

Yep, and that's an example of why. It makes a big difference. Anyway, to
answer the elided question, I don't see anything obviously wrong with
the code that includes the GET. I can't comment on the specific effect
on the random number generator, as I don't know the details of the one
that gFortran uses.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

glen herrmannsfeldt

unread,
Apr 5, 2012, 5:56:39 PM4/5/12
to
Athanasios Migdalas <hera2...@gmail.nada> wrote:

(snip)
> I'm sorry, I wrote the code by heart and I missed the GET.
> The true code is here:

(snip)
> CALL RANDOM_SEED(GET=new_seed)
> CALL DATE_AND_TIME(VALUES=date)
> new_seed(1) = new_seed(1) + SUM(date(1:3)) + SUM(date(5:8))
> CALL RANDOM_SEED(PUT=new_seed)

(snip)
> So, does this code leave *anything* uninitialized that would
> motivate the same sequence of numbers? That is, is the
> *default* seed, the one obtained using GET, uninitialized?
> If not, why changing it first element will not be enough in
> order to get different sequences of numbers with different runs?

As far as I know, the standard doesn't say anything about which
elements of seed are used, or how they are used.

There are some generators that use a number of 32 bit values,
in different 32 bit algorithms, and then return the values in
some order. In that case, if you changed one it might not change
the early returned numbers.

There also might be some that completely ignore the first
array element.

-- glen

Dick Hendrickson

unread,
Apr 5, 2012, 7:13:49 PM4/5/12
to
On 4/5/12 4:56 PM, glen herrmannsfeldt wrote:
> Athanasios Migdalas<hera2...@gmail.nada> wrote:
>
> (snip)
>> I'm sorry, I wrote the code by heart and I missed the GET.
>> The true code is here:
>
> (snip)
>> CALL RANDOM_SEED(GET=new_seed)
>> CALL DATE_AND_TIME(VALUES=date)
>> new_seed(1) = new_seed(1) + SUM(date(1:3)) + SUM(date(5:8))
>> CALL RANDOM_SEED(PUT=new_seed)
>
> (snip)
>> So, does this code leave *anything* uninitialized that would
>> motivate the same sequence of numbers? That is, is the
>> *default* seed, the one obtained using GET, uninitialized?
>> If not, why changing it first element will not be enough in
>> order to get different sequences of numbers with different runs?
>
> As far as I know, the standard doesn't say anything about which
> elements of seed are used, or how they are used.

Indeed! All it says is "Returns one pseudorandom number or an array of
pseudorandom numbers from the uniform distribution over the range 0 <= x
< 1." So, it could always return .314 and meet the rules. But, vendors
try to do the right thing and the RNGs will meet reasonable (minimum)
definitions/expectations of random numbers.

Dick Hendrickson

Richard Maine

unread,
Apr 6, 2012, 2:01:11 AM4/6/12
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
[about random_seed]

> What I would have liked to see was separate calls for saving the
> state and for seeding the sequence. The latter would allow the
> routine to generate a good seed from whatever the user supplied,
> in a manner appropriate for the given generator.

Note that your description of what you would like to be allowed is
pretty much exactly what the standard does, in fact, say. The standard
pretty pointedly does not say that the PUT value becomes the seed.
Rather, it says "It is used in a processor-dependent manner to determine
the value of the seed..." It then goes on to explain that a GET that
imediately follows a PUT might return a different value than was PUT. I
interpret this as being because the value PUT might have been massaged
to generate a good seed.

About the only difference I see between your description and that of the
standard is that yours specifies that the seed generated should be a
"good" one, while the standard is silent on the matter of quality.

glen herrmannsfeldt

unread,
Apr 6, 2012, 6:38:18 AM4/6/12
to
Richard Maine <nos...@see.signature> wrote:

(snip, I wrote)
>> What I would have liked to see was separate calls for saving the
>> state and for seeding the sequence. The latter would allow the
>> routine to generate a good seed from whatever the user supplied,
>> in a manner appropriate for the given generator.

> Note that your description of what you would like to be allowed is
> pretty much exactly what the standard does, in fact, say. The standard
> pretty pointedly does not say that the PUT value becomes the seed.
> Rather, it says "It is used in a processor-dependent manner to determine
> the value of the seed..." It then goes on to explain that a GET that
> imediately follows a PUT might return a different value than was PUT. I
> interpret this as being because the value PUT might have been massaged
> to generate a good seed.

But then it goes on to say that "either value as the PUT argument in
a subsequent call to RANDOM_SEED shall result in the same sequence
of pseudo-random numbers being generated."

> About the only difference I see between your description and that of the
> standard is that yours specifies that the seed generated should be a
> "good" one, while the standard is silent on the matter of quality.

Other languages have both operations, and both are useful.

The above restriction doesn't allow for as much massaging as
might allow for a better generator. Also, if different values can
give the same sequence, then not all of the supplied PUT value
can go into the seed. That seems to be how this thread got started...

-- glen

Richard Maine

unread,
Apr 6, 2012, 11:35:33 AM4/6/12
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:
[discussion about random_seed]

Well, I suppose I shouldn't spend too much effort in defending the
standard's treatment of random number generation. Even the person who
allegedly (it was before my time on the committee, so I wasn't there)
wrote the words once said that he had intended to specify a few more
things about seeding, but failed to actually write that part and forgot
that he hadn't. Thus, those parts ended up getting left processor
dependent in ways that have subsequently caused annoyances.

I recall this because the author tried to use this explanation as
justification for adding the specification in response to a defect
report. However, just because he wrote the words, didn't give him
"ownership" of them. The specification that he claimed had been his
intention in the first place was not presented to, discusssed, or voted
on by the committee during the development of f90, so his personal
intent could not be taken as that of the committee as a whole.

In the interim, multiple vendors had implemented random number
generators using different approaches, as allowed by the words actually
in the standard. Redoing the standard's specification at that point
would have been an incompatible change, invalidating existing compilers
and code. I'm sure there are still people who think it should have been
changed anyway, but that's not what passed. It was left processor
dependent and remains so today.

(No I don't recall exactly what variant he claimed to have intended. It
was quite a while ago. But I do very much recall the attempt to claim
that his previously unwritten personal intent should be taken as the
"intent of the committee". It had to do with the behavior when the
program never called random_seed or when it was called with no
arguments.)

michael...@compuserve.com

unread,
Apr 6, 2012, 3:02:10 PM4/6/12
to
The PRNG was first added to the draft of Fortran 90 (then known as Fortran 8x) at the meeting in Halifax in August, 1986. Not only do I still remember the lobster dinner, but I still have my notes of the meeting. FWIW, this is what I wrote:

" A persistent request has been for Fortran to provide a random number intrinsic function [sic]. As was clear from the discussion, it is not intended that the results of the function be portable, only the interface. There were two proposals, both containing a means to set or extract the seed, one being a function, the other a subroutine. The function was initially favoured 20-5-7. There was a long discussion on the effect a function has on optimization and on side-effects - the fact that the value of the seed is changed at each call is a clear side-effect and therefore inappropriate for a function. Additionly, a scalar value returned as part of an array-valued expression would broadcast its single value over the whole expression, which would certainly surprise the naive user. Sentiment turned against the function, 8-11-3, and towards the subroutine, 13-3-14. (I voted against both as I had increasing misgivings about the wisdom of standardizing on something which is inherently non-portable without appearing to be so.) After more furious[!] debate, the subroutine was finally passed 15-12. My motion to change the range from 0.0 <= x <= 1.0 to 0.0 <= x < 1.0 the passed 28-0. I would be happy to discuss this intrinsic with anyone interesred."

Regards,

Mike Metcalf

Richard Maine

unread,
Apr 6, 2012, 3:52:21 PM4/6/12
to
<michael...@compuserve.com> wrote:

> Am Freitag, 6. April 2012 17:35:33 UTC+2 schrieb Richard Maine:

> > Well, I suppose I shouldn't spend too much effort in defending the
> > standard's treatment of random number generation. Even the person who
> > allegedly (it was before my time on the committee, so I wasn't there)
> > wrote the words once said that he had intended to specify a few more
> > things about seeding, but failed to actually write that part and forgot
> > that he hadn't. Thus, those parts ended up getting left processor
> > dependent in ways that have subsequently caused annoyances.
..
> > (No I don't recall exactly what variant he claimed to have intended. It
> > was quite a while ago. But I do very much recall the attempt to claim
> > that his previously unwritten personal intent should be taken as the
> > "intent of the committee". It had to do with the behavior when the
> > program never called random_seed or when it was called with no
> > arguments.)

> The PRNG was first added to the draft of Fortran 90 (then known as Fortran
8x) at the meeting in Halifax in August, 1986. Not only do I still
remember the lobster dinner, but I still have my notes of the meeting.
FWIW, this is what I wrote:
[elided]

The problem I recall had more to do with whether you get the same result
each time or a different result each time if you call random_seed with
no arguments, or if you don't call random_seed at all.
0 new messages