Metoda Runge-Kutta

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 12 mai 2021; verificările necesită 2 modificări .

Metodele Runge-Kutta (există un nume de metode Runge-Kutta în literatură ) este o clasă mare de metode numerice pentru rezolvarea problemei Cauchy pentru ecuațiile diferențiale obișnuite și sistemele acestora. Primele metode din această clasă au fost propuse în jurul anului 1900 de către matematicienii germani K. Runge și M. V. Kutta .

Clasa metodelor Runge-Kutta include metoda Euler explicită și metoda Euler modificată cu recalculare, care sunt metode de ordinul întâi și respectiv al doilea de precizie. Există metode standard explicite de ordinul trei de precizie care nu sunt utilizate pe scară largă. Cea mai des folosită și implementată în diverse pachete matematice ( Maple , MathCAD , Maxima ) este metoda clasică Runge-Kutta , care are ordinul al patrulea de precizie. Atunci când se efectuează calcule cu acuratețe sporită, metodele de ordinul al cincilea și al șaselea de precizie sunt din ce în ce mai utilizate [1] [2] . Construcția circuitelor de ordin superior este asociată cu mari dificultăți de calcul [3] .

Metodele de ordinul al șaptelea trebuie să aibă cel puțin nouă etape, iar metodele de ordinul al optulea trebuie să aibă cel puțin 11 etape. Pentru metodele de ordinul al nouălea și superior (care însă nu au o mare semnificație practică), nu se știe câte etape sunt necesare pentru a atinge ordinea corespunzătoare de precizie [3] .

Metoda clasică Runge-Kutta de ordinul al patrulea

Metoda Runge-Kutta de ordinul al patrulea pentru calcule cu un pas constant de integrare este atât de răspândită încât este adesea numită pur și simplu metoda Runge-Kutta.

Luați în considerare problema Cauchy pentru un sistem de ecuații diferențiale ordinare de ordinul întâi. (În continuare , a ).

Apoi valoarea aproximativă la punctele ulterioare este calculată prin formula iterativă:

Calculul unei noi valori are loc în patru etape:

unde  este valoarea pasului de grilă în .

Această metodă are al patrulea ordin de precizie. Aceasta înseamnă că eroarea la un pas este de ordin , iar eroarea totală la intervalul final de integrare este de ordin .

Metode Runge-Kutta explicite

Familia metodelor Runge-Kutta explicite este o generalizare atât a metodei explicite Euler, cât și a metodei clasice Runge-Kutta de ordinul patru. Este dat de formule

unde  este valoarea pasului în grilă și calculul noii valori are loc în următorii pași:

Metoda specifică este determinată de numărul și coeficienții și . Acești coeficienți sunt adesea ordonați într-un tabel (numit tabel Butcher ):

Pentru coeficienții metodei Runge-Kutta trebuie îndeplinite condițiile pentru . Dacă doriți ca metoda să aibă ordine , atunci ar trebui să furnizați și condiția

unde  este aproximarea obtinuta prin metoda Runge-Kutta. După diferențierea multiplă, această condiție este transformată într-un sistem de ecuații polinomiale în raport cu coeficienții metodei.

Metode implicite Runge-Kutta

Toate metodele Runge-Kutta menționate până acum sunt metode explicite . Din păcate, metodele explicite Runge-Kutta, de regulă, nu sunt potrivite pentru rezolvarea ecuațiilor rigide din cauza regiunii mici a stabilității lor absolute [4] . Instabilitatea metodelor explicite Runge-Kutta creează, de asemenea, probleme foarte serioase în rezolvarea numerică a ecuațiilor cu diferențe parțiale .

Instabilitatea metodelor explicite Runge-Kutta a motivat dezvoltarea metodelor implicite. Metoda implicită Runge-Kutta are forma [5] [6] :

Unde

Metoda explicită se caracterizează prin faptul că matricea de coeficienți are o formă triunghiulară inferioară (inclusiv diagonala principală zero) - spre deosebire de metoda implicită, unde matricea are o formă arbitrară. Acest lucru se vede și în Butcher's table .

