1 il linguaggio fortran 90: 4. array: vettori e matrici

41
1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

Upload: dafne-valli

Post on 01-May-2015

256 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

1

Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

Page 2: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

2

Vettori

• Gruppi di variabili dello stesso tipo memorizzate in locazioni contigue di memoria.

• La i-esima posizione dell’array a è indicata con a(i)

• Gli elementi di un array sono normali variabili

a(1) a(5)a(2) a(3) a(4)

Page 3: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

3

Dichiarazione di variabili vettore• REAL, DIMENSION (20) :: a

L’attributo DIMENSION serve per dichiarare la lunghezza del vettore• CHARACTER(len=20), DIMENSION (50) :: cognome

Indica un vettore di 50 elementi ognuno dei quali è una stringa di 20 caratteri• Costanti di tipo array:

(/ 1, 2, 3, 4, 5 /)• Inizializzazione di un array:

INTEGER, DIMENSION (5) :: a = (/ 1, 2, 3, 4, 5 /)• DO i=1, 5

a(i)=iEND DO

• Il range di variabilità può essere fissato altrimenti:REAL DIMENSION (inf : sup) :: a

Page 4: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

4

Somma di due vettori! File: somvett1.for! Scopo: esempio di uso di array

PROGRAM somma_vettori ! Questo programma calcola la somma di due vettori a 3 componenti

! *** SEZIONE DICHIARATIVA *** !IMPLICIT NONE INTEGER, PARAMETER :: dimensione = 3 INTEGER, DIMENSION(dimensione) :: v1, v2 ! i due vettori letti INTEGER, DIMENSION(dimensione) :: somma ! il vettore somma INTEGER :: i! indice di ciclo per scandire le componenti dei vettori

! *** SEZIONE ESECUTIVA *** !! lettura primo vettore WRITE(*,*) 'Immetti il primo vettore!' DO i = 1, dimensione ! leggiamo il vettore una componente alla volta WRITE(*,*) 'Componente ', i, ' ? ' READ (*,*) v1(i) END DO

Page 5: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

5

Somma di due vettori (cont.)! lettura secondo vettore WRITE(*,*) 'Immetti il secondo vettore!' DO i = 1, dimensione ! leggiamo il vettore una componente alla volta WRITE(*,*) 'Componente ', i, ' ? ' READ (*,*) v2(i) END DO

! calcolo vettore somma DO i = 1, dimensione somma(i) = v1(i) + v2(i) ! N.B. si potrebbe fare direttamente somma = v1 + v2 END DO

! stampa del vettore somma WRITE(*,*) 'Il vettore somma e'':' DO i = 1, dimensione WRITE(*,*) 'Componente ', i, ' : ', somma(i)END DO STOP

END PROGRAM somma_vettori

Page 6: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

6

Passaggio di Parametri Vettore

• Array fittizi di forma presuntaUna procedura non conosce in generale la dimensione dei parametri effettivi array passati alla procedura

• Array fittizi non specificano la dimensione dell’array• REAL, DIMENSION (:) :: aINTEGER :: iDO i = LBOUND (a,1), UBOUND (a,1)

a (i) = 0END DO

• In alternativa occorre passare come parametro la dimensione degli array

Page 7: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

7

Passaggio di Parametri di Tipo Vettore

! File: util-vet.for

MODULE operazioni_su_vettori ! Questo modulo contiene alcune unita‘ che effettuano operazioni su! Vettori:! - leggi_vettore : subroutine per la lettura di un vettore di interi! di lunghezza arbitraria ! - stampa_vettore : subroutine per la stampa di un vettore di interi! di lunghezza arbitraria ! - somma_vettori : funzione per la somma vettoriale di due vettori di! interi di lunghezza arbitraria (passata come parametro)! - somma_vettori_sub : subroutine per la somma vettoriale di due! vettori di interi di lunghezza arbitraria. Analoga alla precedente! ma non e' necessario passare la lunghezza.

CONTAINS

Page 8: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

8

Passaggio di Parametri di Tipo Vettore (cont.)

SUBROUTINE leggi_vettore (vet)

IMPLICIT NONE ! ** DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, INTENT(IN OUT), DIMENSION(:) :: vet ! il vettore di input ! ** DICHIARAZIONE VARIABILI LOCALI INTEGER :: i ! indice di ciclo DO i = LBOUND(vet,1), UBOUND(vet,1) WRITE(*,*) 'Componente ', i, ' ? ' READ (*,*) vet(i) END DO RETURN

