#Olk. n = x-osavälien lkm, p=n-1=sisäsolmujen lkm (x-suunnassa)
# kmax= aikaindeksin suurin arvo
n:=5:p:=n-1:kmax:=5:u:='u':h:=0.2:
# Alkuehdot:
for j from 0 to n do u[j,0]:=evalf(sin(j*Pi*h)) od;
# Reunaehdot:
for k from 0 to kmax do u[0,k]:=0: u[n,k]:=0 od:
#
# Muodostetaan kutakin k-arvoa kohti C-N-yhtälö (r=1)ja ratkaistaan samantien.
# Saadut arvot ovat tunnettuja seuraavassa vaiheessa. Tässä on hyvin
# kätevää käyttää assign-komentoa, joka muuttaa solve-komennolla saatavat
# yhtälöt sijoituslauseiksi (eli voidaan ajatella, että "=" muuttuu ":=" -
# operaatioksi)
#
for k from 0 to kmax do
for j from 1 to p do
yht[j,k]:=4*u[j,k+1]-u[j+1,k+1]-u[j-1,k+1]=u[j+1,k]+u[j-1,k]
od:
assign(solve({seq(yht[j,k],j=1..p)},{seq(u[j,k+1],j=1..p)}))
od:
# Järjestetään tulokset matriisiksi:
with(linalg):
umatr:=matrix(n+1,kmax+1,[seq(seq(u[j,k],j=0..n),k=0..kmax)]):
op(umatr);
Tästä on hyvä jatkaa. Differenssimenetelmä oli jo AV-tehtävissä, laitan
siitäkin ehkä kohta pienen ohjepätkän ... Tässähän on nyt r mukana parametrinä.
... Välillä se luvattu Poisson-koodi. LaplaceEq on jo
Maple koodeja-
sivulla
lag on
Maple koodeja-
sivulla
Tässä riittää tehdä interpolaatio-osuus.
Siinä voi tehdä jonkun osan lag-funktion avulla ja loput voi yhtä hyvin
tehdä valmiilla interp-funktiolla.
(Kyllä voi tehdä interp:llä kokonaankin.)
n:=5:h:=2/n:x5:=[seq(-1+k*h,k=0..n)]; # väli [-1,1], pituus = 2
# Sitten voit muutella n:ää.
f:=x->1/(1+25*x^2);
y5:=map(f,x5); # Tämä on kätevä ja yleispätevä tapa
p5:=interp(x5,y5,x);
plot({f(x),p5},x=-1..1);
Sitten vaan lisää polynomeja (n:ää muuttelemalla).
Jätetään siis PNS-osuus "vapaaehtoiseksi", kannattaa ainakin ensin
tehdä muita tehtäviä.
Huom! Erilaisiin funktioiden approksimointeihin on Maplessa kiintoisan näköinen pakkaus numapprox (kts. ?numapprox) Esim. pade on usein käytännössä hyödyllinen, se muodostaa rationaalifunktio- approksimaation.
# alkuviikon teht. 5 vastaus:
> u:=100*sin(Pi*x/80)*exp(-(1.158*Pi/80)^2*t)
# Pintapiirros:
> plot3d(u, x=0..80, t=0..500,axes=boxed, title=`tehtava 2`);
> # lämpötilaprofiileja: annetut ajanhetket t=0.1 jne käsitetään
> minuuteissa annetuiksi, muuten käyrät ovat turhan lähekkäin.
> Eli 0.1 <-> 6, 0.5 <-> 30 jne.
> plot({subs(t=0,u),subs(t=6,u),subs(t=30,u)},x=0..80):
Kuvaa voi kierrellä tarttumalla hiiren vasemmalla ja
sitten oikella valita "redraw"
Jos mieluummin teet display-tyylillä, niin mikäs siinä:
> p1:=plot(subs(t=0,u),x=0..80):
> p2:=plot(subs(t=6,u),x=0..80):
> ...
> with(plots):
> display({p1,p2,p3,p4,p5});
u:='u':n:='n'; # Varmuuden vuoksi
> osdy:=a^2*diff(u(x,t),x$2)=diff(u(x,t),t);
> eval(subs(u(x,t)=X(x)*T(t), osdy));
# Jaetaan puolittain (a^2*X(x)*T(t)):llä:
> separoitu:=simplify("/(a^2*X(x)*T(t)));
> xyht:=lhs(separoitu)=-p^2; # Vasen puoli = vakio (negat)
> tyht:=rhs(separoitu)=-p^2; # Oikea puoli = sama vakio
> xyht:=xyht*X(x); tyht:=a^2*tyht*T(t); # Kerrotaan nimittäjät pois
> xx:=rhs(dsolve(xyht,X(x)));
> dsolve(tyht,T(t)); tt:=rhs(");
> tt:=subs(_C1=1,tt); # (Vakio kertaa vakio) yhdistetään yhdeksi vakioksi.
# Katso, onko _C1 vai _C2, dsolve voi vaihdella
# järjestystä.
> # RE1 => ... RE2 => ..., sijoita nämä suoraan (Tässä ei ole mieltä "solvata")
> # sin:n 0-kohdat ovat Pi:n monikertoja, kuten tiedetään.
> xx:=subs({_C1=0,_C2=Bn,p=...},xx);
> tt:=subs(p=...,tt);
> uu:=xx*tt
# Sitten vielä alkuehto:
# Sinisarjan kertoimet:
> Bn:=simplify((2/l)*int(F*sin(n*Pi*x/l),x=0..l)); # Tässä F on alkuarvofunktio
> # Sijoita se F:n paikalle.
Huom! Maple ei havaitse, että n:n arvolla 1 tulee 0. No sen voi
ottaa huomioon alkamalla alempana olevan summauksen 2:sta
> l:=...;a:=...; # Sijoita annetut numeeriset arvot
> UU:=sum(uu,n=1..10); # tai sum:n sijasta add (vm. on kai nykyisin
# suositus)
# Otetaan siis 10 termiä (voit kokeilla muutakin)
> plot3d(UU, x=0..10, t=0..5,axes=boxed);
plot({subs(t=0,UU),xsubs(t=0.1,UU),subs(t=0.5,UU),subs(t=2,UU),subs(t=5,UU},
x=0..10):
Teht. 4
Painovirhe: p.o.: a2=... (eli potenssi 2 on pudonnut
tehtäväpaperista)
-----------------------------------------------------
with(inttrans) # V.4 # readlib(laplace) #V.3 alias(H=Heaviside,L=laplace,IL=invlaplace): ############ ### Muistathan vielä, jos matriiseja tarvitset: with(linalg):
Periaate:
Kehitetään oikea puoli r(x) Fourier-sarjaksi r(x)=r1(x)+r2(x)+... ja etsitään erikseen diff. yhtälöiden vp=r1(x), vp=r2(x) ,... erityisratkaisut käyttämällä yritteitä yr1,yr2,... Tällöin yr1+yr2+... on yhtälön vp=r1(x)+r2(x)+... ratkaisu.
Kannattaa käsitellä vasen puoli (vp) ja oikea puoli (op) erikseen.
with(inttrans):alias(L=laplace,IL=invlaplace,H=Heaviside): vp:=R*diff(i(t),t)+(1/C)*i(t); Lvp:=L(vp,t,s); Lvp:=subs(i(0)=0,L(vp,t,s));Oikea puoli on helpointa muuntaa suoraan määritelmän perusteella:
Lop:=int((e0/epsilon)*exp(-s*t),t=0..epsilon); # Lasketaan suoraan L-muunnoksen
# määritelmästä.
Ldy:=Lvp=Lop # Laplace-muunnettu yhtälö
II:=solve(Ldy,L(i(t),t,s));
Huom: Maple ei Laplace-muunna H(t-a):ta , ellei se tiedä
a:n merkkiä. Kokeile vaikka
assume(a>0):L(H(t-a),t,s);
assume(epsilon>0);# Tätä tarvitaan, jotta vastaavasti käänteismuunnokset
# jatkossa onnistuisivat.
a:='a': # Tällä pääsee eroon "assume-ominaisuudesta".
Otetaan vielä pelkät inputit (valikoiden/modifioiden)
Eulerin Fourier-kerroinkaavat:
## Jätetään Maple-prompti pois, silloin voi leikata/liimata kokonaisuuden.
a0:=(1/(2*l))*int(f(x),x=-l..l); ## Tässä ei ole mitään olennaista
an:=(1/l)*int(f(x)*cos(n*Pi*x/l),x=-l..l); # etua a[n]-tyylistä, se
bn:=(1/l)*int(f(x)*sin(n*Pi*x/l),x=-l..l); # voi pikemminkin olla
# harhaanjohtava.
## Nyt voidaan laskea mitä esimerkkejä halutaan. Vaikkapa harj.9 AV teht. 6:
f:=x->x;
assume(n,integer):
a0;an;
bn; # V.4 osaa käyttää integer-tietoa, V.3 ei osaa - no tehdään sitten itse:
bn:=subs({sin(n*Pi)=0,cos(n*Pi)=(-1)^n,l=Pi},bn);
s:=seq(sum(bn*sin(n*x),n=1..N),N=1..5);
plot({x,s},x=-Pi..Pi);
## Jos halutaan laskea jokin erillinen osasumma vaikka suurella n:llä
## Gibbsin ilmiön havainnollistamiseksi tai muuten, niin luonnollisesti:
s50:=sum(bn*sin(n*x),n=1..50):plot({x,s50},x=-Pi..Pi);
plot(x-s50,x=-Pi+.1..Pi-.1); #Erotus,mutta ei ihan "hyppypisteeseen" saakka
exp -funktio lasketaan exp(t) eikä
e^t. Maple ei tunne symbolia e (ellei tehdä e:=exp(1),
mitä en suosittele (Aivan sama pätee Matlabiin nähden.)
> with(inttrans); #Versiossa V.4: > readlib(laplace);#Versiossa V.3: > alias(H=Heaviside,L=laplace,IL=invlaplace); # Tämä on aika mukavaMuista: Kun teet
laplace(f,t,s) ja invlaplace(F,s,t) (tai tällä
aliasoinnilla L(f,t,s) ..., niin muuttujien järjestys on tärkeä
(ja yleensä se on juuri tämä).
Luentoesimerkkejä L-muunnoksen käytöstä
dyht:=diff(y(t),t)=sin(t)-y(t)/2;Kannattaa myös (ja ehkä ihan ensin) ratkaista dsolve:lla ja piirtää siitä saatava käyräparvi ihan normaalilla plot:lla:
ratk:=dsolve(dyht,y(t));
Y:=rhs(ratk); # dsolve palauttaa yhtälön, otetaan sen oikea puoli (rhs).
Y:=subs(_C1=c,Y); # helpompi symboli vakiolle
parvi:=seq(Y,c=-10..10): # Voit kokeilla eri c:n arvoja ja
plot({parvi},t=0..10); # aikaskaalaa (huom: tämä vaikuttaa hyvin
# olennaisesti kuvaan)
Malliksi tehtävä (alkuv.) 4a "luentotyylillä"
>
> # Teht. 4
>
> with(linalg):
> A:=matrix(2,2,[3,-1,-1,3]);
> esys:=eigenvects(A);
> v1:=op(esys[1][3]);v2:=op(esys[2][3]);
> lam:=eigenvals(A);
> y:=evalm(c1*exp(lam[2]*t)*v1+c2*exp(lam[1]*t)*v2);
> # Katsotaan pääakselikoordinaatistossa:
> z1:=exp(lam[2]*t);z2:=exp(lam[1]*t);
> # z2=K*z1^2
> # Piirretään ensin z1-z2-koordinaatistoon (sanotaan (u,v))
>
> v:=seq(K*u^2,K=-10..10);
> plot({v},u=-2..2);
> op(v1);op(v2);
> y1aks:=plot([[0,0],convert(v1,list)]):y2aks:=plot([[0,0],convert(v2,list)]):
> with(plots):
> parvi:=seq(seq([y[1],y[2]],c1=-5..5),c2=-5..5):
> varit:=[aquamarine, black , blue , navy, coral, cyan , \
> brown , gold , green , gray , grey , khaki ,\
> magenta , maroon, orange , pink , plum ,red,\
> sienna , tan , turquoise, violet, wheat ,white ,yellow];
>
> ## pp:=seq(plot([op(parvi[i]),t=-1.. .4],color=varit[i]),i=1..25):
> pp:=seq(plot([op(parvi[i]),t=-1.. .4],y1=-5..5,y2=-5..5,color=varit[i]),i=1..25):
> display({pp,y1aks,y2aks});
dsolve({dy,y(0)=0,D(y)(0)=1},y(t));
(eikä siis y(x) )
A:=randmatrix(20,20);
A:=convert(op(A),float); # jotta eigenvals laskisi numeerisesti
eig:=eigenvals(A);
c:=seq([Re(eig[i]),Im(eig[i])],i=1..20); # [x1,y1],[x2,y2],...
plot([c],style=point); # Piirtää listassa olevat pisteet
r:=max(op(map(abs,[eig]))); # spektraalisäde
-------------------
plot([r*cos(t),r*sin(t),t=0..2*Pi]): # parametrikäyrien syntaksi
plot([c],x=-100..100,y=-100.100,style=point): # x-ja y-välit kannattaa antaa
# ainakin Re- tai Im-akselilla
# sijaitsevia pistejoukkoja piirrettäessä
Kuvat saadaan samaan näin:
with(plots): # Ladataan lisägrafiikkapakkaus, jossa mm. display-funktio
p1:=plot([r*cos(t),r*sin(t),t=0..2*Pi]): # muista kaksoispiste, eikä
p2:=plot([c],x=-100..100,y=-100.100,style=point): # puolipistettä (tai kärsi)
display({p1,p2}):
> with(linalg): # Aina, kun käsitellään matriiseja > A:=matrix([[rivi1],[rivi2],...[rivim]]); > ## tai > A:=matrix(3,4,[a11,a12,a13,a14,a21,a22,...,a34]); # koko ja sitten data > # pötkönä vaakarivijärjestyksessä. > b:=vector([b1,b2,b3]); > Ab:=augment(A,b); # Vektori liitetään matriisin perään. > # Voidaan liittää myös matriisi, kuten teht. 5: > Id:=diag(1,1,1); AI:=augment(A,Id);
> osa:=submatrix(A,i1..i2,j1..j2) > osa2:=submatrix(A,[i1,i2,i3],[j1,j2,j3,j4]); # Sieltä täältä poiminta > stack(A,b) # alle liittäminen (näissä tehtävissä ei tarvita)
GramSchmidt ei normeeraa. Vektorin euklidinen normi voidaan
laskea komennolle norm(v,2) Helpommalla pääsee käyttämällä
komentoa normalize , joka jakaa vektorin normillaan
(euklidisella).
Miten sitten operoidaan listaan vektoreita?
normalize ei suoraan sovella itseään alkioittain. Tehdään se yleispätevällä
komennolla map
Esim:
> lista:=[a,b,c];
lista := [a, b, c]
------------------------------------------------------------------------------
> map(f,lista);
[f(a), f(b), f(c)]
>
Yleisesti funktio (tässä f) "mapataan" tietorakenteen osille, kuten listan
alkioille.
Tässä tapauksessa
> gslista:=GramSchmidt([v1,v2,v3]); # ensin tietysti v1:=...,v2:=...,v3:=...; > ortoNORMAALIkanta:=map(normalize,gslista); # kaunista!Huom: Jos kutsuttaisiin
GramSchmidt({v1,v2,v3]}); , niin
Maple käsittelisi inputargumenttia vektorien joukkona , jolloin
järjestyksellä ei olisi merkitystä. Maple päättäisi itse, missä järjestyksessä
tehdään. Ortonormalisointiprosessin tulos riippuu järjestyksestä.
Siis, kun haluat itse päättää järjestyksen, niin käytä listaa , eli hakasulkuja [...] .