Ciclo DO in Fortran
- I Cicli o Loop sono costrutti di controllo che permettono di eseguire una sequenza di istruzioni più volte.
- In Fortran, esistono due forme principali di loop: Loop
DO
eDO WHILE
e Loop iterativi. - La differenza principale tra i due tipi di loop è come viene controllata la ripetizione: i loop
DO
si ripetono fino a quando una condizione è soddisfatta, mentre i loop iterativi si ripetono un numero specificato di volte. - Un loop
DO
viene ripetuto fino a quando una condizione è vera, e può contenere uno o più punti di uscita (EXIT
). - Un loop
DO
ben strutturato deve avere un solo punto di ingresso e un solo punto di uscita per garantire un corretto funzionamento. - Dimenticare un'istruzione
EXIT
in un loopDO
può causare un loop infinito.
I Cicli o Loop
I Loop o Cicli sono costrutti di controllo in Fortran che ci permettono di eseguire una sequenza di istruzioni più volte.
Esistono due forme principali di loop in Fortran:
- Loop
DO
eDO WHILE
: il cui scopo è ripetere un blocco di istruzioni fintanto che certe condizioni siano verificate; - Loop iterativi (o loop di conteggio): il cui scopo è ripetere un blocco di istruzioni un numero specificato di volte.
La differenza principale tra questi due tipi di loop è come viene controllata la ripetizione:
- Loop
DO
eDO WHILE
: si ripete un numero indefinito di volte, fino a quando una condizione specificata dall'utente viene soddisfatta. - Loop iterativo: si ripete un numero specificato di volte, noto prima che il loop inizi.
In questa lezione ci concentreremo sui loop DO
.
Ciclo DO
Un loop DO
è un blocco di istruzioni che viene ripetuto fino a quando una condizione è vera.
La sintassi generale di un loop DO
in Fortran è:
DO
! Istruzioni Precedenti
! ...
! Controllo della condizione di uscita
IF (condizione_di_uscita) EXIT
! Istruzioni Successive
! ...
END DO
- Le istruzioni tra
DO
edEND DO
vengono eseguite ripetutamente fino a quandocondizione_di_uscita
diventa vera. - Quando l'
EXIT
viene eseguito, il controllo passa alla prima istruzione dopoEND DO
.
Un loop DO
può contenere uno o più EXIT
, generalmente all'interno di un'istruzione IF
.
Se la condizione condizione_di_uscita
è falsa, il loop continua a eseguire.
Se logical_expr
è vera, il controllo passa subito all'istruzione successiva dopo END DO
.
Se la condizione logical_expr
è già vera alla prima iterazione, solo le istruzioni del gruppo Istruzioni Precedenti
verranno eseguite. Mentre, le istruzioni del gruppo Istruzioni Successive
non verranno eseguite.
Per chiarire meglio le idee, basta osservare la seguente figura che mostra il diagramma di flusso per un ciclo DO
:
Inserire un solo punto di uscita in un ciclo DO
Ogni loop DO
dovrebbe contenere un solo punto di uscita (EXIT
) per garantire un corretto funzionamento del loop.
Un loop DO
ben strutturato deve avere:
- Un solo punto di ingresso: L'istruzione
DO
. - Un solo punto di uscita: L'istruzione
EXIT
.
Avere un solo punto di uscita facilita la verifica che il loop funzioni correttamente in tutte le condizioni.
Assenza di punti di uscita in un ciclo DO
Dimenticare un'istruzione EXIT
in un loop DO
può causare un loop infinito, dove il programma continua a eseguire il loop senza mai uscire.
Bisogna sempre assicurarsi che il loop abbia una condizione di uscita ben definita.
Ora vedremo un esempio pratico di analisi statistica implementato utilizzando un loop DO.
Esempio: Calcolo della Media e Deviazione Standard
In ingegneria e nelle scienze, è comune lavorare con grandi insiemi di numeri, ognuno dei quali rappresenta una misura di una specifica proprietà che ci interessa.
Spesso non è necessario esaminare ogni singolo valore di un set di misurazioni.
Invece, è utile riassumere i dati con pochi numeri che descrivono l'insieme.
Due misure fondamentali sono:
- Media aritmetica (o media)
- Deviazione standard
La media aritmetica di un insieme di numeri è definita come:
dove
La deviazione standard è definita come:
Essa misura la dispersione dei valori rispetto alla media: più è alta, più i dati sono dispersi.
Proviamo a realizzare un programma che deve:
- Leggere un numero arbitrario di misurazioni
- Calcolare la media e la deviazione standard
Utilizzeremo un loop DO
per accumulare i dati prima di eseguire i calcoli.
Per segnalare che non ci sono più dati da inserire, useremo un valore negativo come flag di terminazione.
Tutti i valori inseriti devono essere positivi o nulli.
Vediamo alcuni punti chiave per realizzare questo programma:
- Il programma non sa in anticipo quanti valori verranno inseriti. L'unico modo per terminare l'inserimento è inserire un valore negativo.
- Il programma deve accumulare i dati in modo da poter calcolare la media e la deviazione standard.
- Dopo aver accumulato i dati, il programma deve calcolare la media e la deviazione standard.
- Infine, il programma deve visualizzare i risultati.
In particolare, per accumulare i dati, possiamo utilizzare una variabile sum_x
per la somma dei valori e una variabile sum_x2
per la somma dei quadrati dei valori. Ad ogni iterazione, aggiorniamo queste variabili con i nuovi valori inseriti:
somma_x = somma_x + x
somma_x2 = somma_x2 + x**2
Invece, al termine dell'inserimento dei dati, possiamo calcolare la media e la deviazione standard utilizzando le formule sopra indicate:
x_bar = somma_x / REAL(n)
std_dev = SQRT((REAL(n)*somma_x2 - somma_x**2) / (REAL(n)*REAL(n-1)))
Dove n
è il numero totale di misurazioni.
Vi è, però, un problema: cosa succede se l'utente inserisce un solo valore? In tal caso, la deviazione standard non può essere calcolata, poiché la formula richiede almeno due valori. Infatti, in tal caso avremmo una divisione per zero.
Quindi dobbiamo inserire un controllo per evitare la divisione per zero. Una soluzione è controllare che il numero di misurazioni sia maggiore di 1 prima di calcolare la deviazione standard.
Proviamo ad implementare il programma suddividendolo in tre parti:
- Inizializzazione delle variabili
- Inserimento dei dati
- Calcolo della media e della deviazione standard
PROGRAM calcolo_media_deviazione_standard
IMPLICIT NONE
INTEGER :: n
REAL :: x, x_bar, std_dev, somma_x, somma_x2
! Inizializzazione delle variabili
n = 0
somma_x = 0.0
somma_x2 = 0.0
! Inserimento dei dati
DO
WRITE (*,*) 'Inserire un valore:'
READ (*,*) x
IF (x < 0.0) EXIT
WRITE (*,*) 'Valore inserito:', x
n = n + 1
somma_x = somma_x + x
somma_x2 = somma_x2 + x**2
END DO
! Calcolo della media e della deviazione standard
IF (n > 1) THEN
x_bar = somma_x / REAL(n)
std_dev = SQRT((REAL(n)*somma_x2 - somma_x**2) / (REAL(n)*REAL(n-1)))
WRITE (*,*) 'Media:', x_bar
WRITE (*,*) 'Deviazione Standard:', std_dev
ELSE
WRITE (*,*) 'Inserire almeno due valori per calcolare la deviazione standard'
END IF
END PROGRAM calcolo_media_deviazione_standard
Proviamo ad eseguire il programma inserendo i seguenti valori:
10.0
20.0
30.0
40.0
Inserendo questi valori ci aspettiamo che:
e
Provando a compilare ed eseguire il programma, otteniamo:
$ ./calcolo_media_deviazione_standard
Inserire un valore:
10.0
Valore inserito: 10.0000000
Inserire un valore:
20.0
Valore inserito: 20.0000000
Inserire un valore:
30.0
Valore inserito: 30.0000000
Inserire un valore:
40.0
Valore inserito: 40.0000000
Inserire un valore:
-1
Media: 25.0000000
Deviazione Standard: 12.9099445
Il diagramma di flusso del programma è mostrato nella figura seguente: