Ciclo DO in Fortran

Concetti Chiave
  • 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 e DO 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 loop DO 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 e DO 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 e DO 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 ed END DO vengono eseguite ripetutamente fino a quando condizione_di_uscita diventa vera.
  • Quando l'EXIT viene eseguito, il controllo passa alla prima istruzione dopo END 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:

Diagramma di flusso del ciclo DO in Fortran
Figura 1: Diagramma di flusso del ciclo DO in Fortran
Consiglio

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:

  1. Un solo punto di ingresso: L'istruzione DO.
  2. 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.

Nota

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:

\bar{x} = \frac{1}{N} \sum_{i=1}^{N} x_i

dove x_i è un campione su N misurazioni.

La deviazione standard è definita come:

s = \sqrt{\frac{N \sum_{i=1}^{N} x_i^2 - \left( \sum_{i=1}^{N} x_i \right)^2}{N(N-1)}}

Essa misura la dispersione dei valori rispetto alla media: più è alta, più i dati sono dispersi.

Proviamo a realizzare un programma che deve:

  1. Leggere un numero arbitrario di misurazioni
  2. 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:

  1. Inizializzazione delle variabili
  2. Inserimento dei dati
  3. 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:

\bar{x} = \frac{10 + 20 + 30 + 40}{4} = 25

e

s = \sqrt{\frac{4 \cdot (10^2 + 20^2 + 30^2 + 40^2) - (10 + 20 + 30 + 40)^2}{4 \cdot (4-1)}} = 12.9099445

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:

Diagramma di Flusso del Programma per il calcolo della deviazione standard
Figura 2: Diagramma di Flusso del Programma per il calcolo della deviazione standard