Home > Net >  Why does `np.sum([-np.Inf, np.Inf])` warn about "invalid value encountered in reduce"
Why does `np.sum([-np.Inf, np.Inf])` warn about "invalid value encountered in reduce"

Time:11-25

python -c "import numpy as np; print(np.sum([-np.Inf,  np.Inf]))" 

gives

numpy\core\fromnumeric.py:86: RuntimeWarning: invalid value encountered in reduce
  return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
nan

I wonder why that is:

  1. There is no warning in

    python -c "import numpy as np; print(np.sum([-np.Inf, -np.Inf]))" 
    

    nor in

    python -c "import numpy as np; print(np.sum([ np.Inf,  np.Inf]))" 
    

    so it can't be the Infs.

  2. There is no warning in

    python -c "import numpy as np; print(np.sum([np.nan, np.nan]))"   
    

    so it can't be the NaN result.

What is it, then, and how can I avoid it? I actually like getting NaN as a result, I just want to avoid the warning.

CodePudding user response:

The warning is fine, because Inf - Inf is mathematically undefined. What result would you expect?

If you want to avoid the warning, use a filter as follows:

import warnings

with warnings.catch_warnings():
    warnings.simplefilter("ignore", category=RuntimeWarning)
    res = np.sum([-np.Inf, np.Inf])

CodePudding user response:

It turns out the answer by @CarlosHorn is pretty close, although hidden deep inside the IEEE standard 754 (I checked the 2008 version).

Section 7.2 (Default exception handling > Invalid operation) writes

The invalid operation exception is signaled if and only if there is no usefully definable result.

I wouldn't know what a "usefully definable result" might be, considering that some people may not find Inf useful; I, by contrast, find even NaN pretty useful. Anyay, the section gives a comprehensive list of examples, which includes (in d) the "magnitude subtraction of infinities", explaining why and form of Inf - Inf should be considered invalid. It does also include (in a) "any [...] operation on a signaling NaN", but does not include operations on a quiet NaN. This important distinction explains why NaN NaN usually does not signal, as np.nan is quiet.

For completeness, section 6.1 explains why Inf Inf should not be considered invalid.

Two things left to says:

  • It is unclear (yet irrelevant) to me why np.inf - np.inf does not raise an exception.
  • with np.errstate(invalid="ignore"): ... is probably the cleanest way to suppress the warning.

More resources:

  • Related