diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2016-06-18 13:00:33 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2016-06-19 13:47:20 -0600 |
commit | 55002a5204240bfaabdc19bd670c50e47881247c (patch) | |
tree | 4dd6397925ce4a89639993f1b543ff2b4eb167fe /numpy/testing | |
parent | 812ca6fcb2461e2617a50c0c132a1a27ac134849 (diff) | |
download | numpy-55002a5204240bfaabdc19bd670c50e47881247c.tar.gz |
ENH: Make assert_almost_equal & assert_array_almost_equal consistent.
This changes the check for scalars in assert_almost_equal so that
abs(actual - desired) < 1.5 * 10**(-decimal)
Note that the previous documentation claimed that the functions were
equivalent to
abs(actual - desired) < .5 * 10**(-decimal)
but that was not how they behaved in practice.
Due to the change in implementation, some very delicate tests may fail
that did not fail before. No extra failures were noted in scipy.
Closes #5200.
Diffstat (limited to 'numpy/testing')
-rw-r--r-- | numpy/testing/tests/test_utils.py | 36 | ||||
-rw-r--r-- | numpy/testing/utils.py | 33 |
2 files changed, 54 insertions, 15 deletions
diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py index fe1f411c4..842d55b37 100644 --- a/numpy/testing/tests/test_utils.py +++ b/numpy/testing/tests/test_utils.py @@ -11,7 +11,7 @@ from numpy.testing import ( assert_warns, assert_no_warnings, assert_allclose, assert_approx_equal, assert_array_almost_equal_nulp, assert_array_max_ulp, clear_and_catch_warnings, run_module_suite, - assert_string_equal, assert_, tempdir, temppath, + assert_string_equal, assert_, tempdir, temppath, ) import unittest @@ -246,6 +246,23 @@ class TestArrayAlmostEqual(_GenericTest, unittest.TestCase): def setUp(self): self._assert_func = assert_array_almost_equal + def test_closeness(self): + # Note that in the course of time we ended up with + # `abs(x - y) < 1.5 * 10**(-decimal)` + # instead of the previously documented + # `abs(x - y) < 0.5 * 10**(-decimal)` + # so this check serves to preserve the wrongness. + + # test scalars + self._assert_func(1.499999, 0.0, decimal=0) + self.assertRaises(AssertionError, + lambda: self._assert_func(1.5, 0.0, decimal=0)) + + # test arrays + self._assert_func([1.499999], [0.0], decimal=0) + self.assertRaises(AssertionError, + lambda: self._assert_func([1.5], [0.0], decimal=0)) + def test_simple(self): x = np.array([1234.2222]) y = np.array([1234.2223]) @@ -288,6 +305,23 @@ class TestAlmostEqual(_GenericTest, unittest.TestCase): def setUp(self): self._assert_func = assert_almost_equal + def test_closeness(self): + # Note that in the course of time we ended up with + # `abs(x - y) < 1.5 * 10**(-decimal)` + # instead of the previously documented + # `abs(x - y) < 0.5 * 10**(-decimal)` + # so this check serves to preserve the wrongness. + + # test scalars + self._assert_func(1.499999, 0.0, decimal=0) + self.assertRaises(AssertionError, + lambda: self._assert_func(1.5, 0.0, decimal=0)) + + # test arrays + self._assert_func([1.499999], [0.0], decimal=0) + self.assertRaises(AssertionError, + lambda: self._assert_func([1.5], [0.0], decimal=0)) + def test_nan_item(self): self._assert_func(np.nan, np.nan) self.assertRaises(AssertionError, diff --git a/numpy/testing/utils.py b/numpy/testing/utils.py index 3f4a8568a..dfed5d148 100644 --- a/numpy/testing/utils.py +++ b/numpy/testing/utils.py @@ -424,11 +424,14 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True): instead of this function for more consistent floating point comparisons. - The test is equivalent to ``abs(desired-actual) < 0.5 * 10**(-decimal)``. + The test verifies that the elements of ``actual`` and ``desired`` satisfy. - Given two objects (numbers or ndarrays), check that all elements of these - objects are almost equal. An exception is raised at conflicting values. - For ndarrays this delegates to assert_array_almost_equal + ``abs(desired-actual) < 1.5 * 10**(-decimal)`` + + That is a looser test than originally documented, but agrees with what the + actual implementation in `assert_array_almost_equal` did up to rounding + vagaries. An exception is raised at conflicting values. For ndarrays this + delegates to assert_array_almost_equal Parameters ---------- @@ -529,7 +532,7 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True): return except (NotImplementedError, TypeError): pass - if round(abs(desired - actual), decimal) != 0: + if abs(desired - actual) >= 1.5 * 10.0**(-decimal): raise AssertionError(_build_err_msg()) @@ -819,14 +822,16 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True): instead of this function for more consistent floating point comparisons. - The test verifies identical shapes and verifies values with - ``abs(desired-actual) < 0.5 * 10**(-decimal)``. + The test verifies identical shapes and that the elements of ``actual`` and + ``desired`` satisfy. - Given two array_like objects, check that the shape is equal and all - elements of these objects are almost equal. An exception is raised at - shape mismatch or conflicting values. In contrast to the standard usage - in numpy, NaNs are compared like numbers, no assertion is raised if - both objects have NaNs in the same positions. + ``abs(desired-actual) < 1.5 * 10**(-decimal)`` + + That is a looser test than originally documented, but agrees with what the + actual implementation did up to rounding vagaries. An exception is raised + at shape mismatch or conflicting values. In contrast to the standard usage + in numpy, NaNs are compared like numbers, no assertion is raised if both + objects have NaNs in the same positions. Parameters ---------- @@ -903,12 +908,12 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True): # casting of x later. dtype = result_type(y, 1.) y = array(y, dtype=dtype, copy=False, subok=True) - z = abs(x-y) + z = abs(x - y) if not issubdtype(z.dtype, number): z = z.astype(float_) # handle object arrays - return around(z, decimal) <= 10.0**(-decimal) + return z < 1.5 * 10.0**(-decimal) assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose, header=('Arrays are not almost equal to %d decimals' % decimal), |