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
Documenti analoghi
Introduzione alla programmazione in FORTRAN
Corso di Calcolo Numerico per Ingegneria Meccanica - Sede di Vicenza
a.a.2005/2006