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