Numerical issue with np.exp()

9.9k views Asked by At

I have the following code

x = -10
for i in range(2,10):
    print i, " | ",np.exp(-x**i)

with the following output:

2  |  3.72007597602e-44
3  |  inf
4  |  0.0
5  |  inf
6  |  0.0
7  |  inf
8  |  0.0
9  |  inf

Why is the results ~0 for i even and Inf for i odd?

3

There are 3 answers

1
hajtos On BEST ANSWER

Since x = -10, x**i will alternate between positive and negative high values, and so will -(x**i) which is what is calulated when you write -x**i .np.exp(inf) = inf and np.exp(-inf) = 0 so for high enough numbers, you're alternating between infinity and 0.

You probably wanted to write np.exp((-x)**i), which will make the power index always positive.

0
Spice On

The maximum value of a double-precision floating value (which numpy uses for floating-point arithmetic) is a little under 1.8e308 (1.8 * 10^308).

The value for 3 in your table would be e^1000, which WolframAlpha says is a little less than 2e434. The problem is that the numbers you want to use are just too large for numpy to handle, so for odd values, you get infinity.

The inverse is true for the even numbers; you're calculating a number so small that numpy must treat it as effectively zero.

0
willeM_ Van Onsem On

Short answer

Because xi with x < 0 is greater than zero if i is even and smaller than zero if i is odd. Since the exponential function generates very large or very small numbers with very large positive and very large negative input, the values are rounded off to infinity or zero, as is normal for IEEE-754 numbers.

For odd values

By default Python handles floating point numbers as IEEE-754 "double precision".

The limits of a double are between -1.7*10308 and 1.7*10308, everything above and below is considered to be -Inf and +Inf. Now if you calculate this for i=3, you get:

exp(-(-10**3))=exp(-(-1000))=exp(1000)

or approximately 1.9*10434, clearly above the threshold value. For every odd i, the result of -10**i is negative, thus the operand of exp is positive, and you will get values above the threshold.

For even values

For even values, this results in:

exp(-(-10**4))=exp(-10000)

which is again approximately 1.13*10-4343

The smallest positive value (greater than zero) a double can represent is 2-53. The obtained value is clearly lower, all positive values lower than this epsilon; are rounded off to zero, simply because it is the nearest representable value.