Hi,
I noticed that allclose does not always behave correctly for arrays with infs.
I've attached a test script for allclose, and here's an alternative
implementation that I believe behaves correctly.
Obviously the test script could be a test case in core/tests/test_numeric.py
I wonder if we should allow nans in the test arrays - possibly with an
optional keyword arg like allownan. After all inf-inf is nan - but we
allow that in the test.
Best,
Matthew
from numpy.core import *
def allclose(a, b, rtol=1.e-5, atol=1.e-8):
"""Returns True if all components of a and b are equal subject to given
tolerances.
The relative error rtol must be positive and << 1.0
The absolute error atol usually comes into play for those elements of b that
are very small or zero; it says how small a must be also.
"""
x = array(a, copy=False)
y = array(b, copy=False)
xinf = isinf(x)
if not all(xinf == isinf(y)):
return False
if not any(xinf):
return all(less_equal(absolute(x-y), atol + rtol * absolute(y)))
if not all(x[xinf] == y[xinf]):
return False
x = x[~xinf]
y = y[~xinf]
return all(less_equal(absolute(x-y), atol + rtol * absolute(y)))
from numpy.core import *
from numpy.testing import assert_array_equal
rtol=1.e-5
atol=1.e-8
x = [1, 0]
y = [1, 0]
assert allclose(x, y)
x = [inf, 0]
assert not allclose(x, y)
y = [1, inf]
''' Currently raises AssertionError '''
assert not allclose(x, y)
x = [inf, inf]
''' Currently raises AssertionError '''
assert not allclose(x, y)
y = [1, 0]
''' Currently raises AttributeError '''
assert not allclose(x, y)
x = [-inf, 0]
y = [inf, 0]
assert not allclose(x, y)
x = [nan, 0]
y = [nan, 0]
''' At least worth a comment in the docstring, possibly override
with optional kwarg, such as allownan=True '''
assert not allclose(x, y)
x = [atol]
y = [0]
assert allclose(x, y)
x = [atol*2]
assert not allclose(x, y)
x = [1]
y = [1+rtol+atol]
assert allclose(x, y)
y = [1+rtol+atol*2]
assert not allclose(x, y)
x = array([100, 1000])
y = x + x*rtol
assert allclose(x, y)
assert allclose(y, x)
''' The following is somewhat surprising at first blush
It is caused by use of y rather than x for scaling of rtol '''
y = y + atol*2
assert allclose(x, y)
assert not allclose(y, x)
''' Mutliple dimensions '''
x = arange(125).reshape((5, 5, 5))
y = x + x*rtol
assert allclose(y, x)
''' Adding atol puts the test very close to rounding error '''
y = y + atol*2
assert not allclose(y, x)
''' Test non-modification of input arrays '''
x = array([inf, 1])
y = array([0, inf])
assert not allclose(x, y)
assert_array_equal(x, array([inf, 1]))
assert_array_equal(y, array([0, inf]))
_______________________________________________
Numpy-discussion mailing list
[email protected]
http://projects.scipy.org/mailman/listinfo/numpy-discussion