diff options
-rw-r--r-- | doc/release/1.16.0-notes.rst | 11 | ||||
-rw-r--r-- | numpy/core/src/umath/loops.c.src | 26 | ||||
-rw-r--r-- | numpy/core/tests/test_half.py | 16 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 5 | ||||
-rw-r--r-- | numpy/core/tests/test_umath.py | 9 |
5 files changed, 44 insertions, 23 deletions
diff --git a/doc/release/1.16.0-notes.rst b/doc/release/1.16.0-notes.rst index 2c67d1853..378b96b3b 100644 --- a/doc/release/1.16.0-notes.rst +++ b/doc/release/1.16.0-notes.rst @@ -100,7 +100,6 @@ Changes Comparison ufuncs will now error rather than return NotImplemented ------------------------------------------------------------------ - Previously, comparison ufuncs such as ``np.equal`` would return `NotImplemented` if their arguments had structured dtypes, to help comparison operators such as ``__eq__`` deal with those. This is no longer needed, as the @@ -115,12 +114,20 @@ raise a ``DeprecationWarning`` if the array is not numerical (i.e., if ``np.positive(array)`` raises a ``TypeError``. For ``ndarray`` subclasses that override the default ``__array_ufunc__`` implementation, the ``TypeError`` is passed on. -Umath and multiarray c-extension modules merged into a single module + +``maximum`` and ``minimum`` set invalid float status for more dtypes -------------------------------------------------------------------- +Previously only ``float32`` and ``float64`` set invalid float status (by +default emitting a `RuntimeWarning`) when a Nan is encountered in +`numpy.maximum` and `numpy.minimum`. Now ``float16``, ``complex64``, +``complex128`` and ``complex256`` will do so as well. +Umath and multiarray c-extension modules merged into a single module +-------------------------------------------------------------------- The two modules were merged, according to the first step in `NEP 15`_. Previously `np.core.umath` and `np.core.multiarray` were the c-extension modules, they are now python wrappers to the single `np.core/_multiarray_math` c-extension module. .. _`NEP 15` : http://www.numpy.org/neps/nep-0015-merge-multiarray-umath.html + diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index e3e011190..66b69f555 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -2224,9 +2224,13 @@ HALF_@kind@(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED { /* */ BINARY_LOOP { - const npy_half in1 = *(npy_half *)ip1; + npy_half in1 = *(npy_half *)ip1; const npy_half in2 = *(npy_half *)ip2; - *((npy_half *)op1) = (@OP@(in1, in2) || npy_half_isnan(in1)) ? in1 : in2; + in1 = (@OP@(in1, in2) || npy_half_isnan(in1)) ? in1 : in2; + if (npy_half_isnan(in1)) { + npy_set_floatstatus_invalid(); + } + *((npy_half *)op1) = in1; } } /**end repeat**/ @@ -2782,20 +2786,20 @@ NPY_NO_EXPORT void @TYPE@_@kind@(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func)) { BINARY_LOOP { - const @ftype@ in1r = ((@ftype@ *)ip1)[0]; - const @ftype@ in1i = ((@ftype@ *)ip1)[1]; + @ftype@ in1r = ((@ftype@ *)ip1)[0]; + @ftype@ in1i = ((@ftype@ *)ip1)[1]; const @ftype@ in2r = ((@ftype@ *)ip2)[0]; const @ftype@ in2i = ((@ftype@ *)ip2)[1]; - if (@OP@(in1r, in1i, in2r, in2i) || npy_isnan(in1r) || npy_isnan(in1i)) { - ((@ftype@ *)op1)[0] = in1r; - ((@ftype@ *)op1)[1] = in1i; + if ( !(@OP@(in1r, in1i, in2r, in2i) || npy_isnan(in1r) || npy_isnan(in1i))) { + in1r = in2r; + in1i = in2i; } - else { - ((@ftype@ *)op1)[0] = in2r; - ((@ftype@ *)op1)[1] = in2i; + if (npy_isnan(in1r) || npy_isnan(in1i)) { + npy_set_floatstatus_invalid(); } + ((@ftype@ *)op1)[0] = in1r; + ((@ftype@ *)op1)[1] = in1i; } - npy_clear_floatstatus_barrier((char*)dimensions); } /**end repeat1**/ diff --git a/numpy/core/tests/test_half.py b/numpy/core/tests/test_half.py index b02f6cae2..d715569f8 100644 --- a/numpy/core/tests/test_half.py +++ b/numpy/core/tests/test_half.py @@ -5,7 +5,7 @@ import pytest import numpy as np from numpy import uint16, float16, float32, float64 -from numpy.testing import assert_, assert_equal +from numpy.testing import assert_, assert_equal, suppress_warnings def assert_raises_fpe(strmatch, callable, *args, **kwargs): @@ -301,13 +301,19 @@ class TestHalf(object): assert_equal(np.copysign(b, a), [2, 5, 1, 4, 3]) assert_equal(np.maximum(a, b), [0, 5, 2, 4, 3]) - x = np.maximum(b, c) - assert_(np.isnan(x[3])) + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + x = np.maximum(b, c) + assert_(np.isnan(x[3])) + assert_equal(len(sup.log), 1) x[3] = 0 assert_equal(x, [0, 5, 1, 0, 6]) assert_equal(np.minimum(a, b), [-2, 1, 1, 4, 2]) - x = np.minimum(b, c) - assert_(np.isnan(x[3])) + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + x = np.minimum(b, c) + assert_(np.isnan(x[3])) + assert_equal(len(sup.log), 1) x[3] = 0 assert_equal(x, [-2, -1, -np.inf, 0, 3]) assert_equal(np.fmax(a, b), [0, 5, 2, 4, 3]) diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 8244dfe20..c38625dac 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -1557,7 +1557,10 @@ class TestRegression(object): def test_complex_nan_maximum(self): cnan = complex(0, np.nan) - assert_equal(np.maximum(1, cnan), cnan) + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_equal(np.maximum(1, cnan), cnan) + assert_equal(len(sup.log), 1) def test_subclass_int_tuple_assignment(self): # ticket #1563 diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index d4bdb3d4e..c15ce83f6 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -1332,10 +1332,11 @@ class TestMinMax(object): # and put it before the call to an intrisic function that causes # invalid status to be set. Also make sure warnings are emitted for n in (2, 4, 8, 16, 32): - with suppress_warnings() as sup: - sup.record(RuntimeWarning) - for r in np.diagflat([np.nan] * n): - assert_equal(np.min(r), np.nan) + for dt in (np.float32, np.float16, np.complex64): + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + for r in np.diagflat(np.array([np.nan] * n, dtype=dt)): + assert_equal(np.min(r), np.nan) assert_equal(len(sup.log), n) def test_minimize_warns(self): |