Overflow Error in Python's numpy.exp function
As fuglede says, the issue here is that np.float64
can't handle a number as large as exp(1234.1)
. Try using np.float128
instead:
>>> cc = np.array([[0.120,0.34,-1234.1]], dtype=np.float128)
>>> cc
array([[ 0.12, 0.34, -1234.1]], dtype=float128)
>>> 1 / (1 + np.exp(-cc))
array([[ 0.52996405, 0.58419052, 1.0893812e-536]], dtype=float128)
Note however, that there are certain quirks with using extended precision. It may not work on Windows; you don't actually get the full 128 bits of precision; and you might lose the precision whenever the number passes through pure python. You can read more about the details here.
For most practical purposes, you can probably approximate 1 / (1 + <a large number>)
to zero. That is to say, just ignore the warning and move on. Numpy takes care of the approximation for you (when using np.float64
):
>>> 1 / (1 + np.exp(-cc))
/usr/local/bin/ipython3:1: RuntimeWarning: overflow encountered in exp
#!/usr/local/bin/python3.4
array([[ 0.52996405, 0.58419052, 0. ]])
If you want to suppress the warning, you could use scipy.special.expit
, as suggested by WarrenWeckesser in a comment to the question:
>>> from scipy.special import expit
>>> expit(cc)
array([[ 0.52996405, 0.58419052, 0. ]])
Deal with overflow in exp using numpy
You can use the bigfloat package. It supports arbitrary precision floating point operations.
http://packages.python.org/bigfloat/
import bigfloat
bigfloat.exp(5000,bigfloat.precision(100))
# -> BigFloat.exact('2.9676283840236670689662968052896e+2171', precision=100)
Are you using a function optimization framework? They usually implement value boundaries (using penalty terms). Try that. Are the relevant values really that extreme? In optimization it's not uncommon to minimize log(f). (approximate log likelihood etc etc). Are you sure you want to optimize on that exp value and not log(exp(f)) == f. ?
Have a look at my answer to this question: logit and inverse logit functions for extreme values
Btw, if all you do is minimize powellBadlyScaled(x,y) then the minimum is at x -> + inf and y -> + inf, so no need for numerics.
Overflow in exp in scipy/numpy in Python?
In your case, it means that b
is very small somewhere in your array, and you're getting a number (a/b
or exp(log(a) - log(b))
) that is too large for whatever dtype (float32, float64, etc) the array you're using to store the output is.
Numpy can be configured to
- Ignore these sorts of errors,
- Print the error, but not raise a warning to stop the execution (the default)
- Log the error,
- Raise a warning
- Raise an error
- Call a user-defined function
See numpy.seterr
to control how it handles having under/overflows, etc in floating point arrays.
How to avoid an overflow in numpy.exp()
SciPy comes with a function to do that, which won't give you that warning:
scipy.special.expit(x)
numpy exp overflow with negative input in numpy where
np.exp(1493)
is e^1493
, right? We can rebase that to be equal to 10^648
.
When we ask numpy what the maximum value of a float64 is, it's 2e308
, which is wildly less than 1e648
.
>>> np.finfo(float)
finfo(resolution=1e-15, min=-1.7976931348623157e+308, max=1.7976931348623157e+308, dtype=float64)
The where clause doesn't evaluate till after you calculate the np.exp(Z) - 1
array.
You could fix this with np.exp(Z, where=Z<0) - 1
.
In response to your comment:
>>> import numpy as np
>>> Z = np.array([[1e11,-1e11]])
>>> np.where(Z>=0, Z, 1*(np.exp(Z)-1) )
__main__:1: RuntimeWarning: overflow encountered in exp
array([[ 1.e+11, -1.e+00]])
>>>
Clearly it does raise the same warning.
Numpy: How do I get inside an "overflow encountered in exp"?
I'm guessing the problem is that you cannot figure out when warning happens. To do that use try
/except
but in slightly modified way:
import warnings
warnings.filterwarnings("error")
...
try:
1/(np.exp((j-w)/x)-1)
except RuntimeWarning:
print(j)
print(w)
print(x)
print((j-w)/x)
This should give a hint, there the problem lies
How to deal with exponent overflow of 64float precision in python?
You can use the function np.logaddexp()
to do such operations. It computes logaddexp(x1, x2) == log(exp(x1) + exp(x2))
without explicitly computing the intermediate exp()
values. This avoids the overflow. Since exp(0.0) == 1
, you would compute np.logaddexp(0.0, 1000.0)
and get the result of 1000.0
, as expected.
How to fix "overflow encounter in exp" when curve fitting data in Scipy?
The problem is the small value for a
. The minimization process tries to compensate via b
resulting in an overflow. I get good results with starting values p0=( 3.2e6, -4000 )
Alternatively, you can define the function to be exp( a - b / t )
which the coverges well with p0=( 15, -4000 )
or even without providing a p0
Related Topics
How to Allocate Array With Shape and Data Type
How to Remove the Decimal Point in a Pandas Dataframe
How to Normalize a Numpy Array to Within a Certain Range
How to Get One Key and Value from a Json in Python
How to Determine Whether a Pandas Column Contains a Particular Value
How to Remove Name and Dtype from Pandas Output
How to Find the Average Colour of an Image in Python With Opencv
How to Align Labels and Entry Boxes in a Gui Program
Csv File Written With Python Has Blank Lines Between Each Row
Python Pandas - Get Row Based on Previous Row Value
How to Remove Strings Present in a List from a Column in Pandas
How to Continue a Loop After Catching Exception in Try ... Except
How to Select All Elements Greater Than a Given Values in a Dataframe
Efficient Way of Having a Function Only Execute Once in a Loop
How to Get the Sum of a CSV Column List to Print
How to Fill Empty Cell Value in Pandas With Condition
Numpy Array Typeerror: Only Integer Scalar Arrays Can Be Converted to a Scalar Index