对于那些试图在SNR和 numpy 生成的正常随机变量之间建立联系的人:
[1] ,重要的是要记住 P 是平均功率。
或以 dB 为单位:
[2]
在这种情况下,我们已经有了一个信号,我们想要产生噪声来给我们一个想要的 SNR。
虽然根据您要建模的内容,噪声可以有不同的风格,但一个好的开始(尤其是对于这个射电望远镜示例)是加性高斯白噪声 (AWGN)。如前面的答案所述,要对 AWGN 建模,您需要在原始信号中添加一个零均值高斯随机变量。该随机变量的方差将影响平均噪声功率。
对于高斯随机变量 X,平均功率,也称为二阶矩,为
[3]
所以对于白噪声,平均功率等于方差。
在 python 中对此进行建模时,您可以
1. 根据所需的 SNR 和一组现有测量值计算方差,如果您希望测量值具有相当一致的幅度值,这将起作用。
2. 或者,您可以将噪声功率设置为已知水平,以匹配接收器噪声之类的东西。接收器噪声可以通过将望远镜指向自由空间并计算平均功率来测量。
无论哪种方式,确保在信号中添加噪声并在线性空间而不是 dB 单位中取平均值非常重要。
下面是一些用于生成信号并绘制电压、以瓦特为单位的功率和以 dB 为单位的功率的代码:
# Signal Generation
# matplotlib inline
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()
以下是根据所需 SNR 添加 AWGN 的示例:
# Adding noise using target SNR
# Set a target SNR
target_snr_db = 20
# Calculate signal power and convert to dB
sig_avg_watts = np.mean(x_watts)
sig_avg_db = 10 * np.log10(sig_avg_watts)
# Calculate noise according to [2] then convert to watts
noise_avg_db = sig_avg_db - target_snr_db
noise_avg_watts = 10 ** (noise_avg_db / 10)
# Generate an sample of white noise
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(noise_avg_watts), len(x_watts))
# Noise up the original signal
y_volts = x_volts + noise_volts
# Plot signal with noise
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()
# Plot in dB
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 的示例:
# Adding noise using a target noise power
# Set a target channel noise power to something very noisy
target_noise_db = 10
# Convert to linear Watt units
target_noise_watts = 10 ** (target_noise_db / 10)
# Generate noise samples
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(target_noise_watts), len(x_watts))
# Noise up the original signal (again) and plot
y_volts = x_volts + noise_volts
# Plot signal with noise
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()
# Plot in dB
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()