Informatica. AA 2009/10.

Lezione di laboratorio n. 2

 
  1. Creare una nuova directory (cartella) per i file relativi a questa esercitazione (per le istruzioni necessarie cfr. quanto fatto nella  lezione di laboratorio n. 1). Rendere questa nuova directory la directory di default ( comando cd, vedi istruzioni nel laboratorio precedente).  Riprendere il programma fortran per la soluzione dell' equazione di secondo grado della precedente esercitazione. 

    Per copiare il file secondo.f90 da una cartella /home/user/es1  a quella corrente, nell' ipotesi che questa sia  /home/user/es2  e'  sufficiente, nella finestra terminale, dare il comando 
    cp ../es1/secondo.f90  .    (attenzione al punto finale!!)
    il cui significato è :  copia nella cartella corrente ( indicata in modo abbreviato mediante il punto finale) il file secondo.f90 che "si trova" nella cartella raggiungibile da quella corrente risalendo alla cartella in cui quest' ultima è   "contenuta" e "scendendo" nella sottocartella di nome es2. Ovvero, in modo più preciso, si chiede di copiare il file il cui nome completo è quello della cartella corrente ( /home/user/es1 ), a  cui viene tolto l' ultimo segmento (es1) e viene aggiunto es2/secondo.f90 su un nuovo file il cui nome termina con lo stesso nome del faile di partenza ( secondo.f90 ) ma inizia col nome della cartella corrente ( .  ovvero /home/user/es2 ). La versione lunga es esplicita del comando precedente sarebbe:
    cp /home/user/es1/secondo.f90 /home/user/es2/secondo.f90
    Da notare che se l' ultimo file de comando cp non esiste,  viene creato.  Se invece esiste già un file con quel nome, viene sovrascritto (ed il vecchio contenuto è perso per sempre).

    Fatto questo (verificare col comando ls che la copia sia stata realizzata), occorre ricompilare il file secondo.f90 mediante il compilatore Fortran (g95) per creare il file eseguibile contenente le istruzioni macchina che implementano le elaborazioni descritte dal sorfgente Fortran.
    Invece di usare il defualt del compilatore (in assenza di altre indicazioni, il comando g95 secondo.f90 creerebbe un file eseguibile di nome a.out nella cartella corrente) si consiglia di compilare mediante il comando

    g95 secondo.f90 -o secondo.x
    Il modificatore -o secondo.x   "dice"  al compilatore che il file di istruzioni macchina eseguibili dal processore deve essere battezzato secondo.x (o in qualsiasi altro modo si voglia battezzare il file).

    Cosa succede se i coefficienti sono tali da dar luogo a discriminante negativo ? (Provare)
  2. Il costrutto Fortran
  3. IF( espressione logica )THEN
    ...blocco 1
    ELSE
    ...blocco 2
    END IF

    esegue le istruzioni del  blocco di istruzioni 1 se l' espressione logica tra parentesi è  vera e quelle del blocco 2 se è  falsa. Usare il costrutto Fortran  IF ( ... ) THEN ... ELSE ... END IF per fare in modo che il programma per la soluzione dell' equazione di secondo grado scriva le soluzioni reali solo se esistono, mentre,  se non esistono visualizzi su schermo un messaggio diagnostico. (Ricordare che l' ordine con  cui si scrivono le istruzioni nel sorgente Fortran corrisponde a quello di esecuzione delle corrispondenti istruzioni macchina.)

  4. Si può  attribuire un valore iniziale ad una variabile nella stessa istruzione in cui se ne   definisce il  tipo. Le variabili possono poi essere ridefinite nel programma  assegnando loro un nuovo valore (eventualmente dipendente dal vecchio).       Nota: l'istruzione implicit none che appare come prima istruzione negi esempi di  programmi dati in questo corso equivale a richiedere che siano date le dichiarazioni esplicite del tipo dati di ogni variabile utilizzata nel programma. In assenza di tale istruzione, il Fortran assumerebbe che le variabili non dichiarate esplicitamente il cui nome inizi per lettere comprese tra a e h e tra o e z siano reali mentre quelle il cui nome inizia per i,j,k,l,m,n siano intere. Questa convenzione implicita del Fortran  è  potenzialmente pericolosa per la possibilita  di introdurre inavvertitamente variabili non previste (e  non inizializzate) e quindi  è  buona norma, anche se non  è un obbligo del linguaggio, utilizzare sempre l' istruzione implict none.
     

    Es:
     
     

    program par
    implicit none
    integer :: i=2

    print*,i
    i=i+1

    print*,i , i+3

    end program par
     
     

    verificare il funzionamento del programma.

  5. Prevedere  cosa dovrebbe scrivere il seguente programma  scrivendo prima le proprie previsioni  su un foglio, e poi  trascrivendo il programma su di un file e compilandolo.  (la sintassi di un DO k=e1,e2,e3 ... END DO è tale che le istruzioni tra DO ed END DO sono eseguite solo finche' la variabile contatore k soddisfa la condizione  k*e3 <= e2*e3;  tenendo conto che ad ogni esecuzione, la variabile k viene incrementata del valore di e3. Ricordare inoltre che se e3  è  assente,  si sottintende e3=1). Si ricordi anche che tutto il contenuto di una linea dal carattere !  in poi viene ignorato dal compilatore (  costituisce un commento al codice ).

  6.  

    program do_loops
    implicit none
    integer :: i,j,n_ciclo = 1

    print*," loop # ",n_ciclo     ! ciclo n. 1 ; scriviamo di quale ciclo si tratta per  identificarlo in output
    do i = 1,10,1
       print*,i
    end do

    n_ciclo = n_ciclo + 1           ! incrementiamo il numero di ciclo
    print*," loop # ",n_ciclo     ! ciclo n. 2
    do i = 1,10
       print*,i
    end do

    n_ciclo = n_ciclo + 1
    print*," loop # ",n_ciclo     ! ciclo n. 3
    do i = 1,10,-1
       print*,i
    end do

    n_ciclo = n_ciclo + 1
    print*," loop # ",n_ciclo     ! ciclo n. 4
    do i = 10,10,2
       print*,i
    end do

    n_ciclo = n_ciclo + 1
    print*," loop # ",n_ciclo     ! ciclo n. 5
    do i = 10,1,-1
       print*,i
    end do

    n_ciclo = n_ciclo + 1
    print*," loop # ",n_ciclo     ! ciclo n. 8
    do i = 1,3
       do j = i+1,3
          print*,"i= ",i," j= ",j
       end do
    end do
    end program do_loops

     


     
  7. Che valore della variabile  verrà  scritto dal seguente frammento di codice ?
  8. integer :: i , j

    i = 0
    do j = 1,10

       i = i + j
    end do
    print*,i
     


  9. Scrivere un programma  che dia  il risultato della somma dei quadrati dei primi N interi. (Il programma deve leggere il valore di N da tastiera (istruzione read*,nome_variabile), sommare uno ad uno gli N termini e confrontare il risultato con quello ottenuto mediante l' espressione analitica per la somma: N(N+1)(2N+1)/6 ).


  10. Il seguente programma chiede il numero dei dati che verranno immessi, li legge e ne calcola la media aritmetica. Verificarne il corretto funzionamento e poi modificarlo aggiungendo il calcolo della media dei quadrati in modo da poter valutare anche la varianza (differenza tra media dei quadrati e quadrato della media).
    program media
    implicit none
    real :: aver,x
    integer :: i,N

    print*," N= ?"
    read*,N

    print*," immetti i dati uno alla volta"
    aver=0.0
    do i=1,N
    read*,x
    aver = aver + x
    end do
    aver = aver/N
    print*," media di ",N," dati : ",aver
    end program media


  11. N.B. per ragioni connesse con la configurazione del software di sistema, prima di compilare il seguente programma andrà  dato il comando:   .   /home/pastore/setg95

    (è  sufficiente darlo una sola volta da ciascuna finestra terminal aperta).

  12. Visualizzare il grafico della funzione e-4 x2 sin(10 x) nell' intervallo [-1.5,1.5] valutando e scrivendo su  file coppie di numeri costituite da ascisse e valori della funzione su punti equispaziati nell' intervallo considerato.

    Suggerimenti:

    1. scrivere un programma che scriva su file fort.1 un certo numero (quante ?) di coppie ordinate (x,f(x)) ad ascisse equispaziate. Per scrivere su file, invece dell' istruzione print*,... si può usare l' istruzione write(unit=M,fmt=*)... dove ... rappresenta la lista delle variabili o costanti che si vuole scrivere. M rappresenta un intero positivo (con g95  deve essere diverso da 0, 5 e 6). Il file su cui il programma scriverà avrà nome fort.M   Da ricordare:
    a) gli indici dei DO devono essere variabili di tipo INTEGER
    b) si possono mettere in corrispondenza le ascisse (reali) equispaziate nell' intervallo [a,b] con gli interi da 0 a N attraverso la relazione lineare: xi=a + i/N*(b-a)   (ATTENZIONE però  a come si implementa in Fortran la precedente formula matematica!)

         2. Per visualizzare un grafico x-y: dalla finestra terminale dare il comando
             gnuplot
            e poi, al prompt (gnuplot>), il comando

             plot    'fort.1'    with   lines     (che si puo' abbreviare in     plot   'fort.1'   w l )

          per avere un grafico del risultato. 

         Se si avessero più colonne nello stesso file e si volessero  graficare i dati delle colonne 2 e 4 il comando andrebbe  modificato come:

          plot   'fort.1'   using 2:4 w l

           abbreviabile in:

         plot   'fort.1'   u 2:4 w l

       Per terminare dare quit; per avere aiuto circa l' uso di gnuplot: help. Un'  osservazione del  grafico risultante dovrebbe darci qualche indicazione sull'  adeguatezza del campionamento della  funzione.
      I grafici possono anche essere  salvati su file mediante i comandi di gnuplot:

      set term postscript color

set output "nomefile.ps"
            seguiti dalla lista di comandi per tracciare i grafici oppure  replot  (cfr help gnuplot per l' utilizzo).
       I file postscript possono essere inviati direttamente su stampante o  visualizzati  con applicazioni quali gv.


Gli esercizi successivi sono ulteriori spunti per esercitarsi  individualmente prima della prossima lezione.
  1. Scrivere un programma che mostri su schermo i quadrati, i cubi e le radici quadrate degli interi da 1 a 10 (Ricordare che c'è la funzione sqrt(x) per calcolare la radice quadrata di x. Tuttavia la funzione sqrt  richiede che l' argomento sia real. Pertanto occorrerà  trasformare un intero in reale.  Questo  può  esser fatto  mediante la funzione real(x), utilizzando una variabile reale intermedia o  anche moltiplicando l'  intero per 1.0 nell' argomento della funzione sqrt (perché ?))

  2. Scrivere un programma che generi e scriva i primi 100 interi ma, per quelli che sono quadrati perfetti (cioe' della forma N*N) scriva accanto al numero la stringa "Quadrato  perfetto ". Suggerimento: cercare metodi semplici per ottenere i quadrati perfetti.  Prima di scrivere anche una sola riga di codice,  cercate di scrivere nella forma più  chiara possibile un algoritmo che risolva il problema.