Zapisz jako PDF

Transkrypt

Zapisz jako PDF
Analiza_sygnałów_-_ćwiczenia/Fourier
Spis treści
1 Transformata Fouriera
1.1 Analiza Fouriera jako rzutowanie wektorów
1.2 Zespolone eksponensy
1.3 Zadanie
1.4 Obliczanie transformaty
1.5 Obliczenia analityczne
1.6 Rekonstrukcja sygnałów:
1.6.1 Zadanie domowe
1.7 Dyskretna Transformata Fouriera (DFT)
1.8 FFT
1.8.1 Zadanie
1.9 Widmo mocy dla sygnałów rzeczywistych: Transformaty rzeczywiste i Hermitowskie
1.10 Zadanie
2 Co musimy z tego zapamiętać?
Transformata Fouriera
Analiza Fouriera jako rzutowanie wektorów
W tym zadaniu chciałbym abyśmy wyrobili sobie intuicję, że analiza Fouriera moze być rozumiana
jako badanie sygnału (niech nazywa się syg) za pomocą pewnych znanych funkcji (będą to funkcje
sin i cos). Jak już mówiliśmy o sygnałach można myśleć, że są to wektory. Jeśli chcemy zbadać, czy
dwa wektory są podobne do siebie to liczymy ich iloczyn skalarny. Zobaczmy jak to działą w
poniższym zadaniu:
import numpy as np
T = 1 # ustawiamy długość czasu
Fs = 100 # ustawiamy częstość próbkowania
t = #wytwarzamy wektor czasu
syg = # wytwarzamy sygnał będący sumą sinusa o cz. 3Hz i cos o częstości 7Hz
syg = syg/np.linalg.norm(syg) # normalizujemy badany sygnał
print("częstość\tsin\tcos" ) # szykujemy nagłówek wydruku
for n in # dla liczb n z zakresu 1 do 10
test_sin = #tworzymy sygnał testowy sinus o częstości n
test_sin = #normalizujemy ten sygnał testowy
test_cos = # tworzymy testowego cosinusa o częstości n
test_cos = # normalizujemy
rzut_s =#obliczamy iloczyn skalarny sygnału z testowym sinusem
rzut_p = #obliczamy iloczyn skalarny z testowym cosinusem
print("%d\t%.3f\t%.3f" %(n,rzut_s, rzut_p)) # wypisujemy wyniki
Zespolone eksponensy
Dla przypomnienia wzory Eulera:
Zadanie
Dla przypomnienia:
uzyskanie liczby zespolonej w pythonie mamy jako 1j.
jeśli prowadzimy obliczenia na liczbach zespolonych to w wyniku dostajemy liczby zespolone
(nawet jeśli ich część urojona jest 0). Aby rzutować wynik na liczby rzeczywiste musimy
wykonać funkcję np.real(.)
Proszę narysować wykres funkcji
między próbkami proszę ustawić na 0.001.
Obejrzeć wykresy dla
Jaki sens ma liczba ?
Jaki sens ma liczba ?
dla
. Odstęp
.
Obliczanie transformaty
Funkcja o okresie 2, w podstawowym okresie dana jest ona wzorem:
dla
,
Za pomocą wykresu coraz to większej ilości składników jej szeregu Fouriera sprawdź jego zbieżność.
Obliczenia analityczne
Musimy obliczyć następującą całkę:
Przypomnijmy sobie, że np. korzystając ze strony WolframAlpha:
Zatem nasze
:
Korzystając ze wzorów Eulera możemy zwinąć to wyrażenie do funkcji trygonometrycznych:
Rekonstrukcja sygnałów:
Na podstawie wyników poprzedniego zadania proszę napisać program, który demonstruje jaki jest
wynik składania coraz większej ilości czynników. Poniższy kod implementuje sumowanie zadanej
ilości składników szeregu i ilustruje wynik. Proszę uruchomić go dla N={2, 4, 6, 20}
W implementacji musimy zwrócić uwagę na fakt, że:
zaś dla pozostałych n całkowitych możemy uwzględnić, że
.
proszę zwrócić uwagę, że otrzymywane sumy są równe swojej części rzeczywistej
jak wygląda rekonstruowany sygnał poza przedziałem t =(-1,1) ?
# -*- coding: utf-8 -*import pylab as py
import numpy as np
def skladnik_modul_t(n ):
'''Funkcja obliczająca n-ty element szeregu Fouriera dla funkcji
moduł t
n - który element szeregu'''
if n==:
c_n = ...
else:
c_n =...
return c_n
t = np.arange(-1,1,0.1)
syg = np.zeros(len(t),dtype='complex')
N = 1 # ustalamy ile par zespolonych eksponensów sumujemy
for n in range(-N,N+1):
c = skladnik_modul_t(n)
print ('n= %d, c= %.2f'%(n,c))
syg += c * ...
py.plot(t,syg,'b', t, syg.imag,'r')
py.ylim((-0.1, 1.1))
Zadanie domowe
Analogicznie do powyższego przykładu proszę znaleźć i zbadać szereg Fouriera dla funkcji:
zaimplementować ilustrację sumowania szeregu Fouriera dla sygnału prostokątnego (przykład
z wykładu): Szereg_Fouriera
Dyskretna Transformata Fouriera (DFT)
W praktycznych zastosowaniach mamy do czynienia z sygnałami próbkowanymi o skończonej
długości. Transformata Fouriera działąjąca na takich sygnałach nazywana jest Dyskretną
Transformatą Fouriera, a algorytm najczęściej wykorzystywany do jej obliczania to szybka
trasnsformata Fouriera (fast Fourier transform FFT). Formułę na współczynniki FFT można
otrzymać z szeregu Fouriera. Załóżmy, że sygnał który chcemy przetransformować składa się z
próbek.
i próbki pobierane były co
sekund. Zakładamy, że analizowany sygnał to jeden okres
nieskończonego sygnału o okresie
. Wprowadźmy oznaczenie:
.
Przepiszmy wzór na współczynniki szeregu Fouriera. Ponieważ sygnał jest teraz dyskretny, całka
zamieni się na sumę Riemanna: pole będzie sumą pól prostokątów o bokach równych wartości
funkcji podcałkowej w zadanych punktach
i odległości między punktami
:
DFT zaimplementowana w numpy.fft jest określona jako:
DFT jest w ogólności zdefiniowane dla zespolonych argumentów i zwraca zespolone współczynniki.
Odwrotna dyskretna transformata Fouriera jest zdefiniowana jako:
Zwróćmy uwagę, że różni się ona do transformaty wprost jedynie znakiem w exponencie i
normalizacją
.
FFT
Dokumentacja numpy: http://docs.scipy.org/doc/numpy/reference/routines.fft.html
numpy implementuje algorytm: "An Algorithm for the Machine Calculation of Complex Fourier
Series" James W. Cooley and John W. Tukey Mathematics of Computation Vol. 19, No. 90 (Apr.,
1965), pp. 297-301.
Wartości zwracane przez fft(a,n) (a sygnał, n ilość punktów transformaty) mają następujący
standardowy porządek: Jeśli A = fft(a, n), to
A[0] zawiera składową stałą (średnią sygnału)
A[1:n/2] zawiera współczynniki odpowiadające dodatnim częstościom
A[n/2+1:] zawiera współczynniki odpowiadające ujemnym częstościom w kolejności od
bardziej do mniej ujemnych.
Dla parzystego n A[n/2] reprezentuje dodatnia i ujemną częstość Nyquista i dla sygnałów
rzeczywistych jest liczbą rzeczywistą.
Dla nieparzystego n, element A[(n-1)/2] zawiera współczynnik dla największej częstości
dodatniej a element A[(n+1)/2] zawiera współczynnik dla największej częstości ujemnej.
Funkcja numpy.fft.fftfreq(len(A),1.0/Fs) zwraca macierz częstości odpowiadających
poszczególnym elementom wyjściowym.
Składnia: numpy.fft.fftfreq(n, d=1.0) Parametry:
n : int — długość okna.
d : skalar — okres próbkowania (odwrotność częstości próbkowania).
Zwracane częstości są obliczane w następujący sposób:
f = [0,1,...,n/2-1,-n/2,...,-1]/(d*n) jeśli n jest przyste
f = [0,1,...,(n-1)/2,-(n-1)/2,...,-1]/(d*n) jeśli n jest nieparzyste.
Funkcja numpy.fft.fftshift(A) przestawia wektor wyjściowy fft i wektor częstości, tak aby
częstość zero wypadała w środku. Zastosowanie funkcji numpy.fft.ifftshift(A) odwraca
działanie numpy.fft.fftshift(.).
Jeśli potraktujemy wejście a jako sygnał w dziedzinie czasu i policzymy A = fft(a), wówczas
np.abs(A) jest widmem amplitudowym, zaś np.abs(A)**2 jest widmem mocy. Można obliczyć
także widmo fazowe za pomocą funkcji np.angle(A).
Zadanie
Proszę wygenerować cosinusoidę oraz sinusoidę o długości 1 s, częstości 2 Hz próbkowaną 10
Hz. Proszę obliczyć współczynniki i wypisać je.
Jakiego typu liczby otrzymaliśmy?
Czy istnieją jakieś związki między współczynnikami?
Jaki jest związek między długością wejściowego sygnału i wyjściowych współczynników?
Proszę wygenerować sygnał będący sumą sinusoid o częstościach f = 30 Hz i f = 21 Hz,
amplitudach A = 2 i A = 5, fazach pi/3 i pi/4 oraz składowej stałej 0.5, o długości T = 5 s
próbkowany 128 Hz.
Narysuj wygenerowany sygnał.
Oblicz współczynniki i wypisz je. Jakiego rodzaju liczby otrzymaliśmy? Jaki jest związek
między długością wejściowego sygnału i wyjściowych współczynników?
Jaki jest związek pomiędzy argumentami zwróconych współczynników a fazą
rzeczywistych sygnałów wejściowych?
Widmo mocy dla sygnałów rzeczywistych: Transformaty rzeczywiste i
Hermitowskie
Jeśli sygnał wejściowy jest rzeczywisty to jego transformata jest hermitowska, tzn. współczynnik przy
częstości
jest sprzężony ze współczynnikiem przy częstości
. Oznacza to, że dla sygnałów
rzeczywistych współczynniki przy ujemnych częstościach nie wnoszą żadnej dodatkowej informacji.
Rodzina funkcji rfft wykorzystuje tą symetrię i zwracają tylko dodatnią część widma włącznie z
częstością Nyquista. Tak więc, n punktów rzeczywistych na wejściu daje na wyjściu
punktów
zespolonych. Funkcje odwrotne w tej rodzinie zakładają tą samą symetrię i aby na wyjściu uzyskać n
punktów rzeczywistych na wejściu trzeba podać
wartości zespolonych.
Dla kompletności powiedzmy jeszcze, że możliwy jest przypadek odwrotny, tzn. widmo jest czysto
rzeczywiste i odpowiada mu hermitowski sygnał zespolony. Tę symetrię wykorzystują funkcje hfft,
które zakładają, że operujemy w dziedzinie czasu
w dziedzinie częstości punktami rzeczywistymi.
punktami zespolonymi i odpowiadającymi im
Zadanie
Pobierz sygnał http://www.fuw.edu.pl/~jarekz/SYGNALY/klawisz.b.
wczytaj ten sygnał jako jeden kanał typu int16
wykreśl ten sygnał
Jest to dźwięk próbkowany częstościa Fs = 44100
można go posłuchać za omocą kodu:
import sounddevice as sd
sd.play(syg, Fs)
wykreśl widmo mocy tego sygnału tj. kwadrat modułu transformaty Fouriera (jest to syg.
rzeczywisty więc używamy funkcji z rodziny rfft)
przy okazji
wczytywanie pliku wav, tak aby był on tablicą numpy można zrobić jak w poniższym kodzie,
wówczas w Fs mamy częstośc próbkowania sygnału audio, a w macierzy syg mamy sygnał
(może być stereo: lewy i prawy kanał)
from scipy.io.wavfile import read
import sounddevice as sd
(Fs, syg) = read('plik.wav')
L = syg[:,]
sd.play(syg[:,], Fs)
Co musimy z tego zapamiętać?
Analiza Fourierowska polega na rzutowaniu sygnału na sygnały próbne: sinusoidy o znanych
częstościach
Ze współczynników transformaty można odtworzyć oryginalny sygnał: mamy więc dwie
reprezentacje sygnału:
w dziedzinie czasu
w dziedzinie częstości
między reprezentacjami przechodzimy za pomocą transformaty Fouriera i odwrotnej
transformaty Fouriera
reprezentacja częstościowa jest na ogół zespolona: widmo mocy to kwadrat modułu
transformaty Fouriera
Analiza_sygnałów_-_ćwiczenia/Fourier