Cicli in Fortran I cicli consentono di eseguire una sequenza di istruzioni più di una volta due tipi: Cicli iterativi Cicli while Ciclo Iterativo DO indice=inizio,fine,incremento istruzione 1 istruzione 2 …………… blocco END DO indice è una variabile intera ed è utilizzatata come contatore del ciclo inizio, fine, incremento sono parametri incremento è facoltativo se è omesso si assume che è uguale a 1 Ciclo Iterativo 1) inizio, fine, incremento possono essere costanti, variabili o espressioni; se sono variabili o espressioni devono essere valutate prima del ciclo 2) all’inizio del ciclo il programma pone indice=inizio se indice*incremento =< fine*incremento il programma esegue le istruzioni all’interno del ciclo Ciclo Iterativo 3) eseguite le istruzioni all’interno del ciclo il programma pone indice=indice+incremento se indice*incremento =< fine*incremento vengono eseguite nuovamente le istruzioni del ciclo 4) si ripete il punto 3) finchè indice*incremento =< fine*incremento quando questa condizione non è più vera viene eseguita la prima istruzione dopo il ciclo 5) Si eseguono n.iter.= (fine-inizio+incremento)/incremento Ciclo Iterativo (esempi) DO i=1,10,2 istruzione …………… 5 iterazioni END DO DO i=3,-3,-2 istruzione …………… END DO 4 iterazioni Istruzione CYCLE Istruzione CYCLE interrompe l’esecuzione delle istruzioni del ciclo e fa ritornare all’inizio del ciclo L’indice del ciclo viene incrementato e l’esecuzione delle istruzioni del ciclo riprende se l’indice non ha raggiunto il suo valore Istruzione CYCLE (esempio) PROBLEM esempio INTEGER :: I DO i=1,10 IF ( i == 3 ) CYCLE WRITE(*,*) i END DO END PROGRAM esempio Si stampano tutti i numeri interi compresi tra 1 e 10 Escluso il numero 3 Istruzione EXIT Istruzione EXIT interrompe l’esecuzione delle istruzioni del ciclo, fa uscire dal ciclo Viene eseguita la prima istruzione dopo END DO del ciclo Istruzione EXIT (esempio) PROBLEM esempio INTEGER :: I DO i=1,10 IF ( i == 3 ) EXIT WRITE(*,*) i END DO END PROGRAM esempio Si stampa solamente il numero 1 Ciclo while DO WHILE (espressione logica) istruzione 1 istruzione 2 …………… blocco END DO quando l’espressione logica è .TRUE. il blocco delle istruzioni del ciclo vengono ripetute quando l’espressione logica è .FALSE. viene eseguita la prima istruzione dopo END DO Ciclo while DO …………... IF (espressione logica) EXIT …………… blocco END DO quando l’espressione logica è .TRUE. il blocco delle istruzioni del ciclo vengono ripetute quando l’espressione logica è .FALSE. viene eseguita la prima istruzione dopo END DO Ciclo while PROBLEM esempio DOUBLE PRECISION :: var,eps eps=1.D0 DO var=1.D0+eps IF ( var.EQ.1.D0) EXIT eps=eps/2.d0 END DO WRITE(*,*) ‘ eps =’, eps END PROGRAM esempio Cicli DO con nome [nome] DO indice = inizio, fine, incremento …………... …………... IF (espressione logica) CYCLE [nome] …………… …………… END DO [nome] Cicli DO con nome [nome] DO …………... IF (espressione logica) CYCLE [nome] …………… …………... IF (espressione logica) EXIT [nome] …………… END DO [nome] SUBROUTINE SUBROUTINE nome_subr ( lista_argomenti ) sezione dichiarativa sezione esecutiva RETURN END SUBROUTINE nome_subr SUBROUTINE PROGRAM nome_prog CALL nome_subr ( lista_argomenti ) END PROGRAM nome_prog SUBROUTINE 1) ogni subroutine è compilata separatamente dal programma principale e da altre subroutine quindi può usare le stessi nomi delle variabili e le stesse etichette utilizzate dal programma principale o da altre subroutine 2) l’ordine e il tipo degli argomenti della chiamata devono corrispondere a quelli della definizione SUBROUTINE PROGRAM main INTEGER, PARAMETER :: n=2 DOUBLE PRECISION :: f,x(n) CALL funct( n,x,f ) END PROGRAM main SUBROUTINE funct(n,x,f ) INTEGER :: n DOUBLE PRECISION :: f,x(n) Istruzione INTENT INTENT(IN) l’argomento è un dato di input INTENT(OUT) l’argomento è un dato di output INTENT(IN OUT) l’argomento è sia un dato di input che di output se l’istruzione INTENT è assente l’argomento è sia un dato di input che di output Istruzione INTENT SUBROUTINE funct(n,x,f ) INTEGER, INTENT(IN) :: n DOUBLE PRECISION, INTENT(IN) :: x(n) DOUBLE PRECISION, INTENT(OUT) :: f FUNCTION FUNCTION nome_funct ( lista_argomenti ) sezione dichiarativa sezione esecutiva nome_funct=espressione RETURN END FUNCTION nome_funct FUNCTION PROGRAM nome_prog var=nome_funct( lista_argomenti ) END PROGRAM nome_prog Calcolo del gradiente approssimato f x, y f x, y x x lim f x f x 0 f x f x errapp ( ) errtronc errapp ( ) 0, 0 Calcolo del gradiente approssimato f x, y f x, y x x lim f x f x 0 f x f x errapp ( ) errtronc errapp ( ) 0, 0 Calcolo del gradiente approssimato per valori di sufficientemente piccoli f x, y x f x, y f x, y x x f x f x f x f x f x f x 2 Forward formula Backward formula Symmetric formula subroutine gradapp(n,x,f) ................................. call funct(n,x,f) do i=1,n z=x z(i)=x(i)+eps call funct(n,z,fp) g(i)=(fp-f)/eps end do return end subroutine gradapp Generatore di Numeri Pseudo-casuali RANDOM_NUMBER(x) x è un REAL ritorna un valore estratto da una sequenza di numeri pseudo-casuali il valore restituito nella variabile x è compreso tra 0 (incluso) e 1 (escluso) 0 x 1 Gen. di Num. Cas. (esempio di numero in PROGRAM num_cas implicit none real :: num double precision, parameter :: l=-10, u=10 double precision :: dnum,x call RANDOM_NUMBER(num) dnum=dble(num) x=l+dnum*(u-l) stop end program num_cas [l,u) ) Sequenza pesudo-casuale circa 1018 numeri s … … seed della sequenza circa 1018 numeri s … … s … Inizializzazione della sequenza RANDOM_SEED() imposta l’innesco della sequenza random s ad un valore ottenuto sulla base del tempo di sistema. se CALL RANDOM_SEED() precede l’istruzione CALL RANDOM_NUMBER(num) ad ogni esecuzione del programma vengono generati numeri differenti altrimenti vengono generati gli stessi numeri