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

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

Post on 13-Jan-2016

40 views

Category:

Documents

0 download

Embed Size (px)

DESCRIPTION

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 dellarray a indicata con a(i) Gli elementi di un array sono normali variabili. Dichiarazione di variabili vettore. - PowerPoint PPT Presentation

TRANSCRIPT

<ul><li><p>Il linguaggio Fortran 90: 4. Array: Vettori e Matrici</p></li><li><p>Vettori Gruppi di variabili dello stesso tipo memorizzate in locazioni contigue di memoria.La i-esima posizione dellarray a indicata con a(i)</p><p>Gli elementi di un array sono normali variabili</p></li><li><p>Dichiarazione di variabili vettoreREAL, DIMENSION (20) :: aLattributo DIMENSION serve per dichiarare la lunghezza del vettoreCHARACTER(len=20), DIMENSION (50) :: cognomeIndica un vettore di 50 elementi ognuno dei quali una stringa di 20 caratteriCostanti 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 DOIl range di variabilit pu essere fissato altrimenti:REAL DIMENSION (inf : sup) :: a</p></li><li><p>Somma di due vettori! File: somvett1.for! Scopo: esempio di uso di array</p><p>PROGRAM somma_vettori ! Questo programma calcola la somma di due vettori a 3 componenti </p><p>! *** 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</p><p>! *** 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</p></li><li><p>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</p><p>! calcolo vettore somma DO i = 1, dimensione somma(i) = v1(i) + v2(i) ! N.B. si potrebbe fare direttamente somma = v1 + v2 END DO</p><p>! stampa del vettore somma WRITE(*,*) 'Il vettore somma e'':' DO i = 1, dimensione WRITE(*,*) 'Componente ', i, ' : ', somma(i)END DO STOP </p><p>END PROGRAM somma_vettori</p></li><li><p>Passaggio di Parametri Vettore Array fittizi di forma presuntaUna procedura non conosce in generale la dimensione dei parametri effettivi array passati alla proceduraArray fittizi non specificano la dimensione dellarrayREAL, DIMENSION (:) :: aINTEGER :: iDO i = LBOUND (a,1), UBOUND (a,1)a (i) = 0END DOIn alternativa occorre passare come parametro la dimensione degli array</p></li><li><p>Passaggio di Parametri di Tipo Vettore! File: util-vet.for</p><p>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.</p><p>CONTAINS </p></li><li><p>Passaggio di Parametri di Tipo Vettore (cont.)SUBROUTINE leggi_vettore (vet)</p><p> 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 </p><p>END SUBROUTINE leggi_vettore</p></li><li><p>Passaggio di Parametri di Tipo Vettore (cont.) SUBROUTINE stampa_vettore (vet)</p><p> ! DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, DIMENSION(:), INTENT(IN) :: vet ! Vettore di input ! DICHIARAZIONE VARIABILI LOCALI INTEGER :: i ! indice del ciclo </p><p> DO i = LBOUND(vet,1), UBOUND(vet,1) WRITE(*,*) 'Componente ', i, ':', vet(i) END DO RETURN </p><p>END SUBROUTINE stampa_vettore</p></li><li><p>Passaggio di Parametri di Tipo Vettore (cont.)FUNCTION somma_vettori (vet1, vet2, dim)</p><p> 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 </p><p> DO i = LBOUND(vet1,1), UBOUND(vet1,1) somma_vettori(i) = vet1(i) + vet2(i) END DO RETURN </p><p>END FUNCTION somma_vettori </p></li><li><p>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 </p><p> ! *** SEZIONE ESECUTIVA DO i = LBOUND(vet1,1), UBOUND(vet1,1) ris(i) = vet1(i) + vet2(i) END DO RETURN </p><p>END SUBROUTINE somma_vettori_sub </p></li><li><p>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 </p><p>PROGRAM somma_vettori_2 </p><p>! *** 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</p></li><li><p>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</p><p>END PROGRAM somma_vettori_2</p></li><li><p>Ordinamento di un VettoreOrdinare un vettore di n interi in modo non decrescente. </p></li><li><p>Algoritmo di Ordinamentoloop1: DO i=1, n-1 Tova la posizione k_min del minimo intero nelle posizioni da i a nScambia lelemento nella posizione i con lelemento nella posizione k_minEND DO loop1</p></li><li><p>Ordinamento di un Vettore (Cont.)Trova la posizione k_min del minimo intero nelle posizioni da i a nk_min = iloop2: DO j=i+1, nIF (a(j) &lt; a(k_min)) k_min = jEND DO loop2Scambia lelemento nella posizione i con lelemento nella posizione k_mintmp = a(i) a(i) = a(kmin)a(kmin) = tmp</p></li><li><p>Ordinamento di un Vettore (Cont.)SUBROUTINE ordinavett(v)! Scopo: ordinamento di un vettore di interi</p><p> 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) &lt; 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</p><p>END SUBROUTINE ordinavett</p></li><li><p>Ordinamento di un Vettore (Cont.)! File: test_ordinavett.for! Scopo: testare la subroutine ordinavett(v) che ordina un vettore di interi</p><p>PROGRAM test_ordinavett </p><p>USE operazioni_su_vettori IMPLICIT NONE INTEGER, PARAMETER :: dimensione = 3INTEGER, DIMENSION(dimensione) :: v ! vettore da leggere e ordinare</p><p>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</p><p>END PROGRAM test_ordinavett</p></li><li><p>Matrici Vettori a due dimensioniOgni elemento indicato da un indice di riga ed un indice di colonnaLelemento della matrice di indice di riga i ed indice di colonna j indicato con a(i,j)</p></li><li><p>Dichiarazione di MatriciINTEGER, DIMENSION (5,10) :: aREAL, DIMENSION (0:100, 5:20) :: valoriInizializzazione di una MatriceINTEGER, DIMENSION (7,10) :: matDO i=1, 7 DO j=1, 10mat(i,j) = 0END DO END DO</p></li><li><p>Gestione delle matrici! File: mod_matr.for</p><p>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</p><p>CONTAINS </p></li><li><p>Gestione delle matrici (cont)SUBROUTINE leggi_matrice (mat)</p><p> 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)</p><p> 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 </p><p>END SUBROUTINE leggi_matrice</p></li><li><p>Gestione delle matrici (cont)SUBROUTINE stampa_matrice (mat)</p><p> 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)</p><p> 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 </p><p>END SUBROUTINE stampa_matrice</p></li><li><p>Somma di MatriciSUBROUTINE somma_matrici(a, b, c)</p><p> 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</p><p> 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 </p><p>END SUBROUTINE somma_matrici</p></li><li><p>Moltiplicazione tra MatriciDate due matrici a(n:m) e b(m:p) calcolare la matrice prodotto c(n:p).DO i=1, n DO j=1, p</p><p>END DO END DO </p></li><li><p>Moltiplicazione tra Matrici (cont.)SUBROUTINE prodotto_matrici (a,b,c,n,m,p)</p><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</p><p> 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</p><p>END SUBROUTINE prodotto_matrici</p></li><li><p>Calcolo del minimo localeData una matrice a(n:m) calcolare per ogni elemento a(i,j) il minimo tra a(i,j) e gli elementi adiacenti. </p></li><li><p>Calcolo del minimo locale (cont.)SUBROUTINE minimo_locale(a,b,n,m)</p><p> 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 &lt; 2) .OR. (m &lt; 2)) THEN b = a ELSE loop1: DO i = 1, n loop2: DO j = 1, mCalcolo del minimo locale nellintorno di a(i,j) ed assegnazione a b(i,j) END DO loop2 END DO loop1 END IF RETURNEND SUBROUTINE minimo_locale</p><p>END MODULE modulo_matrici</p></li><li><p>Calcolo del minimo locale (cont.)Calcolo del minimo locale nellintorno di a(i,j):</p><p> 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</p></li><li><p>Calcolo del minimo locale (cont.) min = a(i,j) loop3: DO k = i1, i2 loop4: DO l = j1, j2 IF (a(k,l) &lt; min) min = a(k,l) END DO loop4 END DO loop3 b(i,j) = min</p></li><li><p>Potenza elettrica erogataPer ogni istante di tempo si conosce la potenza elettrica erogata da n generatori. Losservazione delle potenza erogata prosegue per m istanti di tempoScrivere 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</p></li><li><p>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)</p></li><li><p>Potenza elettrica erogata(cont.)Esempio: 4 generatori, 5 istanti di tempo</p></li><li><p>Potenza elettrica erogata(cont.)Calcolo della potenza mediaSUBROUTINE pot_media (erogati, n, m, media)! Scopo: calcolo della potenza media erogata da ogni generatore</p><p> ! *** 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</p></li><li><p>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 </p><p>END SUBROUTINE pot_media</p></li><li><p>Potenza elettrica erogata(cont.)Calcolo della potenza totaleSUBROUTINE pot_totale (erogati, n, m, totale)! Scopo: calcolo della potenza totale erogata da ogni generatore</p><p> ! *** 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</p></li><li><p>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 </p><p>END SUBROUTINE pot_totale</p></li><li><p>Calcolo dei prodotti scalariUna matrice x(n:m) memorizza le componenti di n vettori ad m dimensioniScrivere una SUBROUTINE che calcoli il prodotto scalare tra tutte le coppie di vettoriIl risultato e formato di...</p></li></ul>

Recommended

View more >