END SUBROUTINE leggi_vettore

Page 9: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

9

Passaggio di Parametri di Tipo Vettore (cont.)

SUBROUTINE stampa_vettore (vet)

! DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, DIMENSION(:), INTENT(IN) :: vet ! Vettore di input ! DICHIARAZIONE VARIABILI LOCALI INTEGER :: i ! indice del ciclo

DO i = LBOUND(vet,1), UBOUND(vet,1) WRITE(*,*) 'Componente ', i, ':', vet(i) END DO RETURN

END SUBROUTINE stampa_vettore

Page 10: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

10

Passaggio di Parametri di Tipo Vettore (cont.)

FUNCTION somma_vettori (vet1, vet2, dim)

IMPLICIT NONE ! ** DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, DIMENSION(:), INTENT(IN) :: vet1, vet2 ! i vettori di input INTEGER, INTENT(IN) :: dim ! la lunghezza dei vettori ! ** DICHIARAZIONE TIPO FUNZIONE INTEGER, DIMENSION(dim) :: somma_vettori ! ** DICHIARAZIONE VARIABILI LOCALI INTEGER :: i ! indice del ciclo

DO i = LBOUND(vet1,1), UBOUND(vet1,1) somma_vettori(i) = vet1(i) + vet2(i) END DO RETURN

END FUNCTION somma_vettori

Page 11: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

11

Passaggio di Parametri di Tipo Vettore (cont.)SUBROUTINE somma_vettori_sub (vet1, vet2, ris) IMPLICIT NONE ! ** DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, DIMENSION(:), INTENT(IN) :: vet1, vet2 ! i vettori di input INTEGER, DIMENSION(:), INTENT(OUT) :: ris ! il vettore di output INTEGER :: i ! indice del ciclo

! *** SEZIONE ESECUTIVA DO i = LBOUND(vet1,1), UBOUND(vet1,1) ris(i) = vet1(i) + vet2(i) END DO RETURN

END SUBROUTINE somma_vettori_sub

Page 12: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

12

Passaggio di Parametri di Tipo Vettore (cont.)

! File: somvett2.for! Scopo: Uso di sottoprogrammi che manipolano array unidimensionali di! due vettori a 3 componenti, usando le SUBROUTINE

PROGRAM somma_vettori_2

! *** SEZIONE DICHIARATIVA *** !USE operazioni_su_vettori IMPLICIT NONE INTEGER, PARAMETER :: dimensione = 3INTEGER, DIMENSION(dimensione) :: v1, v2 ! i due vettori letti INTEGER, DIMENSION(dimensione) :: somma ! il vettore somma

Page 13: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

13

Passaggio di Parametri di Tipo Vettore (cont.)

! *** SEZIONE ESECUTIVA *** !WRITE(*,*) 'Immetti il primo vettore!' CALL leggi_vettore(v1) ! lettura secondo vettore WRITE(*,*) 'Immetti il secondo vettore!' CALL leggi_vettore(v2) ! calcolo vettore somma con la funzione somma = somma_vettori(v1,v2,dimensione) ! stampa del vettore somma WRITE(*,*) 'Il vettore somma e'':' CALL stampa_vettore(somma) ! calcolo vettore somma con la subroutine CALL somma_vettori_sub(v1,v2,somma) ! stampa del vettore somma WRITE(*,*) 'Il vettore somma (calcolato in altra maniera) e'':' CALL stampa_vettore(somma) STOP

END PROGRAM somma_vettori_2

Page 14: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

14

Ordinamento di un Vettore

• Ordinare un vettore di n interi in modo non decrescente.

10 16 12 3

1 123 6 10

Page 15: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

15

Algoritmo di Ordinamento

loop1: DO i=1, n-1 “Tova la posizione k_min del minimo intero nelle posizioni da i a n”“Scambia l’elemento nella posizione i con l’elemento nella posizione k_min”

END DO loop1

Page 16: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

16

Ordinamento di un Vettore (Cont.)

“Trova la posizione k_min del minimo intero nelle posizioni da i a n”k_min = iloop2: DO j=i+1, n

IF (a(j) < a(k_min)) k_min = jEND DO loop2

“Scambia l’elemento nella posizione i con l’elemento nella posizione k_min”tmp = a(i) a(i) = a(kmin)a(kmin) = tmp

