Salta al contenuto
Note per Studenti Esercizio 26 · trasformata di Fourier con FFT e zero-padding (temi d'esame gennaio 2025 e febbraio 2026)

Esercizio 26trasformata di Fourier con FFT e zero-padding (temi d'esame gennaio 2025 e febbraio 2026)

Esame
In questa pagina 4

Due domande di "Matlab" dagli esami, risolte in Python (numpy). L'esame le prevede in Matlab; la traduzione delle funzioni è nella tabella di Segnali e sistemi in Python - campioni, convoluzione e filtriAl calcolatore un segnale continuo è un vettore di campioni con un asse dei tempi. Con numpy si definiscono i segnali, si approssimano area ed energia con somme moltiplicate per il passo, si calcola la convoluzione continua con np.convolve(x, y)*dt (asse = somma degli istanti iniziali), si simulano filtri con equazioni alle differenze e si verificano numericamente linearità e tempo-invarianza.Segnali e sistemi in Python - campioni, convoluzione e filtri →.

Testo A (tema d'esame gennaio 2025, domanda di Matlab, 3 punti). Si consideri il segnale x(t)=Acos⁡(ωt)rect⁡(t−T2T)x(t)=A\cos(\omega t)\operatorname{rect}\left(\frac{t-T}{2T}\right). Scrivere uno script che:

  1. calcoli x(t)x(t) nell'intervallo (−2,30)(-2,30) campionato a passo Δ=10−3\Delta=10^{-3}, con A=2A=2, T=10T=10, ω=3\omega=3;
  2. tracci in una figura l'andamento di x(t)x(t) nell'intervallo;
  3. tracci in una figura, usando la FFT, l'andamento del modulo della TFtc di xx solo per frequenze positive. È importante identificare correttamente la scala delle frequenze. Per il calcolo della FFT usare un opportuno zero-padding.

Testo B (tema d'esame febbraio 2026, domanda di Matlab, 3 punti). Si consideri il segnale x(t)=A e−3tu(t)x(t)=A\,e^{-3t}u(t). Scrivere uno script che:

  1. calcoli x(t)x(t) nell'intervallo (0,T)(0,T) campionato a passo Δ=10−3\Delta=10^{-3}, con A=2A=2, T=20T=20;
  2. tracci in una figura l'andamento di x(t)x(t);
  3. tracci in una seconda figura l'andamento del modulo di X(ω)X(\omega), la TFtc di xx, usando la FFT con un opportuno zero-padding (attenzione alla denominazione dell'asse delle ascisse);
  4. tracci nella stessa figura l'andamento teorico di ∣X(ω)∣|X(\omega)| (da calcolare analiticamente, non nello script).

Teoria usata: FFT e zero-padding - TF, TFtd e asse delle pulsazioniLa FFT dei campioni di un segnale a durata finita, moltiplicata per il passo $T_c$, approssima la trasformata di Fourier: $X(\omega_k)\approx T_c,\mathtt{fft}(x,M)[k]$ con $\omega_k=\frac{2\pi k}{MT_c}$ (e fattore di fase $e^{-j\omega t_0}$ se l'asse parte da $t_0$). Lo zero-padding ($M>N$) infittisce i punti della stessa TFtd senza aggiungere informazione; la risoluzione dipende dalla durata osservata. Per un segnale reale $|X|$ è simmetrico: il picco in $k$ ha un gemello in $M-k$.FFT e zero-padding - TF, TFtd e asse delle pulsazioni →, Trasformata di Fourier a tempo discreto (TFtd)La TFtd di una sequenza è $X(\omega)=\sum_nx(n)e^{-j\omega n}$, funzione continua e periodica di periodo $2\pi$; si inverte con $x(n)=\frac1{2\pi}\int_{-\pi}^{\pi}X(\omega)e^{j\omega n}d\omega$. Ha le stesse proprietà della TF continua (la convoluzione diventa prodotto, $n,x(n)\leftrightarrow jX'$). È la risposta in frequenza dei sistemi discreti; con la TFD e lo zero-padding se ne ottengono campioni arbitrariamente fitti.Trasformata di Fourier a tempo discreto (TFtd) →, Proprietà della trasformata di FourierCon le proprietà (linearità, simmetrie, ritardo $\leftrightarrow e^{-j\omega t_0}$, modulazione $\leftrightarrow$ traslazione in frequenza, scala, dualità, convoluzione $\leftrightarrow$ prodotto, Parseval $E=\frac1{2\pi}\int|X|^2$, derivata $\leftrightarrow j\omega$, moltiplicazione per $t\leftrightarrow j,d/d\omega$, integrazione) quasi tutte le trasformate si ottengono da poche coppie base senza integrare.Proprietà della trasformata di Fourier →, Conversione A-D e campionamento di segnali non limitati in bandaUn convertitore A/D è la catena filtro anti-aliasing passa-basso, campionatore, quantizzatore a $B$ bit. Nessun segnale reale è a banda esattamente limitata: si sceglie la banda essenziale (che contiene quasi tutta l'energia) e un passo $T_c$ tale che le repliche aliasing siano trascurabili. La quantizzazione introduce un errore con potenza $\Delta^2/12$ e un rapporto segnale-rumore di circa $6{,}02B+1{,}76$ dB.Conversione A-D e campionamento di segnali non limitati in banda →.

Il metodo (richiamo)

Per campioni xn=x(t0+nΔ)x_n=x(t_0+n\Delta) si ha X(ωk)≈Δ e−jωkt0 fft(x,M)[k]X(\omega_k)\approx\Delta\,e^{-j\omega_kt_0}\,\mathtt{fft}(x,M)[k] con ωk=2πkMΔ\omega_k=\frac{2\pi k}{M\Delta}, fk=kMΔf_k=\frac k{M\Delta} (indici k=0,…,M−1k=0,\ldots,M-1; per k>M2k>\frac M2 sono le frequenze negative). Per il modulo, t0t_0 non conta (FFT e zero-padding - TF, TFtd e asse delle pulsazioniLa FFT dei campioni di un segnale a durata finita, moltiplicata per il passo $T_c$, approssima la trasformata di Fourier: $X(\omega_k)\approx T_c,\mathtt{fft}(x,M)[k]$ con $\omega_k=\frac{2\pi k}{MT_c}$ (e fattore di fase $e^{-j\omega t_0}$ se l'asse parte da $t_0$). Lo zero-padding ($M>N$) infittisce i punti della stessa TFtd senza aggiungere informazione; la risoluzione dipende dalla durata osservata. Per un segnale reale $|X|$ è simmetrico: il picco in $k$ ha un gemello in $M-k$.FFT e zero-padding - TF, TFtd e asse delle pulsazioni →). Lo zero-padding si ottiene con np.fft.fft(x, M), scegliendo MM potenza di due maggiore di NN (qui M=23+⌈log⁡2N⌉M=2^{3+\lceil\log_2N\rceil}).

Soluzione del testo A

Passo 1: il segnale. rect⁡(t−T2T)\operatorname{rect}\left(\frac{t-T}{2T}\right) vale 11 per ∣t−T∣<T|t-T|<T, cioè 0<t<2T=200<t<2T=20: il coseno è "acceso" tra 00 e 2020 s (in (−2,30)(-2,30) c'è quindi un tratto nullo prima e uno dopo). Si usa un indicatore booleano.

python
import numpy as np
nextpow2 = lambda N: int(np.ceil(np.log2(N)))

A, T, w0, Tc = 2.0, 10.0, 3.0, 1e-3
t = np.arange(-2, 30 + Tc/2, Tc)                      # (-2, 30) a passo Tc
x = A*np.cos(w0*t) * (np.abs((t - T)/(2*T)) < 0.5)     # A cos(w t) rect((t-T)/(2T))
# plt.plot(t, x)   -> figura 1

Passo 2: lo spettro con la FFT. N=32001N=32001 campioni; M=23+16=218=262144M=2^{3+16}=2^{18}=262144 (zero-padding di un fattore ≈8\approx8).

python
N = len(t); M = 2**(3 + nextpow2(N))
X = Tc*np.abs(np.fft.fft(x, M))              # |X| = Tc |fft|   (modulo: t0 non conta)
Fc = 1/Tc
f = np.arange(M//2 + 1) * Fc / M             # frequenze POSITIVE in Hz: 0, Fc/M, ..., Fc/2
# plt.plot(f, X[:M//2+1]); plt.xlim(0, 3*w0/(2*np.pi))   -> figura 2

Scala delle frequenze. I campioni della FFT hanno passo FcM=1MΔ=0,0038\frac{F_c}{M}=\frac1{M\Delta}=0{,}0038 Hz e coprono [0,Fc)[0,F_c); le frequenze positive fino a Fc2=500\frac{F_c}2=500 Hz sono i primi M2+1\frac M2+1 campioni. Si disegna l'ascissa in Hz perché il testo chiede "frequenze" (per le pulsazioni ω=2πf\omega=2\pi f).

Cosa si osserva. Il modulo ha un picco di 20,0820{,}08 a f≈0,4768f\approx0{,}4768 Hz (campione più vicino a f0=ω2π=0,4775f_0=\frac{\omega}{2\pi}=0{,}4775 Hz): l'impulso è una sinusoide a ω=3\omega=3 limitata nel tempo a una finestra lunga 2T=202T=20 s, quindi lo spettro è un sinc⁡\operatorname{sinc} centrato in f0f_0 con altezza A2⋅2T=AT=20\frac A2\cdot2T=AT=20 e lobo principale con gli zeri a ±12T=±0,05\pm\frac1{2T}=\pm0{,}05 Hz dal centro (largo 0,10{,}1 Hz in totale) (Proprietà della trasformata di FourierCon le proprietà (linearità, simmetrie, ritardo $\leftrightarrow e^{-j\omega t_0}$, modulazione $\leftrightarrow$ traslazione in frequenza, scala, dualità, convoluzione $\leftrightarrow$ prodotto, Parseval $E=\frac1{2\pi}\int|X|^2$, derivata $\leftrightarrow j\omega$, moltiplicazione per $t\leftrightarrow j,d/d\omega$, integrazione) quasi tutte le trasformate si ottengono da poche coppie base senza integrare.Proprietà della trasformata di Fourier →: A2W(ω−ω0)\frac A2W(\omega-\omega_0), W(ω)=2Tsinc⁡(ωTπ)e−jωTW(\omega)=2T\operatorname{sinc}\left(\frac{\omega T}{\pi}\right)e^{-j\omega T}). Il valore 20,0820{,}08 (e non 2020) include il contributo della replica a frequenza negativa −ω0-\omega_0, che a f0f_0 vale poco più dell'1%1\%. In tre punti vicini al picco, la FFT dà ∣X(2,5)∣=3,345|X(2{,}5)|=3{,}345, ∣X(3)∣=20,080|X(3)|=20{,}080, ∣X(3,5)∣=4,091|X(3{,}5)|=4{,}091 (con ω\omega in rad/s) in accordo con la formula esatta.

Perché lo zero-padding. Senza zero-padding (M=N=32001M=N=32001) il passo in frequenza sarebbe 100032001≈0,031\frac{1000}{32001}\approx0{,}031 Hz; con M=262144M=262144 è 0,00380{,}0038 Hz e il lobo principale (largo 0,10{,}1 Hz) è disegnato con circa 2626 punti (senza zero-padding ne basterebbero 33) (FFT e zero-padding - TF, TFtd e asse delle pulsazioniLa FFT dei campioni di un segnale a durata finita, moltiplicata per il passo $T_c$, approssima la trasformata di Fourier: $X(\omega_k)\approx T_c,\mathtt{fft}(x,M)[k]$ con $\omega_k=\frac{2\pi k}{MT_c}$ (e fattore di fase $e^{-j\omega t_0}$ se l'asse parte da $t_0$). Lo zero-padding ($M>N$) infittisce i punti della stessa TFtd senza aggiungere informazione; la risoluzione dipende dalla durata osservata. Per un segnale reale $|X|$ è simmetrico: il picco in $k$ ha un gemello in $M-k$.FFT e zero-padding - TF, TFtd e asse delle pulsazioni →).

Soluzione del testo B

python
A, Tc, T = 2.0, 1e-3, 20.0
t = np.arange(0, T + Tc/2, Tc)
x = A*np.exp(-3*t)                         # per t >= 0 il gradino vale 1
N = len(t); M = 2**(nextpow2(N) + 3)
X = np.fft.fftshift(Tc*np.fft.fft(x, M))
w = 2*np.pi*np.arange(-M/2, M/2)/(M*Tc)    # asse delle PULSAZIONI [rad/s]
Xe = A/np.sqrt(9 + w**2)                   # |X| teorico
# plt.plot(w, np.abs(X)); plt.plot(w, Xe); plt.xlim(-20, 20)

Lo spettro teorico. X(ω)=A∫0∞e−3te−jωtdt=A3+jωX(\omega)=A\int_0^\infty e^{-3t}e^{-j\omega t}dt=\frac A{3+j\omega}, con modulo A9+ω2\frac{A}{\sqrt{9+\omega^2}}. Per A=2A=2: ∣X(0)∣=23|X(0)|=\frac23, e 218=0,471\frac{2}{\sqrt{18}}=0{,}471 in ω=3\omega=3 (taglio a −3-3 dB).

Asse delle ascisse. Le ascisse sono pulsazioni ω\omega in rad/s (testo: "attenzione alla denominazione dell'asse"): ωk=2πkMΔ\omega_k=\frac{2\pi k}{M\Delta} da −πΔ=−3141,6-\frac\pi\Delta=-3141{,}6 a πΔ−2πMΔ\frac\pi\Delta-\frac{2\pi}{M\Delta} rad/s, passo 0,0240{,}024 rad/s. Si fa uno zoom con xlim(-20, 20) per vedere il picco.

Confronto numerico. Per ∣ω∣<20|\omega|<20 l'errore massimo tra la FFT (moltiplicata per Δ\Delta) e la formula è 1,0⋅10−31{,}0\cdot10^{-3} (0,15%0{,}15\% del picco 23\frac23): le due curve sono praticamente sovrapposte. L'accordo non è perfetto per due motivi.

  1. Primo campione. La FFT calcola Δ∑n≥0xne−jωnΔ\Delta\sum_{n\ge0}x_n e^{-j\omega n\Delta} (somma rettangolare), che dà x(0)=A=2x(0)=A=2 pieno peso; il segnale Ae−3tu(t)Ae^{-3t}u(t) in t=0t=0 ha però un salto da 00 a AA e, con la convenzione dell'emivalore, vale A2\frac A2. L'errore è proprio Δ2⋅A=10−3\frac\Delta2\cdot A=10^{-3}. Correggendo con Δ[fft(x,M)−x02]\Delta\left[\mathtt{fft}(x,M)-\frac{x_0}2\right] (regola dei trapezi) l'errore massimo scende a 3,4⋅10−63{,}4\cdot10^{-6}.
  2. Aliasing e troncamento. Il segnale non è a banda limitata: ∣X∣→0|X|\to0 come 1∣ω∣\frac1{|\omega|} e la frequenza massima rappresentabile è πΔ=3142\frac\pi\Delta=3142 rad/s, quindi la prima replica aggiunge ≈26283=3⋅10−4\approx\frac{2}{6283}=3\cdot10^{-4} in ω≈0\omega\approx0, trascurabile rispetto alla scala del grafico (Conversione A-D e campionamento di segnali non limitati in bandaUn convertitore A/D è la catena filtro anti-aliasing passa-basso, campionatore, quantizzatore a $B$ bit. Nessun segnale reale è a banda esattamente limitata: si sceglie la banda essenziale (che contiene quasi tutta l'energia) e un passo $T_c$ tale che le repliche aliasing siano trascurabili. La quantizzazione introduce un errore con potenza $\Delta^2/12$ e un rapporto segnale-rumore di circa $6{,}02B+1{,}76$ dB.Conversione A-D e campionamento di segnali non limitati in banda →). Il troncamento a T=20T=20 s è irrilevante: x(20)=2e−60≈10−26x(20)=2e^{-60}\approx10^{-26}.

Errori comuni

  • Dimenticare il fattore Δ=Tc\Delta=T_c (lo spettro verrebbe 1Δ=1000\frac1\Delta=1000 volte troppo grande).
  • Costruire l'asse delle frequenze con np.arange(M)/M (frequenza normalizzata) invece di kMΔ\frac{k}{M\Delta} (in Hz) o 2πkMΔ\frac{2\pi k}{M\Delta} (in rad/s); oppure dimenticare di passare da Hz a rad/s quando il testo chiede la pulsazione.
  • Disegnare tutto il vettore della FFT quando si chiedono solo le frequenze positive: occorre fermarsi a M2+1\frac M2+1.
  • Non usare lo zero-padding e disegnare una curva "a scalini" con pochi punti.
  • Usare np.fft.fft(x, N) senza argomento MM: lo zero-padding si ottiene solo passando MM.

Versione ripasso

Testo. (A, gennaio 2025) x=Acos⁡(ωt)rect⁡t−T2Tx=A\cos(\omega t)\operatorname{rect}\frac{t-T}{2T}, A=2A=2, T=10T=10, ω=3\omega=3 in (−2,30)(-2,30), Δ=10−3\Delta=10^{-3}: grafico di xx e di ∣X∣|X| con FFT (solo f>0f>0). (B, febbraio 2026) x=Ae−3tu(t)x=Ae^{-3t}u(t), A=2A=2, T=20T=20: xx, ∣X(ω)∣|X(\omega)| da FFT e teorico (febbraio 2026).

Teoria collegata