CAPITOLO 1 Esercizi risolti di programmazione Fortran

Transcript

CAPITOLO 1 Esercizi risolti di programmazione Fortran
CAPITOLO
1
Esercizi risolti di programmazione Fortran
In questa appendice si propongono testi e risoluzioni di alcuni temi d’esame di programmazione apparsi negli ultimi 6 anni nelle prove scritte per Ingegneria Industriale
Civile ed Ambientale. La soluzione è scritta nel vecchio linguaggio Fortan 77 ma può
essere compilata anche da più moderni compilatori quali il Fortran90 o il Fortran95.
I programmi che seguono rappresentano naturalmente una delle possibili soluzioni ai
temi d’esame e quindi hanno lo scopo di suggerire una traccia allo studente.
Per ogni tema si forniscono: l’enunciato, evenutali commenti e il codice Fortran di
soluzione diviso in due parti: un main che contiene il programma principale e tutti i
sottoprogrammi richiesti.
Prima di cominciare, è opportuno richiamare brevemente la sequenza di operazioni
che è necessario compiere per potere eseguire un programma Fortran sotto il sistema
operativo Linux, che è quello adottato per esempio nell’aula di Laboratorio per i corsi
di studio in Ingegneria.
Per una trattazione approfondita e dettagliata dell’uso del Fortran per Applicazioni
Numeriche si consiglia il testo numero [?] della bibliografia.
1
2
Esercizi risolti di programmazione Fortran
1.1
Scrittura compilazione ed esecuzione di un programma Fortran
I passi da seguire per l’esecuzione di un programma Fortran possono essere schematizzati come segue.
1. Creare un file in cui scrivere il programma vero e proprio (programma sorgente).
Tale file deve essere salvato con una estensione esplicita .f ad esempio radici.f.
Usare per questa operazione un editore, cioè un programma che permette di
aprire, modificare salvare un file. L’editore più semplice è kedit che si può fare
partire semplicemente digitando kedit sulla linea di comandi.
2. Compilare il programma sorgente per la generazione del programma eseguibile.
Si deve dare il seguente comando.
g77 file sorgente −o file eseguibile
Il nome del file eseguibile è arbitrario e non necessita di alcuna estensione. Ad
esempio
g77 radici.f −o radici
Questo comando invoca il compilatore dandogli come file di input il file radici.f che abbiamo precedentemente generato e restituisce come output il file
eseguibile radici.
3. Esecuzione del programma. A questo punto per fare eseguire il programma si
deve semplicemente dare l’istruzione
./file eseguibile
Nel nostro esempio
./radici
1.1#1
3
Programma sorgente per il calcolo delle soluzioni di un’equazione di secondo grado.
radici.f
program r a d i c i
c
! c a l c o l a l e s o l u z i o n i r e a l i d i una equazione d i secondo grado
c
i m p l i c i t none
r e a l a , b , c , delta , x1 , x2
write ( 6 , ∗ )
1
’ i n s e r i s c i i tre c o e f f i c i e n t i della
equazione d i secondo grado ’
read ( 5 , ∗ ) a , b , c
d e l t a = b∗∗2 − 4 . ∗ a∗ c
i f ( d e l t a . l t . 0 . 0 ) then
write ( 6 , ∗ ) ’ non c i sono s o l u z i o n i r e a l i ’
e l s e i f ( d e l t a . eq . 0 . 0 ) then
x1 = −b / ( 2 . 0 ∗ a )
write ( 6 , ∗ ) ’ s o l u z i o n i c o i n c i d e n t i in x1 = ’ , x1
else
x1 = (−b + s q r t ( d e l t a ) ) / ( 2 . ∗ a )
x2 = (−b − s q r t ( d e l t a ) ) / ( 2 . ∗ a )
write ( 6 , ∗ ) ’ l e due s o l u z i o n i sono : x1 = ’ , x1 , ’
end i f
stop
end
x2 = ’ , x2
Esempio di esecuzione del programma.
1. Dopo aver digitato dalla linea dei comandi: ./radici
2. apparirà sullo schermo la scritta inserisci i tre coefficienti della equazione
di secondo grado
3. a questo punto digitare i numeri: 1 -3 2 (separati da uno spazio o dal tasto di
invio).
4. Sullo schermo appariranno le soluzioni dell’equazione di II grado x2 − 3x + 2 = 0
x1 =1 x2 = 2
4
Esercizi risolti di programmazione Fortran
Esempio di programma sorgente per l’implementazione del metodo del
punto fisso per la soluzione dell’equazione x = cos(x)
punto fisso.f
!
!
!
!
program p u n t o f i s s o
i m p l i c i t none
dichiarazione delle v a r i a b i l i
i n t e g e r i t e r , imax
r e a l x0 , t o l , xnew , s c a r t o , xold
apertura f i l e d i output
open ( 2 3 , f i l e = ’ r i s u l t a t i ’ )
l e t t u r a d e i d a t i input
write ( 6 , ∗ ) ’ i n s e r i s c i x0 t o l
read ( 5 , ∗ ) x0 , t o l , imax
inizializzazione delle variabili
xold = x0
iter = 0
s c a r t o = 2 . d0∗ t o l
write ( 3 2 , 9 0 0 )
imax ’
c
! c i c l o i t e r a t i v o per l a implementazione d e l metodo d i
c
do while ( s c a r t o . gt . t o l . and . i t e r . l t . imax )
iter = iter + 1
xnew = cos ( xold )
s c a r t o = abs ( xnew − xold )
! importante : stampa r i s u l t a t i intermedi
! secondo un formato d e f i n i t o d a l l a r i g a 1000
write ( 3 2 , 1 0 0 0 ) i t e r , xnew , s c a r t o
xold = xnew
end do
1000 format ( i8 , f21 . 1 4 , d15 . 5 )
i f ( s c a r t o . l e . t o l ) then
! convergenza ! !
write ( 3 2 , ∗ ) ’ s o l u z i o n e f i n a l e ’ , xnew
write ( 3 2 , ∗ ) ’ i t e r a z i o n i ’ , i t e r
write ( 3 2 , ∗ ) ’ s c a r t o f i n a l e ’ , s c a r t o
else
! non convergenza ! !
write ( 3 2 , ∗ ) ’ s o l u z i o n e non t r o v a t a ’
end i f
close (32)
900
format ( 6 x , ” i t ” ,14 x , ” xk ” ,12 x , ” s c a r t o ” )
stop
end
punto f i s s o
1.2#1
5
• compilazione:
g77 punto_fisso.f -o punto_fisso
• esecuzione:
./punto_fisso
• dati in ingresso:
1 1.e-4 100
• file in output: risultati
it
xk
1
0.54030227661133
2
0.85755324363708
3
0.65428978204727
4
0.79348033666611
5
0.70136880874634
6
0.76395964622498
7
0.72210246324539
8
0.75041770935059
9
0.73140406608582
10
0.74423736333847
11
0.73560476303101
12
0.74142509698868
13
0.73750686645508
14
0.74014735221863
15
0.73836916685104
16
0.73956722021103
17
0.73876029253006
18
0.73930388689041
19
0.73893773555756
20
0.73918443918228
21
0.73901826143265
22
0.73913019895554
23
0.73905479907990
soluzione finale 0.7390548
iterazioni
23
scarto finale 7.5399876E-05
scarto
0.45970D+00
0.31725D+00
0.20326D+00
0.13919D+00
0.92112D-01
0.62591D-01
0.41857D-01
0.28315D-01
0.19014D-01
0.12833D-01
0.86326D-02
0.58203D-02
0.39182D-02
0.26405D-02
0.17782D-02
0.11981D-02
0.80693D-03
0.54359D-03
0.36615D-03
0.24670D-03
0.16618D-03
0.11194D-03
0.75400D-04
6
Esercizi risolti di programmazione Fortran
1.2
Temi d’esame risolti
Esercizio 1.1 Date le matrici quadrate A e B di dimensione N (N ≤ 30) si vuole
calcolare la matrice C = AB + BA, la sua traccia e la sua norma di Frobenius.
Scrivere un programma in linguaggio Fortran che:
(a) legge N, A e B;
(b) calcola la matrice C = AB + BA impiegando la subroutine PRODMAT che esegue
il prodotto tra due matrici quadrate;
(c) calcola la traccia α della matrice C usando la function TRAC;
qP
n
2
c
servendosi
(d) calcola la norma di Frobenius β della matrice C β =
i,j=1 ij
della function EUCMAT;
(e) stampa con commento α e β.
Risoluzione.
Si è definita una costante nmax per dimensionare al massimo le matrici. Tale parametro
deve essere passato, unitamente alla dimensione effettiva delle matrici stesse, a tutti i
sottoprogrammi che coinvolgono matrici.
Si noti che è sufficiente scrivere una sola subroutine: PRODMAT per eseguire il
calcolo della matrice C. Essa deve essere chiamata due volte con parametri invertiti (si
veda il main alla pagina seguente):
call PRODMAT(...,A,B,...)
call PRODMAT(...,B,A,...)
1.2#1
7
Listing 1.1: none
!
!
!
!
!
!
program B1
i m p l i c i t none
dichiarazione delle v a r i a b i l i
i n t e g e r nmax
parameter (nmax=30)
integer i , j , k , n
r e a l ∗8 a ( nmax, nmax) , b ( nmax, nmax) , c ( nmax, nmax)
r e a l ∗8 d ( nmax, nmax) , e ( nmax, nmax)
r e a l ∗8 a l f a , beta , trac , eucmat
lettura dei dati
open ( 1 5 , f i l e = ’ d a t i ’ )
read ( 1 5 , ∗ ) n
do i = 1 ,n
read ( 1 5 , ∗ ) ( a ( i , j ) , j =1 ,n )
end do
do i = 1 ,n
read ( 1 5 , ∗ ) ( b ( i , j ) , j =1 ,n )
end do
chiamata subroutine PRODMAT
D = AB
c a l l PRODMAT( n , nmax, a , b , d )
E = BA
c a l l PRODMAT( n , nmax, b , a , e )
C = AB + BA
do i = 1 ,n
do j = 1 ,n
c ( i , j ) = d( i , j ) + e( i , j )
end do
end do
a l f a = TRAC( n , nmax, C)
beta = EUCMAT( n , nmax, C)
!
write ( 6 , ∗ )
close (15)
!
stop
end
’ t r a c c i a d i C ’ , a l f a , ’ norma d i Frobenius ’ , beta
8
Esercizi risolti di programmazione Fortran
sottoprogrammi–ES1
! sottoprogrammi
subroutine PRODMAT( n , nmax, a , b , c )
i m p l i c i t none
i n t e g e r i , j , k , n , nmax
r e a l ∗8 a ( nmax, nmax) , b ( nmax, nmax) , c ( nmax, nmax)
do i = 1 ,n
do j = 1 ,n
c ( i , j ) = 0 . d0
do k = 1 ,n
c ( i , j ) = c ( i , j ) + a ( i , k ) ∗b ( k , j )
end do
end do
end do
return
end
!
r e a l ∗8 f u n c t i o n TRAC( n , nmax, c )
i m p l i c i t none
i n t e g e r i , n , nmax
r e a l ∗8 c ( nmax, nmax)
t r a c = 0 . d0
do i = 1 ,n
trac = trac + c ( i , i )
end do
return
end
!
r e a l ∗8 f u n c t i o n EUCMAT( n , nmax, c )
i m p l i c i t none
i n t e g e r i , j , n , nmax
r e a l ∗8 c ( nmax, nmax)
eucmat = 0 . d0
do i = 1 ,n
do j = 1 ,n
eucmat = eucmat + c ( i , j ) ∗∗2
end do
end do
eucmat = s q r t ( eucmat )
return
end
1.2#1
9
Esercizio 1.2 Si vuole risolvere il sistema lineare Ax = b di dimensione m ≤ 80
mediante il metodo iterativo di Richardson:
xk+1 = (I − βA)xk + βb
con β un numero reale positivo. Scrivere un programma in linguaggio FORTRAN che:
1. legge la soluzione iniziale x0 , il parametro β, la tolleranza sullo scarto T OLL e il
numero massimo di iterazioni IT M AX;
2. ad ogni iterazione calcola il vettore z = βAxk mediante la subroutine BMATVET,
la soluzione corrente xk+1 = xk − z + βb e lo scarto dk+1 = xk+1 − xk ;
3. calcola la norma euclidea del vettore scarto kdk+1 k2 mediante la function EUC;
4. arresta le iterazioni quando kdk+1 k2 ≤ T OLL oppure il numero di iterazioni supera IT M AX;
5. stampa la soluzione ed il numero di iterazioni effettuate.
Risoluzione.
Il metodo iterativo si implementa utilizzando due vettori xold e xnew per codificare
rispettivamente xk e xk+1 . Il ciclo iterativo è tradotto in Fortran utilizzando il costrutto while: si continua ad iterare fintantoché sono contemporaneamente verificate le
condizioni: kdk+1 k2 > T OLL e iter < ITMAX.
10
Esercizi risolti di programmazione Fortran
B2 main.f
!
!
!
!
program B2
i m p l i c i t none
dichiarazione delle v a r i a b i l i
i n t e g e r nmax
parameter (nmax=80)
r e a l ∗8 xold (nmax) , xnew (nmax) ,A( nmax, nmax) , z (nmax) , dk (nmax)
r e a l ∗8 b (nmax)
r e a l ∗8 t o l l , beta , s c a r t o , euc
i n t e g e r n , itmax , i t e r , i , j
l e t t u r a d a t i da f i l e
open ( 1 5 , f i l e = ’ d a t i ’ )
open ( 1 6 , f i l e = ’ output ’ )
read ( 1 5 , ∗ ) n , itmax , t o l l , beta
do i = 1 ,n
read ( 1 5 , ∗ ) ( a ( i , j ) , j =1 ,n )
end do
read ( 1 5 , ∗ ) ( xold ( i ) , i =1 ,n )
read ( 1 5 , ∗ ) ( b ( i ) , i =1 ,n )
inizializzazione
iter = 0
s c a r t o = 1 . d10
ciclo iterativo
do while ( i t e r . l t . itmax . and . s c a r t o . gt . t o l l )
c a l l bmatvet ( n , nmax, beta , xold , A, z )
do i = 1 ,n
xnew ( i ) = xold ( i ) − z ( i ) + beta ∗b ( i )
dk ( i ) = xnew ( i ) − xold ( i )
end do
s c a r t o = euc ( n , dk )
do i = 1 ,n
xold ( i ) = xnew ( i )
end do
end do
i f ( s c a r t o . l e . t o l l ) then
write ( 1 6 , ∗ ) ’ s o l u z i o n e raggiunta in ’ , i t e r , ’ i t e r a z i o n i ’
do i = 1 ,n
write ( 1 6 , ∗ ) xnew ( i )
end do
else
write ( 6 , ∗ ) ’ s o l u z i o n e non raggiunta in ’ , itmax , ’ i t e r a z i o n i ’
end i f
close (15)
close (16)
stop
end
1.2#1
11
sottoprogrammi–ES2
subroutine bmatvet ( n , nmax, beta , A, x , z )
i m p l i c i t none
i n t e g e r n , nmax
r e a l ∗8 x ( n ) , z ( n ) , a ( nmax, nmax) , beta
integer i , j
!
do i = 1 ,n
z ( i ) = 0 . d0
do j = 1 ,n
z ( i ) = z ( i ) + a ( i , j ) ∗x ( j )
end do
z ( i ) = beta ∗z ( i )
end do
return
end
!
!
!
r e a l ∗8 f u n c t i o n EUC( n , x )
i m p l i c i t none
integer n
r e a l ∗8 x ( n )
integer i
!
EUC = 0 . d0
do i = 1 ,n
EUC = EUC + x ( i ) ∗∗2
end do
EUC = s q r t (EUC)
return
end
12
Esercizi risolti di programmazione Fortran
Esercizio 1.3 Date la matrice quadrata A ed il vettore x di dimensione N ≤ 45 si vuole
calcolare il vettore y = A200 x secondo il seguente algoritmo:
1. y0 = x
2. yk+1 = Ayk ,
k = 0, · · · 199
3. y = y200
in cui il punto 2. deve essere implementato richiamando la subroutine MATVET
Scrivere un programma in linguaggio FORTRAN che:
1. legge N, A e x .
2. calcola il vettore y impiegando l’algoritmo precedente.
3. stampa con commento il vettore y.
Si fornisca inoltre la subroutine MATVET.
Risoluzione.
sottoprogrammi–ES3
subroutine matvet ( n , nmax, x , A, z )
i m p l i c i t none
i n t e g e r n , nmax
r e a l ∗8 x ( n ) , z ( n ) , a ( nmax, nmax)
integer i , j
c
do i = 1 ,n
z ( i ) = 0 . d0
do j = 1 ,n
z ( i ) = z ( i ) + a ( i , j ) ∗x ( j )
end do
end do
return
end
1.2#1
13
B3 main.f
program B3
i m p l i c i t none
!
dichiarazione delle v a r i a b i l i
i n t e g e r nmax
parameter (nmax=45)
r e a l ∗8 yold (nmax) , ynew (nmax) ,A( nmax, nmax) , x (nmax)
r e a l ∗8 t o l l , s c a r t o
integer n , i , j
! l e t t u r a d a t i da f i l e
open ( 1 5 , f i l e = ’ d a t i ’ )
open ( 1 6 , f i l e = ’ output ’ )
read ( 1 5 , ∗ ) n
do i = 1 ,n
read ( 1 5 , ∗ ) ( a ( i , j ) , j =1 ,n )
end do
read ( 1 5 , ∗ ) ( x ( i ) , i =1 ,n )
do i = 1 ,n
yold ( i ) = x ( i )
end do
c
do j = 1 ,200
c a l l matvet ( n , nmax, yold , A, ynew )
do i = 1 ,n
yold ( i ) = ynew ( i )
end do
end do
write ( 1 6 , ∗ ) ’ v e t t o r e y ’
do i = 1 ,n
write ( 1 6 , ∗ ) ynew ( i )
end do
close (15)
close (16)
stop
end
14
Esercizi risolti di programmazione Fortran
Esercizio 1.4 Si scriva un programma Fortran che calcola il quoziente di Rayleigh
q=
xT Ax
xT x
di una matrice quadrata di dimensione al massimo 40 × 40. Si richede in particolare di implementare una subroutine che esegue il prodotto di una matrice quadrata
per un vettore (MATVET) e una function che esegue il prodotto scalare tra due vettori
(SCAL) Il programma principale dovrà leggere la matrice ed il vettore da file, chiamare
opportunamente i sottoprogrammi e infine stampare con commento il risultato q.
Risoluzione.
Per quanto riguarda la subroutine MATVET si faccia riferimento al precedente esercizio B.3. Di seguito scriviamo l’implementazione della function SCAL.
sottoprogrammi–ES4
r e a l ∗8 f u n c t i o n s c a l ( n , x , y )
i m p l i c i t none
integer n
r e a l ∗8 x ( n ) , y ( n )
integer i
s c a l = 0 . d0
do i = 1 ,n
s c a l = s c a l + x ( i ) ∗y ( i )
end do
return
end
1.2#1
15
B4 main.f
program B4
i m p l i c i t none
!
dichiarazione delle v a r i a b i l i
i n t e g e r nmax
parameter (nmax=45)
r e a l ∗8 A( nmax, nmax) , x (nmax) , z (nmax)
r e a l ∗8 q , s c a l , numeratore , denominatore
integer n , i , j
! l e t t u r a d a t i da f i l e
open ( 1 5 , f i l e = ’ d a t i ’ )
read ( 1 5 , ∗ ) n
do i = 1 ,n
read ( 1 5 , ∗ ) ( a ( i , j ) , j =1 ,n )
end do
read ( 1 5 , ∗ ) ( x ( i ) , i =1 ,n )
!
! z = Ax
!
c a l l matvet ( n , nmax, x , A, z )
!
! numeratore = x ˆ T z
!
numeratore = s c a l ( n , x , z )
!
! denominatore = x ˆ T x
!
denominatore = s c a l ( n , x , x )
q = numeratore / denominatore
! stampa a video
write ( 6 , ∗ ) ’ i l quoziente d i Rayleigh vale ’ , q
close (15)
stop
end
16
Esercizi risolti di programmazione Fortran
Esercizio 1.5 Si vuole risolvere il sistema lineare Ax = b di dimensione m ≤ 40
mediante il seguente metodo iterativo:
xk+1 = Exk + q
con E matrice quadrata m × m e q vettore noto. Scrivere un programma in linguaggio
FORTRAN che:
1. legge la soluzione iniziale x0 , la tolleranza sullo scarto T OLL e il numero massimo
di iterazioni IT M AX; legge inoltre il vettore iniziale x0 , la matrice E ed il vettore
q.
2. ad ogni iterazione calcola la soluzione corrente xk+1 utilizzando la subroutine
MATVET per il prodoto matrice per vettore e lo scarto dk+1 = xk+1 − xk ;
3. calcola la norma euclidea del vettore scarto kdk+1 k2 mediante la function EUC;
4. arresta le iterazioni quando kdk+1 k2 ≤ T OLL oppure il numero di iterazioni
supera IT M AX;
5. stampa il numero di iterazioni effettuate e lo scarto finale.
Risoluzione.
I sottoprogrammi richiesti sono già stati descritti in esercizi precedenti. In particolare
per la function EUC si veda l’esercizio B.2 mentre per la subroutine MATVET l’esercizio
B.3.
1.2#1
17
B5 main.f
!
!
!
!
program B5
i m p l i c i t none
dichiarazione delle v a r i a b i l i
i n t e g e r nmax
parameter (nmax=40)
r e a l ∗8 xold (nmax) , xnew (nmax) ,A( nmax, nmax) , dk (nmax) , z (nmax)
r e a l ∗8 q (nmax)
r e a l ∗8 t o l l , s c a r t o , euc
i n t e g e r n , itmax , i t e r , i , j
l e t t u r a d a t i da f i l e
open ( 1 5 , f i l e = ’ d a t i ’ )
open ( 1 6 , f i l e = ’ output ’ )
read ( 1 5 , ∗ ) n , itmax , t o l l
do i = 1 ,n
read ( 1 5 , ∗ ) ( a ( i , j ) , j =1 ,n )
end do
read ( 1 5 , ∗ ) ( xold ( i ) , i =1 ,n )
read ( 1 5 , ∗ ) ( q ( i ) , i =1 ,n )
inizializzazione
iter = 0
s c a r t o = 1 . d10
ciclo iterativo
do while ( i t e r . l t . itmax . and . s c a r t o . gt . t o l l )
iter = iter + 1
c a l l matvet ( n , nmax, xold , A, z )
do i = 1 ,n
xnew ( i ) = z ( i ) + q ( i )
dk ( i ) = xnew ( i ) − xold ( i )
end do
s c a r t o = euc ( n , dk )
do i = 1 ,n
xold ( i ) = xnew ( i )
end do
end do
i f ( s c a r t o . l e . t o l l ) then
write ( 1 6 , ∗ ) ’ s o l u z i o n e raggiunta in
’ , iter , ’ iterazioni ’
write ( 1 6 , ∗ ) ’ norma d e l l o s c a r t o f i n a l e : ’ , s c a r t o
else
write ( 6 , ∗ ) ’ s o l u z i o n e non raggiunta in ’ , itmax , ’ i t e r a z i o n i ’
end i f
close (15)
close (16)
stop
end
18
Esercizi risolti di programmazione Fortran
Esercizio 1.6 Si scriva un programma Fortran che implementa il seguente metodo
iterativo
f (xn )
xn+1 = xn −
,
n = 0, 1, 2, . . .
K
dove x0 è il punto iniziale, f (x) = x3 − cos(x) e K è una costante assegnata. Il test
di arresto da utilizzare è basato sullo scarto e sul numero massimo di iterazioni. Il
programma dovrà leggere da file K, x0 , nmax e toll e visualizzare al termine del ciclo:
la soluzione trovata, lo scarto finale ed il numero di iterazioni impiegato. Si implementi
come function la funzione f .
Risoluzione.
B6 main.f
program B6
i m p l i c i t none
i n t e g e r j , nmax, i t e r
r e a l ∗8 f , k , xold , xnew , x0 , s c a r t o , t o l l
read ( 5 , ∗ ) x0 , t o l l , nmax, k
xold = x0
s c a r t o = 1 . d0
iter = 0
do while ( abs ( s c a r t o ) . gt . t o l l . and . i t e r . l t . nmax)
iter = iter + 1
xnew = xold − f ( xold ) / k
s c a r t o = xnew − xold
xold = xnew
end do
i f ( abs ( s c a r t o ) . l e . t o l l ) then
write ( 6 , ∗ ) ’ s o l u z i o n e = ’ , xnew
write ( 6 , ∗ ) ’ i t e r a z i o n i = ’ , i t e r
write ( 6 , ∗ ) ’ s c a r t o f i n a l e = ’ , s c a r t o
else
write ( 6 , ∗ ) ’ s o l u z i o n e non t r o v a t a in ’ ,nmax, ’ i t e r a z i o n i ’
end i f
stop
end
!
r e a l ∗8 f u n c t i o n f ( x )
i m p l i c i t none
r e a l ∗8 x
f = x∗∗3 − cos ( x )
return
end
1.2#1
19
Esercizio 1.7 Si scriva un programma Fortran che approssimi l’integrale
Z
2
I=
(e−x + x3 )dx
−1
utilizzando la formula di Cavalieri Simpson composta. In particolare il programma
deve
1. Leggere da tastiera gli estremi di integrazione e il numero m di applicazioni della
formula.
2. implementare tramite function: CAVSIM la formula semplice di Cavalieri
Simpson.
3. Implementare la formula composta chiamando opportunamente CAVSIM,
4. implementare tramite due function la funzione integranda f e la sua primitiva.
5. Visualizzare a video il numero di intervalli, l’approssimazione dell’integrale, il
valore vero e l’errore vero.
Risoluzione.
sottoprogrammi–ES7
r e a l ∗8 f u n c t i o n CAVSIM( a , b )
i m p l i c i t none
r e a l ∗8 a , b , fun , xmed
xmed = . 5 d0 ∗ ( a+b )
cavsim = ( b−a ) ∗ ( fun ( a ) +4. d0∗fun ( xmed ) +fun ( b ) ) / 6 . d0
return
end
c
r e a l ∗8 f u n c t i o n p r i m i t i v a ( x )
i m p l i c i t none
r e a l ∗8 x
p r i m i t i v a = −exp(−x ) + x ∗∗4∗0.25
return
end
c
r e a l ∗8 f u n c t i o n fun ( x )
i m p l i c i t none
r e a l ∗8 x
fun = exp(−x ) + x∗∗3
return
end
20
Esercizi risolti di programmazione Fortran
B7 main.f
program B7
!
i m p l i c i t none
r e a l ∗8 lung , v a l o r e v e r o , a , b , fun , p r i m i t i v a
r e a l ∗8 csim ,CAVSIM, errore , xa , xb
i n t e g e r i ,m
!
read ( 5 , ∗ ) a , b ,m
valore vero = primitiva ( b ) − primitiva ( a )
write ( 6 , ’ ( a , 2 f 8 . 2 ) ’ ) ’ i n t e r v a l l o d i i n t e g r a z i o n e ’ , a , b
write ( 6 , ’ ( a , f12 . 6 ) ’ ) ’ v a l o r e vero
’ , valore vero
csim = 0 . d0
lung = ( b−a ) / d f l o a t (m)
do i = 0 ,m−1
xa = a + d f l o a t ( i ) ∗lung
xb = xa + lung
csim = csim + CAVSIM( xa , xb )
end do
!
e r r o r e = abs ( v a l o r e v e r o − csim )
write ( 6 , ∗ ) ’ numero d i i n t e r v a l l i ’ ,m
write ( 6 , ∗ ) ’ i n t e g r a l e approssimato ’ , csim
write ( 6 , ∗ ) ’ e r r o r e a s s o l u t o ’ , e r r o r e
!
stop
end
1.2#1
21
Esercizio 1.8 Data la matrice quadrata A di dimensione n ≤ 50 e i fattori triangolari L
e U , basso e alto rispettivamente, tali che LU = à con à un’approssimazione sparsificata
di A, si vuole misurare la lunghezza euclidea del vettore differenza (v − x) ove x è un
vettore assegnato e:
v = L−1 AU −1 x
Scrivere un programma in linguaggio FORTRAN che:
1. legge n, A, L, U e x;
2. calcola il vettore y = U −1 x mediante sostituzioni all’indietro;
3. calcola il prodotto z = Ay con la subroutine MATVET;
4. calcola il vettore v = L−1 z mediante sostituzioni in avanti;
5. calcola il vettore differenza w = v − x;
6. calcola la norma euclidea di w mediante la function EUC e la stampa.
Suggerimento:
che per
dei vettore
y e v valgono le re si ricordi
le componenti
i-esime
Pn
Pi−1
lazioni yi = xi − j=i+1 uij yj /uii e vi = zi − j=1 lij zj /lii . Inoltre, le yi vanno
calcolate dall’ultima alla prima, mentre le vi dalla prima all’ultima.
Risoluzione.
Prestare attenzione alla lettura delle matrici L ed U .
Per quanto riguarda la function EUC si veda l’implementazione dell Esercizio B.1
mentre la subroutine MATVET è già presente nell implementazione dell’Esercizio
B.3.
22
Esercizi risolti di programmazione Fortran
B8 main.f
program B8
i m p l i c i t none
! dichiarazione delle v a r i a b i l i
i n t e g e r nmax
parameter (nmax=50)
r e a l ∗8 A( nmax, nmax) ,L ( nmax, nmax) ,U( nmax, nmax)
r e a l ∗8 v (nmax) , x (nmax) , z (nmax) , y (nmax) ,w(nmax)
r e a l ∗8 euc , nrm
integer n , i , j
! l e t t u r a d a t i da f i l e
open ( 1 5 , f i l e = ’ d a t i ’ )
read ( 1 5 , ∗ ) n
! l e t t u r a matrice A
do i = 1 ,n
read ( 1 5 , ∗ ) ( a ( i , j ) , j =1 ,n )
end do
! l e t t u r a matrice L
do i = 1 ,n
read ( 1 5 , ∗ ) ( l ( i , j ) , j =1 , i )
end do
! l e t t u r a matrice U
do i = 1 ,n
read ( 1 5 , ∗ ) ( u ( i , j ) , j =i , n )
end do
! lettura vettore x
read ( 1 5 , ∗ ) ( x ( i ) , i =1 ,n )
! backward s u b s i t u t i o n
do i = n,1 , −1
y( i ) = x( i )
do j = i +1 ,n
y ( i ) = y ( i ) − U( i , j ) ∗y ( j )
end do
y( i ) = y( i ) /u( i , i )
end do
! z = A y
c a l l MATVET( n , nmax, y , A, z )
! forward s u b s i t u t i o n
do i = 1 ,n
v( i ) = z( i )
do j = 1 , i −1
v ( i ) = v ( i ) − L ( i , j ) ∗v ( j )
end do
v( i ) = v( i ) / l ( i , i )
end do
do i = 1 ,n
w( i ) = v ( i ) − x ( i )
end do
nrm = EUC( n ,w)
write ( 6 , ∗ ) ’ norma d i w= ’ ,nrm
close (15)
stop
end
1.2#1
23
Esercizio 1.9
Si vuole risolvere l’equazione non lineare f (x) = 0, con f (x) =
il seguente schema iterativo noto come schema di Steffensen:
xk+1 = xk −
√
x2 + 1 + ln x, mediante
h2k
f (xk + hk ) − hk
in cui hk = f (xk ). Scrivere un programma in linguaggio FORTRAN che:
1. legge la soluzione iniziale x0 , la tolleranza sullo scarto τ e il numero massimo di
iterazioni IT M AX;
2. implementa lo schema assegnato arrestando le iterazioni quando |xk+1 − xk | ≤ τ
oppure il numero di iterazioni supera IT M AX;
3. stampa la soluzione ed il numero di iterazioni effettuate.
Risoluzione.
B9 main.f
program B9
i m p l i c i t none
i n t e g e r j , itmax , i t e r
r e a l ∗8 f , xold , xnew , x0 , s c a r t o , tau , hk
read ( 5 , ∗ ) x0 , tau , itmax
xold = x0
s c a r t o = 1 . d0
iter = 0
do while ( abs ( s c a r t o ) . gt . tau . and . i t e r . l t . itmax )
iter = iter + 1
hk = f ( xold )
xnew = xold − hk ∗ ∗ 2 / ( f ( xold+hk )−hk )
write ( 6 , ∗ ) i t e r , xnew , s c a r t o
s c a r t o = xnew − xold
xold = xnew
end do
i f ( abs ( s c a r t o ) . l e . tau ) then
write ( 6 , ∗ ) ’ s o l u z i o n e = ’ , xnew
write ( 6 , ∗ ) ’ i t e r a z i o n i = ’ , i t e r
write ( 6 , ∗ ) ’ s c a r t o f i n a l e = ’ , s c a r t o
else
write ( 6 , ∗ ) ’ s o l u z i o n e non t r o v a t a in ’ , itmax , ’ i t e r a z i o n i ’
end i f
stop
end
!
r e a l ∗8 f u n c t i o n f ( x )
i m p l i c i t none
r e a l ∗8 x
f = s q r t ( x ∗∗2+1. d0 ) + l o g ( x )
return
end