Funktionsteori Funktionsteori Datorlaboration 2 Fourierserier Inledning Största delen av denna laboration handlar om Fourierserier, men vi startar med seriesummation. Vissa filer kan du behöva hämta på kursens hemsida. Förbered dig genom att titta igenom denna handledning och anvisningarna nedan. Komplettera motiveringen på sidan 2. Jämför sidan 122 i läroboken och lösningen av övning 7.22. Läs också igenom kapitlet om Fourierserier i läroboken, om du inte gjort det innan. Seriesummation Vi skall nu utföra numerisk summation av några serier. För att förstå bättre vad som händer skall du i alla exemplen beräkna delsummorna (med cumsum) och titta på dem, t ex med kommandot stairs. 2.1 Serien k 4 har summan π 4 /90. Beräkna seriens summa med tre riktiga (korrekta) k=1 decimaler. Tre riktiga decimaler betyder att vi tolererar ett fel vars absolutbelopp högst är lika med tol = 0.0005. Jämförelse med integral ger resttermsuppskattningen och r n tol om r n 1 3n 3, ( ) 1 1 1/3 tol n 3n3 3tol Bestäm hur många termer som behövs för att få seriens summa med 3 decimaler (använd Matlab för räkningen). Bilda nu detta antal av seriens termer och summera. Beräkna närmevärdet på π 4 /90. Detta kan göras genom att på en rad skriva så här: format long; tol = 5e-4; n = ceil(1/(3*tol)ˆ(1/3)), k = 1:n;a = 1./k.ˆ4; summa = sum(a) Kontrollera vad ceil gör för någonting. I detta fall kan vi jämföra med Matlabs inbyggda värde. fel = (piˆ4)/90 - summa Gör nu om alltsammans (format long behöver inte upprepas) med 6 och 9 decimalers noggrannhet. Använd tangenten pil uppåt för att återkalla raden med Matlabkommandon. Det går givetvis att tillverka en skriptfil som gör räkningarna. 1
Summa Antal termer Antal riktiga decimaler Fel enligt Matlab fel =π 4 /90 summa 3 6 9 Räkningarna i exemplet ovan kan användas för att ge ett numeriskt värde på π. Vi tar nu en serie som med framgång kan jämföras med en geometrisk serie. 2.2 Målet nu är att beräkna e 6. För detta skall vi approximativt summera serien k=0 6 k k! på följande sätt. Vi har alltså rekursionsformeln a 0 = 1, a k+1 = 6 k + 1 a k för termerna. Om vi avbryter summan efter n termer, så har vi ett fel (restterm) som måste uppskattas. Motivera resttermsuppskattningen r n 2a n+1 om n 10. Motivering: 0 r n = a n+1 + a n+2 + a n+3 + a n+4 +... a n+2 2 1 a n+1 a n+3 2 1 a n+2 2 2 a n+1 a n+4...? Fortsätt och avsluta resonemanget Beräkna nu iterativt termer och delsummor tills resttermen blir så liten som önskat. Man kan göra så här: Gå till File, New, M-file Skriv in eller hämta (från kursens hemsida) filen 2
function [s,antaltermer]=expsum(tol) %s anger närmevärdet av eˆ6 %tol = toleransen a = 1; s = 0; k = 0; while ((2*a> tol) (k<11)) s = s + a; a = a*6/(k+1); k=k+1; end; antaltermer=k; Spara filen under namnet expsum. Du har nu skapat Matlab-funktionen expsum. Genom att i Matlab skriva [s,antaltermer]=expsum(5e-4) så får du ett närmevärde till e 6 med tre riktiga decimaler. Jämför värdet med Matlabs exp(6) Kör om beräkningen igen för att få 6 decimalers noggrannhet och jämför än en gång med Matlabs exp(6). Avsluta med format så återgår Matlab till att visa normalt antal siffror. (I mån av tid) Ändra funktionen ovan så att den i stället beräknar e x, där x 0. 2.3 (I mån av tid) Beräkna cos x. Använd metoden att summera serien k=0 ( 1) k x2k (2k)! Använd att termerna är u k = ( 1) k x 2k /(2k)! och delsummorna s n uppfyller rekursionerna x 2 u k+1 = (2k + 2)(2k + 1) u k, s k+1 = s k + u k+1. Vilka är begynnelsevärdena? Jämför med Matlabs värde för cos x. Tillverka en Matlab-funktion, t ex cosinus, som beräknar cos x och slutar då felet garanterat är mindre än en given tolerans. Exempelvis kan funktionsfilen inledas med function[s,antaltermer]=cosinus(x,tol). Använd funktionen för att beräkna cos 10, cos 20, cos 30 och cos 40. Jämför också med Matlabs värde. Se på termerna i serien (grafiskt) och försök förklara vad som sker. Förklaring: 3
Fourierserier i Matlab Vi skall nu göra ett experimentellt studium av trigonometriska Fourierserier, dvs funktionsserier av formen 1 1 2 a 0 + a k cos(kt) + b k sin(kt), k=1 där a = a k och b = b k är reella talföljder. En term i en sådan serie kan också skrivas som u k (t) = a k cos(kt) + b k sin(kt) = A k cos(kt + δ k ) och är alltså en harmonisk svängning med vinkelfrekvens k och period 2π/k. Amplituden ges av formeln A k = a 2 k + b2 k. Vi skall alltså addera sinusformade funktioner med högre och högre frekvenser. 2.4 Förberedelser: Hämta m-filerna fourkoeff.m, visafunk.m, visaserie.m och visadelsummor.m från datorövningens hemsida. Definiera två följder genom K = 1:100; t = -10:0.05:10; Variabeln K svarar mot index k ovan, och t är tidsvariabeln. Ändra inte dessa variabler i fortsättningen. Koefficienterna a och b skall lagras i den skalära variabeln anoll och i vektorerna akoeff och bkoeff. 2.5 Slå in Vi skall nu beräkna delsummor till funktionsserien» anoll = 0; k=1» akoeff = zeros(size(k)); sin kt k» bkoeff = ones(size(k))./k; = sin t + sin 2t 2 + sin 3t 3 +.... Plotta successivt» s0 = anoll/2*ones(size(t)); plot(t,s0)» s1 = s0+bkoeff(1)*sin(t); plot(t,s1)» s2 = s1+bkoeff(2)*sin(2*t); plot(t,s2)» s3 = s2+bkoeff(3)*sin(3*t); plot(t,s3) och så vidare, tills du tröttnar. 1 Här motsvarar 1 a0 det som i formelsamlingen och föreläsningarna kallas c0. 2 4
2.6 Vill man slippa skriva in så mycket så kan man göra så här:» s=anoll/2*ones(size(t));» for k=1:100; s=s+bkoeff(k)*sin(k*t); plot(t,s), title([ delsumma s_{ int2str(k) } ]), pause, end Tag reda på vad pause innebär innan du startar körningen. Det går att bryta med Ctrl-C, om alla 100 stegen tar för lång tid. Verkar Fourierserien konvergera? Rita in vad du tror är seriesumman då 4π < t < 4π. y π/2 4π 3π 2π π π 2π 3π 4π t π/2 Konvergerar den trigonometriska Fourierserien likformigt t. ex då 2π < t < 2π? Lägg märke till att alla sinustermer, och därmed även delsummorna, är udda funktioner. 2.7 Slå nu in koefficienter a k = 2 π cos(kπ/2) 1 k 2, k 1, a 1 = 1 2, b k = 0 och rita upp några delsummor. Hur ser resultatet ut? (Förklaringen finns till största delen i övning 8.29. Se också svaret till övningen.) 5
Skiss av summan y 1 π 2π 3π π π/2 π/2 3π/2 5π/2 t För att förenkla hanteringen kan du använda skriptet visaserie.m som visar termer och delsummor serier av typen ovan för koefficienter som är angivna på tidigare nämnd form. 2.8 Hämta visaserie.m och övriga m-filer från kursens hemsida. Använd hjälpfunktionen, help visaserie Skriv in ymin=-0.5; ymax=1.5; i Matlab. Kör visaserie för att se på seriens termer och delsummor. Med normal upplösning på skärmen är det inte lönt att ta med mer än ca 50 termer. Bryt sedan med Ctrl-C. 2.9 Då 0 t π gäller att k=0 cos(2k + 1)t (2k + 1) 2 = π 4 (π t). (1) 2 I mån av tid kan du visa detta genom handräkning genom att bestämma cosinusserien för högerledet i (1). Med hjälp av Matlab går det emellertid att snabbt göra det troligt att (1) gäller. Innan du använder visaserie behöver du skriva in anoll, akoeff och bkoeff. Glöm inte ymin=-1.5;ymax=1.5; innan du använder visaserie. Jämför restultatet genom att plotta högerledet. Använd tex hold on och hold off för att se flera plottar i samma figur. För vilka t verkar likheten stämma? Svar: 2.10 Om seriens summafunktion är känd från början, så kan man även beräkna och rita upp dess resttermer. Detta går att göra med skriptet visadelsummor.m. I 2.7 är summafunktionen en halvvågslikriktad cosinusvåg. Skriv återigen in anoll, akoeff och bkoeff. Skriv också in» funktion = max(cos(tid),0) och kör visadelsummor. I mitten visas den senast tillagda termen u n i rött och resttermen r n i blått. Överst visas delsumman i blått och nederst seriens summa i grönt (om man angivit den rätt i funktion). Förstora gärna figurfönstret lite (genom att dra med musen i nedre högra hörnet). Tryck på valfri tangent (= mellanslag) för att få nästa delsumma. Bryt med Ctrl-C. 6
Med hjälp av visadelsummor kan man kontrollera alla svar i övningarna på Fourierkoefficienter. Om man inte tycker om att partialintegrera, så kan man låta Matlab räkna ut koefficienterna. Detta sker med den numeriska metoden snabb Fouriertransformation (FFT). Det finns naturligtvis ett Matlabkommando som heter fft. Med hjälp av m-filen fourkoeff kan man använda detta för att beräkna Fourierkoefficienterna för en given funktion. Titta på fourkoeff.m, och lägg märke till att index är förskjutna ett steg, eftersom Matlab indicerar vektorer med början på k = 1. Vi låter fourkoeff beräkna 2 8 = 256 koefficienter numeriskt (vilket svarar mot 128 termer i den trigonometriska Fourierserien). 2.11 Vi skall nu se på utvecklingen av en fyrkantsvåg. Den kan definieras genom funktion = (tid < pi) - (tid > pi) Om tid är en vektor, så blir (tid < pi) en vektor med samma antal element som tid. Den har ettor i de element där villkoret tid < pi är sant i tid och nollor för övrigt. Rita nu upp fyrkantsvågens partialsummor med hjälp av kommandona fourkoeff, visadelsummor 2.12 Undersök på samma sätt triangelvågen, som kan beskrivas som funktion = tid.*(tid < pi) + (2*pi-tid).*(tid >= pi) 2.13 (I mån av tid.) Definiera nu en lagom komplicerad funktion, med språng och olika utseenden på olika delintervall. Ett förslag är» funktion= (tid<pi/2).*tid - (tid>4*pi/3).*(tid<3*pi/2) Kör nu fourkoeff, så beräknas koefficienterna. Dessutom ritas funktionen upp. Kör sedan visadelsummor och kontrollera att delsummorna närmar sig den givna funktionen. Hitta gärna på ett eget exempel på en konstig funktion och undersök dess Fourierserie. Ljud i Matlab Matlab är försett med en primitiv ljudfunktion, som sänder ut följder till högtalaren med hastighet av 2 13 = 8192 element i sekunden (på en del system kan man ändra samplingsfrekvensen). Kommandot för att skicka en vektor x till högtalaren är sound(x). Testa med x = cos(2*pi*440/8192*(1:8192)); sound(0.1*x) för en ren ton och x = randn(1,8192); sound(0.1*x) 7
för rent brus. 2.14 Hämta filen temple.mat från hemsidan och ladda den genom att skriva load temple. Denna innehåller en samplad signal f samt samplingsfrekvens samprate. Testa att spela upp signalen. För att titta på frekvensinnehållet så kan du skriva plot(abs(fftshift(fft(fftshift(f))))); Operationen fftshift har med centrering (förskjutning) att göra. Definiera fyra filter w1=1; w2=[1-1]; w3=ones(10,1);w4=conv(w2,w3); Räkna ut faltningen mellan signalen f och de olika filtren genom att använda kommandot g=conv(f,w). Spela upp g och titta på dess frekvensinnehåll. Vad händer? 8