Υπολογιστικά Μαθηματικά (Set 2)

Σχετικά έγγραφα
Υπολογιστικά Mαθηματικά II

Προγραμματισμός Ι. Κλάσεις και Αντικείμενα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Υπολογιστικά Mαθηματικά II

Γ7.1 Επανάληψη ύλης Β Λυκείου. Γ Λυκείου Κατεύθυνσης

Η εντολή if-else. Η απλή μορφή της εντολής if είναι η ακόλουθη: if (συνθήκη) { Η γενική μορφή της εντολής ifelse. εντολή_1; εντολή_2;..

Αριθμητικές Μέθοδοι σε Προγραμματιστικό Περιβάλλον

Πρόλογος Εισαγωγή στη δεύτερη έκδοση Εισαγωγή... 11

15 εκεµβρίου εκεµβρίου / 64

Υπολογιστικά Μαθηματικά

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τύποι δεδομένων ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ ΠΡΑΞΕΙΣ ΜΕΤΑΒΛΗΤΕΣ. Ακέραιοι αριθμοί (int) Πράξεις μεταξύ ακεραίων αριθμών

Αριθµητική Ολοκλήρωση

Εντολές εισόδου - εξόδου. Εισαγωγή στη C++

Πληροφορική 2. Γλώσσες Προγραμματισμού

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Τύποι δεδομένων, μεταβλητές, πράξεις. Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Αριθµητική Ανάλυση. ιδάσκοντες: Τµήµα Α ( Αρτιοι) : Καθηγητής Ν. Μισυρλής, Τµήµα Β (Περιττοί) : Επίκ. Καθηγητής Φ.Τζαφέρης. 25 Μαΐου 2010 ΕΚΠΑ

Είναι γνωστό ότι η δύναμη που ασκείται σε ένα ελατήριο και ονομάζεται δύναμη επαναφοράς δίνεται από τη σχέση : F = kx (3.1)

Αναφορές, είκτες και Αλφαριθμητικά

Στοιχειώδης προγραμματισμός σε C++

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τι περιλαμβάνει μια μεταβλητή; ΔΕΙΚΤΕΣ. Διεύθυνση μεταβλητής. Δείκτης

Υπερφόρτωση τελεστών

Κεφ. 7: Συνήθεις διαφορικές εξισώσεις (ΣΔΕ) - προβλήματα αρχικών τιμών

Δομές Επανάληψης. Εισαγωγή στη C++

5269: Υπολογιστικές Μέθοδοι για Μηχανικούς. Ολοκληρώματα.

Ευστρατιάδης Ευστράτιος Γεώργιος ΑΕΜ: ο σετ ασκήσεων Υπολ.Μαθ.2

Προγραμματισμός Υπολογιστών με C++

Συναρτήσεις (Functions) Εισαγωγή στη C++

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Εντολές for, while, do-while Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Aριθμητική Ανάλυση, 4 ο Εξάμηνο Θ. Σ. Παπαθεοδώρου

Προγραμματισμός Υπολογιστών με C++

Κεφ. 6Β: Συνήθεις διαφορικές εξισώσεις (ΣΔΕ) - προβλήματα αρχικών τιμών

Εισαγωγή στον Προγραμματισμό με C++

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Συναρτήσεις I Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Αριθμητική Ανάλυση και Εφαρμογές

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα εξής ακαδημαϊκά έτη: Διάρκεια: 2,5 ώρες, κλειστά βιβλία και σημειώσεις ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

Αριθμητικές Μέθοδοι σε Προγραμματιστικό Περιβάλλον

Χωρική Βάση δεδοµένων Autocad

5269: Υπολογιστικές Μέθοδοι για Μηχανικούς. Ολοκληρώματα.

Παράδειγµα #11 ΠΡΟΒΛΗΜΑΤΑ ΑΡΧΙΚΩΝ ΤΙΜΩΝ Σ Ε ΕΠΙΜΕΛΕΙΑ: Ν. Βασιλειάδης

x από το κεντρικό σημείο i: Ξεκινάμε από το ανάπτυγμα Taylor στην x κατεύθυνση για απόσταση i j. Υπολογίζουμε το άθροισμα:

Οντοκεντρικός Προγραμματισμός

Εφαρμοσμένα Μαθηματικά 3η εργαστηριακή άσκηση

Άσκηση 1. Α. Υπολογίστε χωρίς να εκτελέσετε κώδικα FORTRAN τα παρακάτω: Ποιά είναι η τελική τιμή του Z στα παρακάτω κομμάτια κώδικα FORTRAN:

ΑΡΙΘΜΗΤΙΚΕΣ ΜΕΘΟΔΟΙ, 5 Ο ΕΞΑΜΗΝΟ, ΠΕΡΙΕΧΟΜΕΝΑ ΠΑΡΑΔΟΣΕΩΝ. Κεφ. 1: Εισαγωγή (διάρκεια: 0.5 εβδομάδες)

Ελληνική Δημοκρατία Τεχνολογικό Εκπαιδευτικό Ίδρυμα Ηπείρου. Πληροφορική II. Ενότητα 3 : Γλώσσες προγραμματισμού. Δρ.

Αντικειμενοστραφείς Γλώσσες Προγραμματισμού C++ / ROOT

Κεφάλαιο 7: Υποπρογράμματα. Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τι είναι ; Συναρτήσεις. Παράδειγμα #1. double convert ( double cm ) { double inch;

Αριθμητικές Μέθοδοι σε Προγραμματιστικό Περιβάλλον

Αριθμητική Ανάλυση και Εφαρμογές

f x και τέσσερα ζευγάρια σημείων

ΜΕΜ251 Αριθμητική Ανάλυση

Κεφάλαιο 5. Το Συμπτωτικό Πολυώνυμο

Κεφάλαιο 7: Υπορουτίνες

2.Τι εννοούμε με βαθμό συνέχειας μιας συνάρτησης; Ποια είναι η χρησιμότητα της από πλευράς εφαρμογών;

Κεφάλαιο 8. Αριθμητικός υπολογισμός ορισμένου ολοκληρώματος

Πιο συγκεκριμένα, η χρήση του MATLAB προσφέρει τα ακόλουθα πλεονεκτήματα.

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τι είναι οι πίνακες; Μονοδιάστατοι πίνακες. Απλές μεταβλητές: Κεντρική μνήμη

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Δομή του προγράμματος. Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Εισαγωγή στην Αριθμητική Ανάλυση

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

Δομές Δεδομένων & Αλγόριθμοι

Β ΜΕΡΟΣ: ΕΦΑΡΜΟΓΗ ΤΟΥ MATLAB ΣΤΗΝ ΑΡΙΘΜΗΤΙΚΗ ΑΝΑΛΥΣΗ

Περιεχόμενα. Κεφάλαιο 1 ΣΥΣΤΗΜΑΤΑ ΣΥΝΤΕΤΑΓΜΕΝΩΝ ΣΕ ΜΙΑ ΕΥΘΕΙΑ Οι συντεταγμένες ενός σημείου Απόλυτη τιμή...14

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Δείκτες Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Προγραμματισμός Υπολογιστών με C++

α n z n = 1 + 2z 2 + 5z 3 n=0

Δομή Προγράμματος C++, Χειρισμός Μεταβλητών και Συναρτήσεις Εισόδου - Εξόδου

ΑΡΙΘΜΗΤΙΚΗ ΑΝΑΛΥΣΗ, , 3 Ο ΕΞΑΜΗΝΟ ΑΠΑΝΤΗΣΕΙΣ ΕΡΓΑΣΙΑΣ #4: ΟΛΟΚΛΗΡΩΣΗ ΕΠΙΜΕΛΕΙΑ: Σ. Μισδανίτης. με το πολυώνυμο παρεμβολής Lagrange 2 ης τάξης

17TimeThis.h function returns reference pointer to same object { return *this; }

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα προηγούμενα ακαδημαϊκά έτη: ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

Προγραµµατιστικές Τεχνικές

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Οντοκεντρικός Προγραμματισμός

Προγραμματισμός Ι. Εισαγωγή στην C++ Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Τεχνολογικό Εκπαιδευτικό Ίδρυμα Σερρών Τμήμα Πληροφορικής & Επικοινωνιών Σήματα και Συστήματα

ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ Α.Π.Θ. ΕΡΓΑΣΤΗΡΙΟ C++ ΕΞΑΜΗΝΟ Γ Ακαδηµαϊκό Έτος

Πληροφορική 2. Αλγόριθμοι

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

Υπερφόρτωση τελεστών (operator(

Εισαγωγή στη γλώσσα προγραμματισμού C++

5269: Υπολογιστικές Μέθοδοι για Μηχανικούς.

3 Αλληλεπίδραση Αντικειμένων

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 3 η : Επίλυση Προβληµάτων Χειµερινό Εξάµηνο 2011

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ Εντολές επανάληψης Εντολές επανάληψης while for do-while ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ Παράδειγμα #1 Εντολή while

y 1 (x) f(x) W (y 1, y 2 )(x) dx,

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Συναρτήσεις II Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

ΜΑΘΗΜΑΤΙΚΩΝ ΔΑΣΟΛΟΓΙΑΣ

(6,5 μονάδες) Θέμα 1 ο. Τμήμα Πολιτικών Μηχανικών Σχολή Τεχνολογικών Εφαρμογών Διεθνές Πανεπιστήμιο Ελλάδος ΟΝΟΜΑΤΕΠΩΝΥΜΟ

Άδειες Χρήσης Το παρόν εκπαιδευτικό υλικό υπόκειται σε άδειες χρήσης Creative Commons. Για εκπαιδευτικό υλικό, όπως εικόνες, που υπόκειται σε άλλου τύ

Τεχνολογικό Εκπαιδευτικό Ίδρυμα Σερρών Τμήμα Πληροφορικής & Επικοινωνιών Σήματα και Συστήματα

ΠΟΛΥΜΟΡΦΙΣΜΟΣ. 4.1 Κληρονομικότητα και Αρχή της Υποκατάστασης

ΟΝΤΟΚΕΝΤΡΙΚΟΣ ΠΡΟΓΡ/ΣΜΟΣ C++

Πίνακας Περιεχομένων

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

ΤΕΧΝΟΛΟΓΙΑ ΛΟΓΙΣΜΙΚΟΥ Ι

ΑΡΙΘΜΗΤΙΚΕΣ ΜΕΘΟΔΟΙ ΓΙΑ ΠΡΟΒΛΗΜΑΤΑ ΜΗΧΑΝΙΚΗΣ ΕΦΑΡΜΟΓΕΣ ΜΕ ΧΡΗΣΗ MATLAB ΔΕΥΤΕΡΗ ΕΚΔΟΣΗ [ΒΕΛΤΙΩΜΕΝΗ ΚΑΙ ΕΠΑΥΞΗΜΕΝΗ]

Οντοκεντρικός Προγραμματισμός

Οντοκεντρικός Προγραμματισμός

Transcript:

Υπολογιστικά Μαθηματικά (Set 2) Ζαφειράκογλου Απόστολος 1 Πολυώνυμο Langrange 1.1 Εισαγωγικά Στην υπόθεση της άσκησης δινοταν η συνάρτηση y(x) = 2 3 x sin(πx), x (0, 2). Ζητούμενο ήταν να προσεγγιστεί με ένα πολυώνυμο: i. Lagrange ii. Hermite Δεδομένου ότι η C++, όπως βέβαια και κάθε κλασσική γλώσσα προγραμματισμού, δεν μπορεί να διαχειριστεί πολυώνυμα, αρχικό ζητούμενο ήταν η ανάπτυξη ενός class, που να μπορεί να δουλέψει δίνοντας την αίσθηση ότι μεταχειρίζεται πολυώνυμα. Το class που αναπτύχθηκε σε αυτή την εργασία για το σκοπό αυτό ονομάζεται polynomial και καλείται ως header στην αρχή των προγραμμάτων μέσω της εντολής #include. Οι λόγοι για τους οποίους γίνεται αυτό είναι δύο: i. αφενώς μικραίνει ο κώδικας που πρέπει να ελέγξει κάποιος στο main πρόγραμμά του και ii. αφετέρου γίνεται ευκολότερη η χρήση του ίδιου κομματιού κώδικα, από άλλα προγράμματα Η κλάση που ακολουθεί, έχει προγραμματιστεί ώστε να κάνει τα ακόλουθα: n o βαθμός του πολυωνύμου a[ ] είναι ο πίνακας των συντελεστών. Το στοιχείο του πίνακα a[i] είναι συντελεστής του όρου x i Ορίζονται οι συναρτήσεις add και multiply, οι οποίες add: προσθέτει δύο αντίκειμενα πολυώνυμα multiply: πολλαπλασιάζει ένα πολυώνυμα με ένα μονώνυμο Χάρη στις δύο παραπάνω συναρτήσεις μπορούν πλέον να γραφούν ευκολότερα οι πράξεις τις αφαίρεσης πολυωνύμων και πολλαπλασιασμού δύο πολυωνύμων (prod). 1

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange Υπερφορτώνονται οι τελεστές +,-,*,/ για όλους τους δυνατούς συνδιασμούς πράξεων, ακόμη και για αφαίρεση double από polynomial ή για πολλαπλασιασμό double με polynomial Δημιουργήθηκε η μέθοδος της παραγώγισης D() ενός polynomial Η συνάρτηση Show δείχνει το αντικείμενο με μορφή πολυωνύμου, ενώ η συνάρτηση valueon() δείχνει την τιμή του πολυωνύμου σε εκείνο το σημείο. 1.2 Header Polynomial.h 1 #ifndef POLYNOMIAL_H_INCLUDED 2 #define POLYNOMIAL_H_INCLUDED 3 #include <iostream> 4 #include <cmath> 5 #include <cstdlib> 6 7 using namespace std; 8 9 class polynomial 10 { 11 12 public: 13 int n; 14 double a [30]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 15 polynomial friend operator+(const polynomial&, const polynomial&); 16 polynomial friend operator+(const polynomial&, const double&); 17 polynomial friend operator (const polynomial&, const polynomial&); 18 polynomial friend operator (const polynomial&, const double&); 19 polynomial friend operator*(const polynomial&, const polynomial&); 20 polynomial friend operator*(const double&, const polynomial&); 21 polynomial friend operator*( const polynomial&,const double&); 22 polynomial friend operator/(const polynomial&,const double&); 23 void show() 24 { 25 short int i=n; 26 while(i>=2) 27 { 28 cout <<"("<< a[i]<<")x^"<<i<<" + "; 29 i ; 30 } 31 cout <<"("<< a[1]<<")x + "<<"("<<a[0]<<")"<<endl; 32 } 33 double valueon(double xx) 34 { 35 int j=n;double val=0; 36 while(j>=0) 37 { 38 val+=a[j]*pow(xx,j); 2

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange 39 j ; 40 } 41 return val; 42 } 43 }; 44 45 /* Object polynomial: overloading +,*, */ 46 polynomial add(polynomial p1, polynomial p2) 47 { 48 polynomial result; 49 int i=p1.n; 50 if(p1.n<p2.n) 51 { 52 i=p2.n; 53 } 54 result.n=i; 55 while(i>=0) 56 { 57 result.a[i]=p1.a[i]+p2.a[i]; 58 i ; 59 } 60 61 return result; 62 } 63 64 polynomial multiply(int j,double x,polynomial p1) 65 { 66 polynomial result; int i; 67 result.n=p1.n+j; 68 i=p1.n; 69 while(i>=0) 70 { 71 result.a[i+j]=x*p1.a[i]; 72 i ; 73 } 74 /*cout <<"****"<<endl; 75 result.show();*/ 76 return result; 77 } 78 79 polynomial prod(polynomial p1, polynomial p2) 80 { 81 polynomial result; 82 result.n=p1.n+p2.n; 83 int i=p1.n; 84 85 86 while(i>=0) 87 { 3

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange 88 result=add(result, multiply(i,p1.a[i],p2)); 89 i ; 90 } 91 return result; 92 } 93 94 polynomial frac(double y,polynomial p1) 95 { 96 int k=p1.n; polynomial result; 97 result.n=p1.n; 98 while(k>=0) 99 { 100 result.a[k]=p1.a[k]/y; 101 k ; 102 } 103 return result; 104 } 105 106 polynomial D(polynomial p1) 107 { 108 polynomial result; 109 result.n=p1.n 1; 110 int i; 111 i=p1.n; 112 while(i>=1) 113 { 114 result.a[i 1]=i*p1.a[i]; 115 i ; 116 } 117 return result; 118 } 119 120 polynomial operator+(const polynomial& p1, const polynomial& p2) 121 { 122 return add(p1, p2); 123 } 124 125 polynomial operator*(const polynomial& p1, const polynomial& p2) 126 { 127 return prod(p1, p2); 128 } 129 polynomial operator*(const double& p1, const polynomial& p2) 130 { 131 return multiply(0,p1, p2); 132 } 133 polynomial operator*( const polynomial& p2,const double& p1) 134 { 135 return multiply(0,p1, p2); 136 } 4

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange 137 polynomial operator/( const polynomial& p2,const double& y) 138 { 139 return frac(y, p2); 140 } 141 polynomial operator (const polynomial& p1, const polynomial& p2) 142 { 143 polynomial p3=( 1)*p2; 144 return add(p1, p3); 145 } 146 polynomial operator (const polynomial& p1, const double& aa) 147 { 148 polynomial p2; 149 p2.n=0;p2.a[0]= aa; 150 return add(p1, p2); 151 } 152 polynomial operator+(const polynomial& p1, const double& aa) 153 { 154 polynomial p2; 155 p2.n=0;p2.a[0]=aa; 156 return add(p1, p2); 157 } 158 159 #endif // POLYNOMIAL_H_INCLUDED 1.3 Πολυώνυμο Lagrange Κάνοντας χρήση της παραπάνω κλάσης έγινε ευκολότερος ο προσδιορισμός των συντελεστών Lagrange και του ομόνυμου πολυωνύμου για την συνάρτηση της υπόθεσης y(x) = 2 3 x sin(πx), x (0, 2). Διάγραμμα 1.1: Γραφική παράσταση της συνάρτησης y(x) = 2 3 x sin(πx) Ο κώδικας που χρησιμοποιήθηκε εκμεταλλεύεται όλα τα στοιχεία της κλάσης. Στην αρχή ορί- 5

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange ζεται η συνάρτηση της εκφώνησης και έπειτα μια συνάρτηση που επιστρέφει ως αποτέλεσμα το πολυώνυμο lagrange. Στην main γίνεται η άθροιση των συντελεστών lagrange επί τις τιμές της συνάρτησης στα αντίστοιχα σημεία, και παρουσιάζεται το αποτέλεσμα. 1 #include <iostream> 2 #include <cmath> 3 #include <fstream> 4 #include "polynomial.h" 5 6 //Langrange 7 using namespace std; 8 9 /*Startup Functions*/ 10 double x[11];double f[11]; 11 int steps=9; 12 double pi=3.14159; 13 14 double myfunc(double xx) 15 { 16 return 2 3*xx*sin(pi*xx); 17 } 18 19 //InitCond 20 void initx() 21 { 22 int i=0;double h=0.2; 23 x[0]=0.2; 24 while( i<=steps) 25 { 26 x[i]=x[0]+i*h; 27 i++; 28 } 29 } 30 void inity() 31 { 32 short int i=0; 33 while(i<=steps) 34 { 35 f[i]= myfunc(x[i]); 36 i++; 37 } 38 } 39 40 void init() 41 { 42 initx();inity(); 43 } 44 45 polynomial lagrange(int i) 6

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange 46 { 47 polynomial result,cur[10]; 48 result.n=0;result.a[0]=1; 49 int k=0,j=0; 50 while(k<=steps) 51 { 52 cur[k].n=1;cur[k].a[0]= x[k];cur[k].a[1]=1; 53 cur[k]=cur[k];//cur[k].valueon(x[k]); 54 k++; 55 } 56 k=0; 57 while(k<=steps) 58 { 59 if(k==i){} 60 else 61 { 62 result=result*cur[k];//cur[k].valueon(x[k]); 63 result=result/result.valueon(x[i]); 64 } 65 k++; 66 } 67 68 return result; 69 } 70 71 int main() 72 { 73 init(); 74 polynomial final;final.n=0;int g=0; 75 while(g<=steps) 76 { 77 final=f[g]*lagrange(g) +final; 78 g++; 79 } 80 81 final.show(); 82 return 0; 83 } Παραθέτω τα πολυώνυμα που έβγαλε ως αποτέλεσμα το πρόγραμμα: 11.9999x 4 75.9997x 3 + 158.999x 2 125x + 31.9999 7

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange Διάγραμμα 1.2 Το πολυώνυμο 9ου βαθμού και το αντίστοιχο διάγραμμα: 0.404047x 9 5.15967x 8 + 24.7236x 7 54.9815x 6 + 56.4546x 5 28.1003x 4 + 21.6489x 3 16.014x 2 + 1.09939x + 1.92493 8

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange Διάγραμμα 1.3: Διάγραμμα προσεγγιστικού πολυωνύμου Lagrange 9ου βαθμού 1.4 Πολυώνυμο Hermite Το δεύτερο ερώτημα της ίδιας άσκησης ζητούσε να προσεγγιστεί η ίδια συνάρτηση με ένα πολύωνυμο Hermite. Αυτό έγινε εύκολα με τροποποίηση του παραπάνω κώδικα. Έγινε χρήση τόσο της συνάρτησης Lagrange, όσο και της μεθόδου της παραγώγισης που αναπτύχθηκε στην κλάση polynomial. Προφανώς χρησιμοποιήθηκε και η παράγωγος της συνάρτησης, η οποία ονομάζεται dmyfunc, που έδωσε του τα σημεία του πίνακα df[]. 1 #include <iostream> 2 #include <cmath> 3 #include <fstream> 4 #include "polynomial.h" 5 //Hermite 6 7 using namespace std; 8 9 10 /*Startup Functions*/ 11 double x[11];double f[11];double df[11]; 12 int steps=9; 13 double pi=3.14159; 14 15 double myfunc(double xx) 16 { 17 return 2 3*xx*sin(pi*xx); 18 } 19 double dmyfunc(double xx) 9

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange 20 { 21 return 3*(xx*cos(pi*xx)*pi + sin(pi*xx)); 22 } 23 24 //InitCond 25 void initx() 26 { 27 int i=0;double h=0.2; 28 x[0]=0.2; 29 while( i<=steps) 30 { 31 x[i]=x[0]+i*h; 32 i++; 33 } 34 } 35 void inity() 36 { 37 short int i=0; 38 while(i<=steps) 39 { 40 f[i]= myfunc(x[i]); 41 df[i]= dmyfunc(x[i]); 42 i++; 43 } 44 } 45 46 void init() 47 { 48 initx();inity(); 49 } 50 51 polynomial lagrange(int i) 52 { 53 polynomial result,cur[10]; 54 result.n=0;result.a[0]=1; 55 int k=0,j=0; 56 while(k<=steps) 57 { 58 cur[k].n=1;cur[k].a[0]= x[k];cur[k].a[1]=1; 59 cur[k]=cur[k];//cur[k].valueon(x[k]); 60 k++; 61 } 62 k=0; 63 while(k<=steps) 64 { 65 if(k==i){} 66 else 67 { 68 result=result*cur[k];//cur[k].valueon(x[k]); 10

ΠΜΣ Υπολογιστικη ς Φυσικη ς 1 Πολυω νυμο Langrange 69 result=result/result.valueon(x[i]); 70 } 71 k++; 72 } 73 74 return result; 75 } 76 77 polynomial A(int i) 78 { 79 polynomial result,mon,dlang,aa;result.n=0;result.a[0]=0;mon.n=1;mon.a [0]= x[i];mon.a[1]=1; 80 aa.n=0;aa.a[0]=1; 81 dlang=d(lagrange(i)); 82 result=(aa 2*mon*dlang.valueon(x[i]))*lagrange(i)*lagrange(i); 83 84 return result; 85 } 86 polynomial B(int i) 87 { 88 polynomial result,mon;result.n=0;result.a[0]=0; 89 mon.n=1;mon.a[0]= x[i];mon.a[1]=1; 90 91 result=mon*lagrange(i)*lagrange(i); 92 93 return result; 94 } 95 int main() 96 { 97 init(); 98 polynomial final,sum1,sum2;final.n=0;int g=0; 99 while(g<=steps) 100 { 101 sum1=sum1+a(g)*f[g]; 102 sum2=sum2+b(g)*df[g]; 103 g++; 104 } 105 final=sum1+sum2; 106 final.show(); 107 return 0; 108 } Το πολυώνυμο που εξήχθει είναι το ακόλουθο, και όπως φαίνεται από την γραφική του παράσταση, εφαρμόζει με εξαιρετική ακρίβεια πάνω στην πραγματική συνάρτηση, και άρα αποτελεί πολύ ικανοποιητική προσέγγιση της, ακόμα και ένα μικρό διάστημα έξω από αυτό που ζητήθηκε! 11

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 0.000165083x 19 0.00327605x 18 + 0.0301957x 17 0.171705x 16 +0.674744x 15 1.94379x 14 + 4.24432x 13 7.17151x 12 +9.58398x 11 10.3582x 10 + 8.46851x 9 3.82361x 8 +2.93964x 7 8.84888x 6 + 0.374634x 5 + 15.4155x 4 +0.0147409x 3 9.42645x 2 + 0.000115186x + 2 Διάγραμμα 1.4: Γραφική παράσταση του πολυωνύμου Hermite (μωβ) με την πραγματική γραφική παράσταση της συνάρτησης (πορτοκαλί). 2 Αριθμητικές Ολοκληρώσεις 2.1 Newton-Cotes (Romberg s Improvement) Ζητούμενο της δεύτερης άσκησης ήταν η αριθμητική ολοκλήρωση δύο συναρτήσεων, με διαφορετικούς τρόπους. Όπως είναι αναμενόμενο, οι μέθοδοι για αυτού του είδους τις ολοκληρώσεις, βασίζονται στην ιδέα του συμπτωτικού πολυωνύμου. Χαρακτηριστικοί τύποι είναι αυτοί των Newton-Cotes. Στο κώδικα που ακολουθεί γίνεται σύγκριση των αποτελεσμάτων με τις πραγματικές τιμές των ολοκληρωμάτων, και υπολογίζεται το σφάλμα. Ακόμη γίνεται χρήση της βελτίωσης του Romberg. Για ευκολία ελέγχου των διαφόρων μεθόδων, ο πηγαίος κώδικας έχει μέσα όλες της ρουτίνες που απαιτούνται. Σε αυτό το σημείο πρέπει να σημειωθούν δύο πράγματα: i. Χάρη στο polynomial class, έγινε δυνατή η ανάπτυξη ρουτίνας που υπολογίζει συμπτωτικό 12

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις πολυώνυμο, αν της δοθεί μιά διαμέριση. Η ρουτίνα ονομάζεται Psympt. Προφανώς για διαμέριση του πεδίου σε 2, 3 ή 4 σημεία, το αποτέλεσμα είναι οι τύποι των Newton- Cotes. Παρ όλ αυτά δεν γίνεται χρήση της ρουτίνας για τόσα σημεία αλλά εφαρμόζονται απευθείας οι έτοιμες φόρμουλες της θεωρίας. ii. Όπως θα φανεί αργότερα από τα αποτελέσματα των μεθόδων, οι μέθοδοι των Newton- Cotes δεν καταφέρνουν να πιάσουν την επιθυμητή ακρίβεια. Γι αυτό ακριβώς το λόγο, προσεγγίζουμε με μια καλύτερη διαμέριση, και ζητούμε από την Psympt την κατασκευή κάποιων πολυωνύμων μεγαλύτερου βαθμού. Ολοκληρώνοντας τα πολυώνυμα με τη χρήση της ρουτίνας Intergrate, μπορούμε να καταλήξουμε σε μια καλύτερη εκτίμηση της πραγματικής τιμής. 1 #include <iostream> 2 #include <iomanip> 3 #include "polynomial.h" 4 #include <cmath> 5 using namespace std; 6 double pi=3.14159;double eps=pow(10, 6); 7 double h;int n; 8 double *x= new double [n+5]; 9 10 double myfunc(double xx) 11 { 12 // Formula of function 13 return sqrt(xx 0.1); 14 //return exp( xx)*sin(5*xx); 15 } 16 void set(double a,double b,double M) 17 { 18 // a:start X, b:end X, M:How many steps 19 int i=0; h=(b a)/(m); n=m; 20 while (i<=n) 21 { 22 x[i]=a+h*i; 23 i++; 24 } 25 } 26 double NC(short int order,int o) 27 { 28 double answ=0; 29 if(order==1){ 30 answ=(h/2)*(myfunc(x[o]) +myfunc(x[o+1])); 31 } 32 else if (order==2){ 33 answ=(h/3)*(myfunc(x[o]) +4*myfunc(x[o+1])+myfunc(x[o+2])); 34 } 35 else if (order ==3){ 13

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 36 answ=(3*h/8)*(myfunc(x[o]) +3*myfunc(x[o+1]) + 3*myfunc(x[o+2])+myfunc(x [o+3])); 37 } 38 return answ; 39 } 40 41 double trapezoid(int k, int o) 42 { 43 int i=o; double sum=0; 44 while(i<=k 1) 45 { 46 sum+=nc(1,i); 47 i++; 48 } 49 return sum; 50 } 51 52 double Simpson(int k, int o) 53 { 54 int i=o; double sum=0; 55 while(i<=k 2) 56 { 57 58 sum+=nc(2,i); 59 i+=2; 60 } 61 return sum; 62 } 63 64 double Simpson38(int k, int o) 65 { 66 int i=o; double sum=0; 67 while(i<=k 3) 68 { 69 sum+=nc(3,i); 70 i+=3; 71 } 72 return sum; 73 } 74 75 double Romberg(int k,int o) 76 { 77 double I1,I2; 78 set(1,2,k); 79 I1=Simpson(k,o); 80 set(1,2,2*k); 81 I2=Simpson(2*k,o); 82 //cout <<"I1="<<I1<<" I2="<<I2<<endl; 83 return I2 + (I2 I1)/3; 14

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 84 } 85 double factorial(double xx) 86 { 87 int i=1; double answ=1; 88 while(i<=xx) 89 { 90 answ*=i; 91 i++; 92 } 93 return answ; 94 } 95 double delta(int k,int i) 96 { 97 double answ=0; 98 if(k==1) 99 { 100 answ=myfunc(x[i+1]) myfunc(x[i]); 101 } 102 else 103 { 104 answ=delta(k 1,i+1) delta(k 1,i); 105 } 106 107 return answ; 108 } 109 polynomial Psympt(int n, int o) 110 { 111 polynomial s,ks,answ;int i=1; 112 s.n=1;s.a[1]=1/h;s.a[0]= x[o]/h; answ.n=0;answ.a[0]=myfunc(x[o]); ks. n=0;ks.a[0]=1; 113 while(i<=n) 114 { 115 ks=ks*(s i+1)/i; 116 answ=answ+delta(i,o)*ks; 117 i++; 118 } 119 return answ; 120 } 121 122 polynomial Intergrate(polynomial p1) 123 { 124 polynomial answ; 125 answ.n=p1.n+1; 126 int i=n; 127 while(i>=0) 128 { 129 answ.a[i+1]=p1.a[i]/(i+1); 130 i ; 131 } 15

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 132 return answ; 133 } 134 135 int main() 136 { 137 int simeia=2; double err; 138 int g; 139 double realvalue=(2*pow(2 0.1,1.5) 2*pow(1 0.1,1.5))/3; 140 141 cout.precision(15) ; 142 cout <<"\n Newton Cotes 1 "<<endl; 143 set(1,2,simeia); 144 cout << " "<<NC(1,0)<<endl; 145 err=fabs(100*((realvalue) (NC(1,0)))/(realvalue)); 146 cout.precision(2) ; 147 cout <<" Error = "<<err <<"%"<<endl; 148 149 cout.precision(15) ; 150 cout <<"\n Newton Cotes 2 "<<endl; 151 simeia=3; 152 set(1,2,simeia); 153 cout << " "<<NC(2,0)<<endl; 154 err=fabs(100*((realvalue) (NC(2,0)))/(realvalue)); 155 cout.precision(2) ; 156 cout <<" Error = "<<err <<"%"<<endl; 157 158 cout.precision(15) ; 159 cout <<"\n Newton Cotes 3 "<<endl; 160 simeia=4; 161 set(1,2,simeia); 162 cout << " "<<NC(3,0)<<endl; 163 err=fabs(100*((realvalue) (NC(3,0)))/(realvalue)); 164 cout.precision(2) ; 165 cout <<" Error = "<<err <<"%"<<endl; 166 167 cout.precision(15) ; 168 169 cout <<"\n Romberg \n"<< " "<< Romberg(4,0)<<"\n"<<endl; 170 err=fabs(100*((realvalue) (Romberg(4,0)))/(realvalue)); 171 cout.precision(2) ; 172 cout <<" Error : "<<err <<"%"<<endl; 173 174 ////Psympt 5 175 cout.precision(2) ; 176 cout <<"\n\n Symptotical Polynomial 5 points "<<endl; 177 polynomial myp,myintergratedp; 178 simeia=5; 179 set(1,2,simeia); 180 myp=psympt(simeia,0); 16

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 181 cout <<" P5(x) = "; 182 myp.show(); 183 myintergratedp=intergrate(myp); 184 cout <<"After Intergration = "; 185 myintergratedp.show(); 186 double myvalue=myintergratedp.valueon(2) myintergratedp.valueon(1); 187 cout.precision(15) ; 188 cout <<"Value of Intergrated Polynomial = "<< myvalue<<endl; 189 err=fabs(100*((realvalue) (myvalue))/(myvalue)); 190 cout.precision(2) ; 191 cout <<" Error = "<<err <<"%"<<endl; 192 cout << "\n"<<endl; 193 ////Psympt 6 194 cout.precision(2) ; 195 cout <<"\n Symptotical Polynomial 6 points "<<endl; 196 //polynomial myp,myintergratedp; 197 simeia=6; 198 set(1,2,simeia); 199 myp=psympt(simeia,0); 200 cout <<" P6(x) = "; 201 myp.show(); 202 myintergratedp=intergrate(myp); 203 cout <<"After Intergration = "; 204 myintergratedp.show(); 205 myvalue=myintergratedp.valueon(2) myintergratedp.valueon(1); 206 cout.precision(15) ; 207 cout <<"Value of Intergrated Polynomial = "<< myvalue<<endl; 208 err=fabs(100*((realvalue) (myvalue))/(myvalue)); 209 cout.precision(2) ; 210 cout <<" Error = "<<err <<"%"<<endl; 211 cout.precision(15) ; 212 213 //Simpson 214 cout <<"\n\n Simpson \n"<<endl; 215 216 g=3; 217 simeia=1; 218 while(g<=24){ 219 simeia=g*simeia; 220 set(1,2,simeia); 221 cout.precision(19) ; 222 cout <<"Running for "<<g<<"points"<<endl; 223 cout << " Simpson = "<<Simpson(simeia,0)<<endl; 224 cout << " Real value = "<<(2*pow(2 0.1,1.5) 2*pow(1 0.1,1.5))/3<<endl; 225 err=100*(((2*pow(2 0.1,1.5) 2*pow(1 0.1,1.5))/3) (Simpson(simeia,0))) /((2*pow(2 0.1,1.5) 2*pow(1 0.1,1.5))/3); 226 cout.precision(3) ; 227 cout<<" Error = "<< fabs(err)<<"%"<<endl; 228 g*=2; 17

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 229 } 230 231 cout <<"\n Simpson38 \n"<<endl; 232 g=4; 233 simeia=1; 234 235 while(g<=100){ 236 simeia=g*simeia; 237 set(1,2,simeia); 238 cout.precision(15) ; 239 cout <<"Running for "<<g<<"points"<<endl; 240 cout << " Simpson38 = "<<Simpson38(simeia,0)<<endl; 241 cout << " Real value = "<<(2*pow(2 0.1,1.5) 2*pow(1 0.1,1.5))/3<<endl; 242 err=100*(((2*pow(2 0.1,1.5) 2*pow(1 0.1,1.5))/3) (Simpson38(simeia,0))) /((2*pow(2 0.1,1.5) 2*pow(1 0.1,1.5))/3); 243 cout.precision(3) ; 244 cout<<" Error = "<< fabs(err)<<"%"<<endl; 245 g*=3; 246 } 247 return 0; 248 } Κάποια πράγματα που αξίζει ακόμη να σχολιαστούν για τον κώδικα, ειναι ο τρόπος σύνταξης των συναρτήσεων. Έγινε προσπάθεια οι ρουτίνες που γράφτηκαν, να προσομοιάζουν το τρόπο σύνταξης των συμβολικών γλωσσών προγραμματισμού. Αυτή η γενικότητα έγινε σκόπιμα, ώστε τόσο τα κομμάτια του κώδικα να είναι δυνατό να μεταφερθούν από την μια άσκηση στην άλλη, όσο και να γίνει ευκολότερη η απασφαλμάτωση κατά τη συγγραφή. Αν και σε γενικές γραμμές τα ονόματα και ο κώδικας δείχνουν τι κάνει η κάθε συνάρτηση, υπάρχουν κάποια σημεία που κρίθηκε αναγκαίο να εξηγηθούν καλύτερα: NC(τύπος, σημείο εκκίνησης): η συνάρτηση NC ανάλογα με το εάν το πρώτο όρισμα είναι 1, 2 ή 3, επιστρέφει το αποτέλεσμα του αντίστοιχου τύπου των Newton-Cotes, ξεκινώντας από το σημείο που καθορίζεται από δεύτερο όρισμα. Αυτό έγινε για να γραφούν οι συναρτήσεις trapezoid, Simpson, Simpson38 με ομοιόμορφο τρόπο set(αρχή διαμέρισης, τέλος διαμέρισης, πλήθος): η συνάρτηση αυτή δημιουργεί το πίνακα των σημείων της διαμέρισης delta(): συνάρτηση που υπολογίζει τις εμπρόσθιες διαφορές μέσω αναδρομής factorial: υπολογίζει το παραγοντικό ενός αριθμού Στον παραπάνω κώδικα βρίσκονται όλες οι συναρτήσεις αριθμητικής ολοκλήρωσης, καθώς και οι συναρτήσεις που πρέπει να ολοκληρώσουμε. Αλλάζοντας μόνο την προς ολοκλήρωση συνάρτηση μπορούμε να υπολογίσουμε και το δεύτερο ολοκλήρωμα με τις ίδιες μεθόδους. Όπως εύκολα μπορούμε να συμπεράνουμε από τα αποτελέσματα, όσο πιο μεγάλος είναι ο βαθμός του 18

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις συμπτωτικού πολυωνύμου, τόσο καλύτερη είναι η προσέγγιση στη πραγματική τιμή. Υπολογιστικά όμως, δεν συμφέρει από την άποψη των πολλών πράξεων που απαιτούνται για την κατασκευή τους. Αξίζει ακόμη να σημειωθεί, ότι σε ίδια τάξη σφάλματος μπορούμε να καταλήξουμε ευκολότερα με τη χρήση της μεθόδου Simpson, και σε ακόμη καλύτερη, και γρηγορότερα, με τη μέθοδο του Simpson 3/8. Αποτελέσματα της εκτέλεσης του κώδικα των μεθόδων όπως αυτά υπολογίστηκαν αυτόματα από τον κώδικα. Οι παρακάτω εικόνες παρουσιάζουν τα σφάλματα 19

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 2.2 Filon Method Το ολοκλήρωμα που δόθηκε στο δεύτερο ερώτημα της δεύτερης άσκησης ήταν της μορφής y(x) sin(kx) dx. Από τη θεωρία προβλέπετε να συγκλίνει ταχύτερα με τη μέθοδο του Filon. Στο παρακάτω πηγαίο κώδικα αναπτύσσεται η μέθοδος του Filon, ενώ γίνεται σύγκριση της μεθόδου με άλλες μεθόδους αριθμητικής ολοκλήρωσης, και συγκεκριμένα με την μέθοδο των τραπεζίων, καθώς επίσης και με τη μέθοδο του Simpson. Ο κώδικας δεν έχει ιδιαίτερες διαφορές με τον προηγούμενο στη γενική φιλοσοφία. Όσον αφορά το κομμάτι της μεθόδου Filon, οι διάφοροι συντελεστές (A, B, Ce, Co) είναι και αυτοί συναρτήσεις. 1 #include <iostream> 2 #include <iomanip> 3 #include <cmath> 4 using namespace std; 5 double pi=3.14159;double eps=pow(10, 6); 6 int n=4;double k=5; 7 double *x= new double [n+5]; 8 //double realvalue=(pi/2+1)*log(pi/2+1); 9 double realvalue= exp( 2*pi)*(sin(5*pi*2)+5*cos(5*pi*2))/26 +exp( 0)*(sin (5*0)+5*cos(5*0))/26; 10 double q,a=0,b=2*pi; 11 double h=((b a)/n); 12 double y(double xx) 13 { 14 return exp( xx); 15 } 16 17 double A() 18 { 19 return 1/q + sin(2*q)/(2*q*q) 2*pow(sin(q),2)/pow(q,3); 20 } 21 double B() 22 { 23 return 1/(q*q) + pow(cos(q),2)/(pow(q,2)) (sin(2*q))/pow(q,3); 24 } 25 double D() 26 { 27 return 4*sin(q)/(q*q*q) 4*cos(q)/(q*q); 28 } 29 double Se() 30 { 31 double sum=0;int i=0; 32 while(i<=n) 33 { 34 sum+=y(a+2*i*h)*sin(k*a+2*i*q); 35 i++; 36 } 20

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 37 return 2*sum y(a)*sin(k*a) y(b)*sin(k*b); 38 } 39 double So() 40 { 41 double sum=0;int i=1; 42 while(i<=n) 43 { 44 sum+=y(a+(2*i 1)*h)*sin(k*a+(2*i 1)*q); 45 i++; 46 } 47 return sum ; 48 } 49 50 double Filon() 51 { 52 q=h*k; 53 return h*(a()*y(a)*cos(k*a) A()*y(b)*cos(k*b)+B()*Se()+D()*So()); 54 } 55 56 int main() 57 { 58 int g=0; 59 cout.precision(4); 60 while(g<=15) 61 { 62 cout <<"h="<<h<<endl; 63 cout.precision(18); 64 cout << "Real Value = "<<realvalue <<"\nfilon = "<< Filon()<<endl; 65 cout.precision(4); 66 cout <<"Error = "<< fabs(100*(realvalue Filon())/realvalue)<<"%\n"<< endl; 67 n=2*n; 68 h=((b a)/n); 69 g++; 70 } 71 return 0; 72 } Τα αποτελέσματα του παραπάνω προγράμματος έδειξαν ότι ακόμα και για πυκνότερη διαμέριση, το σφάλμα της Filon δεν πέφτει κάτω από ένα σημείο, σε αντίθεση με τη μέθοδο των τραπεζίων ή του Simpson. Πρέπει να σημειωθεί ότι αυτή την ιδιομορφία την παρουσιάζει αυτή η συνάρτηση, και (παρ ότι δεν μπορώ να το αποδείξω) σχετίζεται με τον εκθετικό παράγοντα. Το ίδιο δεν παρατηρήθηκε με άλλες συναρτήσεις που δίνονταν ως παραδείγματα σε διάφορα βιβλία αριθμητικής ανάλυσης, για να δοκιμαστεί ο κώδικας, και άρα είναι ασφαλές να πούμε ότι δεν υπάρχει κάποιο λογικό σφάλμα. 21

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις Αποτελέσματα της εκτέλεσης του κώδικα των μεθόδων όπως αυτά υπολογίστηκαν αυτόματα από τον κώδικα. Οι παρακάτω εικόνες παρουσιάζουν τα σφάλματα 22

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 23

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 2.3 Μέθοδος Gauss Η μέθοδος Gauss αποτελεί προσέγγιση της πραγματικής τιμής ενός ολοκληρώματος της μορφής 1 1 f(x)dx. Το ολοκλήρωμα που ζητούσε η υπόθεση ήταν το π 2 0 log(x + 1)dx. Προφανώς με ένα μετασχηματισμό μπορεί να αλλάξει μορφή, και να γίνει της μορφής Gauss. Επιλέγουμε την αλλαγή μεταβλητής t = 1 2 (b + a)x + 1 (b a), και το ολοκλήρωμα μετασχηματίζεται σε 2 1 π 1 4 log( π (t + 1) + 1)dt. Το πρόγραμμα τρέχει με Gauss δύο σημείων, 4 και 8 σημείων, καθώς επίσης και άλλες μεθόδους ολοκλήρωσης για να γίνει σύγκριση αυτών. Είναι προφανές 4 ότι το σφάλμα της μεθόδου Gauss για 2 μόλις σημεία είναι αισθητά μικρότερο σε σχέση με άλλες αριθμητικές μεθόδους ολοκλήρωσης στα 2 σημεία. Το ίδιο ισχύει και για τα 4 σημεία. 1 #include <iostream> 2 #include <iostream> 3 #include <iomanip> 4 #include <cmath> 5 //Gauss 6 using namespace std; 7 double pi=3.1415926535897932;double eps=pow(10, 6); 8 int n=4;double a=0,b=pi/2,h=(b a)/n; 9 10 double x[1000]; 11 double realvalue=(pi/2)*(log(pi/2+1) 1)+log(pi/2+1); 12 13 double myfunc(double xx) 14 { 15 // Formula of function 16 return log(xx+1); 17 18 } 24

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 19 double myfunc2(double tt) 20 { 21 // Formula of function 22 return log((pi/4)*(tt+1)+1)*pi/4; 23 } 24 void set(double a,double b,double M) 25 { 26 // a:start X, b:end X, M:How many steps 27 int i=0; h=(b a)/(m); n=m; 28 29 30 while (i<=n) 31 { 32 x[i]=a+h*i; 33 i++; 34 } 35 } 36 37 double NC(short int order,int o) 38 { 39 double answ=0; 40 if(order==1){ 41 answ=(h/2)*(myfunc(x[o]) +myfunc(x[o+1])); 42 } 43 else if (order==2){ 44 answ=(h/3)*(myfunc(x[o]) +4*myfunc(x[o+1])+myfunc(x[o+2])); 45 } 46 else if (order ==3){ 47 answ=(3*h/8)*(myfunc(x[o]) +3*myfunc(x[o+1]) + 3*myfunc(x[o+2])+myfunc(x [o+3])); 48 } 49 return answ; 50 } 51 52 double trapezoid(int k, int o) 53 { 54 int i=o; double sum=0; 55 while(i<=k 1) 56 { 57 sum+=nc(1,i); 58 i++; 59 } 60 return sum; 61 } 62 63 double Simpson(int k, int o) 64 { 65 int i=o; double sum=0; 66 while(i<=k 2) 25

ΠΜΣ Υπολογιστικη ς Φυσικη ς 2 Αριθμητικε ς Ολοκληρω σεις 67 { 68 69 sum+=nc(2,i); 70 i+=2; 71 } 72 return sum; 73 } 74 double Gauss() 75 { 76 return myfunc2(0.5773)+myfunc2( 0.5773); 77 } 78 double Gauss4() 79 { 80 return 0.34785485*myfunc2(0.86113631)+0.34785485*myfunc2( 0.86113631) +0.62214515*myfunc2( 0.33948104)+0.62214515*myfunc2(0.33948104); 81 } 82 double Gauss8() 83 { 84 return 0.10122854*myfunc2(0.96028986)+0.22381034*myfunc2(0.79666648) +0.31370665*myfunc2(0.52553241)+0.36268378*myfunc2(0.18343464) +0.10122854*myfunc2( 0.96028986)+0.22381034*myfunc2( 0.79666648) +0.31370665*myfunc2( 0.52553241)+0.36268378*myfunc2( 0.18343464); 85 } 86 int main() 87 { 88 int simeia; 89 cout << "Gauss (2 points)= "<<Gauss()<<endl; 90 cout << "Real Value= "<<realvalue<<endl; 91 cout << "Error on Gauss= "<<fabs(100*(realvalue Gauss())/realvalue)<<"%" <<endl; 92 93 cout << "\ngauss (4 points)= "<<Gauss4()<<endl; 94 cout << "Real Value= "<<realvalue<<endl; 95 cout << "Error on Gauss= "<<fabs(100*(realvalue Gauss4())/realvalue)<<"% "<<endl; 96 97 cout << "\ngauss (8 points)= "<<Gauss8()<<endl; 98 cout << "Real Value= "<<realvalue<<endl; 99 cout << "Error on Gauss= "<<fabs(100*(realvalue Gauss8())/realvalue)<<"% "<<endl; 100 101 simeia=2; 102 set(a,b,simeia); 103 cout <<"\n\trapezoid (2 points)= " <<trapezoid(simeia,0)<<endl; 104 cout << "Error on Trapezoid= "<<fabs(100*(realvalue trapezoid(simeia,0)) /realvalue)<<"%"<<endl; 105 106 simeia=3; 107 set(a,b,simeia); 26

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις 108 cout <<"\n\nsimpson (3 points)= " <<Simpson(simeia,0)<<endl; 109 cout << "Error on Simpson= "<<fabs(100*(realvalue Simpson(simeia,0))/ realvalue)<<"%"<<endl; 110 111 112 simeia=6; 113 set(a,b,simeia); 114 cout <<"\n\nsimpson (6 points)= " <<Simpson(simeia,0)<<endl; 115 cout << "Error on Simpson= "<<fabs(100*(realvalue Simpson(simeia,0))/ realvalue)<<"%"<<endl; 116 117 118 return 0; 119 } Παραθέτω τα αποτελέσματα του εκτελέσιμου που παρουσιάζουν και τα σχετικά σφάλματα: 3 Διαφορικές Εξισώσεις Οι διαφορικές εξισώσεις αποτελούν ένα από τα πιο ουσιώδη κομμάτια της αριθμητικής ανάλυσης. Η σημασία είναι προφανής, αφού οι περισσότεροι νόμοι στη φυσική περιγράφονται με μια διαφορική εξίσωση, η οποία σπανίως είναι αναλυτικά επιλύσιμη. Συνεπώς για να μπορέσουμε να πάρουμε αριθμητικά δεδομένα, αναγκαζόμαστε να καταφύγουμε σε μεθόδους αριθμητικής ολοκλήρωσης. Στην εργασία αυτή, ζητούμενο ήταν η ολοκλήρωση των εξισώσεων κίνησης του Χαμιλτονιανού συστήματος H = p2 2 cosθ. Οι μέθοδοι που εφαρμόστηκαν και συγκρίθηκαν ήταν οι: i. Runge-Kutta 4ης τάξης ii. Milne 27

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις 3.1 Runge-Kutta Η πιο ευρέως διαδεδομένη μέθοδος ολοκλήρωσης είναι η Runge-Kutta. Αυτό έχει να κάνει τόσο με την προγραμματιστική απλότητα που παρουσιάζει, όσο και με την μεγάλη ακρίβεια που μπορεί να δώσει στις αριθμητικές ολοκληρώσεις των διαφορικών εξισώσεων. Από την H = p2 cosθ μπορούμε να πάρουμε τις εξισώσεις κίνησης με τη χρήση των 2 σχέσεων: dp dt = H dθ = sinθ, θ dt = H p = p Θεωρούμε αυτές λοιπόν ως σύστημα διαφορικών εξισώσεων, με αρχικές συνθήκες θ(0) = 0 και p(0) = ± 2E 0 + sinθ 0 για τιμές E 0 = 0 και E 0 = 1.5. Στο ακόλουθo πρόγραμμα αναπτύχθηκε η μέθοδος για προσέγγιση 4ης τάξης (Runge-Kutta 4th Order). 1 #include<iostream> 2 #include<cmath> 3 #include<cstdlib> 4 #include <fstream> 5 #define steps 1000000 6 7 using namespace std; 8 9 double F( double theta, double p){ 10 double z; 11 z=p; 12 return z;} 13 14 double G( double theta, double p){ 15 double z; 16 z= sin(theta); 17 return z;} 18 19 int main() 20 { 21 ofstream fout; 22 fout.open ("RKdata.txt"); 23 double theta,theta0,p,p0,h,h,e; 24 double k1,k2,k3,k4; 25 double l1,l2,l3,l4; 26 int i; 27 cout.precision(11); 28 fout.precision(11); 29 h=0.0001; 30 theta0=0; 31 E=1.5; 32 p0=fabs(sqrt(2.*(e+cos(theta0)))); 33 //cout << p0 <<endl; 34 theta=theta0; 35 p=p0; 36 i=0; 28

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις 37 fout<<"t"<<" "<<"theta"<<" "<<"p"<<" "<<"H"<<endl<<endl; 38 39 while(i<steps) 40 { 41 //k1,l1 42 k1=h*f(theta,p); 43 l1=h*g(theta,p); 44 45 //k2,l2 46 k2=h*f(theta+0.5*k1,p+0.5*l1); 47 l2=h*g(theta+0.5*k1,p+0.5*l1); 48 //k3,l3 49 k3=h*f(theta+0.5*k2,p+0.5*l2); 50 l3=h*g(theta+0.5*k2,p+0.5*l2); 51 52 //k4,l4 53 k4=h*f(theta+k3,p+l3); 54 l4=h*g(theta+k3,p+l3); 55 56 //new values of theta,p 57 theta=theta+(k1+2.*k2+2.*k3+k4)/6.; 58 p=p+(l1+2.*l2+2.*l3+l4)/6.; 59 H=(p*p*0.5) cos(theta); 60 cout <<"\n\n Status:\n \n"<<endl; 61 cout <<" Iteration : "<<i<<"\n * theta= "<<theta<<"\n * p= "<<p<<endl; 62 cout <<"\n * Energy H= "<<H<<endl; 63 fout<<i<<" "<<theta<<" "<<p<<" "<<H<<endl; 64 i++; 65 } 66 cout<<"\n\n\n=========================\n Energy at the end \n * H="<<H<< endl; 67 fout.close(); 68 69 return 0; 70 } Τα αποτελέσματα του εκτελέσιμου αποθηκεύτηκαν σε ένα αρχείο txt και σχεδιάστηκαν με το gnuplot. Όπως εύκολα παρατηρούμε, για ενέργεια Ε 0 = 0, το σύστημα εκτελεί περιοδική κίνηση, καθώς ο γεωμετρικός τόπος των σημείων του, είναι κλειστή κωνική τομή. Αντίθετα, για Ε 0 = 1.5, το φασικό διάγραμμα δείχνει μια ημιτονοειδή μορφή. Σε κάθε περίπτωση, η ενέργεια δείχνει να παραμένει σχετικά σταθερή ακόμη και μετά από 10 6 χρονικές μονάδες. 29

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις Διάγραμμα 3.1: Φασικό διάγραμμα για Ε=1.5 Διάγραμμα 3.2: Ενέργεια σε σχέση με το χρόνο Διάγραμμα 3.3: Φασικό διάγραμμα για Ε=0 30

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις Διάγραμμα 3.4: Εξέλιξη της ενέργειας με το χρόνο 3.2 Milne Μία ακόμα πολύ διαδεδομένη μέθοδος αριθμητικής ολοκλήρωσης διαφορικών είναι η μέθοδος Milne. Δεδομένου ότι η μέθοδος αυτή απαιτεί τη γνώση κάποιων αρχικών συνθηκών παραπάνω, χρησιμοποιείται στην αρχή ένα RK4 ως εκκινητής για να παράξει αυτές τις συνθήκες. Για το ακριβώς ίδιο σύστημα διαφορικών εξισώσεων, γράφτηκε ο ακόλουθος κώδικας: 1 #include<iostream> 2 #include<cmath> 3 #include<cstdlib> 4 #include <fstream> 5 #define steps 1000000 6 7 using namespace std; 8 double parray[4],thetaarray[4],harray[4]; 9 double thetan,thetanp1,thetanp2,thetanp3,pn,pnp1,pnp2,pnp3 ; 10 double k1,k2,k3,k4, l1,l2,l3,l4; 11 12 double F( double theta, double p){ 13 double z; 14 z=p; 15 return z;} 16 17 double G( double theta, double p){ 18 double z; 19 z= sin(theta); 20 return z;} 21 22 int main() 23 { 24 double theta,theta0,p,p0,h,h,e; 25 ofstream fout; 26 fout.open ("Milnedata.txt"); 31

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις 27 fout<<"t"<<" "<<"theta"<<" "<<"p"<<" "<<"H"<<endl<<endl; 28 29 //double k1,k2,k3,k4; 30 //double l1,l2,l3,l4; 31 int i; 32 cout.precision(11); 33 h=0.0001; 34 theta0=0; 35 E=0.; 36 p0=fabs(sqrt(2.*(e+cos(theta0)))); 37 theta=theta0; 38 p=p0; 39 i=0; 40 //Runge Kutta Starter 41 while(i<5) 42 { 43 //k1,l1 44 k1=h*f(theta,p); 45 l1=h*g(theta,p); 46 47 //k2,l2 48 k2=h*f(theta+0.5*k1,p+0.5*l1); 49 l2=h*g(theta+0.5*k1,p+0.5*l1); 50 //k3,l3 51 k3=h*f(theta+0.5*k2,p+0.5*l2); 52 l3=h*g(theta+0.5*k2,p+0.5*l2); 53 54 //k4,l4 55 k4=h*f(theta+k3,p+l3); 56 l4=h*g(theta+k3,p+l3); 57 58 //new values of theta,p 59 theta=theta+(k1+2.*k2+2.*k3+k4)/6.; 60 p=p+(l1+2.*l2+2.*l3+l4)/6.; 61 H=(p*p*0.5) cos(theta); 62 63 parray[i]=p; 64 thetaarray[i]=theta; 65 Harray[i]=H; 66 fout<<i<<" "<<theta<<" "<<p<<" "<<H<<endl; 67 68 //cout <<"\n\n Status:\n \n"<<endl; 69 //cout <<" Iteration : "<<i<<"\n * theta= "<<theta<<"\n * p= "<<p<<endl; 70 //cout <<"\n * Energy H= "<<H<<endl; 71 i++; 72 } 73 //InitCond 74 thetan=thetaarray[3]; 75 thetanp1=thetaarray[2]; 32

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις 76 thetanp2=thetaarray[1]; 77 thetanp3=thetaarray[0]; 78 pn=parray[3]; 79 pnp1=parray[2]; 80 pnp2=parray[1]; 81 pnp3=parray[0]; 82 83 while(i<steps) 84 { 85 thetanp3=thetanp2; 86 thetanp2=thetanp1; 87 thetanp1=thetan; 88 thetan=thetanp3 (4*h/3)*(2*F(thetan,pn) F(thetanp1,pnp1)+2*F(thetanp2, pnp2)); 89 90 pnp3=pnp2; 91 pnp2=pnp1; 92 pnp1=pn; 93 pn=pnp3 (4*h/3)*(2*G(thetan,pn) G(thetanp1,pnp1)+2*G(thetanp2,pnp2)); 94 H=(pn*pn*0.5) cos(thetan); 95 96 fout<<i<<" "<<thetan<<" "<<pn<<" "<<H<<endl; 97 98 i++; 99 } 100 101 cout<<"\n\n\n=========================\n Energy at the end \n * H="<<H<< endl; 102 fout.close(); 103 104 return 0; 105 } Γραφικές Παραστάσεις h=0.0001 Οι γραφικές παραστάσεις του χώρου των φάσεων καθώς επίσης και της εξέλιξης της ενέργειας για h = 10 4 για 10 6 βήματα με τη μέθοδο RK4. 33

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις Διάγραμμα 3.5: Φασικό διάγραμμα για E 0 = 0 με RK4 Διάγραμμα 3.6: Φασικό διάγραμμα για E 0 = 1.5 με RK4 Διάγραμμα 3.7: Εξέλιξη της ενέργειας E 0 = 0 με RK4 34

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις Οι ίδιες γραφικές παραστάσεις για h = 10 4 σε ίδιο αριθμό βημάτων με την Milne Διάγραμμα 3.8: Φασικό διάγραμμα για E 0 = 0 με Milne Διάγραμμα 3.9: Φασικό διάγραμμα για E 0 = 1.5 με Milne 35

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις Διάγραμμα 3.10: Εξέλιξη της ενέργειας E 0 = 1.5 με Milne Διάγραμμα 3.11: Εξέλιξη της ενέργειας E 0 = 0 με Milne Η σύγκριση των διαγραμμάτων των δύο μεθόδων για μικρότερο βήμα h = 0.01. 36

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις Διάγραμμα 3.12: Εξέλιξη της ενέργειας RK4 Διάγραμμα 3.13: Εξέλιξη της ενέργειας Milne 3.3 Σύγκριση των δύο μεθόδων Στα επόμενα δύο διαγράμματα παρουσιάζεται το elapsed time of execution σαν συνάρτηση των steps ολοκλήρωσης. Το βήμα διατηρήθηκε στα h = 10 4. Όπως εύκολα μπορεί να συμπεράνει κανείς, η μέθοδος Milne είναι περίπου 3 φορές πιο αργή για τις ίδιες συνθήκες εργασίας. Επιπλέον μειονέκτημα είναι ότι χρησιμοποιεί ένα RK starter, όμως η ακρίβεια της μεθόδου είναι εξαιρετική. 37

ΠΜΣ Υπολογιστικη ς Φυσικη ς 3 Διαφορικε ς Εξισω σεις Διάγραμμα 3.14: Runge-Kutta execution time Διάγραμμα 3.15: Milne execution time 38