Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ps:labs_python:09 [2023/10/19 13:30]
constantin.savu1510 created
ps:labs_python:09 [2023/12/13 09:00] (current)
ionut.gorgos
Line 1: Line 1:
 ===== Laboratorul 09. ===== ===== Laboratorul 09. =====
-<​hidden>​ 
 ==== Convoluția,​ filtre FIR și metoda de proiectare folosind ferestre ==== ==== Convoluția,​ filtre FIR și metoda de proiectare folosind ferestre ====
-Prezentarea PowerPoint pentru acest laborator poate fi găsită aici: [[https://​docs.google.com/​presentation/​d/​16NWgSnRxFygNBcrHc7IvEfMR_MzZxyu7/​edit?​usp=sharing&​ouid=110538702824281541719&​rtpof=true&​sd=true|aici]] 
  
 În acest laborator vom face câteva exerciții pentru a ne familiariza cu operația de convoluție precum și cu filtre cu răspunsul finit la impuls (finite impulse response - FIR) și cu metode de proiectare a acestora prin metode folosind ferestre. În acest laborator vom face câteva exerciții pentru a ne familiariza cu operația de convoluție precum și cu filtre cu răspunsul finit la impuls (finite impulse response - FIR) și cu metode de proiectare a acestora prin metode folosind ferestre.
Line 17: Line 15:
 $y(n) = h(k) \ast x(n) = \sum_{k=0}^{M-1} h(k) \cdot x(n-k)$, $y(n) = h(k) \ast x(n) = \sum_{k=0}^{M-1} h(k) \cdot x(n-k)$,
  
-unde $M$ este lungimea secvenței h(k). De reținut că această operație definește un //singur// element de ieșire y(n). Pentru următorul element de ieșire, y(n+1), trebuie ​sa shiftăm secvența h(k) astfel încât să se potrivească cu elementele [x(n+1), x(n), ..., x(n-M+2)]. Vedeți slide-urile 5 și 6 {{:​ps:​labs:​fir_lyons.pdf|aici}}.+unde $M$ este lungimea secvenței h(k). De reținut că această operație definește un //singur// element de ieșire y(n). Pentru următorul element de ieșire, y(n+1), trebuie ​să shiftăm secvența h(k) astfel încât să se potrivească cu elementele [x(n+1), x(n), ..., x(n-M+2)]. Vedeți slide-urile 5 și 6 {{:​ps:​labs:​fir_lyons.pdf|aici}}.
  
 În general presupunem că secvența h(k) are un număr $M$ finit și, în general, mic de elemente. ​ În general presupunem că secvența h(k) are un număr $M$ finit și, în general, mic de elemente. ​
-/​*<​hidden>​*/​ In our context, these elements will usually be the //taps// of a filter, and the convolution operation will be used to filter an input sequence x(n), as we shall see in the following exercises. /​*</​hidden>​*/​ 
  
 Rezolvați următoarele exerciții: Rezolvați următoarele exerciții:
   - Dacă x(n) are N elemente și h(k) are M elemente, câte elemente are secvența obținută prin convoluție $h(k) \ast x(n)$? (presupunând că efectuăm convoluția doar pe elementele diferite de zero, adică atunci când elementele celei mai scurte secvențe se suprapun în totalitate cu elementele celeilalte)   - Dacă x(n) are N elemente și h(k) are M elemente, câte elemente are secvența obținută prin convoluție $h(k) \ast x(n)$? (presupunând că efectuăm convoluția doar pe elementele diferite de zero, adică atunci când elementele celei mai scurte secvențe se suprapun în totalitate cu elementele celeilalte)
-  - Fie x(n) secvența [1, 3, 5, 7, 5, 4, 2] și h(k) secvența [0.1, 0.3, 0.1]. Secvența obținută prin convoluție $y(n) = h(k) \ast x(n), n \in \{1,​2,​3,​4,​5\}$ ar trebui ​sa aibă 5 elemente. Scrieți fiecare dintre aceste elemente ca un produs scalar. Observați că trebuie să inversați ordinea secvenței x(n) (doar partea care se înmulțeste cu filtrul) înainte să o înmulțiți cu h(k) (alternativ,​ puteți inversa o singură dată elementele filtrului). +  - Fie x(n) secvența [1, 3, 5, 7, 5, 4, 2] și h(k) secvența [0.1, 0.3, 0.1]. Secvența obținută prin convoluție $y(n) = h(k) \ast x(n), n \in \{1,​2,​3,​4,​5\}$ ar trebui ​să aibă 5 elemente. Scrieți fiecare dintre aceste elemente ca un produs scalar. Observați că trebuie să inversați ordinea secvenței x(n) (doar partea care se înmulțeste cu filtrul) înainte să o înmulțiți cu h(k) (alternativ,​ puteți inversa o singură dată elementele filtrului). 
-  - Fie x(n) o secvență de $N=64$ elemente corespunzătoare unei sinusoide de frecvență $f=3$ kHz, eșantionată cu $f_s=64$ kHz. Fie h(k) secvența [0.1, 0.2, 0.2, 0.2, 0.1]. Generați aceste secvențe în MATLAB ​și implementați convoluția pentru a obține elementele $y(n) = h(k) \ast x(n)$. Plotați inputul x(n) și ieșirea y(n); folosiți funcția //stem// în locul funcției //plot// pentru acest exercițiu.+  - Fie x(n) o secvență de $N=64$ elemente corespunzătoare unei sinusoide de frecvență $f=3$ kHz, eșantionată cu $f_s=64$ kHz. Fie h(k) secvența [0.1, 0.2, 0.2, 0.2, 0.1]. Generați aceste secvențe în Python ​și implementați convoluția pentru a obține elementele $y(n) = h(k) \ast x(n)$. Plotați inputul x(n) și ieșirea y(n); folosiți funcția //stem// în locul funcției //plot// pentru acest exercițiu.
   - Înlocuiți x(n) cu secvența de impuls cu 9 elemente [0, 0, 0, 0, 1, 0, 0, 0, 0] și efectuați convoluția cu aceeași secvență h(k) ca mai sus. Ce obțineți ca y(n)? Cum se numește aceasta?   - Înlocuiți x(n) cu secvența de impuls cu 9 elemente [0, 0, 0, 0, 1, 0, 0, 0, 0] și efectuați convoluția cu aceeași secvență h(k) ca mai sus. Ce obțineți ca y(n)? Cum se numește aceasta?
-  - Încercați operațiile de mai sus folosind funcția ​MATLAB ​//conv//. Obțineți aceleași rezultate? Care sunt diferențele?​+  - Încercați operațiile de mai sus folosind funcția //np.convolve// din NumPy sau //​signal.convolve//​ din //​scipy.signal//​. Obțineți aceleași rezultate? Care sunt diferențele?​ 
 +  - [<color red>​BONUS</​color>​] Teorema Convoluției. Convoluția în timp [ $h(k) \ast x(n)$ ] este echivalentă cu înmulțirea element cu element a spectrelor în frecvență [ $H(m) \cdot X(m)$ ] și invers. Pentru a testa asta faceți următorii pași: 
 +  * Folosiți secvența h(k) = [0.1, 0.2, 0.2, 0.2, 0.1], dar adăugați încă 59 de zerouri la finalul ei, precum am făcut în laboratoarele precedente. 
 +  * Aplicați FFT peste această secvență și afișați spectrul ei (cu stem). 
 +  * Aplicați FFT peste sinusoida de la subpunctul 3 și afișați spectrul ei (cu stem). 
 +  * Înmulțiți element cu element cele două spectre și afișați rezultatul cu stem. S-a modificat ceva? 
 +  * Reveniți în domeniul timp folosind //ifft// și //​np.real//​. 
 +  * Comparați rezultatul de mai sus cu cel al funcției //​np.convolve//​ din NumPy sau //​signal.convolve//,​ setând parametrul //​mode='​full'//​ și păstrând doar primele N elemente. Obțineți aceleași rezultate? Care sunt diferențele?​
  
 <note tip> <note tip>
Line 43: Line 47:
   * Țineți minte că acest spectru poate fi văzut ca ieșirea din DFT(FFT), adică primul element corespunde frecvenței //0//, pe când următoarele //N/2-1// corespund frecvențelor pozitive, iar ultimele //N/2// componente reprezintă frecvențele negative.   * Țineți minte că acest spectru poate fi văzut ca ieșirea din DFT(FFT), adică primul element corespunde frecvenței //0//, pe când următoarele //N/2-1// corespund frecvențelor pozitive, iar ultimele //N/2// componente reprezintă frecvențele negative.
  
-  - Acum aplicați inversa DFT(în practică inversa FFT, //ifft// în MATLAB) pentru a obține secvența corespunzătoare în domeniul timp hk(n). Rețineți: trebuie să aplicați funcția //​ifftshift//​ pe rezultat pentru a obține o funcție sinc simetrică, adică folosiți ceva precum: <​code ​matlab>hk = ifftshift(ifft(HK));</​code>​ +  - Acum aplicați inversa DFT(în practică inversa FFT, //ifft// în Python) pentru a obține secvența corespunzătoare în domeniul timp hk(n). Rețineți: trebuie să aplicați funcția //​ifftshift//​ pe rezultat pentru a obține o funcție sinc simetrică, adică folosiți ceva precum: <​code ​python>hk = ifftshift(ifft(HK));</​code>​ 
-  - Trunchiați secvența hk(n) prin selectarea a doar //L=65// de eșantioane din centru(32 din stânga maximului funcției sinc, maximul funcției, și 32 de eșantioane din dreapta). Aceasta corespunde multiplicării secvenței hk(n) cu o fereastră ​rectangulară centrată în punctul maxim al funcției sinc. Plotați secvența. +  - Trunchiați secvența hk(n) prin selectarea a doar //L=65// de eșantioane din centru(32 din stânga maximului funcției sinc, maximul funcției, și 32 de eșantioane din dreapta). Aceasta corespunde multiplicării secvenței hk(n) cu o fereastră ​dreptunghiulară centrată în punctul maxim al funcției sinc. Plotați secvența. 
-  - Aplicați DFT(//​fft//​) pe secvența trunchiată,​ adică cea înmulțită cu fereastra ​rectangulară (care conține doar 1) și plotați spectrul (cu //plot//). Rețineți: este important aici, precum și la primul plot pentru filtru trece-jos ideal, să notăm axa frecvențelor (axa x) ca o funcție de $F_s$, adică de la //0// la //1//. Vedeți diferențe față de filtrul ideal trece-jos? Acestea sunt efectele ferestrei dreptunghiulare. +  - Aplicați DFT(//​fft//​) pe secvența trunchiată,​ adică cea înmulțită cu fereastra ​dreptunghiulară (care conține doar 1) și plotați spectrul (cu //plot//). Rețineți: este important aici, precum și la primul plot pentru filtru trece-jos ideal, să notăm axa frecvențelor (axa x) ca o funcție de $F_s$, adică de la //0// la //1//. Vedeți diferențe față de filtrul ideal trece-jos? Acestea sunt efectele ferestrei dreptunghiulare. 
-  - Folosiți aceeași secvență trunchiată (hk(n)), dar înmulțiți-o cu o fereastră precum //​Blackman//​ (//​blackman//​ în MATLAB). Efectuați din nou DFT și plotați spectrul (cu //plot//). Arată mai bine?. +  - Folosiți aceeași secvență trunchiată (hk(n)), dar înmulțiți-o cu o fereastră precum //​Blackman//​ (//np.blackman// în Python). Efectuați din nou DFT și plotați spectrul (cu //plot//). Arată mai bine?. 
-  - În final, folosiți ca intrare sinusoida din Exercițiul 1 ca x(n) și filtrați-o printr-o convoluție cu secvența obținută mai sus după folosirea ferestrei Blackman(folosiți funcția //conv// din MATLAB). Plotați intrarea și ieșirea în aceeași figură folosind //stem// pentru a observa efectele filtrului.+  - În final, folosiți ca intrare sinusoida din Exercițiul 1 ca x(n) și filtrați-o printr-o convoluție cu secvența obținută mai sus după folosirea ferestrei Blackman(folosiți funcția //np.convolve// din NumPy sau //​signal.convolve//​ din //​scipy.signal//​). Plotați intrarea și ieșirea în aceeași figură folosind //stem// pentru a observa efectele filtrului.
  
-=== Exercițiul 3 -- Proiectarea rapidă de filtre FIR folosind ​MATLAB ​===+=== Exercițiul 3 -- Proiectarea rapidă de filtre FIR folosind ​Python ​===
 [<color red>​2p</​color>​] [<color red>​2p</​color>​]
  
-Putem descrie un filtru (sistem liniar) cu feedback(IIR având termenii $a_i$ mai jos) sau fără feedback (FIR) folosind o ecuație cu diferențe precum:+Putem descrie un filtru (sistem liniar) cu feedback (IIR având termenii $a_i$ mai jos) sau fără feedback (FIR) folosind o ecuație cu diferențe precum: 
 $y(n) = b_0 \cdot x(n) + b_1 \cdot x(n-1) + \ldots + b_q \cdot x(n-q) + a_1 \cdot y(n-1) + \ldots + a_p \cdot y(n-p)$ $y(n) = b_0 \cdot x(n) + b_1 \cdot x(n-1) + \ldots + b_q \cdot x(n-q) + a_1 \cdot y(n-1) + \ldots + a_p \cdot y(n-p)$
  
 Putem reprezenta întârzierile $x(n-1)$ ca $z^{-1} \cdot x(n)$, unde $z=e^{j2\pi}$. Putem reprezenta întârzierile $x(n-1)$ ca $z^{-1} \cdot x(n)$, unde $z=e^{j2\pi}$.
 Apoi, obținem o ecuație care depinde doar de $x(n)$ și $y(n)$ și obținem funcția de transfer a filtrului $H(z) = \frac{Y(z)}{X(z)}$ precum: Apoi, obținem o ecuație care depinde doar de $x(n)$ și $y(n)$ și obținem funcția de transfer a filtrului $H(z) = \frac{Y(z)}{X(z)}$ precum:
 +
 $H(z) = \frac{\sum_{k=0}^q b_k \cdot z^{-k}}{1 - \sum_{k=1}^p a_k \cdot z^{-k}}$ $H(z) = \frac{\sum_{k=0}^q b_k \cdot z^{-k}}{1 - \sum_{k=1}^p a_k \cdot z^{-k}}$
  
-În MATLAB, puteți folosi funcția //fir1// pentru a obține ​rapid elementele ​$b_i$ ale unui filtru FIR trece-jos, trece-bandă sau trece-sus(ignorați coeficienții $a_i$ deocamdată). Apoi puteți folosi funcția //filter// pentru a filtra orice secvență folosind coeficienții $b_i$ dați de //fir1//, iar $a_0=1$.+În Python, puteți folosi funcția //signal.firwin// din SciPy, ​pentru a obține ​coeficienții ($b_i$) ai unui filtru FIR trece-jos, trece-bandă sau trece-sus(ignorați coeficienții $a_i$ deocamdată). Apoi puteți folosi funcția //signal.lfilter// din SciPy, ​pentru a filtra orice secvență folosind coeficienții $b_i$ dați de //signal.firwin//, iar $a_0 = 1$.
  
-Pentru acest exercițiu, ​folosiți funcția //fir1// pentru a proiecta ​filtre FIR trece-jos, trece-bandă și trece-sus. Apoi folosiți funcția //filter// pentru a testa filtrele cu niște sinusoide ca în Exercițiul 1, cu $f=3$ kHz, $15$ kHz, $30$ kHz . Puteți verifica designul filtrelor folosind //freqz//+Pentru acest exercițiu, ​trebuie să proiectați filtre FIR trece-jos ​(folosiți cutoff = 0.1), trece-bandă ​(folosiți cutoff = [0.2, 0.5]) și trece-sus ​(folosiți cutoff = 0.75). Puteți alege //numtaps = 65//. Apoi folosiți funcția //signal.lfilter// pentru a testa filtrele cu niște sinusoide ca în Exercițiul 1, cu $f=3$ kHz, $15$ kHz, $30$ kHz. Afișați cu stem, în subplot-uri sinusoidele inițiale și pe cele filtrate. 
-<​code ​matlab>freqz(b,1);</​code>​ +Pentru răspunsul în frecvență,​ vă puteți folosi de următorul cod: 
-/*<​hidden>​*/​ + 
-<note warning>​Pentru a putea folosi funcțiile ​//fir1// și //freqz// trebuie să instalați pachetul signal din Octave+<​code ​python> 
-<code matlab> +freq, H = signal.freqz(b_low, 1, fs=fs
-pkg install -forge -nodeps signal+plt.figure() 
 +plt.plot(freq,​ 20 np.log10(abs(H))) 
 +plt.xlabel('​Frequency [Hz], from 0 to fs/2') 
 +plt.ylabel('​Amplitude [dB]') 
 +plt.title('​Digital Filter Frequency Response'​) 
 +plt.grid() 
 +plt.show()
 </​code>​ </​code>​
-iar apoi să-l încărcați: +unde b_low sunt coeficienții $b_i$ ai unui filtru FIR trece-jos.
-<code matlab>​ +
-pkg load signal +
-</​code>​ +
-</​note>​ +
-/​*</​hidden>​*/​+
  
-Pentru răspunsul la impuls puteți folosi: +=== Exercițiul 4 -- Proiectarea rapidă de filtre FIR/IIR folosind MATLAB === 
-<code matlab>stem(b);</code> +[<color red>BONUS</color>]
-Ar trebui să vedeți sinc-ul digital.+
  
-Pentru răspunsul ​în frecvență, vă puteți folosi ​de următorul cod:+În acest exercițiu, încercăm să urmăm pașii de la exercițiul 3, dar în **MATLAB**. Pentru a accesa MATLAB, puteți folosi MATLAB instalat pe PC-urile din laborator sau să folosiți **MATLAB Online**din browser. Pentru MATLAB Online, trebuie să vă creați un cont cu adresa ​de e-mail de la facultate pe site-ul [[https://​www.mathworks.com/​mwaccount/​register|acesta]].
  
-<code matlab>​ +În MATLABputeți folosi funcția //fir1// pentru a obține rapid elementele $b_i$ ale unui filtru FIR trece-jostrece-bandă sau trece-sus. Apoi puteți folosi funcția //filter// pentru a filtra orice secvență folosind coeficienții $b_i$ dați de //fir1//iar $a_0 = 1$. 
-[Hfreq] = freqz(b,1,Nfs); + 
-figure; +Pentru acest exercițiufolosiți funcția //fir1// pentru a proiecta filtre FIR trece-jos, trece-bandă și trece-sus. Apoi folosiți funcția //filter// pentru a testa filtrele cu aceleași secvențe ca în exercițiul precedent. Puteți verifica designul filtrelor folosind tool-ul //fvtool//.
-plot(freqabs(H)); +
-xlabel('​Frequency (Hz)'​);​ +
-ylabel('​Frequency response'​);​ +
-</code>+
  
-</hidden>+De asemenea puteți folosi tool-ul MATLAB ​//fdatool// pentru a proiecta și analiza rapid performanțele filtrelor FIR și IIR: 
 +  - Generați un filtru FIR trece-jos folosind o fereastră Kaiser, având Fs = 48000 Hz, Fc = 10000 Hz, cu N=10 coeficienți(ordin) 
 +  - Generați un filtru IIR trece-jos (Butterworth sau Chebyshev type I) cu aceiași parametri. 
 +  - Comparați amplitudinea răspunsului. 
 +  - Încercați să creați un filtru FIR cu un răspuns similar cu al unui filtru IIR, prin creșterea numărului de coeficienți. 
 +    
 +După proiectarea filtrelor precum ați dorit, le puteți salva (File->Generate MATLAB Code) și să le folosiți direct în alte scripturi MATLAB pentru a filtra diverse semnale.
  
ps/labs_python/09.1697711423.txt.gz · Last modified: 2023/10/19 13:30 by constantin.savu1510
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0