array-api-strict 2.3__py3-none-any.whl → 2.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- array_api_strict/__init__.py +11 -5
- array_api_strict/_array_object.py +226 -200
- array_api_strict/_constants.py +1 -1
- array_api_strict/_creation_functions.py +97 -119
- array_api_strict/_data_type_functions.py +73 -64
- array_api_strict/_dtypes.py +35 -24
- array_api_strict/_elementwise_functions.py +138 -482
- array_api_strict/_fft.py +28 -32
- array_api_strict/_flags.py +65 -26
- array_api_strict/_helpers.py +23 -14
- array_api_strict/_indexing_functions.py +3 -8
- array_api_strict/_info.py +64 -69
- array_api_strict/_linalg.py +57 -53
- array_api_strict/_linear_algebra_functions.py +11 -9
- array_api_strict/_manipulation_functions.py +30 -30
- array_api_strict/_searching_functions.py +22 -33
- array_api_strict/_set_functions.py +4 -6
- array_api_strict/_sorting_functions.py +6 -6
- array_api_strict/_statistical_functions.py +57 -64
- array_api_strict/_typing.py +30 -50
- array_api_strict/_utility_functions.py +11 -13
- array_api_strict/_version.py +2 -2
- array_api_strict/py.typed +0 -0
- array_api_strict/tests/test_array_object.py +163 -56
- array_api_strict/tests/test_creation_functions.py +14 -12
- array_api_strict/tests/test_data_type_functions.py +40 -6
- array_api_strict/tests/test_elementwise_functions.py +94 -45
- array_api_strict/tests/test_searching_functions.py +79 -1
- array_api_strict/tests/test_validation.py +1 -3
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/METADATA +5 -4
- array_api_strict-2.4.dist-info/RECORD +44 -0
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/WHEEL +1 -1
- array_api_strict-2.3.dist-info/RECORD +0 -43
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/LICENSE +0 -0
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/top_level.txt +0 -0
|
@@ -1,51 +1,49 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from functools import wraps
|
|
3
|
+
from types import NoneType
|
|
2
4
|
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from ._array_object import Array
|
|
8
|
+
from ._creation_functions import asarray
|
|
9
|
+
from ._data_type_functions import broadcast_to, iinfo
|
|
3
10
|
from ._dtypes import (
|
|
4
|
-
_boolean_dtypes,
|
|
5
|
-
_floating_dtypes,
|
|
6
|
-
_real_floating_dtypes,
|
|
7
11
|
_complex_floating_dtypes,
|
|
12
|
+
_dtype_categories,
|
|
8
13
|
_integer_dtypes,
|
|
9
|
-
_integer_or_boolean_dtypes,
|
|
10
|
-
_real_numeric_dtypes,
|
|
11
14
|
_numeric_dtypes,
|
|
15
|
+
_real_floating_dtypes,
|
|
16
|
+
_real_numeric_dtypes,
|
|
12
17
|
_result_type,
|
|
13
|
-
_dtype_categories,
|
|
14
18
|
)
|
|
15
|
-
from ._array_object import Array
|
|
16
19
|
from ._flags import requires_api_version
|
|
17
|
-
from ._creation_functions import asarray
|
|
18
|
-
from ._data_type_functions import broadcast_to, iinfo
|
|
19
20
|
from ._helpers import _maybe_normalize_py_scalars
|
|
20
21
|
|
|
21
|
-
from typing import Optional, Union
|
|
22
|
-
|
|
23
|
-
import numpy as np
|
|
24
|
-
|
|
25
22
|
|
|
26
23
|
def _binary_ufunc_proto(x1, x2, dtype_category, func_name, np_func):
|
|
27
24
|
"""Base implementation of a binary function, `func_name`, defined for
|
|
28
|
-
|
|
25
|
+
dtypes from `dtype_category`
|
|
29
26
|
"""
|
|
30
27
|
x1, x2 = _maybe_normalize_py_scalars(x1, x2, dtype_category, func_name)
|
|
31
28
|
|
|
32
29
|
if x1.device != x2.device:
|
|
33
|
-
raise ValueError(
|
|
30
|
+
raise ValueError(
|
|
31
|
+
f"Arrays from two different devices ({x1.device} and {x2.device}) can not be combined."
|
|
32
|
+
)
|
|
34
33
|
# Call result type here just to raise on disallowed type combinations
|
|
35
34
|
_result_type(x1.dtype, x2.dtype)
|
|
36
35
|
x1, x2 = Array._normalize_two_args(x1, x2)
|
|
37
36
|
return Array._new(np_func(x1._array, x2._array), device=x1.device)
|
|
38
37
|
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
"""
|
|
39
|
+
_docstring_template = """
|
|
42
40
|
Array API compatible wrapper for :py:func:`np.%s <numpy.%s>`.
|
|
43
41
|
|
|
44
42
|
See its docstring for more information.
|
|
45
43
|
"""
|
|
46
44
|
|
|
47
45
|
|
|
48
|
-
def
|
|
46
|
+
def _create_binary_func(func_name, dtype_category, np_func):
|
|
49
47
|
def inner(x1, x2, /) -> Array:
|
|
50
48
|
return _binary_ufunc_proto(x1, x2, dtype_category, func_name, np_func)
|
|
51
49
|
return inner
|
|
@@ -54,15 +52,15 @@ def create_binary_func(func_name, dtype_category, np_func):
|
|
|
54
52
|
# static type annotation for ArrayOrPythonScalar arguments given a category
|
|
55
53
|
# NB: keep the keys in sync with the _dtype_categories dict
|
|
56
54
|
_annotations = {
|
|
57
|
-
"all": "
|
|
58
|
-
"real numeric": "
|
|
59
|
-
"numeric": "
|
|
55
|
+
"all": "complex | Array",
|
|
56
|
+
"real numeric": "float | Array",
|
|
57
|
+
"numeric": "complex | Array",
|
|
60
58
|
"integer": "int | Array",
|
|
61
|
-
"integer or boolean": "int |
|
|
59
|
+
"integer or boolean": "int | Array",
|
|
62
60
|
"boolean": "bool | Array",
|
|
63
61
|
"real floating-point": "float | Array",
|
|
64
62
|
"complex floating-point": "complex | Array",
|
|
65
|
-
"floating-point": "
|
|
63
|
+
"floating-point": "complex | Array",
|
|
66
64
|
}
|
|
67
65
|
|
|
68
66
|
|
|
@@ -75,7 +73,7 @@ _binary_funcs = {
|
|
|
75
73
|
"bitwise_xor": "integer or boolean",
|
|
76
74
|
"_bitwise_left_shift": "integer", # leading underscore deliberate
|
|
77
75
|
"_bitwise_right_shift": "integer",
|
|
78
|
-
# XXX: copysign: real fp or numeric?
|
|
76
|
+
# XXX: copysign: real fp or numeric?
|
|
79
77
|
"copysign": "real floating-point",
|
|
80
78
|
"divide": "floating-point",
|
|
81
79
|
"equal": "all",
|
|
@@ -105,7 +103,7 @@ _numpy_renames = {
|
|
|
105
103
|
"atan2": "arctan2",
|
|
106
104
|
"_bitwise_left_shift": "left_shift",
|
|
107
105
|
"_bitwise_right_shift": "right_shift",
|
|
108
|
-
"pow": "power"
|
|
106
|
+
"pow": "power",
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
|
|
@@ -117,10 +115,10 @@ for func_name, dtype_category in _binary_funcs.items():
|
|
|
117
115
|
numpy_name = _numpy_renames.get(func_name, func_name)
|
|
118
116
|
np_func = getattr(np, numpy_name)
|
|
119
117
|
|
|
120
|
-
func =
|
|
118
|
+
func = _create_binary_func(func_name, dtype_category, np_func)
|
|
121
119
|
func.__name__ = func_name
|
|
122
120
|
|
|
123
|
-
func.__doc__ =
|
|
121
|
+
func.__doc__ = _docstring_template % (numpy_name, numpy_name)
|
|
124
122
|
func.__annotations__['x1'] = _annotations[dtype_category]
|
|
125
123
|
func.__annotations__['x2'] = _annotations[dtype_category]
|
|
126
124
|
|
|
@@ -153,168 +151,137 @@ if _bitwise_right_shift.__doc__: # noqa: F821
|
|
|
153
151
|
|
|
154
152
|
|
|
155
153
|
# clean up to not pollute the namespace
|
|
156
|
-
del func,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
154
|
+
del func, _create_binary_func
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _create_unary_func(
|
|
158
|
+
func_name: str,
|
|
159
|
+
dtype_category: str,
|
|
160
|
+
np_func_name: str | None = None,
|
|
161
|
+
) -> Callable[[Array], Array]:
|
|
162
|
+
allowed_dtypes = _dtype_categories[dtype_category]
|
|
163
|
+
np_func_name = np_func_name or func_name
|
|
164
|
+
np_func = getattr(np, np_func_name)
|
|
165
|
+
|
|
166
|
+
def func(x: Array, /) -> Array:
|
|
167
|
+
if not isinstance(x, Array):
|
|
168
|
+
raise TypeError(f"Only Array objects are allowed; got {type(x)}")
|
|
169
|
+
if x.dtype not in allowed_dtypes:
|
|
170
|
+
raise TypeError(
|
|
171
|
+
f"Only {dtype_category} dtypes are allowed in {func_name}; "
|
|
172
|
+
f"got {x.dtype}."
|
|
173
|
+
)
|
|
174
|
+
return Array._new(np_func(x._array), device=x.device)
|
|
168
175
|
|
|
176
|
+
func.__name__ = func_name
|
|
177
|
+
func.__doc__ = _docstring_template % (np_func_name, np_func_name)
|
|
178
|
+
return func
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _identity_if_integer(func: Callable[[Array], Array]) -> Callable[[Array], Array]:
|
|
182
|
+
"""Hack around NumPy 1.x behaviour for ceil, floor, and trunc
|
|
183
|
+
vs. integer inputs
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
@wraps(func)
|
|
187
|
+
def wrapper(x: Array, /) -> Array:
|
|
188
|
+
if isinstance(x, Array) and x.dtype in _integer_dtypes:
|
|
189
|
+
return x
|
|
190
|
+
return func(x)
|
|
191
|
+
|
|
192
|
+
return wrapper
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
abs = _create_unary_func("abs", "numeric")
|
|
196
|
+
acos = _create_unary_func("acos", "floating-point", "arccos")
|
|
197
|
+
acosh = _create_unary_func("acosh", "floating-point", "arccosh")
|
|
198
|
+
asin = _create_unary_func("asin", "floating-point", "arcsin")
|
|
199
|
+
asinh = _create_unary_func("asinh", "floating-point", "arcsinh")
|
|
200
|
+
atan = _create_unary_func("atan", "floating-point", "arctan")
|
|
201
|
+
atanh = _create_unary_func("atanh", "floating-point", "arctanh")
|
|
202
|
+
bitwise_invert = _create_unary_func("bitwise_invert", "integer or boolean", "invert")
|
|
203
|
+
ceil = _identity_if_integer(_create_unary_func("ceil", "real numeric"))
|
|
204
|
+
conj = _create_unary_func("conj", "numeric")
|
|
205
|
+
cos = _create_unary_func("cos", "floating-point", "cos")
|
|
206
|
+
cosh = _create_unary_func("cosh", "floating-point", "cosh")
|
|
207
|
+
exp = _create_unary_func("exp", "floating-point")
|
|
208
|
+
expm1 = _create_unary_func("expm1", "floating-point")
|
|
209
|
+
floor = _identity_if_integer(_create_unary_func("floor", "real numeric"))
|
|
210
|
+
imag = _create_unary_func("imag", "complex floating-point")
|
|
211
|
+
isfinite = _create_unary_func("isfinite", "numeric")
|
|
212
|
+
isinf = _create_unary_func("isinf", "numeric")
|
|
213
|
+
isnan = _create_unary_func("isnan", "numeric")
|
|
214
|
+
log = _create_unary_func("log", "floating-point")
|
|
215
|
+
log10 = _create_unary_func("log10", "floating-point")
|
|
216
|
+
log1p = _create_unary_func("log1p", "floating-point")
|
|
217
|
+
log2 = _create_unary_func("log2", "floating-point")
|
|
218
|
+
logical_not = _create_unary_func("logical_not", "boolean")
|
|
219
|
+
negative = _create_unary_func("negative", "numeric")
|
|
220
|
+
positive = _create_unary_func("positive", "numeric")
|
|
221
|
+
real = _create_unary_func("real", "numeric")
|
|
222
|
+
reciprocal = requires_api_version("2024.12")(
|
|
223
|
+
_create_unary_func("reciprocal", "floating-point")
|
|
224
|
+
)
|
|
225
|
+
round = _create_unary_func("round", "numeric")
|
|
226
|
+
signbit = requires_api_version("2023.12")(
|
|
227
|
+
_create_unary_func("signbit", "real floating-point")
|
|
228
|
+
)
|
|
229
|
+
sin = _create_unary_func("sin", "floating-point")
|
|
230
|
+
sinh = _create_unary_func("sinh", "floating-point")
|
|
231
|
+
sqrt = _create_unary_func("sqrt", "floating-point")
|
|
232
|
+
square = _create_unary_func("square", "numeric")
|
|
233
|
+
tan = _create_unary_func("tan", "floating-point")
|
|
234
|
+
tanh = _create_unary_func("tanh", "floating-point")
|
|
235
|
+
trunc = _identity_if_integer(_create_unary_func("trunc", "real numeric"))
|
|
169
236
|
|
|
170
|
-
# Note: the function name is different here
|
|
171
|
-
def acos(x: Array, /) -> Array:
|
|
172
|
-
"""
|
|
173
|
-
Array API compatible wrapper for :py:func:`np.arccos <numpy.arccos>`.
|
|
174
|
-
|
|
175
|
-
See its docstring for more information.
|
|
176
|
-
"""
|
|
177
|
-
if x.dtype not in _floating_dtypes:
|
|
178
|
-
raise TypeError("Only floating-point dtypes are allowed in acos")
|
|
179
|
-
return Array._new(np.arccos(x._array), device=x.device)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
# Note: the function name is different here
|
|
183
|
-
def acosh(x: Array, /) -> Array:
|
|
184
|
-
"""
|
|
185
|
-
Array API compatible wrapper for :py:func:`np.arccosh <numpy.arccosh>`.
|
|
186
|
-
|
|
187
|
-
See its docstring for more information.
|
|
188
|
-
"""
|
|
189
|
-
if x.dtype not in _floating_dtypes:
|
|
190
|
-
raise TypeError("Only floating-point dtypes are allowed in acosh")
|
|
191
|
-
return Array._new(np.arccosh(x._array), device=x.device)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
# Note: the function name is different here
|
|
195
|
-
def asin(x: Array, /) -> Array:
|
|
196
|
-
"""
|
|
197
|
-
Array API compatible wrapper for :py:func:`np.arcsin <numpy.arcsin>`.
|
|
198
|
-
|
|
199
|
-
See its docstring for more information.
|
|
200
|
-
"""
|
|
201
|
-
if x.dtype not in _floating_dtypes:
|
|
202
|
-
raise TypeError("Only floating-point dtypes are allowed in asin")
|
|
203
|
-
return Array._new(np.arcsin(x._array), device=x.device)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
# Note: the function name is different here
|
|
207
|
-
def asinh(x: Array, /) -> Array:
|
|
208
|
-
"""
|
|
209
|
-
Array API compatible wrapper for :py:func:`np.arcsinh <numpy.arcsinh>`.
|
|
210
|
-
|
|
211
|
-
See its docstring for more information.
|
|
212
|
-
"""
|
|
213
|
-
if x.dtype not in _floating_dtypes:
|
|
214
|
-
raise TypeError("Only floating-point dtypes are allowed in asinh")
|
|
215
|
-
return Array._new(np.arcsinh(x._array), device=x.device)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
# Note: the function name is different here
|
|
219
|
-
def atan(x: Array, /) -> Array:
|
|
220
|
-
"""
|
|
221
|
-
Array API compatible wrapper for :py:func:`np.arctan <numpy.arctan>`.
|
|
222
|
-
|
|
223
|
-
See its docstring for more information.
|
|
224
|
-
"""
|
|
225
|
-
if x.dtype not in _floating_dtypes:
|
|
226
|
-
raise TypeError("Only floating-point dtypes are allowed in atan")
|
|
227
|
-
return Array._new(np.arctan(x._array), device=x.device)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
# Note: the function name is different here
|
|
231
|
-
def atanh(x: Array, /) -> Array:
|
|
232
|
-
"""
|
|
233
|
-
Array API compatible wrapper for :py:func:`np.arctanh <numpy.arctanh>`.
|
|
234
|
-
|
|
235
|
-
See its docstring for more information.
|
|
236
|
-
"""
|
|
237
|
-
if x.dtype not in _floating_dtypes:
|
|
238
|
-
raise TypeError("Only floating-point dtypes are allowed in atanh")
|
|
239
|
-
return Array._new(np.arctanh(x._array), device=x.device)
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
# Note: the function name is different here
|
|
243
|
-
def bitwise_invert(x: Array, /) -> Array:
|
|
244
|
-
"""
|
|
245
|
-
Array API compatible wrapper for :py:func:`np.invert <numpy.invert>`.
|
|
246
|
-
|
|
247
|
-
See its docstring for more information.
|
|
248
|
-
"""
|
|
249
|
-
if x.dtype not in _integer_or_boolean_dtypes:
|
|
250
|
-
raise TypeError("Only integer or boolean dtypes are allowed in bitwise_invert")
|
|
251
|
-
return Array._new(np.invert(x._array), device=x.device)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
def ceil(x: Array, /) -> Array:
|
|
255
|
-
"""
|
|
256
|
-
Array API compatible wrapper for :py:func:`np.ceil <numpy.ceil>`.
|
|
257
|
-
|
|
258
|
-
See its docstring for more information.
|
|
259
|
-
"""
|
|
260
|
-
if x.dtype not in _real_numeric_dtypes:
|
|
261
|
-
raise TypeError("Only real numeric dtypes are allowed in ceil")
|
|
262
|
-
if x.dtype in _integer_dtypes:
|
|
263
|
-
# Note: The return dtype of ceil is the same as the input
|
|
264
|
-
return x
|
|
265
|
-
return Array._new(np.ceil(x._array), device=x.device)
|
|
266
|
-
|
|
267
|
-
# WARNING: This function is not yet tested by the array-api-tests test suite.
|
|
268
237
|
|
|
269
238
|
# Note: min and max argument names are different and not optional in numpy.
|
|
270
239
|
@requires_api_version('2023.12')
|
|
271
240
|
def clip(
|
|
272
241
|
x: Array,
|
|
273
242
|
/,
|
|
274
|
-
min:
|
|
275
|
-
max:
|
|
243
|
+
min: Array | float | None = None,
|
|
244
|
+
max: Array | float | None = None,
|
|
276
245
|
) -> Array:
|
|
277
246
|
"""
|
|
278
247
|
Array API compatible wrapper for :py:func:`np.clip <numpy.clip>`.
|
|
279
248
|
|
|
280
249
|
See its docstring for more information.
|
|
281
250
|
"""
|
|
282
|
-
if isinstance(
|
|
283
|
-
raise
|
|
284
|
-
if isinstance(max, Array) and x.device != max.device:
|
|
285
|
-
raise ValueError(f"Arrays from two different devices ({x.device} and {max.device}) can not be combined.")
|
|
251
|
+
if not isinstance(x, Array):
|
|
252
|
+
raise TypeError(f"Only Array objects are allowed; got {type(x)}")
|
|
286
253
|
|
|
287
254
|
if (x.dtype not in _real_numeric_dtypes
|
|
288
255
|
or isinstance(min, Array) and min.dtype not in _real_numeric_dtypes
|
|
289
256
|
or isinstance(max, Array) and max.dtype not in _real_numeric_dtypes):
|
|
290
257
|
raise TypeError("Only real numeric dtypes are allowed in clip")
|
|
291
|
-
if not isinstance(min, (int, float, Array, type(None))):
|
|
292
|
-
raise TypeError("min must be an None, int, float, or an array")
|
|
293
|
-
if not isinstance(max, (int, float, Array, type(None))):
|
|
294
|
-
raise TypeError("max must be an None, int, float, or an array")
|
|
295
|
-
|
|
296
|
-
# Mixed dtype kinds is implementation defined
|
|
297
|
-
if (x.dtype in _integer_dtypes
|
|
298
|
-
and (isinstance(min, float) or
|
|
299
|
-
isinstance(min, Array) and min.dtype in _real_floating_dtypes)):
|
|
300
|
-
raise TypeError("min must be integral when x is integral")
|
|
301
|
-
if (x.dtype in _integer_dtypes
|
|
302
|
-
and (isinstance(max, float) or
|
|
303
|
-
isinstance(max, Array) and max.dtype in _real_floating_dtypes)):
|
|
304
|
-
raise TypeError("max must be integral when x is integral")
|
|
305
|
-
if (x.dtype in _real_floating_dtypes
|
|
306
|
-
and (isinstance(min, int) or
|
|
307
|
-
isinstance(min, Array) and min.dtype in _integer_dtypes)):
|
|
308
|
-
raise TypeError("min must be floating-point when x is floating-point")
|
|
309
|
-
if (x.dtype in _real_floating_dtypes
|
|
310
|
-
and (isinstance(max, int) or
|
|
311
|
-
isinstance(max, Array) and max.dtype in _integer_dtypes)):
|
|
312
|
-
raise TypeError("max must be floating-point when x is floating-point")
|
|
313
258
|
|
|
314
259
|
if min is max is None:
|
|
315
|
-
# Note: NumPy disallows min = max = None
|
|
316
260
|
return x
|
|
317
261
|
|
|
262
|
+
for argname, arg in ("min", min), ("max", max):
|
|
263
|
+
if isinstance(arg, Array):
|
|
264
|
+
if x.device != arg.device:
|
|
265
|
+
raise ValueError(
|
|
266
|
+
f"Arrays from two different devices ({x.device} and {arg.device}) "
|
|
267
|
+
"can not be combined."
|
|
268
|
+
)
|
|
269
|
+
# Disallow subclasses of Python scalars, e.g. np.float64
|
|
270
|
+
elif type(arg) not in (int, float, NoneType):
|
|
271
|
+
raise TypeError(
|
|
272
|
+
f"{argname} must be None, int, float, or Array; got {type(arg)}"
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# Mixed dtype kinds is implementation defined
|
|
276
|
+
if (x.dtype in _integer_dtypes
|
|
277
|
+
and (isinstance(arg, float) or
|
|
278
|
+
isinstance(arg, Array) and arg.dtype in _real_floating_dtypes)):
|
|
279
|
+
raise TypeError(f"{argname} must be integral when x is integral")
|
|
280
|
+
if (x.dtype in _real_floating_dtypes
|
|
281
|
+
and (isinstance(arg, int) or
|
|
282
|
+
isinstance(arg, Array) and arg.dtype in _integer_dtypes)):
|
|
283
|
+
raise TypeError(f"{arg} must be floating-point when x is floating-point")
|
|
284
|
+
|
|
318
285
|
# Normalize to make the below logic simpler
|
|
319
286
|
if min is not None:
|
|
320
287
|
min = asarray(min)._array
|
|
@@ -351,6 +318,7 @@ def clip(
|
|
|
351
318
|
|
|
352
319
|
def _isscalar(a):
|
|
353
320
|
return isinstance(a, (int, float, type(None)))
|
|
321
|
+
|
|
354
322
|
min_shape = () if _isscalar(min) else min.shape
|
|
355
323
|
max_shape = () if _isscalar(max) else max.shape
|
|
356
324
|
|
|
@@ -372,329 +340,17 @@ def clip(
|
|
|
372
340
|
return Array._new(out, device=device)
|
|
373
341
|
|
|
374
342
|
|
|
375
|
-
def conj(x: Array, /) -> Array:
|
|
376
|
-
"""
|
|
377
|
-
Array API compatible wrapper for :py:func:`np.conj <numpy.conj>`.
|
|
378
|
-
|
|
379
|
-
See its docstring for more information.
|
|
380
|
-
"""
|
|
381
|
-
if x.dtype not in _numeric_dtypes:
|
|
382
|
-
raise TypeError("Only numeric dtypes are allowed in conj")
|
|
383
|
-
return Array._new(np.conj(x._array), device=x.device)
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
def cos(x: Array, /) -> Array:
|
|
387
|
-
"""
|
|
388
|
-
Array API compatible wrapper for :py:func:`np.cos <numpy.cos>`.
|
|
389
|
-
|
|
390
|
-
See its docstring for more information.
|
|
391
|
-
"""
|
|
392
|
-
if x.dtype not in _floating_dtypes:
|
|
393
|
-
raise TypeError("Only floating-point dtypes are allowed in cos")
|
|
394
|
-
return Array._new(np.cos(x._array), device=x.device)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
def cosh(x: Array, /) -> Array:
|
|
398
|
-
"""
|
|
399
|
-
Array API compatible wrapper for :py:func:`np.cosh <numpy.cosh>`.
|
|
400
|
-
|
|
401
|
-
See its docstring for more information.
|
|
402
|
-
"""
|
|
403
|
-
if x.dtype not in _floating_dtypes:
|
|
404
|
-
raise TypeError("Only floating-point dtypes are allowed in cosh")
|
|
405
|
-
return Array._new(np.cosh(x._array), device=x.device)
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
def exp(x: Array, /) -> Array:
|
|
409
|
-
"""
|
|
410
|
-
Array API compatible wrapper for :py:func:`np.exp <numpy.exp>`.
|
|
411
|
-
|
|
412
|
-
See its docstring for more information.
|
|
413
|
-
"""
|
|
414
|
-
if x.dtype not in _floating_dtypes:
|
|
415
|
-
raise TypeError("Only floating-point dtypes are allowed in exp")
|
|
416
|
-
return Array._new(np.exp(x._array), device=x.device)
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
def expm1(x: Array, /) -> Array:
|
|
420
|
-
"""
|
|
421
|
-
Array API compatible wrapper for :py:func:`np.expm1 <numpy.expm1>`.
|
|
422
|
-
|
|
423
|
-
See its docstring for more information.
|
|
424
|
-
"""
|
|
425
|
-
if x.dtype not in _floating_dtypes:
|
|
426
|
-
raise TypeError("Only floating-point dtypes are allowed in expm1")
|
|
427
|
-
return Array._new(np.expm1(x._array), device=x.device)
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
def floor(x: Array, /) -> Array:
|
|
431
|
-
"""
|
|
432
|
-
Array API compatible wrapper for :py:func:`np.floor <numpy.floor>`.
|
|
433
|
-
|
|
434
|
-
See its docstring for more information.
|
|
435
|
-
"""
|
|
436
|
-
if x.dtype not in _real_numeric_dtypes:
|
|
437
|
-
raise TypeError("Only real numeric dtypes are allowed in floor")
|
|
438
|
-
if x.dtype in _integer_dtypes:
|
|
439
|
-
# Note: The return dtype of floor is the same as the input
|
|
440
|
-
return x
|
|
441
|
-
return Array._new(np.floor(x._array), device=x.device)
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
def imag(x: Array, /) -> Array:
|
|
445
|
-
"""
|
|
446
|
-
Array API compatible wrapper for :py:func:`np.imag <numpy.imag>`.
|
|
447
|
-
|
|
448
|
-
See its docstring for more information.
|
|
449
|
-
"""
|
|
450
|
-
if x.dtype not in _complex_floating_dtypes:
|
|
451
|
-
raise TypeError("Only complex floating-point dtypes are allowed in imag")
|
|
452
|
-
return Array._new(np.imag(x._array), device=x.device)
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
def isfinite(x: Array, /) -> Array:
|
|
456
|
-
"""
|
|
457
|
-
Array API compatible wrapper for :py:func:`np.isfinite <numpy.isfinite>`.
|
|
458
|
-
|
|
459
|
-
See its docstring for more information.
|
|
460
|
-
"""
|
|
461
|
-
if x.dtype not in _numeric_dtypes:
|
|
462
|
-
raise TypeError("Only numeric dtypes are allowed in isfinite")
|
|
463
|
-
return Array._new(np.isfinite(x._array), device=x.device)
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
def isinf(x: Array, /) -> Array:
|
|
467
|
-
"""
|
|
468
|
-
Array API compatible wrapper for :py:func:`np.isinf <numpy.isinf>`.
|
|
469
|
-
|
|
470
|
-
See its docstring for more information.
|
|
471
|
-
"""
|
|
472
|
-
if x.dtype not in _numeric_dtypes:
|
|
473
|
-
raise TypeError("Only numeric dtypes are allowed in isinf")
|
|
474
|
-
return Array._new(np.isinf(x._array), device=x.device)
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
def isnan(x: Array, /) -> Array:
|
|
478
|
-
"""
|
|
479
|
-
Array API compatible wrapper for :py:func:`np.isnan <numpy.isnan>`.
|
|
480
|
-
|
|
481
|
-
See its docstring for more information.
|
|
482
|
-
"""
|
|
483
|
-
if x.dtype not in _numeric_dtypes:
|
|
484
|
-
raise TypeError("Only numeric dtypes are allowed in isnan")
|
|
485
|
-
return Array._new(np.isnan(x._array), device=x.device)
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
def log(x: Array, /) -> Array:
|
|
489
|
-
"""
|
|
490
|
-
Array API compatible wrapper for :py:func:`np.log <numpy.log>`.
|
|
491
|
-
|
|
492
|
-
See its docstring for more information.
|
|
493
|
-
"""
|
|
494
|
-
if x.dtype not in _floating_dtypes:
|
|
495
|
-
raise TypeError("Only floating-point dtypes are allowed in log")
|
|
496
|
-
return Array._new(np.log(x._array), device=x.device)
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
def log1p(x: Array, /) -> Array:
|
|
500
|
-
"""
|
|
501
|
-
Array API compatible wrapper for :py:func:`np.log1p <numpy.log1p>`.
|
|
502
|
-
|
|
503
|
-
See its docstring for more information.
|
|
504
|
-
"""
|
|
505
|
-
if x.dtype not in _floating_dtypes:
|
|
506
|
-
raise TypeError("Only floating-point dtypes are allowed in log1p")
|
|
507
|
-
return Array._new(np.log1p(x._array), device=x.device)
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
def log2(x: Array, /) -> Array:
|
|
511
|
-
"""
|
|
512
|
-
Array API compatible wrapper for :py:func:`np.log2 <numpy.log2>`.
|
|
513
|
-
|
|
514
|
-
See its docstring for more information.
|
|
515
|
-
"""
|
|
516
|
-
if x.dtype not in _floating_dtypes:
|
|
517
|
-
raise TypeError("Only floating-point dtypes are allowed in log2")
|
|
518
|
-
return Array._new(np.log2(x._array), device=x.device)
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
def log10(x: Array, /) -> Array:
|
|
522
|
-
"""
|
|
523
|
-
Array API compatible wrapper for :py:func:`np.log10 <numpy.log10>`.
|
|
524
|
-
|
|
525
|
-
See its docstring for more information.
|
|
526
|
-
"""
|
|
527
|
-
if x.dtype not in _floating_dtypes:
|
|
528
|
-
raise TypeError("Only floating-point dtypes are allowed in log10")
|
|
529
|
-
return Array._new(np.log10(x._array), device=x.device)
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
def logical_not(x: Array, /) -> Array:
|
|
533
|
-
"""
|
|
534
|
-
Array API compatible wrapper for :py:func:`np.logical_not <numpy.logical_not>`.
|
|
535
|
-
|
|
536
|
-
See its docstring for more information.
|
|
537
|
-
"""
|
|
538
|
-
if x.dtype not in _boolean_dtypes:
|
|
539
|
-
raise TypeError("Only boolean dtypes are allowed in logical_not")
|
|
540
|
-
return Array._new(np.logical_not(x._array), device=x.device)
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
def negative(x: Array, /) -> Array:
|
|
544
|
-
"""
|
|
545
|
-
Array API compatible wrapper for :py:func:`np.negative <numpy.negative>`.
|
|
546
|
-
|
|
547
|
-
See its docstring for more information.
|
|
548
|
-
"""
|
|
549
|
-
if x.dtype not in _numeric_dtypes:
|
|
550
|
-
raise TypeError("Only numeric dtypes are allowed in negative")
|
|
551
|
-
return Array._new(np.negative(x._array), device=x.device)
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
def positive(x: Array, /) -> Array:
|
|
555
|
-
"""
|
|
556
|
-
Array API compatible wrapper for :py:func:`np.positive <numpy.positive>`.
|
|
557
|
-
|
|
558
|
-
See its docstring for more information.
|
|
559
|
-
"""
|
|
560
|
-
if x.dtype not in _numeric_dtypes:
|
|
561
|
-
raise TypeError("Only numeric dtypes are allowed in positive")
|
|
562
|
-
return Array._new(np.positive(x._array), device=x.device)
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
def real(x: Array, /) -> Array:
|
|
566
|
-
"""
|
|
567
|
-
Array API compatible wrapper for :py:func:`np.real <numpy.real>`.
|
|
568
|
-
|
|
569
|
-
See its docstring for more information.
|
|
570
|
-
"""
|
|
571
|
-
if x.dtype not in _numeric_dtypes:
|
|
572
|
-
raise TypeError("Only numeric dtypes are allowed in real")
|
|
573
|
-
return Array._new(np.real(x._array), device=x.device)
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
@requires_api_version('2024.12')
|
|
577
|
-
def reciprocal(x: Array, /) -> Array:
|
|
578
|
-
"""
|
|
579
|
-
Array API compatible wrapper for :py:func:`np.reciprocal <numpy.reciprocal>`.
|
|
580
|
-
|
|
581
|
-
See its docstring for more information.
|
|
582
|
-
"""
|
|
583
|
-
if x.dtype not in _floating_dtypes:
|
|
584
|
-
raise TypeError("Only floating-point dtypes are allowed in reciprocal")
|
|
585
|
-
return Array._new(np.reciprocal(x._array), device=x.device)
|
|
586
|
-
|
|
587
|
-
def round(x: Array, /) -> Array:
|
|
588
|
-
"""
|
|
589
|
-
Array API compatible wrapper for :py:func:`np.round <numpy.round>`.
|
|
590
|
-
|
|
591
|
-
See its docstring for more information.
|
|
592
|
-
"""
|
|
593
|
-
if x.dtype not in _numeric_dtypes:
|
|
594
|
-
raise TypeError("Only numeric dtypes are allowed in round")
|
|
595
|
-
return Array._new(np.round(x._array), device=x.device)
|
|
596
|
-
|
|
597
|
-
|
|
598
343
|
def sign(x: Array, /) -> Array:
|
|
599
344
|
"""
|
|
600
345
|
Array API compatible wrapper for :py:func:`np.sign <numpy.sign>`.
|
|
601
346
|
|
|
602
347
|
See its docstring for more information.
|
|
603
348
|
"""
|
|
349
|
+
if not isinstance(x, Array):
|
|
350
|
+
raise TypeError(f"Only Array objects are allowed; got {type(x)}")
|
|
604
351
|
if x.dtype not in _numeric_dtypes:
|
|
605
352
|
raise TypeError("Only numeric dtypes are allowed in sign")
|
|
353
|
+
# Special treatment to work around non-compliant NumPy 1.x behaviour
|
|
606
354
|
if x.dtype in _complex_floating_dtypes:
|
|
607
355
|
return x/abs(x)
|
|
608
356
|
return Array._new(np.sign(x._array), device=x.device)
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
@requires_api_version('2023.12')
|
|
612
|
-
def signbit(x: Array, /) -> Array:
|
|
613
|
-
"""
|
|
614
|
-
Array API compatible wrapper for :py:func:`np.signbit <numpy.signbit>`.
|
|
615
|
-
|
|
616
|
-
See its docstring for more information.
|
|
617
|
-
"""
|
|
618
|
-
if x.dtype not in _real_floating_dtypes:
|
|
619
|
-
raise TypeError("Only real floating-point dtypes are allowed in signbit")
|
|
620
|
-
return Array._new(np.signbit(x._array), device=x.device)
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
def sin(x: Array, /) -> Array:
|
|
624
|
-
"""
|
|
625
|
-
Array API compatible wrapper for :py:func:`np.sin <numpy.sin>`.
|
|
626
|
-
|
|
627
|
-
See its docstring for more information.
|
|
628
|
-
"""
|
|
629
|
-
if x.dtype not in _floating_dtypes:
|
|
630
|
-
raise TypeError("Only floating-point dtypes are allowed in sin")
|
|
631
|
-
return Array._new(np.sin(x._array), device=x.device)
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
def sinh(x: Array, /) -> Array:
|
|
635
|
-
"""
|
|
636
|
-
Array API compatible wrapper for :py:func:`np.sinh <numpy.sinh>`.
|
|
637
|
-
|
|
638
|
-
See its docstring for more information.
|
|
639
|
-
"""
|
|
640
|
-
if x.dtype not in _floating_dtypes:
|
|
641
|
-
raise TypeError("Only floating-point dtypes are allowed in sinh")
|
|
642
|
-
return Array._new(np.sinh(x._array), device=x.device)
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
def square(x: Array, /) -> Array:
|
|
646
|
-
"""
|
|
647
|
-
Array API compatible wrapper for :py:func:`np.square <numpy.square>`.
|
|
648
|
-
|
|
649
|
-
See its docstring for more information.
|
|
650
|
-
"""
|
|
651
|
-
if x.dtype not in _numeric_dtypes:
|
|
652
|
-
raise TypeError("Only numeric dtypes are allowed in square")
|
|
653
|
-
return Array._new(np.square(x._array), device=x.device)
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
def sqrt(x: Array, /) -> Array:
|
|
657
|
-
"""
|
|
658
|
-
Array API compatible wrapper for :py:func:`np.sqrt <numpy.sqrt>`.
|
|
659
|
-
|
|
660
|
-
See its docstring for more information.
|
|
661
|
-
"""
|
|
662
|
-
if x.dtype not in _floating_dtypes:
|
|
663
|
-
raise TypeError("Only floating-point dtypes are allowed in sqrt")
|
|
664
|
-
return Array._new(np.sqrt(x._array), device=x.device)
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
def tan(x: Array, /) -> Array:
|
|
668
|
-
"""
|
|
669
|
-
Array API compatible wrapper for :py:func:`np.tan <numpy.tan>`.
|
|
670
|
-
|
|
671
|
-
See its docstring for more information.
|
|
672
|
-
"""
|
|
673
|
-
if x.dtype not in _floating_dtypes:
|
|
674
|
-
raise TypeError("Only floating-point dtypes are allowed in tan")
|
|
675
|
-
return Array._new(np.tan(x._array), device=x.device)
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
def tanh(x: Array, /) -> Array:
|
|
679
|
-
"""
|
|
680
|
-
Array API compatible wrapper for :py:func:`np.tanh <numpy.tanh>`.
|
|
681
|
-
|
|
682
|
-
See its docstring for more information.
|
|
683
|
-
"""
|
|
684
|
-
if x.dtype not in _floating_dtypes:
|
|
685
|
-
raise TypeError("Only floating-point dtypes are allowed in tanh")
|
|
686
|
-
return Array._new(np.tanh(x._array), device=x.device)
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
def trunc(x: Array, /) -> Array:
|
|
690
|
-
"""
|
|
691
|
-
Array API compatible wrapper for :py:func:`np.trunc <numpy.trunc>`.
|
|
692
|
-
|
|
693
|
-
See its docstring for more information.
|
|
694
|
-
"""
|
|
695
|
-
if x.dtype not in _real_numeric_dtypes:
|
|
696
|
-
raise TypeError("Only real numeric dtypes are allowed in trunc")
|
|
697
|
-
if x.dtype in _integer_dtypes:
|
|
698
|
-
# Note: The return dtype of trunc is the same as the input
|
|
699
|
-
return x
|
|
700
|
-
return Array._new(np.trunc(x._array), device=x.device)
|