Page 17: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

17

Ordinamento di un Vettore (Cont.)SUBROUTINE ordinavett(v)! Scopo: ordinamento di un vettore di interi

IMPLICIT NONE ! Dichiarazione parametri formali

INTEGER, DIMENSION (:), INTENT (IN OUT) :: v ! Dichiarazione variabili locali INTEGER :: i, j, k_min, i_min, i_max, tmp i_min = LBOUND(v,1) i_max = UBOUND(v,1) loop1: DO i=i_min, (i_max - 1) k_min = i loop2: DO j=i+1, i_max IF (v(j) < v(k_min)) k_min = j END DO loop2 tmp = v(i) v(i) = v(k_min) v(k_min) = tmp END DO loop1 RETURN

END SUBROUTINE ordinavett

Page 18: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

18

Ordinamento di un Vettore (Cont.)! File: test_ordinavett.for! Scopo: testare la subroutine ordinavett(v) che ordina un vettore di interi

PROGRAM test_ordinavett

USE operazioni_su_vettori IMPLICIT NONE INTEGER, PARAMETER :: dimensione = 3INTEGER, DIMENSION(dimensione) :: v ! vettore da leggere e ordinare

WRITE(*,*) 'Immetti il vettore di interi da ordinare ' CALL leggi_vettore(v)! stampa del vettore inserito WRITE(*,*) 'Vettore inserito: ' CALL stampa_vettore(v)! ordino il vettore somma con la funzione ordinavett(v)CALL ordinavett(v)! stampa del vettore ordinato WRITE(*,*) 'Vettore ordinato: ' CALL stampa_vettore(v)STOP

END PROGRAM test_ordinavett

Page 19: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

19

Matrici • Vettori a due dimensioni

• Ogni elemento è indicato da un indice di riga ed un indice di colonna

• L’elemento della matrice di indice di riga i ed indice di colonna j è indicato con a(i,j)

1 2 3 4 5

2

3

4

1

Page 20: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

20

Dichiarazione di Matrici

• INTEGER, DIMENSION (5,10) :: a• REAL, DIMENSION (0:100, 5:20) :: valori• Inizializzazione di una Matrice

INTEGER, DIMENSION (7,10) :: mat

DO i=1, 7

DO j=1, 10

mat(i,j) = 0

END DO

END DO

Page 21: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

21

Gestione delle matrici

! File: mod_matr.for

MODULE modulo_matrici ! Questo modulo contiene alcune unita‘ che effettuano operazioni su! matrici:! - leggi_matrice : subroutine per la lettura di una matrice! bidimensionale di interi di forma arbitraria ! - stampa_matrice : subroutine per la stampa di una matrice! bidimensionale di interi di forma arbitraria ! - somma_matrici : funzione per la somma vettoriale di due matrici! bidimensionali di interi di forma arbitraria! - prodotto_matrici : funzione che calcola il prodotto di due! matrici di interi

CONTAINS

Page 22: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

22

Gestione delle matrici (cont)SUBROUTINE leggi_matrice (mat)

IMPLICIT NONE ! ** DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, INTENT(IN OUT), DIMENSION(:,:) :: mat ! matrice di input ! ** DICHIARAZIONE VARIABILI LOCALI INTEGER :: i, j, r_min, r_max, c_min, c_max r_min = LBOUND (mat,1) r_max = UBOUND (mat,1) c_min = LBOUND (mat,2) c_max = UBOUND (mat,2)

WRITE(*,*) 'Inserisci matrice', (r_max-r_min+1), ' *',(c_max-c_min+1) DO i = r_min, r_max DO j = c_min, c_max WRITE(*,*) 'componente ', i, j, ' : ' READ (*,*) mat(i,j) END DO END DO RETURN

END SUBROUTINE leggi_matrice

Page 23: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

23

Gestione delle matrici (cont)SUBROUTINE stampa_matrice (mat)

IMPLICIT NONE ! ** DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, INTENT(IN), DIMENSION(:,:) :: mat ! matrice di input ! ** DICHIARAZIONE VARIABILI LOCALI INTEGER :: i, j, r_min, r_max, c_min, c_max r_min = LBOUND (mat,1) r_max = UBOUND (mat,1) c_min = LBOUND (mat,2) c_max = UBOUND (mat,2)

