Numeriska metoder, grundkurs II Övning 5 för I Dagens program Övningsgrupp 1 Johannes Hjorth hjorth@nada.kth.se Rum :006, Roslagstullsbacken 5 08-790 69 00 Kurshemsida: http://www.csc.kth.se/utbildning/kth/kurser/d0/numi07 Material utdelat på övningarna: http://www.csc.kth.se/ hjorth/teaching/numi07 Gyllenesnittetminimering Hitta funktionsminimum utan att derivera Differentialekvationer Euler, Runge-Kutta, ode45 Fråga om teorital Något speciellt tal vi ska gå igenom? Rättelse övning 4 Newtons metod har kvadratisk konvergens! Gyllenesnittminimering, eempel 4.7 Det som är intressant här är while-slingan och hur punkterna u a, u b, u 1 och u uppdateras för varje varv beroe på vilken av u 1 och u som är minst. % Kod för gyllenesnittminimering clear all g = (sqrt(5) - 1)/; ua = pi/4; ub = /4*pi; u1 = ua*g + (1-g)*ub; u = ua*(1-g) + g*ub; tol = 1e-5; Förhållandet mellan olika segment hos snäckor uppfyller approimativt gyllene snittet. Vi ska dock använda g = 5 till att hitta minimum för en funktion. Inga derivator behövs. function L = len(u) Q1 = [0;]; Q = [;]; R = 4; P = [8+R*cos(u); +R*sin(u)]; L = norm(q1-p) + norm(q-p); while(abs(ua-ub) > tol) if(len(u1) < len(u)) ub = u; u = u1; u1 = ua*g + (1-g)*ub; else ua = u1; u1 = u; u = ua*(1-g) + g*ub; mean([ua ub])
Vi har valt de inre punkterna u 1 och u så att vi hela tiden kan återanvända en av dem i nästa iteration. Euler framåt, eempel 7.1 Iterations 1, error = 1.5708 1 ua u1 u ub 0.5 1 1.5.5 Iterations, error = 0.59999 Iterations, error = 0.97081 1 ua ub u1 u 0.5 1 1.5.5 Iterations 5, error = 1.515e 05 Antag att vi har en diff-ekvation och vi vet att y(0) = 1. dy = f(y, t) = 1 + t y dt 1 ua u1 u ub 0.5 1 1.5.5 >> gyllenesnittminimering ans = 1.781 15 1 1 11 0.5 1 1.5.5 I första iterationen ser vi att u är mindre än u 1, eftersom funktionen är unimodal kan minimum alltså inte finnas mellan u 1 och u a, eller hur? Vi låter u 1 bli vårt nya u a. Då kan u användas som det nya u 1, och vi behöver bara beräkna fram det nya u värdet. Dubbelkolla i figuren! Vi kan då lösa den för hand med Euler framåt, vilket har förekommit några gånger i gamla tentor. Med Euler framåt tar vi ett litet steg t framåt i derivatans riktning y(t + t) = y(t) + t f(y, t) för att beräkna det nya funktionsvärdet i t + t. Rita figur och räkna för hand! ode45 För att kunna lösa diff ekvationer med matlabs inbyggda funktioner måste vi först skapa en funktion som ode45 kan anropa. Första argumentet måste vara tiden, oavsett om funktionen har något tidsberoe eller ej. function f = flode(t,h) A = 0.8; C = 0.1; g = 9.81; Qin = ma(0,1-h/0); Qut = C*sqrt(*g*h); f = (Qin - Qut)/A; Anropet till ode45 har tre parametrar, namnet på funktionen, tidsintervallet och begynnelsevärden. [t,h] = ode45(@flode,[0 0], h0); Räkna ett steg med h = 0. och gör sedan om beräkningen med h = 0.1, då behövs två steg. Som svar får vi kolumnvektorer med tiden och höjden vid de olika tidpunkterna.
I eemplet ska vi lösa för tre olika startvärden, vilket görs enklast med en for-loop. clear all, close all for h0 = [0 ]; % Vi löser från t = 0 till t = 0 [t,h] = ode45(@flode,[0 0], h0); plot(t,h), hold on title( Eempel 7.4 ) label( tid (s) ), ylabel( höjd (m) ) Eempel 7.4 Andra ordningens Runge-Kutta Andra ordningens Runge-Kutta använder två lutningar för att stega framåt y(t + t) = y(t) + h (f(t,y) + f ) Här är f en approimation till lutningen i nästa punkt f = f(t + t, y + h f(t,y)) Steget vi tar utnyttjar medelvärdet av dessa två lutningarna. Metoden är mest av teoretiskt intresse. hojd (m) 8 6 4 Rita figur! 0 0 5 15 0 tid (s) Fjärde ordningens Runge-Kutta Eempel 7.7 Vi kommer att använda oss av fjärde ordningens Runge-Kutta. Nästa steg beräknas ur Vi har att dy d = f(, y) och ska beräkna en lösning till differentialekvationen med hjälp av fjärde ordningens Runge-Kutta. y(t + t) = y(t) + h 6 (f 1 + f + f + f 4 ) där f 1 = f(t,y) f = f(t + h, y + h f 1) f = f(t + h, y + h f ) f 4 = f(t + h, y + h f ) nx = 8; = 0; y = 0; h = 0.8/nX; v = ; yv = y; % Vektorer att spara,y värdena i for i = 1:nX f1 = funk(,y); f = funk(+h/,y + h/*f1); f = funk(+h/,y + h/*f); f4 = funk(+h,y + h*f); = + h; y = y + h/6 *(f1 + *f + *f + f4); v = [v ]; yv = [yv y]; Koden fortsätter på nästa slide...
För sista biten löser vi som en funktion av y. ny = 5; h = y/ny; = 1; y = 0; v = ; yv = y; for i = 1:nY f1 = ifunk(y,); f = ifunk(y+h/, + h/*f1); f = ifunk(y+h/, + h/*f); f4 = ifunk(y+h, + h*f); y = y + h; = + h/6 *(f1 + *f + *f + f4); Vi behöver funktionen för y = f(,y), observera att nollan specialbehandlas. function f = funk(,y) if( == 0) f = sqrt(); % Fås mha L Hospital else f = */y * (/(1 + *^ + y^) - 1); och funktionen för = 1/f(, y) function f = ifunk(y,) f = y/(*)/(/(1+*^+y^)-1); v = [v ]; yv = [yv y]; clf, hold on, plot(v,yv, o,v,yv, * ) 0.5 Eempel 7.7 plot(v,yv, v,-yv), plot(v,yv,v,-yv) title( Eempel 7.7 ), label( ), ylabel( y ) y 0 0.5 0 0. 0.4 0.6 0.8 1 Teorital Härledning av feltermer Titta igenom teoritalen, är det något speciellt tal som är etra svårt? Maila eller säg till så kan vi försöka hinna gå igenom det på sista övningen. Vi kan härleda feltermerna för framåt och central differanskvoten med hjälp av taylorutvecklingar. f (+h) = f()+h f ()+ h! f ()+ h! f ()+... Börja med att få f () ensamt på en sida, så faller pusselbitarna på plats. Vänta inte, gör det nu! För centraldifferanskvoten behöver vi utvecklingen för f ( h) också. Subtrahera sedan den från utveckligen av f( + h). Återstår få f () ensam.
Gauss-kvadratur Hur väljer vi punkter och vikter? När man ska beräkna en integral är ett sätt att placera ut punkterna jämnt i intervallet. Det finns dock andra sätt att göra det på. Vi kan tillåta oss att placera ut punkterna var som helst på intervallet, samt att multiplicera de olika funktionsvärdena med konstanter. 1 f()d w 1 f( 1 ) + w f( ) Tanken med Gauss-kvadratur är att det ska vara eakt för polynom upp till en viss given grad. Lösningen ska vara eakt för 8 1 >< f() = >: Härledning följer w 1 + w = w 1 1 + w = w 1 1 + w = w 1 1 + w = 1d = [] 1 = 1 + 1 = d = = = " " " 4 4 # 1 # 1 # 1 = 1 1 = 0 = 1 + 1 = = 1 4 1 4 = 0 En lösning till detta är (sätt in och kontrollera) 1 = 1, = 1, w 1 = 1, w = 1 Praktisk användning Horners algoritm Gauss-kvadratur är härlett för f()d men vi har ofta andra integrationsgränser Z b a f()d Vi måste då göra en variabeltransformation, te = d = b a (b a) t + a + b dt Vilket ger oss för två punkter, n = Z b a f()d = b a «(b a) t + a + b f dt b a nx «(b a) t + a + b w i f i=1 Säg att vi har ett polynom y = c 0 + c 1 + c + c Att beräkna en punkt kräver då många multiplikationer, med Horners algoritm kan man reducera antalet. y = ((c } {{ } +c ) +c 1 ) +c 0 en }{{} två }{{} Tre multiplikationer istället för 1 + + = 6. tre
Tidsåtgång För gausseliminering är tidsåtgången proportionell mot n. Det betyder att om vi fördubblar storleken på systemet tar det = 8 gånger längre tid. Tidsåtgången för lösning av triangulära matriser är n, vi kan använda detta sambandet för att uppskatta körtiden. Tentatal på detta bygger ofta på att vi vet att te t = C n, så får man hur lång tid det tar för ett visst n, då kan C bestämmas. Sedan är uppgiften att räkna fram hur lång tid det tar för ett större n. För tridiagonala system väer tidsåtgången linjärt. Då lagrar vi bara de nollskillda elementen, dvs n för tridiagonalen istället för n. Tar mindre plats. För stora system kan det vara bra att använda glesa matriser i matlab (sparse), te då vi använder oss av bandmatrismetoden.