Άσκηση ΥΠΟΛΟΓΙΣΤΙΚΕΣ ΜΕΘΟΔΟΙ, -, 5 Ο ΕΞΑΜΗΝΟ ΕΠΙΛΥΣΗ ΕΡΓΑΣΙΑΣ #: ΣΥΝΗΘΕΙΣ ΔΙΑΦΟΡΙΚΕΣ ΕΞΙΣΩΣΕΙΣ ΚΑΙ ΣΥΣΤΗΜΑΤΑ ΠΡΟΒΛΗΜΑΤΑ ΑΡΧΙΚΩΝ ΤΙΜΩΝ ΕΠΙΜΕΛΕΙΑ: Ιωάννης Λυχναρόπουλος Δίδεται η διαφορική εξίσωση dy x = y+ e dx με αρχική συνθήκη y()=. Να επιλυθεί το πρόβλημα αρχικών τιμών με τις μεθόδους Euler και Runge-Kutta ης τάξης. Να σχολιασθούν υα αποτελέσματα και να γίνει σύγκριση με τα αντίστοιχα αναλυτικά. Στη συνέχεια να αποδειχθεί το κριτήριο ευστάθειας των δύο μεθόδων για το συγκεκριμένο πρόβλημα και να υπολογισθεί το μέγιστο επιτρεπτό βήμα Δ x. Να ελεγχθεί αν τα αναλυτικά ευρήματα σχετικά με την ευστάθεια επαληθεύονται αριθμητικά. Λύση Έχουμε dy x = y + e = f( x, y) () dx Βρίσκουμε την αναλυτική λύση χρησιμοποιώντας το Mathematica. Δίνοντας την εντολή: DSolve[{y'[x] -y[x]+exp[-x],y[] },y[x],x] x παίρνουμε την αναλυτική λύση: y( x) = e ( + x) Κάνουμε το γράφημα της λύσης με την εντολή: Plot[ -x (+x),{x,,5},axesorigin {,}] 3 5 Αναλυτική λύση
Στη συνέχεια χρησιμοποιούμε τους αλγορίθμους Euler και Runge-Kutta ης τάξης για να βρούμε την αριθμητική λύση της εξίσωσης με βήματα h=., h=. και h=.5 και πλήθος βημάτων n= Βήμα h=. Euler....E+. 9.9 9.9.39959E-3 3. 9. 9.59.79E-3.3 9.73 9.73357.73E- 5. 9.7 9.33.557E-.5 9.5579 9.559.997E- 7. 9.77 9.75.3E-.7 9.357 9.39.3E- 9. 9.33 9.35.99E-.9 9. 9.57.3393E-. 9.359 9.3.35E- RK....E+. 9.9 9.9.9537E- 3. 9.59 9.59.9537E-.3 9.73357 9.73357.E+ 5. 9.33 9.33.9537E-.5 9.5595 9.559.9537E- 7. 9.75 9.75.973E-5.7 9.39 9.39.973E-5 9. 9.35 9.35.973E-5.9 9.5 9.57.E-5. 9.3 9.3.E-5 Βήμα h=. Euler....E+. 9. 9.3.357E- 3...355.759E-.3 7.533 7.33.99E- 5..59.9733.37E+.5.35.357.3E+ 7. 5.735 5.7.39E+.7 5.3 5.33.53E+ 9..959.575.57E+.9.7.3.55E+. 3.37.7.9E+
RK....E+. 9.3 9.3.9537E- 3..35.355.973E-5.3 7.33 7.33.973E-5 5..9733.9733.3E-5.5.357.357.3E-5 7. 5.7 5.7.3E-5.7 5.337 5.33.E-5 9..57.575.3E-5.9.3.3.E-5...7.E-5 Βήμα h=.5 Euler....E+.5 5.5.357.57E+ 3. 3.537.7.993E+.5.757.5.55E+ 5..95..577E+.5.559..797E+ 7 3..359.73.33E+ 3.5.39.7.E+ 9..9.5.973E+.5.5..957E- 5..3.7.3E- RK....E+.5.375.357.977E- 3..9.7.E-.5.53.5.33E- 5..595..9E-.5.75..93E- 7 3..35.73.E- 3.5..7.37E-3 9..57.5.5779E-3.5.9..9E-3 5..35.7.79E-3 Παρατηρούμε ότι σε όλες τις περιπτώσεις η μέθοδος RK δίνει καλύτερα αποτελέσματα από την μέθοδο Euler. Επίσης, όπως ήταν αναμενόμενο, η ακρίβεια αυξάνει και στις δύο μεθόδους καθώς το βήμα h μικραίνει. Βέβαια η μέθοδος Euler ακόμη και για το σχετικά μικρό βήμα h=.5, δεν δίνει ικανοποιητικά αποτελέσματα. 3
Κώδικας Fortran: program initial_value_problems! Solve: y'=-y+exp(-x), y[]= implicit none real::h real,allocatable,dimension(:)::x,y integer::i,method,n=! number of iterations allocate(x(n),y(n)) x()= y()= h=.!starting point!initial value do method=,!=euler, =rk select case (method) case () call euler(x,y,h,n) print*,'--------------euler--------------' case () call rk(x,y,h,n) print* print*,'--------------rk--------------' end select do i=,n print '(i3,",",f.3,",",e5.5,",",e5.5,",",e5.5)',i,x(i),y(i),f(x(i)),a bs(f(x(i))-y(i)) enddo enddo contains subroutine euler(x,y,h,n) real::x(:),y(:),h integer::i,n do i=,n- y(i+)=y(i)+h*f(x(i),y(i)) x(i+)=x(i)+h enddo end subroutine euler subroutine rk(x,y,h,n) real::x(:),y(:),h,k,k,k3,k integer::i,n do i=,n- k=f(x(i),y(i)) k=f(x(i)+.5*h,y(i)+.5*h*k) k3=f(x(i)+.5*h,y(i)+.5*h*k) k=f(x(i)+h,y(i)+h*k3) y(i+)=y(i)+(h/)*(k+*k+*k3+k) x(i+)=x(i)+h enddo end subroutine rk
real function f(x,y) result(z) real,intent(in)::x,y z=-y+exp(-x) end function f real function f(x) result(y)!analytic solution real,intent(in)::x y=exp(-x)*(+x) end function f end program initial_value_problems Ορισμός σφάλματος Το σφάλμα ορίζεται ως ε i = yi y i () όπου y i και y i η αριθμητική και αναλυτική τιμή της συνάρτησης y στο σημείο x i. Από την () προκύπτει πως yi = yi +εi (3) Επίσης είναι από (): f ( xy, ) = y+ e x () Ανάλυση ευστάθειας μεθόδου Euler Η μέθοδος Euler γράφεται ως y = i y + + i hf( xi, yi) (5) Αντικαθιστώντας την (3) στην (5) και κάνοντας χρήση της () παίρνουμε διαδοχικά: yi+ + εi+ = yi + εi + hf( xi, yi + εi) xi yi+ + εi+ = yi + εi + h( ( yi + εi) + e ) xi yi+ + εi+ = yi + h( yi + e ) + ( h) εi εi+ εi+ = ( h) εi = h εi Επομένως για να έχουμε ευστάθεια θα πρέπει να ισχύει: h < < h< < h < Άρα για να είναι η μέθοδος Euler ευσταθής θα πρέπει να επιλέξουμε ένα βήμα h <. Βεβαίως για μεγάλα h η ακρίβεια του αριθμητικού σχήματος χειροτερεύει σημαντικά. Για h >. η αριθμητική λύση αρχίζει να διαφέρει αρκετά από την αναλυτική, όπως γίνεται φανερό στα επόμενα γραφήματα, τα οποία παρουσιάζουν την αναλυτική (μπλέ γραμμή) και την αριθμητική (κόκκινη γραμμή) λύση για διάφορες τιμές του βήματος h. h=.5 h=. 3 5 3 5 5
h=. h=.5 3 3 h=.5 h=.9 5 5 5 5 3 3 - -5 h= 5 5 5 5 3 35-5 Παρατηρούμε ότι για h 5. προκύπτουν αρνητικές τιμές που είναι τελείως λάθος σχετικά με τη φυσική του προβλήματος. Επομένως, τα αποτελέσματα είναι ασταθή και η κατάσταση χειροτερεύει καθώς το h αυξάνει. Για το συγκεκριμένο πρόβλημα φαίνεται ότι το αναλυτικό κριτήριο ευστάθειας είναι χαλαρό σε σχέση με τα αριθμητικά αποτελέσματα και αυτό οφείλεται στο γεγονός ότι η ανάλυση ευστάθειας βασίζεται σε ανάπτυγμα Taylor όπου η παράμετρος h πρέπει να παίρνει μικρές τιμές. Ο κώδικας σε Mathematica που χρησιμοποιήθηκε για την παραγωγή των ανωτέρω γραφημάτων είναι ο ακόλουθος: euler[f_,g_,n_,h_,t_,z_]:=module[{t,z,k,i}, t=n[t];z=n[z];i=; m[[]]={t,z,g[t],abs[z-g[t]],}; While[ i<n,
i=i+; k=n[f[t,z]]; z=n[z+h*k]; t=t+h; m[[i]]={t,z,g[t],abs[z-g[t]],k}; ]] eq={y'[x]==exp[-x]-y[x],y[]==}; f[x_,y_]=part[eq[[]]/.y[x] y,] g[x_]=fullsimplify[part[dsolve[eq,y[x],x],,,]] n=; h=; x=eq[[,,]]; y=eq[[,]]; m=table[,{n}]; euler[f,g,n,h,x,y] TableForm[m,TableHeadings {None,{"x","Αριθμ (y)","αναλ (g)"," Αριθμ- Αναλ ","k"}}] b=transpose[m]; c={b[[]],b[[]]}; m=transpose[c]; g=listplot[m,plotjoined True,PlotStyle RGBColor[,,],PlotRange All] g=plot[g[x],{x,x,35},plotrange All] Show[g,g,PlotRange {{,35},All},AxesOrigin {,}] Ανάλυση ευστάθειας μεθόδου RK Η μέθοδος RK γράφεται ως εξής: xi k = f( xi, yi) = yi e () h, h xi + k = f xi + yi + k = yi + k + e (7) h xi + h 3, h h k = f xi + yi + k = yi + k + e () ( xi h) k = f x + h, y + hk = y + hk + e + (9) ( ) ( ) i i 3 i 3 y = y + h i i ( 3 k + k + k + k ) () + Στα επόμενα με kj, j =,,3, εννοούμε τα kj, j =,,3, στα οποία αντί της αριθμητικής τιμής y i εμφανίζεται η αντίστοιχη αναλυτική τιμή y i Αντικαθιστώντας την (3) στις (-9) και κάνοντας χρήση της () παίρνουμε τα: x i xi k = ( y + ε ) e = y e ε = k εi i i i i h h h xi + xi h + i ε i i εi εi ( ) ( ) ( ) k = y + + k + e = y + + k + e = h h xi + h h = yi + k + e εi + εi = k εi 7
h h h xi + h h xi + k ( ) 3 = yi + k + e = yi + εi + k εi + e = h h xi + h h h h = yi + k + e εi εi = k3 + εi και ( ) xi + h h h ( xi + h) k = ( yi + hk 3) + e = ( yi + εi) + h k3 + εi + e = 3 ( xi + h) h h h h = ( yi + hk3) + e εi + h + εi = k h+ ε i Αντικαθιστώντας τέλος την (3) στην () και κάνοντας χρήση της () παίρνουμε διαδοχικά: h yi+ + εi+ = yi + εi + ( k + k + k 3 + k ) yi+ + εi+ = yi + εi + 3 h h h h h h k εi + k εi k3 εi k h εi + + + + 3 h h h h h h εi+ = εi + εi εi + εi h + εi 3 3 3 h h h h h εi+ h h h εi+ = εi + + 3h h + εi εi+ = h+ + εi = h+ + εi Επομένως για να είναι η μέθοδος ευσταθής θα πρέπει να ισχύει: Στο Mathematica δίνουμε την εντολή NBReduce BAbs B Re@hD + Re@hD Re@hD3 και παίρνουμε τη λύση της ανισότητας: < h <.759 + Re@hD F <, hff 3 h h h h + + < Έτσι το μέγιστο επιτρεπτό βήμα είναι h <.7. h=.5 h= 3 5 3
h=.5 h= 3 5 5 5 3 h=.5 h=.7 5 5 5 3 5 5 5 3 h=. 5 5 5 5 5 3 35 Στη περίπτωση του αλγορίθμου Runge Kutta ης τάξης το αναλυτικό κριτήριο ευστάθειας επαληθεύεται, δηλαδή τα αριθμητικά αποτελέσματα για μεγάλες τιμές του h εφόσον το h <.7 δεν είναι ακριβή αλλά είναι ευσταθή (δεν είναι αφύσικα) ενώ για h >.7 είναι ασταθή αφού έχουν αφύσικη συμπεριφορά. Ο κώδικας σε Mathematica που χρησιμοποιήθηκε για την παραγωγή των ανωτέρω γραφημάτων είναι ο ακόλουθος: rk[f_,g_,n_,h_,t_,z_]:=module[{t,z,k,k,k3,k,i}, t=n[t];z=n[z];i=; m[[]]={t,z,g[t],abs[z-g[t]],,,,}; While[ i<n, i=i+; k=n[f[t,z]]; 9
k=n[f[t+.5*h,z+.5*h*k]]; k3=n[f[t+.5*h,z+.5*h*k]]; k=n[f[t+h,z+h*k3]]; z=n[z+h/*(k+ k+ k3+k)]; t=t+h; m[[i]]={t,z,g[t],abs[z-g[t]],k,k,k3,k}; ]] eq={y'[x]==exp[-x]-y[x],y[]==}; f[x_,y_]=part[eq[[]]/.y[x] y,] g[x_]=fullsimplify[part[dsolve[eq,y[x],x],,,]] n=3; h=.; x=eq[[,,]]; y=eq[[,]]; m=table[,{n}]; rk[f,g,n,h,x,y] TableForm[m,TableHeadings {None,{"x","Αριθμ (y)","αναλ (g)"," Αριθμ- Αναλ ","k","k","k3","k"}}] b=transpose[m]; c={b[[]],b[[]]}; m=transpose[c]; g=listplot[m,plotjoined True,PlotStyle RGBColor[,,],PlotRange All] g=plot[g[x],{x,x,35},plotrange All] Show[g,g,PlotRange {{,35},All},AxesOrigin {,}]
Άσκηση Δίδεται το πρόβλημα αρχικών τιμών d x dx dx xt t x dt dt dt t= + + ( ) = sin( ), () =., =. Να επιλυθεί αριθμητικά με τον παρακάτω αλγόριθμο ης τάξης: h yi+ = yi + k+ k k3 k + + + k = f( x, y ) i i h h k = f xi +, yi + k h k3 = f xi +, yi + hk hk + + k = f xi + h, yi hk + + hk3 Να συγκριθούν τα αποτελέσματα με τα αντίστοιχα αναλυτικά και να σχολιασθούν. Τέλος, περιγράψτε ένα φυσικό πρόβλημα που θα μπορούσε να μοντελοποιείται με το παραπάνω πρόβλημα αρχικών τιμών. Λύση Θα πρέπει αρχικά να δημιουργήσουμε ένα σύστημα δύο διαφορικών εξισώσεων ης τάξης θέτοντας dx dg g = x και g = = dt dt Έτσι παίρνουμε το σύστημα: dg = g, g() =. dt dg + g + g = sin( t), g() =. dt το οποίο φέρνουμε στη μορφή: dg = g = f(, t g, g) dt dg = sin( t) g g = f( t, g, g) dt Αρχικά χρησιμοποιούμε το Mathematica για να πάρουμε την αναλυτική λύση : DSolve[{x''[t]+x'[t]+x[t] Sin[t],x[].,x'[].},x[t],t] 3 3 3 3 x t = Sin t e + Cos t e Cos t Cos t Sin t Cos t t/ t/ ( ).5. ( ) ( )
..5 3 5 -.5 -. Αναλυτική λύση Το δεδομένο πρόβλημα αρχικών τιμών αποτελεί μία εξαναγκασμένη αρμονική ταλάντωση. Θα επιλύσουμε τώρα το αρχικό πρόβλημα κάνοντας χρήση της κλασσικής μεθόδου Runge Kutta ης τάξης, καθώς και της τροποποιημένης που προτείνεται στην εκφώνηση, έτσι ώστε να συγκρίνουμε τις δύο μεθόδους μεταξύ τους: Για h=. έχουμε RK....35E-7....9E-7 3..35.35.97E-7.3.5.5.595E-7 5..7.7.9E-7.5.3.3.E+ 7..57.57.9E-7.7.99.99.73E-7 9..3.3.97E-7.9.53.53.9E-..97.97.7E-..3.3.E- 3..35335.35335.3E-.3.3775.3775.9E- 5..3.3.373E-.5...9E- 7..57.57.9E-.7.53.53.9E- 9..5.5.9E-.9.55.55.3E-
Τροποποιημένη RK....35E-7....9E-7 3..35.35.97E-7.3.5.5.595E-7 5..7.7.9E-7.5.3.3.E+ 7..57.57.9E-7.7.99.99.9E-7 9..3.3.75E-7.9.53.53.9E-..97.97.9E-..3.3.7E- 3..35335.35335.E-.3.3775.3775.E- 5..3.3.9E-.5...E- 7..57.57.9E-.7.53.53.9E- 9..5.5.9E-.9.55.55.3E- Για h=.5 έχουμε RK....35E-7.5.3.3.353E-3 3..97.97.937E-5.5...E-3 5..55.53.39E-3.5.37.37.399E-5 7 3...795.577E-3 3.5.735.737.97E-3 9..7593.753.33E-3.5.37.3.5533E-3 5. -.33 -.333.77E-3 5.5 -.753 -.739.3977E-3 3. -.9735 -.977.57E-3.5 -.99 -.937.9E-3 5 7. -.7 -.773.5E- 7.5 -.379 -.37.9E-3 7..759.7.573E-3.5.3.3.57E- 9 9..9.9.59E-3 9.5.7..99E-3 3
Τροποποιημένη RK....35E-7.5.3.3.355E-3 3..97.97.97E-5.5...E-3 5..55.53.39E-3.5.37.37.399E-5 7 3...795.57E-3 3.5.735.737.97E-3 9..7593.753.39E-3.5.37.3.5599E-3 5. -.33 -.333.775E-3 5.5 -.753 -.739.393E-3 3. -.9735 -.977.57E-3.5 -.99 -.937.9E-3 5 7. -.7 -.773.5E- 7.5 -.379 -.37.97E-3 7..759.7.577E-3.5.3.3.57E- 9 9..9.9.59E-3 9.5.7..99E-3 Όπως γίνεται φανερό τα αποτελέσματα και των δύο μεθόδων RK ταυτίζονται. Κώδικας Fortran: program initial_value_problems_system! Solve: y''+y'+y=sin(t), y[]=., y'[]=. implicit none real::h real,allocatable,dimension(:)::z,z,x integer::i,method,n=! number of iterations allocate(x(n),z(n),z(n)) do method=,!=rk, =rk_modified x()=!starting point z()=.!initial value z()=.!initial value h=.5 select case (method) case () call rk(x,z,z,h,n) case () call rk_modified(x,z,z,h,n) end select print*, '--------------------',method,'----------------------' do i=,n
print '(i3,",",f.3,",",f.5,",",f.5,",",e5.5)',i,x(i),z(i),f(x(i)), abs(f(x(i))-z(i)) enddo end do contains subroutine rk(x,z,z,h,n) real::x(:),z(:),z(:),h,k,k,k3,k,k,k,k3,k integer::i,n do i=,n- k=f(x(i),z(i),z(i)) k=g(x(i),z(i),z(i)) enddo end subroutine rk k=f(x(i)+.5*h,z(i)+.5*h*k,z(i)+.5*h*k) k=g(x(i)+.5*h,z(i)+.5*h*k,z(i)+.5*h*k) k3=f(x(i)+.5*h,z(i)+.5*h*k,z(i)+.5*h*k) k3=g(x(i)+.5*h,z(i)+.5*h*k,z(i)+.5*h*k) k=f(x(i)+h,z(i)+h*k3,z(i)+h*k3) k=g(x(i)+h,z(i)+h*k3,z(i)+h*k3) x(i+)=x(i)+h z(i+)=z(i)+(h/)*(k+*k+*k3+k) z(i+)=z(i)+(h/)*(k+*k+*k3+k) subroutine rk_modified(x,z,z,h,n) real::x(:),z(:),z(:),h,k,k,k3,k,k,k,k3,k integer::i,n do i=,n- k=f(x(i),z(i),z(i)) k=g(x(i),z(i),z(i)) k=f(x(i)+.5*h,z(i)+.5*h*k,z(i)+.5*h*k) k=g(x(i)+.5*h,z(i)+.5*h*k,z(i)+.5*h*k) k3=f(x(i)+.5*h,z(i)+(-.5+./sqrt(.))*h*k+(-./sqrt(.))*h*k,z(i)+(-.5+./sqrt(.))*h*k+(-./sqrt(.))*h*k) k3=g(x(i)+.5*h,z(i)+(-.5+./sqrt(.))*h*k+(-./sqrt(.))*h*k,z(i)+(-.5+./sqrt(.))*h*k+(-./sqrt(.))*h*k) k=f(x(i)+h,z(i)- (./sqrt(.))*h*k+(+./sqrt(.))*h*k3,z(i)- (./sqrt(.))*h*k+(+./sqrt(.))*h*k3) k=g(x(i)+h,z(i)- (./sqrt(.))*h*k+(+./sqrt(.))*h*k3,z(i)- (./sqrt(.))*h*k+(+./sqrt(.))*h*k3) x(i+)=x(i)+h z(i+)=z(i)+(h/.)*(k+*(- /sqrt(.))*k+*(+/sqrt(.))*k3+k) 5
z(i+)=z(i)+(h/.)*(k+*(- /sqrt(.))*k+*(+/sqrt(.))*k3+k) enddo end subroutine rk_modified real function f(x,x,x3) result(z) real,intent(in)::x,x,x3 z=x3 end function f real function g(x,x,x3) result(z) real,intent(in)::x,x,x3 z=sin(x)-x-x3 end function g real function f(t) result(y)!analytic solution real,intent(in)::t y=(.*cos((sqrt(3.)*t)/.) - Exp(t/.)*Cos(t)*Cos((Sqrt(3.)*t)/.)** +.5373*Sin((Sqrt(3.)*t)/.) - Exp(t/.)*Cos(t)*Sin((Sqrt(3.)*t)/.)**)/Exp(t/.) end function f end program initial_value_problems_system
Άσκηση 3 Να εξεταστεί πότε οι αλγόριθμοι ολοκλήρωσης συνήθων διαφορικών εξισώσεων Runge-Kutta ανάγονται στους κανόνες ολοκλήρωσης Newton Cotes. Λύση Οι αλγόριθμοι ολοκλήρωσης συνήθων διαφορικών εξισώσεων Runge-Kutta ανάγονται στους κανόνες ολοκλήρωσης Newton Cotes όταν η παράγωγος dy εξαρτάται μόνον από dx το x, δηλαδή όταν είναι: dy f ( x) dx = () Σε αυτή την περίπτωση η αριθμητική λύση δίνεται από τον τύπο: xi + h y = i y + + i f( x) dx xi Αν ισχύει η () τότε η μέθοδος RK γίνεται k = f( x i ), k = f ( xi + h) h h y = i y + + i ( k k ) yi ( f( xi) f( xi h) ) + = + + + η οποία αντιστοιχεί στη μέθοδο ολοκλήρωσης του τραπεζίου: xi + h h f ( xdx ) = ( f( xi) + f( xi + h) ) xi Αν ισχύει η () τότε η μέθοδος RK3 γίνεται k = f( x i ), k = f ( xi + h/), k3 = f ( xi + h) h ( 3) h ( ) ( h yi+ = yi + k + k + k = yi + f xi + f xi + ) + f( xi + h), η οποία σχέση αντιστοιχεί στον κανόνα /3 του Simpson: xi + h' h' h f ( xdx ) = ( f( xi) + f( xi + h') + f( xi + h') ), με h ' = 3 xi Αν ισχύει η () τότε η μέθοδος RK γίνεται k = f( x i ), k = f ( xi + h/), k3 = f ( xi + h/), k = f ( xi + h) h h h yi+ = yi + ( k+ k + k3+ k) = yi + f( xi) + f( xi + ) + f( xi + h) RK3 RK 7