Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a complex gaussian white noise signal in python(or numpy/scipy)?

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?

like image 521
Hu Xixi Avatar asked Oct 18 '25 15:10

Hu Xixi


1 Answers

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
like image 189
Warren Weckesser Avatar answered Oct 21 '25 05:10

Warren Weckesser



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!