DO i = r_min, r_max WRITE(*,*) 'riga', i DO j = c_min, c_max WRITE(*,*) ' col.', j, ' =', mat(i,j) END DO END DO RETURN

END SUBROUTINE stampa_matrice

Page 24: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

24

Somma di MatriciSUBROUTINE somma_matrici(a, b, c)

IMPLICIT NONE ! Dichiarazioni parametri fittizi INTEGER, DIMENSION(:,:), INTENT (IN) :: a, b INTEGER, DIMENSION (:,:),INTENT (OUT) :: c ! Dichiarazione variabili locali INTEGER :: i, j, r_min, r_max, c_min, c_max

r_min = LBOUND (a,1) r_max = UBOUND (a,1) c_min = LBOUND (a,2) c_max = UBOUND (a,2) DO i = r_min, r_max DO j = c_min, c_max c(i,j) = a (i,j) + b (i,j) END DO END DO RETURN

END SUBROUTINE somma_matrici

Page 25: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

25

Moltiplicazione tra Matrici

• Date due matrici a(n:m) e b(m:p) calcolare la matrice prodotto c(n:p).

DO i=1, n DO j=1, p

END DO

END DO

m

1kj)b(k, k)a(i, j)c(i,

Page 26: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

26

Moltiplicazione tra Matrici (cont.)SUBROUTINE prodotto_matrici (a,b,c,n,m,p)

IMPLICIT NONE ! Dichiarazioni parametri formali INTEGER, INTENT(IN) :: n, m, p INTEGER, DIMENSION (n,m), INTENT (IN) :: a INTEGER, DIMENSION (m,p), INTENT (IN) :: b INTEGER, DIMENSION (n,p), INTENT (OUT) :: c ! Dichiarazione variabili locali INTEGER :: i, j, k

DO i = 1, n DO j = 1, p c(i,j) = 0 DO k = 1, m c(i,j) = c(i,j) + a(i,k) * b(k,j) END DO END DO END DO RETURN

END SUBROUTINE prodotto_matrici

Page 27: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

27

Calcolo del minimo locale

• Data una matrice a(n:m) calcolare per ogni elemento a(i,j) il minimo tra a(i,j) e gli elementi adiacenti.

3

6102

12

6

5

1 31

a b

Page 28: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

28

Calcolo del minimo locale (cont.)SUBROUTINE minimo_locale(a,b,n,m)

IMPLICIT NONE INTEGER, INTENT(IN) :: n, m INTEGER, DIMENSION(n,m), INTENT (IN) :: a INTEGER, DIMENSION (n,m),INTENT (OUT) :: b ! Dichiarazione variabili locali INTEGER :: i, j, k, l, i1,i2, j1, j2,min IF ((n < 2) .OR. (m < 2)) THEN b = a ELSE loop1: DO i = 1, n loop2: DO j = 1, m

“Calcolo del minimo locale nell’intorno di a(i,j) ed assegnazione a b(i,j)”

END DO loop2 END DO loop1 END IF RETURNEND SUBROUTINE minimo_locale

END MODULE modulo_matrici

Page 29: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

29

Calcolo del minimo locale (cont.)“Calcolo del minimo locale nell’intorno di a(i,j)”:

IF (i == 1) THEN i1 = 1 ELSE i1 = i-1 END IF IF (i == n) THEN i2 = n ELSE i2 = i+1 END IF IF (j == 1) THEN j1 = 1 ELSE j1 = j-1 END IF IF (j == m) THEN j2 = m ELSE j2 = j+1 END IF

Page 30: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

30

Calcolo del minimo locale (cont.)

min = a(i,j) loop3: DO k = i1, i2 loop4: DO l = j1, j2 IF (a(k,l) < min) min = a(k,l) END DO loop4 END DO loop3 b(i,j) = min

Page 31: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

31

Potenza elettrica erogata

• Per ogni istante di tempo si conosce la potenza elettrica erogata da n generatori.

• L’osservazione delle potenza erogata prosegue per m istanti di tempo

• Scrivere una SUBROUTINE che calcoli la potenza media erogata da ogni generatore lungo gli m istanti di tempo ed una SUBROUTINE che calcoli la potenza totale erogata dagli n generatori ad ogni istante di tempo

Page 32: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

32

Potenza elettrica erogata(cont.)

• I dati di input alla procedura sono rappresentati in una matrice di reali erogati(n,m) di n righe ed m colonne.

• I dati di output sono rappresentati in un vettore media(n) ed un vettore totale(m)

Page 33: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

33

Potenza elettrica erogata(cont.)

• Esempio: 4 generatori, 5 istanti di tempo1 2 3 4 5

2

3

4

1 30.0 26.7 24.9 28.1 31.4

18.2

36.6

24.4

28.22

119.2totale

media

Page 34: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

34

Potenza elettrica erogata(cont.)Calcolo della potenza media

SUBROUTINE pot_media (erogati, n, m, media)! Scopo: calcolo della potenza media erogata da ogni generatore

! *** SEZIONE DICHIARATIVA *** ! IMPLICIT NONE ! Dichiarazione parametri formali REAL, DIMENSION(:,:), INTENT(IN) :: erogati INTEGER, INTENT(IN) :: n, m REAL, DIMENSION(:), INTENT(OUT) :: media ! Dichiarazione variabili locali INTEGER :: i,j REAL ::temp

Page 35: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

35

Potenza elettrica erogata(cont.)Calcolo della potenza media

! *** SEZIONE ESECUTIVA *** ! DO i=1, n ! Calcola la potenza media del generatore i temp = 0. DO j=1, m ! Scandisci gli m istanti di tempo temp = temp + erogati(i,j) END DO media(i) = temp / m END DO RETURN

END SUBROUTINE pot_media

Page 36: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

36

Potenza elettrica erogata(cont.)Calcolo della potenza totale

SUBROUTINE pot_totale (erogati, n, m, totale)! Scopo: calcolo della potenza totale erogata da ogni generatore

! *** SEZIONE DICHIARATIVA *** ! IMPLICIT NONE ! Dichiarazione parametri formali REAL, DIMENSION(:,:), INTENT(IN) :: erogati INTEGER, INTENT(IN) :: n, m REAL, DIMENSION(:), INTENT(OUT) :: totale ! Dichiarazione variabili locali INTEGER :: i,j REAL ::temp

Page 37: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

37

Potenza elettrica erogata(cont.)Calcolo della potenza totale

! *** SEZIONE ESECUTIVA *** ! DO i=1, m ! Calcola la potenza totale erogata al tempo i temp = 0. DO j=1, n ! Scandisci gli n generatori temp = temp + erogati(j,i) END DO totale(i) = temp END DO RETURN

END SUBROUTINE pot_totale

Page 38: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

38

Calcolo dei prodotti scalari

• Una matrice x(n:m) memorizza le componenti di n vettori ad m dimensioni

• Scrivere una SUBROUTINE che calcoli il prodotto scalare tra tutte le coppie di vettori

• Il risultato e’ formato di n**2 prodotti scalari che memorizziamo in una matrice prod (n:n)

Page 39: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

39

Calcolo dei prodotti scalari

EX: m=3

v1 = x(1,1) i + x(1,2) j+ x(1,3) k

v2 = x(2,1) i + x(2,2) j+ x(2,3) k

v1 v2 = x(1,1) * x(2,1) + x(1,2) * x(2,2) + x(1,3) * x(2,3)

Page 40: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

40

Calcolo dei prodotti scalari (cont.)

SUBROUTINE prodotto_scalare (x, n, m, prod)! Scopo: calcolo dei prodotti scalari tra tutte le coppie di n righe! di una matrice x(n,m).! Ritorna la matrice dei prodotti scalari prod(n,n)

! *** SEZIONE DICHIARATIVA *** ! IMPLICIT NONE !Dichiarazione parametri formali INTEGER, INTENT(IN) :: n, m REAL, DIMENSION(:,:), INTENT(IN) :: x ! x(i,j) memorizza la j-ma componente dell’i-mo vettore REAL, DIMENSION(:,:), INTENT(OUT) :: prod ! Prod(i,j) memorizza il prodotto scalare tra il vettore i ed il ! vettore j !Dichiarazione variabili locali INTEGER :: i, j, k REAL :: tmp

Page 41: 1 Il linguaggio Fortran 90: 4. Array: Vettori e Matrici

41

Calcolo dei prodotti scalari (cont.)

! *** SEZIONE ESECUTIVA *** ! DO i = 1, n DO j = 1, n tmp = 0.0 DO k = 1, m tmp = tmp + x(i,k) * x(j,k) END DO WRITE(*,*)'prod(',i,j,') = ',tmp prod (i,j) = tmp END DO END DO RETURN

END SUBROUTINE prodotto_scalare