Numeerinen ja symbolinen laskenta
Harjoitus 6

Heikki Apiola ja Mika Juntunen

Alustukset

>    restart:   

>    alustukset:=proc()
local polku,ns05;
#ns05:="/p/edu/mat-1.192/ns05.mpl");
#ns05:="c:/usr/heikki/numsym05/maple/ns05.mpl";
ns05:="/home/apiola/opetus/numsym/05/maple/ns05.mpl";
#polku:="c:/MATLAB6p1/work/":
#polku:="/tmp/":
#datafile:=cat(polku,"hab.txt");
with(plots):setoptions3d(orientation=[-30,50],axes=box):
read(ns05);
#with(LinearAlgebra);
end proc:

>    alustukset();

Tämä kannattaa sijoittaa eri työarkille, niin on tehty:   H/alustukset.mws

Tällöin on helppo käydä restart :n jälkeen napsauttamassa alustukset päälle.

Tehtävä 1

(a)

>    restart:   # Nyt on käytävä määrittelemässä alustukset();

>    bn:=2/L*Int(f(x)*sin(n*Pi*x/L),x=0..L);

bn := 2/L*Int(f(x)*sin(n*Pi*x/L),x = 0 .. L)

>    L:=Pi; # asetetaan L=Pi
bn;

L := Pi

2/Pi*Int(f(x)*sin(n*x),x = 0 .. Pi)

Osittaisintegroidaan

>    u:=f(x);
dv:=sin(n*x);

u := f(x)

dv := sin(n*x)

>    du:=Diff(f(x),x);
v:=int(dv,x);

du := Diff(f(x),x)

v := -1/n*cos(n*x)

>    Int(u*dv,x=0..L)
=-Int(du*v,x=0..L) + subs(x=Pi,u*v) -subs(x=0,u*v);

Int(f(x)*sin(n*x),x = 0 .. Pi) = -Int(-Diff(f(x),x)/n*cos(n*x),x = 0 .. Pi)-f(Pi)/n*cos(n*Pi)+f(0)/n*cos(0)

Osittaisintegroidaan uudestaan

>    u2:=Diff(f(x),x); dv2:=cos(n*x)/n;

u2 := Diff(f(x),x)

dv2 := 1/n*cos(n*x)

>    du2:=Diff(u2,x); v2:=int(dv2,x);

du2 := Diff(f(x),`$`(x,2))

v2 := 1/n^2*sin(n*x)

>    Int(u*dv,x=0..L)
=-Int(du2*v2,x=0..L) +subs(x=Pi,u2*v2) -subs(x=0,u2*v2)
+subs(x=Pi,u*v) -subs(x=0,u*v);

Int(f(x)*sin(n*x),x = 0 .. Pi) = -Int(Diff(f(x),`$`(x,2))/n^2*sin(n*x),x = 0 .. Pi)+Diff(f(Pi),Pi)/n^2*sin(n*Pi)-Diff(f(0),0)/n^2*sin(0)-f(Pi)/n*cos(n*Pi)+f(0)/n*cos(0)

>    Int(u*dv,x=0..L)
=-Int(du2*v2,x=0..L) +subs(x=Pi,u*v) +f(0)/n;

Int(f(x)*sin(n*x),x = 0 .. Pi) = -Int(Diff(f(x),`$`(x,2))/n^2*sin(n*x),x = 0 .. Pi)-f(Pi)/n*cos(n*Pi)+f(0)/n

Koska parittoman jatkuvan funktion on oltava 0:ssa 0 ja samoin 2L-jaksoisen parittoman jatkuvan on oltava L:ssä 0, niin sijoitustermit häviävät.

Olkoon M = max(abs(diff(f(x),x,x))) . M on äärellinen, koska `in`(f,C^2)  

.

 Siis    b[n] < 2/pi*M*pi/(n^2)

eli 2*M/(n^2) = O(1/(n^2)) .

                   

Tämä on varmaankin vaivattomampi laskea käsin, mutta harjoiteltiinpa samalla hieman Maple-tekstinkäsittelyä.

