Esercizio - Convoluzione a blocchi con la DFT
In questa pagina 4
Testo (lezioni 15-17, corso Multimedia Signal Processing, UniPD; esempi svolti a lezione). Si considerano , e poi , .
- Calcolare la convoluzione lineare e la convoluzione circolare a di con ; spiegare la differenza e verificare che con (zero-padding) le due coincidono.
- Per e , calcolare con overlap-add (blocchi di , DFT a ).
- Lo stesso con overlap-save (, ).
- Scrivere in Python i due algoritmi e verificarli su un segnale casuale di campioni con un FIR di coefficienti.
Teoria usata: Convoluzione a blocchi - overlap-add e overlap-saveLa convoluzione lineare y = x * h (h lungo M) si può calcolare con la FFT scegliendo N >= Dx + M - 1 (potenza di 2): costo per campione circa 3 k log2 N contro k M del calcolo diretto, quindi la FFT conviene per M abbastanza grande (con Dx circa M, già da M = 16). Per segnali lunghi o infiniti si divide x in blocchi. Overlap-add: blocchi disgiunti di lunghezza L, ognuno convoluto con h (lunghezza L+M-1 con FFT di N >= L+M-1) e le code di M-1 campioni si sommano. Overlap-save: blocchi di N campioni sovrapposti di M-1, convoluzione circolare, si scartano i primi M-1 campioni di ogni uscita (corrotti dall'aliasing). Stesso costo.Convoluzione a blocchi - overlap-add e overlap-save →, Trasformata di Fourier discreta (DFT) e convoluzione circolareLa DFT di N campioni x[0..N-1] è X[k] = sum x[n] e^{-j2pi kn/N}, k = 0..N-1 (IDFT: x[n] = (1/N) sum X[k] e^{j2pi kn/N}); vede il segnale come periodico di periodo N e dà N campioni equispaziati della DTFT, cioè X(z) valutata sulle radici N-esime dell'unità. Se x ha durata M <= N non c'è aliasing temporale e lo zero-padding (N > M) infittisce solo i campioni della stessa DTFT. Proprietà: traslazione circolare, simmetria coniugata X[k] = X*[N-k], prodotto = convoluzione circolare. La convoluzione circolare coincide con la lineare solo se N >= Dx + M - 1; altrimenti la coda si ripiega sull'inizio. La FFT calcola la DFT con (N/2) log2 N moltiplicazioni invece di N^2.Trasformata di Fourier discreta (DFT) e convoluzione circolare →, Sistemi LTI e convoluzione discretaUn sistema lineare e tempo-invariante (LTI) è completamente descritto dalla sua risposta impulsiva h[n]: y[n] = Σ x[k] h[n-k] = x[n] * h[n] (somma di convoluzione). Si ricava scomponendo x in impulsi traslati e usando linearità e invarianza. La convoluzione è commutativa, associativa e distributiva; una cascata di LTI equivale a un solo filtro con h = h1 * h2 e l'ordine non conta. Se x ha lunghezza N e h lunghezza L, y ha lunghezza N+L-1. Si calcola col metodo della finestra scorrevole o a tabella. I FIR sono LTI; altri sistemi (n·x[n], x[-n], x²) non lo sono.Sistemi LTI e convoluzione discreta →.
Punto 1: lineare e circolare
Lineare: ha lunghezza :
Circolare a : . Poiché è costante e vale su tutti i posti, ogni uscita è la somma di tutti i campioni, :
Il confronto: la circolare ha solo campioni, perché la coda della lineare ( in ) si ripiega sui primi posti: , , , : tutte le somme valgono . Con zero-padding a : , la circolare è , uguale alla lineare (più uno zero). Verificato con np.fft.
Punto 2: overlap-add
Blocchi non sovrapposti di : , (il secondo è più corto: si completa con zeri). Con : si completano , e a campioni, si calcola .
- (indici );
- , da traslare di : occupa gli indici .
Somma:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 3 | 6 | 9 | 7 | 4 | |||||
| 5 | 11 | 11 | 6 | 0 | 0 | |||||
| 1 | 3 | 6 | 9 | 12 | 15 | 11 | 6 | 0 | 0 |
L'uscita lineare vera ha campioni, : gli ultimi due zeri sono padding. La sovrapposizione ( campioni, in e ) è dove si sommano le due code: e .
Punto 3: overlap-save
Blocchi di campioni, sovrapposti di ; il primo parte da due zeri.
- : circolare con : . Si scartano i primi campioni () e si tengono .
- (ultimi due campioni del blocco precedente, poi e padding): circolare . Si scartano e si tengono .
Uscita: , uguale a . I campioni scartati sono quelli in cui la convoluzione circolare ha ripiegato la coda: per la convoluzione lineare è e la coda si somma ai due zeri iniziali.
Punto 4: il codice
import numpy as np
def overlap_add(x, h, L):
M = len(h)
N = 1 << int(np.ceil(np.log2(L + M - 1))) # potenza di 2 >= L+M-1
H = np.fft.fft(h, N) # DFT di h, una volta sola
y = np.zeros(len(x) + M - 1)
for s in range(0, len(x), L):
blk = x[s:s + L]
yk = np.real(np.fft.ifft(np.fft.fft(blk, N) * H))[:len(blk) + M - 1]
y[s:s + len(yk)] += yk # somma delle code sovrapposte
return y
def overlap_save(x, h, N):
M = len(h)
L = N - M + 1 # campioni validi per blocco
H = np.fft.fft(h, N)
xp = np.concatenate([np.zeros(M - 1), x, np.zeros(N)]) # M-1 zeri iniziali
out = []
for s in range(0, len(x) + M - 1, L):
blk = xp[s:s + N]
if len(blk) < N:
blk = np.concatenate([blk, np.zeros(N - len(blk))])
yk = np.real(np.fft.ifft(np.fft.fft(blk) * H))
out.append(yk[M - 1:]) # si scartano i primi M-1 campioni
return np.concatenate(out)[:len(x) + M - 1]
rng = np.random.default_rng(3)
x = rng.normal(size=1000); h = rng.normal(size=33)
print(np.allclose(overlap_add(x, h, 100), np.convolve(x, h))) # True
print(np.allclose(overlap_save(x, h, 128), np.convolve(x, h))) # TrueEntrambi i controlli stampano True (eseguito). Con e le funzioni danno .
Osservazione sul costo. Per ogni blocco servono una FFT diretta, un prodotto di numeri e una FFT inversa; è calcolata una sola volta. Per e ogni blocco produce campioni validi con circa moltiplicazioni complesse, cioè circa per campione (contro moltiplicazioni reali per campione del calcolo diretto, da confrontare tenendo conto che una moltiplicazione complessa ne vale circa quattro reali).
Versione ripasso
Punto 1. ha lunghezza . Con e : . La circolare a dà : la coda si ripiega sui primi posti (, , , ). Con zero-padding a la circolare coincide con la lineare.
Punto 2 - overlap-add. Blocchi , , , .
- negli indici ;
- traslato di , negli indici .
- Somma: . Le code si sommano in () e ().
Punto 3 - overlap-save. , campioni scartati, .
- : circolare , si tengono .
- : circolare , si tengono .
- Uscita , uguale a .
Punto 4 - codice. overlap_add(x,h,L) e overlap_save(x,h,N) verificati su campioni casuali con coefficienti: entrambi True contro np.convolve. Costo per blocco: una FFT diretta, un prodotto di elementi, una FFT inversa; si calcola una volta.
Teoria: Convoluzione a blocchi - overlap-add e overlap-saveLa convoluzione lineare y = x * h (h lungo M) si può calcolare con la FFT scegliendo N >= Dx + M - 1 (potenza di 2): costo per campione circa 3 k log2 N contro k M del calcolo diretto, quindi la FFT conviene per M abbastanza grande (con Dx circa M, già da M = 16). Per segnali lunghi o infiniti si divide x in blocchi. Overlap-add: blocchi disgiunti di lunghezza L, ognuno convoluto con h (lunghezza L+M-1 con FFT di N >= L+M-1) e le code di M-1 campioni si sommano. Overlap-save: blocchi di N campioni sovrapposti di M-1, convoluzione circolare, si scartano i primi M-1 campioni di ogni uscita (corrotti dall'aliasing). Stesso costo.Convoluzione a blocchi - overlap-add e overlap-save →, Trasformata di Fourier discreta (DFT) e convoluzione circolareLa DFT di N campioni x[0..N-1] è X[k] = sum x[n] e^{-j2pi kn/N}, k = 0..N-1 (IDFT: x[n] = (1/N) sum X[k] e^{j2pi kn/N}); vede il segnale come periodico di periodo N e dà N campioni equispaziati della DTFT, cioè X(z) valutata sulle radici N-esime dell'unità. Se x ha durata M <= N non c'è aliasing temporale e lo zero-padding (N > M) infittisce solo i campioni della stessa DTFT. Proprietà: traslazione circolare, simmetria coniugata X[k] = X*[N-k], prodotto = convoluzione circolare. La convoluzione circolare coincide con la lineare solo se N >= Dx + M - 1; altrimenti la coda si ripiega sull'inizio. La FFT calcola la DFT con (N/2) log2 N moltiplicazioni invece di N^2.Trasformata di Fourier discreta (DFT) e convoluzione circolare →, Sistemi LTI e convoluzione discretaUn sistema lineare e tempo-invariante (LTI) è completamente descritto dalla sua risposta impulsiva h[n]: y[n] = Σ x[k] h[n-k] = x[n] * h[n] (somma di convoluzione). Si ricava scomponendo x in impulsi traslati e usando linearità e invarianza. La convoluzione è commutativa, associativa e distributiva; una cascata di LTI equivale a un solo filtro con h = h1 * h2 e l'ordine non conta. Se x ha lunghezza N e h lunghezza L, y ha lunghezza N+L-1. Si calcola col metodo della finestra scorrevole o a tabella. I FIR sono LTI; altri sistemi (n·x[n], x[-n], x²) non lo sono.Sistemi LTI e convoluzione discreta →.
Errori tipici:
- Confrontare la circolare a con la lineare senza fare lo zero-padding: la coda si ripiega e le uscite cambiano.
- In overlap-add sommare i blocchi senza traslarli di .
- In overlap-save non scartare i primi campioni di ogni blocco circolare.
- Dimenticare che una moltiplicazione complessa vale circa quattro reali nel confronto dei costi.