I am doing some works about DSP(digital signal process), and there need to generate a discrete complex white gaussian noise signal. I know I can use numpy.random.normal(0, 1, n) to generate the discrete sequence, but it is in real number field. It is easy to simulate with Matlab, but I wander how to replace matlab code with python?
解决方案
Here's one way you can do it. This generates an array of standard normal variates of shape (n, 2), and then uses the .view() method to view the array as an array of complex values with shape (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]])
You can replace np.random.randn(n, 2) with np.random.normal(size=(n, 2)) if you prefer to use that function.
According to the wikipedia article on the complex normal distribution, the variance of the real and imaginary parts of a complex standard normal random variable should be 1/2 (so the variance of the complex samples is 1). I'll use np.random.normal this time, but you could also scale np.random.rand appropriately.
Create a large sample so we can verify that the variance is close to 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]])
As expected, the variance is close to 1:
In [22]: np.var(z)
Out[22]: 0.9998204444495904
Alternatively, you can use np.random.multivariate_normal, and use 0.5*np.eye(2) for the covariance matrix:
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