(Tähän ei kannata paljon panostaa, mutta tekstimuotoisen Maple-syntaksia noudattavan lausekkeen voi helposti muuntaa matemaattiseen muotoon maalaamalla ja painamalla maalatun päällä hiiren oikeaa, josta -> convert -> standard math.)

Esim yllä oleva C^2:een kuuluminen kirjoitettiin näin: f in C^2 , joka hiirellä konvertoitiin.

(b)

>    restart:

>    alustukset();

>    #read("/p/edu/mat-1.192/ns05.mpl");
#read("c:/usr/heikki/numsym05/maple/ns05.mpl");
#read("/home/apiola/opetus/numsym/05/maple/ns05.mpl");

>    bn:=2/L*Int(f(x)*sin(n*Pi*x/L),x=0..L);

bn := 2/L*Int(f(x)*sin(n*Pi*x/L),x = 0 .. L)

>    f:=x->piecewise(x<L/2,x,x>L/2,L-x);

f := proc (x) options operator, arrow; piecewise(x < 1/2*L,x,1/2*L < x,L-x) end proc

>    kuva1:=plot(subs(L=2,f(x)),x=0..2,color=blue):
kuva2:=plot(subs(L=2,D(f)(x)),x=0..2,color=black):
display(kuva1,kuva2);

[Maple Plot]

>    bn:=2/L*(int(x*sin(n*Pi*x/L),x=0..L/2)+int((L-x)*sin(n*Pi*x/L),x=L/2..L));

bn := 2/L*(-1/2*L^2*(-2*sin(1/2*n*Pi)+n*Pi*cos(1/2*n*Pi))/n^2/Pi^2+1/2*L^2*(-2*sin(n*Pi)+n*Pi*cos(1/2*n*Pi)+2*sin(1/2*n*Pi))/n^2/Pi^2)

>    b[n]:=trigsiev(bn,n); abs('b[n]') < subs(sin(n*Pi/2)=1,%);
#Tekstinkäisttelyä.  

b[n] := 4*L*sin(1/2*n*Pi)/n^2/Pi^2

abs(b[n]) < 4*L/n^2/Pi^2

(c)

>    restart: #alustukset(); # eri ws:llä

Järkevintä olisi laittaa tiedoston nimi polkuineen sinSkertoimet -funktion argumentiksi, jolloin polkumuutokset tehtäisiin yllä olevissa alustuskomennoissa, eikä tarvitsisi kajota funktion koodiin. Itse asiassa näin on tehty , mutta vanhatkin funktiot ovat jäljellä.

Uusi funktio on nimeltään sinikertoimet .

Yllä olevaa voi käyttää hyödyksi nyt haluttaessa lukea Mapleen dataa. Tyypillisesti on tehty raskas laskentaoperaatio,

vaikka 1000 sinisarjan kerrointa. Kun niitä tarvitaan uudestaan, kannattaa lukea tiedostosta:

kertoimet:=readdata(datafile,1):

Jos tarvitaan vain Maplesta Mapleen, niin voidaan käyttää  save/read-yhdistelmää, kts alla.

>    N:=100;
L:=10;
f:=x->sin(Pi*x/5)*exp(x/2);

N := 100

L := 10

f := proc (x) options operator, arrow; sin(1/5*Pi*x)*exp(1/2*x) end proc

>    plot(ParitonJ(f),-10..10);Jpf:=JJ(ParitonJ(f),-10..10);

[Maple Plot]

Jpf := proc (x::algebraic) local y; y := floor(1/20*x+1/2); proc (x) options operator, arrow; piecewise(0 < x,sin(1/5*Pi*x)*exp(1/2*x),x < 0,sin(1/5*Pi*x)*exp(-1/2*x)) end proc(x-20*y) end proc
Jpf := proc (x::algebraic) local y; y := floor(1/20*x+1/2); proc (x) options operator, arrow; piecewise(0 < x,sin(1/5*Pi*x)*exp(1/2*x),x < 0,sin(1/5*Pi*x)*exp(-1/2*x)) end proc(x-20*y) end proc
Jpf := proc (x::algebraic) local y; y := floor(1/20*x+1/2); proc (x) options operator, arrow; piecewise(0 < x,sin(1/5*Pi*x)*exp(1/2*x),x < 0,sin(1/5*Pi*x)*exp(-1/2*x)) end proc(x-20*y) end proc
Jpf := proc (x::algebraic) local y; y := floor(1/20*x+1/2); proc (x) options operator, arrow; piecewise(0 < x,sin(1/5*Pi*x)*exp(1/2*x),x < 0,sin(1/5*Pi*x)*exp(-1/2*x)) end proc(x-20*y) end proc

