Esercitazioni di Informatica (CIV) - Fortran Andrea Romanoni e-mail

Pagina creata da Giacomo Fava
 
CONTINUA A LEGGERE
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