[Numpy-discussion] numarray and NaN ?
Perry Greenfield
perry at stsci.edu
Tue Sep 23 14:27:10 CDT 2003
Chris Barker writes:
>
> There was a lot of discussion a long while back about how Numeric treats
> erros in the middle of an array operation. The way it works is if one
> operation in an array has a problem (overflow, division by zero, etc),
> an exception is returned. You have no idea which element caused the
> problem, and teh whole operation grinds to a halt. Personally, I would
> MUCH prefer MATLAB's way of handling this: the problematic operation
> results in a -Inf, Inf, or NaN result for that element, and the rest of
> the array operation can continue. MATLAB also provides utility functions
> along the line of isnan, isinf, etc, so you can check for the
> problematic areas later.
>
> There was a fair bit of disagreement over whether Numeric should act
> similarly, as well as the problem that not all compilers have the
> required IEEE support to make this work.
>
I don't recall if there was disagreement about this being useful, but
perhaps there was disagreement that it should always do this.
> Anyway, how does numarray handle this issue? I'd love to have the MATLAB
> behaviour...I'm writing this because I'm about to have to write a bunch
> of code to keep making sure I don't pass a 0 into log(), when I'd be
> much happier if I could just replace the NaNs with what I want later.
>
numarray allows one to customize how errors are handled. You can
choose:
1) to silently ignore all errors.
2) print a warning message (default)
3) raise an exception.
One may separately set one of these three behaviors for each of
the 4 ieee categories of floating point errors, namely
1) invalid results (i.e., NaNs)
2) divide by zeros (Infs)
3) overflows
4) underflows
for the first two modes the computation on floats just inserts the
appropriate
ieee value in the array (Infs and NaNs). There are portable constants and
functions to test and set these values (see examples below).
These modes also apply to integer calculations.
I've pasted some examples I presented from some slides shown at the scipy
conference to illustrate how it works and what's available.
Customize how errors are handled
>>> numeric.Error.setMode(all="warn")
>>> numeric.Error.pushMode(dividebyzero="warn",
.. Invalid="raise",overflow="warn",underflow="ignore")
>>> numeric.Error.popMode()
>>> a = 1/arange(10.)
Warning: Encountered divide by zero(s) in divide
Manipulate IEEE-754 special values
>>> import numarray.ieeespecial as ieee
>>> ieee.getinf(a) # return indices of Infs
(array([0],)
>>> a = arange(10.)/arange(10.)
>>> ieee.setnan(a, 999) # set all NaNs to 999
>>> a
array([999.,1.,1.,1.,1.,1.,1.,1.,1.,1.])
>>> a[ieee.getinf(a)] = 999 # equivalent
Use defined constants
>>> a[5] = ieee.nan
>>> a[6] = ieee.plus_inf
>>> a[7] = ieee.minus_inf
>>> a[8] = ieee.inf
>>> a
array([999.,1.,1.,1.,1.,nan,inf,-inf,inf,1.]
Perry
More information about the Numpy-discussion
mailing list