如何在Python(或Numpy/Scipy)中生成复杂高斯白噪声信号?

5

我正在进行一些有关数字信号处理的工作,需要生成离散的复高斯白噪声信号。我知道可以使用numpy.random.normal(0, 1, n)生成离散序列,但它是在实数域中的。在Matlab中很容易模拟,但我想知道如何用Python替换Matlab代码?

1个回答

14
这里有一个方法可以实现。它生成了一个形状为(n,2)的标准正态变量数组,然后使用.view()方法将该数组视为形状为(n,)的复数值数组。
In [26]: n = 10                                                                                                     

In [27]: z = np.random.randn(n, 2).view(np.complex128)                                                              

In [28]: z                                                                                                          
Out[28]: 
array([[ 0.90179497-0.14081956j],
       [-2.17633115+0.88782764j],
       [ 0.94807348+0.27575325j],
       [-1.25452512+0.64883484j],
       [-0.58886548+0.15419947j],
       [ 0.58296574+1.45711421j],
       [ 0.803825  +0.6197812j ],
       [ 0.09225137+0.38012939j],
       [ 0.5017482 -0.39747648j],
       [-1.00186317+1.02918796j]])

如果您更喜欢使用该函数,可以将np.random.randn(n, 2)替换为np.random.normal(size=(n,2))

根据维基百科关于复正态分布的文章,复标准正态随机变量的实部和虚部的方差应为1/2(因此复样本的方差为1)。这次我将使用np.random.normal,但您也可以适当缩放np.random.rand

创建一个大样本,以便我们可以验证方差接近1:

In [19]: n = 100000                                                                                                                                                               

In [20]: z = np.random.normal(loc=0, scale=np.sqrt(2)/2, size=(n, 2)).view(np.complex128)                                                                                         

In [21]: z[:10]                                                                                                                                                                   
Out[21]: 
array([[ 0.31439115+1.39059186j],
       [ 0.18306617+1.19364778j],
       [ 0.20281354+0.31695626j],
       [ 0.27230747+1.18380383j],
       [-0.71353935-0.11587812j],
       [-0.2371236 +0.91542372j],
       [ 0.04254323+1.50538309j],
       [ 0.23024067+0.96947144j],
       [ 0.6954942 +0.20933687j],
       [-0.66853093+2.00389192j]])

正如预期的那样,方差接近于1:

In [22]: np.var(z)                                                                                                                                                                
Out[22]: 0.9998204444495904

或者,您可以使用np.random.multivariate_normal,并使用0.5*np.eye(2)作为协方差矩阵:

In [31]: z = np.random.multivariate_normal(np.zeros(2), 0.5*np.eye(2), size=n).view(np.complex128)                                                                                

In [32]: z[:10]                                                                                                                                                                   
Out[32]: 
array([[-0.25012362+0.80450233j],
       [-0.85853563+0.05350865j],
       [ 0.36715694-0.10483562j],
       [ 1.0740756 +0.081779j  ],
       [-1.04655701+0.15211247j],
       [ 0.18248473+0.49350875j],
       [ 0.6152102 +0.08037717j],
       [ 0.12423999+0.56175553j],
       [-1.05282963-0.60113989j],
       [-0.01340098+0.80751573j]])

In [33]: np.var(z)                                                                                                                                                                
Out[33]: 1.0001327524747319

1
这仅适用于“圆对称复正态”。还有更通用的方法吗? - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接