domenica 21 marzo 2010

Numeri casuali in Fortran 90, 95 e 2003

Tempo fa, quando su linux, freeBSD ed altri sistemi simili non esisteva un valido compilatore fortran 90 ho usato il compilatore fornito dall intel trovandomi benissimo, ed abituandomi inevitabilmente alla sua implementazione dello standard del linguaggio.

Dopo anni  ho rimesso mano al linguaggio, e non nego con qualche ruggine mentale :), niente di piu' bello che installare gfortran, scrivere due righe di codice e constatare i primi problemi :) infatti, dopo aver compilato il seguente codice:
program prova
implicit none
integer :: i
real     :: r
call random_seed()
do i=1,10
call random_number(r)
write(*,*) r
enddo
end program prova

Mi trovo che ad ogni esecuzione i numeri "pseudo-casuali" generati sono sempre gli stessi.

Installo anche g95 ricompilo e qui le cose cambiano, i numeri generati sono differenti ad ogni esecuzione del codie!

Ma allora che succede?

Penso ad un bug a qualcosa di anomalo, e mi informo... risultato?

Lo stardard è ambiguo circa la generazione di numeri casuali, per cui il comportamento di gfortran è corretto quanto quello di g95, ifort ed altri.

Bene, occorre rimediare, comincio a leggere un po' di documentazione ed ecco questa piccola subroutine, che consiglio di usare come liberia all'interno di un "module".

Usandola si otterrà del codice che genera differenti numeri casuali in ogni esecuzione del programma, che quello che ci sia aspetta :)

Eccovi il codice e buon lavoro, attenzione non funziona con compilatori fortran77 come il g77 :
SUBROUTINE init_random_seed()
INTEGER :: i, n, clock
INTEGER, DIMENSION(:), ALLOCATABLE :: seed

CALL RANDOM_SEED(size = n)
ALLOCATE(seed(n))

CALL SYSTEM_CLOCK(COUNT=clock)

seed = clock + 37 * (/ (i - 1, i = 1, n) /)
CALL RANDOM_SEED(PUT = seed)

DEALLOCATE(seed)
END SUBROUTINE

Nessun commento:

Posta un commento