Tag Archives: lezioni fortran

Manuale Fortran

FORTRAN

In questa pagina vi propongo il manuale Fortran, a cura di Giuseppe Ciaburro; si tratta di una guida alla programmazione in ambiente Fortran destinato agli utenti alle prime armi che iniziano a programmare partendo da zero.

Il Fortran è un buon linguaggio particolarmente adatto ai principianti in quanto è facile da imparare e disponibile gratuitamente. È particolarmente utile per ricercatori e ingegneri, in quanto dispone di numerose funzioni incorporate per la gestione di costrutti matematici attraverso le matrici. La precisione di calcolo può essere selezionata in base alla necessità del calcolo. Sono inoltre disponibili numerose librerie di algoritmi numerici per la codifica rapida. Poiché si tratta di una guida per principianti ho focalizzato la stessa sul linguaggio di base. Gli esempi si riferiscono alle versioni FORTRAN 90 o 95.

Nel manuale Fortran, a cura di Giuseppe Ciaburro, sono trattati tutti gli argomenti necessari per iniziare a programmare che possono essere utilizzati dagli studenti come ausilio per la preparazione del esami di Informatica.

Sommario del manuale Fortran

Introduzione

Tipi di dati

Strutture di controllo del flusso

Array

Procedure e funzioni

Operazioni di ingresso/uscita

 

Manuale Fortran a cura di Giuseppe Ciaburro – Ultimo aggiornamento 16 Novembre 2016.

Array allocabili nel Fortran


FORTRANLe funzionalità di elaborazione degli Array nel Fortran 90 rappresentano i più significativi miglioramenti del linguaggio offerti dal nuovo standard. Tra queste assumono particolare importanza gli Array allocabili nel Fortran, cioè la possibilità di dichiarare un array con l’attributo ALLOCATABLE. Tale attributo indica che lo spazio per quell’array non viene riservato all’inizio dell’esecuzione del programma ma solo dopo l’esecuzione dell’istruzione ALLOCATE(), in cui si determina anche la dimensione dell’array.

Gli array possono essere molto grandi, in tal caso, richiedono molta memoria; pertanto, è spesso utile riservare questo spazio solo durante i tempi in cui è richiesto l’utilizzo dell’array. Questo non può essere fatto quando la dimensione dell’array è dichiarato durante la compilazione. Per questo motivo è conveniente utilizzare, per tali risorse, la cosiddetta “free store” una memoria di run time per allocare così tale memoria solo durante l’esecuzione del programma. Questa memoria può essere utilizzata e ripristinata utilizzando i seguenti comandi.

Per dichiarare un array come allocabile utilizzeremo la seguente sintassi:

type, DIMENSION(:), ALLOCATABLE ::nome_array

Ad esempio scriveremo:

INTEGER, DIMENSION(:), ALLOCATABLE :: VETTORE

che crea un array intero di nome  VETTORE  a cui sarà allocata della memoria solo durante l’esecuzione ed in misura della sua grandezza.

Una volta che l’array non risulta più necessario, è importante deallocare la memoria in modo che possa essere utilizzata per altre risorse. Per fare questo utilizzeremo il comando DEALLOCATE. Quindi sarà importante utilizzare l’opzione STAT onde verificare che la deallocazione abbia avuto successo.

 DEALLOCATE (VETTORE)

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Come formattare i numeri nel formato esponenziale nel Fortran


FORTRANPer formattare i numeri nel formato esponenziale nel Fortran si utilizza il descrittore E che ci consente di controllare la rappresentazione dei numeri nel formato esponenziale. La forma generale di tale descrittore è:

rEw.d

dove r,w e d assumono il seguente significato:

  • d = Numero di cifre da visualizzare a destra del punto decimale
  • r = Fattore di ripetizione: specifica il numero di volte che un descrittore deve essere utilizzato
  • w = Larghezza di campo: numero di caratteri da utilizzare

Per meglio comprendere il concetto appena esposto analizziamo allora il seguente esempio di istruzione di uscita formattata:

E15.5

che indica di rapresentare il numero in notazione esponenziale con 15 caratteri di cui 5 a destra del punto.

Quindi se dovessimo rappresentare il numero 5.37939E6 con il formato precedente avremmo:

       0.53794E+07
   ____|____|____|
       5   10    15

infatti occorrono:

  • 1 carattere per il segno della mantissa;
  • 2 caratteri per lo zero ed il punto decimale;
  • 5 caratteri per la mantissa;
  • 1 carattere per la lettera E;
  • 1 carattere per il segno dell’esponente;
  • 2caratteri per l’esponente;

