Why does float64 create RuntimeWarning, where does the float produce nan?

I use the warnings module to raise warnings as errors.

When I call my plot_fig_4 function, I get the following error:

 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 

OK Therefore, I stick to pdb.set_trace inside _integrate_little_phi , before the line in which the error occurs, it starts again and checks the values โ€‹โ€‹of the corresponding variables:

 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'> 

Yes. So the error was raised because I subtracted infinity from infinity. Can i reproduce this?

 (Pdb) upper_int - lower_int *** RuntimeWarning: invalid value encountered in double_scalars 

Yes. But wait a minute. Let's try one more thing:

 (Pdb) np.inf inf (Pdb) type(np.inf) <type 'float'> (Pdb) np.inf - np.inf nan 

What? When I directly subtract infinity from infinity using np.inf (where np is numpy ), I get nan , not RuntimeWarning .

Why am I getting nan in this instance and RuntimeWarning in another? I intentionally posted the difference in type ( float vs float64 ). The question is why these (trivially) different types produce different results?

0
source share
2 answers

Because in the case of np.inf type is float (base data type), whereas in the case of upper_int / lower_int the data type is numpy.float64 . A similar question can be reproduced with

 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 

In the case of 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 

I think this may be because in the case of normal inf you cannot get it from the calculation. Example -

 >>> 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') 

Instead, you always get an overflow error.

While using np.float64 you can get the infinity value from the calculation (although even at that time it would give a warning) -

 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 

Therefore, since you can get infinity through np.float64 by calculation, they throw more warnings when you try to do more calculations on it, which may try to reduce the number from infinity to a much smaller value, i.e. subtract / divide by infinity (multiplication or adding infinity is beautiful, because adding infinity to infinity will only return infinity). Example -

 In [71]: n - n C:\Anaconda3\Scripts\ipython-script.py:1: RuntimeWarning: invalid value encountered in double_scalars if __name__ == '__main__': Out[71]: nan In [72]: n/n C:\Anaconda3\Scripts\ipython-script.py:1: RuntimeWarning: invalid value encountered in double_scalars if __name__ == '__main__': Out[72]: nan In [73]: n*n Out[73]: inf 

Although in your case, I believe you may have received a direct infinite value from the source.

+1
source

There seems to be no reason that subtracting two float64 should cause a warning when subtracting from two float fails.

Therefore, it looks like a bug in numpy .

My recommendation (for me) is to convert float64 to float during subtraction: ie,

 return upper_int - lower_int 

becomes

 return float(upper_int) - float(lower_int). 

This prevents a warning.

(Of course, there may be situations where a warning is required for this subtraction โ€” for this I would give the opposite recommendation โ€” that is, to keep things as they are. In a sense, it's nice to have this switch for a warning.)

0
source

All Articles