summaryrefslogtreecommitdiff
path: root/numpy/core/numeric.py
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core/numeric.py')
-rw-r--r--numpy/core/numeric.py82
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.