Is there a way in python not to generate (nan*j) when calculating (1/0+0j) in numpy

77 Views Asked by At

I am new to python and I am converting some of Matlab scripts to Python. I reached this issue when dealing with complex arrays with numpy when I need to get the reciprocal of the array elements. If the element is 0+0j then the reciprocal is: 1/(0+0j)= inf+nanj. example:

import numpy as np
array1 = np.array([[6+2j, 6], [0, 4]])
print(array1)
reciprocal_array = 1/array1
print(reciprocal_array)

However, in Matlab the result of 1/(0+0j) is only inf but here in python the imaginary NAN makes a problem for me. I need these imaginary NAN (nanj) not to be there. Are there any solution not to have them?

I found a way to get rid of nanj in the reciprocal array after I generate it but I am asking if there is more feasible solutions.

where_are_nans = np.isnan(array1 )
array1[where_are_nans] = np.inf
1

There are 1 best solutions below

1
hpaulj On

Your sample array:

In [34]: array1
Out[34]: 
array([[6.+2.j, 6.+0.j],
       [0.+0.j, 4.+0.j]])

Make 2 arrays from this:

In [35]: out = np.full_like(array1, np.inf+0j)    
In [36]: out
Out[36]: 
array([[inf+0.j, inf+0.j],
       [inf+0.j, inf+0.j]])

In [37]: cond = array1!=0    
In [38]: cond
Out[38]: 
array([[ True,  True],
       [False,  True]])

Your divide can also be expressed with the divide ufunc:

In [39]: 1/array1
C:\Users\paul\AppData\Local\Temp\ipykernel_964\2387133254.py:1: RuntimeWarning: divide by zero encountered in true_divide
  1/array1
C:\Users\paul\AppData\Local\Temp\ipykernel_964\2387133254.py:1: RuntimeWarning: invalid value encountered in true_divide
  1/array1
Out[39]: 
array([[0.15      -0.05j, 0.16666667+0.j  ],
       [       inf +nanj, 0.25      +0.j  ]])

In [40]: np.divide(1,array1)
C:\Users\paul\AppData\Local\Temp\ipykernel_964\2318703765.py:1: RuntimeWarning: divide by zero encountered in true_divide
  np.divide(1,array1)
C:\Users\paul\AppData\Local\Temp\ipykernel_964\2318703765.py:1: RuntimeWarning: invalid value encountered in true_divide
  np.divide(1,array1)
Out[40]: 
array([[0.15      -0.05j, 0.16666667+0.j  ],
       [       inf +nanj, 0.25      +0.j  ]])

The ufunc takes a where parameter, telling it where to do the division. It also needs an out array, telling it what to use else where:

In [41]: np.divide(1,array1,where=cond, out=out)
Out[41]: 
array([[0.15      -0.05j, 0.16666667+0.j  ],
       [       inf+0.j  , 0.25      +0.j  ]])

This both gives the desired result, and avoids the warnings.