Scopo di questa esercitazione è di familiarizzarsi con le manipolazioni di base di files e directories, con l' interfaccia di linea, con il meccanismo di scrittura, compilazione ed esecuzione di semplici programmi. Il primo programma risolve la generica equazione algebrica di secondo grado in ampo complesso. Successivamente dovrà esser modificato per lavorare in campo reale. Infine qualche esercizio di base su cicli e operazioni completeranno un primo giro delle caratteristiche di base del linguaggio.
Gli esercizi prima della linea orizzontale andrebbero implementati (o almeno ne andrebbe tentata l'implementazione) prima del turno di laboratorio. Quelli dopo la linea orizzontale sono esercizi da fare dopo i pomeriggio di laboratorio. Tutti gli esercizi potrano essere ri-discussi e approfonditi sul forum dedicato agli esercizi sul sito moodle.Cosa hanno in comune i file che sono "apparsi" con l' opzione -a ?
Creare una directory di nome es1 (il
comando è mkdir: mkdir es1). Una volta creata la
directory es1, si potrà far
diventare questa la directory di default col comando cd es1. In questo modo tutti i nomi
"corti" dei files saranno completati dal sistema con la gerarchia di
directory che termina in es1: p.es il file pippo sarà interpretato come
corrispondente al nome lungo.
program secondo_grado
implicit none
! l' istruzione precedente obbliga a definire esplicitamente il tipo di ogni variabile
real :: a,b,c ! i coefficienti reali dell' equazione
! a x**2 + b x + c = 0
complex :: discr,xp,xm ! discriminante e soluzioni corrispondenti
! alle due scelte del segno davanti la
! radice quadrata
read*, a,b,c ! i coefficienti vengono letti da tastiera
discr = b**2 - 4*a*c
xp = ( -b + sqrt(discr) )/(2*a)
xm = ( -b - sqrt(discr) )/(2*a)
print*,xp,xm ! le due radici vengono scritte sullo schermo come complessi
end program secondo_grado
1 0 0
1 0 -1
1 0 1
1 -2 1
che il programma dia i risultati attesi. Prender nota di eventuali risultati inattesi.
Nel compilare i sorgenti Fortran può esser comodo utilizzare uno dei
parametri opzionali del comando gfortran per attribuire al file binario
eseguibile prodotto dal compilatore un nome diverso da a.out (risparmiando quindi l'
eventuale passo di cambiarne successivamente il nome con i
comandi di shell). Il parametro è
-o file
dove file indica il nome che si vuole attribuire all'
eseguibile. P.es.
gfortran pippo.f90 -o
pippo.x
il significato del comando è di compilare il file pippo.f90 e di
scrivere in output ( da cui -o ) il file binario (istruzioni macchina
corrispondenti) sul file il cui nome segue immediatamente il
modificatore -o.
Attenzione però a non sbagliarsi: se si mette per errore il
nome del file sorgente ( .f90) subito dopo -o il file sorgente verrà
cancellato!
IF( espressione logica )THENesegue le istruzioni del blocco 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 di errore. (Ricordare che l' ordine con cui si scrivono le istruzioni nel sorgente Fortran corrisponde a quello di esecuzione delle corrispondenti istruzioni macchina.)
...blocco 1
ELSE
...blocco 2
END IF
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).
Es:
program par
implicit none
integer :: i=2
print*,i
i=i+1
print*,i, i+3
print*,i
end program par
verificare il funzionamento del programma compilandolo ed eseguendolo.
integer :: somma , j
somma = 0
do j = 1,10
somma = somma + j
end do
print*,somma
Suggerimenti: procedere per passi successivi secondo la
seguente successione.
(ATTENZIONE però a come si implementa in Fortran la precedente formula matematica!)
2. aggiungere il calcolo e la scrittura su schermo delle ordinate (i valori della funzione). Sullo schermo dovranno apparire su ogni riga una coppia costituita da ascissa e ordinata.3. modificare infine l' istruzione di scrittura delle coppie in modo che vengano scritte su file fort.1. 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 a cui deve essere assegnato un valore intero (con gfortran deve essere diverso da 0, 5 e 6). Il file su cui il programma scriverà avrà nome fort.M (esempio: write(unit=10,fmt=*)a,b scriverà i valori delle variabili a e b sul file fort.10; è anche lecito abbreviare l' istruzione come: write(10,*)a,b.
4. 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 p '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:
p 'fort.1' u 2:4 w l Per terminare dare quit;
per avere aiuto circa l' uso di gnuplot: help.
Un' osservazione direta 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 pdfseguiti dalla lista di comandi per tracciare i grafici oppure replot (cfr help gnuplot per l' utilizzo).
set output "nomefile.pdf"
program cicli_do
implicit none
integer :: i,j,n_ciclo = 1 ! la variabile n_ciclo e'
inizializzata a 1 oltre che dichiarata
print*," ciclo N. ",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*," ciclo N. ",n_ciclo ! ciclo n. 2
do i = 1,10
print*,i
end do
n_ciclo = n_ciclo + 1
print*," ciclo N. ",n_ciclo ! ciclo n. 3
do i = 1,10,-1
print*,i
end do
n_ciclo = n_ciclo + 1
print*," ciclo N. ",n_ciclo ! ciclo n. 4
do i = 10,10,2
print*,i
end do
n_ciclo = n_ciclo + 1
print*," ciclo N. ",n_ciclo ! ciclo n. 5
do i = 10,1,-1
print*,i
end do
n_ciclo = n_ciclo + 1
print*," ciclo N. ",n_ciclo ! ciclo n. 6
do i = -10,10,3
print*,i
end do
n_ciclo = n_ciclo + 1
print*," ciclo N. ",n_ciclo ! ciclo n. 7
do i = 1,3
do j = 1,3
print*,"i= ",i," j= ",j
end do
end do
n_ciclo = n_ciclo + 1
print*," ciclo N. ",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 cicli_do
program espres
implicit none
real :: ra,rb,rc,rd,re,rf,rg,rh,ri,rs
integer :: ip,iq,ir,is,iu,iw,ix,iy,ij
logical :: les1,les2,les3
ra = 2
rb = 1
rc = 3.0
ip = 2
iq = 3
rd = rb/ra + rc
re = rb/rc + ra
rf = ip/iq
rg = ip/iq*iq/ip
ir = ra/rc*rc/ra
iu = (ra/rc)*(rc/ra)
iw = 8**(1/3)
rh = 4.7
ri = 10.2
ix = rh
iy = ri
ij = -4.7
les1 = ij < -4.0
les2 = .true. .and. (3*(1/3) == 1)
! il risultato di un' operazione di AND logico
! e' vero se e solo se sono veri tutti e due gli operandi
les3 = (1<2) .or. (3<=3) .and. (-5>-4.0) ! chi ha precedenza tra un .or. e un .and. ?
print *," in questo programma nomi che iniziano per r indicano variabili reali"
print *," nomi che iniziano per i indicano variabili intere, con l logiche"
print*," ra = 2: ra = ", ra
print*," rb = 1: rb = ", rb
print*," rc = 3.0: rc = ", rc
print*," ip = 2: ip = ", ip
print*," iq = 3: iq = ", iq
print *," rd = rb/ra + rc = ",rd
print *," re = rb/rc + ra = ",re
print *," rf = ip/iq = ",rf
print *," rg = ip/iq*iq/ip = ",rg
print *," ir = ra/rc*rc/ra = ",ir
print *," iu = (ra/rc)*(rc/ra) = ",iu
print *," is = ",is , " rs = ", rs, &
" (variabili dichiarate ma non definite nel programma) "
print *," iw = 8**(1/3) = ",iw
print *," ix = rh: ix = ",ix
print *," iy = ri: iy = ",iy
print *," ij = -4.7: ij = ",ij
print *,"2**3**2 = ", 2**3**2," quale potenza viene calcolata per prima ?"
print *,"les1 = ij < -4.0 : = ", les1
print *,"les2 = .true. .and. (3*(1/3) == 1) : = ",les2
print *,"les3 = (1<2) .or. (3<=3) .and. (-5>-4.0) : = ",les3
end program espres