Corso di Laurea in Matematica - Laboratorio di Programmazione gr.2 – a.a. 2014/15 Esercitazione in Laboratorio n. 6 Argomenti Linguaggio Fortran : a) uso di subroutines e functions , b) I/O da files su disco; Algoritmi : 1) Calcolo della trasposta con memoria aggiuntiva, 2) Array reversal, 3) Trasposizione di matrice quadrata sul posto (senza memoria aggiuntiva) PROMEMORIA PROCEDURE (subroutines e functions ): A. SUBROUTINES Creazione Chiamata SUBROUTINE nomesub (lista par. formali ) ……. ……. RETURN END SUBROUTINE nomesub CALL nomesub (lista par. attuali ) [N.B. la chiamata a subroutine è una istruzione ] B. FUNCTIONS : Creazione Chiamata tipo FUNCTION nomefun (lista par. formali) ……. ( ) nomefun = …. * ……. RETURN END FUNCTION nomefun nomefun (lista parametri attuali) [N.B la chiamata a functione è un primario, può comparire in una espressione, o comunque dovunque potrebbe trovarsi il nome di una costante, nel programma] ( ) * N.B. Nel corpo della function, almeno una assegnazione ad una variabile che ha lo stesso nome della function C. Compilazione e LINKAGGIO di un programma con procedure scritte dall’utente: [prompt]$ gfortran –c fmain.f90 [prompt]$ …..….….. …….…… [prompt]$ gfortran –c fsub1.f90 gfortran –c fsubn.f90 prompt]$ gfortran –o feseguibile fmain.o fsub1.o fsub2.o … fsubn.o _____________________________________________________________________________ 1 Esercizio n. 1 Il seguente programma Fortran costruisce una matrice e ne calcola la trasposta (utilizzando una seconda matrice di appoggio). Studiare il codice Fortran, poi eseguire il programma per verificarne la correttezza, quindi: 1.a Trasformare il programma in una subroutine che riceve come parametri in ingresso le dimensioni della matrice nonché la matrice stessa, e fornisce come parametro in uscita la matrice trasposta, esempio di intestazione : SUBROUTINE trasp ( nri, nco, mat, trmat) inoltre scrivere un programma che legga una matrice da un file su disco, richiami questa subroutine per calcolarne la trasposta, e scriva la trasposta calcolata in UN ALTRO file su disco. Dopo aver compilato, linkato ed eseguito il programma, controllare il contenuto del file che esso ha creato, ricorrendo al comando CAT di Linux. 1.b Come secondo esercizio, modificare anche il programma per il calcolo del prodotto di matrici costruito nelle scorse lezioni in modo tale da ottenere un programma che legga da disco una matrice mat (con nri righe ed nco colonne), ne calcoli la trasposta trmat (richiamando la subroutine costruita in 1.a ), calcoli il prodotto di mat per trmat e stampi quest’ultimo, per righe, sullo schermo. --------------------------------------------------------------------------------------------------------------------------------PROGRAM mattrasp ! crea una matrice di dimensioni fissate qualsiasi MAT e ne calcola la trasposta TRASP IMPLICIT NONE INTEGER, parameter :: nri = 3, nco = 5 INTEGER :: i,j REAL, DIMENSION (nri, nco) :: mat = 0. REAL, DIMENSION (nco, nri) :: trasp = 0. !---------------creazione della matrice mat riga_i: DO i=1, nri elemento_ij : DO j = 1, nco mat(i,j) = 2*i + j END DO elemento_ij END DO riga_i !--------------costruzione della trasposta rigatras: DO i = 1, nco eletras_ij: DO j=1, nri trasp(i,j) = mat(j,i) END DO eletras_ij END DO rigatras !-----------------output WRITE(*,*) WRITE(*,*)'La trasposta della matrice di dimensione',nri,'x',nco,':' WRITE(*,*) printriga: DO i=1, nri WRITE(*,100) (mat(i,j),j = 1,nco) END DO printriga WRITE(*,*) WRITE(*,*)'e'' la seguente matrice, di dimensione',nco,'x',nri WRITE(*,*) printras: DO i=1, nco WRITE(*,100) (trasp(i,j),j = 1,nri) END DO printras 100 FORMAT ( 2x, 10f5.0) STOP END PROGRAM mattrasp ______________________________________________________________________ 2 Esercizio n. 2 Inversione dell’ordine degli elementi in un array monodimensionale (array reversal) Il flowchart in fig.1 ( a pag. 4 ) illustra un algoritmo che permette di invertire l’ordine degli elementi di un array di rango uno (vettore) e di dimensione nota n senza fare uso di memoria aggiuntiva. Sia (ai, i = 1..n) il nostro vettore. A procedimento completato, an occuperà la prima posizione, an-1 occuperà la seconda, e così via …. a1 sarà lo n-mo (ultimo) elemento del nuovo array a. Studiare bene il flowchart e riflettere: quanti ‘scambi’ prevede l’algoritmo? E quindi, quante operazioni di assegnazione? Se si raddoppia il numero di elmenti dell’array, il numero di assegnazioni rimane invariato o cresce? Ed in che misura cresce ? E se si triplica n ? Sapreste esprimere e scrivere qui sotto il numero di assegnazioni da effettuare come funzione di n ? Nscambi_areversal(n) = f1(n) = ?______ Nass_areversal(n) = f2(n) = ?______ Parte pratica: 2.a Una volta capito bene l’algoritmo di array reversal, codificarlo in un programma Fortran che legga un vettore a componenti reali da un file su disco in cui nel primo record è memorizzato il numero di elementi dell’array [n] e nei successivi n records vi sono i singoli elementi di a [a1 a2… an]. Il programma deve visualizzare sullo schermo l’array appena letto, poi invertire l’ordine delle componenti e quindi visualizzare l’array modificato. Preparare il file di dati. Compilare, linkare, ed eseguire il programma. 2.b Come passo successivo scrivere l’algoritmo di array reversal sotto forma di subroutine, e strutturare il programma principale nel modo seguente: lettura dei dati da disco, chiamata a subroutine, output dei dati sullo stesso file da cui sono stati letti (cancellando i dati precedenti), oltre che sullo schermo. Compilare ed eseguire il programma usando lo stesso file di dati preparato precedentemente. Dopo l’esecuzione del programma, visualizzare il contenuto del file di dati usando un opportuno comando Linux. Esercizio n. 3 Trasposizione di una matrice quadrata ‘sul posto’ Il flowchart in fig.2 (a pag. 5) illustra un algoritmo che permette trasporre una matrice quadrata senza fare uso di memoria aggiuntiva. Tale algoritmo è simile a quello di array reversal. Procedendo come nell’esercizio n. 2 , per prima cosa studiare il flowchart . Una volta capito bene il procedimento, valutare il numero di assegnazioni richiesto dallo algoritmo come funzione della dimensione della matrice quadrata, cioè di n. Nscambi_ traspmat (n) = f1(n) = ?______ Nass_ traspmat (n) = f2(n) = ?______ 3.a Procedere alla codifica Fortran ed alla preparazione del file di dati avente la seguente forma: n n EOR A11 A12…….A1n EOR A21 A22…….A2n EOR … An1 An2 …. Ann EOR EOF Quindi eseguire il programma per controllarne la correttezza. 3.b Modificare il programma in modo che l’input e l’output siano effettuati nel main, ma la trasposizione della matrice sia effettuata in una subroutine. Eseguire la nuova versione del programma, controllarne la correttezza. 3 Figura 1 : Array reversal START LEGGI: n LEGGI: a(k), k = 1..n nmezzi = [ n/2 ] i=0 i=i+1 app = a(i) a(i) = a( n+1-i ) a(n+1-i ) = app FALSO i = nmezzi VERO SCRIVI: a(k), k = 1..n STOP 4 Figura 2 : Trasposizione di matrice quadrata (senza uso di memoria aggiuntiva) START LEGGI: n LEGGI: a(i,k), i=1..n; k = 1..n i=1 i=i+1 k=0 k = k+ 1 app = a(i,k) a(i,k) = a(k,i) a(k,i) = app k= i-1 FALSO VERO FALSO i =n VERO SCRIVI: a(i,k), i=1..n; k = 1..n STOP stop 5