Υπολογιστικά Μαθηματικά CompMath Set1, Ζαφειράκογλου Απόστολος Εισαγωγή Η φιλοσοφία που χρησιμοποιήθηκε στην παρούσα εργασία ακολουθεί τα πρότυπα του συναρτησιακού προγραμματισμού. Οι κώδικες είναι γραμμένοι σε C++, έχουν μεταγλωτιστεί με το Gnu Compliler. Στους αλγορίθμους γίνεται χρήση κάποιων global λογικών μεταβλητών, που ελέγχουν τη ροή του προγράμματος, και αν έχει επιτευχθεί η απαιτούμενη σύγκλιση. Τα προγράμματα έχουν πολλές μικρές συναρτήσεις, που κάνουν αυτό το οποίο περιγράφει το όνομα τους. Στην main() κάθε προγράμματος οι συναρτήσεις καλούνται ακριβώς με τον τρόπο που θα σκεφτόμασταν/περιγράφαμε με λόγια τον αλγόριθμο. Για παράδειγμα, η συνάρτηση Bolzano, κάνει το έλεγχο στη συνάρτηση και στα ορίσματα που θα της δωθούν, χωρίς να ασχολείται με το πως βρέθηκαν τα ορίσματα. Με αυτή τη φιλοσοφία, στην τελευταία άσκηση, ορίσαμε συναρτήσεις που κάνουν πράξεις γραμμικής άλγεβρας, όπως αφαίρεση γραμμών πίνακα, πολλαπλασιασμός γραμμής με αριθμό, αντιμετάθεση γραμμών κτλ. 1 Άσκηση Find the root to the following equations: i) e x sin(x) = 0, x ( 4, 3) ii) x 2 5cos(x) e x + 3 = 0, x (0, 2) using the methods of bisection, linear interpolation and Newton-Raphson. Compare the three methods by computing the number of iterations needed to achieve relative accuracy of 10 10. 1
Computational Mathematics 1 ΑΣΚΗΣΗ 1.1 Η εξίσωση e x sin(x) = 0 1.1.1 Μέθοδος Bisection Εικόνα 1.1: Η εξίσωση e x sin(x) = 0 # include <iostream > # include <iomanip> / / std : : s e t p r e c i s i o n # include <cmath> using namespace std ; / * m e t a v l i t e s x, y : to pedio s t o opoio anazitw t i riza, x0 : to simeio pou elegxw gia riza, root : i r i z a * / double x= 4; double y= 3; double x0 ; double a k r i v e i a=pow(10, 10) ; double root ; i n t i t e r ; bool iknowtheroot= f a l s e ; double f ( double x ) return exp ( x ) s i n ( x ) ; bool bolzano ( double a, double b ) i f ( f ( a ) * f ( b ) ==0) 2
Computational Mathematics 1 ΑΣΚΗΣΗ iknowtheroot=true ; i f ( f ( a ) ==0) root=a ; e l s e root=b ; return true ; e l s e i f ( f ( a ) * f ( b ) <0) x=a ; y=b ; return true ; e l s e return f a l s e ; bool c h e c k t h i s ( double k s i ) i f ( abs ( f ( k s i ) )<= a k r i v e i a ) iknowtheroot=true ; root=k s i ; e l s e iknowtheroot= f a l s e ; return iknowtheroot ; / * * / void b i s e c t ( ) i f ( bolzano ( x, x0 )==true ) y=x0 ; e l s e x=x0 ; 3
Computational Mathematics 1 ΑΣΚΗΣΗ i n t main ( ) i t e r =1; while ( iknowtheroot== f a l s e ) x0=(x+y ) / 2 ; c h e c k t h i s ( x0 ) ; b i s e c t ( ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root <<endl << i t e r a t i o n s : << i t e r <<endl ; return 0; Εικόνα 1.2: Επίλυση της εξίσωσης e x sin(x) = 0 με τη μέθοδo Bisection 1.1.2 Μέθοδος Linear Interpolation # include <iostream > # include <cmath> # include <iomanip> / / std : : s e t p r e c i s i o n using namespace std ; 4
Computational Mathematics 1 ΑΣΚΗΣΗ / * m e t a v l i t e s x, y : to pedio s t o opoio anazitw t i riza, x0 : to simeio pou elegxw gia riza, root : i r i z a * / double x= 4; double y= 3; double x0 ; double a k r i v e i a=pow(10, 10); double root ; i n t i t e r ; bool iknowtheroot= f a l s e ; double f ( double x ) return exp ( x) s i n ( x ) ; bool bolzano ( double a, double b ) i f ( f ( a ) * f ( b)==0) iknowtheroot=true ; i f ( f ( a)==0) root=a ; e l s e root=b ; return true ; e l s e i f ( f ( a ) * f ( b) <0) x=a ; y=b ; return true ; e l s e return f a l s e ; bool c h e c k t h i s ( double k s i ) i f ( abs ( f ( k s i )) <= a k r i v e i a ) iknowtheroot=true ; root=k s i ; e l s e 5
Computational Mathematics 1 ΑΣΚΗΣΗ iknowtheroot= f a l s e ; return iknowtheroot ; / * * / void b i s e c t ( ) i f ( bolzano ( x, x0)== true ) y=x0 ; e l s e x=x0 ; i n t main ( ) i t e r =1; while ( iknowtheroot== f a l s e ) x0=y ( f ( y ) * ( y x ) ) / ( f ( y) f ( x ) ) ; c h e c k t h i s ( x0 ) ; b i s e c t ( ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root <<endl << i t e r a t i o n s : << i t e r <<endl ; return 0; 6
Computational Mathematics 1 ΑΣΚΗΣΗ Εικόνα 1.3: Επίλυση της εξίσωσης e x sin(x) = 0 με τη μέθοδo Linear Interpolation 1.1.3 Μέθοδος Newton-Raphson # include <iostream > # include <iomanip> / / std : : s e t p r e c i s i o n # include <cmath> using namespace std ; / * m e t a v l i t e s x, y : to pedio s t o opoio anazitw t i riza, x0 : to simeio pou elegxw gia riza, root : i r i z a * / / / double x= 4; double y= 3; double x0= 4; double a k r i v e i a=pow(10, 10); double root ; i n t i t e r ; bool iknowtheroot= f a l s e ; double f ( double x ) return exp ( x) s i n ( x ) ; 7
Computational Mathematics 1 ΑΣΚΗΣΗ double df ( double x ) return exp ( x) cos ( x ) ; bool c h e c k t h i s ( double k s i ) i f ( abs ( f ( k s i )) <= a k r i v e i a ) iknowtheroot=true ; root=k s i ; e l s e iknowtheroot= f a l s e ; return iknowtheroot ; / * * / i n t main ( ) i t e r =1; while ( iknowtheroot== f a l s e ) x0=x0 ( f ( x0 ) ) / ( df ( x0 ) ) ; c h e c k t h i s ( x0 ) ; / / b i s e c t ( ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root <<endl << i t e r a t i o n s : << i t e r <<endl ; return 0; 8
Computational Mathematics 1 ΑΣΚΗΣΗ Εικόνα 1.4: Επίλυση της εξίσωσης e x sin(x) = 0 με τη μέθοδo Newton-Raphson 9
Computational Mathematics 1 ΑΣΚΗΣΗ 1.2 Η εξίσωση x 2 5cos(x) e x + 3 = 0 Εικόνα 1.5: Η εξίσωση x 2 5cos(x) e x + 3 = 0 1.2.1 Μέθοδος Bisection # include <iostream > # include <iomanip> / / std : : s e t p r e c i s i o n # include <cmath> using namespace std ; / * m e t a v l i t e s x, y : to pedio s t o opoio anazitw t i riza, x0 : to simeio pou elegxw gia riza, root : i r i z a * / double x =0; double y =2; double x0 ; double a k r i v e i a=pow(10, 10) ; double root ; i n t i t e r ; bool iknowtheroot= f a l s e ; double f ( double x ) return x * x 5*cos ( x ) exp ( x ) +3; bool bolzano ( double a, double b ) 10
Computational Mathematics 1 ΑΣΚΗΣΗ i f ( f ( a ) * f ( b ) ==0) iknowtheroot=true ; i f ( f ( a ) ==0) root=a ; e l s e root=b ; return true ; e l s e i f ( f ( a ) * f ( b ) <0) x=a ; y=b ; return true ; e l s e return f a l s e ; bool c h e c k t h i s ( double k s i ) i f ( abs ( f ( k s i ) )<= a k r i v e i a ) iknowtheroot=true ; root=k s i ; e l s e iknowtheroot= f a l s e ; return iknowtheroot ; / * * / void b i s e c t ( ) i f ( bolzano ( x, x0 )==true ) y=x0 ; e l s e x=x0 ; 11
Computational Mathematics 1 ΑΣΚΗΣΗ i n t main ( ) i t e r =1; while ( iknowtheroot== f a l s e ) x0=(x+y ) / 2 ; c h e c k t h i s ( x0 ) ; b i s e c t ( ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root <<endl << i t e r a t i o n s : << i t e r <<endl ; return 0; Εικόνα 1.6: Επίλυση της εξίσωσης x 2 5cos(x) e x + 3 = 0 με τη μέθοδο Bisection 1.2.2 Μέθοδος Linear Interpolation # include <iostream > # include <iomanip> / / std : : s e t p r e c i s i o n # include <cmath> 12
Computational Mathematics 1 ΑΣΚΗΣΗ using namespace std ; / * m e t a v l i t e s x, y : to pedio s t o opoio anazitw t i riza, x0 : to simeio pou elegxw gia riza, root : i r i z a * / double x= 4; double y= 3; double x0 ; double a k r i v e i a=pow(10, 10); double root ; i n t i t e r ; bool iknowtheroot= f a l s e ; double f ( double x ) return x * x 5*cos ( x) exp ( x )+3; bool bolzano ( double a, double b ) i f ( f ( a ) * f ( b)==0) iknowtheroot=true ; i f ( f ( a)==0) root=a ; e l s e root=b ; return true ; e l s e i f ( f ( a ) * f ( b) <0) x=a ; y=b ; return true ; e l s e return f a l s e ; bool c h e c k t h i s ( double k s i ) i f ( abs ( f ( k s i )) <= a k r i v e i a ) iknowtheroot=true ; root=k s i ; 13
Computational Mathematics 1 ΑΣΚΗΣΗ e l s e iknowtheroot= f a l s e ; return iknowtheroot ; / * * / void b i s e c t ( ) i f ( bolzano ( x, x0)== true ) y=x0 ; e l s e x=x0 ; i n t main ( ) i t e r =1; while ( iknowtheroot== f a l s e ) x0=(x+y ) / 2 ; c h e c k t h i s ( x0 ) ; b i s e c t ( ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root <<endl << i t e r a t i o n s : << i t e r <<endl ; return 0; 14
Computational Mathematics 1 ΑΣΚΗΣΗ Εικόνα 1.7: Επίλυση της εξίσωσης x 2 5cos(x) e x + 3 = 0 με τη μέθοδο Linear Interpolation 1.2.3 Μέθοδος Newton-Raphson # include <iostream > # include <iomanip> / / std : : s e t p r e c i s i o n # include <cmath> using namespace std ; / * m e t a v l i t e s x, y : to pedio s t o opoio anazitw t i riza, x0 : to simeio pou elegxw gia riza, root : i r i z a * / / / double x= 4; double y= 3; double x0= 4; double a k r i v e i a=pow(10, 10); double root ; i n t i t e r ; bool iknowtheroot= f a l s e ; double f ( double x ) return x * x 5*cos ( x) exp ( x )+3; 15
Computational Mathematics 1 ΑΣΚΗΣΗ double df ( double x ) return 2*x+5* s i n ( x) exp ( x ) ; bool c h e c k t h i s ( double k s i ) i f ( abs ( f ( k s i )) <= a k r i v e i a ) iknowtheroot=true ; root=k s i ; e l s e iknowtheroot= f a l s e ; return iknowtheroot ; / * * / i n t main ( ) i t e r =1; while ( iknowtheroot== f a l s e ) x0=x0 ( f ( x0 ) ) / ( df ( x0 ) ) ; c h e c k t h i s ( x0 ) ; / / b i s e c t ( ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root <<endl << i t e r a t i o n s : << i t e r <<endl ; return 0; 16
Computational Mathematics 1 ΑΣΚΗΣΗ Εικόνα 1.8: Επίλυση της εξίσωσης x 2 5cos(x) e x + 3 = 0 με τη μέθοδο Newton-Raphson 1.3 Σχόλια Η διχοτόμηση του πεδίου ορισμού (Bisection), παρά το ότι συγκλίνει στην πραγματική λύση, απαιτεί μεγάλο αριθμό βημάτων, πράγμα που την καθιστά λιγότερο χρήσιμη. Επίσης, είναι προβληματική σαν μέθοδος σε περίπτωση που δεν πληρούνται οι προυποθέσεις του θεωρήματος Bolzano, δηλαδή στις περιπτώσεις που: η συνάρτηση παρουσιάζει κάποια ασυνέχεια η συνάρτηση έχει διπλές λύσεις Η γραμμική παρεμβολή (Linear Interpolation), αποτελεί βελτίωση της παραπάνω μεθόδου, και συγκλίνει ταχύτερα, όπως άλλωστε φαινεται από τον αριθμό των επαναλήψεων. Ένα μεγάλο πλεονέκτημα αυτής της μεθόδου, είναι ότι η λύση, δεν είναι υποχρεωτικό να περιέχεται στο αρχικό διάστημα που ψάχνουμε. Η μέθοδος Newton-Raphson είναι προφανώς η καλύτερη (συνήθως) επιλογή. Χρησιμοποιεί μία επιπλέον πληροφορία, αυτή της παραγώγου της συνάρτησης, και αποδεικνύεται ότι συγκλίνει πολύ ταχύτερα. Αρνητικά αυτής της μεθόδου είναι ότι: πρέπει να έχουμε παραγωγίσιμη συνάρτηση στην περιοχή που αναζητούμε τη λύση και προφανώς να γνωρίζουμε την τιμή της παραγώγου της συνάρτησης στα διάφορα σημεία (αυτό βέβαια δεν είναι τόσο δύσκολο, αφού τα πιο πολλά προβλήματα στη Φυσική έχουν συναρτήσεις συνεχείς και παραγωγίσιμες) θέλει προσοχή στα σημεία που μηδενίζεται ο παρονομαστής. 17
Computational Mathematics 2 ΑΣΚΗΣΗ 2 Άσκηση Find the roots to the following equations, using the x = g(x) method (carefully select the x = g(x) format that converges) and Aitken s acceleration formula: i) e x 2x 2 = 0, x ( 2, 0) ii) x 2 2x 3 = 0, (ρ 1 = 1, ρ 2 = 3) 2.1 Η εξίσωση e x 2x 2 = 0 2.1.1 Θετική ρίζα Εικόνα 2.1: Η εξίσωση e x 2x 2 = 0 # include <iostream > # include <cmath> # include <iomanip> / / std : : s e t p r e c i s i o n using namespace std ; double a k r i v e i a=pow(10, 10); double root ; bool i s i t o k = f a l s e ; i n t i t e r ; 18
Computational Mathematics 2 ΑΣΚΗΣΗ double g ( double x ) return s q r t ( exp ( x ) / 2 ) ; void c h e c k t h i s ( double x ) i f ( fabs ( g ( x) x)<= a k r i v e i a ) root=x ; i s i t o k =true ; i n t main ( ) double x= 2; i t e r =1; while ( i s i t o k == f a l s e ) c h e c k t h i s ( x ) ; x=g ( x ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root << i t e r a t i o n s : << i t e r <<endl ; return 0; 19
Computational Mathematics 2 ΑΣΚΗΣΗ Εικόνα 2.2: Θετική ρίζα της εξίσωσης e x 2x 2 = 0 2.1.2 Αρνητική ρίζα # include <iostream > # include <cmath> # include <iomanip> / / std : : s e t p r e c i s i o n using namespace std ; double a k r i v e i a=pow(10, 10); double root ; bool i s i t o k = f a l s e ; i n t i t e r ; double g ( double x ) return s q r t ( exp ( x ) / 2 ) ; void c h e c k t h i s ( double x ) i f ( fabs ( g ( x) x)<= a k r i v e i a ) root=x ; i s i t o k =true ; i n t main ( ) 20
Computational Mathematics 2 ΑΣΚΗΣΗ double x= 2; i t e r =1; while ( i s i t o k == f a l s e ) c h e c k t h i s ( x ) ; x=g ( x ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root << i t e r a t i o n s : << i t e r <<endl ; return 0; Εικόνα 2.3: Αρνητική ρίζα της εξίσωσης e x 2x 2 = 0 21
Computational Mathematics 2 ΑΣΚΗΣΗ 2.2 Η εξίσωση x 2 2x 3 = 0 Εικόνα 2.4: Η εξίσωση x 2 2x 3 = 0 2.2.1 Θετική ρίζα # include <iostream > # include <cmath> # include <iomanip> / / std : : s e t p r e c i s i o n using namespace std ; double a k r i v e i a=pow(10, 10); double root ; bool i s i t o k = f a l s e ; i n t i t e r ; double g ( double x ) return ( x * x x 3); void c h e c k t h i s ( double x ) i f ( fabs ( g ( x) x)<= a k r i v e i a ) root=x ; i s i t o k =true ; 22
Computational Mathematics 2 ΑΣΚΗΣΗ i n t main ( ) double x= 2; i t e r =1; while ( i s i t o k == f a l s e ) c h e c k t h i s ( x ) ; x=g ( x ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root << i t e r a t i o n s : << i t e r <<endl ; return 0; Εικόνα 2.5: Θετική ρίζα της εξίσωσης x 2 2x 3 = 0 2.2.2 Αρνητική ρίζα # include <iostream > # include <cmath> # include <iomanip> / / std : : s e t p r e c i s i o n using namespace std ; double a k r i v e i a=pow(10, 10); double root ; bool i s i t o k = f a l s e ; 23
Computational Mathematics 2 ΑΣΚΗΣΗ i n t i t e r ; double g ( double x ) return ( 3 ) / ( x 2); void c h e c k t h i s ( double x ) i f ( fabs ( g ( x) x)<= a k r i v e i a ) root=x ; i s i t o k =true ; i n t main ( ) double x= 1.9; i t e r =1; while ( i s i t o k == f a l s e ) c h e c k t h i s ( x ) ; x=g ( x ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s : <<root << i t e r a t i o n s : << i t e r <<endl ; return 0; 24
Computational Mathematics 2 ΑΣΚΗΣΗ Εικόνα 2.6: Αρνητική ρίζα της εξίσωσης x 2 2x 3 = 0 2.3 Σχόλια Η μέθοδος x = g(x) προσπαθεί να βρει που τέμνει η διχοτόμος του 1ου-3ου τεταρτημορίου την συνάρτηση g(x) που επιλέξαμε. Κριτήριο αποτελούσε να είναι g (x) < 1. Έτσι επιλέχθηκαν οι συναρτήσεις: για τη δευτεροβάθμια g(x) = x 2 x 3 g(x) = 3 x 2 για την εκθετική e x g(x) = 2 e x g(x) = + 2 Οι δυο αυτές εξισώσεις συγκλίνουν τόσο στις θετικές, όσο και στις αρνητικές ρίζες. Η μέθοδος συγκλίνει αρκέτα γρήγορα, ιδιαίτερα αν επιλέξουμε σωστή περιοχή για να ξεκινήσουμε την αναζήτηση της λύσης. 25
Computational Mathematics 3 ΑΣΚΗΣΗ 3 Άσκηση Solve the following system of equation, using both the x = g(x) and Newton- Raphson methods. Compare the convergence speed of the two methods, for relative accuracy of 10 9 : e x y = 0 xy e x = 0 Εικόνα 3.1: Εξισώσεις e x y = 0 και xy e x = 0 3.1 Μέθοδος x = g(x) # include <iostream > # include <cmath> # include <iomanip> / / std : : s e t p r e c i s i o n using namespace std ; double a k r i v e i a=pow(10, 10); double rootx ; double rooty ; bool i s i t o k = f a l s e ; i n t i t e r ; double g ( double x, double y ) return exp ( x ) / x ; double h( double x, double y ) 26
Computational Mathematics 3 ΑΣΚΗΣΗ return log ( y ) ; void c h e c k t h i s ( double x, double y ) i f ( fabs ( g ( x, y) y)<= a k r i v e i a ) i f ( fabs (h( x, y) x)<= a k r i v e i a ) rooty=y ; rootx=x ; i s i t o k =true ; i n t main ( ) double x =0.1; double y =0.1; i t e r =1; while ( i s i t o k == f a l s e ) c h e c k t h i s ( x, y ) ; y=g ( x, y ) ; x=h( x, y ) ; i t e r ++; std : : cout << std : : s e t p r e c i s i o n (15) << the root i s ( <<rootx <<, <<rooty << ) \ n a f t e r << i t e r a t i o n s : << i t e r <<endl ; return 0; 27
Computational Mathematics 3 ΑΣΚΗΣΗ Εικόνα 3.2: Επίλυση του συστήματος με τη μέθοδο x = g(x) 3.2 Μέθοδος Newton-Raphson # include <iostream > # include <iomanip> / / std : : s e t p r e c i s i o n # include <cmath> using namespace std ; double a =0.5; double b = 1. 1 ; double f ( double x, double y ) / / cout << i n s i d e f= <<exp ( x) y<<endl ; return exp ( x) y ; double g ( double x, double y ) / / cout << i n s i d e g= <<x *y exp ( x)<< endl ; return x *y exp ( x ) ; double fx ( double x, double y ) / / cout << i n s i d e dfx= << exp ( x)<< endl ; return exp ( x ) ; 28
Computational Mathematics 3 ΑΣΚΗΣΗ double fy ( double x, double y ) / / cout << i n s i d e dfy= << 1<<endl ; return 1; double gx ( double x, double y ) / / cout << i n s i d e dgx= <<y exp ( x)<< endl ; return y exp ( x ) ; double gy ( double x, double y ) / / cout << i n s i d e dgy= <<x<<endl ; return x ; bool iknowtheroot= f a l s e ; double rootx, rooty ; double a k r i v e i a=pow(10, 11); void c h e c k t h i s ( double x, double y ) i f ( fabs ( f ( x, y)< a k r i v e i a ) ) i f ( fabs ( g ( x, y)< a k r i v e i a ) ) cout << done\n ; iknowtheroot=true ; rootx=x ; rooty=y ; i n t main ( ) i n t i t e r =1; while ( iknowtheroot== f a l s e ) c h e c k t h i s ( a, b ) ; / * i epomeni grammi kwdika den e x e i enter, apla den xwraei se mikos xaraktirwn * / a=a ( f ( a, b ) * gy ( a, b) g ( a, b ) * fy ( a, b ) ) / ( fx ( a, b ) * gy ( a, b) gx ( a, b ) * fy ( a, b ) ) ; / * i epomeni grammi kwdika den e x e i enter, apla den xwraei se mikos xaraktirwn * / b=b (g ( a, b ) * fx ( a, b) f ( a, b ) * gx ( a, b ) ) / ( fx ( a, b ) * gy ( a, b) gx ( a, b ) * fy ( a, b ) ) ; i t e r ++; 29
Computational Mathematics 3 ΑΣΚΗΣΗ cout << \n\nresult a f t e r << i t e r << i t e r a t i o n s \n << endl ; std : : cout << std : : s e t p r e c i s i o n (15) << ( <<a<<, <<b<< ) <<endl ; return 0; Εικόνα 3.3: Επίλυση του συστήματος με τη μέθοδο Newton-Raphson 3.3 Σχόλια Με ακριβώς αντίστοιχο τρόπο και ανάλογη φιλοσοφία με την άσκηση 2, δουλεύουμε και για το μη-γραμμικό σύστημα εξισώσεων που μας δίνεται. Έτσι επιλέγουμε τις εξισώσεις: g(x, y) = y = ex x h(x, y) = x = ln(x) H μέθοδος Newton-Raphson για μη-γραμμικά συστήματα εξισώσεων έχει ταχύτατη σύγκλιση. Οι αναδρομικοί τύποι που χρησιμοποιούνται είναι: x n+1 = x n f g y g f y f x g y g x f y y n+1 = y n g f x f g x f x g y g x f y 30
Computational Mathematics 4 ΑΣΚΗΣΗ 4 Άσκηση Find the solution of the linear system Ax = B, using the (a) Gauss-Jordan (with pivoting), (b) L-U decomposition and (c) Jacobi methods. How many steps are required by the Jacobi method, in order to approximate the exact solution with an accuracy of 10 9? A = 0.002 4.000 4.000 3.000 2.906 5.387 7.998 B = 4.481 4.415 4.1 Μέθοδος Gauss-Jordan # include <iostream > # include <cmath> # include <iomanip> / / std : : s e t p r e c i s i o n using namespace std ; double t [ 3 ] [ 4 ] ; double c ; double dr [ 4 ] ; void pivot ( i n t c ) ; void showthearray ( ) short i n t i, j ; cout << \n\n <<endl ; f o r ( i =0; i <3; i ++) f o r ( j =0; j <4; j ++) i f ( j ==3) cout << ; std : : cout << std : : s e t p r e c i s i o n (10) << t [ i ] [ j ]<< ; cout <<endl ; void i n i t c o n d ( ) 31
Computational Mathematics 4 ΑΣΚΗΣΗ t [0][0]= 0.002; t [ 0 ] [ 1 ] = 4. 0 0 0 ; t [ 0 ] [ 2 ] = 4. 0 0 0 ; t [ 0 ] [ 3 ] = 7. 9 9 8 ; t [1][0]= 2.000; t [ 1 ] [ 1 ] = 2. 9 0 6 ; t [1][2]= 5.387; t [1][3]= 4.481; t [2][0]=3.000; t [2][1]= 4.031; t [2][2]= 3.112; t [2][3]= 4.415; void difrow ( i n t r1, i n t r2 ) i n t s ; f o r ( s =0; s <4; s ++) t [ r1 ] [ s] = t [ r2 ] [ s ] ; / / cout << << t [ 2 ] [ 0 ] << << t [ r2 ] [ s ]<< endl ; void multrowby ( i n t r1, double c ) f o r ( i n t s =0; s <4; s ++) t [ r1 ] [ s ]= t [ r1 ] [ s ] * c ; void keeprow ( i n t r1 ) i n t s ; f o r ( s =0; s <4; s ++) dr [ s ]= t [ r1 ] [ s ] ; void bringrowback ( i n t r1 ) i n t s ; f o r ( s =0; s <4; s ++) t [ r1 ] [ s ]= dr [ s ] ; / / void swaprows ( i n t r1, i n t r2 ) keeprow ( r1 ) ; f o r ( i n t i i =0; i i <4; i i ++) t [ r1 ] [ i i ]= t [ r2 ] [ i i ] ; 32
Computational Mathematics 4 ΑΣΚΗΣΗ bringrowback ( r2 ) ; i n t main ( ) i n i t c o n d ( ) ; cout << \n S t a r t \nepauksimenos Pinakas\n ; showthearray ( ) ; i n t i, j, k ; f o r (k=0;k<4;k++) / / pivot (k ) ; f o r ( i =(k +1); i <3; i ++) keeprow (k ) ; c=t [ i ] [ k ] / t [ k ] [ k ] ; multrowby (k, c ) ; difrow ( i, k ) ; bringrowback (k ) ; cout << \n END\nResult\n ; showthearray ( ) ; return 0; 33
Computational Mathematics 4 ΑΣΚΗΣΗ Εικόνα 4.1: Επίλυση του συστήματος με τη μέθοδο Gauss-Jordan 4.2 Μέθοδος L-U decomposition Οι αλγόριθμοι του Jacobi και του LU Decomposition αποτελούν μεταφράσεις των αλγορίθμων του βιβλίου της αριθμητικής ανάλυσης. Τα σύμβολα των αθροισμάτων έχουν αντικατασταθεί από μικρούς βρόγχους που αποθηκεύουν στις δυνητικές μεταβλητές sum. Ο αλγόριθμος περιγράφεται από το ακόλουθο σχήμα. 34
Computational Mathematics 4 ΑΣΚΗΣΗ Εικόνα 4.2 # include <iostream > # include <conio. h> # include <cmath> using namespace std ; double a [ 4 ] [ 4 ], l [ 4 ] [ 4 ] = 0, u [ 4 ] [ 4 ] = 0,sum, b [ 4 ], z [4]=0, x [4]=0; i n t main ( ) i n t n, i, k, j, p ; n=3; a [1][1]= 0.002; a [ 1 ] [ 2 ] = 4. 0 0 0 ; a [ 1 ] [ 3 ] = 4. 0 0 0 ; b [ 1 ] = 7. 9 9 8 ; a [2][1]= 2.000; a [2][2]=2.906; a [2][3]= 5.387; b[2]= 4.481; a [ 3 ] [ 1 ] = 3. 0 0 0 ; a [3][2]= 4.031; a [3][3]= 3.112; b[3]= 4.415; / / * * * * * * * * * * LU decomposition * * * * * / / f o r (k=1;k<=n ; k++) u[ k ] [ k ]=1; f o r ( i =k ; i <=n ; i ++) sum=0; 35
Computational Mathematics 4 ΑΣΚΗΣΗ f o r (p=1;p<=k 1;p++) sum+= l [ i ] [ p ] * u [ p ] [ k ] ; l [ i ] [ k]=a [ i ] [ k] sum; f o r ( j =k+1; j <=n ; j ++) sum=0; f o r (p=1;p<=k 1;p++) sum+= l [ k ] [ p ] * u [ p ] [ j ] ; u [ k ] [ j ]=( a [ k ] [ j ] sum ) / l [ k ] [ k ] ; / / * * * * * * * * Displaying LU matrix * * * * * * * * * * / / cout <<endl <<endl << LU matrix i s <<endl ; f o r ( i =1; i <=n ; i ++) f o r ( j =1; j <=n ; j ++) cout << l [ i ] [ j ]<< ; cout <<endl ; cout <<endl ; f o r ( i =1; i <=n ; i ++) f o r ( j =1; j <=n ; j ++) cout <<u [ i ] [ j ]<< ; cout <<endl ; / / * * * * * FINDING Z; LZ=b * * * * * * * * * / / f o r ( i =1; i <=n ; i ++) / / forward s u b t i t u t i o n method sum=0; f o r (p=1;p< i ; p++) sum+= l [ i ] [ p ] * z [ p ] ; z [ i ]=( b [ i ] sum ) / l [ i ] [ i ] ; / / * * * * * * * * * * FINDING X; UX=Z * * * * * * * * * * * / / f o r ( i =n ; i >0; i ) sum=0; f o r (p=n ; p> i ; p ) sum+=u[ i ] [ p ] * x [ p ] ; x [ i ]=( z [ i ] sum ) / u [ i ] [ i ] ; / / * * * * * * * * * * * DISPLAYING SOLUTION * * * * * * * * * * * * * * / / cout <<endl << S e t of s o l u t i o n i s <<endl ; f o r ( i =1; i <=n ; i ++) 36
Computational Mathematics 4 ΑΣΚΗΣΗ cout <<endl <<x [ i ] ; getch ( ) ; return 0; Εικόνα 4.3: Επίλυση του συστήματος με τη μέθοδο L-U decomposition 4.3 Μέθοδος Jacobi # include <iostream > # include <math. h> # include <iomanip> / / std : : s e t p r e c i s i o n # define N 3 # define E pow(10.0, 9) using namespace std ; double a [N] [N], b [N], x [N], xprev [N], acc [N], sum,mo; i n t i, j, k ; void i n i t c o n d ( ) a [1][0]= 0.002; a [ 1 ] [ 1 ] = 4. 0 0 0 ; a [ 1 ] [ 2 ] = 4. 0 0 0 ; b [ 1 ] = 7. 9 9 8 ; a [2][0]= 2.000; a [ 2 ] [ 1 ] = 2. 9 0 6 ; a [2][2]= 5.387; b[2]= 4.481; a [0][0]=3.000+ a [ 1 ] [ 0 ] ; a [0][1]= 4.031+ a [ 1 ] [ 1 ] ; a [0][2]= 3.112+ a [ 1 ] [ 2 ] ; b[0]= 4.415+b [ 1 ] ; void showa ( ) 37
Computational Mathematics 4 ΑΣΚΗΣΗ cout << endl << Pinakas A << endl ; f o r ( i =0; i <N; i ++) f o r ( j =0; j <N; j ++) std : : cout << std : : s e t p r e c i s i o n (15) << a [ i ] [ j ]<< \ t ; cout << endl ; cout << << endl ; cout << Pinakas B << endl ; f o r ( i =0; i <N; i ++) std : : cout << std : : s e t p r e c i s i o n (15) << b [ i ] << endl ; cout << << endl ; cout << S t a r t i n g from << endl ; x [ 0 ] = 1 ; x [ 1 ] = 2 ; x [2]=3; f o r ( i =0; i <N; i ++) cout << x << i +1 << = << x [ i ] << endl ; cout << << endl ; i n t main ( ) i n i t c o n d ( ) ; showa ( ) ; k=0; mo=1; while (mo>=e) f o r ( i =0; i <N; i ++) sum=0; f o r ( j =0; j <N; j ++) i f ( i!= j ) sum = sum + ( a [ i ] [ j ] * x [ j ] ) ; xprev [ i ]=x [ i ] ; x [ i ]=( b [ i ] / a [ i ] [ i ]) (sum / a [ i ] [ i ] ) ; acc [ i ]= fabs ( ( x [ i ] xprev [ i ] ) / xprev [ i ] ) ; mo=acc [ i ] /N; k++; cout << Result <<endl ; std : : cout << std : : s e t p r e c i s i o n (15) << s o l 1 = <<x [ 0 ] << \ t << sol2 = <<x [ 1 ] << \ t << sol3 = << x [ 2 ] << endl ; cout << After i n t e r a t i o n s : << k << endl ; return 0; 38
Computational Mathematics 4 ΑΣΚΗΣΗ Εικόνα 4.4: Επίλυση του συστήματος με τη μέθοδο Jacobi Η μέθοδος Jacobi, μετά από τη βελτίωση Αitken xρειάστηκε ένα βήμα για να προσεγγίσει τη λύση με ακρίβεια 10 9. 39