Esercizio - rumore bianco gaussiano e filtro passa-basso in Python (laboratorio 6)
Questa pagina non ha ancora la versione ripasso: qui sotto c'è il testo completo.
In questa pagina 3
Testo (laboratorio 6, parte 8, corso Teoria dei Segnali, UniPD). Un processo a tempo discreto con Hz è un rumore bianco gaussiano: campioni indipendenti , , campioni. Passa in un filtro FIR passa-basso con frequenza di taglio Hz e coefficienti (ordine ), progettato con il metodo della finestra. Si chiede di:
- generare il rumore e rappresentare e l'uscita nel tempo;
- stimare la correlazione empirica di e ;
- stimare la densità spettrale di potenza (PSD) bilatera con il metodo di Welch;
- confrontare con la teoria: , , , potenza dell'uscita.
Teoria usata: Processi aleatori - definizioni, media e autocorrelazioneUn processo aleatorio x(t), t in I (R o Z(T)), è una famiglia di variabili aleatorie sullo stesso spazio di probabilità; fissato l'esito si ottiene una realizzazione (un segnale). Si descrive con le densità di ordine N (complete), in particolare del primo e del secondo ordine, oppure solo con media m_x(t) e correlazione r_x(t,s) = E[x(t)x*(s)] (descrizione di potenza). Un processo gaussiano è determinato da media e correlazione.Processi aleatori - definizioni, media e autocorrelazione →, Processi stazionari e densità spettrale di potenzaUn processo è stazionario in media, in potenza, nel primo ordine o in correlazione se la rispettiva grandezza non cambia traslando il tempo; stazionario in senso lato (sl) = media costante e r_x(t,s) = r_x(t-s); in senso stretto (ss) = tutte le densità invarianti. La densità spettrale di potenza R_x(f) = F[r_x(τ)] è non negativa e ha integrale = potenza statistica. Rumore bianco: R costante. Ciclostazionario: statistiche periodiche. Ergodico in media: la media temporale di una realizzazione converge a m_x.Processi stazionari e densità spettrale di potenza →, Processi aleatori attraverso sistemi LTIUna trasformazione applicata a ogni realizzazione dà un nuovo processo, ma dalla descrizione statistica di x non sempre si ricava quella di y (controesempi); si può se ogni vettore di y dipende da un vettore finito di x. Per una tf lineare m_y e r_y si calcolano col nucleo; un filtro LTI conserva la stazionarietà in senso lato: m_y = G(0) m_x, R_y = |G|² R_x. Il campionamento di un processo sl dà un processo sl con PSD ripetuta periodicamente. L'interpolazione LTI di un processo discreto sl è ciclostazionaria. Teorema del campionamento per processi: R_x nulla fuori da (-B,B) e Fc ≥ 2B danno ricostruzione esatta in media quadratica; altrimenti la potenza dell'errore è in banda + fuori banda.Processi aleatori attraverso sistemi LTI →, Risposta in frequenza e filtriLa risposta in frequenza G(f) = F[g] di un filtro LTI dà Y = G·X. Gli esponenziali complessi sono autofunzioni (autovalore G(f)), quindi un ingresso sinusoidale esce sinusoidale con ampiezza moltiplicata per |G(f0)| e fase aumentata di arg G(f0). Il filtro è reale se G è hermitiana, invertibile se G non si annulla. I filtri ideali sono rect in frequenza; non distorsione secondo Heaviside: |G| costante e fase lineare.Risposta in frequenza e filtri →, Trasformata di Fourier a tempo discretoLa trasformata di Fourier di un segnale discreto è $S(f)=\sum_nT,s(nT),e^{-i2\pi fnT}$: una funzione continua e periodica in $f$ di periodo $F_p=1/T$. L'antitrasformata è l'integrale su un periodo, $s(nT)=\int_0^{F_p}S(f)e^{i2\pi fnT}df$. Le regole sono quelle del caso continuo (traslazione, convoluzione $\leftrightarrow$ prodotto, Parseval $\sum T|s|^2=\int_0^{F_p}|S|^2$), con incremento e somma corrente al posto di derivata e integrale. Per segnali reali $S(f)=S^*(-f)$, quindi basta $[0,F_p/2]$. Esempi: $\delta\to1$, $1\to\delta_{F_p}$, rect $\to$ sinc periodico, $a^n\mathbf 1_0\to\frac T{1-ae^{-i2\pi fT}}$.Trasformata di Fourier a tempo discreto →, Vettori gaussianiX = (X₁, ..., Xₙ) è un vettore gaussiano N(m, Σ) se ogni combinazione lineare a·X è gaussiana (equivalentemente X = m + AZ con Z gaussiane standard indipendenti); se Σ è invertibile ha densità exp(−½(x−m)ᵀΣ⁻¹(x−m)) / √((2π)ⁿ det Σ). Proprietà chiave: AX + b ~ N(Am + b, AΣAᵀ), le marginali sono gaussiane e componenti non correlate sono indipendenti.Vettori gaussiani →.
(1) Teoria: correlazione e PSD con la convenzione del corso
Ingresso. Campioni indipendenti a media nulla e potenza hanno
La densità spettrale di potenza di un processo su è la trasformata di Fourier discreta (con il peso ) della correlazione:
costante (da qui "bianco") e periodica di periodo ; sull'intervallo ha integrale , la potenza statistica (Processi stazionari e densità spettrale di potenzaUn processo è stazionario in media, in potenza, nel primo ordine o in correlazione se la rispettiva grandezza non cambia traslando il tempo; stazionario in senso lato (sl) = media costante e r_x(t,s) = r_x(t-s); in senso stretto (ss) = tutte le densità invarianti. La densità spettrale di potenza R_x(f) = F[r_x(τ)] è non negativa e ha integrale = potenza statistica. Rumore bianco: R costante. Ciclostazionario: statistiche periodiche. Ergodico in media: la media temporale di una realizzazione converge a m_x.Processi stazionari e densità spettrale di potenza →). Il valore è proprio quello che restituisce scipy.signal.welch con scaling='density' (densità in V/Hz).
Uscita. Per un filtro LTI (Processi aleatori attraverso sistemi LTIUna trasformazione applicata a ogni realizzazione dà un nuovo processo, ma dalla descrizione statistica di x non sempre si ricava quella di y (controesempi); si può se ogni vettore di y dipende da un vettore finito di x. Per una tf lineare m_y e r_y si calcolano col nucleo; un filtro LTI conserva la stazionarietà in senso lato: m_y = G(0) m_x, R_y = |G|² R_x. Il campionamento di un processo sl dà un processo sl con PSD ripetuta periodicamente. L'interpolazione LTI di un processo discreto sl è ciclostazionaria. Teorema del campionamento per processi: R_x nulla fuori da (-B,B) e Fc ≥ 2B danno ricostruzione esatta in media quadratica; altrimenti la potenza dell'errore è in banda + fuori banda.Processi aleatori attraverso sistemi LTI →) l'uscita di un processo stazionario è stazionaria con Il FIR ha, nel corso, risposta impulsiva e quindi , con per un passa-basso a guadagno unitario. La potenza dell'uscita è l'area della PSD (Parseval sul periodo): Per il filtro ideale ( per , zero altrove) l'area è un rettangolo di altezza e larghezza : È la frazione della banda di Nyquist lasciata passare: il rumore bianco ha la stessa potenza per Hz a tutte le frequenze e il filtro ne tiene solo il . Anche la correlazione dell'uscita si ottiene da : per l'ideale nulla ai lag multipli di ms; per il FIR reale . I campioni dell'uscita non sono più indipendenti: sono correlati su circa ms, cioè su campioni a ms.
Grafico interattivo: PSD in unità di 10^-3 V²/Hz: il rumore bianco ha R_x(f) = σ²/Fs = 1 piatta; il passa-basso ideale con fc = 80 Hz lascia R_y(f) = 1 solo per |f| < 80 Hz, l'area 0,16 è la potenza dell'uscita
Grafico interattivo: Correlazione dell'uscita per il passa-basso ideale: r_y(τ) = 0,16 sinc(0,16 τ) con τ in ms; vale la potenza 0,16 in 0 e si annulla a multipli di 6,25 ms
(2) Il codice, passo per passo
- Generazione.
rng.standard_normal(N)dà campioni indipendenti , moltiplicati per (Matlabrandn). Campioni indipendenti implica incorrelati (il viceversa vale perché sono gaussiani). - Filtro.
firwin(L+1, fc, fs=Fs)progetta con il metodo della finestra la risposta all'impulso di un passa-basso ideale (un seno cardinale troncato a coefficienti) con finestra di Hamming, che è anche la finestra predefinita difir1di Matlab (il commento del file dice Hann, mafir1usa Hamming se non specificato). Il guadagno in continua è e, per costruzione, ( dB nel taglio, non dB come per Butterworth). - Transitorio.
lfilterparte con stato nullo; si scartano i primi campioni,x[L:]ey[L:], per lavorare a regime. - Correlazione. Stima
biased: (Matlabxcorr(z, tau_max, 'biased')); è la stima della media d'insieme fatta con la media temporale, lecita perché il rumore bianco gaussiano stazionario è ergodico. - PSD.
welchdivide il segnale in segmenti di campioni sovrapposti al , moltiplica ciascuno per una finestra di Hann, ne calcola il periodogramma e fa la media sui segmenti.return_onesided=Falsedà la PSD bilatera su (frequenze negative nella seconda metà):fftshiftla riordina in . Risoluzione in frequenza Hz. La media su periodogrammi riduce lo scarto relativo di una stima di PSD a circa : per segmenti (un singolo periodogramma ha scarto del , non converge al crescere di ). - Confronto.
freqz(h, 1, worN=f, fs=Fs)calcola esatta sulla stessa griglia, enp.correlate(h, h, 'full')dà per la correlazione teorica dell'uscita.
import numpy as np
from scipy import signal, stats
import matplotlib.pyplot as plt
rng = np.random.default_rng(8)
Fs, N, sigma, fc, L = 1000, 2**17, 1.0, 80, 128
x = sigma * rng.standard_normal(N) # rumore bianco gaussiano: campioni indipendenti N(0, sigma^2)
h = signal.firwin(L + 1, fc, fs=Fs) # MATLAB: fir1(L, fc/(Fs/2)); L+1 coefficienti, finestra di Hamming
y = signal.lfilter(h, 1, x) # uscita: y[n] = sum_k h[k] x[n-k]
x, y = x[L:], y[L:] # scarto il transitorio iniziale (L campioni)
def corr(z, tau_max=150): # correlazione empirica 'biased' (divisa per N), lag 0..tau_max
return np.array([z[: len(z) - k] @ z[k:] / len(z) for k in range(tau_max + 1)])
rx, ry = corr(x), corr(y)
# PSD bilatera con Welch; fftshift per mettere f = 0 al centro
nper = 2048
f, Rx = signal.welch(x, Fs, window="hann", nperseg=nper, noverlap=nper // 2, nfft=nper, return_onesided=False)
_, Ry = signal.welch(y, Fs, window="hann", nperseg=nper, noverlap=nper // 2, nfft=nper, return_onesided=False)
f, Rx, Ry = np.fft.fftshift(f), np.fft.fftshift(Rx), np.fft.fftshift(Ry)
df = f[1] - f[0]
# ---- confronto con la teoria ----
_, Hf = signal.freqz(h, 1, worN=f, fs=Fs) # H(f) = sum_k h[k] e^{-i2 pi f k T} (= T * fft(h/T), convenzione del corso)
Ry_teo = np.abs(Hf)**2 * sigma**2 / Fs # R_y = |H|^2 R_x, con R_x = sigma^2 T = sigma^2/Fs
print(f"H(0) = sum h = {h.sum():.4f}; |H(fc)| = {abs(signal.freqz(h, 1, worN=[fc], fs=Fs)[1][0]):.4f}")
print(f"r_x(0) = {rx[0]:.4f}; max |r_x(k)|, k >= 1: {np.abs(rx[1:]).max():.4f}")
print(f"R_x medio (Welch) = {Rx.mean():.3e}; teoria sigma^2/Fs = {sigma**2 / Fs:.3e}; scarto relativo tipico {Rx.std() / Rx.mean():.3f}")
print(f"R_y per |f|<50: {Ry[np.abs(f) < 50].mean():.3e}; in f=+-fc: {Ry[np.abs(np.abs(f) - fc).argmin()]:.3e} "
f"(teoria {Ry_teo[np.abs(np.abs(f) - fc).argmin()]:.3e}); per |f|>110: {Ry[np.abs(f) > 110].mean():.1e}")
print(f"potenza = integrale della PSD: x {Rx.sum() * df:.4f} (varianza {x.var():.4f}); y {Ry.sum() * df:.4f} (varianza {y.var():.4f})")
print(f"potenza di y: r_y(0) = {ry[0]:.4f}; sigma^2 sum(h^2) = {sigma**2 * np.sum(h**2):.4f}; "
f"filtro ideale sigma^2 fc/(Fs/2) = {sigma**2 * fc / (Fs / 2):.4f}")
ry_teo = sigma**2 * np.r_[np.correlate(h, h, "full")[L:], np.zeros(150 - L)] # r_y(kT) = sigma^2 sum_m h[m] h[m+k]
ry_id = sigma**2 * 2 * fc / Fs * np.sinc(2 * fc * np.arange(151) / Fs) # filtro ideale: 0.16 sinc(2 fc tau)
print("r_y(0..3): empirica", np.round(ry[:4], 4), "| FIR teorica", np.round(ry_teo[:4], 4), "| ideale", np.round(ry_id[:4], 4))
print(f"max |r_y empirica - FIR teorica| sui lag 0..150: {np.abs(ry - ry_teo).max():.4f}")
print(f"curtosi in eccesso di y (0 per una gaussiana): {stats.kurtosis(y):.3f}")
plt.show()(3) Risultati e cosa si vede
- Nel tempo. è una nuvola irregolare di valori in (dev. standard ), senza struttura visibile; è molto più liscia (le variazioni veloci sono state eliminate), con escursioni minori (deviazione standard ).
- Correlazione dell'ingresso. (teoria ) e per : un impulso in su un fondo che fluttua di .
- Correlazione dell'uscita. Non è più un impulso: è un seno cardinale di larghezza dell'ordine di , con per uguale a (teoria per il FIR: ; per l'ideale : ). L'errore massimo fra stima e teoria del FIR sui lag è .
- PSD dell'ingresso. Piatta, media (teoria ), con una fluttuazione relativa del da punto a punto (il valore atteso per medie è ). L'area coincide con la varianza campionaria .
- PSD dell'uscita. A forma di "finestra": piatta a per Hz, scende a in (teoria : dB), e vale oltre Hz, cioè dB rispetto alla banda passante. Il rapporto riproduce .
- Potenza dell'uscita. Dall'area della PSD: ; dalla correlazione, (uguale alla varianza campionaria ); teoria per il FIR reale ; teoria per il passa-basso ideale . Il valore ideale è leggermente più alto perché il FIR ha una banda di transizione e lascia passare un po' meno potenza nei dintorni di .
- Gaussianità. è combinazione lineare di variabili gaussiane indipendenti, quindi gaussiana (Vettori gaussianiX = (X₁, ..., Xₙ) è un vettore gaussiano N(m, Σ) se ogni combinazione lineare a·X è gaussiana (equivalentemente X = m + AZ con Z gaussiane standard indipendenti); se Σ è invertibile ha densità exp(−½(x−m)ᵀΣ⁻¹(x−m)) / √((2π)ⁿ det Σ). Proprietà chiave: AX + b ~ N(Am + b, AΣAᵀ), le marginali sono gaussiane e componenti non correlate sono indipendenti.Vettori gaussiani →) con varianza : la curtosi in eccesso misurata vale .
Errori tipici.
- Scrivere la PSD del rumore bianco discreto come invece di : la PSD è per unità di frequenza e il suo integrale su un periodo deve dare la potenza .
- Moltiplicare per invece che per nel passaggio da a .
- Dimenticare che la PSD ottenuta da un solo periodogramma non è consistente (serve mediare, come fa Welch) e leggere come "righe" le fluttuazioni casuali.
Vedi anche: Esercizio - processi aleatori, media d'insieme, correlazione e potenza temporale in Python (laboratorio 6), Processi aleatori stazionari e densità spettrale di potenzaUn processo aleatorio è un segnale i cui valori a ogni istante sono variabili aleatorie. Se è stazionario in senso lato (WSS) la media è costante e l'autocorrelazione $r_x(\tau)$ dipende solo dalla differenza dei tempi; la sua trasformata è la densità spettrale di potenza $\mathcal P_x(f)$, il cui integrale è la potenza statistica $r_x(0)$. Un filtro LTI dà $m_y=m_xH(0)$ e $\mathcal P_y=\mathcal P_x\lvert H\rvert^2$; se l'ingresso è gaussiano anche l'uscita lo è. Il rumore bianco ha $\mathcal P(f)=\frac{N_0}2$.Processi aleatori stazionari e densità spettrale di potenza →.