>    #plot(ParitonJ(f),-0.1..0.1);

>    plot(Jpf,-20..20);plot(Jpf,-2..2);

[Maple Plot]

[Maple Plot]

>    D(ParitonJ(f));

proc (x) options operator, arrow; piecewise(x <= 0,1/5*cos(1/5*Pi*x)*Pi*exp(-1/2*x)-1/2*sin(1/5*Pi*x)*exp(-1/2*x),0 < x,1/5*cos(1/5*Pi*x)*Pi*exp(1/2*x)+1/2*sin(1/5*Pi*x)*exp(1/2*x)) end proc

>    plot(D(ParitonJ(f)),-1..2);plot(D(D(ParitonJ(f))),-1..2);

[Maple Plot]

[Maple Plot]

Pariton jatke on siis   C^l  , mutta ei C^2  .

>    bn:=sinikertoimet(f,L,N,bfile): # Talletetaan tiedostoon.

>    nops(bn);

100

 Tässä pieni sivujuonne:

save/read -- muuttujien talletus tiedostoon

>    #?save

>    B:=readdata(bfile,1):

>    save B,afile;

>    B:='B': # B:n tyhjennys

>    B;

B

>    read afile:

>    B[1..5];

[10., -14.86135515, 25.45304893, -18.67536387, 9.493114283]

Kaikenlaista muutakin voidaan tallettaa:

>    f:=x->x^2: g:=D(f): a:=[1,2,3]:save f,g,a, afile;

>    f:=1;g:=hups; a:='a';

                              

f := 1

g := hups

a := 'a'

>    read afile;
f(x), g(t), a;

f := proc (x) options operator, arrow; x^2 end proc

g := proc (x) options operator, arrow; 2*x end proc

a := [1, 2, 3]

x^2, 2*t, [1, 2, 3]

Pääjuoni jatkuu...

>    bn:=readdata(bfile,1):

>    bn:=bn[2..-1]:

>    bn[1..3];

[-14.86135515, 25.45304893, -18.67536387]

>    # ns05.,pl:ssä on myös Matlab-henkinen piirtofunktio matlabplot.

>    op(matlabplot);

>    X:=map( ln,[seq(i,i=1..N)] ):

>    Y:=map(ln, map(abs,bn)):

>    Y1:=map(x->x-Y[1],Y):

>    kuva1:=matlabplot(X,Y1,color=black):

>    kuva2:=plot(-2*x,x=0..max(op(X)),color=red):

>    kuva3:=plot(-3*x,x=0..max(op(X)),color=blue):

>    display(kuva1,kuva2,kuva3);

[Maple Plot]

Katsotaan kuvasta hiiren avulla, mikä vakio suunnilleen pitää mustasta käyrästä vähentää, että tullaan siniselle. => hiukan alle 7.

>    Y4:=map(x->x-7,Y):

>    kuva4:=matlabplot(X,Y4,'black'):

>    display(kuva1,kuva2,kuva3,kuva4);

[Maple Plot]

Hyvinpä selvästi näkyy O(1/(n^3))  - käytös.

Nähtiin, että sileä funktio, jonka pariton jatko on vain C^l voi antaa Fourier-kertoimille jopa O(1/(n^3))  - käytöksen.

Asian systemaattinen tutkimus jääköön tällä erää.

Tehtävä 2

>    restart:

>    alustukset();   # Tee alustukset.mws-työarkilla

>   

>    L:=10; c:=1; N:=10:

L := 10

c := 1

>    f:=x->-sin(Pi*x/5)*exp(x/2);

f := proc (x) options operator, arrow; -sin(1/5*Pi*x)*exp(1/2*x) end proc

>    #print(lamposin):

