I am encountering the runtime overflow error in exp because it crosses the limit for 64 bits and I can't use np.float128() as I'm using a 64-bit windows computer.
I can clip and use it, but how do I clip for a complex number and still get an imaginary and complex parts.
Current code:
import numpy as np
x = 738.368295193386-738.368295193386j
x = np.clip(x, -709.78, 709.78)
print(np.exp(x))
Output is like this:
(1.7928227943945157e 308 0j)
But also want the imaginary term to have a value.
For example:
np.exp(708.368295193386 708.368295193386j)
is (-2.657182604727012e 306-4.3615140206566584e 307j)
How could I get a similar result with a value and the sign ( -) maintained?
CodePudding user response:
While the strategy of clamping the value works for real numbers, it is flawed for complex numbers. Indeed, the complex exponential perform a kind of rotation in the complex space (see similarity) that cause the sign of the real/imaginary part to change with only a small change. Fortunately, you can use a modulus to reduce the imaginary part and a clamp to saturate the real part. This strategy is significantly more numerically stable. You can also extract the real/imaginary part with np.real
and np.imag
. Here is an example:
x = np.fmod(np.imag(x), 2*np.pi)*1j np.clip(np.real(x), -709.78, 709.78)
The imaginary part will lies in the range ]-2π;2π[
. It must not be clamped since it would strongly impact the result of the exponential (including the sign).
If this is not enough, you can compute the exponential of the real part and then rotate the result in the complex space yourself using np.cos
and np.sin
.