Numeriska metoder, grundkurs II Övning 3 för I Dagens program Övningsgrupp Johannes Hjorth hjorth@nada.kth.se Rum 63:6, Roslagstullsbacken 35 8-79 69 Kurshemsida: http://www.csc.kth.se/utbildning/kth/kurser/d4/numi7 Material utdelat på övningarna: http://www.nada.kth.se/ hjorth/teaching/numi7 Ögna igenom de gamla övningsanteckningarna Fler associationer i hjärnan innebär att det blir lättare för oss att komma ihåg informationen Interpolation med kubiska splines Skriv något kul här... Trapetsmetoden Vi beräknar integraler Richardsonetrapolering Vi förbättrar resultatet utan att räkna mer! Substitutioner och svans-kapning Hur hanterar man elaka integraler? Kubiska splines Eempel 5. Vi vill skapa en serie med hermitepolnom efter varandra, genom givna punkter, med första och andra derivatorna kontinuerliga. Detta ger oss ett ekvationssstem... h h k b h (h + h ) h k B h 3 (h + h 3 ) h C Bk 3 C @ h 4 (h 3 + h 4 ) h @ 3 k = b Bb 3 C @ 4 b 4 h 4 h 4 k 5 b 5 hi b i = 3 i + h «i i, i =, 3, 4 h i h i och för naturliga splines har vi b = 3 och b 5 = 3 4 När k i bestämts ur sstemet kan vi rita polnomen (t) (t) g i = i + t h i = i + t i + t( t) g i + t ( t) c i = h i k i i c i = i h i (k i + k i+ ) % Kubiska splines makes bab jesus cr... = [ 4 6]; = [3 4 3 6]; h = diff(); d = diff(); % Vi räknar fram lutningarna som uppfller villkoren ud = [h() h(:3)]; ld = [h(:4) h(4)]; d = [*h() *(h(:3) + h(:4)) *h(4)]; = diag(d,) + diag(ud,) + diag(ld,-); b(:4) = 3*(d(:4).*h(:3)./h(:4) + d(:3).*h(:4)./h(:3)); b() = 3*d(); b(5) = 3*d(4); k = \b ; % Sen är det dags att rita allt, t är en kolumnmatris t = linspace(,,) ; g = h.*k(:4) -d; c = *d - h.*(k(:4) + k(:5) ); % Rita upp matriserna och fundera för att se vad som händer v = ones(size(t))*(:4) + t*((:5) - (:4)); v = ones(size(t))*(:4) + t*d + t.*(-t)*g... + t.^.*(-t)*c; % Varje kolumn i v, v svarar mot en hermite-kurva plot(v,v, -,,, * ) title( Eempel 5. ), label( ), label( ) 6 5 4 3 Eempel 5. 3 4 5 6
Eempel 5. Vi ska anpassa en kurva till en kvartscirkel i första kvadranten. Först med en kvadratisk Bézierkurva r(t) = ( t) p + t( t)b + t q Kurvan kommer att gå från p i riktning mot b för att sedan böja av mot q. Punkten b bestämmer lutningen i både p och q. Här blir p = (,), q = (, ) och b = (,). För den kubiska Bézierkurvan gäller r(t) = ( t) 3 p + 3t( t) b + 3t ( t)c + t 3 q I p går kurvan i riktning mot b, och i q mot c. Vi har två frihetsgrader kvar, vi kan bestämma hur långt bort b och c ska vara. Detta utnttjar vi för att gå igenom mittpunkten på cirkelsegmentet Vi kan teckna b och c r( ) = (,) b = p + a k = (, ) + a (, ) = (a,) c = q + a k = (, ) + a (, ) = (, a ) Stoppar vi in detta i formeln ovan får vi a = a = 4 3 ( ) % Cirkelsegment v = linspace(, pi/, ); = cos(v); = sin(v); % Kvadratisk Bézierkurva p = [,]; q = [,]; b = [,]; t = linspace(,,) ; % obs, transponat r = (-t).^*p + *t.*(-t)*b + t.^*q; % Kubisk Bézierkurva a = 4/3*(sqrt()-); b = [a,]; c = [,a]; r3 = (-t).^3*p + 3*t.*(-t).^*b... + 3*t.^.*(-t)*c + t.^3*q; % Plotta leg = plot(,, -.k, r(:,), r(:,), --r,... r3(:,), r3(:,), -b ); Vi ser att den kvadratiska Bézierkurvan avviker som mest från cirkelsegmentet i mittpunkten. Den kubiska varianten ligger dock mcket nära. Vi måste zooma in i grafen för att skilja dem åt..8.6.4. Cirkelsegment Kvadratisk Bezier Kubisk Bezier Eempel 5...4.6.8 legend(leg, Cirkelsegment,... Kvadratisk Bézier,... Kubisk Bézier ) title( Eempel 5. ) label( ), label( ) ais equal
Trapetsmetoden Eempel 6.a Med trapetsmetoden delar vi upp integralen, och beräknar tan av varje segment för sig. f(a) f(a+h) Vi vill lösa 3 e + 3d med fra korrekta decimaler. Först skriver vi en funktion i filen f6a.m function = f6a() = ep()./( + *.^3); vilket kan skrivas: a a+h b Det är viktigt att funktionen kan hantera vektorer korrekt. Z b a f() = h f(a) + f(a + h) +h f(a + h) + f(a + h) Grupperar vi om termerna får vi: b a f() = h n f( + n h) h i= Ändpunkterna förekommer inte dubbelt! h) + f(b) + +h f(b f(a) + f(b) clear all, format long, format compact f = linspace(,3,); f = f6a(f); n = 4; tol =.5e-4; corr = inf; F = inf; while(abs(corr) > tol) % Skapa -vektorn, beräkna h, spara undan gamla F = linspace(,3,n); h = ()-(); oldf = F; end % Trapetsmetoden F = h*(sum(f6a()) -.5*(f6a(())+f6a((end)))); corr = F - oldf; disp([f corr]) % Detta är bara för att få lite pedagogiska figurer clf, hold on plot(f,f, k--,,f6a(), b- ) stem(,f6a()) label( ), label( ) title([ Number of points: numstr(n)]) pause % Uhm... kom ihåg denna raden bara! n = *n; Vi ser hur algoritmen successivt ger en bättre approimation till integralen.5.5 Number of points: 4.5.5.5 3 Number of points: 6.5.5.5.5.5 3.5.5 Number of points: 8.5.5.5 3 Number of points: 56.4..8.6.4..5.5.5 3 >> tal6a.3349795 -Inf.5484677783.3568547977.6698367436637.37497984.6954998348.558654764.73967.5887964358.7768856837.45978687.737463947.347383377 >>
Eempel 6.b Nu ska vi istället lösa integralen π sin d Observera att matlab bråkar då vi dividerar med. Det kan vi lösa på två sätt, antingen skriver vi en funktion som klarar av att hantera =, eller så undviker vi att skicka det värdet. Facits metod, i trapetsmetoden bter vi ut = linspace(,pi,n); h = () - (); = f6b(); F = h*(sum() - (() + (end))/); mot = linspace(,pi,n); h = () - (); = [ f6b((:end))]; F = h*(sum() - (() + (end))/); Vi skickar helt enkelt aldrig = till funktionen. lternativt, vi skriver en funktion som klarar av alla -värden. För att hantera = behöver vi bta ut det felaktiga värdet NaN (not a number) mot =. Vi använder find för att leta nollan, den retunerar positionen på elementet i vektorn. function = f6b() % Kommer att ge varning för = = sin()./; % Vi vill att den räknar rätt, så leta upp det % felaktiga värdet med find( == ) och sätt det till. % Find returnerar positionen i vektorn i = find( == ); % Bt ut -värdet för det -värdet mot (i) = ; Vi kan sen använda trapetsmetoden från föregående uppgift, behöver bara bta integrationsgränser och funktionsnamn. Det går att undvika varningen också med find, men det lämnas som övning åt den som bara måste veta. Här ville jag endast visa hur find används. Härledning av Trapetsregelns felterm Richardsonetrapolering f() ntag att vi räknat på trapetsregeln Vi tecknar stapelns area, den har bredd h. m Z Z f()d = f(m)+f (m)( m)+f ( m) (m) + d! Integrerar vi Talorutvecklingen får vi " f(m)( m) + f ( m) (m) + f ( m)3 (m) 3! vilket blir = f(m) h + f (m) h3 3 + # m+ h m h T(h) = + c (h) = + 4ch + O(h 4 ) och sedan halverat steglängden och räknat igen T(h) = + c h + O(h 4 ) Borde vi inte kunna få fram ett bättre värde på? Vi kan teckna första feltermen som c h = T(h) T(h) 3 Drar vi bort den från T(h) får vi ett bättre värde! Kubisk felterm?! Nej, nu är assen ute och snurrar... Det ska ju bli kvadratiskt, vad har vi missat?
Eempel och quadl Svanskapning Vi testar Richardsonetrapolering på några värden från eempel 6.a >> tal6a.3349795 -Inf.5484677783.3568547977.6698367436637.37497984.6954998348.558654764.73967.5887964358.7768856837.45978687.737463947.347383377 Vi tar värdena från tredje och fjärde raden och utför Richardsonetrapolering. >>.6954998348 - (.6698367436637 -.6954998348)/3 ans =.7395749989 Vi får ett förbättrat värde, trevligt! Kontrollera svaret med quadl och tolerans 8 >> quadl(@f6a,,3,e-8) ans =.738884635 Vi ska beräkna 3 + 4 + + 3d Börja med att dela upp integralen i två delar, från till och från till. Därefter väljer vi så stort att den andra integralen blir försumbar, vi måste dock visa det också. 3 + 4 + + 3d < 3 4d < 8 vilket ger att [ 3 3 ] = 3 < 3 8 > för stora så är felet i svansen försumbart. Vi beräknar sedan första halvan av integralen med den inbggda funktionen quadl. Sammanfattning Interpolation, följ kokboksrecepten och ta det lugnt. Trapetsmetoden har kvadratiskt fel, kom ihåg Richardsonetrapolering. Tpiskt teorital att man får några funktionsvärden och ska beräkna ett bättre värde. När ni använder quadl måste funktionen klara av vektorer. För vilka värden är funktionen definierad, är det någonstans då nämnaren blir noll. Måste vi specialbehandla? Om integralen går till oändligheten, kan vi visa att den sista biten är begränsad? Kapa! Kom ihåg att ta med svansfelet i felgränsen! Tappa inte tallriken...