1 / 41

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

Il linguaggio Fortran 90: 4. Array: Vettori e Matrici. 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. Dichiarazione di variabili vettore.

margo
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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

  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)=i END DO • Il range di variabilità può essere fissato altrimenti: REAL DIMENSION (inf : sup) :: a

  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

  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

  6. Passaggio di Parametri Vettore • Array fittizi di forma presunta Una procedura non conosce in generale la dimensione dei parametri effettivi array passati alla procedura • Array fittizi non specificano la dimensione dell’array • REAL, DIMENSION (:) :: a INTEGER :: i DO i = LBOUND (a,1), UBOUND (a,1) a (i) = 0 END DO • In alternativa occorre passare come parametro la dimensione degli array

  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

  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

  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

  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

  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

  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 = 3 INTEGER, DIMENSION(dimensione) :: v1, v2 ! i due vettori letti INTEGER, DIMENSION(dimensione) :: somma ! il vettore somma

  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

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

  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

  16. Ordinamento di un Vettore (Cont.) “Trova la posizione k_min del minimo intero nelle posizioni da i a n” k_min = i loop2: DO j=i+1, n IF (a(j) < a(k_min)) k_min = j END 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

  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

  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 = 3 INTEGER, 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

  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)

  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

  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

  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

  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

  24. Somma di Matrici SUBROUTINE 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

  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

  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

  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. 

  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 RETURN END SUBROUTINE minimo_locale END MODULE modulo_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

  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

  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

  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)

  33. Potenza elettrica erogata(cont.) • Esempio: 4 generatori, 5 istanti di tempo

  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

  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

  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

  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

  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)

  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)

  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

  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

More Related