8
8
from ._lib ._utils ._compat import array_namespace
9
9
from ._lib ._utils ._typing import Array
10
10
11
- __all__ = ["pad" ]
11
+ __all__ = ["allclose" , "isclose" , " pad" ]
12
12
13
13
14
14
def _delegate (xp : ModuleType , * backends : Backend ) -> bool :
@@ -30,6 +30,144 @@ def _delegate(xp: ModuleType, *backends: Backend) -> bool:
30
30
return any (backend .is_namespace (xp ) for backend in backends )
31
31
32
32
33
+ def allclose (
34
+ a : Array ,
35
+ b : Array ,
36
+ * ,
37
+ rtol : float = 1e-05 ,
38
+ atol : float = 1e-08 ,
39
+ equal_nan : bool = False ,
40
+ xp : ModuleType | None = None ,
41
+ ) -> Array :
42
+ """
43
+ Return True if two arrays are element-wise equal within a tolerance.
44
+
45
+ This is a simple convenience reduction around `isclose`.
46
+
47
+ Parameters
48
+ ----------
49
+ a, b : Array
50
+ Input arrays to compare.
51
+ rtol : array_like, optional
52
+ The relative tolerance parameter.
53
+ atol : array_like, optional
54
+ The absolute tolerance parameter.
55
+ equal_nan : bool, optional
56
+ Whether to compare NaN's as equal. If True, NaN's in `a` will be considered
57
+ equal to NaN's in `b` in the output array.
58
+ xp : array_namespace, optional
59
+ The standard-compatible namespace for `a` and `b`. Default: infer.
60
+
61
+ Returns
62
+ -------
63
+ Array
64
+ A 0-dimensional boolean array, containing `True` if all `a` is elementwise close
65
+ to `b` and `False` otherwise.
66
+
67
+ See Also
68
+ --------
69
+ isclose
70
+ math.isclose
71
+
72
+ Notes
73
+ -----
74
+ If `xp` is a lazy backend (e.g. Dask, JAX), you may not be able to test the result
75
+ contents with ``bool(allclose(a, b))`` or ``if allclose(a, b): ...``.
76
+ """
77
+ xp = array_namespace (a , b ) if xp is None else xp
78
+ return xp .all (isclose (a , b , rtol = rtol , atol = atol , equal_nan = equal_nan , xp = xp ))
79
+
80
+
81
+ def isclose (
82
+ a : Array ,
83
+ b : Array ,
84
+ * ,
85
+ rtol : float = 1e-05 ,
86
+ atol : float = 1e-08 ,
87
+ equal_nan : bool = False ,
88
+ xp : ModuleType | None = None ,
89
+ ) -> Array :
90
+ """
91
+ Return a boolean array where two arrays are element-wise equal within a tolerance.
92
+
93
+ The tolerance values are positive, typically very small numbers. The relative
94
+ difference `(rtol * abs(b))` and the absolute difference atol are added together to
95
+ compare against the absolute difference between a and b.
96
+
97
+ NaNs are treated as equal if they are in the same place and if equal_nan=True. Infs
98
+ are treated as equal if they are in the same place and of the same sign in both
99
+ arrays.
100
+
101
+ Parameters
102
+ ----------
103
+ a, b : Array
104
+ Input arrays to compare.
105
+ rtol : array_like, optional
106
+ The relative tolerance parameter (see Notes).
107
+ atol : array_like, optional
108
+ The absolute tolerance parameter (see Notes).
109
+ equal_nan : bool, optional
110
+ Whether to compare NaN's as equal. If True, NaN's in `a` will be considered
111
+ equal to NaN's in `b` in the output array.
112
+ xp : array_namespace, optional
113
+ The standard-compatible namespace for `a` and `b`. Default: infer.
114
+
115
+ Returns
116
+ -------
117
+ Array
118
+ A boolean array of shape broadcasted from `a` and `b`, containing `True` where
119
+ ``a`` is close to ``b``, and `False` otherwise.
120
+
121
+ Warnings
122
+ --------
123
+ The default atol is not appropriate for comparing numbers with magnitudes much
124
+ smaller than one ) (see notes).
125
+
126
+ See Also
127
+ --------
128
+ allclose
129
+ math.isclose
130
+
131
+ Notes
132
+ -----
133
+ For finite values, `isclose` uses the following equation to test whether two
134
+ floating point values are equivalent::
135
+
136
+ absolute(a - b) <= (atol + rtol * absolute(b))
137
+
138
+ Unlike the built-in `math.isclose`, the above equation is not symmetric in a and b,
139
+ so that `isclose(a, b)` might be different from `isclose(b, a)` in some rare
140
+ cases.
141
+
142
+ The default value of `atol` is not appropriate when the reference value `b` has
143
+ magnitude smaller than one. For example, it is unlikely that ``a = 1e-9`` and
144
+ ``b = 2e-9`` should be considered "close", yet ``isclose(1e-9, 2e-9)`` is `True`
145
+ with default settings. Be sure to select atol for the use case at hand, especially
146
+ for defining the threshold below which a non-zero value in `a` will be considered
147
+ "close" to a very small or zero value in `b`.
148
+
149
+ The comparison of `a` and `b` uses standard broadcasting, which means that `a` and
150
+ `b` need not have the same shape in order for `isclose(a, b)` to evaluate to
151
+ `True`.
152
+
153
+ `isclose` is not defined for non-numeric data types. `bool` is considered a numeric
154
+ data-type for this purpose.
155
+ """
156
+ xp = array_namespace (a , b ) if xp is None else xp
157
+
158
+ if _delegate (
159
+ xp ,
160
+ Backend .NUMPY ,
161
+ Backend .CUPY ,
162
+ Backend .DASK ,
163
+ Backend .JAX ,
164
+ Backend .TORCH ,
165
+ ):
166
+ return xp .isclose (a , b , rtol = rtol , atol = atol , equal_nan = equal_nan )
167
+
168
+ return _funcs .isclose (a , b , rtol = rtol , atol = atol , equal_nan = equal_nan , xp = xp )
169
+
170
+
33
171
def pad (
34
172
x : Array ,
35
173
pad_width : int | tuple [int , int ] | Sequence [tuple [int , int ]],
0 commit comments