>    u:=lamposini(f,L,c,N,bfile):

>    plot3d(u(x,t),x=0..10,t=0..10,axes=boxed);

[Maple Plot]

Vaihtoehtoinen tapa, readdata:n käyttö suoraan

Oikeastaan koko lamposini -funktion sisältö on tämä kaava:

>    S:=(x,t,N)->add(b[n]*sin(n*Pi*x/L)*exp(-lambda(n)^2*t),n=1..N);

S := proc (x, t, N) options operator, arrow; add(b[n]*sin(n*Pi*x/L)*exp(-lambda(n)^2*t),n = 1 .. N) end proc

>    lambda:=n->n*Pi/L;

lambda := proc (n) options operator, arrow; n*Pi/L end proc

Ajatellaan, että b-kertoimet on kirjoitettu tiedostoon, jonka nimi polkuineen on muuttujassa datafile .

>    op(f); L:=10: N:=100:

proc (x) options operator, arrow; -sin(1/5*Pi*x)*exp(1/2*x) end proc

>    plot(f,0..10):

>    bfile;

Tehdään nyt se kirjoittaminen (eikä vain ajatella tehdyksi,vrt.yllä).

>    sinikertoimet(f,L,N,bfile):

>    Lb:=readdata(bfile,1):

>    L:=Lb[1]: b:=Lb[2..-1]:

>    L;nops(b);

10.

100

>    plot3d(S(x,t,50),x=0..10,t=0..10);

[Maple Plot]

Määritellään grafiikkafunktio, jonka avulla on joustavaa tarkkailla ratkaisua eri aika-alueilla. (Kun ei voida lokalisoida, käytetään edes hiukan kummallisia muuttujan nimiä.)

>    kuva:=(N,tvali::range)->plot3d(S(xxx,ttt,N),xxx=0..10,ttt=op(1,tvali)..op(2,tvali));

kuva := proc (N, tvali::range) options operator, arrow; plot3d(S(xxx,ttt,N),xxx = 0 .. 10,ttt = op(1,tvali) .. op(2,tvali)) end proc

>    kuva(15,0.1..10);kuva(15,0..0.1);

[Maple Plot]

[Maple Plot]

>    display(seq(kuva(N,0..0.1),N=[3,5,7,9,11,13,15]),insequence=true);

>   

[Maple Plot]

>    display(seq(kuva(15,0..t),t=[seq(kk*0.1,kk=2..50)]),insequence=true);

[Maple Plot]

>    L;op(f);

10.

proc (x) options operator, arrow; -sin(1/5*Pi*x)*exp(1/2*x) end proc

>    Nmax:=100; t0:=0.1; Tol:=1e-6;

Nmax := 100

t0 := .1

Tol := .1e-5

>    #bn:=sinikertoimet(f,L,Nmax):

>    Lb:=readdata(bfile,1):L:=Lb[1]: b:=Lb[2..-1]:

>    b[1..3];

[14.86135515, -25.45304893, 18.67536387]

Virhearvio:

>    e:=(t,N,L,maxbn)->maxbn*evalf(exp(-(N*Pi/L)^2*t)/(1-exp(-N*(Pi/L)^2*t)));

e := proc (t, N, L, maxbn) options operator, arrow; maxbn*evalf(exp(-N^2*Pi^2/L^2*t)/(1-exp(-N*Pi^2/L^2*t))) end proc

>    plot([seq([n,abs(b[n])],n=1..nops(b))],view=[0..50,0..2]);

[Maple Plot]

Tällä perusteella voidaan ottaa maxbn=b[N].

Toki maxbn saataisin helposti näin:

>    # max(seq (abs(b[k]), k=N..Nmax) :

Otetaan malliksi 2 tapausta: (1) Pieni t0 ja (2) suuri t0.

On selvää, että virhe pienenee dramaattisesti, kun t kasvaa.

(1)   Pieni t0

>    t0:=0.1:

>    seq(e(t0,m,L,b[m]),m=2..11);

