diff options
author | Ryan Nelson <rnelsonchem@gmail.com> | 2014-12-05 11:39:39 -0500 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2015-01-11 10:36:21 -0700 |
commit | 103fee0ddc23bf29367b052fd39a411c926daae5 (patch) | |
tree | e03be1d68fa70d0fa2efca1eb17907455894c52c /numpy/testing | |
parent | ae2fbd3754d3fb60531705a4f212b9bdfbbdaefd (diff) | |
download | numpy-103fee0ddc23bf29367b052fd39a411c926daae5.tar.gz |
TST: Update assert_array_almost_equal_nulp tests
This fix addresses Issue #347.
All of the tests in this class were using random numbers generated
without a seed. This broke `test_simple` in a nondeterministic manner.
Rewrote all tests for this function. Instead of using random numbers,
well-defined arrays of widely varying amplitude were created instead.
Changed the array modification values so that the test arrays were
either just above or just below the NULP threshold.
Added tests for float64, float32, complex128, and complex64 dtypes, and
added both addition and subtraction tests. Tried to standardize the code
for all tests.
Diffstat (limited to 'numpy/testing')
-rw-r--r-- | numpy/testing/tests/test_utils.py | 203 |
1 files changed, 164 insertions, 39 deletions
diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py index 34608125d..756ea997e 100644 --- a/numpy/testing/tests/test_utils.py +++ b/numpy/testing/tests/test_utils.py @@ -468,47 +468,172 @@ class TestAssertAllclose(unittest.TestCase): self.assertTrue("mismatch 25.0%" in msg) class TestArrayAlmostEqualNulp(unittest.TestCase): - @dec.knownfailureif(True, "Github issue #347") - def test_simple(self): - np.random.seed(12345) - for i in range(100): - dev = np.random.randn(10) - x = np.ones(10) - y = x + dev * np.finfo(np.float64).eps - assert_array_almost_equal_nulp(x, y, nulp=2 * np.max(dev)) - - def test_simple2(self): - x = np.random.randn(10) - y = 2 * x - def failure(): - return assert_array_almost_equal_nulp(x, y, - nulp=1000) - self.assertRaises(AssertionError, failure) - - def test_big_float32(self): - x = (1e10 * np.random.randn(10)).astype(np.float32) - y = x + 1 - assert_array_almost_equal_nulp(x, y, nulp=1000) - - def test_big_float64(self): - x = 1e10 * np.random.randn(10) - y = x + 1 - def failure(): - assert_array_almost_equal_nulp(x, y, nulp=1000) - self.assertRaises(AssertionError, failure) - def test_complex(self): - x = np.random.randn(10) + 1j * np.random.randn(10) - y = x + 1 - def failure(): - assert_array_almost_equal_nulp(x, y, nulp=1000) - self.assertRaises(AssertionError, failure) - - def test_complex2(self): - x = np.random.randn(10) - y = np.array(x, np.complex) + 1e-16 * np.random.randn(10) + def test_float64_pass(self): + # The number of units of least precision + # In this case, use a few places above the lowest level (ie nulp=1) + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + + # Addition + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + # Subtraction + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + def test_float64_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + def test_float32_pass(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + def test_float32_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + + def test_complex128_pass(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + # The test condition needs to be at least a factor of sqrt(2) smaller + # because the real and imaginary parts both change + y = x + x*eps*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + y = x - x*epsneg*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + def test_complex128_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + # The test condition needs to be at least a factor of sqrt(2) smaller + # because the real and imaginary parts both change + y = x + x*eps*nulp + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + y = x - x*epsneg*nulp + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) + + def test_complex64_pass(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + y = x + x*eps*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + y = x - x*epsneg*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + def test_complex64_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + y = x + x*eps*nulp + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + y = x - x*epsneg*nulp + self.assertRaises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) - assert_array_almost_equal_nulp(x, y, nulp=1000) class TestULP(unittest.TestCase): def test_equal(self): |