Obligatorisk oppgave 1 a) Oppgaveteksten oppgir et vektorfelt f(x, y) F x, y = g x, y der f og g er oppgitt ved f x, y = x 3 3xy 1 og g x, y = y 3 + 3x y. Vi kan med dette regne ut Jacobimatrisen F x, y for vektorfeltet F x, y på følgende måte: F x, y = δf (x,y) δx δg (x,y) δx δf (x,y) δy δg (x,y) δy = δ(x 3 3xy 1) δx δ( y 3 +3x y ) δx δ(x 3 3xy 1) δy δ( y 3 +3x y ) δy F x, y = 3x 3y 6xy 6xy 3y + 3x b) Videre ønsker vi å tegne grafene f(x, y) og g(x, y) hver for seg og sammen. Dersom vi bruker Matlab til å gjøre dette skriver vi en kode: % create vectors of 100 points and transform into arrays a = linspace(-1.4, 1.4); b = linspace(-1.4, 1.4); [x, y] = meshgrid(a, b); f = x.^3-3*x.*y.^; g = -y.^3 + 3.*(x.^).*y; % plot f and g respectively figure(1); mesh(x,y,f); colorbar; title('f(x,y)') figure(); mesh(x,y,g); colorbar; title('g(x,y)') % plot f and g together figure(3); mesh(x,y,f); hold on; mesh(x,y,g); colorbar; title('f(x,y) and g(x,y)'); hold off Dersom vi kjører dette programmet i matlab vil vi få følgende visualiseringer. 1
Vi kan også vri bildene slik at vi ser grafene ovenfra. Vi kan begynne med å se på grafen f(x, y): Dersom vi vrir på grafen ser vi hvordan de forskjellige verdiene varierer punktvis, hvor fargene indikerer verdiene for hvert punkt.
Vi kan også gjøre det samme for g(x, y). På samme måte får vi også sett grafen g(x, y) ovenfra. 3
Da vi har gjort det for de enkelte grafene f x, y og g(x, y) kan vi gjøre det samme for figuren hvor figurene er tegnet sammen, men dersom vi vrir grafene på samme måte som vi gjorde for de enkelte grafene vil vi kun se de punktvise middelverdiene. Dette kan ses på figuren til høyre. Vi bør derfor vri grafen på en slik måte at det er mulig å se grafene fra en best mulig vinkel, slik at vi kan se hvordan grafene utvikler seg i forhold til hverandre. Vi kan vri på en måte slik at vi ser grafene fra en annen vinkel, hvor alle hjørnene syns. 4
c) Det er også mulig å tegne nivåkurver for grafene ved hjelp av kommandoen contour. Dersom vi skriver om programmet for dette vil vi få et program som tegner nivåkurvene. Det kan også være nyttig å bruke kommandoen clabel for å skrive på verdiene til den enkelte nivåkurve. a = linspace(-1.4, 1.4); b = linspace(-1.4, 1.4); [x, y] = meshgrid(a, b); f = x.^3-3.*x.*y.^; g = -y.^3 + 3.*(x.^).*y; figure(1); clabel(contour(x,y,f)); title('f(x,y)') figure(); clabel(contour(x,y,g)); title('g(x,y)') figure(3); clabel(contour(x,y,f)); hold on; clabel(contour(x,y,g)); title('f(x,y) and g(x,y)'); hold off Dersom vi kjører dette programmet i Matlab vil vi få tre bilder med nivåkurver. Et for hver enkelt grafem og et for de to grafene. Ut fra det siste bildet hvor nivåkurvene er lagt over hverandre kan det tenkes at F x, y = 0 der hvor nivåkurvene med verdi 0 møtes. Altså rundt punktet (0,0). 5
d) Vi kan finne de reelle løsningene for F x, y = 0 ved å se på likningssettet. F x, y = f(x, y) g x, y = x3 3xy 1 y 3 + 3x y = 0 0 Med dette får vi to likninger som skal løses. 1. x 3 3xy 1 = 0. y 3 + 3x y = 0 Først ønsker vi å finne et uttrykk for y: y 3 + 3x y = 0 3x y = y 3 y = 3x Med uttrykket for y finner vi en verdi for x: x 3 3xy 1 = 0 x 3 3x 3x 1 = 0 x 3 9x 3 = 1 8x 3 = 1 x 3 = 1 8 3 x = 1 8 x = 1 Deretter setter vi inn verdien vi har funnet for x for å finne y: 3x = y 3 1 = y 3 4 = y y = 3 4 y = ± 3 Vi har med dette funnet to løsninger, den tredje løsningen er funnet ved å sette inn for f(x, y) eller g(x, y). Ved å anta at x eller y er 0 for x 3 3xy 1 = 0 kan vi finne den tredje løsningen. y = 0 x = 0 x 3 3xy 1 = 0 x 3 3xy 1 = 0 x 3 1 = 0 1 0 3 x = 1 x = 1 x 0 Vi kan dobbeltsjekke ved å bruke den andre funksjonen g(x, y) som vi enda ikke har tatt i brukt. Dersom verdiene er riktige skal svaret bli 0. y 3 + 3x y = 0 3 + 3 1 0 = 0 + 0 = 0 6
Løsningene for F x, y = 0 er 1, ± 3 og 1, 0. Med andre ord: r 1 = 1, 3 r = 1, 3 r 3 = 1,0 e) Vi kan vise at F x = 0 dersom følgen x n n>0 konvergerer mot et punkt x der F (x) er inverterbar. x n+1 = x n F x n 1 F (x n ), n 1 x n+1 x n = F x n 1 F (x n ) x n+1 + x n = F x n 1 F (x n ) lim x n+1 + x n = lim n n x + x = F x 1 F (x) F x 0 = F x F x 1 F (x) 0 = I F (x) F x = 0 Vi har med dette vist at F x = 0. F x n 1 F x n f) Deretter ønsker vi å skrive et program som beregner grensen for denne følgen. Programmet har fire inputparametre: x 1, y 1, toleransen ε og det maksimale antall iterasjoner N. Videre vil utregningen foregå i en for -løkke som kjøres så lenge x n x n 1 ε er gyldig og n N. Programkoden for et slikt program kan se slik ut: % define function function [x,y,n]=newton(x1,y1,eps,n) x(1)=x1;y(1)=y1; u = [x(1); y(1)]; % handle data for n=1:n F = [u(1)^3-3*u(1)*u()^ - 1; -u()^3 + 3*u()*u(1)^]; jf = [3*u(1)^-3*u()^, -6*u(1)*u(); 6*u(1)*u(), -3*u()^+3*u(1)^]; inverse = inv(jf); unew = u - inverse*f; if (abs(unew-u)).^ <= eps break end u = unew; end % print result u, n g) Dersom vi kjører programmet med verdiene x 1, y 1 = 1,0, x 1, y 1 = 1,1 og x 1, y 1 = 1.1,0 med en passende ε får vi følgende output: 7
>> newton(-1,0,0.000000001,0); u = 1.0000 0 n = 9 >> newton(1,1,0.000000001,0); u = 1.0000-0.0000 n = 8 >> newton(1.1,0,0.000000001,0); u = 1.0000 0 n = 4 Med disse startverdiene finner vi én av tre løsninger. Dersom vi bruker andre verdier er det mulig å finne andre løsninger. Eksampelvis har vi en løsning dersom vi kjører programmet med startverdiene x 1, y 1 = 1, : >> newton(-1,,0.000000001,0); u = -0.5000 0.8660 n = 6 h) Da koden vi skal skrive tar utgangspunkt i det tidligere programmet ( newton.m ), kan det være en idé å modifisere på en slik måte at resultatet ikke blir printet for hver loop. Vi fjerner derfor de siste to linjene slik at den nye filen nå leses som: % define function function [x,y,n]=newton(x1,y1,eps,n) x(1)=x1;y(1)=y1; u = [x(1); y(1)]; % handle data for n=1:n F = [u(1)^3-3*u(1)*u()^ - 1; -u()^3 + 3*u()*u(1)^]; jf = [3*u(1)^-3*u()^, -6*u(1)*u(); 6*u(1)*u(), -3*u()^+3*u(1)^]; inverse = inv(jf); unew = u - inverse*f; if (abs(unew-u)).^ <= eps break end u = unew; end Ved å gjøre dette slipper vi at det nye programmet bruker tid på å presentere resultatene for hver loop. Det nye programmet som tar utgangspunkt i newton.m er følgende: e = 0.00001; N=40; x = zeros (801,801); y = zeros (801,801); n = zeros (801,801); h =.8/800; a = -1.4+ h *[0:800]; b = a; 8
for i=1:801; for j=1:801; [x(i,j),y(i,j),n(i,j)]=newton(a(i),b(j),e,n); end; end; figure(1); pcolor(a,b,n), shading flat; axis square; colorbar; title('antall iterasjoner'); figure(); pcolor(a,b,y), shading flat; axis square; colorbar; title ('De fire mengdene'); figure(3); pcolor(x,y,n), shading flat; axis square; colorbar; title ( x, y, n'); Dersom vi kjører dette programmet vil vi få følgende figurfiler: Her er det også mulig å se de tre reelle løsningene til F x : r 1 = 1, 3 r = 1, 3 r 3 = 1,0 Disse er markert med rødt på den mindre figuren til høyre. 9
De to andre figurene vi får er : Dersom vi prøver å plotte disse mengdene på et kvadrat som er mindre 0.1, 01 x 0.1,0.1, får vi et utsnitt av figuren på det respektive området. Vi kan endre verdiene på programmet vårt slik at det tas hensyn til et mindre kvadrat. Det nye programmet blir med dette: e = 0.00001; N=40; x = zeros (801,801); y = zeros (801,801); n = zeros (801,801); h = 0./800; 10
a = -0.1 + h *[0:800]; b = a; for i=1:801; for j=1:801; [x(i,j),y(i,j),n(i,j)]=newton(a(i),b(j),e,n); end; end; figure(1); pcolor(a,b,n), shading flat; axis square; colorbar; title('antall iterasjoner '); figure(); pcolor(a,b,y), shading flat; axis square; colorbar; title ('De fire mengdene '); figure(3); pcolor(x,y,n), shading flat; axis square; colorbar; title ( x, y, n'); På samme måte som vi fikk tre figurer da vi kjørte programmet første gangen, får vi også tre figurer nå. Vi kan se at de nye figurfilene er et utsnitt av området 0.1, 01 x 0.1,0.1. 11
Det andre figurbildet vi får er ganske likt det vi fikk første gangen vi kjørte programmet, men også her et utsnitt av området 0.1, 01 x 0.1,0.1. Det same gjelder for den tredje figuren, som også er et utsnitt på det samme området. 1