如何通过Python:NumPy/SciPy直接在频域生成高斯分布的随机样本?

如何通过Python:NumPy/SciPy直接在频域生成高斯分布的随机样本?,numpy,scipy,gaussian,noise,Numpy,Scipy,Gaussian,Noise,通过使用(比如)NumPy,可以很容易地从正态(高斯)分布中提取(伪)随机样本: import numpy as np mu, sigma = 0, 0.1 # mean and standard deviation s = np.random.normal(mu, sigma, 1000) 现在,考虑 s>代码>的快速傅立叶变换: from scipy.fftpack import fft sHat = fft(s) 考虑到,假设直接在频域生成高斯随机数对于各种应用可能更聪明(?(因此,有

通过使用(比如)NumPy,可以很容易地从正态(高斯)分布中提取(伪)随机样本:

import numpy as np
mu, sigma = 0, 0.1 # mean and standard deviation
s = np.random.normal(mu, sigma, 1000)

现在,考虑<代码> s>代码>的快速傅立叶变换:

from scipy.fftpack import fft
sHat = fft(s)
考虑到,假设直接在频域生成高斯随机数对于各种应用可能更聪明(?(因此,有效?),并且据报道,
sHat
可以直接生成,而无需理论上所示的
s
的傅里叶变换

你能就如何实现这样一个有用的想法给新手(比如我)一些建议吗?有利的是,我在网上找不到一个可用的实现


以下是我对上述理论解释的编码尝试:

import numpy as np 
from scipy.fftpack import ifft

N = 100
gaussComplex = np.full(shape=N, dtype=complex, fill_value=0.+0.j)

mu, sigma = 0, 1
s = np.random.normal(mu, sigma, N)

iters = np.arange(N) # 0..N-1

# 0..N/2-1
for i, item in enumerate(iters[:N/2]):
    gaussComplex[i] = complex(s[i], s[i+N/2])

conjugateGaussComplex = np.conjugate(gaussComplex)

# N/2..N-1
for i, item in enumerate(iters[N/2:]):
    gaussComplex[item] = conjugateGaussComplex[N-item]

sNew = ifft(gaussComplex)
s
sNew
进行比较,可以发现以下几点,因为我认为它们是相同的:

plt.plot(sHat.real, 'blue')
plt.plot(s, 'red')

白噪声的傅里叶变换就是白噪声

这是真的,但这并不意味着它们是完全相同的-否则做FFT就没有多大意义了

如果绘制
s
fft(s)
的实部,您将看到变换后的噪声具有更高的值

相反,如果用标准偏差1的随机值填充
gaussComplex
,则反向变换的噪声的标准偏差将低得多。这就是你观察到的

要在频域中生成高斯白噪声的FFT,需要对其进行正确的缩放。在您的情况下,这应该可以做到:

gaussComplex *= np.sqrt(N/2)
您需要按
sqrt(N)
进行缩放,因为这是FFT的标准化因子。此外,您还需要按
1/sqrt(2)
进行缩放,因为在FFT的实部和虚部中都放置了标准偏差为1的噪声。(但是,绝对值的标准偏差应为1,因此需要除以
sqrt(1+1)

使用正确的缩放比例绘制
s
sNew
,结果如下:

结果不完全相同(如预期),但噪声在相同范围内变化-两者的标准偏差均为~1