Ćwiczenia 4
Analiza_sygnałów_-_ćwiczenia/AR_1
Funkcja autokorelacji
Dla sygnału [math]x(t)[/math] możemy badać jak jest on do siebie podobny dla przesunięciaczasowego [math]\tau [/math]:
- [math]\sigma _{xx}(\tau ) = \int {x(t) x(t+\tau ) dt} [/math]
Zwróćmy uwagę na związek funkcji korelacji:
- z iloczynem skalarnym wektorów [math]x(t)[/math] i jego przesuniętej wersji [math]x(t +\tau)[/math]
- ze splotem.
Dla skończonych dyskretnych sygnałów mamy estymatory korelacji:
- [math]R_{xx}(m) = E\lbrace x_{n+m}x^*_n \rbrace = E\lbrace x_{n}x^*_{n-m} \rbrace [/math]
oraz kowariancji:
- [math]C_{xx}(m) = E\lbrace (x_{n+m}-\bar{x}) (x_n-\bar{y})^*\rbrace = R_{xx}(m) - \bar{x} \bar{x}^*[/math]
Funkcję [math]R[/math] można estymować z jednej realizacji procesu (zakładamy jego ergodyczność):
- [math] \widehat{R}_{xx}(m) = \left\lbrace \begin{array}{ll} \sum _{n=0}^{N-m-1}{x_{n+m} x_n^*} & m \ge 0 \\ \widehat{R}_{xx}^*(-m) & m \lt 0 \end{array} \right.[/math]
Zadanie: Jak obliczyć funkcję autokorelacji?
W pythonie mamy wydajną implementację funkcji autokorelacji (tak naprawdę to funkcji korelacji wzajemnej, której szczególnym przypadkiem jest autokorelacja) w: numpy.correlate. Zanim jednak przejdziemy do rutynowego korzystania z tej funkcji warto sobie wyrobić pewną intuicję co do jej działania. Możemy sobie to działanie wyobrazić tak, że tworzymy dwie kopie naszego sygnału wydłużone zerami. jedna kopia ma oryginalny sygnał po środku, a w drugiej będzie on stopniowo przesuwany od pozycji takiej w której z nieruchomą kopią ma jeden punkt wspólny z lewej stron do takiej, kiedy ma jeden punkt wspólny z prawej strony. W każdym położeniu wzajemnym sygnałów musimy policzyć ich iloczyn skalarny. Poniższy kod pomoże nam to zilustrować:
import numpy as np
import pylab as py
# Niech nasz sygnał będzie:
x = np.array([1,2,3,2,1])
# Ma on długość
N = ...
# przygotujmy miejsce na kopie sygnału
# najpierw kopia nieruchoma na środku
x_2 = np.zeros(3*N-2, dtype = 'int')
x_2[...] = x
print('liczymy f. autokorelacji sygnału x= ',x)
for k in range(-N,N-1):
print(' ')
x_1 = np.zeros(3*N-2, dtype = 'int')
x_1[...]=x # to jest kopia sygnału x cofnięta o k próbek w stosunku do nieruchomej kopii
print('x1: \t'+str(x_1))
print('x2: \t'+str(x_2))
print(40*'-')
print('x1*x2\t', x_1*x_2)
f_corr[k+N] = ...
print('f_corr(',k+1,') = \t',...)
# porównajmy wynik z wywołaniem funkcji bibliotecznej:
...
Badanie zależności między sygnałami przy pomocy funkcji korelacji
def gabor(t0=0.5, sigma = 0.1, f = 10, T = 1, Fs = 128, phi =0 ):
dt = 1.0/Fs
t = np.arange(0,T,dt)
s = np.exp( -0.5*((t-t0)/sigma)**2 )*np.cos(2*np.pi*f*t + phi)
return (s,t)
- wygeneruj dwa sygnały długości [math]T=2s[/math] próbkowane z częstością [math]f_s=128[/math] Hz przy uzyciu funkcji gabor. Oba gabory mają częstość [math]f=10[/math] Hz i [math]\sigma =0.1[/math] s. Oba sygnały s1 i s2 są centrowane na [math]t_0=0.5[/math] s
- oblicz funkcję korelacji wzajemnej z = np.correlate(s1,s2,mode='full')
- Jaka jest długość sygnału z?
- Wykreśl w funkcji odpowiednich skal czasu na dwóch subplotach: na górnym sygnały s1 i s2 a na dolnym z.
- Zaobserwuj położenie maksimum funkcji korelacji wzajemnej. Jaki jest związek oscylacji w funkcji korelacji wzajemnej z oscylacjami funkcji s1 i s2
Wskazówka: Związek między czasem t dla sygnałów s1 i s2 a skalą czasu dla korelacji f_corr_t można zapisać w Pythonie:
f_corr_t = np.zeros(2*len(t)-1)
f_corr_t[0:len(t)]= -t[len(t)::-1]
f_corr_t[len(t):]=t[1:]
- Powtórz punkty 1-5 zmieniając położenie sygnału s1 od 0.5 do 0.1 z krokiem 0.1, oraz sygnału s2 od 0.5 do 0.9 z krokiem 0.1. Zaobserwuj związek między położeniem maksimum funkcji korelacji wzajemnej a odległością między centrami gaborów.
- Wykonaj analogiczne iteracje zachowując stałe położenie gaborów (dla obu t0 = 0.5 zmieniaj natomiast częstość s2 [math]f[/math] od 10 Hz do 16 Hz co 2 Hz. Wymuś stały zakres osi y na -100:100(funkcja pylab.ylim((-100,100)))
*