summaryrefslogtreecommitdiff
path: root/numpy/lib/tests/test_function_base.py
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2019-02-16 19:11:38 -0800
committerEric Wieser <wieser.eric@gmail.com>2019-02-24 15:47:48 -0800
commit0139a2d118ddfcff5a0139a016be826dbc44854f (patch)
tree12134c51fe8258c58b2a91b37659a7d3cb60391c /numpy/lib/tests/test_function_base.py
parent02ae0e3aa5f8f894f5e0496e609e3efe0f49eacd (diff)
downloadnumpy-0139a2d118ddfcff5a0139a016be826dbc44854f.tar.gz
ENH: Improve handling of infinities in np.interp
Alternative to gh-12978, using a method that does not need a lot of special cases. This is likely more robust in the face of overflow Fixes gh-12951.
Diffstat (limited to 'numpy/lib/tests/test_function_base.py')
-rw-r--r--numpy/lib/tests/test_function_base.py71
1 files changed, 70 insertions, 1 deletions
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index d9a97db1b..1e04bfaec 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -33,6 +33,17 @@ def get_mat(n):
return data
+def _make_complex(real, imag):
+ """
+ Like real + 1j * imag, but behaves as expected when imag contains non-finite
+ values
+ """
+ ret = np.zeros(np.broadcast(real, imag).shape, np.complex_)
+ ret.real = real
+ ret.imag = imag
+ return ret
+
+
class TestRot90(object):
def test_basic(self):
assert_raises(ValueError, rot90, np.ones(4))
@@ -2354,7 +2365,7 @@ class TestInterp(object):
x0 = np.nan
assert_almost_equal(np.interp(x0, x, y), x0)
- def test_non_finite_behavior(self):
+ def test_non_finite_behavior_exact_x(self):
x = [1, 2, 2.5, 3, 4]
xp = [1, 2, 3, 4]
fp = [1, 2, np.inf, 4]
@@ -2362,6 +2373,64 @@ class TestInterp(object):
fp = [1, 2, np.nan, 4]
assert_almost_equal(np.interp(x, xp, fp), [1, 2, np.nan, np.nan, 4])
+ @pytest.fixture(params=[
+ lambda x: np.float_(x),
+ lambda x: _make_complex(x, 0),
+ lambda x: _make_complex(0, x),
+ lambda x: _make_complex(x, np.multiply(x, -2))
+ ], ids=[
+ 'real',
+ 'complex-real',
+ 'complex-imag',
+ 'complex-both'
+ ])
+ def sc(self, request):
+ """ scale function used by the below tests """
+ return request.param
+
+ def test_non_finite_any_nan(self, sc):
+ """ test that nans are propagated """
+ assert_equal(np.interp(0.5, [np.nan, 1], sc([ 0, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, np.nan], sc([ 0, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, 1], sc([np.nan, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, 1], sc([ 0, np.nan])), sc(np.nan))
+
+ def test_non_finite_inf(self, sc):
+ """ Test that interp between opposite infs gives nan """
+ assert_equal(np.interp(0.5, [-np.inf, +np.inf], sc([ 0, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, 1], sc([-np.inf, +np.inf])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, 1], sc([+np.inf, -np.inf])), sc(np.nan))
+
+ # unless the y values are equal
+ assert_equal(np.interp(0.5, [-np.inf, +np.inf], sc([ 10, 10])), sc(10))
+
+ def test_non_finite_half_inf_xf(self, sc):
+ """ Test that interp where both axes have a bound at inf gives nan """
+ assert_equal(np.interp(0.5, [-np.inf, 1], sc([-np.inf, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [-np.inf, 1], sc([+np.inf, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [-np.inf, 1], sc([ 0, -np.inf])), sc(np.nan))
+ assert_equal(np.interp(0.5, [-np.inf, 1], sc([ 0, +np.inf])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, +np.inf], sc([-np.inf, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, +np.inf], sc([+np.inf, 10])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, +np.inf], sc([ 0, -np.inf])), sc(np.nan))
+ assert_equal(np.interp(0.5, [ 0, +np.inf], sc([ 0, +np.inf])), sc(np.nan))
+
+ def test_non_finite_half_inf_x(self, sc):
+ """ Test interp where the x axis has a bound at inf """
+ assert_equal(np.interp(0.5, [-np.inf, -np.inf], sc([0, 10])), sc(10))
+ assert_equal(np.interp(0.5, [-np.inf, 1 ], sc([0, 10])), sc(10))
+ assert_equal(np.interp(0.5, [ 0, +np.inf], sc([0, 10])), sc(0))
+ assert_equal(np.interp(0.5, [+np.inf, +np.inf], sc([0, 10])), sc(0))
+
+ def test_non_finite_half_inf_f(self, sc):
+ """ Test interp where the f axis has a bound at inf """
+ assert_equal(np.interp(0.5, [0, 1], sc([ 0, -np.inf])), sc(-np.inf))
+ assert_equal(np.interp(0.5, [0, 1], sc([ 0, +np.inf])), sc(+np.inf))
+ assert_equal(np.interp(0.5, [0, 1], sc([-np.inf, 10])), sc(-np.inf))
+ assert_equal(np.interp(0.5, [0, 1], sc([+np.inf, 10])), sc(+np.inf))
+ assert_equal(np.interp(0.5, [0, 1], sc([-np.inf, -np.inf])), sc(-np.inf))
+ assert_equal(np.interp(0.5, [0, 1], sc([+np.inf, +np.inf])), sc(+np.inf))
+
def test_complex_interp(self):
# test complex interpolation
x = np.linspace(0, 1, 5)