BYFE/EMFE 1000, 2012/2013 Numerikkoppgaver uke 43 Oppgave 1 Riemann-summer med regulære partisjoner a) Vi velger oss f(x) = x 2 + e x, a = 1 og b = 1. Integralet blir b a f(x) dx = 1 1 ( x 2 + e x) dx = [ x 3 /3 + e x] 1 1 = 1/3 + e ( 1/3 + e 1 ) = 2/3 + e 1/e 3.017. b) Vi får x = b a = 2 5 5 x i = x 0 + i x = 1 + 2i/5 P 5 = { 1, 3/5, 1/5, 1/5, 3/5, 1} S 5,v = { 1, 3/5, 1/5, 1/5, 3/5} S 5,v = { 3/5, 1/5, 1/5, 3/5, 1} S 5,h = { 4/5, 2/5, 0, 2/5, 4/5} Vi regner ut de tre Riemann-summene ved å lage et lite skript til å kjøre i Octave: % Skript som regner ut Riemann-summer for en regulær % partisjon på tre ulike måter % Maskevidde DeltaX=2/5; % Partisjon: P=-1:DeltaX:1; % Seleksjoner Sv=P(1:5); Sh=P(2:6); Sm=-4/5:DeltaX:4/5; 1
% Setter de tre summene til nll: RsumV=0; RsumH=0; RsumM=0; % Bestemmer antall punkt i seleksjonene n=length(sv); % for-løkke som regner summene for i=1:n XvStjerne=Sv(i); XhStjerne=Sh(i); XmStjerne=Sm(i); RsumV=RsumV+IntFunk(XvStjerne)*DeltaX; RsumH=RsumH+IntFunk(XhStjerne)*DeltaX; RsumM=RsumM+IntFunk(XmStjerne)*DeltaX; RsumV RsumH RsumM I Octave får vi: > TreRiemannSummer RsumV = 2.6316 RsumH = 3.5717 RsumM = 2.9748 c) Vi velger å bruke input-funksjonen slik at vi ikke trenger re skriptet hver gang vi velger en ny n (skriptet er veldig likt det i deloppgave b): % Skript som regner ut Riemann-summer for en regulær % partisjon på tre ulike måter % Antall del-intervaller: n=input('angi antall del-intervaller ') % Maskevidde DeltaX=2/n; % Partisjon (den har n+1 elementer): P=-1:DeltaX:1; % Seleksjoner (de har n elementer) Sv=P(1:n); Sh=P(2:(n+1)); Sm=(Sv+Sh)/2; % Setter de tre summene til numm: 2
RsumV=0; RsumH=0; RsumM=0; % for-løkke som regner summene for i=1:n XvStjerne=Sv(i); XhStjerne=Sh(i); XmStjerne=Sm(i); RsumV=RsumV+IntFunk(XvStjerne)*DeltaX; RsumH=RsumH+IntFunk(XhStjerne)*DeltaX; RsumM=RsumM+IntFunk(XmStjerne)*DeltaX; RsumV RsumH RsumM Her har vi regnet ut Sh-vektoren som gjennomsnittet av de to vektorene Sv og Sh. Alternativt kunne vi ha gjort det slik: `Sh=(-1+DeltaX/2):DeltaX:(1-DeltaX/2);'. d) Vi kjører skriptet for diverse n-verdier: > TreRiemannSummer Angi antall del-intervaller 5 n = 5 RsumV = 2.6316 RsumH = 3.5717 RsumM = 2.9748 > TreRiemannSummer Angi antall del-intervaller 10 n = 10 RsumV = 2.8032 RsumH = 3.2733 RsumM = 3.0065 > TreRiemannSummer Angi antall del-intervaller 20 n = 20 RsumV = 2.9048 RsumH = 3.1399 RsumM = 3.0144 > TreRiemannSummer Angi antall del-intervaller 50 n = 50 RsumV = 2.9709 RsumH = 3.0649 RsumM = 3.0166 > TreRiemannSummer Angi antall del-intervaller 100 3
n = 100 RsumV = 2.9938 RsumH = 3.0408 RsumM = 3.0170 > TreRiemannSummer Angi antall del-intervaller 500 n = 500 RsumV = 3.0124 RsumH = 3.0218 RsumM = 3.0171 Det ser ut til at alle tre Riemann-summene nærmer seg integralet når n øker (se deloppgave a)). Men det er tydelg at midt-summen nærmer seg mye raskere; allerede med n = 50 har denne metoden 3 desimaler riktig, mens dette ikke en gang er tilfelle for høgre- og venstresummen for n = 500. e) Vi lager tre funksjonsler for hver av de tre funksjonene. Den for R Pn,Sn,v b a f(x) dx ser slik ut: function D=RiemannDiffV(n) % Funksjon som regner ut absoluttverdien av differanse mellom et integral % og en Riemann-sum for en regulær partisjon og venstre-seleksjon. Integral=2/3+e-1/e; % Maskevidde DeltaX=2/n; % Partisjon (den har n+1 elementer): P=-1:DeltaX:1; % Seleksjoner (de har n elementer) Sv=P(1:n); % Setter de tre summene til numm: RsumV=0; % for-løkke som regner summene for i=1:n XvStjerne=Sv(i); RsumV=RsumV+IntFunk(XvStjerne)*DeltaX; D=abs(RsumV-Integral); og heter RiemannDiV.m. De andre to ser tilsvare ut og har tilsvare navn. Vi lager et skript som lager plottet: 4
Figur 1: Figuren viser de tre Riemann-summene som funksjoner av n. % Velger n-verdier nvektor=5:5:100; % Lager vektorer for plotting indeks=1; for n=nvektor VenstreVektor(indeks)=RiemannDiffV(n); HogreVektor(indeks)=RiemannDiffH(n); MidtVektor(indeks)=RiemannDiffM(n); indeks=indeks+1; % Plotter plot(nvektor,venstrevektor,'bx') hold on plot(nvektor,hogrevektor,'r+') plot(nvektor,midtvektor,'go') hold off leg('venstre-seleksjon','hogre-seleksjon','midt-seleksjon') Resultatet er vist i gur 1. Tilsvare for litt ere og større n-verdier er også vist i gur 2, som er et logaritmisk plott. 5
Figur 2: Figuren viser det sammme som gur 1 men med logaritmiske akser. Legg merke til at på et slikt plott ser feilen ut til å gå mot rette linjer der den grønne er den klart bratteste. 6
Konklusjonen bør være ganske tydelig: Riemann-summen konvergerer mye raksere mot integralet om vi velger midtpunktene enn når vi velger ene. Oppgave 2 Trapes-integrasjon a) Siden P skal være regulær, må vi ha at P = {x 0, x 1, x 2 } = {a, a + x, b} med x = (b a)/2. Trapes-metoden gir føge estimat for integralet: T 3 = x/2 f(x 0 ) + x f(x 1 ) + x/2 f(x 2 ). Venstre og høgre Riemann-summ blir henholdsvis R v = f(x 0 ) x + f(x 1 ) x og R h = f(x 1 ) x + f(x 2 ) x slik at gjennomsnittet av dem blir (R v + R h )/2 = f(x 0 ) x/2 + f(x 1 ) x/2 + f(x 1 ) x/2 + f(x 2 ) x/2 = x/2 f(x 0 ) + x f(x 1 ) + x/2 f(x 2 ) = T 3 (q. e. d.) Her har vi for enkelhetss skyld skrevet R v i stedet for R P,Sv og tilsvare for høgre-seleksjonen. Med n delintervaller: R v = f(x 0 ) x + f(x 1 ) x +... + f(x n 1 ) x og R h = f(x 1 ) x + f(x 2 ) x +... + f(x n ) x. Gjennomsnittet blir f(x 0 ) x/2 +f(x 1 ) x/2 +... + f(x n 1 ) x/2 + f(x 1 ) x/2 +... + f(x n 1 ) x/2 + f(x n ) x/2 = f(x 0 ) x/2 + 2 f(x 1 ) x/2 +... + 2 f(x n 1 ) x/2 + f(x n ) x/2 = x/2 f(x 0 ) + x f(x 1 ) +... + x f(x n 1 ) + x/2 f(x n ) = T n b) Algoritmen kan implementeres på denne måten: % Skript som estimerer et integral ved hjelp av % trapes-metoden på en regulær partisjon. Funksjonen % som skal integreres er gitt i IntFunk.m % Input-parametre - a, b og n a=input('nedre integrasjonsgrense: '); b=input('oevre integrasjonsgrense: '); n=input('antall del-intervall: '); 7
% Bestemmer Delta x: DeltaX=(b-a)/n; % Setter summen til 0: T=0; % for-løkke som summerer: for i=0:n x=a+i*deltax; if i==0 T=T+DeltaX*IntFunk(x)/2; elseif i==n T=T+DeltaX*IntFunk(x)/2; else T=T+DeltaX*IntFunk(x); % Skriver T til skjerm: T if-satsene i for-løkka kan vi slå sammen til én: if i==0 i==n T=T+DeltaX*IntFunk(x)/2; else... Symbolet betyr altså eller. Vi bruker her funksjonla IntFunk.m for hver deloppgave. a 1 0 x2 dx, n = 5. Vi rer den siste linja i IntFunk.m til `F=xˆ 2;' og kjører skriptet: Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 1 Antall del-intervall: 5 T = 0.34000 Svaret, 0.34, er ganske nær det eksakte svaret, som vi kan nne ved anti-derivasjon: 1 0 x2 dx = [1/3 x 3 ] 1 0 = 1/3. b 4 0 x dx, n = 8. Siste linje i IntFunk.m blir nå `F=sqrt(x);', og vi får: Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 4 Antall del-intervall: 8 8
T = 5.2650 Det eksakte svaret er 4 [ ] x 1/2 1 4 dx = 0 1/2 + 1 x1/2+1 = 2 0 3 43/2 = 16 3 5.33333. c π 0 cos x dx, n = 6. Vi justerar funksjonsla og kjører skriptet vårt: Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: pi Antall del-intervall: 6 T = 3.8858e-016 > eps ans = 2.2204e-016 Vi får altså svaret 3.9 10 16, som er omtrent maskin-nøyaktigheten. Om vi hadde regna ut T 6 analytisk, ville vi ha funne at svaret, ikkje overraskande, blir eksakt 0. Dette er også den eksakte verdien av integralet: π 0 cos x dx = [sin x]π 0 = 0. c) a Én prosent av svaret er 1/3 1/100 = 1/300 0.003333. Vi prøver oss fram med høyere og høyere n-verdier (etter å ha justert på funksjon- la igjen). Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 1 Antall del-intervall: 3 T = 0.35185 octave-3.2.4.exe:90> T-1/3 ans = 0.018519 Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 1 Antall del-intervall: 5 T = 0.34000 octave-3.2.4.exe:94> T-1/3 ans = 0.0066667 Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 1 Antall del-intervall: 7 T = 0.33673 > T-1/3 ans = 0.0034014 9
Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 1 Antall del-intervall: 8 T = 0.33594 > T-1/3 ans = 0.0026042 Vi nner at feilen er mindre enn 1% med n = 8 (og formodentlig også med n > 8). b Her er én prosent av svaret 16/3 1/100 = 4/75 0.05333. Vi prøver oss fram, og nner at feilen blir mindre enn dette når n 10: Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 4 Antall del-intervall: 9 T = 5.2759 > T-16/3 ans = -0.057481 Nedre integrasjonsgrense: 0 Oevre integrasjonsgrense: 4 Antall del-intervall: 10 T = 5.2841 > T-16/3 ans = -0.049259 Oppgave 3 En kjøretur a) Plottet kan lages slik: > clear all > Tab=load('Kjoretur.dat'); > T=Tab(:,1)+Tab(:,2)/60; > V=Tab(:,3); > plot(t,v,'linewidth',2) > xlabel('tid (min)'); ylabel('fart (km/h)') Resultatet kan sees i gur 3 b) Integralet kan estimeres slik: % Laster inn data Tab=load('Kjoretur.dat'); T=Tab(:,1)+Tab(:,2)/60; V=Tab(:,3); 10
Figur 3: Figurer viser farten under en biltur ved ulike tidspunkt. % Bestemmer lengda N=length(T); Sum=0; % For løkke for å regne ut integralet for i=1:(n-1) DeltaXi=T(i+1)-T(i); Sum=Sum+(V(i)+V(i+1))/2*DeltaXi; Integral=Sum Når vi kjører skriptet i Octave, får vi svaret 1360. Enheten her blir km/h min = 1/60 km. Vi har altså kjørt ca 1360/60 km 22.7 km. Med fare for at noen vil synest vi har gått et stykke over bekken etter vann: Octave har trapes-integrering innebygd (`trapz'); utregninga kunne ha blitt gjort slik: > Int=trapz(T,V) Int = 1360.0 c) I stedet for å bare regne ut hele integralet, lager vi en vektor som estimerer integralet fram til T(i): % Laster inn data 11
Figur 4: Figuren viser et estimat på hvor langt man har kjørt som funksjon av tid. Tab=load('Kjoretur.dat'); T=Tab(:,1)+Tab(:,2)/60; V=Tab(:,3); % Bestemmer lengda N=length(T); Sum=0; % For løkke for å regne ut integralet IntegralVektor(1)=0 for i=1:(n-1) DeltaXi=T(i+1)-T(i); Sum=Sum+(V(i)+V(i+1))/2*DeltaXi; IntegralVektor(i+1)=Sum; plot(t,integralvektor/60,'linewidth',2) xlabel('tid (min)'); ylabel('strekning (km)') Legg merke til forskyvningen i indeksen til vektoren IntegralVektor i linje 15. Når vi plotter IntVektor mot T, får vi plottet vist i gur 4. 12
Ekstra: Oppgave 4 Monte Carlo-integrering a) Siden begge uttrykkene skal gi f (tilnærma i det siste tilfellet), kan vi helt enkelt sette dem lik hverandre: 1 b a b a b a f(x) dx 1 n n f(x i ) i=1 f(x) dx b a n b) Vi velger like godt det samme som i 1 a). c) For å demonstrere terningkastinga: Terning = 1 Terning = 2 Terning = 1 Terning = 1 Terning = 1 Terning = 4 Terning = 1 Terning = 2 Terning = 6 Terning = 5 n f(x i ) i=1 (q.e.d.) Et telfeldig tall mellom a og b kan lages slik: `x=a+(b-a)*rand'. Med våre verdier: >a=-1; b=1; >x=a+(b-a)*rand x = -0.68356 >x=a+(b-a)*rand x = 0.36963 >x=a+(b-a)*rand x = -0.78574 >x=a+(b-a)*rand x = -0.26901 13
>x=a+(b-a)*rand x = -0.66438 >x=a+(b-a)*rand x = 0.76575 d) Metoden kan implementeres slik: % Skript som regner ut integralet av funksjonen gitt ved % IntFunk.m fra a til b ved Monte Carlo metoden % Input-parametre - a, b og n a=input('nedre integrasjonsgrense: '); b=input('oevre integrasjonsgrense: '); n=input('maksimalt antall trekk: '); % Setter summen til 0: S=0; % for-løkke som regner ut integral-tilnærminga % for alle trekninger fra og med 1 til og med n for i=1:n x=a+(b-a)*rand; % Trekker tilfeldig x i intervallet y=intfunk(x); % Bestemmer funksjonsverdi S=S+y; % Summerer IntEst(i)=(b-a)*S/i; % Bestemmer estimat av integralet % Plotter estimatet som funksjon av antall trekk plot(1:n,intest,'bx','linewidth',2) % Plotter også eksakt svar IntEksakt=2/3+exp(1)-exp(-1); hold on plot([1 n],[1 1]*IntEksakt,'k-') % Justerer opp skriftsstørrelsen på aksene hold off set(gca,'fontsize',20) xlabel('antall trekk') Vi har kalt skriptet `MonteCarlo.m'. Som vi ser, plotter det integralestimatet som funksjon av antall trekk. Når vi kjører det i Octave, ser det slik ut: > MonteCarlo Nedre integrasjonsgrense: -1 Oevre integrasjonsgrense: 1 Maksimalt antall trekk: 100 Selvsagt vil vi ikke få de samme sekvensene av x-verdier hver gang vi kjører skriptet. Derfor vil estimate gå mot integralet på ulike måter hver 14
Figur 5: Tre sekvenser med Monte Carlo estimat av integralet fra oppgave 1a). gang vi kjører skriptet. I gur 5 har vi vist hvordan tre ulike sekvenser konvergerer. Selv om disse resultatene ser ganske ulike ut for hver gang, ser alle tre ut til å konvergere mot riktig svar men ganske sakte. At konvergensen går sakte ser vi a tydeligere i gur 6. Først etter ere tusen trekk begynner kurva å plassere seg oppå verdien av integralet (på denne skalaen). Like fullt er Monte Carlo-integrering en svært nyttig og mye brukt teknikk ikke minst når man skal beregne er-dimensjonale integraler. (Det skal vi ikke gjøre i dette kurset.) 15
Figur 6: Konvergens plott for en lengre sekvens av en Monte Carlo-beregning. 16