Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R Prof. Michele Scarpiniti Dipartimento di Ingegneria dell Informazione, Elettronica e Telecomunicazioni Sapienza Università di Roma http://ispac.ing.uniroma1.it/scarpiniti/index.htm michele.scarpiniti@uniroma1.it Roma, 15 Ottobre 2012 M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 1 / 29
1 Le sequenze 2 M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 2 / 29
Le sequenze M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 3 / 29
Le sequenze numeriche Le sequenze I segnali a tempo-discreto (TD) sono matematicamente rappresentati con una sequenza di numeri x[n] con < n < : x[n] = {..., x[ k],..., x[ 2], x[ 1], x[0], x[1], x[2],..., x[k],...}, Una sequenza x[n] per cui x[n] 0, n < 0 è detta sequenza causale. Dunque, senza perdita di generalità, da ora in poi le sequenze saranno di tipo causale se non diversamente specificato. In Matlab una sequenza viene semplicemente rappresentata come un vettore, quindi i valori della sequenza sono racchiusi tra parentesi quadre, separati o meno da virgole: >> x = [x[0], x[1], x[2], \ldots, x[k], \ldots, x[n]]; E ovviamente possibile rappresentare in Matlab solo sequenze di durata finita, ovvero con indice 0 n N. M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 4 / 29
Le sequenze numeriche Le sequenze Per visualizzare una sequenza numerica è possibile utilizzare il comando >> stem(h); che visualizza un pallino sul valore del campione n-simo. Ad esempio: 6 5 4 3 >> x =[3-2 0 1-3 5 2-2 0 3]; >> stem(x); >> grid; 2 1 0 1 2 3 4 1 2 3 4 5 6 7 8 9 10 11 M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 5 / 29
Le sequenze numeriche Le sequenze Si noti che il primo campione della sequenza corrisponde al campione etichettato con 1, a differenza di quanto accade in altri linguaggi, come il C/C++, dove si parte con l indice 0. Per ottenera la lunghezza di una sequenza x[n], ovvero il numero di campioni, è possibile utilizzare il comando length(x). Per l esempio precedente si ha: >> N = length(x) N = 10 Se vogliamo il valore del k-esimo campione, basta digitare x(k), ad esempio: >> x5 = x(5) x5 = -3 M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 6 / 29
Le sequenze numeriche Le sequenze Per cambiare il valore del k-esimo campione si usa x(k) = val, ad esempio >> x(5) = 2; >> x = 3-2 0 1 2 5 2-2 0 3 Per eliminare il k-esimo campione dalla sequenza x[n] si usa x(k) = [], ad esempio >> x(5) = []; >> x = 3-2 0 1 5 2-2 0 3 A questo punto la sequenza x[n] è lunga N 1 campioni. M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 7 / 29
Le sequenze numeriche Le sequenze Per effettuare lo shifting (di solito a destra) di k campioni di una sequenza è necessario eseguire due operazioni: 1 lo spostamento di tutti i campioni di una sequenza di k posizioni; 2 il riempimento con zeri delle posizioni liberate. N x[1] x[2] x[k] x[k+1] x[n-1] x[n] 0 0 x[1] x[2] x[k] x[k+1] x[n-1] x[n] N+2 >> x(k+1:n+k) = x; >> x(1:k) = 0; M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 8 / 29
Le sequenze numeriche Le sequenze Per l esempio precedente, ponendo ad esempio k = 3, ricordando che N = 10 si ottiene >> x(4:13) = x; >> x(1:3) = 0; >> x = 0 0 0 3-2 0 1 2 5 2-2 0 3 Si ottiene quindi come risultato una sequenza lunga N +k!! Questo risultato è dovuto al fatto che il primo elemento di un vettore è considerato in Matlab quello con indice pari a 1. Inoltre, per velocizzare l operazione conviene preventivamente inizializzare il vettore x come un vettore di zeri di lunghezza opportuna. M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 9 / 29
M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 10 / 29
Il filtro: Matlab R Date due sequenza x[n] e h[n] la convoluzione tra di esse è una sequenza y[n] definita come y[n] = x[n] h[n] = N x[k]h[n k] In Matlab la convoluzione tra le due sequenze x[n] (rappresentante il segnale di ingresso di lunghezza N) e h[n] (rappresentante la risposta impulsiva di lunghezza M) può essere ottenuta mediante il seguente comando >> y=conv(h,x); k=0 Questa operazione produce una sequenza y[n] di lunghezza L = N + M 1. M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 11 / 29
Il filtro in frequenza: Matlab R In Matlab una convoluzione tra due sequenze x[n] (rappresentante il segnale di ingresso di lunghezza N) e h[n] (rappresentante la risposta impulsiva di lunghezza M) può essere anche essere ottenuta passando attraverso il dominio della frequenza, con il metodo dell overlap and add: y[n] = IFFT {FFT {x[n]} FFT {h[n]}} dove indica il prodotto elemento per elemento. Viene adoperato il seguente comando >> y=fftfilt(h,x); Viene restituito una sequenza y[n] della stessa dimensione di x[n]. Questa funzione è vantaggiosa per ingressi x[n] (o risposte impulsive h[n]) particolarmente lunghi. M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 12 / 29
Il filtro in frequenza: overlap and add Nel metodo overlap and add (OA), la sequenza x[n] di ingresso viene suddivisa in un numero intero di blocchi di lunghezza L. La convoluzione con il filtro (di lunghezza M) è effettuata con una convoluzione circolare, facendo le FFT a N L + M 1 punti (di solito N è una potenza di 2). Se necessario si effettua zero padding. I blocchi in ingresso vengono sovrapposti parzialmente di M 1 campioni e sommati al blocco precedente: M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 13 / 29
Filtri FIR Un convolutore (cioè un circuito che implementa una somma di convoluzione) può anche essere implementato come filtro FIR. Il filtro FIR è caratterizzato da una risposta impulsiva di lunghezza finita. Inoltre esso è un filtro la cui rappresentazione in frequenza ha solo il numeratore. y[n] = N 1 k=0 b k x[n k] = b 0 x[0] + b 1 x[n 1] +... + b N 1 x[n N + 1] In questo caso la risposta impulsiva h[n] è la sequenza h[n] = {b 0, b 1, b 2,..., b N } Nel dominio della trasformata Z (in frequenza) posso scrivere: H(z) = M b k z k k=0 M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 14 / 29
Filtri IIR Un modello più generale di filtro è quello in cui l uscita all istante n-esimo è funzione non solo degli ingressi, ma anche delle uscite agli istanti precedenti. Tale tipo di filtro è denoominato filtro IIR ed è caratterizzato da una risposta impulsiva di lunghezza infinita. In frequenza è rappresentato da un numeratore e da un denominatore. y[n] = N 1 k=0 M 1 b k x[n k] j=1 a j y[n j] dove si è posto a 0 = 1 (è il coefficiente di y[n]). Nel dominio della trasformata Z (in frequenza) posso scrivere: H(z) = M b k z k k=0 N a k z k k=0 M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 15 / 29
Il filtro: Matlab R In Matlab l uscita y[n] di una sequenza x[n] di un filtro IIR, rappresentato dai vettori a = [a 0, a 1,..., a M 1 ] e b = [b 0, b 1,..., b N 1 ], può essere ottenuta mediante il seguente comando >> y=filter(b,a,x); Questa operazione produce un vettore y di lunghezza pari alla lunghezza dell ingresso x[n]. Ovviamente posso utilizzare questa funzione anche per il calcolo dell uscita di un filtro FIR: basta porre a 0 = 1 e tutti gli a k = 0, k 0: >> y=filter(b,1,x); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 16 / 29
o: ritardo Costruiamo un semplice filtro per effettuare un ritardo di T secondi, ovvero D = F s T campioni. >> [s,fs]=wavread( radio.wav ); >> h=zeros(1,16000); >> D=2*Fs; >> h(d)=1; >> y=fftfilt(h,s); >> soundsc(y,fs); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 17 / 29
o: eco Ora otteniamo un eco ripetendo il segnale dopo un ritardo di T secondi, ovvero D = F s T campioni. >> [s,fs]=wavread( tada.wav ); >> h=zeros(1,64000); >> h(1)=1; >> D=1.3*Fs; >> h(d)=0.9; >> y=conv(h,s(:,1)); >> soundsc(y,fs); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 18 / 29
o: riverbero artificiale Un primo esempio di riverbero può essere ottenuto con un filtro contenente due o tre picchi entro un secondo di risposta. >> [s,fs]=wavread( radio.wav ); >> h=zeros(1,16000); >> h(1)=1; >> h(128)=0.9; >> h(800)=0.8; >> y=fftfilt(h,s); >> soundsc(y,fs); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 19 / 29
o: riverbero artificiale Un riverbero più naturale può essere ottenuto, come ha mostrato Schroeder, utilizzando filtri comb. Un primo esempio è riportato di seguito. H(z) = z D 1 + gz D Di conseguenza è possibile scrivere i due vettori b e a dei coefficienti del numeratore e denominatore, rispettivamente: b = [ 0 0 1 0 0 ] a = [ 1 0 0 g 0 0 ] ed uso: >> y=filter(b,a,x); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 20 / 29
o: riverbero artificiale Vediamo una semplice implementazione del filtro: >> [x,fs]=wavread( radio.wav ); >> g=0.7; >> D=0.1*Fs; >> a=zeros(1,d); >> b=zeros(1,d); >> b(d)=1; >> a(1)=1; >> a(d)=g; >> y=filter(b,a,x); >> soundsc(y,fs); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 21 / 29
o: riverbero artificiale Una versione alternativa di filtro comb per la costruzione di un riverbero artificiale è descritta di seguito. H(z) = 1 1 gz D Di conseguenza è possibile scrivere i due vettori b e a dei coefficienti del numeratore e denominatore, rispettivamente: ed uso: >> y=filter(1,a,x); b = 1 a = [ 1 0 0 g 0 0 ] M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 22 / 29
o: riverbero artificiale Vediamo una semplice implementazione del filtro: >> [x,fs]=wavread( radio.wav ); >> g=0.7; >> D=0.1*Fs; >> a=zeros(1,d); >> b=1; >> a(1)=1; >> a(d)=-g; >> y=filter(b,a,x); >> soundsc(y,fs); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 23 / 29
o: riverbero artificiale Un effetto più realistico di riverbero diffuso, può essere ottenuto utilizzando un filtro all-pass (AP), come di seguito descritto. H(z) = g + z D 1 + gz D Di conseguenza è possibile scrivere i due vettori b e a dei coefficienti del numeratore e denominatore, rispettivamente: b = [ g 0 0 1 0 0 ] a = [ 1 0 0 g 0 0 ] ed uso, come al solito: >> y=filter(b,a,x); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 24 / 29
o: riverbero artificiale Vediamo una semplice implementazione del filtro: >> [x,fs]=wavread( radio.wav ); >> g=0.7; >> D=0.1*Fs; >> a=zeros(1,d); >> b(1)=g; >> b(d)=1; >> a(1)=1; >> a(d)=g; >> y=filter(b,a,x); >> soundsc(y,fs); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 25 / 29
o: filtro passa-banda Nel seguente esempio vengono caricati da file i coefficienti di un filtro passabanda e usati per filtrare il segnale radiofonico. >> [x,fs]=wavread( radio.wav ); >> load tel_filter %carica in h i coefficienti del filtro >> y=fftfilt(h,x); >> soundsc(y,fs); >> pause; >> soundsc(x,fs); M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 26 / 29
Ricostruzione della risposta impulsiva Se si conoscono i vettori a e b dei coefficienti del denominatore e numeratore, rispettivamente, la risposta impulsiva h[n] può essere stimata con le seguenti funzioni. >> [h,t]=impz(b,a); in t viene restituito l asse dei tempi. >> [h,t]=impz(b,a,n); >> [h,t]=impz(b,a,n,fs); restituiscono i primi N campioni della risposta impulsiva equispaziati di 1/F s. >> impz(b,a); senza argomenti di uscita, restituisce il grafico (con stem) della risposta impulsiva. M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 27 / 29
Ricostruzione della risposta impulsiva: un esempio Per un esempio pratico: >> a=zeros(1,800); >> b=zeros(1,800); >> a(1)=1; >> a(800)=0.8; >> b(800)=1; >> [h,t]=impz(b,a,8192,8000); >> stem(t,h); ottenedo la risposta: M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 28 / 29
Bibliografia Matlab MATLAB 7: Getting Started Guide. Available on-line: http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/getstart.pdf Matlab Signal Processing Toolbox: User s Guide. Available on-line: http://www.mathworks.com/access/helpdesk/help/pdf_doc/signal/signal_tb.pdf A.V. Oppenheim, R.W. Schafer. Discrete-Time Signal Processing 2-nd Edition, Prentice Hall, 1999. T.A. Davis. MATLAB Primer. 8-th Edition, CRC Press, 2010.. D.M. Smith. Engineering Computation with MATLAB. 2-nd Edition, Addison-Wesley, 2010. A. Gilat. MATLAB: An Introduction with Applications Wiley, 2008. A.D. Poularikas. Signals and Systems Primer with MATLAB. CRC Press, 2006. M. Scarpiniti Circuiti a Tempo Discreto Esercitazione 2 - Sequenze e Convoluzione in Matlab R 29 / 29