giovedì 24 marzo 2011

Fortran Parte I: Gli array in Fortran95

Molti ridono quando sentono parlare del Fortran, ma di fatto chi programma in tale linguaggio non è mai un informatico di professione.

In genere chi usa tale linguaggio è una persona che necessita di scrivere del software che si deve interfacciare direttamente a persone o sistemi, ma per la precisione, scrive  software per il calcolo numerio.

Tutti i linguaggi sono pensati per eseguire calcoli, ma nessuno permette di ottenere le prestazioni e la semplicità di base che si può ottenere con il Fortran95.

In questa breve nota mostrerò l'aspetto che più apprezzo di questo linguaggio, e che alla fine è quello che mi impedisce anche di passare al C o similari, parliamo di ARRAY!

ARRAY in FORTRAN

Un Array è un insieme di dati omogenei, e non differesiche in nulla da quelli che sono gli array in altri linguaggi.

Possiamo quindi avere:

  • Array di numeri interi

  • Array di numeri reali

  • Array di numeri complessi

  • Array di caratteri

  • Array di tipi personali, cioè di tipi creati per uno scopo preciso


Ancora una volta gli array possono essere statici o dinamici, e vedremo più avanti cosa vuol dire.

Per un ingegnere, un fisico, un matematico, un chimico, una persona che vuol fare dei calcoli, l'array non è altro che una MATRICE.

Possiamo avere array monodimensionali, quindi avremo un VETTORE, o array multimensionali quindi MATRICI.

In molte materie scientifiche si realizza un modello matematico basato su matrici ed il calcolo matriciale per semplificare il problema.

Gli esempi sono innumerevoli:

  • L'analisi del moto dei corpi celesti

  • La scienza delle costruzioni

  • L'analisi agli elementi finiti

  • La fluido dinamica numerica

  • L'aerodinamica applicata

  • ecc.


Per cui possedere un linguaggio che gestisca in modo diretto le matrici non è cosa da poco.

Passiamo agli esempi :)

Dichiarazione degli ARRAY
integer :: matrice(10,10)
integer, dimension(10,10) :: matrice

con le due dichiarazioni precedenti si crea una matrice di interi di rango 10x10

analogamente si può creare un vettore di numeri reali o complessi:
double precision :: vettore(10)

double precision, dimension(10) :: vettore

Le dichiarazioni precedenti sono usate quando si conosce a priori la dimensione dell'array da usare, in molti casi si può avere a che fare con array dalle dimensioni sconosciute, in tal caso occore usare gli array dinamici ed allocare di volta in volta lo spazio i memori necessario.

La dichiarazione è simile alla precedende, ma al posto della dimensione si inserisce il simbolo ":".
integer, allocatable :: matrice(:,:)

integer, allocatable, dimension(:) :: vettore

ALLOCATE(matrice(10,10))

ALLOCATE(vettore(10))

Per liberare la memori quando le matrici non sono più necessarie basta:
DEALLOCATE(matrice)

DEALLOCATE(vettore)

ASSEGNAZIONI DI VALORI AGLI ARRAY

Gli array possono essere usati come semplici variabi sia con la metodologia di accesso in lettura e scrittura basata su indici, quindi:
WRITE(*,*) A(i,j) -> stampa l'elemento di coordinate (i,j)

A(i,j) = 5 -> assegnail valore 5 all'elemento di coordinate (i,j)

Ma fin qui tutto è in linea con le possibilità offerte da C/C++, vediamo quindi le peculiarità circa l'uso degli array.
INTEGER :: A(10,20;30)  ! creo un array di interi 10x20x30

A = 1 ! tutti gli elementi dell'array sono pari ad 1

A(1,:,:) = 2 ! tutti gli elementi che hanno il primo indicie pari a 1 assumono valore 2, quindi A(1,1,1) = 2, A(1,1,3) = 2, ..., A(1,20,30) = 2

A(1,1,:) = 3 ! tutti gli elementi di coordinate inizilia (1,1) hanno valore = 3, quindi A(1,1,1)=3, A(1,1,2)=3, ...; A(1,1,30) = 3

C = A+B !somma indice ad indice gli elementi di un array ovviamente si può avere anche la sottrazione

C=A*B ! moltiplica indice ad indice 

Tali modi di accesso possono essere usati per ridurre le righe di codice, semplificare la lettura e permette al compilatore di implementare l'ottimizzazione migliore di accesso, specialmente quando si ha a che fare con migliaia o milioni di elementi.

FUNZIONI NATIVE PER GLI ARRAY


Il linguaggio offre delle funzioni native per particolari operazioni su array quali:
DOT_PRODUCT(A, B) ! prodotto scalare di A e della B

MAXVAL(A)  !  restituisce il valore maggiore dell'array A

MINVAL(A)  !restituisce  il valore minore di A

MAXLOC(A)  !  restituisce le coordinate le valore maggiore di A

MINLOC(A)  ! restituisce le coordinate del valore minore di A

PRODUCT(A)  ! prodotto degli elementi di A

SUM(A) ! somma gli elementi di A

TRANSPOSE(A) ! crea la matrice trasposta

e molte altre ancora per fare lo scorrimento degli elementi, la scelta di elementi da leggere o scrive con l'applicazioni di filtri (chiamati maschera) ecc.

Il mio intento non è quello di scrivere una guida, se il linguaggio vi interessa potete chiedere qui o consultare i diversi manuali che si trovano in rete.

vi lascio con un piccolo esempio:



Qui il risultato:


Ci sarebbe ancora molto da scrivere, ma sarà per la prossima volta.

Infatti non abbiamo parlato di compilatori, lo faremo prossimamente, per ora vi lascio qualche link per curiosare e provare se queste poche note vi hanno incuriosito.

http://hpff.rice.edu/index.htm

http://www.dmi.units.it/~chiarutt/didattica/parallela/fortran/index.html

http://www.nsc.liu.se/~boein/f77to90/f77to90.html#index

Nessun commento:

Posta un commento