Fourier-sarjat, L/L16four.mws
20.11.02 HA
Kirjallisuutta
KRE Luku 10
Tämä ws: L/L16four.html
Apufunktioita: JJ, trigsiev, jana
> | restart: |
Warning, the name changecoords has been redefined
> | with(plots): |
> | #read("/p/edu/mat-1.414/maple/v302.mpl"): |
> | #read("c:\\usr\\heikki\\s02\\v302.mpl"): |
> | read("/home/apiola/opetus/peruskurssi/v2-3/maple/v302.mpl"): |
Määritellään uudet koodit varmuuden vuoksi myös tässä, vaikka ovatkin fourier.mpl:ssä (ja ohjelmat.mpl:ssä).
> | # Jaksollinen jatko: MapleTech Vol 3 No. 3 1996 # JJ:=proc(f,d::range) subs({'F'=f,'L'=lhs(d),'D'=rhs(d)-lhs(d)}, proc(x::algebraic) local y; y:=floor((x-L)/D); F(x-y*D); end) end: |
> | # Esim: #sw:=JJ(signum,-1..1); #plot(sw,-4..4); # |
> | parillinenjatko:=f->unapply(piecewise(x>0,f(x),x<0,f(-x)),x): paritonjatko:=f->unapply(piecewise(x>0,f(x),x<0,-f(-x)),x): |
Haluamme välttää assume-komennon käyttöä, koska sillä on joissakin tilanteissa ikäviä sivuvaikutuksia.
Siksi joudumme määrittelemään hieman kömpelön oman sievennysfunktion. n ajatellaan kokonaisluvuksi.
> | trigsiev:=proc(lauseke,n) local tulos; tulos:=subs(sin(n*Pi)=0,lauseke); tulos:=subs(cos(n*Pi)=(-1)^n,tulos); tulos:=algsubs(exp(-2*I*n*Pi)=1,tulos); tulos:=algsubs(exp(2*I*n*Pi)=1,tulos); tulos:=subs((-1)^(2*n)=1,tulos);simplify(tulos); end: |
> | jana:=(x,y)->plot([[x,0],[x,y]],thickness=3,color=blue): |
> | #display([seq(jana(n,abs(an)),n=1..6)],axes=box); |
> | op(trigsiev); |
10.1 Jaksolliset funktiot, trigonometriset sarjat
Perusteet kirjassa ja luennolla
Lyhyesti: f: R -> R on jaksollinen, jaksona p>0, jos
kaikilla
.
Pienin p on perusjakso.
Jos f on p-jaksoinen, niin se on
-jaksoinen kaikilla
.
(Kaikilla jaksollisilla ei ole pienintä, vakiofunktio on jaksollinen ja kaikki p>0 ovat jaksoja.)
,
ovat
- jaksoisia.
,
ovat
- jaksoisia.
Tutkimme sarjaa:
> | ![]() |
Jaksollinen jatkaminen
Jokainen jollain välillä [a,b] määritelty funktio voidaan jatkaa jaksollisena (p=b-a) koko R:ään.
Hyvä, että meillä on Maple-funktio JJ sitä varten.
Esim:
> | f:=x->x^2: # välillä [0,1], jatka 1-jaksoisena! |
> | Jf:=JJ(f,0..1); |
> | plot(Jf(x),x=-2..2); |
> | f:=x->x^2: # välillä [-1,1], jatka 2-jaksoisena! |
> | Jf:=JJ(f,-1..1); |
> | plot(Jf,-4..4); |
Esim. Kanttiaaltoja saa kätevästi Heavisiden funktion jaksollisena jatkona.
> | with(inttrans): alias(u=Heaviside): |
> | Ju:=JJ(u,-1..1): |
> | plot(Ju,-2..2); |
> | plot(2*Ju-1,-2..2,scaling=constrained,axes=boxed); |
Ehkä helpompaa on määritellä näin:
> | f:=x->piecewise(x>0,1,x<0,-1); |
> | Jf:=JJ(f,-1..1): plot(Jf,-2..2); |
Kaikkein helpointa on käyttää signum -funktiota, vrt. yllä.
10.2 Fourier-sarjojen laskeminen
> | Sis:=(f,g)->int(f(x)*g(x),x=-Pi..Pi); |
Palautetaan mieleen sisätuloavaruuden vektorin esitys ON kannan suhteen
Olkoon
ON kanta sisätuloavaruudessa V. Olkoon v jokin vektori V:ssä.
. Määrätään kertoimet
.
Sehän tapahtui näin: Kerrotaan yhtälö puolittain sisätulon mielessä
:lla,
:
.
Summassa on vain yksi nollasta poikkeava termi =
, joka = 1, joten
.
Siispä
Tätähän kutsuimme edellä jo Fourier-esitykseksi.
Muista myös toinen näkökulma:
Jos
on sisätuloavaruuden
aliavaruus ja jos
on
:n ON kanta, niin mielivaltaisen vektorin
paras approksimaatio aliavaruudessa
(PNS-approksimaatio) on
v* =
Trigonometrisen systeemin ortogonaalisuus
> | cos((n+k)*x): %=expand(%); |
> | cos((n-k)*x): %=expand(%); |
> | cosyht:=cos(x*n)*cos(x*k)=1/2*(cos((n+k)*x)+cos((n-k)*x)); |
> | sinyht:=sin(x*n)*sin(x*k)=1/2*(cos((n-k)*x)-cos((n+k)*x)); |
_|_
, kun
:
> | Int(lhs(cosyht),x=-Pi..Pi)=int(rhs(cosyht),x); # jos n erisuuri kuin k. |
missä oikealla sijoitetaan
. Saadaan siis 0.
_|_
, kun
:
Aivan samoin saadaan nolla, kun
siniyhtälössä:
> | Int(lhs(sinyht),x=-Pi..Pi)=int(rhs(sinyht),x); # jos n erisuuri kuin k. |
_|_ 1 ,
_|_ 1 , kun k > 0:
> | ![]() |
> | ![]() |
> | ![]() |
koska
on parillinen fkt. ja
pariton.
Siten niiden tulo on pariton, joten integraali O:n suhteen symmetrisen välin yli on = 0.
Osoitimme siis, että trigonometrinen systeemi
on ortogonaalinen.
Lasketaan vielä normit:
> | (cos(k*x))^2=combine(cos(k*x)^2); |
> | int(rhs(%),x=-Pi..Pi);trigsiev(%,k); |
> | #trigsiev #(read("polku/v302.mpl"):) |
> | sin(k*x)^2=combine(sin(k*x)^2); |
> | int(rhs(%),x=-Pi..Pi);trigsiev(%,k); |
Molemmista saatiin siis
, joten ||
|| = ||
|| =
.
|| 1 || =
, joka on
.
Fourier-kertoimet
-jaksoiset funktiot
Koska trigonometrinen systeemi on ortogonaalinen, voimme käyttää kertoimien johtamisessa aivan samaa tekniikkaa,
kuin edellä. Nyt on vain kyse sarjasta ja tehtävänasettelu on tämä: Oletetaan, että
-jaksoinen funktio f: R --> R
voidaan esittää suppenevan sarjan summana muodossa:
(1)
.
Oletetaan lisäksi, että sarjan integrointi termeittäin on sallittua. Tällöin kertoimien lausekkeet ovat välttämättä alla olevat.
Päättely on nyt aivan sama kuin yllä: Kun määrätään kerrointa
tai
, niin kerrotaan yhtälö puolittain vastaavalla
kantafunktiolla ja integroidaan yli välin [-
,
]. Ts. kerrotaan puolittain sisätulon mielessä ko, kantafunktiolla.
Ortogonaalisuuden ansiosta summaan jää vain yksi nollasta poikkeava termi (summausindeksin n arvolla k, tai jos k=0,
jolloin lasketaan
:aa, jää pelkkä
- termi (eli
).)
Näihin kaavoihin siis johdutaan. Kaavat johti jo kauan ennen Fourieria , kukas muu kuin Euler v. 1777.
> | f:='f': |
> | a0:=(1/(2*Pi))*Int(f(x),x=-Pi..Pi); |
> | an:=(1/Pi)*Int(f(x)*cos(n*x),x=-Pi..Pi); |
> | bn:=(1/Pi)*Int(f(x)*sin(n*x),x=-Pi..Pi); |
> | sarja:='a0'+Sum('an'*cos(n*x)+'bn'*sin(n*x),n=1..infinity); |
> | osasumma:=(x,N)->a0+add(an*cos(n*x)+bn*sin(n*x),n=1..N): |
Fourier -sarjojen muodostaminen on nyt helppoa. Toki voi tulla integrointivaivaa, mutta Maplea voi käyttää
nautinnollisesti hyödyksi. Voi tietysti syntyä myös tilanteita, joissa on turvauduttava numeeriseen integrointiin.
Siihenkin Maplessa on välineitä.
Esim. Kanttiaalto (KRE Exa 1 s. 532)
> | kantti:=JJ(signum,-Pi..Pi); # Tehdään nyt helpoimmalla tavalla. |
> | plot(kantti(x),x=-2*Pi..2*Pi); |
Voitaisiin käyttää signum -funktiota tai piecewise -määrittelyä, tms. yleisissä kaavoissa, mutta tehdään, kuten käsin laskiessa.
> | ![]() |
> | ![]() |
Koska funktio f on pariton, ja
-kertoimien kaavassa se kerrotaan parillisella funktiolla (1 tai cos), on integroitava pariton, ja tulos siten 0.
> | ![]() |
Integroitava on nyt parillinen (pariton x pariton), joten voidaan
laskea myös näin:
> | ![]() |
> | bn:=trigsiev(bn,n); |
> | seq(bn,n=1..7); |
> |
> | sarja:='a[0]'+Sum('a[n]'*cos(n*x)+'b[n]'*sin(n*x),n=1..infinity); |
> | osasumma:=(x,N)->add(bn*sin(n*x),n=1..N); |
> | osasumma(x,9); |
> | sarja:=(4/Pi)*Sum(sin(2*k-1)*x/(2*k-1),k=1..infinity); # Muista iso Sum ! |
Kuvaajia:
> | plot([kantti(x),osasumma(x,1)],x=-2*Pi..2*Pi); |
> | plot([kantti(x),seq(osasumma(x,N),N=1..11)],x=-2*Pi..2*Pi); |
> | plot([kantti(x),seq(osasumma(x,N),N=[1,3,5,31,67])],x=-2*Pi..2*Pi,color=[gray,black,green,blue,red]); |
> | plots[display](%,view=[-Pi..Pi,-1.5..1.5]); |
> |
> | plot([kantti(x),osasumma(x,101)],x=-0.1..Pi+.1,color=[gray,blue],numpoints=100); |
> | display(%,view=[0..Pi,0.7..1.3]); |
Fourier-sarjojen suppeneminen
Jos on annettu
- jaksoinen integroituva f: R->R, voidaan aina muodostaa Fourier-kertoimet
,
ja siten Fourier-sarja
.
Kysymys1: Suppeneeko sarja
Kysymys 2: Jos suppenee, niin esittääkö funktiota f.
Usein merkitään:
f (x) ~
Suppenemislauseet ovat yleensä vaikeita ja syvällisiä. Teoreettiset kysymykset ovat vaikeita, käytännön laskut ja soveltaminen helppoa.
Välttämättömiä ja riittäviä suppenemisehtoja ei vieläkään tunneta.
Sensijaan käyttökelpoisia riittäviä ehtoja on tarjolla. Tässä oikein sopiva:
Lause.
(KRE s. 535 Thm 1) Jos
- jaksoinen f: R-->R on paloittain jatkuva välillä [
,
] ja jos sillä on v.p. ja o.p. derivaatat (*) kaikissa
välin pisteissä, niin f:n Fourier-sarja suppenee
Huom! v.p. ja o.p. derivaatta tarkoittavat tässä yhteydessä tavanomaisten käsitteiden lievennystä sikäli, että derivaatan laskentapisteeksi
otetaan vastaava v.p. tai o.p. raja-arvo. Niinpä tässä tarkoitetussa mielessä esim. Heavisiden funktiolla u(x) on 0:ssa v.p. ja o.p. derivaatat,
ja molemmat ovat = 0. Varsinaisessa mielessä näin ei ole, määriteltiinpä u(0) miten tahansa. (Jos olisi, niin u:lla olisi derivaatta 0:ssa, ja se
romuttaisi hyvän osan ykköskurssien oppeja.)
Tämä on tärkeä "pointti", sillä näin saamme lauseen piiriin juuri porrasfunktioita yms. "kanttikäytöksiä".
KRE-kirjassa annetaan lauseelle todistus vahventamalla huomattavasti oletuksia ja lieventämällä johtopäätöstä. (Pelkkä suppenemsitodistus
ilman mitään yritystäkään siihen, esittääkö summa f(x):ää (kirjallisuusviite kylläkin ja maininta syvällisyydestä).
Koska jälkimmäinen on juuri se olennainen, päätämme jättää tämän todistuksen väliin, sinänsä se ei ole lainkaan vaikea (mutta siis aika hyödytön).
Katsotaan suppenemislauseen kannalta uudestaan kanttiaallon F-sarjaa.
.
> | kantti(Pi/2)=4/Pi*(1-1/kolme+1/viisi-1/seitseman+ooo); |
Saadaan
:lle sarjakehitelmä:
> | Pi=4*(Sum((-1)^(k-1)/(2*k-1),k=1..infinity)); |
Tämän sarjan johti Leibniz 1673. Fourier-sarjalauseiden voimaa kuvastaa se, että niiden avulla saadaan sivutuotteena erinäisten vakiotermisten
sarjojen summia. (Sarjan summan määrittäminenhän on yleensä paljon vaikeampaa kuin pelkän suppenemisen osoitteminen.)
Mielivaltainen jakso
Saadaan edellisestä skaalaamalla: Otetaan uusi muuttuja
.
Jos f on 2*L-jaksoinen, saadaan näin kaavat:
missä
> |
Esim: Puoliaaltotasasuunnattu siniaalto
> |
Sinisarja ja kosinisarja
Jäljempänä esitämme parillisen ja parittoman laajennusoperaattorin. Käytännössä parillista/paritonta laajennusta vastaa kosini/sinisarja, jossa lähdetään liikkeelle välillä [0,d] määritellystä funktiosta f, joka laajennetaan parilliseksi/parittomaksi. Tällöin yllä olevat kaavat tulevat muotoon:
1) kosinisarja:
> | f:='f': T:='T': omega:='omega': #omega:=2*Pi/T: |
> | a0:=(1/d)*int(f(t),t=-d..d);an:=(1/d)*int(f(t)*cos(n*omega*t),t=-d..d);bn:=0; |
> |
Koska yllä olevat integroitavat ovat parilllisia, voidaan integroida [0..d], kunhan tulos kerrotaan 2:lla.
Tällöin tullaan toimeen alkuperäisellä, välillä [0,d] määritellyllä funktiolla, eikä tarvitse kohdistaa integrointia parilliseen laajennukseen. Siispä kosinisarjakaavat ovat:
> | f:='f':T:='T':omega:='omega':#omega:=2*Pi/T: a0:=(2/d)*int(f(t),t=0..d); an:=(2/d)*int(f(t)*cos(n*omega*t),t=0..d);bn:=0; sarja:='a0'/2+sum('an'*cos(n*omega*t),n=1..infinity); |
Sinisarja saadaan aivan vastaavasti:
> | f:='f':T:='T':omega:='omega':#omega:=2*Pi/T: bn:=(2/d)*int(f(t)*sin(n*omega*t),t=0..d); sarja:=sum('bn'*cos(n*omega*t),n=1..infinity); |
Kompleksinen muoto
Kokeillaan vaihteeksi sellaista tyyliä, että c on n:n funktio, tässä se on mukavaa, kun kaavatkin ovat yhtenäiset. c-funktio on syytä määritellä unapply-tavalla. Laskentatehossa nimittäin on dramaattinen ero. (unapply evaluoi (esim. integroi) määrittelyaikana, kun taas -> määrittely tekee sen kutsuaikana.)
> | T:='T': f:='f': omega:='omega': omega:=2*Pi/T: |
> | c:=unapply(1/T*int(f(t)*exp(-I*n*omega*t),t=0..T),n);c(0):=1/T*int(f(t),t=0..T); |
Vaikka seuraava toimii, niin ei kannata tehdä, kts. yllä.
> | #c:=n->1/T*int(f(t)*exp(-I*n*omega*t),t=0..T); |
> | # sarja:=sum('c(n)'*exp(I*n*'omega'*t),n=-infinity..infinity); |
Esim.
Muodosta alla määriteltävän funktion Fourier-sarja, piirrä jaksollinen laajennus ja Fourier-osasummien kuvaajia. Piirrä myös taajuusspektrit. Käsittele sekä reaalimuotoista sin/cos-sarjaa että kompleksimuotoista.
> | f:=t->piecewise(-Pi<t and t < 0,t+Pi,0<t and t<Pi,Pi); |
> | plot(f,-Pi..Pi); |
> | jaksf:=JJ(f,-Pi..Pi): |
> | plot(jaksf,-2*Pi..2*Pi); |
> | T:=2*Pi:omega:=2*Pi/T: |
> | a0:=(2/T)*int(f(t),t=-Pi..Pi); an:=(2/T)*int(f(t)*cos(n*omega*t),t=-Pi..Pi):an:=trigsiev(an,n); bn:=(2/T)*int(f(t)*sin(n*omega*t),t=-Pi..Pi):bn:=trigsiev(bn,n); |
Koska halusimme välttyä assume -komennon aiheuttamilta sivuvaikutuksilta, sievensimme omalla trigsiev- komennolla. Huomaamme, että int osasi käsitellä piecewise -määriteltyä funktiota ihan nätisti. Luultavaa on, että se osaa myös epäjatkuvalle, mutta kannattaa tarkkailla.
> | #sarja:=a0/2+sum(an*cos(n*omega*t)+bn*sin(n*omega*t),n=1..infinity); |
> | osasumma:=N->a0/2+sum(an*cos(n*omega*t)+bn*sin(n*omega*t),n=1..N); |
> | osasumma(5); |
Tässä tyylissä (jossa an ja bn integroitiin symbolisesti valmiiksi), on aivan sopivaa (ja suositeltavaa) käyttää -> funktiomääritystapaa.
> | plot([jaksf(t),osasumma(10)],t=-2*Pi..2*Pi); |
> | plot([jaksf(t),seq(osasumma(k),k=1..10)],t=-2*Pi..2*Pi); |
Taajuusspekrit:
Piirtäminen hoituu oikein näppärästi yllä määrittelemällämme jana -funktiolla.
> | A0:=a0/2; An:=abs(an-I*bn); |
> | print(jana); |
> | phi0:=0: phin:=argument(an-I*bn); |
> | display([jana(0,A0),seq(jana(n,An),n=1..6)],axes=box,title="Amplitudispektri");display([jana(0,phi0),seq(jana(n,phin),n=1..6)],title="Vaihespektri"); |
Kompleksinen muoto
> | c:=unapply(1/T*int(f(t)*exp(-I*n*omega*t),t=0..T),n);c(0):=1/T*int(f(t),t=0..T); |
> | sarja:=sum('c(n)'*exp(I*n*'omega'*t),n=-infinity..infinity); |
> | c(0); |
> | c(1); |
> | seq(c(n),n=-5..5); |
> | display([seq(jana(n,abs(c(n))),n=-6..6)],axes=box,title="Amplitudispektri"); |
> | display([seq(jana(n,argument(c(n))),n=-6..6)],title="Vaihespektri"); |
> |
Parilliset ja parittomat laajennukset
Määritellään laajennusoperaattorit "
parillinenjatko"
ja "
paritonjatko
", jotka jatkavat
positiivisella R-akselilla määritellyn funktion parillisena/parittomana koko R:ään.
(Ovat ohjelmat.mpl:ssä)
> | parillinenjatko:=f->unapply(piecewise(x>0,f(x),x<0,f(-x)),x): |
> | paritonjatko:=f->unapply(piecewise(x>0,f(x),x<0,-f(-x)),x): |
> | f:=t->t; |
> | plot(parillinenjatko(f),-1..1); |
> | plot(paritonjatko(f),-1..1); |
> | plot(paritonjatko(x->x^2),-1..1); |
> | jakspariton:=JJ(paritonjatko(x->x^2),-1..1): |
> | plot(jakspariton,-3..3); |
Onpas meillä nyt hyvät välineet. Tehtävien ratkominen on pelkkää nautiskelua!
Lisäksi kannattaa ottaa vielä numeerisen integroinnin tapaus.
Fourier-sarjan laskeminen numeerisesti integroiden
Titenkään integrointi ei aina onnistu symbolisesti. Otetaan esimerkki, jossa samalla tulee sinisarjan kaavan käyttö.
Kehitettävä sinisarjaksi välillä [-1,1] funktio:
> | f:=t->t^sin(4*Pi*t); |
> | plot(paritonjatko(f),-1..1); |
> | d:=1:omega:=Pi: |
> | b:=array(1..20): |
> | for n from 1 to 20 do b[n]:=(2/d)*evalf(Int(f(t)*sin(n*omega*t),t=0..d)); od: n:='n': |
Tässä yksi sitkeä Maple "feature" : for-loopin jälkeen n:llä on arvo 21, mikä johtaa jatkossa virhetilanteeseen, siksi n vapautetaan tässä.
> | osasumma:=N->sum(b[n]*sin(n*omega*t),n=1..N); |
> | osasumma(10); |
> | plot([paritonjatko(f)(t),op(map(osasumma,[3,5,7,17]))],t=-1..1); |
> |
Tehtiin pikku briljeeraus vielä mappaamalla osasumma erinäisille indekseille.