summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorRaghuveer Devulapalli <raghuveer.devulapalli@intel.com>2019-05-01 08:43:21 -0700
committerRaghuveer Devulapalli <raghuveer.devulapalli@intel.com>2019-08-03 10:48:43 -0700
commite50e72513212764f673027328b9f33574cc3d254 (patch)
treee9bc1197e7e74980a36d433ec42745d5219b6d58 /numpy
parentbd2c82bf141852b4737da297c081e5f621604317 (diff)
downloadnumpy-e50e72513212764f673027328b9f33574cc3d254.tar.gz
BUG: fixing NAN handling and adding tests for sin/cos
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/umath/simd.inc.src10
-rw-r--r--numpy/core/tests/test_umath.py17
2 files changed, 23 insertions, 4 deletions
diff --git a/numpy/core/src/umath/simd.inc.src b/numpy/core/src/umath/simd.inc.src
index 58ec48447..7bd5aa2b5 100644
--- a/numpy/core/src/umath/simd.inc.src
+++ b/numpy/core/src/umath/simd.inc.src
@@ -1473,7 +1473,7 @@ static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
#if defined HAVE_ATTRIBUTE_TARGET_@ISA@_WITH_INTRINSICS
static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
-@ISA@_sincos_FLOAT(npy_float * op, npy_float * ip, const npy_int array_size,
+@ISA@_sincos_FLOAT(npy_float * op, npy_float * ip, const npy_intp array_size,
char* operation)
{
const npy_int num_lanes = @BYTES@/sizeof(npy_float);
@@ -1505,9 +1505,9 @@ static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
@vtype@ zero_f = _mm@vsize@_set1_ps(0.0f);
@vtype@ quadrant, reduced_x, reduced_x2, cos, sin;
@vtype@i iquadrant;
- @mask@ glibc_mask, sine_mask, negate_mask;
+ @mask@ nan_mask, glibc_mask, sine_mask, negate_mask;
@mask@ load_mask = @isa@_get_full_load_mask();
- npy_int num_remaining_elements = array_size;
+ npy_intp num_remaining_elements = array_size;
while (num_remaining_elements > 0) {
@@ -1524,7 +1524,8 @@ static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
glibc_mask = @isa@_in_range_mask(x, large_number,-large_number);
glibc_mask = @and_masks@(load_mask, glibc_mask);
- x = @isa@_set_masked_lanes(x, zero_f, glibc_mask);
+ nan_mask = _mm@vsize@_cmp_ps@vsub@(x, x, _CMP_NEQ_UQ);
+ x = @isa@_set_masked_lanes(x, zero_f, @or_masks@(nan_mask, glibc_mask));
npy_int iglibc_mask = @mask_to_int@(glibc_mask);
if (iglibc_mask != @full_mask@) {
@@ -1556,6 +1557,7 @@ static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
/* multiply by -1 for appropriate elements */
negate_mask = @isa@_should_negate(iquadrant, twos, twos);
cos = @isa@_blend(cos, _mm@vsize@_sub_ps(zero_f, cos), negate_mask);
+ cos = @isa@_set_masked_lanes(cos, _mm@vsize@_set1_ps(NPY_NANF), nan_mask);
@masked_store@(op, @cvtps_epi32@(load_mask), cos);
}
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 91d403d98..0948cbfe6 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -678,6 +678,23 @@ class TestSpecialFloats(object):
assert_raises(FloatingPointError, np.log, np.float32(-np.inf))
assert_raises(FloatingPointError, np.log, np.float32(-1.0))
+ def test_sincos_values(self):
+ with np.errstate(all='ignore'):
+ x = [np.nan, np.nan, np.nan, np.nan]
+ y = [np.nan, -np.nan, np.inf, -np.inf]
+ for dt in ['f', 'd', 'g']:
+ xf = np.array(x, dtype=dt)
+ yf = np.array(y, dtype=dt)
+ assert_equal(np.sin(yf), xf)
+ assert_equal(np.cos(yf), xf)
+
+ with np.errstate(invalid='raise'):
+ assert_raises(FloatingPointError, np.sin, np.float32(-np.inf))
+ assert_raises(FloatingPointError, np.sin, np.float32(np.inf))
+ assert_raises(FloatingPointError, np.cos, np.float32(-np.inf))
+ assert_raises(FloatingPointError, np.cos, np.float32(np.inf))
+
+
class TestExpLogFloat32(object):
def test_exp_float32(self):
np.random.seed(42)