O consecință a acestei diferențe este necesitatea de a rezolva sistemul de ecuații pentru , unde  este numărul de etape, la fiecare pas. Acest lucru crește costul de calcul, totuși, cu o valoare suficient de mică, se poate aplica principiul mapărilor de contracție și se poate rezolva acest sistem prin simpla iterație [7] . În cazul unei iterații, aceasta crește costul de calcul cu doar un factor de doi.

Pe de altă parte, Jean Kunzman (1961) și John Butcher (1964) au arătat că pentru orice număr de etape există o metodă Runge-Kutta implicită cu ordinea preciziei . Aceasta înseamnă, de exemplu, că pentru metoda explicită în patru etape de ordinul al patrulea descrisă mai sus, există un analog implicit cu ordinul de două ori precizie.

Metoda Runge-Kutta de ordinul doi implicită

Cea mai simplă metodă implicită Runge-Kutta este metoda Euler modificată „cu recalculare”. Este dat de formula:

.

Pentru a-l implementa la fiecare pas, sunt necesare cel puțin două iterații (și două evaluări de funcții).

Prognoza:

.

Corecţie:

.

A doua formulă este o simplă iterație a soluției sistemului de ecuații cu privire la , scrisă sub forma unei mapări de contracție. Pentru a îmbunătăți acuratețea, corectarea iterației poate fi făcută de mai multe ori prin înlocuirea . Metoda Euler modificată „cu recalculare” are al doilea ordin de precizie.

Sustenabilitate

Avantajul metodelor implicite Runge-Kutta în comparație cu cele explicite este stabilitatea lor mai mare, care este deosebit de importantă la rezolvarea ecuațiilor rigide . Considerăm ca exemplu ecuația liniară y' = λ y . Metoda obișnuită Runge-Kutta aplicată acestei ecuații se reduce la iterație , cu r egal cu

unde denotă un vector coloană de unități [8] . Funcția se numește funcție de stabilitate [9] . Se poate observa din formula care este raportul a două polinoame de grad dacă metoda are etape. Metodele explicite au o matrice triunghiulară strict inferioară , ceea ce implică că și că funcția de stabilitate este un polinom [10] .

Soluția numerică a acestui exemplu converge la zero în condiția c . Mulțimea acestora se numește regiunea de stabilitate absolută . În special, o metodă se numește A-stabilă dacă toți c sunt în regiunea de stabilitate absolută. Funcția de stabilitate a metodei Runge-Kutta explicite este un polinom, deci metodele Runge-Kutta explicite nu pot fi în principiu A-stabile [10] .

Dacă metoda are ordine , atunci funcția de stabilitate îndeplinește condiția pentru . Astfel, raportul polinoamelor de un grad dat prezintă interes, aproximând funcția exponențială în cel mai bun mod. Aceste relații sunt cunoscute ca aproximanți Padé . Aproximantul Padé cu numărător de grade și numitor de grade este A-stabil dacă și numai dacă [11]

Metoda Gauss-Legendre -stage are ordine , deci funcția sa de stabilitate este aproximarea Padé . Aceasta implică faptul că metoda este A-stabilă [12] . Acest lucru arată că metodele Runge-Kutta A-stabile pot fi de ordin arbitrar înalt. În schimb, ordinea stabilității A a metodelor lui Adams nu poate depăși două.

Pronunție

Conform normelor gramaticale ale limbii ruse, numele de familie Kutta este declinat, așa că ei spun: „Metoda Runge-Kutta”. Regulile gramaticii ruse prescriu să flexeze toate numele de familie (inclusiv cele masculine) care se termină în -а, -я, precedate de o consoană. Singura excepție o constituie numele de familie de origine franceză cu accent pe ultima silabă precum Dumas, Zola [13] . Cu toate acestea, uneori există o versiune indeclinabilă a „Metodei Runge-Kutta” (de exemplu, în cartea [14] ).

Un exemplu de soluție în limbaje de programare algoritmică

făcând o înlocuire și transferând în partea dreaptă, obținem sistemul:

