Для тих, хто намагається встановити зв’язок між SNR та нормальною випадковою величиною, що генерується numpy:
[1]
, де важливо мати на увазі, що Р - середня потужність.
Або в дБ:
[2]
У цьому випадку ми вже маємо сигнал, і ми хочемо генерувати шум, щоб дати нам бажаний SNR.
У той час як шум може прийти в різних смаків в залежності від того, що ви моделювання, гарний початок (особливо для цього радіо , наприклад телескоп) є адитивним білим гауссовским шумом (AWGN) . Як зазначалося в попередніх відповідях, для моделювання AWGN вам потрібно додати нульову середню гауссову випадкову величину до вихідного сигналу. Дисперсія цієї випадкової величини впливатиме на середню потужність шуму.
Для гауссової випадкової величини X середня потужність
, також відома як другий момент , дорівнює
[3] 
Отже, для білого шуму
середня потужність тоді дорівнює дисперсії
.
При моделюванні цього в python, ви можете:
1. Розрахувати дисперсію на основі бажаного SNR та набору існуючих вимірювань, які працювали б, якщо ви очікуєте, що ваші вимірювання мають досить постійні значення амплітуди.
2. Як варіант, ви можете встановити потужність шуму на відомий рівень, щоб відповідати чомусь типу шуму приймача. Шум приймача можна виміряти, спрямувавши телескоп у вільний простір і розрахувавши середню потужність.
У будь-якому випадку, важливо переконатися, що ви додаєте шум до свого сигналу і приймаєте середні значення в лінійному просторі, а не в дБ.
Ось деякий код для генерації сигналу та графіку напруги, потужності у ватах та потужності в дБ:
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()

Ось приклад додавання AWGN на основі бажаного SNR:
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()

І ось приклад для додавання AWGN на основі відомої потужності шуму:
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()
