Per coloro che cercano di stabilire la connessione tra SNR e una normale variabile casuale generata da numpy:
[1]
, dove è importante tenere presente che P è la potenza media .
Oppure in dB:
[2]
In questo caso, abbiamo già un segnale e vogliamo generare rumore per darci un SNR desiderato.
Mentre il rumore può avere diversi gusti a seconda di ciò che stai modellando, un buon inizio (specialmente per questo esempio di radiotelescopio) è Additive White Gaussian Noise (AWGN) . Come affermato nelle risposte precedenti, per modellare AWGN è necessario aggiungere una variabile casuale gaussiana a media zero al segnale originale. La varianza di quella variabile casuale influenzerà la potenza media del rumore.
Per una variabile casuale gaussiana X, la potenza media
, nota anche come secondo momento , è
[3] 
Quindi per il rumore bianco,
e la potenza media è quindi uguale alla varianza
.
Quando si modella questo in python, è possibile
1. Calcolare la varianza in base a un SNR desiderato e un insieme di misurazioni esistenti, che funzionerebbero se si prevede che le misurazioni abbiano valori di ampiezza abbastanza coerenti.
2. In alternativa, è possibile impostare la potenza del rumore a un livello noto in modo che corrisponda a qualcosa come il rumore del ricevitore. Il rumore del ricevitore può essere misurato puntando il telescopio nello spazio libero e calcolando la potenza media.
In ogni caso, è importante assicurarsi di aggiungere rumore al segnale e prendere le medie nello spazio lineare e non in unità dB.
Ecco un codice per generare un segnale e tracciare la tensione, la potenza in Watt e la potenza in dB:
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(1, 100, 1000)
x_volts = 10*np.sin(t/(2*np.pi))
plt.subplot(3,1,1)
plt.plot(t, x_volts)
plt.title('Signal')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
x_watts = x_volts ** 2
plt.subplot(3,1,2)
plt.plot(t, x_watts)
plt.title('Signal Power')
plt.ylabel('Power (W)')
plt.xlabel('Time (s)')
plt.show()
x_db = 10 * np.log10(x_watts)
plt.subplot(3,1,3)
plt.plot(t, x_db)
plt.title('Signal Power in dB')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()

Ecco un esempio per l'aggiunta di AWGN in base a un SNR desiderato:
target_snr_db = 20
sig_avg_watts = np.mean(x_watts)
sig_avg_db = 10 * np.log10(sig_avg_watts)
noise_avg_db = sig_avg_db - target_snr_db
noise_avg_watts = 10 ** (noise_avg_db / 10)
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(noise_avg_watts), len(x_watts))
y_volts = x_volts + noise_volts
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise (dB)')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()

Ed ecco un esempio per l'aggiunta di AWGN in base a una potenza di rumore nota:
target_noise_db = 10
target_noise_watts = 10 ** (target_noise_db / 10)
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(target_noise_watts), len(x_watts))
y_volts = x_volts + noise_volts
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()