Cod Java pentru rezolvarea unui sistem de ecuații diferențiale folosind metoda Runge-Kutta clasă publică MainClass { public static void main ( String [] args ) { int k = 2 ; dublu Xo , Yo , Y1 , Zo , Z1 ; dublu k1 , k2 , k4 , k3 , h ; dublu q1 , q2 , q4 , q3 ; /* *Condiții inițiale */ Xo = 0 ; Yo = 0,8 ; Zo = 2 ; h = 0,1 ; // Etapa Sistem . afară . println ( "\tX\t\tY\t\tZ" ); pentru (; r ( Xo , 2 ) < 1,0 ; Xo += h ){ k1 = h * f ( Xo , Yo , Zo ); q1 = h * g ( Xo , Yo , Zo ); k2 = h * f ( Xo + h / 2,0 , Yo + q1 / 2,0 , Zo + k1 / 2,0 ); q2 = h * g ( Xo + h / 2,0 , Yo + q1 / 2,0 , Zo + k1 / 2,0 ); k3 = h * f ( Xo + h / 2,0 , Yo + q2 / 2,0 , Zo + k2 / 2,0 ); q3 = h * g ( Xo + h / 2,0 , Yo + q2 / 2,0 , Zo + k2 / 2,0 ); k4 = h * f ( Xo + h , Yo + q3 , Zo + k3 ); q4 = h * g ( Xo + h , Yo + q3 , Zo + k3 ); Z1 = Zo + ( k1 + 2,0 * k2 + 2,0 * k3 + k4 ) / 6,0 ; Y1 = Yo + ( q1 + 2.0 * q2 + 2.0 * q3 + q4 ) / 6.0 ; Sistem . afară . println ( "\t" + r ( Xo + h , k ) + "\t\t" + r ( Y1 , k ) + "\t\t" + r ( Z1 , k )); Yo = Y1 ; Zo = Z1 ; } } /** * funcție de rotunjire și de eliminare a „cozii” */ public static double r ( double value , int k ){ return ( double ) Math . rotund (( Math . pow ( 10 , k ) * valoare )) / Math . pow ( 10 , k ); } /** * funcții care se obțin din sistem */ public static double f ( double x , double y , double z ){ return ( Math . cos ( 3 * x ) - 4 * y ); } public static double g ( double x , double y , double z ){ return ( z ); } } Cod în C# folosind System ; folosind System.Collections.Generic ; namespace PRJ_RungeKutta { /// <summary> /// Implementarea metodei Runge-Kutta pentru o ecuație diferențială obișnuită /// </summary> public abstract class RungeKutta { /// <summary> /// Ora curentă /// </summary > public dublu t ; /// <summary> /// Soluția dorită Y[0] este soluția în sine, Y[i] este derivata i-a a soluției /// </summary> public double [] Y ; /// <summary> /// Variabile interne /// </summary> double [] YY , Y1 , Y2 , Y3 , Y4 ; dublu protejat [] FY ; /// <summary> /// Constructor /// </summary> /// <param name="N">dimensiunea sistemului</param> public RungeKutta ( uint N ) { Init ( N ); } /// <summary> /// Constructor /// </summary> public RungeKutta (){} /// <summary> /// Alocați memorie pentru matrice de lucru /// </summary> /// <param name="N">Dimensiunile matricelor</param> protected void Init ( uint N ) { Y = new double [ N ]; YY = dublu nou [ N ]; Y1 = dublu nou [ N ]; Y2 = dublu nou [ N ]; Y3 = dublu nou [ N ]; Y4 = dublu nou [ N ]; FY = dublu nou [ N ]; } /// <summary> /// Setați condițiile inițiale /// </summary> /// <param name="t0">Ora de începere</param> /// <param name="Y0">Condiția inițială </param> public void SetInit ( double t0 , double [] Y0 ) { t = t0 ; if ( Y == null ) Init (( uint ) Y0 . Lungime ); pentru ( int i = 0 ; i < Y . Lungime ; i ++) Y [ i ] = Y0 [ i ]; } /// <summary> /// Calculul părților corecte ale sistemului /// </summary> /// <param name="t">ora curentă</param> /// <param name=" Y">soluții vectoriale</param> /// <returns>partea dreaptă</returns> abstract public double [] F ( double t , double [] Y ); /// <summary> /// Următorul pas al metodei Runge-Kutta /// </summary> /// <param name="dt">pasul de timp curent (poate fi variabil)</param> public void Următorul Pas ( double dt ) { int i ; if ( dt < 0 ) return ; // se calculează Y1 Y1 = F ( t , Y ); pentru ( i = 0 ; i < Y . Lungime ; i ++) YY [ i ] = Y [ i ] + Y1 [ i ] * ( dt / 2,0 ); // se calculează Y2 Y2 = F ( t + dt / 2,0 , YY ); pentru ( i = 0 ; i < Y . Lungime ; i ++) YY [ i ] = Y [ i ] + Y2 [ i ] * ( dt / 2,0 ); // se calculează Y3 Y3 = F ( t + dt / 2,0 , YY ); pentru ( i = 0 ; i < Y . Lungime ; i ++) YY [ i ] = Y [ i ] + Y3 [ i ] * dt ; // se calculează Y4 Y4 = F ( t + dt , YY ); // calculează soluția la pasul nou pentru ( i = 0 ; i < Y . Lungime ; i ++) Y [ i ] = Y [ i ] + dt / 6.0 * ( Y1 [ i ] + 2.0 * Y2 [ i ] + 2,0 * Y3 [ i ] + Y4 [ i ]); // calculăm timpul curent t = t + dt ; } } clasă TMyRK : RungeKutta { public TMyRK ( uint N ) : bază ( N ) { } /// <summary> /// exemplu pendul matematic /// y''(t)+y(t)=0 /// </summary> /// <param name="t">Timp</param > /// <param name="Y">Soluție</param> /// <returns>Dreapta</returns> public override double [] F ( double t , double [] Y ) { FY [ 0 ] = Y [ 1 ]; FY [ 1 ] = - Y [ 0 ]; returnează FY ; } /// <summary> /// Exemplu de utilizare /// </summary> static public void Test () { // Time step double dt = 0,001 ; // Sarcina obiect al metodei TMyRK = TMyRK nou ( 2 ); // Definiți condițiile inițiale y(0)=0, y'(0)=1 ale problemei dublu [] Y0 = { 0 , 1 }; // Setați condițiile inițiale pentru sarcina de activitate . SetInit ( 0 , Y0 ); // rezolvă până la 15 secunde în timp ce ( sarcină . t <= 15 ) { Consolă . WriteLine ( "Timp = {0:F5}; Func = {1:F8}; d Func / dx = {2:F8}" , task . t , task . Y [ 0 ], task . Y [ 1 ]); // ieșire t, y, y' // calculează pasul următor, sarcina pasului de integrare . Următorul Pas ( dt ); } Consolă . ReadLine (); } } class Program { static void Main ( șir [] args ) { TMyRK . test (); } } }

Programul C# folosește clasa abstractă RungeKutta , care ar trebui să suprascrie metoda abstractă F care specifică părțile din dreapta ecuațiilor.

Un exemplu de soluție în mediul MATLAB

Rezolvarea sistemelor de ecuații diferențiale prin metoda Runge-Kutta este una dintre cele mai comune metode de rezolvare numerică în inginerie. În mediul MATLAB este implementată una dintre varietățile sale - metoda Dorman-Prince . Pentru a rezolva un sistem de ecuații, trebuie mai întâi să scrieți o funcție care calculează derivatele, adică funcțiile y = g ( x ,  y ,  z ) și z = cos(3 x ) − 4 y = f ( x ,  y ) ,  z ), așa cum este descris mai sus. Într-unul dintre directoarele care sunt accesibile din sistemul MATLAB , trebuie să creați un fișier text numit (de exemplu) runge.m cu următorul conținut (pentru MATLAB versiunea 5.3):

MATLAB , runge.m funcția Dy = runge ( x, y ) Dy = y (:); Dy ( 1 ) = y ( 2 ); Dy ( 2 ) = cos ( 3 * x ) - 4 * y ( 1 );

Numele fișierului și numele funcției trebuie să se potrivească, dar poate fi orice nu a fost folosit anterior.

Apoi trebuie să creați un fișier principal numit, de exemplu, main.m , care va face calculele de bază. Acest fișier principal va conține următorul text:

MATLAB , principal.m limpede ; clc ; % Ștergeți memoria și ecranul h = 0,1 ; % Pas de integrare x_fin = 8 ; % Timp final de integrare y0 = 0,8 ; % Valoarea inițială a funcției Dy0 = 2 ; % Valoarea inițială a derivatei funcției [ x , y ] = ode45 ( 'runge' , [ 0 : h : x_fin ], [ y0 Dy0 ]); % metoda Runge-Kutta plot ( x , y , 'LineWidth' , 2 ); grila ; % Plot and Grid legenda ( 'y(x)' , 'y''(x)' , 0 ); % Legendă pe diagramă

Deoarece MATLAB este orientat pe matrice, soluția Runge-Kutta este foarte ușor de realizat pentru o gamă întreagă de x , ca, de exemplu, în exemplul de program de mai sus. Aici soluția este graficul funcției în intervale de timp de la 0 la x_fin .

Variabilele x și y returnate de funcția ODE45 sunt vectori de valoare. În mod evident, soluția exemplului de mai sus este al doilea element al lui x , deoarece prima valoare este 0, pasul de integrare este h = 0,1, iar valoarea dobânzii x = 0,1. Următoarea intrare din fereastra de comandă MATLAB va oferi soluția dorită:

soluție MATLAB y1 = y ( găsiți ( x == 0,1 ))

Răspuns: y1 = 0,98768

Note

  1. Bakhvalov N. S. , Zhidkov N. P. , Kobelkov G. M.  . Metode numerice. - M . : Laboratorul de Cunoștințe de bază, 2001. - 630 p. — ISBN 5-93208-043-4 .  - S. 363-375.
  2. Ilyina V. A., Silaev P. K. . Metode numerice pentru fizicienii teoreticieni. Partea 2. - Moscova-Ijevsk: Institutul de Cercetări Informatice, 2004. - 118 p. — ISBN 5-93972-320-9 .  - S. 16-30.
  3. 12 Măcelarul J. C.  . Metode numerice pentru ecuații diferențiale obișnuite. — New York: John Wiley & Sons , 2008. — ISBN 978-0-470-72335-7 .
  4. Süli & Mayers, 2003 , p. 349-351.
  5. Iserles, 1996 , p. 41.
  6. Süli & Mayers, 2003 , p. 351-352.
  7. Implicit Runge Methods - Kutta Arhivat 6 martie 2019 la Wayback Machine .
  8. Hairer & Wanner, 1996 , p. 40-41.
  9. Hairer & Wanner, 1996 , p. 40.
  10. 1 2 Iserles, 1996 , p. 60.
  11. Iserles, 1996 , p. 62-63.
  12. Iserles, 1996 , p. 63.
  13. Cum să refuzi numele de familie (cazuri dificile) - „Gramota.ru” - referință și informații Portal de internet „Limba rusă” . Consultat la 5 iulie 2016. Arhivat din original la 23 mai 2018.
  14. Demidovich B. P., Maron I. A., Shuvalova E. Z. . Metode numerice de analiză. a 3-a ed. — M .: Nauka , 1967.

Literatură

  • Hairer E., Wanner G. . Rezolvarea ecuaţiilor diferenţiale ordinare II: Probleme rigide şi algebrice diferenţiale. a 2-a ed. - Berlin, New York: Springer-Verlag , 1996. - ISBN 978-3-540-60452-5 .
  • Iserles A. . Un prim curs în analiza numerică a ecuațiilor diferențiale. - Cambridge: Cambridge University Press , 1996. - ISBN 978-0-521-55655-2 .
  • Suli E., Mayers D. . O introducere în analiza numerică. - Cambridge: Cambridge University Press , 2003. - ISBN 0-521-00794-1 .