-1251.826312, 585.7129792, -209.4172072, 82.66736980, -35.44061048, 17.02250329, -8.472432516, 4.528295264, -2.430232209, 1.368865391
-1251.826312, 585.7129792, -209.4172072, 82.66736980, -35.44061048, 17.02250329, -8.472432516, 4.528295264, -2.430232209, 1.368865391

>    S:=(x,t,N)->add(b[n]*sin(n*Pi*x/L)*exp(-lambda(n)^2*t),n=1..N);

S := proc (x, t, N) options operator, arrow; add(b[n]*sin(n*Pi*x/L)*exp(-lambda(n)^2*t),n = 1 .. N) end proc

>    lambda:=n->n*Pi/L;

lambda := proc (n) options operator, arrow; n*Pi/L end proc

Verrataan virhearviota ja "todellista" virhettä. Viime mainittu saadaan pitämällä lukua N=100  "äärettömänä". Piirretään ja haetaan hiirellä maksimiarvo ja sijoitetaan saatu lukema virheen arvoksi muuttujaan maxvirhe[...].

>    plot(abs(S(x,t0,100)-S(x,t0,10)),x=0..L);

[Maple Plot]

>    maxvirhe[t0,10]:=0.35;

maxvirhe[.1,10] := .35

>    virhearvio[t0,10]:=e(t0,11,L,b[11]);

virhearvio[.1,10] := 1.368865391

Tehdään sama, kun otetaan 20 termiä. Jotta kuvan asteikkonumerot riittäisivät, skaalataan kertomalla 100:lla, joka sitten jaetaan pois.

>    plot(100*abs(S(x,t0,100)-S(x,t0,20)),x=0..L);

[Maple Plot]

>    maxvirhe[t0,20]:=0.19/100;

maxvirhe[.1,20] := .1900000000e-2

>    L;

10.

>    virhearvio[t0,20]:=e(t0,21,L,b[21]);

virhearvio[.1,20] := .4526261720e-2

Nyt täytyy kertoa 10000:lla, jotta asteikkolukuja näkyisi.

>    plot(10000*abs(S(x,t0,100)-S(x,t0,30)),x=0..L);

[Maple Plot]

>    maxvirhe[t0,30]:=0.03/10000;

maxvirhe[.1,30] := .3000000000e-5

>    virhearvio[t0,30]:=e(t0,31,L,b[31]);

virhearvio[.1,30] := .5879050397e-5

>    yhteenveto[t0]:=seq([n,maxvirhe[t0,n],virhearvio[t0,n]],n=[10,20,30]);

yhteenveto[.1] := [10, .35, 1.368865391], [20, .1900000000e-2, .4526261720e-2], [30, .3000000000e-5, .5879050397e-5]

>    't0'=t0;  # Vain tekstiä varten.

t0 = .1

>    'N',cat("todellinen ", "maxvirhe"), maxvirhearvio;  # Otsikkoteksti

>   

N,

>    Matrix([yhteenveto[t0]]);

Matrix(%id = 17452804)

>   

Virhearvion avulla voitaisiin rakentaa seuraavanlainen silmukka, jonka avulla taataan riittävä määrä termejä tietyllä ajanhetkellä.

(Voitaisi kirjoittaa proseduuriksi, mutta antaa nyt toistaiseksi  olla "kertakäyttökoodina",

jota leikataan/liimataan.)

>    Tol:=10.^(-6);

>    Nmax;

100

>    t0:=0.1;

t0 := .1

>    err:=2*Tol+1:
N:=1:
while err>Tol do
  
N:=N+1;
  if N=Nmax then
    print("Tarvitaan lisää termejä");
    break;
  end if;

  err:=evalf(e(t0,N+1,L,abs(b[N+1])));  
  print(N+1,err);
end do:

3, 585.7129792

4, 209.4172072

5, 82.66736980

6, 35.44061048

7, 17.02250329

8, 8.472432516

9, 4.528295264

10, 2.430232209

11, 1.368865391

12, .7612634261

13, .4387304842

14, .2472215217

15, .1432662326

16, .8068255848e-1

17, .4649866103e-1

18, .2593696160e-1

19, .1475570105e-1

20, .8101953001e-2

21, .4526261720e-2

22, .2435495911e-2

23, .1331026992e-2

24, .6995473175e-3