per un totale di 12 caratteri, avendo utilizzato 15 caratteri rendiamo il tutto più leggibile.

In generale deve valere la seguente espressione:

w >= d+7

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Come formattare i numeri reali nel Fortran

FORTRANPer formattare i numeri reali nel Fortran si utilizza il descrittore F che ci consente di controllare la rappresentazione dei numeri reali. La forma generale di tale descrittore è:

rFw.d

dove r,w e d assumono il seguente significato:

  • d = Numero di cifre da visualizzare a destra del punto decimale
  • r = Fattore di ripetizione: specifica il numero di volte che un descrittore deve essere utilizzato
  • w = Larghezza di campo: numero di caratteri da utilizzare

Per meglio comprendere il concetto appena esposto analizziamo allora il seguente esempio di istruzione di uscita formattata:

2F8.3

che indica di ripetere per due variabili il formato di numero reale con l’utilizzo di 8 caratteri di cui 3 a destra del punto.

Quando viene stampato un numero reale, la sua parte intera viene stampato come se si utilizzasse il descrittre Im-(d+1). Pertanto, se il numero di posizioni non è sufficiente per stampare completamente la parte intera, tutte le posizioni w saranno riempite con asterischi. Si noti che la parte intera contiene un segno e di conseguenza w deve essere maggiore o uguale a d + 2.
La parte frazionaria può avere più di d cifre. In questo caso, la (D+1)-esima cifra sarà arrotondata alla desima cifra.

Come formattare i numeri reali nel Fortran

Ad esempio, se il numero 1,73 è stampato con il formato F3.1 (usando cioè 3 posizioni per stampare un numero reale con la posizione più a destra utilizzata per la parte frazionaria), poiché la seconda cifra della parte frazionaria è 3, il risultato sarà 1.7 in quanto l’ultima cifra è arrotondata per difetto. Tuttavia, se si stampa il numero 1,76 con lo stesso formato F3.1, il risultato diventa 1.8 perché l’ultima cifra è arrotondata per eccesso.

La parte frazionaria può avere meno di d cifre. In questo caso, verranno aggiunti degli zeri finali.
Si noti che d può essere zero. In questo caso, nessuna parte frazionaria verrà stampata. Più precisamente, la posizione più a destra è il punto decimale.

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Come formattare i numeri interi nel Fortran


FORTRANPer formattare i numeri interi nel Fortran si utilizza ildescrittore I che ci consente di controllare la rappresentazione dei numeri interi. La forma generale di tale descrittore è:

rIw oppure rIw.m

dove r,w e m assumono il seguente significato:

  • m = Numero minimo di cifre da stampare
  • r = Fattore di ripetizione: specifica il numero di volte che un descrittore deve essere utilizzato
  • w = Larghezza di campo: numero di caratteri da utilizzare

Per meglio comprendere il concetto appena esposto analizziamo allora il seguente esempio di istruzione di uscita formattata:

INTEGER :: a = 1, b = -2  
WRITE(*,"(2I5.2)") a, b

Il descrittore di formato utilizzato è 2I5.2 che del tutto uguale a (I5.2,I5.2,) grazie all’utilizzo del contatore di ripetizione 2. Così, ognuna delledue variabili intere sarà restituita secondo quanto stabilito dallo specificatore I5.2 ottenendo così il risultato seguente:

___01__-02

Analizziamo nel dettaglio quanto appena scritto: abbiamo deciso di rappresentare le due varibili intere mediante lo stesso descrittore che ci impone di utilizzare almeno due cifre e cinque spazi. Allora per la varibile a che contiene il numero 1 abbiamo utilizzato le cifre 01 in quanto il descrittore ci imponeva l’utilizzo di almeno due cifre (ecco il significato della presenza dello zero), mentre abbiamo inserito tre spazi bianchi a sinistra del numero ( tre caratteri underscore _), in quanto occorrevano cinque spazi per rappresentare il numero così come indicato dal ddescrittore.

Come formattare i numeri interi nel FortranNelle operazioni di input i due descrittori Iw.m e Iw si comportano allo stesso modo in quanto gli eventuali spazi bianchi posizionati in testa al numero, inseriti per garantire la lunghezza del campo, vengono completamente ignorati.

Nelle operazioni di output invece il dato intero viene rappresentato in un campo di w caratteri con almeno m cifre, di cui le prime uguali a zero se il numero da rappresentare è composto da meno di m cifre. In tal caso, come specificato nell’esempio appena mostrato, la lunghezza del campo wviene garantita dall’inserimento di spazi bianchi. Nel caso invece il campo non fosse sufficiente per contenere tutte le cifre del valore intero da produrre, il campo sarà riempito con un numero di asterischi pari a w.

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Il tipo complex nel Fortran


