Jyrkimmän laskeuman menetelmä

The method of Steepest Descent, gradienttimenetelmä

3.4.2002

..L/SD.mws

> restart:

Warning, the name changecoords has been redefined

> with(LinearAlgebra):with(linalg):with(plottools): with(plots):setoptions3d(axes=boxed,orientation=[-30,50]):

Warning, the previous binding of the name GramSchmidt has been removed and it now has an assigned value

Warning, the protected names norm and trace have been redefined and unprotected

Warning, the name arrow has been redefined

Warning, the name arrow has been redefined

> V2L:=vek->convert(vek,list):

Steepest Descent

Pieni kiusa: Joudutaan konvertoimaan Vectorin ja listan välillä. Sitä varten on yllä V2L .

Eräs mahdollisuus, jota päädyin suosittelemaan myös harj8 tehtävissä on määritellä erikseen vektorimuuttujan funktio ja muuttujajonon funktio. (Matemaattisesti nämä ovat samoja asioita, mutta Maplen kannalta edellisellä on vain yksi (vektori)argumentti ja jälkimmäisellä useita (skalaari)argumentteja.)

Tämä näkyy toimivan oikein hienosti.

> f:=(x,y)->4*x^2-4*x*y+2*y^2;

f := proc (x, y) options operator, arrow; 4*x^2-4*y...

> fv:=unapply(f(X[1],X[2]),X);

fv := proc (X) options operator, arrow; 4*X[1]^2-4*...

> fv(X);
fv:=X->4*X[1]^ 2-4*X[1]*X[2]+2*X[2]^2; # X saa olla vektori tai lista.

4*X[1]^2-4*X[2]*X[1]+2*X[2]^2

fv := proc (X) options operator, arrow; 4*X[1]^2-4*...

Gradientti:

> g:=[D[1](f),D[2](f)];
gv:=v->g(v[1],v[2]); # Tässä vektorargumenttiimuoto.

g := [proc (x, y) options operator, arrow; 8*x-4*y ...

gv := proc (v) options operator, arrow; g(v[1],v[2]...

> g(x,y); g(1,2);gv([1,2]); gv(<1,2>); # Toimii, kuten pitää.

[8*x-4*y, -4*x+4*y]

[0, 4]

[0, 4]

[0, 4]

Ryhdytään iteroimaan. Kerätään pisteet indeksoituun (taulukko)muuttujaan X.

>

>

> X[0]:=<1,-2>;

X[0] := _rtable[135697256]

> u:=-Normalize(Vector(gv(X[0])));

u := _rtable[136102900]

> evalm(X[0]+t*u);

vector([-t+1, 3/4*t-2])

Tässä on suoran parametriesitys etsintäsuunnalla u. Parametri t > 0.

> phi:=t->simplify(fv(evalm(X[0]+t*u))); # Nyt on kätevää, kun meillä on vektorimuoto!

phi := proc (t) options operator, arrow; simplify(f...

> phi(t);

65/8*t^2-25*t+20

> tmin:=solve(diff(phi(t)=0,t));

tmin := 20/13

> X[1]:=X[0]+tmin*u;

X[1] := _rtable[135974792]

Näin saimme ensimmäisen SD-askeleen valmiiksi. Nyt voimme tehdä pienen for-silmukan.

Huom! Ennekuin testaat, talleta ws. Kokeile aina aluksi pienellä N:n arvolla.

> X:='X':X[0]:=<1,-2>:

> N:=5:for i to N do u:=-Normalize(Vector(gv(X[i-1])));
phi:=t->simplify(fv(evalm(X[i-1]+t*u)));
tmin:=solve(diff(phi(t)=0,t));
X[i]:=(evalm(X[i-1]+tmin*u));
od:

> map(print,[seq(X[i],i=0..5)]);

_rtable[135974992]

vector([-7/13, -11/13])

vector([1/26, -1/13])

vector([-7/338, -11/338])

vector([1/676, -1/338])

vector([-7/8788, -11/8788])

[]

> XX:=Matrix(map(V2L,[seq(X[i],i=0..5)]));

XX := _rtable[135359260]

> reitti:=convert(XX,listlist);

reitti := [[1, -2], [-7/13, -11/13], [1/26, -1/13],...

¨Tai suoraan ilman Matrix-vaihetta:

> #map(V2L,[seq(X[i],i=0..5)]); # Matrix välivaihe ehkä auttaa näkemään paremmin.

> reitinkuva:=plot(reitti,color=blue,scaling=constrained):

> korkeusparvi:=contourplot(f(x,y),x=-1..2,y=-1..3):

> reittikorkeudet:=contourplot(f(x,y),x=-1..2,y=-1..1.6,contours=map(fv,reitti),grid=[40,40]):

> display(reitinkuva,korkeusparvi,reittikorkeudet);

[Maple Plot]

>

> display(%,view=[-0.6..0.4,-1..0.3]);

[Maple Plot]

>

>

> map(V2L,[seq(X[i],i=0..5)]);

[[1, -2], [-7/13, -11/13], [1/26, -1/13], [-7/338, ...

>

Kokoamme proseduureiksi

Maple-ohjelmat kannattaa yleensä kirjoittaa tekstitiedostoon, joka luetaan Mapleen:

Muuta hakemistopolku tarpeen mukaan/vaihda kommentti.

> #read("c:\\opetus\\maple\\v202.mpl"):
read("/home/www/public_html/opetus/v/maple/v202.mpl");
#read("/p/edu/mat-1.414/maple/v202.mpl"); # Tämä toimii ATK-keskuksen UNIX:ssa.

Yllä olevat interaktiiviset komennot on koottu proc:ksi. Lisäpiirteenä on interpolointi 2. asteen polynomilla kussakin

1-ulotteisessa viivahaussa.

> #op(SD2); # Poista alkukommentti, niin näet koodin.

Hyödyllisiä havainnollistukseen ovat nämä, jälkimmäinen myös numeroi, mikä on tarpeen usein erit. Newtonin menetelmässä.

> #op(piirrareitti);

> #op(piirrareittin);

> with(LinearAlgebra):with(plots):

>

Warning, the assigned name GramSchmidt now has a global binding

> f:=(x,y)->exp(x)*(4*x^2+2*y^2+4*x*y+2*y+1);

f := proc (x, y) options operator, arrow; exp(x)*(4...

> fv:=xx->f(xx[1],xx[2]);

fv := proc (xx) options operator, arrow; f(xx[1],xx...

> reitti:=SD2(f,[0,0],10);

reitti := [[0, 0], [-.1280701802, -.2561403605], [....
reitti := [[0, 0], [-.1280701802, -.2561403605], [....
reitti := [[0, 0], [-.1280701802, -.2561403605], [....

> farvot:=map(fv,reitti);

farvot := [1, .7176976791, .4730896205, .3272026144...
farvot := [1, .7176976791, .4730896205, .3272026144...

> piirrareitti(reitti,-1..1,-1..1,scaling=constrained);

[Maple Plot]

> contourplot(f(x,y),x=-1..1,y=-1..1,contours=farvot);

[Maple Plot]

> display([%%,%]);

[Maple Plot]

>

>