Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy division with RuntimeWarning: invalid value encountered in double_scalars

I wrote the following script:

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

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.

How to solve this kind of problem?

like image 845
Heinz Avatar asked Jan 05 '15 17:01

Heinz


People also ask

What is Runtimewarning invalid value encountered in double_scalars?

Why Is the Runtimewarning: Invalid Value Encountered in double_scalars Error Happening? The runtimewarning: invalid value encountered in double_scalars error happens when web developers try to perform certain mathematical operations that include numbers at the opposite end of the spectrum.

What is a double scalar in Python?

A double scalar is a value of type double . It is called scalar to differentiate it in numpy from double arrays.

What is an invalid value in double_scalars?

The RuntimeWarning: invalid value encountered in double_scalars mainly occurs when you perform a complex mathematical operation that results in extremely large or small numbers and also if we pass an invalid input such as NaN or null while performing NumPy operations.

What is runtimewarning error in NumPy?

The error which we basically encounter when we use the Numpy library is Runtimewarning: invalid value encountered in doubled_scalars. We face this error basically when we do mathematical operations on a list of very large numbers or vary the small number and when we supply any invalid input to NumPy operation like NaN or null as input.

What is runtimewarning error in double_scalars?

RuntimeWarning: invalid value encountered in double_scalars We receive a RuntimeWarning because the denominator is a complex number and extremely small that is closer to zero. Hence when we perform the division with an extremely small denominator, we will get a large complex number as an output that Python cannot handle and raises a RuntimeWarning

What is double scalar in NumPy?

A double scalar is a value of type double. It is called scalar to differentiate it in numpy from double arrays. – Muhammad Alkarouri Sep 22 '10 at 9:21 Say thanks for this answer. 0 others reacted with thanks. Show activity on this post. It looks like a floating-point calculation error.


1 Answers

You can't solve it. Simply answer1.sum()==0, and you can't perform a division by zero.

This happens because answer1 is the exponential of 2 very large, negative numbers, so that the result is rounded to zero.

nan is returned in this case because of the division by zero.

Now to solve your problem you could:

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

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

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) 

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) 

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 

The difference between this number and the exponent above is +1.7053025658242404e-13, so the approximation we made at the denominator was fine.

The final result is

'exp(-266.99999385580668) = 1.1050349147204485e-116 

From wolfram alpha is (link)

1.105034914720621496.. × 10^-116 # Wolfram alpha. 

and again, it is safe to use numpy here too.

like image 159
gg349 Avatar answered Sep 28 '22 06:09

gg349