Esercitazioni di Informatica (CIV) - Fortran Andrea Romanoni e-mail
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Esercitazioni di Informatica (CIV) Fortran Andrea Romanoni e-mail: andrea.romanoni@polimi.it website: http://home.deib.polimi.it/romanoni/ 17 dicembre 2015
Fortran Scrittura formattata Possiamo scrivere le variabili in modo formattato utilizzando uno dei parametri della WRITE, simulando ciò che succede con la printf WRITE (*,*) →diventa→ WRITE (*,F) dove F è un descrittore di formato; i principali descrittori sono: Iw utilizzo w colonne per rappresentare un numero intero, compreso il segno; Fw.d utilizzo w colonne per rappresentare un numero reale nella forma a punto fisso con d cifre dopo la vigola, compreso il segno; Ew.d utilizzo w colonne per rappresentare un numero reale nella forma esponenziale, compreso il segno; Aw stampa w caratteri della stringa nX stampa n spazi bianchi Andrea Romanoni Esercitazioni di Informatica (CIV) 2 / 17
Fortran Scrittura formattata – Esempio PROGRAM arrayFortran INTEGER :: a LOGICAL :: b REAL, DIMENSION(4) :: c = (/ 1.0, 2.0, 2.5, 3.8/) a = 1110 b = .false. WRITE(*, ’(I15)’) a WRITE(*, ’(I5)’) a WRITE(*, ’(I2)’) a WRITE(*, ’(L8)’) b WRITE(*, ’(L5)’) b WRITE(*, ’(L5)’) b WRITE(*, ’(F5.3)’) c WRITE(*, ’(F5.1)’) c END Andrea Romanoni Esercitazioni di Informatica (CIV) 3 / 17
Temi d’esame
Tema d’esame del 24 giugno 2013 Esercizio 1 - 9 Punti (1/3) Un video è formato dalla successione di singole immagini, dette frame. Se il video è in bianco e nero e rappresentato in forma digitale, ciascun frame è una griglia rettangolare composta da singoli elementi d’immagine detti pixel. Per memorizzare un video digitale occorre parecchio spazio di memoria. Tuttavia è in genere possibile ridurre fortemente questa richiesta applicando al video un processo di compressione video prima della memorizzazione. Gli algoritmi di compressione video più semplici si basano sulla rilevazione delle zone di immagine che non sono variate apprezzabilmente al passare da un frame ai successivi: infatti, se al passare dal frame A al frame B una zona non cambia apprezzabilmente, è possibile memorizzare i pixel di tale zona solo una volta, come parte del frame A. Nei frame successivi, fino a B compreso, basterà memorizzare l’informazione “questa zona va copiata dal frame precedente”. L’esercizio chiede di scrivere una subroutine Fortran che riceve in ingresso due frame e li confronta per valutare le differenze tra essi, al fine di valutare l’applicabilità della compressione video. La subroutine riceve in ingresso: le dimensioni dei frame da analizzare, sotto forma di due interi Base e Altezza; i due frame da analizzare, Frame1 e Frame2, rappresentati in modo opportuno (decida lo studente, tenendo conto che ogni pixel è rappresentato da un intero); un intero Soglia che rappresenta la soglia di compressione desiderata, ovvero indica di quanto possono differire due frame per essere ancora considerati identici; il numero di strisce orizzontali in cui suddividere ciascuno dei due frame, rappresentato da un intero NumStrisce compreso tra 2 e il valore di Altezza (>= 2). Andrea Romanoni Esercitazioni di Informatica (CIV) 5 / 17
Tema d’esame del 24 giugno 2013 Esercizio 1 - 9 Punti (2/3) La subroutine deve considerare Frame1 e Frame2 come suddivisi in NumStrisce strisce orizzontali. La larghezza di ciascuna striscia è pari a Base pixel; l’altezza (in numero di pixel) di tutte le strisce tranne l’ultima si ottiene dividendo Altezza per NumStrisce e prendendo la parte intera del risultato. L’ultima striscia rappresenta la parte di frame non coperta dalle strisce precedenti. Dunque, nel caso in cui Altezza non è un multiplo di NumStrisce, essa differisce da quella delle strisce precedenti. Esempio: se Altezza vale 200 e NumStrisce vale 6, 200/6=33,333... Quindi Frame1 e Frame2 vanno suddivisi in 5 strisce alte 33 pixel e una alta 35 pixel. Andrea Romanoni Esercitazioni di Informatica (CIV) 6 / 17
Tema d’esame del 24 giugno 2013 Esercizio 1 - 9 Punti (3/3) La subroutine deve svolgere le seguenti operazioni: Per ciascuna coppia di strisce corrispondenti (ovvero aventi la stessa posizione) in Frame1 e Frame2, trovare la differenza tra esse. La differenza è una porzione di frame avente la stessa dimensione delle strisce considerate, che va memorizzata in una struttura dati dello stesso tipo di quelle usate per Frame1 e Frame2 (di questa struttura dati verrà dunque utilizzata solo una parte, dal momento che una striscia comprende meno pixel di un frame). Ciascun pixel della differenza ha valore dato dalla differenza tra i valori dei pixel aventi la stessa posizione nelle due strisce in esame: si noti che tale valore può essere positivo, nullo o negativo. Per ciascuna delle coppie di strisce considerate al punto 1, calcolare il totale delle differenze. Tale valore intero si ottiene prendendo il valore di tutti i pixel della differenza, calcolando il valore assoluto di ciascuno di essi, e sommando i valori assoluti. Attenzione: occorre evitare di includere nella somma anche gli elementi della struttura dati che contiene la differenza non effettivamente utilizzati per gli elementi della differenza. Per ciascuna delle coppie di strisce considerate al punto 1, una volta calcolato il totale delle differenze si verifichi se esso è minore o uguale a Soglia. Se ciò avviene, le due strisce vengono considerate identiche. La subroutine deve fornire in uscita un array di NumStrisce dati di tipo LOGICAL, uno per ciascuna delle coppie di strisce analizzate. Se la k-esima coppia di strisce è stata considerata identica, l’elemento k-esimo dell’array vale .TRUE.. In caso contrario l’elemento vale .FALSE.. Andrea Romanoni Esercitazioni di Informatica (CIV) 7 / 17
Tema d’esame del 24 gennaio 2011 Soluzione (1/2) SUBROUTINE ConfrontaFrame(Base, Altezza, Frame1, Frame2, Soglia, NumStrisce, Confronto) IMPLICIT NONE INTEGER, INTENT(IN) :: Base, Altezza INTEGER, DIMENSION(Altezza,Base), INTENT(IN) :: Frame1, Frame2 INTEGER, INTENT(IN) :: Soglia INTEGER, INTENT(IN) :: NumStrisce LOGICAL,DIMENSION(NumStrisce),INTENT(OUT)::Confronto INTEGER :: i, j INTEGER :: ContStriscia INTEGER :: AltezzaStrisce INTEGER :: AltezzaUltima INTEGER :: inizio, fine INTEGER, DIMENSION(Altezza,Base) :: DifferenzaPixel INTEGER :: SommaDiff AltezzaStrisce = ceiling(real(Altezza)/NumStrisce) AltezzaUltima = Altezza - (NumStrisce-1)*AltezzaStrisce Andrea Romanoni Esercitazioni di Informatica (CIV) 8 / 17
Tema d’esame del 24 gennaio 2011 Versione alla C Versione “intelligente” DO ContStriscia = 1, NumStrisce SommaDiff = sum(abs(Frame1-Frame2),2) inizio =(ContStriscia-1)*AltezzaStrisce+1 IF (ContStriscia < NumStrisce) THEN DO ContStriscia = 1, NumStrisce fine = inizio+AltezzaStrisce-1 inizio =(ContStriscia-1)*AltezzaStrisce+1 ELSE IF (ContStriscia < NumStrisce) THEN fine = Altezza fine = inizio+AltezzaStrisce-1 END IF ELSE DifferenzaPixel(inizio:fine,1:Base) = & fine = Altezza Frame2(inizio:fine,1:Base) - & END IF Frame1(inizio:fine,1:Base) IF (sum(SommaDiff(inizio:fine)) > Soglia) THEN SommaDiff = 0 Confronto(ContStriscia) = .FALSE. DO i = 1, Base ELSE DO j = inizio, fine Confronto(ContStriscia) = .TRUE. IF (Frame2(j, i) >= Frame1(j, i)) THEN END IF SommaDiff = SommaDiff + & END DO Frame2(j, i) - Frame1(j, i) RETURN ELSE END SUBROUTINE ConfrontaFrame SommaDiff = SommaDiff + & Frame1(j, i) - Frame2(j, i) END IF END DO END DO IF (SommaDiff > Soglia) THEN Confronto(ContStriscia) = .FALSE. ELSE Confronto(ContStriscia) = .TRUE. END IF END DO RETURN END SUBROUTINE Andrea ConfrontaFrame Romanoni Esercitazioni di Informatica (CIV) 9 / 17
Tema d’esame del 18 luglio 2013 Esercizio 1 - 9 Punti (1/3) Si consideri il problema di valutare se un autocarro è in grado di percorrere un tunnel dalle pareti irregolari senza che alcuna parte dell’autocarro e del suo carico urti le pareti del tunnel. Un modello3D di un autocarro è costituito da una matrice a 3 dimensioni di 1000x1000x10000 elementi di tipo LOGICAL. Ogni elemento della matrice rappresenta un cubo di spazio di 1cm di lato. Complessivamente la matrice rappresenta un volume di spazio parallelepipedale di 10m (larghezza = direzione x) x 10m (altezza = direzione y) x 100m (profondità = direzione z) contenente un autocarro. Se un determinato elemento del volume è occupato, in tutto o in parte, da un elemento dell’autocarro il corrispondente elemento della matrice vale .TRUE.; se l’elemento del volume è vuoto, l’elemento della matrice vale invece .FALSE. Andrea Romanoni Esercitazioni di Informatica (CIV) 10 / 17
Tema d’esame del 18 luglio 2013 Esercizio 1 - 9 Punti (2/3) Una sagoma2D è una rappresentazione della parte di un piano verticale occupata dalla proiezione (definita nel seguito) di un oggetto solido. Essa è costituita da una matrice di 1000x1000 elementi di tipo .LOGICAL., ciascuno dei quali rappresenta un quadrato di 1cm di lato. Complessivamente la matrice rappresenta un quadrato di 10m (larghezza) x 10m (altezza). Il processo di proiezione sopra citato parte da un oggetto rappresentato da un modello3D e ne produce la corrispondente sagoma2D in base alla seguente regola: data una coppia di indici (x, y), se al variare di z esiste anche un solo elemento di indici (x, y, z) del modello3D che vale .TRUE. (ovvero che rappresenta una porzione di spazio occupato), l’elemento della sagoma2D di indici (x, y) vale .TRUE.; in caso contrario, l’elemento della sagoma2D vale .FALSE. Le sagome2D di un autocarro e di un tunnel sono dette compatibili se è possibile sovrapporle senza che alcun elemento occupato (ovverosia contenente .TRUE.) nella prima risulti occupato anche nella seconda. Non devono cioè esistere coppie di indici in corrispondenza delle quali entrambe le sagome2D contengono .TRUE. Se le due sagome2D sono compatibili l’autocarro è in grado di transitare per il tunnel senza collisioni. Andrea Romanoni Esercitazioni di Informatica (CIV) 11 / 17
Tema d’esame del 18 luglio 2013 Esercizio 1 - 9 Punti (3/3) Si scriva un modulo Fortran contenente: La subroutine Proietta, che riceve in ingresso un modello3D e una sagoma2D, esegue la proiezione del modello3D secondo il metodo descritto, e memorizza il risultato nella sagoma2D. Le dimensioni delle matrici del modello3D e della sagoma2D vanno passate alla subroutine sotto forma di parametri (a tale scopo si usi il minimo numero di parametri sufficiente, tenendo conto delle relazioni dimensionali tra modello3D e sagoma2D). La funzione PassaggioOk, che riceve in ingresso i modelli3D di un autocarro e di un tunnel, utilizza la subroutine Proietta per calcolare le corrispondenti sagome3D e restituisce .TRUE. se queste ultime sono compatibili, .FALSE. in caso contrario. Le dimensioni delle matrici dei modelli3D vanno passate alla subroutine sotto forma di parametri. Andrea Romanoni Esercitazioni di Informatica (CIV) 12 / 17
Tema d’esame del 18 luglio 2013 Esercizio 1 - Soluzione module Autocarro implicit none contains subroutine Proietta(modello3D, sagoma2D, l, h, p) integer, intent(IN)::l integer, intent(IN)::h integer, intent(IN)::p logical, dimension(l,h,p),intent(IN) :: modello3D logical, dimension(l,h), intent(out) :: sagoma2D integer::ContP sagoma2D(:,:) = .FALSE. do ContP = 1, P sagoma2D = sagoma2D .OR. modello3D(:,:,ContP) end do !oppure sagoma2D = any(modello3D, 3) end subroutine Proietta Andrea Romanoni Esercitazioni di Informatica (CIV) 13 / 17
Tema d’esame del 18 luglio 2013 Esercizio 1 - Soluzione logical function PassaggioOk(modelloAuto, modelloTunnel, l, h, p) integer, intent(IN)::l integer, intent(IN)::h integer, intent(IN)::p logical, dimension(l,h, p), intent(in) :: modelloAuto logical, dimension(l,h, p), intent(in) :: modelloTunnel logical, dimension(l,h) :: sagoma2DAuto logical, dimension(l,h) :: sagoma2DTunnel logical, dimension(l,h) :: F call Proietta(modelloAuto, sagoma2DAuto, l, h, p) call Proietta(modelloTunnel, sagoma2DTunnel, l, h, p) F=.not. sagoma2DAuto .eqv. sagoma2DTunnel) if (all(.not. sagoma2DTunnel .or. F) then PassaggioOk = .true. else PassaggioOk = .false. end if end function PassaggioOk end module Autocarro Andrea Romanoni Esercitazioni di Informatica (CIV) 14 / 17
Tema d’esame del 24 luglio 2012 Esercizio 1 - 8 Punti Scrivere un programma per controllare l’esattezza di una soluzione nel gioco del Sudoku. Il programma chiede in input tutti gli 81 numeri all’utente e li memorizza all’interno di un array bidimensionale costituito da 9 x 9 interi. Controlla quindi, per ogni cifra da 1 a 9, che essa sia presente: in ogni riga in ogni colonna in ogni gruppo di caselle 3x3, secondo la suddivisione mostrata in figura Se il programma trova un numero mancante, allora segnala la soluzione come errata, altrimenti la soluzione può considerarsi valida, ed il gioco risolto. La segnalazione, sia di soluzione errata che di Sudoku risolto correttamente, avviene attraverso la stampa di un messaggio a video. Andrea Romanoni Esercitazioni di Informatica (CIV) 15 / 17
Tema d’esame del 24 luglio 2012 Soluzione PROGRAM sudoku IMPLICIT NONE INTEGER, PARAMETER :: DIM_SUDOKU = 9 INTEGER :: contatoreRiga, contatoreColonna, cifraSudoku INTEGER, DIMENSION (DIM_SUDOKU, DIM_SUDOKU) :: tabella_sudoku logical, DIMENSION (DIM_SUDOKU, DIM_SUDOKU) :: tabella_sudoku_confronto LOGICAL :: sudokuOK !Input dei numeri che popolano la tabella del sudoku WRITE(*,*) ’Inserisci i i numeri che compongono il sudoku’; DO contatoreColonna = 1, DIM_SUDOKU DO contatoreRiga = 1, DIM_SUDOKU WRITE(*,*) ’Scrivi l’’elemento (’, contatoreRiga,’,’,contatoreColonna,’)’ READ(*,*) tabella_sudoku(contatoreRiga, contatoreColonna) END DO END DO WRITE(*,’(9I2)’) tabella_sudoku Andrea Romanoni Esercitazioni di Informatica (CIV) 16 / 17
Tema d’esame del 24 luglio 2012 Soluzione sudokuOK = .TRUE. DO cifraSudoku = 1, DIM_SUDOKU tabella_sudoku_confronto = tabella_sudoku == cifraSudoku if(any(count(tabella_sudoku_confronto,1) /= 1 )) then sudokuOK = .FALSE. end if if(any(count(tabella_sudoku_confronto,2) /= 1 )) then sudokuOK = .FALSE. end if DO contatoreRiga = 1, DIM_SUDOKU, 3 DO contatoreColonna = 1, DIM_SUDOKU, 3 if(count(tabella_sudoku_confronto(contatoreRiga:contatoreRiga + 2 ,& contatoreColonna:contatoreColonna+2)) /= 1) then sudokuOK = .FALSE. end if END DO END DO END DO IF (sudokuOK .EQV. .TRUE.) THEN WRITE(*,*) ’Sudoku OK’ ELSE WRITE(*,*) ’Sudoku KO’ END IF END PROGRAM sudoku Andrea Romanoni Esercitazioni di Informatica (CIV) 17 / 17
Puoi anche leggere