Esercizio - laboratorio 3, segnali discreti
In questa pagina 7
Testo (laboratorio 3 del corso Teoria dei Segnali, UniPD, file lab3.m, parti 1-5). (1) Rappresentare con stem parte reale, parte immaginaria, modulo e fase di un esponenziale complesso causale su , per (con , , ), e della sua versione traslata di campioni. (2) Calcolarne l'energia. (3) Calcolare l'area del segnale che vale sugli istanti con . (4) Calcolare energia e potenza su un periodo di con e . (5) Convolvere due impulsi rettangolari discreti con : per su e per su , e costruire l'asse temporale del risultato.
Teoria usata: Segnali a tempo discretoUn segnale a tempo discreto è una funzione complessa $s(nT)$ definita sui multipli interi del quanto temporale $T$ (insieme $\mathbb Z(T)$, velocità $F_p=1/T$). Le definizioni sono quelle dei segnali continui con la somma al posto dell'integrale e il quanto $T$ al posto di $dt$: area $\sum T,s(nT)$, energia $\sum T|s(nT)|^2$, convoluzione $\sum T,x(kT)y(nT-kT)$. L'impulso ideale discreto vale $1/T$ nell'origine. Esponenziali e sinusoidi discreti sono periodici solo se $f_0/F_p$ è razionale e hanno frequenza ambigua a meno di multipli di $F_p$. I segnali periodici con periodo $NT$ sono descritti da $N$ valori e si trattano al calcolatore.Segnali a tempo discreto →, Energia, potenza e valor medio dei segnaliSu un segnale continuo si calcolano quattro numeri riassuntivi: l'area $\int s,dt$, il valor medio (componente continua) $\lim\frac1{2T}\int_{-T}^Ts,dt$, l'energia $\int|s|^2dt$ e la potenza media $\lim\frac1{2T}\int_{-T}^T|s|^2dt$. Un segnale ad energia finita ha potenza nulla e uno a potenza finita non nulla ha energia infinita. Per un segnale periodico di periodo $T_p$ area ed energia si calcolano su un periodo; un segnale periodico è la ripetizione periodica $\sum_ku(t-kT_p)$ di un suo periodo. Valgono per traslazione l'invarianza, per scala $s(at)$ la divisione per $|a|$.Energia, potenza e valor medio dei segnali →, ConvoluzioneLa convoluzione $xy(t)=\int x(u),y(t-u),du$ combina due segnali ribaltando e traslando il secondo, moltiplicando e integrando. È commutativa, associativa, lineare; l'area del risultato è il prodotto delle aree; l'estensione è la somma delle estensioni (estremo con estremo); l'impulso $\delta$ è l'elemento neutro; la convoluzione con il gradino integra. Per due segnali periodici di uguale periodo si usa la convoluzione ciclica (integrale su un periodo). È l'operazione del filtraggio: l'uscita di un filtro è la convoluzione dell'ingresso con la risposta impulsiva.Convoluzione →, Serie notevoli - geometrica, telescopica, armonicaLe serie di cui si conosce il carattere e da usare come termine di paragone: geometrica (converge a 1/(1-q) se |q|<1), telescopiche (somma b_1 - lim b_n, come Mengoli), armonica generalizzata (1/n^alpha converge se e solo se alpha>1).Serie notevoli - geometrica, telescopica, armonica → (somma della serie geometrica), Serie di FourierUn segnale periodico di periodo $T_p$ si scrive come somma di esponenziali alle frequenze multiple della fondamentale $F=1/T_p$: $s(t)=\sum_nS_ne^{i2\pi nFt}$, con $S_n=\frac1{T_p}\int_{T_p}s(t)e^{-i2\pi nFt}dt$. Si basa sull'ortogonalità degli esponenziali su un periodo. $S_0$ è il valor medio; per segnali reali $S_{-n}=S_n^$ e si passa alla forma con coseni e seni; vale il teorema di Parseval $P=\sum|S_n|^2$. La convoluzione ciclica diventa il prodotto $T_pX_nY_n$ dei coefficienti. Le somme troncate presentano il fenomeno di Gibbs vicino ai salti.Serie di Fourier → (potenza della cosinusoide).
Cosa si vuole calcolare e perché
Un segnale discreto su è l'elenco dei valori agli istanti multipli del quanto temporale . Nel corso le grandezze globali si scrivono tenendo esplicito, in modo che valgano anche quando e si confrontino con quelle dei segnali continui da cui i campioni provengono:
Il fattore è esattamente il del laboratorio 2: ogni campione rappresenta una striscia di larghezza . Nel laboratorio il vettore degli istanti nTp ha passo T; i campioni x sono un vettore della stessa lunghezza. Il codice mostra come tenere nei conti: T * np.sum(...) per area ed energia, T * np.convolve(...) per la convoluzione.
Parte 1 - esponenziale complesso causale, parte reale, immaginaria, modulo e fase
import numpy as np
import matplotlib.pyplot as plt
# PARTE 1 - esponenziale complesso causale su Z(T): x(nT) = alpha^(nT) e^(i 2 pi f nT) per nT >= 0
T = 1
nTp = np.arange(-10, 51) * T # MATLAB [-10:T:50]: 61 istanti da -10 a 50
alpha = 0.8
f = 1 / 12
x = (nTp >= 0) * (alpha ** nTp * np.exp(1j * 2 * np.pi * f * nTp)) # (nTp >= 0) vale 1 o 0: e' il gradino
k = 5 # traslazione di k campioni
x_traslato = (nTp - k * T >= 0) * (alpha ** (nTp - k * T) * np.exp(1j * 2 * np.pi * f * (nTp - k * T)))
x_reale = np.real(x)
x_immaginaria = np.imag(x)
x_modulo = np.abs(x)
x_fase = np.angle(x)
plt.figure(figsize=(10, 7))
plt.subplot(2, 2, 1)
plt.stem(nTp, x_reale, basefmt=' ', label='Parte reale')
plt.stem(nTp, np.real(x_traslato), linefmt='C1-', markerfmt='C1o', basefmt=' ', label='Parte reale traslata')
plt.grid(True); plt.xlabel('nT [secondi]'); plt.ylabel('Ampiezza'); plt.legend()
plt.subplot(2, 2, 2)
plt.stem(nTp, x_immaginaria, basefmt=' ', label='Parte immaginaria')
plt.stem(nTp, np.imag(x_traslato), linefmt='C1-', markerfmt='C1o', basefmt=' ', label='Parte immaginaria traslata')
plt.grid(True); plt.xlabel('nT [secondi]'); plt.ylabel('Ampiezza'); plt.legend()
plt.subplot(2, 2, 3)
plt.stem(nTp, x_modulo, basefmt=' ', label='Modulo')
plt.stem(nTp, np.abs(x_traslato), linefmt='C1-', markerfmt='C1o', basefmt=' ', label='Modulo traslato')
plt.grid(True); plt.xlabel('nT [secondi]'); plt.legend()
plt.subplot(2, 2, 4)
plt.stem(nTp, x_fase, basefmt=' ', label='Fase')
plt.stem(nTp, np.angle(x_traslato), linefmt='C1-', markerfmt='C1o', basefmt=' ', label='Fase traslata')
plt.grid(True); plt.xlabel('nT [secondi]'); plt.legend()
plt.tight_layout()
plt.show()
print("campioni:", len(nTp), " primo:", nTp[0], " ultimo:", nTp[-1])
for n in [0, 1, 3, 6]:
xn = x[nTp == n][0]
print(f"x({n}T) = {xn.real:+.4f} {xn.imag:+.4f}i modulo {abs(xn):.4f} (0.8^{n} = {0.8 ** n:.4f}) fase {np.angle(xn):+.4f} (2 pi n/12 = {2 * np.pi * n / 12:.4f})")
print("x(-1T) =", x[nTp == -1][0], " (il segnale e' causale)")
print("x traslato = x ritardato di 5 campioni:", np.allclose(x_traslato[k:], x[:-k]))Risultato:
campioni: 61 primo: -10 ultimo: 50
x(0T) = +1.0000 +0.0000i modulo 1.0000 (0.8^0 = 1.0000) fase +0.0000 (2 pi n/12 = 0.0000)
x(1T) = +0.6928 +0.4000i modulo 0.8000 (0.8^1 = 0.8000) fase +0.5236 (2 pi n/12 = 0.5236)
x(3T) = +0.0000 +0.5120i modulo 0.5120 (0.8^3 = 0.5120) fase +1.5708 (2 pi n/12 = 1.5708)
x(6T) = -0.2621 +0.0000i modulo 0.2621 (0.8^6 = 0.2621) fase +3.1416 (2 pi n/12 = 3.1416)
x(-1T) = 0j (il segnale e' causale)
x traslato = x ritardato di 5 campioni: TrueIl segnale. Con è per e per : una progressione geometrica di ragione complessa (con , ). Il fattore (nTp >= 0) vale quando la condizione è vera e quando è falsa: è il gradino , e rende il segnale causale (). Da questa ragione si ricava tutto:
- modulo : scende di un fattore a ogni passo (), come in tabella;
- fase ( rad a ogni passo): per , per , per .
np.anglerestituisce l'angolo principale in , quindi da in poi la fase "salta" a e prosegue; non è un errore, è la fase riportata modulo ; - parte reale e parte immaginaria (formula di Eulero, Numeri complessiI numeri complessi estendono i reali introducendo l'unità immaginaria $i$ ($i^2 = -1$) e possono essere rappresentati in forma algebrica, trigonometrica o polare. Tramite la formula di Eulero e le proprietà del modulo e dell'argomento, è possibile calcolare agilmente prodotti, potenze e radici ennesime.Numeri complessi →): due oscillazioni di periodo campioni con ampiezza che decade.
Per il segnale vale zero e np.angle(0) restituisce .
Grafico interattivo: Parte reale di x(n) = 0,8^n e^(iπn/6) per n ≥ 0 (con T = 1): un coseno di periodo 12 campioni, con l'ampiezza che decade di un fattore 0,8 a ogni campione; il valore a n = 0 è 1 e il segnale è nullo per n < 0
Traslazione. x_traslato si ottiene sostituendo con nell'espressione, con : è lo stesso segnale ritardato di 5 campioni, . Il confronto x_traslato[5:] con x[:-5] (stampato True) lo conferma: il campione di quello traslato è il campione dell'originale (Segnali a tempo continuo - definizioni e trasformazioniUn segnale a tempo continuo è una funzione complessa di variabile reale $s:\mathbb R\to\mathbb C$ (reale se $s=s^*$). Si descrive con parte reale e immaginaria oppure con modulo e fase (valore principale in $(-\pi,\pi]$). Sui segnali si fanno tre operazioni elementari: ribaltamento $s(-t)$, traslazione $s(t-t_0)$ e cambio di scala $s(at)$. Ogni segnale si scompone in una parte pari e una dispari, in una reale e una immaginaria, in una hermitiana e una antihermitiana. Estensione e durata dicono dove il segnale è diverso da zero; i segnali con estensione nel semiasse positivo sono causali.Segnali a tempo continuo - definizioni e trasformazioni →, trasformazioni dell'asse). Nei grafici a gambo la versione traslata ha la stessa forma, ritardata: parte da con modulo (e non ), e la sua fase vale , cioè quella originale ritardata di cinque campioni.
Differenze Python. plt.stem(x, y) è lo stem di MATLAB; i marker sono già pieni ('filled' non serve), basefmt=' ' toglie la linea di base; per sovrapporre due serie di colore diverso si danno linefmt e markerfmt ('C1-', 'C1o'). 1j è l'unità immaginaria; il prodotto di un vettore booleano per un vettore complesso funziona (vero vale 1, falso 0).
Parte 2 - energia
Dal blocco della parte 1 si calcola, con la formula del corso:
# PARTE 2 - energia: E = somma di T |x(nT)|^2
energia_segnale = T * np.sum(np.abs(x) ** 2)
print(f"L'energia del segnale è {energia_segnale:.3f} V^2*s")
# confronto con la serie geometrica: somma di 0.64^n per n = 0..50, e per n = 0..infinito
print(f"somma finita (n da 0 a 50): {np.sum(0.64 ** np.arange(51)):.6f}")
print(f"serie geometrica 1/(1 - 0.64) = {1 / (1 - 0.64):.6f}")
print(f"energia del segnale traslato: {T * np.sum(np.abs(x_traslato) ** 2):.6f}")L'energia del segnale è 2.778 V^2*s
somma finita (n da 0 a 50): 2.777778
serie geometrica 1/(1 - 0.64) = 2.777778
energia del segnale traslato: 2.777778, perché . La fase non conta (il modulo quadro cancella ) e la somma è la serie geometrica troncata a :
Sono uguali alla sesta cifra, perché : il segnale è praticamente finito dopo pochi campioni. L'energia del segnale traslato è identica (): l'energia non dipende dall'istante in cui il segnale parte (Energia, potenza e valor medio dei segnaliSu un segnale continuo si calcolano quattro numeri riassuntivi: l'area $\int s,dt$, il valor medio (componente continua) $\lim\frac1{2T}\int_{-T}^Ts,dt$, l'energia $\int|s|^2dt$ e la potenza media $\lim\frac1{2T}\int_{-T}^T|s|^2dt$. Un segnale ad energia finita ha potenza nulla e uno a potenza finita non nulla ha energia infinita. Per un segnale periodico di periodo $T_p$ area ed energia si calcolano su un periodo; un segnale periodico è la ripetizione periodica $\sum_ku(t-kT_p)$ di un suo periodo. Valgono per traslazione l'invarianza, per scala $s(at)$ la divisione per $|a|$.Energia, potenza e valor medio dei segnali →).
Parte 3 - area
# PARTE 3 - area di un segnale discreto: somma di T x(nT)
T = 2
t_inizio = -6
t_fine = 6
nTp = np.arange(t_inizio, t_fine + 1, T) # -6, -4, ..., 6: 7 istanti
x = np.array([0.5, 1, 2, 3, 2, 1, 0.5])
print("istanti:", nTp, " campioni:", len(x))
plt.figure()
plt.stem(nTp, x, basefmt=' ')
plt.grid(True); plt.xlabel('nT'); plt.ylabel('x(nT)')
plt.show()
area_signal = T * np.sum(x)
print(f"L'area del segnale vale: {area_signal:.2f}")istanti: [-6 -4 -2 0 2 4 6] campioni: 7
L'area del segnale vale: 20.00L'area è . Se si dimenticasse si troverebbe (la somma dei campioni), cioè la metà: il fattore è proprio quello che trasforma una somma di campioni in un'area. Attenzione al controllo delle lunghezze: np.arange(t_inizio, t_fine + 1, T) dà istanti, tanti quanti i valori di x; con un numero diverso plt.stem darebbe errore. Si somma al secondo estremo perché np.arange esclude l'estremo finale.
Parte 4 - energia e potenza di un segnale periodico
# PARTE 4 - energia e potenza su un periodo di un segnale discreto periodico
T = 0.5
nTp = np.arange(-40, 41) * T # MATLAB -20:T:20, 81 istanti
f = 1 / 20
Tp = 1 / f # periodo: 20 s
x = 2.5 + np.cos(2 * np.pi * f * nTp)
campioni_periodo = round(Tp / T) # 40 campioni in un periodo
E_periodo = T * np.sum(np.abs(x[:campioni_periodo]) ** 2)
P_periodo = E_periodo / Tp
plt.figure()
plt.stem(nTp, x, basefmt=' ')
plt.grid(True); plt.title('Segnale periodico reale'); plt.xlabel('nT'); plt.ylabel('x(nT)')
plt.show()
print(f"campioni per periodo: {campioni_periodo}")
print(f"Energia su un periodo: {E_periodo:.2f}")
print(f"Potenza su un periodo: {P_periodo:.2f}")
print(f"2.5^2 + 1/2 = {2.5 ** 2 + 0.5}")
print(f"la stessa potenza partendo da un altro campione (n = 17): {T * np.sum(x[17:17 + campioni_periodo] ** 2) / Tp:.2f}")
print(f"potenza = media dei quadrati dei campioni di un periodo: {np.mean(x[:campioni_periodo] ** 2):.2f}")campioni per periodo: 40
Energia su un periodo: 135.00
Potenza su un periodo: 6.75
2.5^2 + 1/2 = 6.75
la stessa potenza partendo da un altro campione (n = 17): 6.75
potenza = media dei quadrati dei campioni di un periodo: 6.75Un segnale periodico ha energia infinita: ogni periodo aggiunge lo stesso contributo, quindi si guarda la potenza, l'energia di un periodo divisa per la durata del periodo. Il segnale è con Hz, periodo s; con s un periodo contiene campioni (round e non floor, per non sbagliare di uno per un arrotondamento). Allora
Il fattore si semplifica: , la media dei quadrati dei campioni di un periodo (ultima riga stampata). Il valore atteso: ; il termine in ha media su un periodo e ha media , quindi (con le serie di Fourier: , Serie di FourierUn segnale periodico di periodo $T_p$ si scrive come somma di esponenziali alle frequenze multiple della fondamentale $F=1/T_p$: $s(t)=\sum_nS_ne^{i2\pi nFt}$, con $S_n=\frac1{T_p}\int_{T_p}s(t)e^{-i2\pi nFt}dt$. Si basa sull'ortogonalità degli esponenziali su un periodo. $S_0$ è il valor medio; per segnali reali $S_{-n}=S_n^*$ e si passa alla forma con coseni e seni; vale il teorema di Parseval $P=\sum|S_n|^2$. La convoluzione ciclica diventa il prodotto $T_pX_nY_n$ dei coefficienti. Le somme troncate presentano il fenomeno di Gibbs vicino ai salti.Serie di Fourier →). Un periodo qualunque va bene: partendo da un altro campione (n=17) si trova lo stesso valore. Il segnale ha 81 campioni (), più di due periodi.
Grafico interattivo: x(nT) = 2,5 + cos(2π f nT) con f = 1/20 e T = 0,5 s, in funzione dell'indice n (nT = n/2 secondi): periodo di 40 campioni (20 s), valore medio 2,5, oscillazione tra 1,5 e 3,5
Parte 5 - convoluzione di due rect discreti
# PARTE 5 - convoluzione di due rect discreti
T = 0.25 # passo temporale
tx = np.arange(-20, 21) * T # -5, -4.75, ..., 5 (41 campioni)
th = np.arange(-16, 17) * T # -4, ..., 4 (33 campioni)
x = np.zeros(len(tx))
h = np.zeros(len(th))
x_left, x_right = -2, 2
h_left, h_right = -1, 1
x[(tx >= x_left) & (tx <= x_right)] = 1
h[(th >= h_left) & (th <= h_right)] = 1.3
y = T * np.convolve(x, h) # convoluzione: il fattore T e' nella definizione
ty = (tx[0] + th[0]) + np.arange(len(y)) * T # asse: da tx[0]+th[0] a tx[-1]+th[-1] con passo T
plt.figure(figsize=(8, 7))
plt.subplot(3, 1, 1)
plt.stem(tx, x, basefmt=' '); plt.xlabel('nT'); plt.ylabel('x(nT)'); plt.ylim(0, 1.7); plt.xlim(ty[0], ty[-1]); plt.grid(True)
plt.subplot(3, 1, 2)
plt.stem(th, h, basefmt=' '); plt.xlabel('nT'); plt.ylabel('h(nT)'); plt.ylim(0, 1.7); plt.xlim(ty[0], ty[-1]); plt.grid(True)
plt.subplot(3, 1, 3)
plt.stem(ty, y, basefmt=' '); plt.xlabel('nT'); plt.ylabel('y(nT)'); plt.grid(True)
plt.tight_layout()
plt.show()
print(f"campioni: x = {len(x)} (di cui {int(x.sum())} a 1), h = {len(h)} (di cui {int((h > 0).sum())} a 1.3), y = {len(y)}")
print(f"asse di y: da {ty[0]} a {ty[-1]} (= tx[0]+th[0] e tx[-1]+th[-1] = {tx[-1] + th[-1]})")
print(f"primo e ultimo istante con y > 0: {ty[y > 0][0]} e {ty[y > 0][-1]}")
print(f"massimo di y: {y.max():.4f} (= T * 9 * 1.3 = {T * 9 * 1.3:.4f}); numero di campioni al massimo: {int(np.sum(np.isclose(y, y.max())))}")
print(f"primo valore non nullo di y: {y[y > 0][0]:.4f} (= T * 1.3 = {T * 1.3:.4f})")
area_x = T * np.sum(x)
area_h = T * np.sum(h)
area_y = T * np.sum(y)
print(f"aree: x = {area_x:.4f}, h = {area_h:.4f}, prodotto = {area_x * area_h:.5f}, y = {area_y:.5f}")Risultato:
campioni: x = 41 (di cui 17 a 1), h = 33 (di cui 9 a 1.3), y = 73
asse di y: da -9.0 a 9.0 (= tx[0]+th[0] e tx[-1]+th[-1] = 9.0)
primo e ultimo istante con y > 0: -3.0 e 3.0
massimo di y: 2.9250 (= T * 9 * 1.3 = 2.9250); numero di campioni al massimo: 9
primo valore non nullo di y: 0.3250 (= T * 1.3 = 0.3250)
aree: x = 4.2500, h = 2.9250, prodotto = 12.43125, y = 12.43125Il calcolo. np.convolve(x, h) calcola senza , quindi si moltiplica per T: è la definizione del corso . Il vettore ha campioni.
L'asse dei tempi. Il campione di indice della convoluzione somma un campione di di istante e uno di di istante con , quindi cade nell'istante . L'asse parte da e arriva a con passo (nel codice tx[0] + th[0] + np.arange(len(y)) * T, che è (tx(1)+th(1)) : T : (tx(end)+th(end)) di MATLAB). Il risultato è nullo fuori da , la somma degli estremi dei due supporti ( e ).
La forma. Il risultato è un trapezio: per tra e (9 campioni) il rect corto sta tutto dentro quello lungo, e la convoluzione vale
mentre ai bordi sale di a ogni passo (1 campione sovrapposto, poi 2, ...). In formula, il numero di campioni sovrapposti nell'indice è e per questo numero.
Grafico interattivo: y(nT) = T·(x*h) con T = 0,25, in funzione dell'indice m (nT = m/4 secondi): trapezio con 9 campioni al massimo 2,925 (|m| ≤ 4, cioè |nT| ≤ 1), che sale di 0,325 a ogni passo e si annulla fuori da |m| ≤ 12 (|nT| ≤ 3)
Il massimo è un po' più grande del valore del caso continuo con gli stessi rect ( per un rect di larghezza e altezza ): i campioni sono quelli compresi tra gli estremi inclusi, e un rect di 9 campioni ha "larghezza" e non (stesso fenomeno del laboratorio 2: il rect continuo ha l'emivalore agli estremi, il vettore li conta interi). Anche per questo l'area non è quella ideale: area di : , area di : , prodotto , e l'area di calcolata con vale : l'area della convoluzione è il prodotto delle aree (verificato, ultima riga). Con il passo giusto nella definizione la regola vale esattamente.
Controllo
- Energia: (serie geometrica di ragione ); invariante per traslazione.
- Area: (); potenza: .
- Convoluzione: 73 campioni, asse da a , supporto , massimo , area .
Versione ripasso
- Formule con . Area , energia , convoluzione
np.convolve; asse del risultato da a con passo . - Esponenziale causale per : modulo , fase (angolo principale), energia , uguale per il segnale traslato (ritardato di 5 campioni).
- Area dei 7 campioni con : .
- Periodico : campioni, , .
- Due rect: trapezio nullo fuori da , massimo ; area .