FORTRANIl tipo complex nel Fortran è un tipo di dati destinato ad ospitare un valore appartenente ad un sottoinsieme dei numeri complessi. E’ composto da due parti: una parte reale ed una parte immaginaria.

La procedura con la quale un numero complesso viene registrato in memoria prevede l’utilizzo di due unità di memoria consecutive destinate ad immagazzinare quindi, due valori reali, rispettivamente la parte reale,e la parte immaginaria del numero complesso.

La sintassi di una istruzione di dichiarazione di tipo di dato complesso ha la seguente forma:

COMPLEX [[([KIND=]parametro di kind )][, attributi ] ::] variabili

Ad esempio, la seguente istruzione dichiara due variabili complesse var_a e var_b aventi parametro di kind pari a 5.

COMPLEX(KIND=5) :: var_a,var_b

Poiché, come già anticipato un tipo complesso contiene due informazioni( parte reale e parte immaginaria del numero), tale specifica del numero di kind resta attribuita ad entrambe le parti.

Altri esempi di dichiarazioni di tipi comlessi sono:

COMPLEX(KIND=4), DIMENSION(8) :: vet_a, vet_b

Per dichiarare una costante del tipo complesso utilizzeremo una coppia di numeri reali (interi), scritti nel modo seguente:

a=(1.4,2.1)

La prima di tali costanti rappresenta la parte reale del valore complesso, la seconda la parte immaginaria. La forma generale di una costante complessa è la seguente:

complesso = “(” (intero | reale) “,” (intero | reale)“)”.

in cui la parte reale e la parte immaginaria sono costanti del tipo REAL/INTEGER.

I seguenti sono esempi di numeri complessi ammessi dal FORTRAN: il numero complesso 3.14 + 0.000736i viene rappresentato come (3.14,.763E-3), mentre il numero complesso 3 + 4i viene rappresentato come (3, 4).

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Il tipo REAL nel Fortran


FORTRANIl tipo REAL nel Fortran rappresenta gli elementi di un sottinsieme dei numeri reali utilizzando due metodi di approssimazione: singola precisione e doppia precisione.

I numeri del tipo real vengono anche detti numeri in virgola mobile (floating-point). L’istruzione REAL è utilizzata per dichiarare una variabile/costante del tipo reale.

La sintassi dell’istruzione di dichiarazione di un ipo REAL è la seguente:

REAL [[([KIND=]parametro_di_kind )][, attributi ] ::] variabili

dove REAL è una parola chiave del Fortran e variabili è una lista di nomi di variabili, costanti o funzioni (separati da virgole) atte a contenere dati di tipo reale.

L’indicazione dei parametri è opzionale, ad esempio se il parametro_di_kind non è specificato allora è impiegato il valore del parametro di kind di default.

Facciamo un esempio:

REAL :: x, y, z

dichiara tre variabili, x, y e z, di tipo reale. Dichiarazioni più complesse sono:

REAL(KIND=high), OPTIONAL :: var1

REAL, SAVE, DIMENSION(10) :: var2

Oppure nella forma:

REAL(KIND=high) :: var3

REAL :: var4

DIMENSION var5(10)

SAVE var6

OPTIONAL var7

Quando risulta necessario definire una costante reale che rappresenta quindi il valore di un numero appartenente al sottoinsieme dei numeri reali, che la macchina che stiamo utilizzando è in grado di rappresentare, sono possibili due metodologie di rappresentazioni che si differenziano per la parte esponenziale.

Una costante del tipo REAL è immagazzinata in memoria con due informazioni: la mantissa e l’esponente. Il numero di bit allocati per la mantissa determina la precisione della costante, mentre il numero di bit allocati per l’esponente determina il range della costante.

Caratteristiche del tipo REAL nel Fortran

-valore reale minimo: –1.70141183E+38 circa
-valore reale massimo: +1.70141183E+38 circa
-precisione: 1.40129846E–45 circa

Operazioni ammesse dal tipo REAL nel Fortran

-assegnazione =
-somma +
-sottrazione –
-moltiplicazione *
-divisione /
-potenza **

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Il tipo INTEGER nel Fortran


FORTRANIl tipo INTEGER nel Fortran rappresenta un tipo di dato destinato ad immagazzinare un valore appartenente ad un sottoinsieme dei numeri interi. Attraverso l’istruzione INTEGER potremo dichiarare che una data variabile è del tipo intero.

