diff options
author | Joe Kington <joferkington@gmail.com> | 2012-03-03 17:17:19 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2012-03-04 15:06:28 -0700 |
commit | 63394270fc28dc5615fe018728af894a2ffb2858 (patch) | |
tree | b364d39f152b6825c9e857d0985f25f1951b07c1 /numpy/core/numeric.py | |
parent | 1857ee3e9049260366634f350d67c3fe7609116c (diff) | |
download | numpy-63394270fc28dc5615fe018728af894a2ffb2858.tar.gz |
ENH: Added "isclose()".
Diffstat (limited to 'numpy/core/numeric.py')
-rw-r--r-- | numpy/core/numeric.py | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index bb13d573e..60111e1f2 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -12,7 +12,7 @@ __all__ = ['newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc', 'array_repr', 'array_str', 'set_string_function', 'little_endian', 'require', 'fromiter', 'array_equal', 'array_equiv', - 'indices', 'fromfunction', + 'indices', 'fromfunction', 'isclose', 'load', 'loads', 'isscalar', 'binary_repr', 'base_repr', 'ones', 'identity', 'allclose', 'compare_chararrays', 'putmask', 'seterr', 'geterr', 'setbufsize', 'getbufsize', @@ -2024,6 +2024,86 @@ def allclose(a, b, rtol=1.e-5, atol=1.e-8): y = y[~xinf] return all(less_equal(absolute(x-y), atol + rtol * absolute(y))) +def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False): + """ + Returns a boolean array where two arrays are element-wise equal within a + tolerance. + + The tolerance values are positive, typically very small numbers. The + relative difference (`rtol` * abs(`b`)) and the absolute difference + `atol` are added together to compare against the absolute difference + between `a` and `b`. + + Parameters + ---------- + a, b : array_like + Input arrays to compare. + rtol : float + The relative tolerance parameter (see Notes). + atol : float + The absolute tolerance parameter (see Notes). + equal_nan : bool + Whether to compare NaN's as equal. If True, NaN's in `a` will be + considered equal to NaN's in `b` in the output array. + + Returns + ------- + y : array_like + Returns a boolean array of where `a` and `b` are equal within the + given tolerance. If both `a` and `b` are scalars, returns a single + boolean value. + + See Also + -------- + allclose + + Notes + ----- + For finite values, isclose uses the following equation to test whether + two floating point values are equivalent. + + absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`)) + + The above equation is not symmetric in `a` and `b`, so that + `isclose(a, b)` might be different from `isclose(b, a)` in + some rare cases. + + Examples + -------- + >>> np.isclose([1e10,1e-7], [1.00001e10,1e-8]) + array([True, False]) + >>> np.isclose([1e10,1e-8], [1.00001e10,1e-9]) + array([True, True]) + >>> np.isclose([1e10,1e-8], [1.0001e10,1e-9]) + array([False, True]) + >>> np.isclose([1.0, np.nan], [1.0, np.nan]) + array([True, False]) + >>> np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True) + array([True, True]) + """ + def within_tol(x, y, atol, rtol): + result = less_equal(abs(x-y), atol + rtol * abs(y)) + if isscalar(a) and isscalar(b): + result = bool(result) + return result + x = array(a, copy=False, ndmin=1) + y = array(b, copy=False, ndmin=1) + xfin = isfinite(x) + yfin = isfinite(y) + if all(xfin) and all(yfin): + return within_tol(x, y, atol, rtol) + else: + # Avoid subtraction with infinite/nan values... + cond = zeros(broadcast(x, y).shape, dtype=bool) + mask = xfin & yfin + cond[mask] = within_tol(x[mask], y[mask], atol, rtol) + # Check for equality of infinite values... + cond[~mask] = (x[~mask] == y[~mask]) + if equal_nan: + # Make NaN == NaN + cond[isnan(x) & isnan(y)] = True + return cond + def array_equal(a1, a2): """ True if two arrays have the same shape and elements, False otherwise. |