25, .3729205063e-3

26, .1909563248e-3

27, .9907594977e-4

28, .4933092436e-4

29, .2486727955e-4

30, .1202079171e-4

31, .5879050397e-5

32, .2755602044e-5

33, .1306048020e-5

34, .5929561814e-6

>    t0:=1;

t0 := 1

>    err:=2*Tol+1:
N:=1:
while err>Tol do
  N:=N+1;
  if N=Nmax then
    print("Tarvitaan lisää termejä");
    break;
  end if;
  err:=evalf(e(t0,N+1,L,abs(b[N+1])));  
  print(N+1,err);
end do:

3, 29.97707234

4, 5.999958986

5, 1.109179081

6, .1862953351

7, .2932654455e-1

8, .4002099431e-2

9, .4906421478e-3

10, .5052881100e-4

11, .4569062660e-5

12, .3412664454e-6

>    t0:=5;

t0 := 5

>    err:=2*Tol+1:
N:=1:
while err>Tol do
  N:=N+1;
  if N=Nmax then
    print("Tarvitaan lisää termejä");
    break;
  end if;
  err:=evalf(e(t0,N+1,L,abs(b[N+1])));  
  print(N+1,err);
end do:

3, .2848065553

4, .4104960192e-2

5, .2441647434e-4

6, .5904529798e-7

Näppärästi nähdään, että tämän enempää ei ainakaan kannata ruutia tuhlata termien lukumäärän suhteen.

Tässä tuli samalla niin pienet kuin suuretkin t0:t.

Tehtävä 3

>   

>    op(e);

proc (t, N, L, maxbn) options operator, arrow; maxbn*evalf(exp(-N^2*Pi^2/L^2*t)/(1-exp(-N*Pi^2/L^2*t))) end proc

Kirjoitetaan em. koodi proc:ksi:

>    annaLkm:=proc(b,Nmax,t0,Tol,L)
local err,N;
err:=2*Tol+1:
N:=1:
while err>Tol do
  N:=N+1;
  if N=Nmax then
    print("Tarvitaan lisää termejä");
    break;
  end if;
  err:=evalf(e(t0,N+1,L,abs(b[N+1])));  
end do:
RETURN(N+1);
end proc:

>    t0;

5

>    T:=[0.2, 0.1, 0.05, 0.025, 0.01];

T := [.2, .1, .5e-1, .25e-1, .1e-1]

>    seq(annaLkm(b,Nmax,T[i],Tol,L),i=1..5);

25, 34, 46, 63, 96

Näiden kanssa jatketaan Matlabissa.

Tehtävä 4

>    restart:

>    alustus():   # mene työarkille alustus.mws ja tee siellä

>    G:=t->t/(1+t)+t*exp(-t/5):

>    Limit(G(t),t=infinity): %=value(%);

Limit(t/(1+t)+t*exp(-1/5*t),t = infinity) = 1

>    plot(G(t),t=0..100);

[Maple Plot]

Ajanhetkellä t=100 ollaan jo aika lähellä 1:tä. (G:llä on minimi suunnilleen 48:ssa ja siitä noustaan hyvin hitaasti kohti 1:tä.)

>    plot(G(t),t=30..200);

[Maple Plot]

>    T:=linspace(30,500,50): map(G,T);

