带有RuntimeWarning的numpy除法:在double_scalars中遇到无效的值 [英] numpy division with RuntimeWarning: invalid value encountered in double_scalars
问题描述
我写了以下脚本:
import numpy
d = numpy.array([[1089, 1093]])
e = numpy.array([[1000, 4443]])
answer = numpy.exp(-3 * d)
answer1 = numpy.exp(-3 * e)
res = answer.sum()/answer1.sum()
print res
但是我得到了这个结果,并且发生了错误:
But I got this result and with the error occurred:
nan
C:\Users\Desktop\test.py:16: RuntimeWarning: invalid value encountered in double_scalars
res = answer.sum()/answer1.sum()
输入元素似乎太小,以至于python将它们设为零,但是除法的确有其结果.
It seems to be that the input element were too small that python turned them to be zeros, but indeed the division has its result.
如何解决此类问题?
推荐答案
您无法解决.只需answer1.sum()==0
,就不能执行零除.
You can't solve it. Simply answer1.sum()==0
, and you can't perform a division by zero.
之所以会发生这种情况,是因为answer1
是2个非常大的负数的指数,因此结果四舍五入为零.
This happens because answer1
is the exponential of 2 very large, negative numbers, so that the result is rounded to zero.
nan
.
现在要解决您的问题,您可以:
Now to solve your problem you could:
- 使用高精度数学库,例如 mpmath .但这没那么有趣.
- 作为较大武器的替代方法,请进行一些数学操作,如下所述.
- 使用量身定制的
scipy/numpy
函数,该函数可以完全满足您的需求!查看@Warren Weckesser的答案.
- go for a library for high-precision mathematics, like mpmath. But that's less fun.
- as an alternative to a bigger weapon, do some math manipulation, as detailed below.
- go for a tailored
scipy/numpy
function that does exactly what you want! Check out @Warren Weckesser answer.
在这里,我解释了如何进行一些数学运算以帮助解决此问题.我们将其用于分子:
Here I explain how to do some math manipulation that helps on this problem. We have that for the numerator:
exp(-x)+exp(-y) = exp(log(exp(-x)+exp(-y)))
= exp(log(exp(-x)*[1+exp(-y+x)]))
= exp(log(exp(-x) + log(1+exp(-y+x)))
= exp(-x + log(1+exp(-y+x)))
x=3* 1089
和y=3* 1093
的上方.现在,这个指数的参数是
where above x=3* 1089
and y=3* 1093
. Now, the argument of this exponential is
-x + log(1+exp(-y+x)) = -x + 6.1441934777474324e-06
对于分母,您可以类似地进行操作,但获得的结果是log(1+exp(-z+k))
已四舍五入为0
,因此分母处的指数函数的参数仅四舍五入为-z=-3000
.然后,您得到的结果是
For the denominator you could proceed similarly but obtain that log(1+exp(-z+k))
is already rounded to 0
, so that the argument of the exponential function at the denominator is simply rounded to -z=-3000
. You then have that your result is
exp(-x + log(1+exp(-y+x)))/exp(-z) = exp(-x+z+log(1+exp(-y+x))
= exp(-266.99999385580668)
已经非常接近您仅保留两个前导项(即分子中的第一个数字1089
和分母中的第一个数字1000
)所得到的结果:>
which is already extremely close to the result that you would get if you were to keep only the 2 leading terms (i.e. the first number 1089
in the numerator and the first number 1000
at the denominator):
exp(3*(1089-1000))=exp(-267)
为此,让我们看看距Wolfram alpha解决方案有多远(
For the sake of it, let's see how close we are from the solution of Wolfram alpha (link):
Log[(exp[-3*1089]+exp[-3*1093])/([exp[-3*1000]+exp[-3*4443])] -> -266.999993855806522267194565420933791813296828742310997510523
该数字与上面的指数之差为+1.7053025658242404e-13
,因此我们在分母处的近似值很好.
The difference between this number and the exponent above is +1.7053025658242404e-13
, so the approximation we made at the denominator was fine.
最终结果是
'exp(-266.99999385580668) = 1.1050349147204485e-116
From wolfram alpha is (link)
1.105034914720621496.. × 10^-116 # Wolfram alpha.
同样,在这里也可以使用numpy.
and again, it is safe to use numpy here too.
这篇关于带有RuntimeWarning的numpy除法:在double_scalars中遇到无效的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!