为什么float64产生一个RuntimeWarning,其中float产生一个nan?

时间:2015-09-07 01:17:43

标签: python numpy runtime-error warnings infinity

我正在使用warnings模块将警告提升为错误。

当我调用我的函数plot_fig_4时,我收到以下错误:

In [5]: plot_amit.plot_fig_4()
g: 1 of 3
theta_E: 1 of 1000
---------------------------------------------------------------------------
RuntimeWarning                            Traceback (most recent call last)
<ipython-input-5-5a631d2493d7> in <module>()
----> 1 plot_amit.plot_fig_4()

/home/dan/Science/dopa_net/plot_amit.pyc in plot_fig_4()
    130                                                                     tau_0, tau,
    131                                                                     theta_E_,
--> 132                                                                     H)
    133 
    134             # Iterate through theta_I, starting at the lowest value.

/home/dan/Science/dopa_net/plot_support.py in _get_d_phi(mu, sigma, tau_0, tau_i, theta_i, H)
   2059     for (i, mu_), (j, sigma_) in itertools.product(enumerate(mu),
   2060                                                    enumerate(sigma)):
-> 2061         phi[i, j] = _get_phi(tau_0, tau_i, theta_i, mu_, sigma_, H)
   2062     import pdb
   2063     pdb.set_trace()

/home/dan/Science/dopa_net/plot_support.py in _get_phi(tau_0, tau, theta_over_J, mu_over_J, sigma_over_J, H)
   1835 
   1836     # Compute the integral.
-> 1837     integral = _integrate_little_phi(lower, alpha)
   1838 
   1839     # Compute phi.

/home/dan/Science/dopa_net/plot_support.py in _integrate_little_phi(lower, upper)
   1869     upper_int = _integrate(upper)
   1870     lower_int = _integrate(lower)
-> 1871     return upper_int - lower_int
   1872 
   1873 

RuntimeWarning: invalid value encountered in double_scalars

行。所以我在pdb.set_trace内部,在引发错误的行之前,重新运行,并检查相关变量的值:

_integrate_little_phi

咦。因此我提出错误是因为我从无穷大中减去了无穷大。我可以复制一下吗?

In [7]: plot_amit.plot_fig_4()
g: 1 of 3
theta_E: 1 of 1000
> /home/dan/Science/dopa_net/plot_support.py(1873)_integrate_little_phi()
-> return upper_int - lower_int
(Pdb) upper_int
inf
(Pdb) lower_int
inf
(Pdb) type(upper_int)
<type 'numpy.float64'>
(Pdb) type(lower_int)
<type 'numpy.float64'>

是。但是等一下。让我们再尝试一下:

(Pdb) upper_int - lower_int
*** RuntimeWarning: invalid value encountered in double_scalars
什么是什么?当我使用(Pdb) np.inf inf (Pdb) type(np.inf) <type 'float'> (Pdb) np.inf - np.inf nan np.infnp)直接从无穷远中减去无穷大时,我得到numpy,而不是nan

为什么我在这个实例中获得RuntimeWarning而在另一个实例中获得nan我故意在类型(RuntimeWarningfloat)中发布了差异。问题是,为什么这些(平凡的)不同类型产生不同的结果?

2 个答案:

答案 0 :(得分:1)

因为在np.inf的情况下,类型是float(基本数据类型),而在upper_int / lower_int的情况下,数据类型是{{1 }。类似的问题可以通过 -

重现
numpy.float64

对于In [7]: a = np.float64('inf') In [8]: type(a) Out[8]: numpy.float64 In [9]: a - a RuntimeWarning: invalid value encountered in double_scalars if __name__ == '__main__': Out[9]: nan / np.inf -

的情况
float

我认为这可能是因为在正常In [3]: float('inf') - float('inf') Out[3]: nan In [11]: np.inf Out[11]: inf In [12]: type(np.inf) Out[12]: float 的情况下,你无法从计算中得到它。示例 -

inf

相反,你总是会遇到溢出错误。

当使用>>> 123123123123. ** 2 1.5159303447561418e+22 >>> _ ** 2 2.298044810152475e+44 >>> _ ** 2 5.281009949468725e+88 >>> _ ** 2 2.788906608638767e+177 >>> _ ** 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> OverflowError: (34, 'Result too large') 时,您可以从计算中获得无穷大值(尽管即使它会发出警告) -

np.float64

因此,由于您可以通过计算得到In [63]: n = np.float64('123123123123123123123') In [64]: n Out[64]: 1.2312312312312313e+20 In [65]: n = n ** 2 In [66]: n = n ** 2 In [67]: n = n ** 2 In [68]: n = n ** 2 C:\Anaconda3\Scripts\ipython-script.py:1: RuntimeWarning: overflow encountered in double_scalars if __name__ == '__main__': In [69]: n Out[69]: inf 无穷大,当您尝试对其进行更多计算时可能会尝试将数字从无穷大减少到更小的值,这是更多的警告,即减去/除以无穷大(无穷大的乘法或加法很好,因为向无穷大添加无穷大只会给出无穷大)。示例 -

np.float64

虽然在你的情况下,我相信你可能从源头获得了直接的无限价值。

答案 1 :(得分:0)

似乎没有任何理由减去两个__atomic_exchange_n s应该发出警告,其中减去两个float64 s。

因此,这似乎是float中的错误。

我的建议(对我自己)是在减法时将numpy转换为float64:即,

float

变为

return upper_int - lower_int

这可以防止警告。

(当然,可能会出现需要对此减法发出警告的情况 - 对于这些情况,我会给出相反的建议 - 即保持原样。从某种意义上说,有这个很好切换警告。)