[1.042104501, .9897757798, .9827021447, .9837320802, .9856627972, .9873484240, .9887092515, .9898111261, .9907179962, .9914767878, .9921209213, .9926745405, .9931554686, .9935771399, .9939498704, .9942...
[1.042104501, .9897757798, .9827021447, .9837320802, .9856627972, .9873484240, .9887092515, .9898111261, .9907179962, .9914767878, .9921209213, .9926745405, .9931554686, .9935771399, .9939498704, .9942...
[1.042104501, .9897757798, .9827021447, .9837320802, .9856627972, .9873484240, .9887092515, .9898111261, .9907179962, .9914767878, .9921209213, .9926745405, .9931554686, .9935771399, .9939498704, .9942...
[1.042104501, .9897757798, .9827021447, .9837320802, .9856627972, .9873484240, .9887092515, .9898111261, .9907179962, .9914767878, .9921209213, .9926745405, .9931554686, .9935771399, .9939498704, .9942...
[1.042104501, .9897757798, .9827021447, .9837320802, .9856627972, .9873484240, .9887092515, .9898111261, .9907179962, .9914767878, .9921209213, .9926745405, .9931554686, .9935771399, .9939498704, .9942...
[1.042104501, .9897757798, .9827021447, .9837320802, .9856627972, .9873484240, .9887092515, .9898111261, .9907179962, .9914767878, .9921209213, .9926745405, .9931554686, .9935771399, .9939498704, .9942...

Varsinainen homma Matlabissa, analyyttinen harj7:ssä.

Tehtävä 5

>    restart:

>    alustus():  # mene ao. työarkille!

>    bfile;

Määritellään funktiot (proseduurit) kosinikertoimet  ja lampokosini  vastaavien "siniserkkujen" tyyliin:

>    L:=10; c:=1; N:=20;
f:=x->exp(-(x-5)^2);

L := 10

c := 1

N := 20

f := proc (x) options operator, arrow; exp(-(x-5)^2) end proc

>    u:=lampokosini(f,L,c,N,afile):

>    plot3d(u(x,t),x=0..10,t=0..10,axes=boxed);

[Maple Plot]

>    ka:=evalf( int(f(x),x=0..10) ) / L;

ka := .1772453851

>    La:=readdata(afile,1):

>    nops(La);

22

>    a:=La[2..-1]:

>    a[1];

.1772453851

true

Tämä on vakioarvo, jota ratkaisu lähestyy,  sarjahan on muotoa   a[0]+sum(a[n]*cos(n*Pi*x/L)*exp(-k*lambda[n]^2*t))  .

Summalauseke  -> 0, kun t-> infinity  . Siispä sarja -> a[0] , joka on juuri tuo integraali (funktion keskiarvo välillä [0,L]).

Siispä vakiofunktio u = 0.17724 on "steady state"-ratkaisu.

>    U:=seq(u(j*1,10),j=0..10):
max(U); min(U);

Homogeeniset Neumann RE:t eivät päästä lämpöä karkaamaan, joten lämpömäärä pysyy samana

mutta se jakautuu tasaisesti koko alueelle.

>    #op(u);

Itse asiassa Maple osaa integroida "analyyttisesti", erf-funktion avulla:

>    int(f(x),x=0..10); evalf(%);

erf(5)*Pi^(1/2)

1.772453851

Tehtävä 6

>    restart:

>    osdy:=c^2*diff(u(x,t),x$2)=diff(u(x,t),t);
eval(subs(u(x,t)=F(x)*G(t), osdy));

osdy := c^2*diff(u(x,t),`$`(x,2)) = diff(u(x,t),t)

c^2*diff(F(x),`$`(x,2))*G(t) = F(x)*diff(G(t),t)

>    separoitu:=simplify(%/(c^2*F(x)*G(t)));

separoitu := 1/F(x)*diff(F(x),`$`(x,2)) = 1/c^2/G(t)*diff(G(t),t)

>    xyht:=lhs(separoitu)=-p^2;
tyht:=rhs(separoitu)=-p^2;

xyht := 1/F(x)*diff(F(x),`$`(x,2)) = -p^2

tyht := 1/c^2/G(t)*diff(G(t),t) = -p^2

>    FDY:=lhs(xyht)*F(x)=rhs(xyht)*F(x);

FDY := diff(F(x),`$`(x,2)) = -p^2*F(x)

>    GDY:=c^2*lhs(tyht)*G(t)=c^2*rhs(tyht)*G(t);

GDY := diff(G(t),t) = -c^2*p^2*G(t)

>    ff:=rhs(dsolve(FDY,F(x)));
dsolve(GDY,G(t)): gg:=rhs(%);

ff := _C1*sin(p*x)+_C2*cos(p*x)

gg := _C1*exp(-c^2*p^2*t)

>    coeff(ff,sin(p*x));  # Tämä on varmempi tapa kuin subs(C_1=...),koska Maple saattaa eri ajoissa muuttaa järjestystä. (Jos käytät em. tapaa, niin tarkkaile!) Tehdään tässä varman päälle. (Silloin, kun on vain yksi kerroin, ei vaaraa ole.)

_C1

>    ff:=subs(coeff(ff,sin(p*x))=0,ff); # koska u_x(0,t)=0
gg:=subs(_C1=1,gg); # Kantafunktion kertoimeksi kelpaa luku 1.

ff := _C2*cos(p*x)

gg := exp(-c^2*p^2*t)

>   

>    ehto2:=diff(ff,x)+h*ff=0;

ehto2 := -_C2*sin(p*x)*p+h*_C2*cos(p*x) = 0

>    ehto2:=subs({_C2=1,x=L},ehto2);

ehto2 := -sin(p*L)*p+h*cos(p*L) = 0

>    ehto2:=tan(p*L)=h/p;

ehto2 := tan(p*L) = h/p

>   

Asettamalla p=sqrt(\lambda) ja s=pL, saadaan

>    ehto2:=tan(s)=L*h/s;

ehto2 := tan(s) = L*h/s

>    L:=10: h:=1:

>   

>    kuva1:=plot([tan(s),L*h/s],s=1..20,y=0..10,discont=true,color=[blue,red]):

>    kuva1;

[Maple Plot]

>    fsolve(ehto2,s=0..Pi/2);

1.428870011

Leikkauspisteet ovat väleillä [n*pi, n*pi+pi/2] , koska leikkauspisteessä  0 < tan(s) < infinity

>    S:=[seq(fsolve(ehto2,s=n*Pi..n*Pi+Pi/2),n=0..10)];

S := [1.428870011, 4.305801413, 7.228109772, 10.20026259, 13.21418568, 16.25936123, 19.32703429, 22.41084833, 25.50638299, 28.61058194, 31.72131067]
S := [1.428870011, 4.305801413, 7.228109772, 10.20026259, 13.21418568, 16.25936123, 19.32703429, 22.41084833, 25.50638299, 28.61058194, 31.72131067]

>    display(kuva1,plot([seq([S[k],tan(S[k])],k=1..nops(S))],style=point,symbol=cross,symbolsize=20,color=black));

[Maple Plot]

>    lambda:=n->(S[n]/L)^2;

lambda := proc (n) options operator, arrow; S[n]^2/L^2 end proc

Ominaisarvot:

>    seq(lambda(k),k=1..nops(S));

.2041669508e-1, .1853992581, .5224557088, 1.040453569, 1.746147032, 2.643668276, 3.735342544, 5.022461229, 6.505755732, 8.185653989, 10.06241551
.2041669508e-1, .1853992581, .5224557088, 1.040453569, 1.746147032, 2.643668276, 3.735342544, 5.022461229, 6.505755732, 8.185653989, 10.06241551

Ominaisfunktiot:

>    X:=(x,n)->cos(sqrt(lambda(n))*x);

X := proc (x, n) options operator, arrow; cos(sqrt(lambda(n))*x) end proc

>   

>    plot([seq(X(x,n),n=1..3)],x=0..10);plot([seq(X(x,n),n=4..7)],x=0..10);

[Maple Plot]

[Maple Plot]

>    plot([seq(X(x,n),n=1..nops(S))],x=0..10);

[Maple Plot]

Paras visualisointi tuosta röykkiöstä syntyy animoiden:

>    kuva:=n->plot(X(x,n),x=0..10);

kuva := proc (n) options operator, arrow; plot(X(x,n),x = 0 .. 10) end proc

>    display(seq(kuva(n),n=1..nops(S)),insequence=true);

[Maple Plot]

Tarkkaile reunoja: Oikeassa reunassa funktion arvon pitäisi olla derivaatan arvon vastaluku. Kyllä se siltä näyttää.Vasemmassa reunassa derivaatta = 0.

(Funktion arvo on sattumoisin 1 (koska cos(0)=1), mutta se ei ole reunaehto.)

Kirjoitetaan ominaisarvot vielä tiedostoon.

>    writedata(afile,[seq(lambda(k),k=1..nops(S))]);

Tähän liittyvä jatkotehtävä voidaan kehittää harjoitukseen 7.