La sintassi dell’istruzione di dichiarazione di un tipo di dato intero è:

INTEGER [[([KIND=]parametro_di_kind )][, attributi ]::] variabili

dove INTEGER e KIND sono parole chiave del Fortran e variaibili è una lista di nomi di variabili, costanti o funzioni, separati tra loro attraverso l’impiego di virgole.

L’inidicazione dei parametri è opzionale, ad esempio se il parametro_di_kind non è specificato allora è impiegato il valore del parametro di kind di default.

Facciamo allora un esempio di dichiarazione di un tipo integer:

INTEGER :: i, j, k

In questa dichiarazione vengono specificate tre variabili, i, j e k, di tipo intero.

Per dichiarare un array di puntatori scriveremo:

 INTEGER, DIMENSION(15), POINTER :: array

Vediamo ora come possono essere dichiarate delle costanti intere: si utilizza una stringa di cifre con un segno (positivo/negativo) opzionale. Esempi corretti di dichiarazione di costati intere sono:

0, -345, 768, +12345

Mentre esempi sbagliati di dichiarazione di costati intere sono:

  • 1,234 : la virgola non è ammessa
  • 12.0: il punto decimale non è ammesso
  • —4 and ++3: più di un segno
  • 5- and 7+: il segno opzionale segue la stringa di cifre, mentre la dovrebbe precedere.

Sulle variabili del tipo integer sono ammesse le seguenti operazioni:

-assegnazione =
-somma +
-sottrazione –
-moltiplicazione *
-divisione intera /
-potenza **
-confronto >,< ,>=,< =,==./=

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Come inserire dei dati in un programma fortran


FORTRANIn questa lezione vedremo come inserire dei dati in programma fortran attraverso l’utilizzo dello statement DATA. La dichiarazione dei dati rappresenta un altro modo di inserire dei dati di input che sono noti al momento in cui il programma è scritto. E ‘ simile alla istruzione di assegnazione. La sintassi è la seguente:

data lista-delle-variabili/ lista-dei-valori/, …

dove i tre punti significano che questo modello può essere ripetuto. Ecco un esempio:

data a/10/,b/20/, c/2.5/, d/2.5/

Potremmo anche avere scritto questo nel modo seguente:

data a, b/10, 20 /, c,d / 2 * 2,5 /

Lo stesso risultato si ottiene con le assegnazioni:

a = 10
b= 20
c = 2.5
d= 2.5

La dichiarazione dei dati con l’ausilio dello statement data è più compatta e quindi spesso più conveniente. Si noti in particolare la notazione abbreviata per l’assegnazione di valori identici da utilizzare ripetutamente. La dichiarazione dei dati viene effettuata solo una volta, giusto prima dell’esecuzione del programma quando cioè esso si avvia. Per questo motivo, la dichiarazione di dati è utilizzata principalmente nel programma principale e non nelle subroutine.

La dichiarazione dei dati può anche essere utilizzata per inizializzare gli array (vettori, matrici). Questo esempio mostra come per assicurarsi che una matrice sia composta da tutti zero all’avvio del programma può essere utilizzato lo statement data:

real A(10,20)
data A/ 200 * 0.0/

Alcuni compilatori inizializzano automaticamente gli array ma non tutti, quindi se si utilizzare una matrice con elementi diversi da zero è una buona idea di seguire questo esempio. Naturalmente è possibile inizializzare gli array con valori diversi da zero. Si possono anche inizializzare i singoli elementi:

data A (1,1) / 12,5 /, A (2,1) / -33,3 /, A (2,2) / 1.0 /

In alternativa, è possibile elencare tutti gli elementi per piccoli array in questo modo:

integer v(5)
real B(2,2)
data v/10,20,30,40,50/, B/1.0,-3.7,4.3,0.0/

I valori per gli array bidimensionali saranno assegnati in ordine di colonna come al solito.

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Interfacce nel Fortran


FORTRANIn questo articolo vedremo come utilizzare le interfacce nel Fortran per definire un sottoprogramma. Le interfacce sono necessarie per definire un sottoprogramma generico. L’ interfaccia è  un blocco di istruzioni non eseguibili  che serve a informare il compilatore sui tipi dati e numero degli argomenti dei sottoprogrammi utilizzati, in mdo che eventuali  utilizzi incoerenti (numero di argomenti diverso,  tipi dati differenti)  possa essere segnalato al momento della compilazione.

La sintassi per definire un blocco interfaccia è la seguente:

interface
...
end interface

