Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gfortran and random numbers

I am trying to compile the following simple code using Gfortran 4.7 from mac-ports (OS-X):

program main

implicit none

integer :: n = 1, clock, i

integer, dimension(1) :: iseed

! initialize the random number generator
call random_seed(size = n)

call system_clock(COUNT=clock)

iseed = clock + 37 * (/ (i - 1, i = 1, n) /)
! iseed = clock
! iseed = abs( mod((clock*181)*((1-83)*359), 104729) )
call random_seed(PUT = iseed)

end program main

and have this error:

gfortran-mp-4.7  tmp.f90
tmp.f90:17.23:

call random_seed(PUT = iseed)
                   1
Error: Size of 'put' argument of 'random_seed' intrinsic at (1) too small (1/12)

I don't use Fortran at all (I am a C++ guy), so would really appreciate if someone could help and make it working.

p.s. On a similar issue i found couple of forum posts, the current uncomment solution is similar to the one mentioned in this GCC bug report.

The one with abs is mentioned in this stack overflow post (added it without PID since i don't run in parallel anyway.

UPDATE:

the following works:

program main

implicit none

integer :: n = 12, clock, i

integer, dimension(:), allocatable :: iseed

! initialize the random number generator
allocate(iseed(n))
call random_seed(size = n)

call system_clock(COUNT=clock)

iseed = clock + 37 * [(i, i = 0,n-1)]
call random_seed(PUT = iseed)

end program main
like image 422
Denis Avatar asked Jan 21 '14 10:01

Denis


People also ask

How do I generate a random number in Fortran?

Description: RAND(FLAG) returns a pseudo-random number from a uniform distribution between 0 and 1. If FLAG is 0, the next number in the current sequence is returned; if FLAG is 1, the generator is restarted by CALL SRAND(0) ; if FLAG has any other value, it is used as a new seed with SRAND .

How do you call a random number in Fortran 90?

Fortran 90 introduced a pseudo-random number generator (PRNG) to the language standard. The routine random_number() returns a single number or an array of numbers from the uniform distribution over the range 0 ≤ x < 1.

What is the use of GFortran?

The GNU gfortran compiler can be used for both the compilation phase and the linking phase of creating executable files. Prints out the version of the compiler. This option is usually used by itself (if at all). Compiles source code files to object files and stops.

How do I use random seed in Fortran?

The Fortran random number generator has a "seed" value which it uses to start its sequence from. You can change this value using using the RANDOM_SEED intrinsic subroutine. The way this is done in a completely portable way (i.e. that can be run on any machine) is complicated.


1 Answers

To amplify somewhat on @Yossarian's comment, this

call random_seed(size = n)

returns, in n, the size of the rank 1 integer array that you have to use if you want to initialise the RNG. I'd suggest making iseed allocatable by changing its declaration to:

integer, dimension(:), allocatable :: iseed

then, after getting a value for n, allocate it:

allocate(iseed(n))

populate it with your favourite values, then put it.

You might be able to allocate and populate it in one statement like this:

allocate(iseed(n), source = clock + 37 * [(i, i = 0,n-1)])

I write might because this depends on how up to date your compiler is.

EDIT, after OP comment

No, you have not quite understood what I suggested.

Get a value for n by executing

call random_seed(size = n)

don't initialise n to 12.

Then allocate the array and populate it, either in one statement (using sourced allocation) or an allocate statement followed by an assignment.

In

allocate(iseed(n))
call random_seed(size = n)

the sequence of operations is incorrect. This sets iseed to have 12 elements (which is the value of n when the first statement is executed), and then sets n to the size of the array required by the RNG. So long as that is 12 you won't see any problems, but as soon as you port your code to another compiler, possibly even another version of the same compiler, you risk running into an RNG which requires an integer array of a different size. There is no need to hardwire a value into your code, so don't.

like image 130
High Performance Mark Avatar answered Sep 19 '22 09:09

High Performance Mark