FONDAMENTI DI ELABORAZIONE NUMERICA DEI SEGNALI 1° Laboratorio Paolo Mazzucchelli [email protected] Il software MATLAB (acronimo di MATrix LABoratory) è uno strumento di simulazione per la generazione ed il trattamento dei segnali. MATLAB integra funzioni per il calcolo, la memorizzazione e la visualizzazione dei segnali con un linguaggio di programmazione orientato alla manipolazione di oggetti matematici. MATLAB come calcolatrice MATLAB mette a disposizione un’interprete di comandi che permette di effettuare un’ampia varietà di operazioni matematiche. Le operazioni disponibili sono +,-,*,/,^ (elevamento a potenza), le funzioni trigonometriche cos(),sin(),tan()…, le funzioni exp(),log(),log10(). Queste operazioni possono essere applicate a espressioni numeriche (MATLAB come “calcolatrice avanzata”). » 1+log10(10^2) ans = 3 » 2.5*(sin(pi/2)+3), ans = 10 ATTENZIONE agli angoli sempre espressi in radianti Variabili in MATLAB Le operazioni matematiche mostrate si possono applicare direttamente a numeri, oppure a variabili. Inoltre, il risultato di un’operazione si può assegnare ad una variabile. » a=5*3+12 a = 27 In MATLAB non è necessario dichiarare le variabili e la loro dimensione prima di poterle utilizzare. Le variabili sono identificate da nomi alfanumerici di lunghezza qualunque, e sono case sensitive. Le variabili in MATLAB sono sempre matrici di numeri (da qui il nome MATrix LABoratory!). I valori scalari e i vettori sono quindi casi particolari di matrici. Gli elementi delle matrici sono numeri reali o complessi, memorizzati con precisione double (8 byte). L’unità immaginaria si indica con j o i (se non vengono utilizzati come nomi di variabili). Assegnamento di un valore scalare complesso: » b=3+2*j b = 3.0000 + 2.0000i Assegnamento di un vettore riga (gli elementi, racchiusi tra parentesi quadre possono essere separati da spazi o da virgole): » c=[1, 2, 0] c = 1 2 0 Assegnamento di una matrice (spazi o virgole separano elementi di una riga, e “;” separano le diverse righe): A = [11 3 2; 5 1 11; 9 6 9; 2 15 14] A = 11 3 2 5 1 11 9 6 9 2 15 14 Gli elementi racchiusi tra le parentesi quadre, e separati da virgole o “;”, possono essere numeri, variabili scalari o matrici stesse (i blocchi accostati devono essere coerenti). Ad esempio: » B=[c;A] B = 1 2 0 11 3 2 5 1 11 9 6 9 2 15 14 Riferimento ad elementi o sottoinsiemi di una matrice. Si può accedere al valore dell’elemento di riga r e colonna c della A matrice con la sintassi A(r,c). ATTENZIONE Gli indici MATLAB partono da 1 B(2,3) è l’elemento (2,3) della matrice. B(:,1) è la prima colonna della matrice. B(2:4,3) sono è un vettore colonna che contiene tre elementi della terza colonna di A. Con questa sintassi si possono modificare elementi della matrice (es. B(2,3)=7). Operazioni sulle matrici. Le operazioni matematiche elementari definite dai simboli: (+,-,*,/,^) si riferiscono a operazioni matriciali, che quindi sono eseguibili solo quando le dimensioni delle matrici sono congruenti. Eccezione a questa regola sono le operazioni tra uno scalare e una matrice. Per poter applicare queste operazioni ripetutamente e singolarmente a ogni elemento della matrice basta anteporre “.” al simbolo dell’operazione. » C=[3 4;5 7] C = 3 4 5 7 » C^2 ans = 29 40 50 69 » C.^2 ans = 9 16 25 49 Le funzioni matematiche (es. sin(), log()) sono applicate ad ogni singolo elemento della matrice. ATTENZIONE infine ai comandi: A’ hermitiana di A (trasposta e complessa coniugata) A.’ trasposta di A size(A) dimensione della matrice A è infine utile conoscere quali sono le variabili attualmente in memoria e la loro dimensione. » whos A 4x3 96 double array B 5x3 120 double array C 2x2 32 double array a 1x1 8 double array b 1x1 16 double array (complex) c 1x3 24 double array Per cancellare tutte le variabili attualmente in memoria clear Per avere informazioni su un qualsiasi comando od operazione MATLAB esiste il comando help » help sqrt SQRT Square root. SQRT(X) is the square root of the elements of X. Complex results are produced if X is not positive. See also SQRTM. Generazione e visualizzazione di segnali in MATLAB Un segnale è essenzialmente una funzione di una (o più) variabili indipendenti: segnali continui - funzioni di una variabile che varia con continuità in un intervallo. segnali discreti - funzioni di una variabile che assume valori discreti a intervalli prefissati (sequenza) In MATLAB possono essere rappresentate solo sequenze, (segnali discreti), come vettori. NON possono essere invece rappresentati segnali continui in senso stretto (infiniti valori). Per poter definire una sequenza con passo arbitrario si può usare la notazione (già utilizzata per estrarre sottoinsiemi da una matrice): partenza:passo:arrivo Ad esempio si supponga di voler rappresentare un segnale nell’intervallo temporale di 2 s, da -1 a 1, con passo di campionamento dt=4 ms La variabile indipendente (tempo) si rappresenta in MATLAB tramite il vettore: » t=-1:0.004:1; ATTENZIONE al “;” al termine di un’istruzione: serve a far eseguire l’operazione senza visualizzarne il risultato. Utilizzando un passo negativo si possono ottenere delle serie decrescenti 3:-0.5:1 » v=3:-0.5:1 v = 3 2.5 2 1.5 1 Se il passo è sottointeso, è assunto uguale a 1. » v=0:10 v = 0 1 2 3 4 5 6 7 8 9 10 Si può quindi costruire un segnale s(t) (esempio, sinusoide di frequenza 5 Hz,di ampiezza 4) campionando il segnale continuo agli istanti definiti nel vettore t: » s=4*sin(2*pi*5*t); Per visualizzare il segnale si usa la funzione: plot(t,s). plot crea il grafico dei punti individuati da t (asse orizzontale) ed s (asse verticale). Pur essendo s una sequenza, l’onda viene rappresentata in forma continua, interpolando tra i due valori adiacenti per gli istanti di tempo mancanti. plot(t,s,’o’) visualizza i soli campioni della sequenza in funzione dei valori di t. Si analizzi l’help della funzione plot per capirne i diversi parametri. La visualizzazione più adatta ai segnali campionati è ottenuta invece con il comando: stem(t,s); Funzioni definite dall’utente Ad una sequenza di comandi MATLAB può essere associato un nome: in questo modo l’insieme delle funzioni disponibili può essere esteso con funzioni definite dall’utente. La sequenza di istruzioni deve essere scritta in un file di testo (obbligatoriamente con l’estensione .m ): verrà eseguita ogni volta che si digiterà al prompt di MATLAB il nome del comando (che CORRISPONDE al nome del file senza l’estensione). Questi files possono essere scritti con un qualsiasi editor di testo; MATLAB fornisce già un editor adatto allo scopo (comando edit al prompt dei comandi, oppure menu file new ). Esistono due tipi di files .m: scripts • sono sequenze di comandi senza nessuna intestazione: • producono esattamente lo stesso effetto dell’esecuzione al prompt dei comandi contenuti, riga per riga: tutte le variabili generate rimangono nel workspace al termine dell’esecuzione • si lanciano digitando nome_file al prompt dei comandi funzioni accettano parametri in ingresso e restituiscono dei valori (i valori di ingresso e uscita possono essere generici oggetti matriciali di MATLAB) • hanno intestazione function [out1,out2...] = nome_file(in1,in2...) • tutte le variabili generate all’interno della funzione (tranne ovviamente quelle restituite) sono locali: vengono cancellate al termine dell’esecuzione; • si lanciano dal prompt dei comandi tramite: [var1,var2...] = nome_file(par1,par2...); ATTENZIONE: le funzioni definite dall’utente per poter essere eseguite devono trovarsi nella directory corrente (comando cd) o nel path di MATLAB (comando path). MATLAB: linguaggio di programmazione L’ambiente MATLAB possiede un completo linguaggio di programmazione. Vediamo la sintassi delle espressioni che permettono di controllare il flusso dell’esecuzione (cicli, salti condizionali): for var=[insieme di valori], azioni… end, Ad ogni ripetizione del ciclo la variabile assume un valore estratto dal vettore [insieme di valori]: non è necessario che questo vettore sia equispaziato o costruito da soli valori interi!! while (espressione logica) azioni… end if (espressione logica) azioni… else azioni… end, Gli operatori logici in MATLAB sono: == uguale ~= diverso <, >, <=, >= disuguaglianze & AND logico | OR logico MATLAB: visualizzazione Ogni istruzione grafica viene eseguita nella finestra attiva. Per creare più finestre, si utilizza il comando figure, che crea una nuova finestra (e la rende attiva). Per fissare gli estremi di ascissa e ordinata mostrati nella finestra grafica, si si utilizza il comando: axis([xmin xmax ymin ymax]) Infine per aggiungere un testo agli assi e alla figura stessa, esistono i comandi: xlabel(‘testo’), ylabel(‘testo’), title(‘testo’) ATTENZIONE: le stringhe in MATLAB sono delimitate da apici. Si generi e si visualizzi, ad esempio, una sinusoide di frequenza 10 Hz. » t=[-4:.004:4]; » s=sin(2*pi*10*t); » plot(t,s); » axis([-4 4 –1.5 1.5]); » xlabel(‘time [sec]’); » title(‘sinusoide’); Più grafici possono coesistere in un’unica finestra grafica di MATLAB, che può essere suddivisa in più aree grafiche. Il comando che permette di inserire più grafici nella stessa finestra è: subplot(ny,nx,na) dove nx e ny rappresentano il numero di divisioni verticali e orizzontali della finestra, e na rappresenta l’indice del grafico attivo tra i (nx*ny) grafici possibili. I grafici sono ordinati per righe. Ad esempio per dividere la finestra attiva in 4 “quadranti” e selezionare il grafico in basso a sinistra, si scriverà: subplot(2,2,3) Talvolta può essere molto utile sovraimporre un grafico ad un altro grafico già esistente nella finestra attiva. Per evitare che quest’ultimo sia cancellato si deve utilizzare il comando: hold on (hold off per disattivare) DSP IN MATLAB Convoluzione di segnali in MATLAB La funzione MATLAB y=conv(x,h)permette di effettuare la convoluzione di sequenze. La durata del segnale risultante è data dalla somma delle durate dei segnali in ingresso Nel caso di segnali approssimati da sequenze l’effettiva durata è (la+lb-1) con la, lb, durata dei segnali in ingresso in campioni. Trasformata di Fourier discreta di sequenze in MATLAB Ad una sequenza x[n], si può associare una funzione X(f), funzione continua e periodica della frequenza che permette di descrivere x[n] come combinazione lineare di esponenziali complessi. L’operatore che calcola X(f) a partire da x[n] si chiama Trasformata di Fourier. Tramite invece la Trasformata discreta di Fourier (DFT), è possibile associare alla sequenza x[n], di lunghezza N, un’altra sequenza X[f], sempre di lunghezza N, i cui valori corrispondono ai valori di un periodo della Trasformata di Fourier, campionata regolarmente a passo df=fc/N. La funzione MATLAB che calcola la trasformata discreta di Fourier di una sequenza è: X=fft(x); con inversa: x=ifft(X); Le frequenze su cui è definita la sequenza X vanno da –1/(2*dt) a +1/(2*dt). Il primo estremo è incluso solo se la lunghezza del vettore x è un numero pari, mentre entrambi gli estremi sono esclusi per lunghezze dispari. Il primo campione di X, X(1) è corrisponde al valore per f=0. Per riordinare le frequenze esiste la funzione fftshift(). Quindi per poter calcolare la trasformata discreta di Fourier del segnale x[n] e rappresentarne correttamente l’asse delle frequenze: » » » » » N=length(x); X=fftshift(fft(x)); df=1/(N*dt); f=[-N/2+[0:N-1]]*df; % se N è pari f=[-(N-1)/2+[0:N-1]]*df; % se N è dispari oppure se si preferisce rappresentare le frequenze normalizzate (angoli): » N=length(x); » X=fft(x); » dphi=2*pi/N; » phi=[0:dphi:2*pi-dphi]; Per visualizzare il risultato è importante ricordare che la trasformata X sarà sempre un vettore complesso. Quindi si potranno mostrare modulo e fase: » subplot(2,1,1), plot(f,abs(X)); » subplot(2,1,2), plot(f,angle(X)); oppure parte reale e parte immaginaria: » subplot(2,1,1), plot(f,real(X)); » subplot(2,1,2), plot(f,imag(X)); Rappresentazione di filtri numerici FIR/IIR. È sempre possibile rappresentare (e implementare) un filtro numerico a partire dalla sua equazione alle differenze: N M k =1 k =0 y( n) = − ∑ ak y( n − k ) + ∑ bk x ( n − k ) {ak }, {bk } parametri costanti I parametri costanti sono i coefficienti dei polinomi al denominatore (parametri ak) e al numeratore (parametri bk) della trasformata Z del filtro stesso. È immediato in Matlab, rappresentando i coefficienti nei due vettori riga a e b, rappresentare la posizione delle singolarità (zeri e poli) nel dominio della trasformata Z, con il comando: zplane(b,a); Per ottenere le radici dei polinomi a numeratore e/o denominatore si può usare il comando: z=roots(b) (restituisce le radici nel vettore colonna z). La risposta all’impulso del filtro caratterizzato da numeratore e denominatore può essere calcolata con il comando: impz(b,a) La trasformata di Fourier del filtro può essere visualizzata (modulo e fase) con il comando: impz(b,a) Infine il risultato y[n] del passaggio di un segnale x[n] attraverso il filtro [a,b] può essere calcolato con il comando: y=filter(b,a,x)