al cui interno vanno inseriti i soli blocchi di dichiarazione dei sottoprogrammi e dei rispettivi argomenti. Non vanno messe nell’ interfaccia né  le dichiarazioni di variabili locali né  le istruzioni eseguibili dei sottoprogrammi.
In un blocco interfaccia si possono collocare le dichiarazioni relative a più  sottoprogrammi. Si possono anche avere più  blocchi interfaccia nella stessa unità  di programma.

Le interfacce nel Fortran riferiscono la specifica conoscenza che il compilatore ha circa una procedura durante la sua compilazione. Se l’interfaccia è esplicita, il compilatore può verificare che il sottoprogramma venga richiamato correttamente. Se, tuttavia, l’interfaccia è implicita, il compilatore Fortran 90 non dispone di informazioni sui tipi e numero di argomenti utilizzati dal sottoprogramma o il valore di ritorno del risultato di una funzione.

La Tipizzazione implicita viene utilizzata nel programma chiamante per determinare il risultato restituito da una funzione, nel caso in cui non si disponga della dichiarazione. Di conseguenza, nessun tipo di controllo può essere fatto per verificare che un sottoprogramma è stato chiamato correttamente. Diremo allora implicite tutte le interfacce che sono disponibili nel Fortran 77.

Ad esempio la funzione sin (x)  calcola, in modo appropriato, il seno del suo argomento, se x è singola o in doppia precisione, oppure un numero reale o complesso. In Fortran 90, i sottoprogrammi definiti dall’utente possono essere generici nello stesso senso. Le funzioni generiche e le subroutine possono essere definiti, analogamente a qualsiasi altro sottoprogramma, anche se l’interfaccia deve essere esplicita. Il modo usuale di definire una tale funzione generica è quella di inserirlo in un modulo, come nell’esempio riportato di seguito.

module AritmeticaRazionale
   type rational
      integer n, d   ! Numeratore e denominatore.
   end type rational

   interface operator (*)
      module procedure integerRationalMultiply, &
                       rationalIntegerMultiply
   end interface

   contains

   function integerRationalMultiply( i, r )
      type( rational ) integerRationalMultiply
      integer, intent( in ) :: i
      type( rational ), intent( in ) :: r

      integerRationalMultiply = rational( i * r%n, r%d )
   end function integerRationalMultiply

   function rationalIntegerMultiply( r, i )
      type( rational ) rationalIntegerMultiply
      type( rational ), intent( in ) :: r
      integer, intent( in ) :: i

      rationalIntegerMultiply = rational( i * r%n, r%d )
   end function rationalIntegerMultiply

end module AritmeticaRazionale

LINK DI APPROFONDIMENTO PER L’ARGOMENTO:

Istruzioni OPEN nel Fortran


FORTRANL’istruzione OPEN nel Fortran associa un file ad un numero di unità di ingresso/uscita. Ha la seguente sintassi:

OPEN(UNIT=num,FILE=’nome ‘,STATUS=’stato’, ACTION= spec, FORM=’fm’, IOSTAT= var)

 Analizziamo nel dettaglio le specifiche contenute nel comando:

  1. UNIT= num – Indica il numero di unità i/o da associare al file, num è un numero intero non negativo.
  2. FILE= nome – Specifica il nome del file da aprire.
  3. STATUS= stato – Specifica lo stato del file da aprire, dove stato può essere: OLD , NEW , REPLACE , SCRATCH , UNKNOWN
  4. ACTION= spec – Specifica se il file deve essere aperto soltanto in lettura,in scrittura o in entrambe le modalità. Dove spec può essere: READ , WRITE , READWRITE
  5. FORM=’fm’ – Specifica che il file conterrà gli usuali caratteri (lettere, numeri, segni di punteggiatura, ecc.) in modo che il programmatore possa leggere il file
  6. IOSTAT= var – Specifica il nome di una variabile intera in cui può essere restituito lo stato dell’operazione OPEN. Dove var è un intero; se l’operazione OPEN ha successo var = 0  altrimenti var > 0.

Analizziamo allora un esempio:

OPEN(UNIT=1,FILE=’PRIMO.DAT’,STATUS=’OLD’,ACTION=’READ’,IOSTAT=’var’)

Tale operazione apre il file PRIMO.DAT e lo associa all’unità numero 1, STATUS=’OLD’ specifica che l’unità esiste già, ACTION=’READ’indica che il file può essere solo letto, IOSTAT=’var’ per il controllo degli errori.

LINK DI APPROFONDIMENTO PER L’ARGOMENTO: