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 2015Fortran
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 / 17Fortran
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 / 17Temi 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Tema 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 / 17Puoi anche leggere