BYFE/EMFE 1000, 2012/2013 Numerikkoppgaver uke 35 Oppgave 1 Halveringsmetoden a) x = cos x x cos x = 0 eller f(x) = 0 med f(x) = x cos x b) f(0) = 0 cos 0 = 1 < 0 og f(π/2) = π/2 cos(π/2) = π/2 > 0. f(x) er sett saman av x og cos x, som begge er kontinuerlege på heile R. Derfor er også f(x) kontinuerleg på heile R (inkludert intevallet [0, π/2]). Derfor må f ha minst ett nullpunkt på intevallet ved skjæringssetninga (se s. 97 i Kalkulus). c) Slik kan det se ut når vi leker oss i Octave: octave-3.2.4.exe:64> a=0 a = 0 octave-3.2.4.exe:65> b=pi/2 b = 1.5708 octave-3.2.4.exe:66> c=(a+b)/2 c = 0.78540 octave-3.2.4.exe:67> fc=c-cos(c) fc = 0.078291 octave-3.2.4.exe:68> b=c b = 0.78540 octave-3.2.4.exe:69> c=(a+b)/2 c = 0.39270 octave-3.2.4.exe:70> fc=c-cos(c) fc = -0.53118 octave-3.2.4.exe:71> a=c a = 0.39270 octave-3.2.4.exe:72> c=(a+b)/2 c = 0.58905 octave-3.2.4.exe:73> fc=c-cos(c) fc = -0.24242 octave-3.2.4.exe:74> a=c a = 0.58905 octave-3.2.4.exe:75> c=(a+b)/2 1
c = 0.68722 octave-3.2.4.exe:76> fc=c-cos(c) fc = -0.085787 octave-3.2.4.exe:77> a=c a = 0.68722 octave-3.2.4.exe:78> c=(a+b)/2 c = 0.73631 octave-3.2.4.exe:79> fc=c-cos(c) fc = -0.0046403 octave-3.2.4.exe:80> a=c a = 0.73631 octave-3.2.4.exe:81> c=(a+b)/2 c = 0.76085 octave-3.2.4.exe:82> fc=c-cos(c) fc = 0.036607 octave-3.2.4.exe:83> b=c b = 0.76085 octave-3.2.4.exe:85> c=(a+b)/2 c = 0.74858 octave-3.2.4.exe:86> fc=c-cos(c) fc = 0.015928 octave-3.2.4.exe:87> b=c b = 0.74858 octave-3.2.4.exe:88> c=(a+b)/2 c = 0.74245 octave-3.2.4.exe:89> fc=c-cos(c) fc = 0.0056301 octave-3.2.4.exe:90> b=c b = 0.74245 octave-3.2.4.exe:91> fc=c-cos(c) fc = 0.0056301 octave-3.2.4.exe:92> c=(a+b)/2 c = 0.73938 octave-3.2.4.exe:93> fc=c-cos(c) fc = 4.9142e-004 octave-3.2.4.exe:94> b=c b = 0.73938 octave-3.2.4.exe:95> c=(a+b)/2 c = 0.73784 octave-3.2.4.exe:96> fc=c-cos(c) fc = -0.0020753 octave-3.2.4.exe:97> a=c a = 0.73784 octave-3.2.4.exe:98> c=(a+b)/2 c = 0.73861 -Kanskje ikke så spenne lesning. Men forhåpentligvis blir systematikken 2
synlig. Vi starter med å sette venstre grense (a=0) og høgre grense (b=pi/2). Vi vet alt at f(a) er negativ og f(b) er positiv. Så regner vi ut mindpunktet (c) og nner funksjonsverdien i dette punktet, f(c). Dersom f(c) er negativ, kan vi ytte venstre-grensa til c (a=c) og regne ut det nye midpunktet (c). Så regner vi ut den nye f(c). Dersom denne er positiv, kan vi ytte høgre-grensa til midpunktet (b=c). Slik kan vi holde på til avstanden mellom a og b blir veldig liten og så velge det nye midpunktet til løsning. Her ser vi ut til å nne løsninga x 0.7386. Vi kan kontrollere: 0.7386 cos 0.8386 = 8.1 10 4, som jo er ganske nær 0. Skjemaet, eller algoritmen, vi har fulgt kan skrives slik: Bestem a og b slik at f(a) og f(b) har motsatt fortegn Gjenta følge så lenge a-b er større enn en viss størrelse: Finn midpunktet c, c=(a+b)/2 Rekn ut f(c) Dersom f(a) og f(c) har samme fortegn: La c bli din nye a Dersom f(a) og f(c) ikke har samme fortegn: La c bli din nye b Når a-b er liten nok, finner vi ei tilnærma løsning som (a+b)/2 d) Vi kjører skriptet: octave-3.2.4.exe:113> HalveringsEksempel NullPunkt = 0.73911 Gikk ikke dette raskt? Vi plotter grafen til f(x) sammen med nullpunktskandidaten vår: octave-3.2.4.exe:114> x=0:.1:pi/2; octave-3.2.4.exe:115> plot(x,x-cos(x)) octave-3.2.4.exe:116> hold on octave-3.2.4.exe:117> plot([0 pi/2],[0 0],'k-') octave-3.2.4.exe:118> plot(nullpunkt,0,'ro') octave-3.2.4.exe:119> hold off Resultatet er vist i gur 1. Svaret kan gjøres mer nøyaktig ved å la variabelen Pres bli a mindre. For å løse b-oppgava i 2.5: 9, gjør rer vi skrptet (og lagrer det): a=0; b=1; Pres=1e-4; while abs(a-b)>pres fa=a^5+3*a-2; 3
Figur 1: Grafen til f(x) = x cos x for x [0, π/2] sammen med numerisk utregnet nullpunkt (rød sirkel). fb=b^5+3*b-2; c=(a+b)/2; fc=c^5+3*c-2; if (fa*fc<0) b=c; else a=c; NullPunkt=(a+b)/2 Når vi nå skriver HalveringsEksempel i Octave, får vi svaret x 0.6328. e) Slik kan skriptet kommenteres: % Enkel implementering av halveringsmetoden. % Løser likninga x-cos(x)=0. % Fikserer grensene og bestemmer hvor nøyaktig løsninga skal være % Det er viktig at a og b blir valgt slik at funksjonen har ulike % fortegn i disse punktene a=0; b=1; Pres=1e-4; % While-løkke som gjentar seg så lenge intervallet mellom a og b har lengde 4
% større enn Pres, som ble fiksert overfor while abs(a-b)>pres fa=a-cos(a); % Regner ut (oppdaterer) f(a) fb=b-cos(b); % Regner ut (oppdaterer) f(b) c=(a+b)/2; % Finner midpunktet c fc=c-cos(c); % Renger ut f(c) if (fa*fc<0) % Hvis f(a) og f(c) har motsatt fortegn... b=c; %... skal vår nye b være midpunktet c else % Hvis ikke... a=c; %... skal vår nye a være midpunktet c % Avslutter if-satsen % Avslutter while-løkka NullPunkt=(a+b)/2 % Skriver svaret til skjerm Forsøk å gjøre det til en vane å alltid kommentere skriptene dine. Merk at det er egentlig ikke nødvig å oppdatere f(a) og f(b); både f(a) og f(b) skal ha det samme fortegnet hele tida. Derfor ville dette ha vært ei litt mer eektiv implementering: a=0; b=1; fa=a-cos(a); fb=b-cos(b); Pres=1e-4; while abs(a-b)>pres c=(a+b)/2; fc=c-cos(c); if (fa*fc<0) b=c; else a=c; NullPunkt=(a+b)/2 (En foreleser lærer også så lenge han lever...) Oppgave 2 for-løkker a) I Octave ser det slik ut: octave-3.2.4.exe:123> for n=1:5 > n > 5
n = 1 n = 2 n = 3 n = 4 n = 5 Her har tydeligvis alle heltallene fra og med 1 til og med 5, ett etter ett, blitt skrevet til skjerm. Variabelen n har tydeligvis hatt disse verdiene i tur og orden. b), c) Vi tar utgangspunkt i funksjonsla DeltForskrift.m fra settet for uke 34. Vi rer navnet på funksjonsla som refereres til og kjører skriptet xvektor=0:1e-2:4; N=length(xVektor); for indeks=1:n x=xvektor(indeks); yvektor(indeks)=deltforskrift(x); plot(xvektor,yvektor) Her har vi også justert noe på intevallet funksjonen plottes over og valgt en mindre steglengde. På den måten blir diskontinuiteten for x = 2 tydeligere. Merk at du må være i samme katalog som funksjonsla DeltForskrift.m og skriptet Plotting.m for å kjøre det. Grafen vi får når vi skriver Plotting, er vist i gur 2. Antall element i xvektor og yvektor kan nnes slik: octave-3.2.4.exe:18> length(xvektor) ans = 401 octave-3.2.4.exe:19> length(yvektor) ans = 401 Dersom ikke disse hadde vært like, ville ikkje det gitt mening å skrive kommandoen plot(xvektor,yvektor); der må være like mange x- og y- verdier. d) Slik kan vi kommentere skriptet: % Skript som plotter funksjonen gitt i funksjonsfila Funk.m % Tilordner x-vektoren, som bestemmer intervallet det skal plottes over % og oppløsninga xvektor=0:.1:10; % N er antall element i x-vektoren N=length(xVektor); 6
Figur 2: Plot av funksjonen fra oppgave 5 b) i settet fra uke 34. Merk at siden Octave setter inn linjer mellom hvert punkt, kan det se ut som funksjonen er kontinuerlig. Men det er den ikke. % For-løkke som kjøres N ganger. Variabelen indeks starter på 1 og øker % med én for hver gang opp til og med N for indeks=1:n x=xvektor(indeks); % x-verdien skal være element nr. indeks i xvektor yvektor(indeks)=funk(x); % element nr. indeks i yvektor skal vere Funk(x) % Slutt på for-løkke plot(xvektor,yvektor) % Lag plott 7