ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ - ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΑΡΙΘΜΗΤΙΚΗ ΑΝΑΛΥΣΗ, 3 Ο ΕΞΑΜΗΝΟ, 2009-2010 ΔΙΔΑΣΚΩΝ: Δρ Ιωάννης Αθ. Σταυράκης 3 η Σειρά Ασκήσεων 08.12.2009 Άσκηση. Για τα παρακάτω δεδομένα: x 100 300 500 700 900 1100 f(x ) 3 14,5 18,5 21,5 24 26 Α. Να προσδιοριστεί πολυώνυμο παρεμβολής 2 ου βαθμού για τα πρώτα 3 σημεία με τις προς τα εμπρός διαφορές. Β. Να γραφτεί πρόγραμμα σε Fortran για τον υπολογισμό των f(200), f(600) και f(800) εφαρμόζοντας τις μεθόδους παρεμβολής: 1. Lagrange, 2. Newton και 3. Ελαχίστων Τετραγώνων για πολυώνυμο 3 ου βαθμού (η επίλυση του γραμμικού συστήματος να γίνει με τη μέθοδο LU ή τη μέθοδο Cholesky). Σε κάθε περίπτωση να γίνει η σύγκριση των αποτελεσμάτων με τις αντίστοιχες μεθόδους του Mathematica. A. Για τον προσδιορισμό του πολυωνύμου παρεμβολής 2 ου βαθμού για τα πρώτα 3 σημεία με τις προς τα εμπρός διαφορές χρησιμοποιείται ο τύπος: όπου f(x) P (x) = f + s 1 f + s 2 f, s = x x h με x = 100 και h = 200. Για τον υπολογισμό των προς τα εμπρός διαφορών f, για k = 1,2, κατασκευάζεται ο πίνακας των προς τα εμπρός διαφορών. x f f f 100 3 11,5 300 14,5-7,5 4 500 18,5
Με βάση τον παραπάνω πίνακα προκύπτουν: f = 11,5 και f = 7,5. Οπότε το πολυώνυμο παρεμβολής 2 ου βαθμού είναι ίσο με: P (x) = f + s 1 f + s 2 f = f + s f + 1 2 s(s 1) f = = f + = 3 + x 100 200 f + 1 x 100 x 300 2 200 200 f = x 100 200 11,5 + 1 x 100 x 300 2 200 200 ( 7,5) = = 3 + 0,0575(x 100) 9,375 10 (x 100)(x 300) = = 3 + 0,0575x 5,75 9,375 10 x 2,8125 + 0,0375x = = 5,5625 + 0,095x 9,375 10 x Στο Mathematica ο προσδιορισμός του πολυωνύμου παρεμβολής 2 ου βαθμού για τα 3 πρώτα ζεύγη τιμών γίνεται δίνοντας: Expand[InterpolatingPolynomial[{{100,3},{300,14.5},{500,18.5}},x]] και προκύπτει: -5.5625+0.095 x-0.00009375 x 2. Β. 1. Το πολυώνυμο παρεμβολής Lagrange δίνεται από τη σχέση: όπου n = 5. x x P (x) = f(x x x ) Παρακάτω φαίνεται ο πηγαίος κώδικας σε γλώσσα προγραμματισμού Fortran για την παρεμβολή Lagrange. Ο κώδικας γράφτηκε σε περιβάλλον Mandrake Linux 10.1 και μεταγλωττίστηκε με τον compiler g77 έκδοση 3.4.1. program lagrange integer n,m,i,j,k parameter (n=6,m=3) double precision x(n),f(n),xx(m),ff(m),s,p x(1)=100.0d0; f(1)=3.0d0
x(2)=300.0d0; f(2)=14.5d0 x(3)=500.0d0; f(3)=18.5d0 x(4)=700.0d0; f(4)=21.5d0 x(5)=900.0d0; f(5)=24.0d0 x(6)=1100.0d0; f(6)=26.0d0 xx(1)=200.0d0 xx(2)=600.0d0 xx(3)=800.0d0 open(unit=10,file="lagrange.txt") do k=1,m s=0.0d0 p=1.0d0 do j=1,n if (j.ne.i) then p=p*(xx(k)-x(j))/(x(i)-x(j)) if s=s+p*f(i) ff(k)=s write(10,*) 'f(',xx(k),' ) =',ff(k) close(10) stop Τα αποτελέσματα που προκύπτουν με την παρεμβολή Lagrange είναι τα εξής: f( 200. ) = 10.4785156 f( 600. ) = 20.0175781 f( 800. ) = 22.8652344 2. Το πολυώνυμο παρεμβολής Newton δίνεται από τη σχέση: P (x) = f[x ] + f[x, x ](x x ) + f[x, x, x ](x x )(x x ) + + f[x, x, x,, x ](x x )(x x ) (x x ) όπου n = 5. Παρακάτω φαίνεται ο πηγαίος κώδικας σε γλώσσα προγραμματισμού Fortran για την παρεμβολή Newton. Ο κώδικας γράφτηκε σε περιβάλλον Mandrake Linux 10.1 και μεταγλωττίστηκε με τον compiler g77 έκδοση 3.4.1. program newton integer n,m,i,j,k
parameter (n=6,m=3) double precision x(n),f(n),xx(m),ff(m),a(n),s,p x(1)=100.0d0; f(1)=3.0d0 x(2)=300.0d0; f(2)=14.5d0 x(3)=500.0d0; f(3)=18.5d0 x(4)=700.0d0; f(4)=21.5d0 x(5)=900.0d0; f(5)=24.0d0 x(6)=1100.0d0; f(6)=26.0d0 xx(1)=200.0d0 xx(2)=600.0d0 xx(3)=800.0d0 call coeff(n,x,f,a) open(unit=10,file="newton.txt") do k=1,m s=a(n) do i=n-1,1,-1 s=a(i)+(xx(k)-x(i))*s ff(k)=s write(10,*) 'f(',xx(k),' ) =',ff(k) close(10) stop Η υπορουτίνα coeff υπολογίζει τους συντελεστές του πολυωνύμου με την βοήθεια των διαιρεμένων διαφορών. subroutine coeff(n,x,f,a) integer n,i,j double precision x(n),f(n),a(n),divdif(n,n) divdif(i,1)=f(i) do j=2,n do i=j,n divdif(i,j)=(divdif(i,j-1)-divdif(i-1,j-1))/(x(i)-x(i-j+1))
a(i)=divdif(i,i) do return Τα αποτελέσματα που προκύπτουν με την παρεμβολή Newton είναι τα εξής: f( 200. ) = 10.4785156 f( 600. ) = 20.0175781 f( 800. ) = 22.8652344 3. Η μέθοδος των Ελαχίστων Τετραγώνων προσδιορίζει ένα πολυώνυμο της μορφής: P (x) = a + a x + + a x, όπου οι συντελεστές a του πολυωνύμου προκύπτουν από την επίλυση του συστήματος: s s s s s s a u =, s s s a u όπου s = x και u = x f. Στην περίπτωση μας, ο βαθμός του πολυωνύμου είναι ίσος με 3 (n = 3) και το πλήθος των σημείων παρεμβολής 6 (m = 5). Παρακάτω φαίνεται ο πηγαίος κώδικας σε γλώσσα προγραμματισμού Fortran για τη μέθοδο των Ελαχίστων Τετραγώνων. Ο κώδικας γράφτηκε σε περιβάλλον Mandrake Linux 10.1 και μεταγλωττίστηκε με τον compiler g77 έκδοση 3.4.1. a u program squares integer n,m,nn,i,j,k parameter (n=6,m=3,nn=3) double precision x(n),f(n),xx(m),ff(m),a(nn+1),s x(1)=100.0d0; f(1)=3.0d0 x(2)=300.0d0; f(2)=14.5d0 x(3)=500.0d0; f(3)=18.5d0 x(4)=700.0d0; f(4)=21.5d0 x(5)=900.0d0; f(5)=24.0d0 x(6)=1100.0d0; f(6)=26.0d0 xx(1)=200.0d0 xx(2)=600.0d0 xx(3)=800.0d0 call coeff(n,x,f,nn,a) open(unit=10,file="squares.txt")
write(10,*) "Least Squares Method" write(10,*) "Polynomial degree is",nn write(10,*) write(10,*) "Polynomial Coefficients" n+1 write(10,*) 'a_',i-1,' =',a(i) write(10,*) do k=1,m s=a(1) do i=2,nn+1 s=s+a(i)*xx(k)**(i-1) ff(k)=s write(10,*) 'f(',xx(k),' ) =',ff(k) close(10) stop Η παράμετρος nn δηλώνει τον βαθμό του πολυωνύμου. Στην υπορουτίνα coeff υπολογίζονται οι συντελεστές του πολυωνύμου. Η επίλυση του συστήματος γίνεται με την μέθοδο LU με μερική οδήγηση, της οποίας ο κώδικας είναι ο ίδιος με εκείνον της 2 ης Σειράς Ασκήσεων και παραλείπεται. subroutine coeff(n,x,f,nn,a) integer n,nn,i,k,j,ipvt(nn+1),info double precision x(n),f(n),a(nn+1) double precision s,sx(2*nn+1),u(nn+1),aa(nn+1,nn+1) do k=1,2*nn+1 s=0.0d0 s=s+x(i)**(k-1) sx(k)=s do k=1,nn+1 s=0.0d0 s=s+(x(i)**(k-1))*f(i) u(k)=s n+1 do j=1,nn+1
aa(i,j)=sx((i-1)+j) call ludecomp(nn+1,aa,ipvt,info) call lussolve(nn+1,aa,u,ipvt,info) do k=1,nn+1 a(k)=u(k) return Τα αποτελέσματα που προκύπτουν για πολυώνυμο 3 ου βαθμού είναι: Least Squares Method Polynomial degree is 3 Polynomial Coefficients a_ 0 = -4.45709325 a_ 1 = 0.0866807209 a_ 2 = -9.99255952E-05 a_ 3 = 4.22453704E-08 f( 200. ) = 9.21999008 f( 600. ) = 20.703125 f( 800. ) = 22.5647321 Η σύγκριση των αποτελεσμάτων, και για την παρεμβολή Lagrange και για την παρεμβολή Newton, με το Mathematica γίνεται δίνοντας: data={{100,3},{300,14.5},{500,18.5},{700,21.5},{900,24},{1100,26}}; Polyonymo[x_]=InterpolatingPolynomial[data,x]; N[Polyonymo[{200,600,800}]] Τα αποτελέσματα που προκύπτουν είναι: {10.4785,20.0176,22.8652}. Η σύγκριση των αποτελεσμάτων για τη μέθοδο των Ελαχίστων Τετραγώνων με το Mathematica γίνεται δίνοντας: data={{100,3},{300,14.5},{500,18.5},{700,21.5},{900,24},{1100,26}}; PSquares3[x_]=Fit[data,{1,x,x 2,x 3 },x]; N[PSquares3[{200,600,800}]] και προκύπτουν τα αποτελέσματα: {9.21999,20.7031,22.5647}.