Sei sulla pagina 1di 7

Esempio di applicazione della trasformata di Fourier

utilizzando il programma Matlab

Alcune avvertenze iniziali: per quanto riguarda la descrizione dettagliata dei comandi di
Matlab, si può consultare una qualsiasi Reference Guide del programma; nella prima parte
l’esempio qui riportato è tratto da un manuale di Matlab; un altro utile testo di riferimento,
nel quale si usa Matlab e C++, può essere: A. L. Garcia, Numerical Methods for Physics,
second edition, Prentice Hall, 2000.

Iniziamo questa esercitazione generando un semplice segnale come somma di due


oscillazioni sinusoidali con frequenza di 50 Hz e 120 Hz:

>> t=0:.001:.6;
>> x=sin(2*pi*50*t)+sin(2*pi*120*t);
>> plot(t,x),grid

Presentiamo anche un ingrandimento della parte iniziale del grafico di ciascuna delle due
onde e della loro somma:

>> x50=sin(2*pi*50*t);
>> x120=sin(2*pi*120*t);
>> subplot(3,1,1),plot(t(1:50),x50(1:50)),grid
>> subplot(3,1,2),plot(t(1:50),x120(1:50)),grid
>> subplot(3,1,3),plot(t(1:50),x(1:50)),grid
Adesso, se aggiungiamo del rumore di fondo di tipo casuale al segnale x(t) (come accade
normalmente nei sistemi reali), diventa molto difficile identificare le frequenze dei due
segnali componenti guardando il grafico (randn è un comando che genera numeri random
distribuiti normalmente con media 0 e varianza 1; di conseguenza, se si ripete il
procedimento qui descritto, occorre tenere presente che i grafici non potranno essere uguali
nei dettagli):

>> y=x+2*randn(size(t));
>> plot(t,y),grid

Mostriamo un ingrandimento della parte iniziale del grafico:

>> plot(t(1:50),y(1:50)),grid
Adesso applichiamo la trasformata di Fourier per via numerica (FFT, cioè la Fast Fourier
Tranform), passando dal dominio temporale (la y(t) è funzione reale del tempo) al dominio
delle frequenze, che indicheremo con f: ricordiamo, infatti, che la trasformata di Fourier, che
indicheremo con Y(f), è una funzione complessa della frequenza e rappresenta
sostanzialmente il limite a cui tendono i coefficienti dello sviluppo complesso in serie di
Fourier della funzione iniziale y(t). Riportiamo ora alcune osservazioni preliminari per poter
meglio comprendere la sequenza dei comandi di Matlab:

 consideriamo la FFT della Y(f) prendendo 512 punti del dominio iniziale della y(t),
invece di 601 (avremmo anche potuto prendere tutti i punti, ma in questo caso il tempo
di calcolo sarebbe stato più elevato: infatti, se è possibile scegliere la lunghezza del
vettore y pari ad una potenza di 2 – come nel nostro caso 512 = 29- viene
implementato un high-speed radix-2 FFT algorithm);
 dato che y(t) è un vettore formato da valori reali, consideriamo solo i primi 256 punti
del vettore Y così ottenuto (cioè la metà), in quanto gli altri 256 punti di Y sono
“simmetrici”, perchè rappresentano i valori complessi coniugati dei primi: in altri
termini, contengono un duplicato del segnale (si tratta del cosiddetto fenomeno
dell’aliasing). Per comprendere bene questo fatto, si può anche ragionare così: dato
che Y è un vettore che ha la stessa dimensione di y, ma le cui componenti sono numeri
complessi coniugati (in quanto ogni componente corrisponde a due numeri reali), a
prima vista sembrerebbe che il contenuto informativo del vettore y (cioè, i dati iniziali,
che sono numeri reali) si raddoppi mediante la trasformata di Fourier, ma
evidentemente questo non è possibile. Di conseguenza, è inevitabile che Y debba
contenere in qualche modo una duplicazione del segnale originale;
 in conseguenza di quanto appena detto, anche le frequenze significative da cui dipende
Y vanno da un minimo ad un massimo. La frequenza minima fm (diversa da 0: infatti,
va considerata anche la trasformata in corrispondenza di f = 0) è pari a 1/T, con T =
lunghezza della serie temporale = dt x N, con dt = intervallo di campionamento (cioè,
il data sampling, il passo temporale fra due valori consecutivi della funzione iniziale)
e N = numero di punti del dominio temporale: nel nostro caso si ha f m = 1/(1/1000 x
512) = 1000/512. Infine, osserviamo che, come conseguenza di questo risultato, per
poter rilevare nel fenomeno in esame basse frequenze diventa necessario disporre di
serie temporali molto lunghe;
 la frequenza massima fM è dell’ordine di 1/dt: sulla base del teorema di Nyquist si
ottiene precisamente che vale 1/(2dt) e, perciò, viene anche chiamata frequenza di
Nyquist fN. Nel nostro caso si ha fN = 1/(2 x 1/1000) = 1000/2=500; tuttavia,
l’implementazione numerica porta ad una frequenza massima leggermente
approssimata per difetto rispetto a fN, pari a (1000 x 255)/512. Infine, osserviamo che,
come conseguenza di questo risultato, per poter rilevare nel fenomeno in esame alte
frequenze diventa necessario disporre di serie temporali acquisite con un passo di
campionamento molto breve (short sampling rate).

