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

Question:

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

gives

numpycorefromnumeric.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.

Asked By: bers

||

Answers:

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])
Answered By: Carlos Horn

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:

Answered By: bers
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.