summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2018-10-29 14:49:47 -0500
committerGitHub <noreply@github.com>2018-10-29 14:49:47 -0500
commit96432eafbbdef03232d2f927d6c57c7285dda2f6 (patch)
tree04cf29c7d43b9c6ec9378c49fc994aec6be39557 /numpy
parent0dc45ecc707766c6983eae9b65e2bf518c487dc7 (diff)
parent46452b360d9f67d6af78801a3957688515c617fe (diff)
downloadnumpy-96432eafbbdef03232d2f927d6c57c7285dda2f6.tar.gz
Merge pull request #12236 from mattip/nan-warnings
BUG: maximum, minimum no longer emit warnings on NAN
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/umath/loops.c.src35
-rw-r--r--numpy/core/src/umath/simd.inc.src10
-rw-r--r--numpy/core/tests/test_half.py18
-rw-r--r--numpy/core/tests/test_regression.py5
-rw-r--r--numpy/core/tests/test_umath.py19
5 files changed, 34 insertions, 53 deletions
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src
index e62942efd..dd7feedc3 100644
--- a/numpy/core/src/umath/loops.c.src
+++ b/numpy/core/src/umath/loops.c.src
@@ -1833,10 +1833,7 @@ NPY_NO_EXPORT void
if (!run_unary_reduce_simd_@kind@_@TYPE@(args, dimensions, steps)) {
BINARY_REDUCE_LOOP(@type@) {
const @type@ in2 = *(@type@ *)ip2;
- io1 = (io1 @OP@ in2 || npy_isnan(io1)) ? io1 : in2;
- }
- if (npy_isnan(io1)) {
- npy_set_floatstatus_invalid();
+ io1 = (npy_isnan(io1) || io1 @OP@ in2) ? io1 : in2;
}
*((@type@ *)iop1) = io1;
}
@@ -1845,13 +1842,11 @@ NPY_NO_EXPORT void
BINARY_LOOP {
@type@ in1 = *(@type@ *)ip1;
const @type@ in2 = *(@type@ *)ip2;
- in1 = (in1 @OP@ in2 || npy_isnan(in1)) ? in1 : in2;
- if (npy_isnan(in1)) {
- npy_set_floatstatus_invalid();
- }
+ in1 = (npy_isnan(in1) || in1 @OP@ in2) ? in1 : in2;
*((@type@ *)op1) = in1;
}
}
+ npy_clear_floatstatus_barrier((char*)dimensions);
}
/**end repeat1**/
@@ -1866,7 +1861,7 @@ NPY_NO_EXPORT void
if (IS_BINARY_REDUCE) {
BINARY_REDUCE_LOOP(@type@) {
const @type@ in2 = *(@type@ *)ip2;
- io1 = (io1 @OP@ in2 || npy_isnan(in2)) ? io1 : in2;
+ io1 = (npy_isnan(in2) || io1 @OP@ in2) ? io1 : in2;
}
*((@type@ *)iop1) = io1;
}
@@ -1874,7 +1869,7 @@ NPY_NO_EXPORT void
BINARY_LOOP {
const @type@ in1 = *(@type@ *)ip1;
const @type@ in2 = *(@type@ *)ip2;
- *((@type@ *)op1) = (in1 @OP@ in2 || npy_isnan(in2)) ? in1 : in2;
+ *((@type@ *)op1) = (npy_isnan(in2) || in1 @OP@ in2) ? in1 : in2;
}
}
npy_clear_floatstatus_barrier((char*)dimensions);
@@ -2195,14 +2190,11 @@ HALF_@kind@(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED
{
/* */
BINARY_LOOP {
- npy_half in1 = *(npy_half *)ip1;
+ const npy_half in1 = *(npy_half *)ip1;
const npy_half in2 = *(npy_half *)ip2;
- in1 = (@OP@(in1, in2) || npy_half_isnan(in1)) ? in1 : in2;
- if (npy_half_isnan(in1)) {
- npy_set_floatstatus_invalid();
- }
- *((npy_half *)op1) = in1;
+ *((npy_half *)op1) = (@OP@(in1, in2) || npy_half_isnan(in1)) ? in1 : in2;
}
+ /* npy_half_isnan will never set floatstatus_invalid, so do not clear */
}
/**end repeat**/
@@ -2219,7 +2211,7 @@ HALF_@kind@(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED
const npy_half in2 = *(npy_half *)ip2;
*((npy_half *)op1) = (@OP@(in1, in2) || npy_half_isnan(in2)) ? in1 : in2;
}
- npy_clear_floatstatus_barrier((char*)dimensions);
+ /* npy_half_isnan will never set floatstatus_invalid, so do not clear */
}
/**end repeat**/
@@ -2761,16 +2753,14 @@ NPY_NO_EXPORT void
@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))) {
+ if ( !(npy_isnan(in1r) || npy_isnan(in1i) || @OP@(in1r, in1i, in2r, in2i))) {
in1r = in2r;
in1i = 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**/
@@ -2786,7 +2776,7 @@ NPY_NO_EXPORT void
const @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(in2r) || npy_isnan(in2i)) {
+ if (npy_isnan(in2r) || npy_isnan(in2i) || @OP@(in1r, in1i, in2r, in2i)) {
((@ftype@ *)op1)[0] = in1r;
((@ftype@ *)op1)[1] = in1i;
}
@@ -2795,6 +2785,7 @@ NPY_NO_EXPORT void
((@ftype@ *)op1)[1] = in2i;
}
}
+ npy_clear_floatstatus_barrier((char*)dimensions);
}
/**end repeat1**/
diff --git a/numpy/core/src/umath/simd.inc.src b/numpy/core/src/umath/simd.inc.src
index 47f9168e5..da0713b2b 100644
--- a/numpy/core/src/umath/simd.inc.src
+++ b/numpy/core/src/umath/simd.inc.src
@@ -1014,7 +1014,7 @@ sse2_@kind@_@TYPE@(@type@ * ip, @type@ * op, const npy_intp n)
{
const npy_intp stride = 16 / (npy_intp)sizeof(@type@);
LOOP_BLOCK_ALIGN_VAR(ip, @type@, 16) {
- *op = (*op @OP@ ip[i] || npy_isnan(*op)) ? *op : ip[i];
+ *op = (npy_isnan(*op) || *op @OP@ ip[i]) ? *op : ip[i];
}
assert(n < (stride) || npy_is_aligned(&ip[i], 16));
if (i + 3 * stride <= n) {
@@ -1038,15 +1038,13 @@ sse2_@kind@_@TYPE@(@type@ * ip, @type@ * op, const npy_intp n)
}
else {
@type@ tmp = sse2_horizontal_@VOP@_@vtype@(c1);
- *op = (*op @OP@ tmp || npy_isnan(*op)) ? *op : tmp;
+ *op = (npy_isnan(*op) || *op @OP@ tmp) ? *op : tmp;
}
}
LOOP_BLOCKED_END {
- *op = (*op @OP@ ip[i] || npy_isnan(*op)) ? *op : ip[i];
- }
- if (npy_isnan(*op)) {
- npy_set_floatstatus_invalid();
+ *op = (npy_isnan(*op) || *op @OP@ ip[i]) ? *op : ip[i];
}
+ npy_clear_floatstatus_barrier((char*)op);
}
/**end repeat1**/
diff --git a/numpy/core/tests/test_half.py b/numpy/core/tests/test_half.py
index d715569f8..2f2d069e5 100644
--- a/numpy/core/tests/test_half.py
+++ b/numpy/core/tests/test_half.py
@@ -301,21 +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])
- 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 = np.maximum(b, c)
+ assert_(np.isnan(x[3]))
x[3] = 0
assert_equal(x, [0, 5, 1, 0, 6])
+
assert_equal(np.minimum(a, b), [-2, 1, 1, 4, 2])
- 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 = np.minimum(b, c)
+ assert_(np.isnan(x[3]))
x[3] = 0
assert_equal(x, [-2, -1, -np.inf, 0, 3])
+
assert_equal(np.fmax(a, b), [0, 5, 2, 4, 3])
assert_equal(np.fmax(b, c), [0, 5, 1, 4, 6])
assert_equal(np.fmin(a, b), [-2, 1, 1, 4, 2])
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index d53f6da84..a929b0efd 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -1557,10 +1557,7 @@ class TestRegression(object):
def test_complex_nan_maximum(self):
cnan = complex(0, np.nan)
- with suppress_warnings() as sup:
- sup.record(RuntimeWarning)
- assert_equal(np.maximum(1, cnan), cnan)
- assert_equal(len(sup.log), 1)
+ assert_equal(np.maximum(1, cnan), cnan)
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 c15ce83f6..bd7985dfb 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -1327,21 +1327,18 @@ class TestMinMax(object):
assert_equal(d.max(), d[0])
assert_equal(d.min(), d[0])
- def test_reduce_warns(self):
+ def test_reduce_reorder(self):
# gh 10370, 11029 Some compilers reorder the call to npy_getfloatstatus
# and put it before the call to an intrisic function that causes
- # invalid status to be set. Also make sure warnings are emitted
+ # invalid status to be set. Also make sure warnings are not emitted
for n in (2, 4, 8, 16, 32):
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):
- # gh 11589
- assert_warns(RuntimeWarning, np.minimum, np.nan, 1)
+ for r in np.diagflat(np.array([np.nan] * n, dtype=dt)):
+ assert_equal(np.min(r), np.nan)
+
+ def test_minimize_no_warns(self):
+ a = np.minimum(np.nan, 1)
+ assert_equal(a, np.nan)
class TestAbsoluteNegative(object):