Adesso procediamo con il calcolo della FFT in Matlab e mostriamo subito il fenomeno
dell’aliasing (seconda parte dei grafici, dopo N = 255):

>> Y=fft(y,512);
>> subplot(2,1,1),plot(real(Y))
>> subplot(2,1,2),plot(imag(Y))

A questo punto, anche limitando l’analisi alla prima metà dei grafici, non è così ovvio
distinguere le principali frequenze presenti nel segnale: certamente, l’aiuto maggiore in
questo esempio viene dalla parte reale della trasformata, dove si vedono chiaramente due
picchi (o, meglio, la presenza di spikes). Allora, costruiamo ora, sulla base di quanto
osservato prima, il vettore della 256 frequenze f significative (0,fm,…,fM) e rappresentiamo
solo i primi 256 valori della parte reale della Y in funzione di f:

>> f=1000*(0:255)/512;
>> plot(f,real(Y(1:256)))
>> grid on
>> grid minor

Ecco allora che compaiono, abbastanza evidenti, due spikes (cioè, delle rapidissime
oscillazioni con picchi) a 50 Hz e 120 Hz, che prevalgono su tutti gli altri. Tuttavia, proprio
per la complessità del grafico, usualmente si preferisce riportare il grafico della power
spectral density, o power spectrum, che in pratica misura l’energia del segnale in
corrispondenza delle varie frequenze, ed è di più immediata interpretazione. Riportiamo nel
seguito questo calcolo dando il valore normalizzato, cioè dividendo per la dimensione del
vettore che rappresenta la trasformata (ma, spesso, si riporta anche il valore unnormalized):
Pyy = |Y|2 /512 = Yk Yk*/512: adesso si vedono di nuovo, ma in modo ancora più evidente,
i due picchi a 50 Hz e 120 Hz:

>> Pyy=Y.*conj(Y)/512; oppure: >> Pyy= abs(Y).^2/512;


>> plot(f,Pyy(1:256))
>> grid minor
Adesso, se facessimo la antitrasformata della Y otterremmo naturalmente, a parte trascurabili
errori numerici, la y originale, con tutto il suo contenuto di rumore casuale. Tuttavia, cosa
accadrebbe se, invece, prima filtrassimo la nostra trasformata Y eliminando, almeno in parte,
le ampiezze corrispondenti alle frequenze diverse da 50 Hz e 120 Hz, e poi facessimo la
trasformata inversa? Il buon senso ci suggerisce che in questo modo, dovremmo riottenere il
segnale x(t) iniziale ma, almeno in parte, “ripulito” dal rumore casuale.
Procediamo allora così: per prima cosa rifacciamo il grafico precedente ma ponendo
sull’asse delle ascisse l’indice delle componenti di Y (essendo identico al precedente non lo
riportiamo):
>> plot(Pyy(1:256))
>> grid minor
In questo modo si vede subito che il picco corrispondente alla prima frequenza significativa
corrisponde ad un indice n compreso approssimativamente fra 25-30, mentre l’altro picco
corrispondente alla seconda frequenza significativa si verifica circa per 60  n  65. Per
evitare il rischio di eliminare parti significative del segnale, decidiamo allora di porre uguali
a zero tutti i valori di Y da n = 71 in avanti, fino all’indice 256. Tuttavia, la nostra
trasformata Y è un vettore di 512 componenti, che da n = 257 in avanti contiene il segnale
duplicato in modo simmetrico. Allora, tenendo conto che in realtà la simmetria parte da n = 2,
perché per n = 1 si ha la Y corrispondente alla frequenza nulla, costruiamo la nostra Y
“filtrata” = Yfil e poi procediamo con l’antitrasformata di Fourier, che indichiamo con yfil:
>> Y1=Y(1:70);
>> Y2=zeros(1,373);
>> Y3=Y(444:512);
>> Yfil=[Y1,Y2,Y3];
>> yfil=ifft(Yfil);
Per maggiore chiarezza, notiamo che la dimensione di Y1 – 1 = 69 (la prima componente di
Y1, come già detto, corrisponde alla frequenza nulla), valore che è uguale alla dimensione di
Y3; ovviamente 512-70-69=373, che è la dimensione di Y2, il vettore composto solo da zeri.
A questo punto, eseguiamo per completezza anche la trasformata inversa di Y senza alcun
filtraggio, che chiamiamo yinv (cioè, la y ottenuta con l’inversione della trasformata):
>> yinv=ifft(Y);
Infine, presentiamo insieme tutti i grafici: in particolare, dall’alto verso il basso abbiamo: 1)
la funzione x(t) originale, somma delle due oscillazioni; 2) la funzione y(t), cioè la x(t) con
il rumore casuale; 3) yinv(t), antitrasformata di Y senza alcuna modifica; 4) yfil(t),
antitrasformata di Yfil, dove abbiamo eliminato parzialmente il contributo del rumore
casuale. Si noti che la yfil(t) è ancora soggetta ad un rumore casuale, ma decisamente ridotto
rispetto a quanto mostrato dai grafici 2) e 3), perché abbiamo in gran parte eliminato il
rumore corrispondente a frequenze più alte, mentre è rimasto quello di più bassa frequenza.
Tuttavia, anche quest’ultimo potrebbe essere ridotto con ulteriori operazioni di “filtraggio”
analoghe a quanto descritto sopra.