Tecnicamente's Weblog

Just another WordPress.com weblog

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

2 risposte a “Numeri casuali in Fortran 90, 95 e 2003

  1. Federica 20 ottobre 2014 alle 2:17 pm

    Ciao, so che il post è vecchio ma ho un problema…
    Ho provato a usare questa subroutine per ottenere dei numeri casuali a ogni iterazione di un ciclo while. Il problema è i numeri che ottengo sono effettivamente diversi ogni volta che faccio il girare il programma, ma all’interno del ciclo sono tutti uguali, mentre io ho bisogno di un numero diverso per ogni iterazione. Ho paura di non essermi spiegata troppo bene, chiedo scusa.
    Ho un ciclo che deve fare 100 iterazioni e per ogni iterazione mi serve un numero casuale diverso, mentre io ottengo ad esempio 30 volte lo stesso numero, poi altre 20 un diverso numero, poi altre 50 volte un terzo numero. Sapresti dirmi come mai?
    Grazie mille…

    • tecnicamente 2 novembre 2014 alle 12:05 pm

      Ciao, penso di capire, ma se nei commenti metti il codice è meglio😉.

      il seed per il generatore di numeri casuali deve essere inizializzato una sola volta fuori dal while, quindi lo inizializzi tra le prime istruzioni del programma e poi otterrai un numero casuale ad ogni iterazione.

      Metti il codice qui oppure scrivi una email.

      quindi inserisci la subroutine init_random_seed() e usala come in questo esempio:
      program prova
      implicit none
      integer :: i
      real :: r
      call init_random_seed() ! <- INIZIALIZZA UNA SOLA VOLTA ALL'ESECUZIONE DEL TUO PROGRAMMA
      do i=1,10
      call random_number(r) ! <- ad ogni esecuione otterrai un valore diverso
      write(*,*) r
      enddo
      end program prova

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: