Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- lib/python3.12/site-packages/numpy/_core/__init__.py +4 -0
- lib/python3.12/site-packages/numpy/_core/__init__.pyi +0 -0
- lib/python3.12/site-packages/numpy/_core/__pycache__/__init__.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/_core/__pycache__/_dtype.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/_core/__pycache__/_internal.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/_core/__pycache__/_multiarray_umath.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/_core/__pycache__/multiarray.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/_core/__pycache__/umath.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/_core/_dtype.py +6 -0
- lib/python3.12/site-packages/numpy/_core/_dtype_ctypes.py +6 -0
- lib/python3.12/site-packages/numpy/_core/_internal.py +6 -0
- lib/python3.12/site-packages/numpy/_core/_multiarray_umath.py +6 -0
- lib/python3.12/site-packages/numpy/_core/multiarray.py +6 -0
- lib/python3.12/site-packages/numpy/_core/umath.py +6 -0
- lib/python3.12/site-packages/numpy/array_api/__init__.py +387 -0
- lib/python3.12/site-packages/numpy/array_api/__pycache__/_data_type_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/__pycache__/_elementwise_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/__pycache__/_indexing_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/__pycache__/_manipulation_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/__pycache__/_searching_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/__pycache__/linalg.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/_array_object.py +1133 -0
- lib/python3.12/site-packages/numpy/array_api/_constants.py +7 -0
- lib/python3.12/site-packages/numpy/array_api/_creation_functions.py +351 -0
- lib/python3.12/site-packages/numpy/array_api/_data_type_functions.py +197 -0
- lib/python3.12/site-packages/numpy/array_api/_dtypes.py +180 -0
- lib/python3.12/site-packages/numpy/array_api/_elementwise_functions.py +765 -0
- lib/python3.12/site-packages/numpy/array_api/_indexing_functions.py +20 -0
- lib/python3.12/site-packages/numpy/array_api/_manipulation_functions.py +112 -0
- lib/python3.12/site-packages/numpy/array_api/_searching_functions.py +51 -0
- lib/python3.12/site-packages/numpy/array_api/_set_functions.py +106 -0
- lib/python3.12/site-packages/numpy/array_api/_sorting_functions.py +54 -0
- lib/python3.12/site-packages/numpy/array_api/_statistical_functions.py +122 -0
- lib/python3.12/site-packages/numpy/array_api/_typing.py +76 -0
- lib/python3.12/site-packages/numpy/array_api/_utility_functions.py +37 -0
- lib/python3.12/site-packages/numpy/array_api/linalg.py +466 -0
- lib/python3.12/site-packages/numpy/array_api/setup.py +12 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__init__.py +7 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_array_object.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_creation_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_data_type_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_elementwise_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_indexing_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_manipulation_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_set_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_sorting_functions.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_validation.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/numpy/array_api/tests/test_array_object.py +395 -0
lib/python3.12/site-packages/numpy/_core/__init__.py
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
This private module only contains stubs for interoperability with
|
| 3 |
+
NumPy 2.0 pickled arrays. It may not be used by the end user.
|
| 4 |
+
"""
|
lib/python3.12/site-packages/numpy/_core/__init__.pyi
ADDED
|
File without changes
|
lib/python3.12/site-packages/numpy/_core/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (336 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/_core/__pycache__/_dtype.cpython-312.pyc
ADDED
|
Binary file (399 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-312.pyc
ADDED
|
Binary file (415 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/_core/__pycache__/_internal.cpython-312.pyc
ADDED
|
Binary file (407 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/_core/__pycache__/_multiarray_umath.cpython-312.pyc
ADDED
|
Binary file (425 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/_core/__pycache__/multiarray.cpython-312.pyc
ADDED
|
Binary file (409 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/_core/__pycache__/umath.cpython-312.pyc
ADDED
|
Binary file (396 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/_core/_dtype.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy.core import _dtype
|
| 2 |
+
|
| 3 |
+
_globals = globals()
|
| 4 |
+
|
| 5 |
+
for item in _dtype.__dir__():
|
| 6 |
+
_globals[item] = getattr(_dtype, item)
|
lib/python3.12/site-packages/numpy/_core/_dtype_ctypes.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy.core import _dtype_ctypes
|
| 2 |
+
|
| 3 |
+
_globals = globals()
|
| 4 |
+
|
| 5 |
+
for item in _dtype_ctypes.__dir__():
|
| 6 |
+
_globals[item] = getattr(_dtype_ctypes, item)
|
lib/python3.12/site-packages/numpy/_core/_internal.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy.core import _internal
|
| 2 |
+
|
| 3 |
+
_globals = globals()
|
| 4 |
+
|
| 5 |
+
for item in _internal.__dir__():
|
| 6 |
+
_globals[item] = getattr(_internal, item)
|
lib/python3.12/site-packages/numpy/_core/_multiarray_umath.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy.core import _multiarray_umath
|
| 2 |
+
|
| 3 |
+
_globals = globals()
|
| 4 |
+
|
| 5 |
+
for item in _multiarray_umath.__dir__():
|
| 6 |
+
_globals[item] = getattr(_multiarray_umath, item)
|
lib/python3.12/site-packages/numpy/_core/multiarray.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy.core import multiarray
|
| 2 |
+
|
| 3 |
+
_globals = globals()
|
| 4 |
+
|
| 5 |
+
for item in multiarray.__dir__():
|
| 6 |
+
_globals[item] = getattr(multiarray, item)
|
lib/python3.12/site-packages/numpy/_core/umath.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from numpy.core import umath
|
| 2 |
+
|
| 3 |
+
_globals = globals()
|
| 4 |
+
|
| 5 |
+
for item in umath.__dir__():
|
| 6 |
+
_globals[item] = getattr(umath, item)
|
lib/python3.12/site-packages/numpy/array_api/__init__.py
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
A NumPy sub-namespace that conforms to the Python array API standard.
|
| 3 |
+
|
| 4 |
+
This submodule accompanies NEP 47, which proposes its inclusion in NumPy. It
|
| 5 |
+
is still considered experimental, and will issue a warning when imported.
|
| 6 |
+
|
| 7 |
+
This is a proof-of-concept namespace that wraps the corresponding NumPy
|
| 8 |
+
functions to give a conforming implementation of the Python array API standard
|
| 9 |
+
(https://data-apis.github.io/array-api/latest/). The standard is currently in
|
| 10 |
+
an RFC phase and comments on it are both welcome and encouraged. Comments
|
| 11 |
+
should be made either at https://github.com/data-apis/array-api or at
|
| 12 |
+
https://github.com/data-apis/consortium-feedback/discussions.
|
| 13 |
+
|
| 14 |
+
NumPy already follows the proposed spec for the most part, so this module
|
| 15 |
+
serves mostly as a thin wrapper around it. However, NumPy also implements a
|
| 16 |
+
lot of behavior that is not included in the spec, so this serves as a
|
| 17 |
+
restricted subset of the API. Only those functions that are part of the spec
|
| 18 |
+
are included in this namespace, and all functions are given with the exact
|
| 19 |
+
signature given in the spec, including the use of position-only arguments, and
|
| 20 |
+
omitting any extra keyword arguments implemented by NumPy but not part of the
|
| 21 |
+
spec. The behavior of some functions is also modified from the NumPy behavior
|
| 22 |
+
to conform to the standard. Note that the underlying array object itself is
|
| 23 |
+
wrapped in a wrapper Array() class, but is otherwise unchanged. This submodule
|
| 24 |
+
is implemented in pure Python with no C extensions.
|
| 25 |
+
|
| 26 |
+
The array API spec is designed as a "minimal API subset" and explicitly allows
|
| 27 |
+
libraries to include behaviors not specified by it. But users of this module
|
| 28 |
+
that intend to write portable code should be aware that only those behaviors
|
| 29 |
+
that are listed in the spec are guaranteed to be implemented across libraries.
|
| 30 |
+
Consequently, the NumPy implementation was chosen to be both conforming and
|
| 31 |
+
minimal, so that users can use this implementation of the array API namespace
|
| 32 |
+
and be sure that behaviors that it defines will be available in conforming
|
| 33 |
+
namespaces from other libraries.
|
| 34 |
+
|
| 35 |
+
A few notes about the current state of this submodule:
|
| 36 |
+
|
| 37 |
+
- There is a test suite that tests modules against the array API standard at
|
| 38 |
+
https://github.com/data-apis/array-api-tests. The test suite is still a work
|
| 39 |
+
in progress, but the existing tests pass on this module, with a few
|
| 40 |
+
exceptions:
|
| 41 |
+
|
| 42 |
+
- DLPack support (see https://github.com/data-apis/array-api/pull/106) is
|
| 43 |
+
not included here, as it requires a full implementation in NumPy proper
|
| 44 |
+
first.
|
| 45 |
+
|
| 46 |
+
The test suite is not yet complete, and even the tests that exist are not
|
| 47 |
+
guaranteed to give a comprehensive coverage of the spec. Therefore, when
|
| 48 |
+
reviewing and using this submodule, you should refer to the standard
|
| 49 |
+
documents themselves. There are some tests in numpy.array_api.tests, but
|
| 50 |
+
they primarily focus on things that are not tested by the official array API
|
| 51 |
+
test suite.
|
| 52 |
+
|
| 53 |
+
- There is a custom array object, numpy.array_api.Array, which is returned by
|
| 54 |
+
all functions in this module. All functions in the array API namespace
|
| 55 |
+
implicitly assume that they will only receive this object as input. The only
|
| 56 |
+
way to create instances of this object is to use one of the array creation
|
| 57 |
+
functions. It does not have a public constructor on the object itself. The
|
| 58 |
+
object is a small wrapper class around numpy.ndarray. The main purpose of it
|
| 59 |
+
is to restrict the namespace of the array object to only those dtypes and
|
| 60 |
+
only those methods that are required by the spec, as well as to limit/change
|
| 61 |
+
certain behavior that differs in the spec. In particular:
|
| 62 |
+
|
| 63 |
+
- The array API namespace does not have scalar objects, only 0-D arrays.
|
| 64 |
+
Operations on Array that would create a scalar in NumPy create a 0-D
|
| 65 |
+
array.
|
| 66 |
+
|
| 67 |
+
- Indexing: Only a subset of indices supported by NumPy are required by the
|
| 68 |
+
spec. The Array object restricts indexing to only allow those types of
|
| 69 |
+
indices that are required by the spec. See the docstring of the
|
| 70 |
+
numpy.array_api.Array._validate_indices helper function for more
|
| 71 |
+
information.
|
| 72 |
+
|
| 73 |
+
- Type promotion: Some type promotion rules are different in the spec. In
|
| 74 |
+
particular, the spec does not have any value-based casting. The spec also
|
| 75 |
+
does not require cross-kind casting, like integer -> floating-point. Only
|
| 76 |
+
those promotions that are explicitly required by the array API
|
| 77 |
+
specification are allowed in this module. See NEP 47 for more info.
|
| 78 |
+
|
| 79 |
+
- Functions do not automatically call asarray() on their input, and will not
|
| 80 |
+
work if the input type is not Array. The exception is array creation
|
| 81 |
+
functions, and Python operators on the Array object, which accept Python
|
| 82 |
+
scalars of the same type as the array dtype.
|
| 83 |
+
|
| 84 |
+
- All functions include type annotations, corresponding to those given in the
|
| 85 |
+
spec (see _typing.py for definitions of some custom types). These do not
|
| 86 |
+
currently fully pass mypy due to some limitations in mypy.
|
| 87 |
+
|
| 88 |
+
- Dtype objects are just the NumPy dtype objects, e.g., float64 =
|
| 89 |
+
np.dtype('float64'). The spec does not require any behavior on these dtype
|
| 90 |
+
objects other than that they be accessible by name and be comparable by
|
| 91 |
+
equality, but it was considered too much extra complexity to create custom
|
| 92 |
+
objects to represent dtypes.
|
| 93 |
+
|
| 94 |
+
- All places where the implementations in this submodule are known to deviate
|
| 95 |
+
from their corresponding functions in NumPy are marked with "# Note:"
|
| 96 |
+
comments.
|
| 97 |
+
|
| 98 |
+
Still TODO in this module are:
|
| 99 |
+
|
| 100 |
+
- DLPack support for numpy.ndarray is still in progress. See
|
| 101 |
+
https://github.com/numpy/numpy/pull/19083.
|
| 102 |
+
|
| 103 |
+
- The copy=False keyword argument to asarray() is not yet implemented. This
|
| 104 |
+
requires support in numpy.asarray() first.
|
| 105 |
+
|
| 106 |
+
- Some functions are not yet fully tested in the array API test suite, and may
|
| 107 |
+
require updates that are not yet known until the tests are written.
|
| 108 |
+
|
| 109 |
+
- The spec is still in an RFC phase and may still have minor updates, which
|
| 110 |
+
will need to be reflected here.
|
| 111 |
+
|
| 112 |
+
- Complex number support in array API spec is planned but not yet finalized,
|
| 113 |
+
as are the fft extension and certain linear algebra functions such as eig
|
| 114 |
+
that require complex dtypes.
|
| 115 |
+
|
| 116 |
+
"""
|
| 117 |
+
|
| 118 |
+
import warnings
|
| 119 |
+
|
| 120 |
+
warnings.warn(
|
| 121 |
+
"The numpy.array_api submodule is still experimental. See NEP 47.", stacklevel=2
|
| 122 |
+
)
|
| 123 |
+
|
| 124 |
+
__array_api_version__ = "2022.12"
|
| 125 |
+
|
| 126 |
+
__all__ = ["__array_api_version__"]
|
| 127 |
+
|
| 128 |
+
from ._constants import e, inf, nan, pi, newaxis
|
| 129 |
+
|
| 130 |
+
__all__ += ["e", "inf", "nan", "pi", "newaxis"]
|
| 131 |
+
|
| 132 |
+
from ._creation_functions import (
|
| 133 |
+
asarray,
|
| 134 |
+
arange,
|
| 135 |
+
empty,
|
| 136 |
+
empty_like,
|
| 137 |
+
eye,
|
| 138 |
+
from_dlpack,
|
| 139 |
+
full,
|
| 140 |
+
full_like,
|
| 141 |
+
linspace,
|
| 142 |
+
meshgrid,
|
| 143 |
+
ones,
|
| 144 |
+
ones_like,
|
| 145 |
+
tril,
|
| 146 |
+
triu,
|
| 147 |
+
zeros,
|
| 148 |
+
zeros_like,
|
| 149 |
+
)
|
| 150 |
+
|
| 151 |
+
__all__ += [
|
| 152 |
+
"asarray",
|
| 153 |
+
"arange",
|
| 154 |
+
"empty",
|
| 155 |
+
"empty_like",
|
| 156 |
+
"eye",
|
| 157 |
+
"from_dlpack",
|
| 158 |
+
"full",
|
| 159 |
+
"full_like",
|
| 160 |
+
"linspace",
|
| 161 |
+
"meshgrid",
|
| 162 |
+
"ones",
|
| 163 |
+
"ones_like",
|
| 164 |
+
"tril",
|
| 165 |
+
"triu",
|
| 166 |
+
"zeros",
|
| 167 |
+
"zeros_like",
|
| 168 |
+
]
|
| 169 |
+
|
| 170 |
+
from ._data_type_functions import (
|
| 171 |
+
astype,
|
| 172 |
+
broadcast_arrays,
|
| 173 |
+
broadcast_to,
|
| 174 |
+
can_cast,
|
| 175 |
+
finfo,
|
| 176 |
+
isdtype,
|
| 177 |
+
iinfo,
|
| 178 |
+
result_type,
|
| 179 |
+
)
|
| 180 |
+
|
| 181 |
+
__all__ += [
|
| 182 |
+
"astype",
|
| 183 |
+
"broadcast_arrays",
|
| 184 |
+
"broadcast_to",
|
| 185 |
+
"can_cast",
|
| 186 |
+
"finfo",
|
| 187 |
+
"iinfo",
|
| 188 |
+
"result_type",
|
| 189 |
+
]
|
| 190 |
+
|
| 191 |
+
from ._dtypes import (
|
| 192 |
+
int8,
|
| 193 |
+
int16,
|
| 194 |
+
int32,
|
| 195 |
+
int64,
|
| 196 |
+
uint8,
|
| 197 |
+
uint16,
|
| 198 |
+
uint32,
|
| 199 |
+
uint64,
|
| 200 |
+
float32,
|
| 201 |
+
float64,
|
| 202 |
+
complex64,
|
| 203 |
+
complex128,
|
| 204 |
+
bool,
|
| 205 |
+
)
|
| 206 |
+
|
| 207 |
+
__all__ += [
|
| 208 |
+
"int8",
|
| 209 |
+
"int16",
|
| 210 |
+
"int32",
|
| 211 |
+
"int64",
|
| 212 |
+
"uint8",
|
| 213 |
+
"uint16",
|
| 214 |
+
"uint32",
|
| 215 |
+
"uint64",
|
| 216 |
+
"float32",
|
| 217 |
+
"float64",
|
| 218 |
+
"bool",
|
| 219 |
+
]
|
| 220 |
+
|
| 221 |
+
from ._elementwise_functions import (
|
| 222 |
+
abs,
|
| 223 |
+
acos,
|
| 224 |
+
acosh,
|
| 225 |
+
add,
|
| 226 |
+
asin,
|
| 227 |
+
asinh,
|
| 228 |
+
atan,
|
| 229 |
+
atan2,
|
| 230 |
+
atanh,
|
| 231 |
+
bitwise_and,
|
| 232 |
+
bitwise_left_shift,
|
| 233 |
+
bitwise_invert,
|
| 234 |
+
bitwise_or,
|
| 235 |
+
bitwise_right_shift,
|
| 236 |
+
bitwise_xor,
|
| 237 |
+
ceil,
|
| 238 |
+
conj,
|
| 239 |
+
cos,
|
| 240 |
+
cosh,
|
| 241 |
+
divide,
|
| 242 |
+
equal,
|
| 243 |
+
exp,
|
| 244 |
+
expm1,
|
| 245 |
+
floor,
|
| 246 |
+
floor_divide,
|
| 247 |
+
greater,
|
| 248 |
+
greater_equal,
|
| 249 |
+
imag,
|
| 250 |
+
isfinite,
|
| 251 |
+
isinf,
|
| 252 |
+
isnan,
|
| 253 |
+
less,
|
| 254 |
+
less_equal,
|
| 255 |
+
log,
|
| 256 |
+
log1p,
|
| 257 |
+
log2,
|
| 258 |
+
log10,
|
| 259 |
+
logaddexp,
|
| 260 |
+
logical_and,
|
| 261 |
+
logical_not,
|
| 262 |
+
logical_or,
|
| 263 |
+
logical_xor,
|
| 264 |
+
multiply,
|
| 265 |
+
negative,
|
| 266 |
+
not_equal,
|
| 267 |
+
positive,
|
| 268 |
+
pow,
|
| 269 |
+
real,
|
| 270 |
+
remainder,
|
| 271 |
+
round,
|
| 272 |
+
sign,
|
| 273 |
+
sin,
|
| 274 |
+
sinh,
|
| 275 |
+
square,
|
| 276 |
+
sqrt,
|
| 277 |
+
subtract,
|
| 278 |
+
tan,
|
| 279 |
+
tanh,
|
| 280 |
+
trunc,
|
| 281 |
+
)
|
| 282 |
+
|
| 283 |
+
__all__ += [
|
| 284 |
+
"abs",
|
| 285 |
+
"acos",
|
| 286 |
+
"acosh",
|
| 287 |
+
"add",
|
| 288 |
+
"asin",
|
| 289 |
+
"asinh",
|
| 290 |
+
"atan",
|
| 291 |
+
"atan2",
|
| 292 |
+
"atanh",
|
| 293 |
+
"bitwise_and",
|
| 294 |
+
"bitwise_left_shift",
|
| 295 |
+
"bitwise_invert",
|
| 296 |
+
"bitwise_or",
|
| 297 |
+
"bitwise_right_shift",
|
| 298 |
+
"bitwise_xor",
|
| 299 |
+
"ceil",
|
| 300 |
+
"cos",
|
| 301 |
+
"cosh",
|
| 302 |
+
"divide",
|
| 303 |
+
"equal",
|
| 304 |
+
"exp",
|
| 305 |
+
"expm1",
|
| 306 |
+
"floor",
|
| 307 |
+
"floor_divide",
|
| 308 |
+
"greater",
|
| 309 |
+
"greater_equal",
|
| 310 |
+
"isfinite",
|
| 311 |
+
"isinf",
|
| 312 |
+
"isnan",
|
| 313 |
+
"less",
|
| 314 |
+
"less_equal",
|
| 315 |
+
"log",
|
| 316 |
+
"log1p",
|
| 317 |
+
"log2",
|
| 318 |
+
"log10",
|
| 319 |
+
"logaddexp",
|
| 320 |
+
"logical_and",
|
| 321 |
+
"logical_not",
|
| 322 |
+
"logical_or",
|
| 323 |
+
"logical_xor",
|
| 324 |
+
"multiply",
|
| 325 |
+
"negative",
|
| 326 |
+
"not_equal",
|
| 327 |
+
"positive",
|
| 328 |
+
"pow",
|
| 329 |
+
"remainder",
|
| 330 |
+
"round",
|
| 331 |
+
"sign",
|
| 332 |
+
"sin",
|
| 333 |
+
"sinh",
|
| 334 |
+
"square",
|
| 335 |
+
"sqrt",
|
| 336 |
+
"subtract",
|
| 337 |
+
"tan",
|
| 338 |
+
"tanh",
|
| 339 |
+
"trunc",
|
| 340 |
+
]
|
| 341 |
+
|
| 342 |
+
from ._indexing_functions import take
|
| 343 |
+
|
| 344 |
+
__all__ += ["take"]
|
| 345 |
+
|
| 346 |
+
# linalg is an extension in the array API spec, which is a sub-namespace. Only
|
| 347 |
+
# a subset of functions in it are imported into the top-level namespace.
|
| 348 |
+
from . import linalg
|
| 349 |
+
|
| 350 |
+
__all__ += ["linalg"]
|
| 351 |
+
|
| 352 |
+
from .linalg import matmul, tensordot, matrix_transpose, vecdot
|
| 353 |
+
|
| 354 |
+
__all__ += ["matmul", "tensordot", "matrix_transpose", "vecdot"]
|
| 355 |
+
|
| 356 |
+
from ._manipulation_functions import (
|
| 357 |
+
concat,
|
| 358 |
+
expand_dims,
|
| 359 |
+
flip,
|
| 360 |
+
permute_dims,
|
| 361 |
+
reshape,
|
| 362 |
+
roll,
|
| 363 |
+
squeeze,
|
| 364 |
+
stack,
|
| 365 |
+
)
|
| 366 |
+
|
| 367 |
+
__all__ += ["concat", "expand_dims", "flip", "permute_dims", "reshape", "roll", "squeeze", "stack"]
|
| 368 |
+
|
| 369 |
+
from ._searching_functions import argmax, argmin, nonzero, where
|
| 370 |
+
|
| 371 |
+
__all__ += ["argmax", "argmin", "nonzero", "where"]
|
| 372 |
+
|
| 373 |
+
from ._set_functions import unique_all, unique_counts, unique_inverse, unique_values
|
| 374 |
+
|
| 375 |
+
__all__ += ["unique_all", "unique_counts", "unique_inverse", "unique_values"]
|
| 376 |
+
|
| 377 |
+
from ._sorting_functions import argsort, sort
|
| 378 |
+
|
| 379 |
+
__all__ += ["argsort", "sort"]
|
| 380 |
+
|
| 381 |
+
from ._statistical_functions import max, mean, min, prod, std, sum, var
|
| 382 |
+
|
| 383 |
+
__all__ += ["max", "mean", "min", "prod", "std", "sum", "var"]
|
| 384 |
+
|
| 385 |
+
from ._utility_functions import all, any
|
| 386 |
+
|
| 387 |
+
__all__ += ["all", "any"]
|
lib/python3.12/site-packages/numpy/array_api/__pycache__/_data_type_functions.cpython-312.pyc
ADDED
|
Binary file (7.82 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/__pycache__/_elementwise_functions.cpython-312.pyc
ADDED
|
Binary file (35.8 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/__pycache__/_indexing_functions.cpython-312.pyc
ADDED
|
Binary file (1.28 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/__pycache__/_manipulation_functions.cpython-312.pyc
ADDED
|
Binary file (5.04 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/__pycache__/_searching_functions.cpython-312.pyc
ADDED
|
Binary file (3.01 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/__pycache__/linalg.cpython-312.pyc
ADDED
|
Binary file (21.1 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/_array_object.py
ADDED
|
@@ -0,0 +1,1133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Wrapper class around the ndarray object for the array API standard.
|
| 3 |
+
|
| 4 |
+
The array API standard defines some behaviors differently than ndarray, in
|
| 5 |
+
particular, type promotion rules are different (the standard has no
|
| 6 |
+
value-based casting). The standard also specifies a more limited subset of
|
| 7 |
+
array methods and functionalities than are implemented on ndarray. Since the
|
| 8 |
+
goal of the array_api namespace is to be a minimal implementation of the array
|
| 9 |
+
API standard, we need to define a separate wrapper class for the array_api
|
| 10 |
+
namespace.
|
| 11 |
+
|
| 12 |
+
The standard compliant class is only a wrapper class. It is *not* a subclass
|
| 13 |
+
of ndarray.
|
| 14 |
+
"""
|
| 15 |
+
|
| 16 |
+
from __future__ import annotations
|
| 17 |
+
|
| 18 |
+
import operator
|
| 19 |
+
from enum import IntEnum
|
| 20 |
+
from ._creation_functions import asarray
|
| 21 |
+
from ._dtypes import (
|
| 22 |
+
_all_dtypes,
|
| 23 |
+
_boolean_dtypes,
|
| 24 |
+
_integer_dtypes,
|
| 25 |
+
_integer_or_boolean_dtypes,
|
| 26 |
+
_floating_dtypes,
|
| 27 |
+
_complex_floating_dtypes,
|
| 28 |
+
_numeric_dtypes,
|
| 29 |
+
_result_type,
|
| 30 |
+
_dtype_categories,
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
from typing import TYPE_CHECKING, Optional, Tuple, Union, Any, SupportsIndex
|
| 34 |
+
import types
|
| 35 |
+
|
| 36 |
+
if TYPE_CHECKING:
|
| 37 |
+
from ._typing import Any, PyCapsule, Device, Dtype
|
| 38 |
+
import numpy.typing as npt
|
| 39 |
+
|
| 40 |
+
import numpy as np
|
| 41 |
+
|
| 42 |
+
from numpy import array_api
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class Array:
|
| 46 |
+
"""
|
| 47 |
+
n-d array object for the array API namespace.
|
| 48 |
+
|
| 49 |
+
See the docstring of :py:obj:`np.ndarray <numpy.ndarray>` for more
|
| 50 |
+
information.
|
| 51 |
+
|
| 52 |
+
This is a wrapper around numpy.ndarray that restricts the usage to only
|
| 53 |
+
those things that are required by the array API namespace. Note,
|
| 54 |
+
attributes on this object that start with a single underscore are not part
|
| 55 |
+
of the API specification and should only be used internally. This object
|
| 56 |
+
should not be constructed directly. Rather, use one of the creation
|
| 57 |
+
functions, such as asarray().
|
| 58 |
+
|
| 59 |
+
"""
|
| 60 |
+
_array: np.ndarray[Any, Any]
|
| 61 |
+
|
| 62 |
+
# Use a custom constructor instead of __init__, as manually initializing
|
| 63 |
+
# this class is not supported API.
|
| 64 |
+
@classmethod
|
| 65 |
+
def _new(cls, x, /):
|
| 66 |
+
"""
|
| 67 |
+
This is a private method for initializing the array API Array
|
| 68 |
+
object.
|
| 69 |
+
|
| 70 |
+
Functions outside of the array_api submodule should not use this
|
| 71 |
+
method. Use one of the creation functions instead, such as
|
| 72 |
+
``asarray``.
|
| 73 |
+
|
| 74 |
+
"""
|
| 75 |
+
obj = super().__new__(cls)
|
| 76 |
+
# Note: The spec does not have array scalars, only 0-D arrays.
|
| 77 |
+
if isinstance(x, np.generic):
|
| 78 |
+
# Convert the array scalar to a 0-D array
|
| 79 |
+
x = np.asarray(x)
|
| 80 |
+
if x.dtype not in _all_dtypes:
|
| 81 |
+
raise TypeError(
|
| 82 |
+
f"The array_api namespace does not support the dtype '{x.dtype}'"
|
| 83 |
+
)
|
| 84 |
+
obj._array = x
|
| 85 |
+
return obj
|
| 86 |
+
|
| 87 |
+
# Prevent Array() from working
|
| 88 |
+
def __new__(cls, *args, **kwargs):
|
| 89 |
+
raise TypeError(
|
| 90 |
+
"The array_api Array object should not be instantiated directly. Use an array creation function, such as asarray(), instead."
|
| 91 |
+
)
|
| 92 |
+
|
| 93 |
+
# These functions are not required by the spec, but are implemented for
|
| 94 |
+
# the sake of usability.
|
| 95 |
+
|
| 96 |
+
def __str__(self: Array, /) -> str:
|
| 97 |
+
"""
|
| 98 |
+
Performs the operation __str__.
|
| 99 |
+
"""
|
| 100 |
+
return self._array.__str__().replace("array", "Array")
|
| 101 |
+
|
| 102 |
+
def __repr__(self: Array, /) -> str:
|
| 103 |
+
"""
|
| 104 |
+
Performs the operation __repr__.
|
| 105 |
+
"""
|
| 106 |
+
suffix = f", dtype={self.dtype.name})"
|
| 107 |
+
if 0 in self.shape:
|
| 108 |
+
prefix = "empty("
|
| 109 |
+
mid = str(self.shape)
|
| 110 |
+
else:
|
| 111 |
+
prefix = "Array("
|
| 112 |
+
mid = np.array2string(self._array, separator=', ', prefix=prefix, suffix=suffix)
|
| 113 |
+
return prefix + mid + suffix
|
| 114 |
+
|
| 115 |
+
# This function is not required by the spec, but we implement it here for
|
| 116 |
+
# convenience so that np.asarray(np.array_api.Array) will work.
|
| 117 |
+
def __array__(self, dtype: None | np.dtype[Any] = None) -> npt.NDArray[Any]:
|
| 118 |
+
"""
|
| 119 |
+
Warning: this method is NOT part of the array API spec. Implementers
|
| 120 |
+
of other libraries need not include it, and users should not assume it
|
| 121 |
+
will be present in other implementations.
|
| 122 |
+
|
| 123 |
+
"""
|
| 124 |
+
return np.asarray(self._array, dtype=dtype)
|
| 125 |
+
|
| 126 |
+
# These are various helper functions to make the array behavior match the
|
| 127 |
+
# spec in places where it either deviates from or is more strict than
|
| 128 |
+
# NumPy behavior
|
| 129 |
+
|
| 130 |
+
def _check_allowed_dtypes(self, other: bool | int | float | Array, dtype_category: str, op: str) -> Array:
|
| 131 |
+
"""
|
| 132 |
+
Helper function for operators to only allow specific input dtypes
|
| 133 |
+
|
| 134 |
+
Use like
|
| 135 |
+
|
| 136 |
+
other = self._check_allowed_dtypes(other, 'numeric', '__add__')
|
| 137 |
+
if other is NotImplemented:
|
| 138 |
+
return other
|
| 139 |
+
"""
|
| 140 |
+
|
| 141 |
+
if self.dtype not in _dtype_categories[dtype_category]:
|
| 142 |
+
raise TypeError(f"Only {dtype_category} dtypes are allowed in {op}")
|
| 143 |
+
if isinstance(other, (int, complex, float, bool)):
|
| 144 |
+
other = self._promote_scalar(other)
|
| 145 |
+
elif isinstance(other, Array):
|
| 146 |
+
if other.dtype not in _dtype_categories[dtype_category]:
|
| 147 |
+
raise TypeError(f"Only {dtype_category} dtypes are allowed in {op}")
|
| 148 |
+
else:
|
| 149 |
+
return NotImplemented
|
| 150 |
+
|
| 151 |
+
# This will raise TypeError for type combinations that are not allowed
|
| 152 |
+
# to promote in the spec (even if the NumPy array operator would
|
| 153 |
+
# promote them).
|
| 154 |
+
res_dtype = _result_type(self.dtype, other.dtype)
|
| 155 |
+
if op.startswith("__i"):
|
| 156 |
+
# Note: NumPy will allow in-place operators in some cases where
|
| 157 |
+
# the type promoted operator does not match the left-hand side
|
| 158 |
+
# operand. For example,
|
| 159 |
+
|
| 160 |
+
# >>> a = np.array(1, dtype=np.int8)
|
| 161 |
+
# >>> a += np.array(1, dtype=np.int16)
|
| 162 |
+
|
| 163 |
+
# The spec explicitly disallows this.
|
| 164 |
+
if res_dtype != self.dtype:
|
| 165 |
+
raise TypeError(
|
| 166 |
+
f"Cannot perform {op} with dtypes {self.dtype} and {other.dtype}"
|
| 167 |
+
)
|
| 168 |
+
|
| 169 |
+
return other
|
| 170 |
+
|
| 171 |
+
# Helper function to match the type promotion rules in the spec
|
| 172 |
+
def _promote_scalar(self, scalar):
|
| 173 |
+
"""
|
| 174 |
+
Returns a promoted version of a Python scalar appropriate for use with
|
| 175 |
+
operations on self.
|
| 176 |
+
|
| 177 |
+
This may raise an OverflowError in cases where the scalar is an
|
| 178 |
+
integer that is too large to fit in a NumPy integer dtype, or
|
| 179 |
+
TypeError when the scalar type is incompatible with the dtype of self.
|
| 180 |
+
"""
|
| 181 |
+
# Note: Only Python scalar types that match the array dtype are
|
| 182 |
+
# allowed.
|
| 183 |
+
if isinstance(scalar, bool):
|
| 184 |
+
if self.dtype not in _boolean_dtypes:
|
| 185 |
+
raise TypeError(
|
| 186 |
+
"Python bool scalars can only be promoted with bool arrays"
|
| 187 |
+
)
|
| 188 |
+
elif isinstance(scalar, int):
|
| 189 |
+
if self.dtype in _boolean_dtypes:
|
| 190 |
+
raise TypeError(
|
| 191 |
+
"Python int scalars cannot be promoted with bool arrays"
|
| 192 |
+
)
|
| 193 |
+
if self.dtype in _integer_dtypes:
|
| 194 |
+
info = np.iinfo(self.dtype)
|
| 195 |
+
if not (info.min <= scalar <= info.max):
|
| 196 |
+
raise OverflowError(
|
| 197 |
+
"Python int scalars must be within the bounds of the dtype for integer arrays"
|
| 198 |
+
)
|
| 199 |
+
# int + array(floating) is allowed
|
| 200 |
+
elif isinstance(scalar, float):
|
| 201 |
+
if self.dtype not in _floating_dtypes:
|
| 202 |
+
raise TypeError(
|
| 203 |
+
"Python float scalars can only be promoted with floating-point arrays."
|
| 204 |
+
)
|
| 205 |
+
elif isinstance(scalar, complex):
|
| 206 |
+
if self.dtype not in _complex_floating_dtypes:
|
| 207 |
+
raise TypeError(
|
| 208 |
+
"Python complex scalars can only be promoted with complex floating-point arrays."
|
| 209 |
+
)
|
| 210 |
+
else:
|
| 211 |
+
raise TypeError("'scalar' must be a Python scalar")
|
| 212 |
+
|
| 213 |
+
# Note: scalars are unconditionally cast to the same dtype as the
|
| 214 |
+
# array.
|
| 215 |
+
|
| 216 |
+
# Note: the spec only specifies integer-dtype/int promotion
|
| 217 |
+
# behavior for integers within the bounds of the integer dtype.
|
| 218 |
+
# Outside of those bounds we use the default NumPy behavior (either
|
| 219 |
+
# cast or raise OverflowError).
|
| 220 |
+
return Array._new(np.array(scalar, self.dtype))
|
| 221 |
+
|
| 222 |
+
@staticmethod
|
| 223 |
+
def _normalize_two_args(x1, x2) -> Tuple[Array, Array]:
|
| 224 |
+
"""
|
| 225 |
+
Normalize inputs to two arg functions to fix type promotion rules
|
| 226 |
+
|
| 227 |
+
NumPy deviates from the spec type promotion rules in cases where one
|
| 228 |
+
argument is 0-dimensional and the other is not. For example:
|
| 229 |
+
|
| 230 |
+
>>> import numpy as np
|
| 231 |
+
>>> a = np.array([1.0], dtype=np.float32)
|
| 232 |
+
>>> b = np.array(1.0, dtype=np.float64)
|
| 233 |
+
>>> np.add(a, b) # The spec says this should be float64
|
| 234 |
+
array([2.], dtype=float32)
|
| 235 |
+
|
| 236 |
+
To fix this, we add a dimension to the 0-dimension array before passing it
|
| 237 |
+
through. This works because a dimension would be added anyway from
|
| 238 |
+
broadcasting, so the resulting shape is the same, but this prevents NumPy
|
| 239 |
+
from not promoting the dtype.
|
| 240 |
+
"""
|
| 241 |
+
# Another option would be to use signature=(x1.dtype, x2.dtype, None),
|
| 242 |
+
# but that only works for ufuncs, so we would have to call the ufuncs
|
| 243 |
+
# directly in the operator methods. One should also note that this
|
| 244 |
+
# sort of trick wouldn't work for functions like searchsorted, which
|
| 245 |
+
# don't do normal broadcasting, but there aren't any functions like
|
| 246 |
+
# that in the array API namespace.
|
| 247 |
+
if x1.ndim == 0 and x2.ndim != 0:
|
| 248 |
+
# The _array[None] workaround was chosen because it is relatively
|
| 249 |
+
# performant. broadcast_to(x1._array, x2.shape) is much slower. We
|
| 250 |
+
# could also manually type promote x2, but that is more complicated
|
| 251 |
+
# and about the same performance as this.
|
| 252 |
+
x1 = Array._new(x1._array[None])
|
| 253 |
+
elif x2.ndim == 0 and x1.ndim != 0:
|
| 254 |
+
x2 = Array._new(x2._array[None])
|
| 255 |
+
return (x1, x2)
|
| 256 |
+
|
| 257 |
+
# Note: A large fraction of allowed indices are disallowed here (see the
|
| 258 |
+
# docstring below)
|
| 259 |
+
def _validate_index(self, key):
|
| 260 |
+
"""
|
| 261 |
+
Validate an index according to the array API.
|
| 262 |
+
|
| 263 |
+
The array API specification only requires a subset of indices that are
|
| 264 |
+
supported by NumPy. This function will reject any index that is
|
| 265 |
+
allowed by NumPy but not required by the array API specification. We
|
| 266 |
+
always raise ``IndexError`` on such indices (the spec does not require
|
| 267 |
+
any specific behavior on them, but this makes the NumPy array API
|
| 268 |
+
namespace a minimal implementation of the spec). See
|
| 269 |
+
https://data-apis.org/array-api/latest/API_specification/indexing.html
|
| 270 |
+
for the full list of required indexing behavior
|
| 271 |
+
|
| 272 |
+
This function raises IndexError if the index ``key`` is invalid. It
|
| 273 |
+
only raises ``IndexError`` on indices that are not already rejected by
|
| 274 |
+
NumPy, as NumPy will already raise the appropriate error on such
|
| 275 |
+
indices. ``shape`` may be None, in which case, only cases that are
|
| 276 |
+
independent of the array shape are checked.
|
| 277 |
+
|
| 278 |
+
The following cases are allowed by NumPy, but not specified by the array
|
| 279 |
+
API specification:
|
| 280 |
+
|
| 281 |
+
- Indices to not include an implicit ellipsis at the end. That is,
|
| 282 |
+
every axis of an array must be explicitly indexed or an ellipsis
|
| 283 |
+
included. This behaviour is sometimes referred to as flat indexing.
|
| 284 |
+
|
| 285 |
+
- The start and stop of a slice may not be out of bounds. In
|
| 286 |
+
particular, for a slice ``i:j:k`` on an axis of size ``n``, only the
|
| 287 |
+
following are allowed:
|
| 288 |
+
|
| 289 |
+
- ``i`` or ``j`` omitted (``None``).
|
| 290 |
+
- ``-n <= i <= max(0, n - 1)``.
|
| 291 |
+
- For ``k > 0`` or ``k`` omitted (``None``), ``-n <= j <= n``.
|
| 292 |
+
- For ``k < 0``, ``-n - 1 <= j <= max(0, n - 1)``.
|
| 293 |
+
|
| 294 |
+
- Boolean array indices are not allowed as part of a larger tuple
|
| 295 |
+
index.
|
| 296 |
+
|
| 297 |
+
- Integer array indices are not allowed (with the exception of 0-D
|
| 298 |
+
arrays, which are treated the same as scalars).
|
| 299 |
+
|
| 300 |
+
Additionally, it should be noted that indices that would return a
|
| 301 |
+
scalar in NumPy will return a 0-D array. Array scalars are not allowed
|
| 302 |
+
in the specification, only 0-D arrays. This is done in the
|
| 303 |
+
``Array._new`` constructor, not this function.
|
| 304 |
+
|
| 305 |
+
"""
|
| 306 |
+
_key = key if isinstance(key, tuple) else (key,)
|
| 307 |
+
for i in _key:
|
| 308 |
+
if isinstance(i, bool) or not (
|
| 309 |
+
isinstance(i, SupportsIndex) # i.e. ints
|
| 310 |
+
or isinstance(i, slice)
|
| 311 |
+
or i == Ellipsis
|
| 312 |
+
or i is None
|
| 313 |
+
or isinstance(i, Array)
|
| 314 |
+
or isinstance(i, np.ndarray)
|
| 315 |
+
):
|
| 316 |
+
raise IndexError(
|
| 317 |
+
f"Single-axes index {i} has {type(i)=}, but only "
|
| 318 |
+
"integers, slices (:), ellipsis (...), newaxis (None), "
|
| 319 |
+
"zero-dimensional integer arrays and boolean arrays "
|
| 320 |
+
"are specified in the Array API."
|
| 321 |
+
)
|
| 322 |
+
|
| 323 |
+
nonexpanding_key = []
|
| 324 |
+
single_axes = []
|
| 325 |
+
n_ellipsis = 0
|
| 326 |
+
key_has_mask = False
|
| 327 |
+
for i in _key:
|
| 328 |
+
if i is not None:
|
| 329 |
+
nonexpanding_key.append(i)
|
| 330 |
+
if isinstance(i, Array) or isinstance(i, np.ndarray):
|
| 331 |
+
if i.dtype in _boolean_dtypes:
|
| 332 |
+
key_has_mask = True
|
| 333 |
+
single_axes.append(i)
|
| 334 |
+
else:
|
| 335 |
+
# i must not be an array here, to avoid elementwise equals
|
| 336 |
+
if i == Ellipsis:
|
| 337 |
+
n_ellipsis += 1
|
| 338 |
+
else:
|
| 339 |
+
single_axes.append(i)
|
| 340 |
+
|
| 341 |
+
n_single_axes = len(single_axes)
|
| 342 |
+
if n_ellipsis > 1:
|
| 343 |
+
return # handled by ndarray
|
| 344 |
+
elif n_ellipsis == 0:
|
| 345 |
+
# Note boolean masks must be the sole index, which we check for
|
| 346 |
+
# later on.
|
| 347 |
+
if not key_has_mask and n_single_axes < self.ndim:
|
| 348 |
+
raise IndexError(
|
| 349 |
+
f"{self.ndim=}, but the multi-axes index only specifies "
|
| 350 |
+
f"{n_single_axes} dimensions. If this was intentional, "
|
| 351 |
+
"add a trailing ellipsis (...) which expands into as many "
|
| 352 |
+
"slices (:) as necessary - this is what np.ndarray arrays "
|
| 353 |
+
"implicitly do, but such flat indexing behaviour is not "
|
| 354 |
+
"specified in the Array API."
|
| 355 |
+
)
|
| 356 |
+
|
| 357 |
+
if n_ellipsis == 0:
|
| 358 |
+
indexed_shape = self.shape
|
| 359 |
+
else:
|
| 360 |
+
ellipsis_start = None
|
| 361 |
+
for pos, i in enumerate(nonexpanding_key):
|
| 362 |
+
if not (isinstance(i, Array) or isinstance(i, np.ndarray)):
|
| 363 |
+
if i == Ellipsis:
|
| 364 |
+
ellipsis_start = pos
|
| 365 |
+
break
|
| 366 |
+
assert ellipsis_start is not None # sanity check
|
| 367 |
+
ellipsis_end = self.ndim - (n_single_axes - ellipsis_start)
|
| 368 |
+
indexed_shape = (
|
| 369 |
+
self.shape[:ellipsis_start] + self.shape[ellipsis_end:]
|
| 370 |
+
)
|
| 371 |
+
for i, side in zip(single_axes, indexed_shape):
|
| 372 |
+
if isinstance(i, slice):
|
| 373 |
+
if side == 0:
|
| 374 |
+
f_range = "0 (or None)"
|
| 375 |
+
else:
|
| 376 |
+
f_range = f"between -{side} and {side - 1} (or None)"
|
| 377 |
+
if i.start is not None:
|
| 378 |
+
try:
|
| 379 |
+
start = operator.index(i.start)
|
| 380 |
+
except TypeError:
|
| 381 |
+
pass # handled by ndarray
|
| 382 |
+
else:
|
| 383 |
+
if not (-side <= start <= side):
|
| 384 |
+
raise IndexError(
|
| 385 |
+
f"Slice {i} contains {start=}, but should be "
|
| 386 |
+
f"{f_range} for an axis of size {side} "
|
| 387 |
+
"(out-of-bounds starts are not specified in "
|
| 388 |
+
"the Array API)"
|
| 389 |
+
)
|
| 390 |
+
if i.stop is not None:
|
| 391 |
+
try:
|
| 392 |
+
stop = operator.index(i.stop)
|
| 393 |
+
except TypeError:
|
| 394 |
+
pass # handled by ndarray
|
| 395 |
+
else:
|
| 396 |
+
if not (-side <= stop <= side):
|
| 397 |
+
raise IndexError(
|
| 398 |
+
f"Slice {i} contains {stop=}, but should be "
|
| 399 |
+
f"{f_range} for an axis of size {side} "
|
| 400 |
+
"(out-of-bounds stops are not specified in "
|
| 401 |
+
"the Array API)"
|
| 402 |
+
)
|
| 403 |
+
elif isinstance(i, Array):
|
| 404 |
+
if i.dtype in _boolean_dtypes and len(_key) != 1:
|
| 405 |
+
assert isinstance(key, tuple) # sanity check
|
| 406 |
+
raise IndexError(
|
| 407 |
+
f"Single-axes index {i} is a boolean array and "
|
| 408 |
+
f"{len(key)=}, but masking is only specified in the "
|
| 409 |
+
"Array API when the array is the sole index."
|
| 410 |
+
)
|
| 411 |
+
elif i.dtype in _integer_dtypes and i.ndim != 0:
|
| 412 |
+
raise IndexError(
|
| 413 |
+
f"Single-axes index {i} is a non-zero-dimensional "
|
| 414 |
+
"integer array, but advanced integer indexing is not "
|
| 415 |
+
"specified in the Array API."
|
| 416 |
+
)
|
| 417 |
+
elif isinstance(i, tuple):
|
| 418 |
+
raise IndexError(
|
| 419 |
+
f"Single-axes index {i} is a tuple, but nested tuple "
|
| 420 |
+
"indices are not specified in the Array API."
|
| 421 |
+
)
|
| 422 |
+
|
| 423 |
+
# Everything below this line is required by the spec.
|
| 424 |
+
|
| 425 |
+
def __abs__(self: Array, /) -> Array:
|
| 426 |
+
"""
|
| 427 |
+
Performs the operation __abs__.
|
| 428 |
+
"""
|
| 429 |
+
if self.dtype not in _numeric_dtypes:
|
| 430 |
+
raise TypeError("Only numeric dtypes are allowed in __abs__")
|
| 431 |
+
res = self._array.__abs__()
|
| 432 |
+
return self.__class__._new(res)
|
| 433 |
+
|
| 434 |
+
def __add__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 435 |
+
"""
|
| 436 |
+
Performs the operation __add__.
|
| 437 |
+
"""
|
| 438 |
+
other = self._check_allowed_dtypes(other, "numeric", "__add__")
|
| 439 |
+
if other is NotImplemented:
|
| 440 |
+
return other
|
| 441 |
+
self, other = self._normalize_two_args(self, other)
|
| 442 |
+
res = self._array.__add__(other._array)
|
| 443 |
+
return self.__class__._new(res)
|
| 444 |
+
|
| 445 |
+
def __and__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 446 |
+
"""
|
| 447 |
+
Performs the operation __and__.
|
| 448 |
+
"""
|
| 449 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__and__")
|
| 450 |
+
if other is NotImplemented:
|
| 451 |
+
return other
|
| 452 |
+
self, other = self._normalize_two_args(self, other)
|
| 453 |
+
res = self._array.__and__(other._array)
|
| 454 |
+
return self.__class__._new(res)
|
| 455 |
+
|
| 456 |
+
def __array_namespace__(
|
| 457 |
+
self: Array, /, *, api_version: Optional[str] = None
|
| 458 |
+
) -> types.ModuleType:
|
| 459 |
+
if api_version is not None and not api_version.startswith("2021."):
|
| 460 |
+
raise ValueError(f"Unrecognized array API version: {api_version!r}")
|
| 461 |
+
return array_api
|
| 462 |
+
|
| 463 |
+
def __bool__(self: Array, /) -> bool:
|
| 464 |
+
"""
|
| 465 |
+
Performs the operation __bool__.
|
| 466 |
+
"""
|
| 467 |
+
# Note: This is an error here.
|
| 468 |
+
if self._array.ndim != 0:
|
| 469 |
+
raise TypeError("bool is only allowed on arrays with 0 dimensions")
|
| 470 |
+
res = self._array.__bool__()
|
| 471 |
+
return res
|
| 472 |
+
|
| 473 |
+
def __complex__(self: Array, /) -> complex:
|
| 474 |
+
"""
|
| 475 |
+
Performs the operation __complex__.
|
| 476 |
+
"""
|
| 477 |
+
# Note: This is an error here.
|
| 478 |
+
if self._array.ndim != 0:
|
| 479 |
+
raise TypeError("complex is only allowed on arrays with 0 dimensions")
|
| 480 |
+
res = self._array.__complex__()
|
| 481 |
+
return res
|
| 482 |
+
|
| 483 |
+
def __dlpack__(self: Array, /, *, stream: None = None) -> PyCapsule:
|
| 484 |
+
"""
|
| 485 |
+
Performs the operation __dlpack__.
|
| 486 |
+
"""
|
| 487 |
+
return self._array.__dlpack__(stream=stream)
|
| 488 |
+
|
| 489 |
+
def __dlpack_device__(self: Array, /) -> Tuple[IntEnum, int]:
|
| 490 |
+
"""
|
| 491 |
+
Performs the operation __dlpack_device__.
|
| 492 |
+
"""
|
| 493 |
+
# Note: device support is required for this
|
| 494 |
+
return self._array.__dlpack_device__()
|
| 495 |
+
|
| 496 |
+
def __eq__(self: Array, other: Union[int, float, bool, Array], /) -> Array:
|
| 497 |
+
"""
|
| 498 |
+
Performs the operation __eq__.
|
| 499 |
+
"""
|
| 500 |
+
# Even though "all" dtypes are allowed, we still require them to be
|
| 501 |
+
# promotable with each other.
|
| 502 |
+
other = self._check_allowed_dtypes(other, "all", "__eq__")
|
| 503 |
+
if other is NotImplemented:
|
| 504 |
+
return other
|
| 505 |
+
self, other = self._normalize_two_args(self, other)
|
| 506 |
+
res = self._array.__eq__(other._array)
|
| 507 |
+
return self.__class__._new(res)
|
| 508 |
+
|
| 509 |
+
def __float__(self: Array, /) -> float:
|
| 510 |
+
"""
|
| 511 |
+
Performs the operation __float__.
|
| 512 |
+
"""
|
| 513 |
+
# Note: This is an error here.
|
| 514 |
+
if self._array.ndim != 0:
|
| 515 |
+
raise TypeError("float is only allowed on arrays with 0 dimensions")
|
| 516 |
+
if self.dtype in _complex_floating_dtypes:
|
| 517 |
+
raise TypeError("float is not allowed on complex floating-point arrays")
|
| 518 |
+
res = self._array.__float__()
|
| 519 |
+
return res
|
| 520 |
+
|
| 521 |
+
def __floordiv__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 522 |
+
"""
|
| 523 |
+
Performs the operation __floordiv__.
|
| 524 |
+
"""
|
| 525 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__floordiv__")
|
| 526 |
+
if other is NotImplemented:
|
| 527 |
+
return other
|
| 528 |
+
self, other = self._normalize_two_args(self, other)
|
| 529 |
+
res = self._array.__floordiv__(other._array)
|
| 530 |
+
return self.__class__._new(res)
|
| 531 |
+
|
| 532 |
+
def __ge__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 533 |
+
"""
|
| 534 |
+
Performs the operation __ge__.
|
| 535 |
+
"""
|
| 536 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__ge__")
|
| 537 |
+
if other is NotImplemented:
|
| 538 |
+
return other
|
| 539 |
+
self, other = self._normalize_two_args(self, other)
|
| 540 |
+
res = self._array.__ge__(other._array)
|
| 541 |
+
return self.__class__._new(res)
|
| 542 |
+
|
| 543 |
+
def __getitem__(
|
| 544 |
+
self: Array,
|
| 545 |
+
key: Union[
|
| 546 |
+
int,
|
| 547 |
+
slice,
|
| 548 |
+
ellipsis,
|
| 549 |
+
Tuple[Union[int, slice, ellipsis, None], ...],
|
| 550 |
+
Array,
|
| 551 |
+
],
|
| 552 |
+
/,
|
| 553 |
+
) -> Array:
|
| 554 |
+
"""
|
| 555 |
+
Performs the operation __getitem__.
|
| 556 |
+
"""
|
| 557 |
+
# Note: Only indices required by the spec are allowed. See the
|
| 558 |
+
# docstring of _validate_index
|
| 559 |
+
self._validate_index(key)
|
| 560 |
+
if isinstance(key, Array):
|
| 561 |
+
# Indexing self._array with array_api arrays can be erroneous
|
| 562 |
+
key = key._array
|
| 563 |
+
res = self._array.__getitem__(key)
|
| 564 |
+
return self._new(res)
|
| 565 |
+
|
| 566 |
+
def __gt__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 567 |
+
"""
|
| 568 |
+
Performs the operation __gt__.
|
| 569 |
+
"""
|
| 570 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__gt__")
|
| 571 |
+
if other is NotImplemented:
|
| 572 |
+
return other
|
| 573 |
+
self, other = self._normalize_two_args(self, other)
|
| 574 |
+
res = self._array.__gt__(other._array)
|
| 575 |
+
return self.__class__._new(res)
|
| 576 |
+
|
| 577 |
+
def __int__(self: Array, /) -> int:
|
| 578 |
+
"""
|
| 579 |
+
Performs the operation __int__.
|
| 580 |
+
"""
|
| 581 |
+
# Note: This is an error here.
|
| 582 |
+
if self._array.ndim != 0:
|
| 583 |
+
raise TypeError("int is only allowed on arrays with 0 dimensions")
|
| 584 |
+
if self.dtype in _complex_floating_dtypes:
|
| 585 |
+
raise TypeError("int is not allowed on complex floating-point arrays")
|
| 586 |
+
res = self._array.__int__()
|
| 587 |
+
return res
|
| 588 |
+
|
| 589 |
+
def __index__(self: Array, /) -> int:
|
| 590 |
+
"""
|
| 591 |
+
Performs the operation __index__.
|
| 592 |
+
"""
|
| 593 |
+
res = self._array.__index__()
|
| 594 |
+
return res
|
| 595 |
+
|
| 596 |
+
def __invert__(self: Array, /) -> Array:
|
| 597 |
+
"""
|
| 598 |
+
Performs the operation __invert__.
|
| 599 |
+
"""
|
| 600 |
+
if self.dtype not in _integer_or_boolean_dtypes:
|
| 601 |
+
raise TypeError("Only integer or boolean dtypes are allowed in __invert__")
|
| 602 |
+
res = self._array.__invert__()
|
| 603 |
+
return self.__class__._new(res)
|
| 604 |
+
|
| 605 |
+
def __le__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 606 |
+
"""
|
| 607 |
+
Performs the operation __le__.
|
| 608 |
+
"""
|
| 609 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__le__")
|
| 610 |
+
if other is NotImplemented:
|
| 611 |
+
return other
|
| 612 |
+
self, other = self._normalize_two_args(self, other)
|
| 613 |
+
res = self._array.__le__(other._array)
|
| 614 |
+
return self.__class__._new(res)
|
| 615 |
+
|
| 616 |
+
def __lshift__(self: Array, other: Union[int, Array], /) -> Array:
|
| 617 |
+
"""
|
| 618 |
+
Performs the operation __lshift__.
|
| 619 |
+
"""
|
| 620 |
+
other = self._check_allowed_dtypes(other, "integer", "__lshift__")
|
| 621 |
+
if other is NotImplemented:
|
| 622 |
+
return other
|
| 623 |
+
self, other = self._normalize_two_args(self, other)
|
| 624 |
+
res = self._array.__lshift__(other._array)
|
| 625 |
+
return self.__class__._new(res)
|
| 626 |
+
|
| 627 |
+
def __lt__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 628 |
+
"""
|
| 629 |
+
Performs the operation __lt__.
|
| 630 |
+
"""
|
| 631 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__lt__")
|
| 632 |
+
if other is NotImplemented:
|
| 633 |
+
return other
|
| 634 |
+
self, other = self._normalize_two_args(self, other)
|
| 635 |
+
res = self._array.__lt__(other._array)
|
| 636 |
+
return self.__class__._new(res)
|
| 637 |
+
|
| 638 |
+
def __matmul__(self: Array, other: Array, /) -> Array:
|
| 639 |
+
"""
|
| 640 |
+
Performs the operation __matmul__.
|
| 641 |
+
"""
|
| 642 |
+
# matmul is not defined for scalars, but without this, we may get
|
| 643 |
+
# the wrong error message from asarray.
|
| 644 |
+
other = self._check_allowed_dtypes(other, "numeric", "__matmul__")
|
| 645 |
+
if other is NotImplemented:
|
| 646 |
+
return other
|
| 647 |
+
res = self._array.__matmul__(other._array)
|
| 648 |
+
return self.__class__._new(res)
|
| 649 |
+
|
| 650 |
+
def __mod__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 651 |
+
"""
|
| 652 |
+
Performs the operation __mod__.
|
| 653 |
+
"""
|
| 654 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__mod__")
|
| 655 |
+
if other is NotImplemented:
|
| 656 |
+
return other
|
| 657 |
+
self, other = self._normalize_two_args(self, other)
|
| 658 |
+
res = self._array.__mod__(other._array)
|
| 659 |
+
return self.__class__._new(res)
|
| 660 |
+
|
| 661 |
+
def __mul__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 662 |
+
"""
|
| 663 |
+
Performs the operation __mul__.
|
| 664 |
+
"""
|
| 665 |
+
other = self._check_allowed_dtypes(other, "numeric", "__mul__")
|
| 666 |
+
if other is NotImplemented:
|
| 667 |
+
return other
|
| 668 |
+
self, other = self._normalize_two_args(self, other)
|
| 669 |
+
res = self._array.__mul__(other._array)
|
| 670 |
+
return self.__class__._new(res)
|
| 671 |
+
|
| 672 |
+
def __ne__(self: Array, other: Union[int, float, bool, Array], /) -> Array:
|
| 673 |
+
"""
|
| 674 |
+
Performs the operation __ne__.
|
| 675 |
+
"""
|
| 676 |
+
other = self._check_allowed_dtypes(other, "all", "__ne__")
|
| 677 |
+
if other is NotImplemented:
|
| 678 |
+
return other
|
| 679 |
+
self, other = self._normalize_two_args(self, other)
|
| 680 |
+
res = self._array.__ne__(other._array)
|
| 681 |
+
return self.__class__._new(res)
|
| 682 |
+
|
| 683 |
+
def __neg__(self: Array, /) -> Array:
|
| 684 |
+
"""
|
| 685 |
+
Performs the operation __neg__.
|
| 686 |
+
"""
|
| 687 |
+
if self.dtype not in _numeric_dtypes:
|
| 688 |
+
raise TypeError("Only numeric dtypes are allowed in __neg__")
|
| 689 |
+
res = self._array.__neg__()
|
| 690 |
+
return self.__class__._new(res)
|
| 691 |
+
|
| 692 |
+
def __or__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 693 |
+
"""
|
| 694 |
+
Performs the operation __or__.
|
| 695 |
+
"""
|
| 696 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__or__")
|
| 697 |
+
if other is NotImplemented:
|
| 698 |
+
return other
|
| 699 |
+
self, other = self._normalize_two_args(self, other)
|
| 700 |
+
res = self._array.__or__(other._array)
|
| 701 |
+
return self.__class__._new(res)
|
| 702 |
+
|
| 703 |
+
def __pos__(self: Array, /) -> Array:
|
| 704 |
+
"""
|
| 705 |
+
Performs the operation __pos__.
|
| 706 |
+
"""
|
| 707 |
+
if self.dtype not in _numeric_dtypes:
|
| 708 |
+
raise TypeError("Only numeric dtypes are allowed in __pos__")
|
| 709 |
+
res = self._array.__pos__()
|
| 710 |
+
return self.__class__._new(res)
|
| 711 |
+
|
| 712 |
+
def __pow__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 713 |
+
"""
|
| 714 |
+
Performs the operation __pow__.
|
| 715 |
+
"""
|
| 716 |
+
from ._elementwise_functions import pow
|
| 717 |
+
|
| 718 |
+
other = self._check_allowed_dtypes(other, "numeric", "__pow__")
|
| 719 |
+
if other is NotImplemented:
|
| 720 |
+
return other
|
| 721 |
+
# Note: NumPy's __pow__ does not follow type promotion rules for 0-d
|
| 722 |
+
# arrays, so we use pow() here instead.
|
| 723 |
+
return pow(self, other)
|
| 724 |
+
|
| 725 |
+
def __rshift__(self: Array, other: Union[int, Array], /) -> Array:
|
| 726 |
+
"""
|
| 727 |
+
Performs the operation __rshift__.
|
| 728 |
+
"""
|
| 729 |
+
other = self._check_allowed_dtypes(other, "integer", "__rshift__")
|
| 730 |
+
if other is NotImplemented:
|
| 731 |
+
return other
|
| 732 |
+
self, other = self._normalize_two_args(self, other)
|
| 733 |
+
res = self._array.__rshift__(other._array)
|
| 734 |
+
return self.__class__._new(res)
|
| 735 |
+
|
| 736 |
+
def __setitem__(
|
| 737 |
+
self,
|
| 738 |
+
key: Union[
|
| 739 |
+
int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array
|
| 740 |
+
],
|
| 741 |
+
value: Union[int, float, bool, Array],
|
| 742 |
+
/,
|
| 743 |
+
) -> None:
|
| 744 |
+
"""
|
| 745 |
+
Performs the operation __setitem__.
|
| 746 |
+
"""
|
| 747 |
+
# Note: Only indices required by the spec are allowed. See the
|
| 748 |
+
# docstring of _validate_index
|
| 749 |
+
self._validate_index(key)
|
| 750 |
+
if isinstance(key, Array):
|
| 751 |
+
# Indexing self._array with array_api arrays can be erroneous
|
| 752 |
+
key = key._array
|
| 753 |
+
self._array.__setitem__(key, asarray(value)._array)
|
| 754 |
+
|
| 755 |
+
def __sub__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 756 |
+
"""
|
| 757 |
+
Performs the operation __sub__.
|
| 758 |
+
"""
|
| 759 |
+
other = self._check_allowed_dtypes(other, "numeric", "__sub__")
|
| 760 |
+
if other is NotImplemented:
|
| 761 |
+
return other
|
| 762 |
+
self, other = self._normalize_two_args(self, other)
|
| 763 |
+
res = self._array.__sub__(other._array)
|
| 764 |
+
return self.__class__._new(res)
|
| 765 |
+
|
| 766 |
+
# PEP 484 requires int to be a subtype of float, but __truediv__ should
|
| 767 |
+
# not accept int.
|
| 768 |
+
def __truediv__(self: Array, other: Union[float, Array], /) -> Array:
|
| 769 |
+
"""
|
| 770 |
+
Performs the operation __truediv__.
|
| 771 |
+
"""
|
| 772 |
+
other = self._check_allowed_dtypes(other, "floating-point", "__truediv__")
|
| 773 |
+
if other is NotImplemented:
|
| 774 |
+
return other
|
| 775 |
+
self, other = self._normalize_two_args(self, other)
|
| 776 |
+
res = self._array.__truediv__(other._array)
|
| 777 |
+
return self.__class__._new(res)
|
| 778 |
+
|
| 779 |
+
def __xor__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 780 |
+
"""
|
| 781 |
+
Performs the operation __xor__.
|
| 782 |
+
"""
|
| 783 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__xor__")
|
| 784 |
+
if other is NotImplemented:
|
| 785 |
+
return other
|
| 786 |
+
self, other = self._normalize_two_args(self, other)
|
| 787 |
+
res = self._array.__xor__(other._array)
|
| 788 |
+
return self.__class__._new(res)
|
| 789 |
+
|
| 790 |
+
def __iadd__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 791 |
+
"""
|
| 792 |
+
Performs the operation __iadd__.
|
| 793 |
+
"""
|
| 794 |
+
other = self._check_allowed_dtypes(other, "numeric", "__iadd__")
|
| 795 |
+
if other is NotImplemented:
|
| 796 |
+
return other
|
| 797 |
+
self._array.__iadd__(other._array)
|
| 798 |
+
return self
|
| 799 |
+
|
| 800 |
+
def __radd__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 801 |
+
"""
|
| 802 |
+
Performs the operation __radd__.
|
| 803 |
+
"""
|
| 804 |
+
other = self._check_allowed_dtypes(other, "numeric", "__radd__")
|
| 805 |
+
if other is NotImplemented:
|
| 806 |
+
return other
|
| 807 |
+
self, other = self._normalize_two_args(self, other)
|
| 808 |
+
res = self._array.__radd__(other._array)
|
| 809 |
+
return self.__class__._new(res)
|
| 810 |
+
|
| 811 |
+
def __iand__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 812 |
+
"""
|
| 813 |
+
Performs the operation __iand__.
|
| 814 |
+
"""
|
| 815 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__iand__")
|
| 816 |
+
if other is NotImplemented:
|
| 817 |
+
return other
|
| 818 |
+
self._array.__iand__(other._array)
|
| 819 |
+
return self
|
| 820 |
+
|
| 821 |
+
def __rand__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 822 |
+
"""
|
| 823 |
+
Performs the operation __rand__.
|
| 824 |
+
"""
|
| 825 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__rand__")
|
| 826 |
+
if other is NotImplemented:
|
| 827 |
+
return other
|
| 828 |
+
self, other = self._normalize_two_args(self, other)
|
| 829 |
+
res = self._array.__rand__(other._array)
|
| 830 |
+
return self.__class__._new(res)
|
| 831 |
+
|
| 832 |
+
def __ifloordiv__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 833 |
+
"""
|
| 834 |
+
Performs the operation __ifloordiv__.
|
| 835 |
+
"""
|
| 836 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__ifloordiv__")
|
| 837 |
+
if other is NotImplemented:
|
| 838 |
+
return other
|
| 839 |
+
self._array.__ifloordiv__(other._array)
|
| 840 |
+
return self
|
| 841 |
+
|
| 842 |
+
def __rfloordiv__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 843 |
+
"""
|
| 844 |
+
Performs the operation __rfloordiv__.
|
| 845 |
+
"""
|
| 846 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__rfloordiv__")
|
| 847 |
+
if other is NotImplemented:
|
| 848 |
+
return other
|
| 849 |
+
self, other = self._normalize_two_args(self, other)
|
| 850 |
+
res = self._array.__rfloordiv__(other._array)
|
| 851 |
+
return self.__class__._new(res)
|
| 852 |
+
|
| 853 |
+
def __ilshift__(self: Array, other: Union[int, Array], /) -> Array:
|
| 854 |
+
"""
|
| 855 |
+
Performs the operation __ilshift__.
|
| 856 |
+
"""
|
| 857 |
+
other = self._check_allowed_dtypes(other, "integer", "__ilshift__")
|
| 858 |
+
if other is NotImplemented:
|
| 859 |
+
return other
|
| 860 |
+
self._array.__ilshift__(other._array)
|
| 861 |
+
return self
|
| 862 |
+
|
| 863 |
+
def __rlshift__(self: Array, other: Union[int, Array], /) -> Array:
|
| 864 |
+
"""
|
| 865 |
+
Performs the operation __rlshift__.
|
| 866 |
+
"""
|
| 867 |
+
other = self._check_allowed_dtypes(other, "integer", "__rlshift__")
|
| 868 |
+
if other is NotImplemented:
|
| 869 |
+
return other
|
| 870 |
+
self, other = self._normalize_two_args(self, other)
|
| 871 |
+
res = self._array.__rlshift__(other._array)
|
| 872 |
+
return self.__class__._new(res)
|
| 873 |
+
|
| 874 |
+
def __imatmul__(self: Array, other: Array, /) -> Array:
|
| 875 |
+
"""
|
| 876 |
+
Performs the operation __imatmul__.
|
| 877 |
+
"""
|
| 878 |
+
# matmul is not defined for scalars, but without this, we may get
|
| 879 |
+
# the wrong error message from asarray.
|
| 880 |
+
other = self._check_allowed_dtypes(other, "numeric", "__imatmul__")
|
| 881 |
+
if other is NotImplemented:
|
| 882 |
+
return other
|
| 883 |
+
res = self._array.__imatmul__(other._array)
|
| 884 |
+
return self.__class__._new(res)
|
| 885 |
+
|
| 886 |
+
def __rmatmul__(self: Array, other: Array, /) -> Array:
|
| 887 |
+
"""
|
| 888 |
+
Performs the operation __rmatmul__.
|
| 889 |
+
"""
|
| 890 |
+
# matmul is not defined for scalars, but without this, we may get
|
| 891 |
+
# the wrong error message from asarray.
|
| 892 |
+
other = self._check_allowed_dtypes(other, "numeric", "__rmatmul__")
|
| 893 |
+
if other is NotImplemented:
|
| 894 |
+
return other
|
| 895 |
+
res = self._array.__rmatmul__(other._array)
|
| 896 |
+
return self.__class__._new(res)
|
| 897 |
+
|
| 898 |
+
def __imod__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 899 |
+
"""
|
| 900 |
+
Performs the operation __imod__.
|
| 901 |
+
"""
|
| 902 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__imod__")
|
| 903 |
+
if other is NotImplemented:
|
| 904 |
+
return other
|
| 905 |
+
self._array.__imod__(other._array)
|
| 906 |
+
return self
|
| 907 |
+
|
| 908 |
+
def __rmod__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 909 |
+
"""
|
| 910 |
+
Performs the operation __rmod__.
|
| 911 |
+
"""
|
| 912 |
+
other = self._check_allowed_dtypes(other, "real numeric", "__rmod__")
|
| 913 |
+
if other is NotImplemented:
|
| 914 |
+
return other
|
| 915 |
+
self, other = self._normalize_two_args(self, other)
|
| 916 |
+
res = self._array.__rmod__(other._array)
|
| 917 |
+
return self.__class__._new(res)
|
| 918 |
+
|
| 919 |
+
def __imul__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 920 |
+
"""
|
| 921 |
+
Performs the operation __imul__.
|
| 922 |
+
"""
|
| 923 |
+
other = self._check_allowed_dtypes(other, "numeric", "__imul__")
|
| 924 |
+
if other is NotImplemented:
|
| 925 |
+
return other
|
| 926 |
+
self._array.__imul__(other._array)
|
| 927 |
+
return self
|
| 928 |
+
|
| 929 |
+
def __rmul__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 930 |
+
"""
|
| 931 |
+
Performs the operation __rmul__.
|
| 932 |
+
"""
|
| 933 |
+
other = self._check_allowed_dtypes(other, "numeric", "__rmul__")
|
| 934 |
+
if other is NotImplemented:
|
| 935 |
+
return other
|
| 936 |
+
self, other = self._normalize_two_args(self, other)
|
| 937 |
+
res = self._array.__rmul__(other._array)
|
| 938 |
+
return self.__class__._new(res)
|
| 939 |
+
|
| 940 |
+
def __ior__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 941 |
+
"""
|
| 942 |
+
Performs the operation __ior__.
|
| 943 |
+
"""
|
| 944 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__ior__")
|
| 945 |
+
if other is NotImplemented:
|
| 946 |
+
return other
|
| 947 |
+
self._array.__ior__(other._array)
|
| 948 |
+
return self
|
| 949 |
+
|
| 950 |
+
def __ror__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 951 |
+
"""
|
| 952 |
+
Performs the operation __ror__.
|
| 953 |
+
"""
|
| 954 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__ror__")
|
| 955 |
+
if other is NotImplemented:
|
| 956 |
+
return other
|
| 957 |
+
self, other = self._normalize_two_args(self, other)
|
| 958 |
+
res = self._array.__ror__(other._array)
|
| 959 |
+
return self.__class__._new(res)
|
| 960 |
+
|
| 961 |
+
def __ipow__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 962 |
+
"""
|
| 963 |
+
Performs the operation __ipow__.
|
| 964 |
+
"""
|
| 965 |
+
other = self._check_allowed_dtypes(other, "numeric", "__ipow__")
|
| 966 |
+
if other is NotImplemented:
|
| 967 |
+
return other
|
| 968 |
+
self._array.__ipow__(other._array)
|
| 969 |
+
return self
|
| 970 |
+
|
| 971 |
+
def __rpow__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 972 |
+
"""
|
| 973 |
+
Performs the operation __rpow__.
|
| 974 |
+
"""
|
| 975 |
+
from ._elementwise_functions import pow
|
| 976 |
+
|
| 977 |
+
other = self._check_allowed_dtypes(other, "numeric", "__rpow__")
|
| 978 |
+
if other is NotImplemented:
|
| 979 |
+
return other
|
| 980 |
+
# Note: NumPy's __pow__ does not follow the spec type promotion rules
|
| 981 |
+
# for 0-d arrays, so we use pow() here instead.
|
| 982 |
+
return pow(other, self)
|
| 983 |
+
|
| 984 |
+
def __irshift__(self: Array, other: Union[int, Array], /) -> Array:
|
| 985 |
+
"""
|
| 986 |
+
Performs the operation __irshift__.
|
| 987 |
+
"""
|
| 988 |
+
other = self._check_allowed_dtypes(other, "integer", "__irshift__")
|
| 989 |
+
if other is NotImplemented:
|
| 990 |
+
return other
|
| 991 |
+
self._array.__irshift__(other._array)
|
| 992 |
+
return self
|
| 993 |
+
|
| 994 |
+
def __rrshift__(self: Array, other: Union[int, Array], /) -> Array:
|
| 995 |
+
"""
|
| 996 |
+
Performs the operation __rrshift__.
|
| 997 |
+
"""
|
| 998 |
+
other = self._check_allowed_dtypes(other, "integer", "__rrshift__")
|
| 999 |
+
if other is NotImplemented:
|
| 1000 |
+
return other
|
| 1001 |
+
self, other = self._normalize_two_args(self, other)
|
| 1002 |
+
res = self._array.__rrshift__(other._array)
|
| 1003 |
+
return self.__class__._new(res)
|
| 1004 |
+
|
| 1005 |
+
def __isub__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 1006 |
+
"""
|
| 1007 |
+
Performs the operation __isub__.
|
| 1008 |
+
"""
|
| 1009 |
+
other = self._check_allowed_dtypes(other, "numeric", "__isub__")
|
| 1010 |
+
if other is NotImplemented:
|
| 1011 |
+
return other
|
| 1012 |
+
self._array.__isub__(other._array)
|
| 1013 |
+
return self
|
| 1014 |
+
|
| 1015 |
+
def __rsub__(self: Array, other: Union[int, float, Array], /) -> Array:
|
| 1016 |
+
"""
|
| 1017 |
+
Performs the operation __rsub__.
|
| 1018 |
+
"""
|
| 1019 |
+
other = self._check_allowed_dtypes(other, "numeric", "__rsub__")
|
| 1020 |
+
if other is NotImplemented:
|
| 1021 |
+
return other
|
| 1022 |
+
self, other = self._normalize_two_args(self, other)
|
| 1023 |
+
res = self._array.__rsub__(other._array)
|
| 1024 |
+
return self.__class__._new(res)
|
| 1025 |
+
|
| 1026 |
+
def __itruediv__(self: Array, other: Union[float, Array], /) -> Array:
|
| 1027 |
+
"""
|
| 1028 |
+
Performs the operation __itruediv__.
|
| 1029 |
+
"""
|
| 1030 |
+
other = self._check_allowed_dtypes(other, "floating-point", "__itruediv__")
|
| 1031 |
+
if other is NotImplemented:
|
| 1032 |
+
return other
|
| 1033 |
+
self._array.__itruediv__(other._array)
|
| 1034 |
+
return self
|
| 1035 |
+
|
| 1036 |
+
def __rtruediv__(self: Array, other: Union[float, Array], /) -> Array:
|
| 1037 |
+
"""
|
| 1038 |
+
Performs the operation __rtruediv__.
|
| 1039 |
+
"""
|
| 1040 |
+
other = self._check_allowed_dtypes(other, "floating-point", "__rtruediv__")
|
| 1041 |
+
if other is NotImplemented:
|
| 1042 |
+
return other
|
| 1043 |
+
self, other = self._normalize_two_args(self, other)
|
| 1044 |
+
res = self._array.__rtruediv__(other._array)
|
| 1045 |
+
return self.__class__._new(res)
|
| 1046 |
+
|
| 1047 |
+
def __ixor__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 1048 |
+
"""
|
| 1049 |
+
Performs the operation __ixor__.
|
| 1050 |
+
"""
|
| 1051 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__ixor__")
|
| 1052 |
+
if other is NotImplemented:
|
| 1053 |
+
return other
|
| 1054 |
+
self._array.__ixor__(other._array)
|
| 1055 |
+
return self
|
| 1056 |
+
|
| 1057 |
+
def __rxor__(self: Array, other: Union[int, bool, Array], /) -> Array:
|
| 1058 |
+
"""
|
| 1059 |
+
Performs the operation __rxor__.
|
| 1060 |
+
"""
|
| 1061 |
+
other = self._check_allowed_dtypes(other, "integer or boolean", "__rxor__")
|
| 1062 |
+
if other is NotImplemented:
|
| 1063 |
+
return other
|
| 1064 |
+
self, other = self._normalize_two_args(self, other)
|
| 1065 |
+
res = self._array.__rxor__(other._array)
|
| 1066 |
+
return self.__class__._new(res)
|
| 1067 |
+
|
| 1068 |
+
def to_device(self: Array, device: Device, /, stream: None = None) -> Array:
|
| 1069 |
+
if stream is not None:
|
| 1070 |
+
raise ValueError("The stream argument to to_device() is not supported")
|
| 1071 |
+
if device == 'cpu':
|
| 1072 |
+
return self
|
| 1073 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 1074 |
+
|
| 1075 |
+
@property
|
| 1076 |
+
def dtype(self) -> Dtype:
|
| 1077 |
+
"""
|
| 1078 |
+
Array API compatible wrapper for :py:meth:`np.ndarray.dtype <numpy.ndarray.dtype>`.
|
| 1079 |
+
|
| 1080 |
+
See its docstring for more information.
|
| 1081 |
+
"""
|
| 1082 |
+
return self._array.dtype
|
| 1083 |
+
|
| 1084 |
+
@property
|
| 1085 |
+
def device(self) -> Device:
|
| 1086 |
+
return "cpu"
|
| 1087 |
+
|
| 1088 |
+
# Note: mT is new in array API spec (see matrix_transpose)
|
| 1089 |
+
@property
|
| 1090 |
+
def mT(self) -> Array:
|
| 1091 |
+
from .linalg import matrix_transpose
|
| 1092 |
+
return matrix_transpose(self)
|
| 1093 |
+
|
| 1094 |
+
@property
|
| 1095 |
+
def ndim(self) -> int:
|
| 1096 |
+
"""
|
| 1097 |
+
Array API compatible wrapper for :py:meth:`np.ndarray.ndim <numpy.ndarray.ndim>`.
|
| 1098 |
+
|
| 1099 |
+
See its docstring for more information.
|
| 1100 |
+
"""
|
| 1101 |
+
return self._array.ndim
|
| 1102 |
+
|
| 1103 |
+
@property
|
| 1104 |
+
def shape(self) -> Tuple[int, ...]:
|
| 1105 |
+
"""
|
| 1106 |
+
Array API compatible wrapper for :py:meth:`np.ndarray.shape <numpy.ndarray.shape>`.
|
| 1107 |
+
|
| 1108 |
+
See its docstring for more information.
|
| 1109 |
+
"""
|
| 1110 |
+
return self._array.shape
|
| 1111 |
+
|
| 1112 |
+
@property
|
| 1113 |
+
def size(self) -> int:
|
| 1114 |
+
"""
|
| 1115 |
+
Array API compatible wrapper for :py:meth:`np.ndarray.size <numpy.ndarray.size>`.
|
| 1116 |
+
|
| 1117 |
+
See its docstring for more information.
|
| 1118 |
+
"""
|
| 1119 |
+
return self._array.size
|
| 1120 |
+
|
| 1121 |
+
@property
|
| 1122 |
+
def T(self) -> Array:
|
| 1123 |
+
"""
|
| 1124 |
+
Array API compatible wrapper for :py:meth:`np.ndarray.T <numpy.ndarray.T>`.
|
| 1125 |
+
|
| 1126 |
+
See its docstring for more information.
|
| 1127 |
+
"""
|
| 1128 |
+
# Note: T only works on 2-dimensional arrays. See the corresponding
|
| 1129 |
+
# note in the specification:
|
| 1130 |
+
# https://data-apis.org/array-api/latest/API_specification/array_object.html#t
|
| 1131 |
+
if self.ndim != 2:
|
| 1132 |
+
raise ValueError("x.T requires x to have 2 dimensions. Use x.mT to transpose stacks of matrices and permute_dims() to permute dimensions.")
|
| 1133 |
+
return self.__class__._new(self._array.T)
|
lib/python3.12/site-packages/numpy/array_api/_constants.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
|
| 3 |
+
e = np.e
|
| 4 |
+
inf = np.inf
|
| 5 |
+
nan = np.nan
|
| 6 |
+
pi = np.pi
|
| 7 |
+
newaxis = np.newaxis
|
lib/python3.12/site-packages/numpy/array_api/_creation_functions.py
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
from typing import TYPE_CHECKING, List, Optional, Tuple, Union
|
| 5 |
+
|
| 6 |
+
if TYPE_CHECKING:
|
| 7 |
+
from ._typing import (
|
| 8 |
+
Array,
|
| 9 |
+
Device,
|
| 10 |
+
Dtype,
|
| 11 |
+
NestedSequence,
|
| 12 |
+
SupportsBufferProtocol,
|
| 13 |
+
)
|
| 14 |
+
from collections.abc import Sequence
|
| 15 |
+
from ._dtypes import _all_dtypes
|
| 16 |
+
|
| 17 |
+
import numpy as np
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def _check_valid_dtype(dtype):
|
| 21 |
+
# Note: Only spelling dtypes as the dtype objects is supported.
|
| 22 |
+
|
| 23 |
+
# We use this instead of "dtype in _all_dtypes" because the dtype objects
|
| 24 |
+
# define equality with the sorts of things we want to disallow.
|
| 25 |
+
for d in (None,) + _all_dtypes:
|
| 26 |
+
if dtype is d:
|
| 27 |
+
return
|
| 28 |
+
raise ValueError("dtype must be one of the supported dtypes")
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def asarray(
|
| 32 |
+
obj: Union[
|
| 33 |
+
Array,
|
| 34 |
+
bool,
|
| 35 |
+
int,
|
| 36 |
+
float,
|
| 37 |
+
NestedSequence[bool | int | float],
|
| 38 |
+
SupportsBufferProtocol,
|
| 39 |
+
],
|
| 40 |
+
/,
|
| 41 |
+
*,
|
| 42 |
+
dtype: Optional[Dtype] = None,
|
| 43 |
+
device: Optional[Device] = None,
|
| 44 |
+
copy: Optional[Union[bool, np._CopyMode]] = None,
|
| 45 |
+
) -> Array:
|
| 46 |
+
"""
|
| 47 |
+
Array API compatible wrapper for :py:func:`np.asarray <numpy.asarray>`.
|
| 48 |
+
|
| 49 |
+
See its docstring for more information.
|
| 50 |
+
"""
|
| 51 |
+
# _array_object imports in this file are inside the functions to avoid
|
| 52 |
+
# circular imports
|
| 53 |
+
from ._array_object import Array
|
| 54 |
+
|
| 55 |
+
_check_valid_dtype(dtype)
|
| 56 |
+
if device not in ["cpu", None]:
|
| 57 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 58 |
+
if copy in (False, np._CopyMode.IF_NEEDED):
|
| 59 |
+
# Note: copy=False is not yet implemented in np.asarray
|
| 60 |
+
raise NotImplementedError("copy=False is not yet implemented")
|
| 61 |
+
if isinstance(obj, Array):
|
| 62 |
+
if dtype is not None and obj.dtype != dtype:
|
| 63 |
+
copy = True
|
| 64 |
+
if copy in (True, np._CopyMode.ALWAYS):
|
| 65 |
+
return Array._new(np.array(obj._array, copy=True, dtype=dtype))
|
| 66 |
+
return obj
|
| 67 |
+
if dtype is None and isinstance(obj, int) and (obj > 2 ** 64 or obj < -(2 ** 63)):
|
| 68 |
+
# Give a better error message in this case. NumPy would convert this
|
| 69 |
+
# to an object array. TODO: This won't handle large integers in lists.
|
| 70 |
+
raise OverflowError("Integer out of bounds for array dtypes")
|
| 71 |
+
res = np.asarray(obj, dtype=dtype)
|
| 72 |
+
return Array._new(res)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def arange(
|
| 76 |
+
start: Union[int, float],
|
| 77 |
+
/,
|
| 78 |
+
stop: Optional[Union[int, float]] = None,
|
| 79 |
+
step: Union[int, float] = 1,
|
| 80 |
+
*,
|
| 81 |
+
dtype: Optional[Dtype] = None,
|
| 82 |
+
device: Optional[Device] = None,
|
| 83 |
+
) -> Array:
|
| 84 |
+
"""
|
| 85 |
+
Array API compatible wrapper for :py:func:`np.arange <numpy.arange>`.
|
| 86 |
+
|
| 87 |
+
See its docstring for more information.
|
| 88 |
+
"""
|
| 89 |
+
from ._array_object import Array
|
| 90 |
+
|
| 91 |
+
_check_valid_dtype(dtype)
|
| 92 |
+
if device not in ["cpu", None]:
|
| 93 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 94 |
+
return Array._new(np.arange(start, stop=stop, step=step, dtype=dtype))
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def empty(
|
| 98 |
+
shape: Union[int, Tuple[int, ...]],
|
| 99 |
+
*,
|
| 100 |
+
dtype: Optional[Dtype] = None,
|
| 101 |
+
device: Optional[Device] = None,
|
| 102 |
+
) -> Array:
|
| 103 |
+
"""
|
| 104 |
+
Array API compatible wrapper for :py:func:`np.empty <numpy.empty>`.
|
| 105 |
+
|
| 106 |
+
See its docstring for more information.
|
| 107 |
+
"""
|
| 108 |
+
from ._array_object import Array
|
| 109 |
+
|
| 110 |
+
_check_valid_dtype(dtype)
|
| 111 |
+
if device not in ["cpu", None]:
|
| 112 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 113 |
+
return Array._new(np.empty(shape, dtype=dtype))
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
def empty_like(
|
| 117 |
+
x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None
|
| 118 |
+
) -> Array:
|
| 119 |
+
"""
|
| 120 |
+
Array API compatible wrapper for :py:func:`np.empty_like <numpy.empty_like>`.
|
| 121 |
+
|
| 122 |
+
See its docstring for more information.
|
| 123 |
+
"""
|
| 124 |
+
from ._array_object import Array
|
| 125 |
+
|
| 126 |
+
_check_valid_dtype(dtype)
|
| 127 |
+
if device not in ["cpu", None]:
|
| 128 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 129 |
+
return Array._new(np.empty_like(x._array, dtype=dtype))
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def eye(
|
| 133 |
+
n_rows: int,
|
| 134 |
+
n_cols: Optional[int] = None,
|
| 135 |
+
/,
|
| 136 |
+
*,
|
| 137 |
+
k: int = 0,
|
| 138 |
+
dtype: Optional[Dtype] = None,
|
| 139 |
+
device: Optional[Device] = None,
|
| 140 |
+
) -> Array:
|
| 141 |
+
"""
|
| 142 |
+
Array API compatible wrapper for :py:func:`np.eye <numpy.eye>`.
|
| 143 |
+
|
| 144 |
+
See its docstring for more information.
|
| 145 |
+
"""
|
| 146 |
+
from ._array_object import Array
|
| 147 |
+
|
| 148 |
+
_check_valid_dtype(dtype)
|
| 149 |
+
if device not in ["cpu", None]:
|
| 150 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 151 |
+
return Array._new(np.eye(n_rows, M=n_cols, k=k, dtype=dtype))
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def from_dlpack(x: object, /) -> Array:
|
| 155 |
+
from ._array_object import Array
|
| 156 |
+
|
| 157 |
+
return Array._new(np.from_dlpack(x))
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def full(
|
| 161 |
+
shape: Union[int, Tuple[int, ...]],
|
| 162 |
+
fill_value: Union[int, float],
|
| 163 |
+
*,
|
| 164 |
+
dtype: Optional[Dtype] = None,
|
| 165 |
+
device: Optional[Device] = None,
|
| 166 |
+
) -> Array:
|
| 167 |
+
"""
|
| 168 |
+
Array API compatible wrapper for :py:func:`np.full <numpy.full>`.
|
| 169 |
+
|
| 170 |
+
See its docstring for more information.
|
| 171 |
+
"""
|
| 172 |
+
from ._array_object import Array
|
| 173 |
+
|
| 174 |
+
_check_valid_dtype(dtype)
|
| 175 |
+
if device not in ["cpu", None]:
|
| 176 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 177 |
+
if isinstance(fill_value, Array) and fill_value.ndim == 0:
|
| 178 |
+
fill_value = fill_value._array
|
| 179 |
+
res = np.full(shape, fill_value, dtype=dtype)
|
| 180 |
+
if res.dtype not in _all_dtypes:
|
| 181 |
+
# This will happen if the fill value is not something that NumPy
|
| 182 |
+
# coerces to one of the acceptable dtypes.
|
| 183 |
+
raise TypeError("Invalid input to full")
|
| 184 |
+
return Array._new(res)
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def full_like(
|
| 188 |
+
x: Array,
|
| 189 |
+
/,
|
| 190 |
+
fill_value: Union[int, float],
|
| 191 |
+
*,
|
| 192 |
+
dtype: Optional[Dtype] = None,
|
| 193 |
+
device: Optional[Device] = None,
|
| 194 |
+
) -> Array:
|
| 195 |
+
"""
|
| 196 |
+
Array API compatible wrapper for :py:func:`np.full_like <numpy.full_like>`.
|
| 197 |
+
|
| 198 |
+
See its docstring for more information.
|
| 199 |
+
"""
|
| 200 |
+
from ._array_object import Array
|
| 201 |
+
|
| 202 |
+
_check_valid_dtype(dtype)
|
| 203 |
+
if device not in ["cpu", None]:
|
| 204 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 205 |
+
res = np.full_like(x._array, fill_value, dtype=dtype)
|
| 206 |
+
if res.dtype not in _all_dtypes:
|
| 207 |
+
# This will happen if the fill value is not something that NumPy
|
| 208 |
+
# coerces to one of the acceptable dtypes.
|
| 209 |
+
raise TypeError("Invalid input to full_like")
|
| 210 |
+
return Array._new(res)
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
def linspace(
|
| 214 |
+
start: Union[int, float],
|
| 215 |
+
stop: Union[int, float],
|
| 216 |
+
/,
|
| 217 |
+
num: int,
|
| 218 |
+
*,
|
| 219 |
+
dtype: Optional[Dtype] = None,
|
| 220 |
+
device: Optional[Device] = None,
|
| 221 |
+
endpoint: bool = True,
|
| 222 |
+
) -> Array:
|
| 223 |
+
"""
|
| 224 |
+
Array API compatible wrapper for :py:func:`np.linspace <numpy.linspace>`.
|
| 225 |
+
|
| 226 |
+
See its docstring for more information.
|
| 227 |
+
"""
|
| 228 |
+
from ._array_object import Array
|
| 229 |
+
|
| 230 |
+
_check_valid_dtype(dtype)
|
| 231 |
+
if device not in ["cpu", None]:
|
| 232 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 233 |
+
return Array._new(np.linspace(start, stop, num, dtype=dtype, endpoint=endpoint))
|
| 234 |
+
|
| 235 |
+
|
| 236 |
+
def meshgrid(*arrays: Array, indexing: str = "xy") -> List[Array]:
|
| 237 |
+
"""
|
| 238 |
+
Array API compatible wrapper for :py:func:`np.meshgrid <numpy.meshgrid>`.
|
| 239 |
+
|
| 240 |
+
See its docstring for more information.
|
| 241 |
+
"""
|
| 242 |
+
from ._array_object import Array
|
| 243 |
+
|
| 244 |
+
# Note: unlike np.meshgrid, only inputs with all the same dtype are
|
| 245 |
+
# allowed
|
| 246 |
+
|
| 247 |
+
if len({a.dtype for a in arrays}) > 1:
|
| 248 |
+
raise ValueError("meshgrid inputs must all have the same dtype")
|
| 249 |
+
|
| 250 |
+
return [
|
| 251 |
+
Array._new(array)
|
| 252 |
+
for array in np.meshgrid(*[a._array for a in arrays], indexing=indexing)
|
| 253 |
+
]
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
def ones(
|
| 257 |
+
shape: Union[int, Tuple[int, ...]],
|
| 258 |
+
*,
|
| 259 |
+
dtype: Optional[Dtype] = None,
|
| 260 |
+
device: Optional[Device] = None,
|
| 261 |
+
) -> Array:
|
| 262 |
+
"""
|
| 263 |
+
Array API compatible wrapper for :py:func:`np.ones <numpy.ones>`.
|
| 264 |
+
|
| 265 |
+
See its docstring for more information.
|
| 266 |
+
"""
|
| 267 |
+
from ._array_object import Array
|
| 268 |
+
|
| 269 |
+
_check_valid_dtype(dtype)
|
| 270 |
+
if device not in ["cpu", None]:
|
| 271 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 272 |
+
return Array._new(np.ones(shape, dtype=dtype))
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
def ones_like(
|
| 276 |
+
x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None
|
| 277 |
+
) -> Array:
|
| 278 |
+
"""
|
| 279 |
+
Array API compatible wrapper for :py:func:`np.ones_like <numpy.ones_like>`.
|
| 280 |
+
|
| 281 |
+
See its docstring for more information.
|
| 282 |
+
"""
|
| 283 |
+
from ._array_object import Array
|
| 284 |
+
|
| 285 |
+
_check_valid_dtype(dtype)
|
| 286 |
+
if device not in ["cpu", None]:
|
| 287 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 288 |
+
return Array._new(np.ones_like(x._array, dtype=dtype))
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def tril(x: Array, /, *, k: int = 0) -> Array:
|
| 292 |
+
"""
|
| 293 |
+
Array API compatible wrapper for :py:func:`np.tril <numpy.tril>`.
|
| 294 |
+
|
| 295 |
+
See its docstring for more information.
|
| 296 |
+
"""
|
| 297 |
+
from ._array_object import Array
|
| 298 |
+
|
| 299 |
+
if x.ndim < 2:
|
| 300 |
+
# Note: Unlike np.tril, x must be at least 2-D
|
| 301 |
+
raise ValueError("x must be at least 2-dimensional for tril")
|
| 302 |
+
return Array._new(np.tril(x._array, k=k))
|
| 303 |
+
|
| 304 |
+
|
| 305 |
+
def triu(x: Array, /, *, k: int = 0) -> Array:
|
| 306 |
+
"""
|
| 307 |
+
Array API compatible wrapper for :py:func:`np.triu <numpy.triu>`.
|
| 308 |
+
|
| 309 |
+
See its docstring for more information.
|
| 310 |
+
"""
|
| 311 |
+
from ._array_object import Array
|
| 312 |
+
|
| 313 |
+
if x.ndim < 2:
|
| 314 |
+
# Note: Unlike np.triu, x must be at least 2-D
|
| 315 |
+
raise ValueError("x must be at least 2-dimensional for triu")
|
| 316 |
+
return Array._new(np.triu(x._array, k=k))
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
def zeros(
|
| 320 |
+
shape: Union[int, Tuple[int, ...]],
|
| 321 |
+
*,
|
| 322 |
+
dtype: Optional[Dtype] = None,
|
| 323 |
+
device: Optional[Device] = None,
|
| 324 |
+
) -> Array:
|
| 325 |
+
"""
|
| 326 |
+
Array API compatible wrapper for :py:func:`np.zeros <numpy.zeros>`.
|
| 327 |
+
|
| 328 |
+
See its docstring for more information.
|
| 329 |
+
"""
|
| 330 |
+
from ._array_object import Array
|
| 331 |
+
|
| 332 |
+
_check_valid_dtype(dtype)
|
| 333 |
+
if device not in ["cpu", None]:
|
| 334 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 335 |
+
return Array._new(np.zeros(shape, dtype=dtype))
|
| 336 |
+
|
| 337 |
+
|
| 338 |
+
def zeros_like(
|
| 339 |
+
x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None
|
| 340 |
+
) -> Array:
|
| 341 |
+
"""
|
| 342 |
+
Array API compatible wrapper for :py:func:`np.zeros_like <numpy.zeros_like>`.
|
| 343 |
+
|
| 344 |
+
See its docstring for more information.
|
| 345 |
+
"""
|
| 346 |
+
from ._array_object import Array
|
| 347 |
+
|
| 348 |
+
_check_valid_dtype(dtype)
|
| 349 |
+
if device not in ["cpu", None]:
|
| 350 |
+
raise ValueError(f"Unsupported device {device!r}")
|
| 351 |
+
return Array._new(np.zeros_like(x._array, dtype=dtype))
|
lib/python3.12/site-packages/numpy/array_api/_data_type_functions.py
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._array_object import Array
|
| 4 |
+
from ._dtypes import (
|
| 5 |
+
_all_dtypes,
|
| 6 |
+
_boolean_dtypes,
|
| 7 |
+
_signed_integer_dtypes,
|
| 8 |
+
_unsigned_integer_dtypes,
|
| 9 |
+
_integer_dtypes,
|
| 10 |
+
_real_floating_dtypes,
|
| 11 |
+
_complex_floating_dtypes,
|
| 12 |
+
_numeric_dtypes,
|
| 13 |
+
_result_type,
|
| 14 |
+
)
|
| 15 |
+
|
| 16 |
+
from dataclasses import dataclass
|
| 17 |
+
from typing import TYPE_CHECKING, List, Tuple, Union
|
| 18 |
+
|
| 19 |
+
if TYPE_CHECKING:
|
| 20 |
+
from ._typing import Dtype
|
| 21 |
+
from collections.abc import Sequence
|
| 22 |
+
|
| 23 |
+
import numpy as np
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
# Note: astype is a function, not an array method as in NumPy.
|
| 27 |
+
def astype(x: Array, dtype: Dtype, /, *, copy: bool = True) -> Array:
|
| 28 |
+
if not copy and dtype == x.dtype:
|
| 29 |
+
return x
|
| 30 |
+
return Array._new(x._array.astype(dtype=dtype, copy=copy))
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def broadcast_arrays(*arrays: Array) -> List[Array]:
|
| 34 |
+
"""
|
| 35 |
+
Array API compatible wrapper for :py:func:`np.broadcast_arrays <numpy.broadcast_arrays>`.
|
| 36 |
+
|
| 37 |
+
See its docstring for more information.
|
| 38 |
+
"""
|
| 39 |
+
from ._array_object import Array
|
| 40 |
+
|
| 41 |
+
return [
|
| 42 |
+
Array._new(array) for array in np.broadcast_arrays(*[a._array for a in arrays])
|
| 43 |
+
]
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def broadcast_to(x: Array, /, shape: Tuple[int, ...]) -> Array:
|
| 47 |
+
"""
|
| 48 |
+
Array API compatible wrapper for :py:func:`np.broadcast_to <numpy.broadcast_to>`.
|
| 49 |
+
|
| 50 |
+
See its docstring for more information.
|
| 51 |
+
"""
|
| 52 |
+
from ._array_object import Array
|
| 53 |
+
|
| 54 |
+
return Array._new(np.broadcast_to(x._array, shape))
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def can_cast(from_: Union[Dtype, Array], to: Dtype, /) -> bool:
|
| 58 |
+
"""
|
| 59 |
+
Array API compatible wrapper for :py:func:`np.can_cast <numpy.can_cast>`.
|
| 60 |
+
|
| 61 |
+
See its docstring for more information.
|
| 62 |
+
"""
|
| 63 |
+
if isinstance(from_, Array):
|
| 64 |
+
from_ = from_.dtype
|
| 65 |
+
elif from_ not in _all_dtypes:
|
| 66 |
+
raise TypeError(f"{from_=}, but should be an array_api array or dtype")
|
| 67 |
+
if to not in _all_dtypes:
|
| 68 |
+
raise TypeError(f"{to=}, but should be a dtype")
|
| 69 |
+
# Note: We avoid np.can_cast() as it has discrepancies with the array API,
|
| 70 |
+
# since NumPy allows cross-kind casting (e.g., NumPy allows bool -> int8).
|
| 71 |
+
# See https://github.com/numpy/numpy/issues/20870
|
| 72 |
+
try:
|
| 73 |
+
# We promote `from_` and `to` together. We then check if the promoted
|
| 74 |
+
# dtype is `to`, which indicates if `from_` can (up)cast to `to`.
|
| 75 |
+
dtype = _result_type(from_, to)
|
| 76 |
+
return to == dtype
|
| 77 |
+
except TypeError:
|
| 78 |
+
# _result_type() raises if the dtypes don't promote together
|
| 79 |
+
return False
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
# These are internal objects for the return types of finfo and iinfo, since
|
| 83 |
+
# the NumPy versions contain extra data that isn't part of the spec.
|
| 84 |
+
@dataclass
|
| 85 |
+
class finfo_object:
|
| 86 |
+
bits: int
|
| 87 |
+
# Note: The types of the float data here are float, whereas in NumPy they
|
| 88 |
+
# are scalars of the corresponding float dtype.
|
| 89 |
+
eps: float
|
| 90 |
+
max: float
|
| 91 |
+
min: float
|
| 92 |
+
smallest_normal: float
|
| 93 |
+
dtype: Dtype
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
@dataclass
|
| 97 |
+
class iinfo_object:
|
| 98 |
+
bits: int
|
| 99 |
+
max: int
|
| 100 |
+
min: int
|
| 101 |
+
dtype: Dtype
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def finfo(type: Union[Dtype, Array], /) -> finfo_object:
|
| 105 |
+
"""
|
| 106 |
+
Array API compatible wrapper for :py:func:`np.finfo <numpy.finfo>`.
|
| 107 |
+
|
| 108 |
+
See its docstring for more information.
|
| 109 |
+
"""
|
| 110 |
+
fi = np.finfo(type)
|
| 111 |
+
# Note: The types of the float data here are float, whereas in NumPy they
|
| 112 |
+
# are scalars of the corresponding float dtype.
|
| 113 |
+
return finfo_object(
|
| 114 |
+
fi.bits,
|
| 115 |
+
float(fi.eps),
|
| 116 |
+
float(fi.max),
|
| 117 |
+
float(fi.min),
|
| 118 |
+
float(fi.smallest_normal),
|
| 119 |
+
fi.dtype,
|
| 120 |
+
)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def iinfo(type: Union[Dtype, Array], /) -> iinfo_object:
|
| 124 |
+
"""
|
| 125 |
+
Array API compatible wrapper for :py:func:`np.iinfo <numpy.iinfo>`.
|
| 126 |
+
|
| 127 |
+
See its docstring for more information.
|
| 128 |
+
"""
|
| 129 |
+
ii = np.iinfo(type)
|
| 130 |
+
return iinfo_object(ii.bits, ii.max, ii.min, ii.dtype)
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
# Note: isdtype is a new function from the 2022.12 array API specification.
|
| 134 |
+
def isdtype(
|
| 135 |
+
dtype: Dtype, kind: Union[Dtype, str, Tuple[Union[Dtype, str], ...]]
|
| 136 |
+
) -> bool:
|
| 137 |
+
"""
|
| 138 |
+
Returns a boolean indicating whether a provided dtype is of a specified data type ``kind``.
|
| 139 |
+
|
| 140 |
+
See
|
| 141 |
+
https://data-apis.org/array-api/latest/API_specification/generated/array_api.isdtype.html
|
| 142 |
+
for more details
|
| 143 |
+
"""
|
| 144 |
+
if isinstance(kind, tuple):
|
| 145 |
+
# Disallow nested tuples
|
| 146 |
+
if any(isinstance(k, tuple) for k in kind):
|
| 147 |
+
raise TypeError("'kind' must be a dtype, str, or tuple of dtypes and strs")
|
| 148 |
+
return any(isdtype(dtype, k) for k in kind)
|
| 149 |
+
elif isinstance(kind, str):
|
| 150 |
+
if kind == 'bool':
|
| 151 |
+
return dtype in _boolean_dtypes
|
| 152 |
+
elif kind == 'signed integer':
|
| 153 |
+
return dtype in _signed_integer_dtypes
|
| 154 |
+
elif kind == 'unsigned integer':
|
| 155 |
+
return dtype in _unsigned_integer_dtypes
|
| 156 |
+
elif kind == 'integral':
|
| 157 |
+
return dtype in _integer_dtypes
|
| 158 |
+
elif kind == 'real floating':
|
| 159 |
+
return dtype in _real_floating_dtypes
|
| 160 |
+
elif kind == 'complex floating':
|
| 161 |
+
return dtype in _complex_floating_dtypes
|
| 162 |
+
elif kind == 'numeric':
|
| 163 |
+
return dtype in _numeric_dtypes
|
| 164 |
+
else:
|
| 165 |
+
raise ValueError(f"Unrecognized data type kind: {kind!r}")
|
| 166 |
+
elif kind in _all_dtypes:
|
| 167 |
+
return dtype == kind
|
| 168 |
+
else:
|
| 169 |
+
raise TypeError(f"'kind' must be a dtype, str, or tuple of dtypes and strs, not {type(kind).__name__}")
|
| 170 |
+
|
| 171 |
+
def result_type(*arrays_and_dtypes: Union[Array, Dtype]) -> Dtype:
|
| 172 |
+
"""
|
| 173 |
+
Array API compatible wrapper for :py:func:`np.result_type <numpy.result_type>`.
|
| 174 |
+
|
| 175 |
+
See its docstring for more information.
|
| 176 |
+
"""
|
| 177 |
+
# Note: we use a custom implementation that gives only the type promotions
|
| 178 |
+
# required by the spec rather than using np.result_type. NumPy implements
|
| 179 |
+
# too many extra type promotions like int64 + uint64 -> float64, and does
|
| 180 |
+
# value-based casting on scalar arrays.
|
| 181 |
+
A = []
|
| 182 |
+
for a in arrays_and_dtypes:
|
| 183 |
+
if isinstance(a, Array):
|
| 184 |
+
a = a.dtype
|
| 185 |
+
elif isinstance(a, np.ndarray) or a not in _all_dtypes:
|
| 186 |
+
raise TypeError("result_type() inputs must be array_api arrays or dtypes")
|
| 187 |
+
A.append(a)
|
| 188 |
+
|
| 189 |
+
if len(A) == 0:
|
| 190 |
+
raise ValueError("at least one array or dtype is required")
|
| 191 |
+
elif len(A) == 1:
|
| 192 |
+
return A[0]
|
| 193 |
+
else:
|
| 194 |
+
t = A[0]
|
| 195 |
+
for t2 in A[1:]:
|
| 196 |
+
t = _result_type(t, t2)
|
| 197 |
+
return t
|
lib/python3.12/site-packages/numpy/array_api/_dtypes.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
|
| 3 |
+
# Note: we use dtype objects instead of dtype classes. The spec does not
|
| 4 |
+
# require any behavior on dtypes other than equality.
|
| 5 |
+
int8 = np.dtype("int8")
|
| 6 |
+
int16 = np.dtype("int16")
|
| 7 |
+
int32 = np.dtype("int32")
|
| 8 |
+
int64 = np.dtype("int64")
|
| 9 |
+
uint8 = np.dtype("uint8")
|
| 10 |
+
uint16 = np.dtype("uint16")
|
| 11 |
+
uint32 = np.dtype("uint32")
|
| 12 |
+
uint64 = np.dtype("uint64")
|
| 13 |
+
float32 = np.dtype("float32")
|
| 14 |
+
float64 = np.dtype("float64")
|
| 15 |
+
complex64 = np.dtype("complex64")
|
| 16 |
+
complex128 = np.dtype("complex128")
|
| 17 |
+
# Note: This name is changed
|
| 18 |
+
bool = np.dtype("bool")
|
| 19 |
+
|
| 20 |
+
_all_dtypes = (
|
| 21 |
+
int8,
|
| 22 |
+
int16,
|
| 23 |
+
int32,
|
| 24 |
+
int64,
|
| 25 |
+
uint8,
|
| 26 |
+
uint16,
|
| 27 |
+
uint32,
|
| 28 |
+
uint64,
|
| 29 |
+
float32,
|
| 30 |
+
float64,
|
| 31 |
+
complex64,
|
| 32 |
+
complex128,
|
| 33 |
+
bool,
|
| 34 |
+
)
|
| 35 |
+
_boolean_dtypes = (bool,)
|
| 36 |
+
_real_floating_dtypes = (float32, float64)
|
| 37 |
+
_floating_dtypes = (float32, float64, complex64, complex128)
|
| 38 |
+
_complex_floating_dtypes = (complex64, complex128)
|
| 39 |
+
_integer_dtypes = (int8, int16, int32, int64, uint8, uint16, uint32, uint64)
|
| 40 |
+
_signed_integer_dtypes = (int8, int16, int32, int64)
|
| 41 |
+
_unsigned_integer_dtypes = (uint8, uint16, uint32, uint64)
|
| 42 |
+
_integer_or_boolean_dtypes = (
|
| 43 |
+
bool,
|
| 44 |
+
int8,
|
| 45 |
+
int16,
|
| 46 |
+
int32,
|
| 47 |
+
int64,
|
| 48 |
+
uint8,
|
| 49 |
+
uint16,
|
| 50 |
+
uint32,
|
| 51 |
+
uint64,
|
| 52 |
+
)
|
| 53 |
+
_real_numeric_dtypes = (
|
| 54 |
+
float32,
|
| 55 |
+
float64,
|
| 56 |
+
int8,
|
| 57 |
+
int16,
|
| 58 |
+
int32,
|
| 59 |
+
int64,
|
| 60 |
+
uint8,
|
| 61 |
+
uint16,
|
| 62 |
+
uint32,
|
| 63 |
+
uint64,
|
| 64 |
+
)
|
| 65 |
+
_numeric_dtypes = (
|
| 66 |
+
float32,
|
| 67 |
+
float64,
|
| 68 |
+
complex64,
|
| 69 |
+
complex128,
|
| 70 |
+
int8,
|
| 71 |
+
int16,
|
| 72 |
+
int32,
|
| 73 |
+
int64,
|
| 74 |
+
uint8,
|
| 75 |
+
uint16,
|
| 76 |
+
uint32,
|
| 77 |
+
uint64,
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
_dtype_categories = {
|
| 81 |
+
"all": _all_dtypes,
|
| 82 |
+
"real numeric": _real_numeric_dtypes,
|
| 83 |
+
"numeric": _numeric_dtypes,
|
| 84 |
+
"integer": _integer_dtypes,
|
| 85 |
+
"integer or boolean": _integer_or_boolean_dtypes,
|
| 86 |
+
"boolean": _boolean_dtypes,
|
| 87 |
+
"real floating-point": _floating_dtypes,
|
| 88 |
+
"complex floating-point": _complex_floating_dtypes,
|
| 89 |
+
"floating-point": _floating_dtypes,
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
# Note: the spec defines a restricted type promotion table compared to NumPy.
|
| 94 |
+
# In particular, cross-kind promotions like integer + float or boolean +
|
| 95 |
+
# integer are not allowed, even for functions that accept both kinds.
|
| 96 |
+
# Additionally, NumPy promotes signed integer + uint64 to float64, but this
|
| 97 |
+
# promotion is not allowed here. To be clear, Python scalar int objects are
|
| 98 |
+
# allowed to promote to floating-point dtypes, but only in array operators
|
| 99 |
+
# (see Array._promote_scalar) method in _array_object.py.
|
| 100 |
+
_promotion_table = {
|
| 101 |
+
(int8, int8): int8,
|
| 102 |
+
(int8, int16): int16,
|
| 103 |
+
(int8, int32): int32,
|
| 104 |
+
(int8, int64): int64,
|
| 105 |
+
(int16, int8): int16,
|
| 106 |
+
(int16, int16): int16,
|
| 107 |
+
(int16, int32): int32,
|
| 108 |
+
(int16, int64): int64,
|
| 109 |
+
(int32, int8): int32,
|
| 110 |
+
(int32, int16): int32,
|
| 111 |
+
(int32, int32): int32,
|
| 112 |
+
(int32, int64): int64,
|
| 113 |
+
(int64, int8): int64,
|
| 114 |
+
(int64, int16): int64,
|
| 115 |
+
(int64, int32): int64,
|
| 116 |
+
(int64, int64): int64,
|
| 117 |
+
(uint8, uint8): uint8,
|
| 118 |
+
(uint8, uint16): uint16,
|
| 119 |
+
(uint8, uint32): uint32,
|
| 120 |
+
(uint8, uint64): uint64,
|
| 121 |
+
(uint16, uint8): uint16,
|
| 122 |
+
(uint16, uint16): uint16,
|
| 123 |
+
(uint16, uint32): uint32,
|
| 124 |
+
(uint16, uint64): uint64,
|
| 125 |
+
(uint32, uint8): uint32,
|
| 126 |
+
(uint32, uint16): uint32,
|
| 127 |
+
(uint32, uint32): uint32,
|
| 128 |
+
(uint32, uint64): uint64,
|
| 129 |
+
(uint64, uint8): uint64,
|
| 130 |
+
(uint64, uint16): uint64,
|
| 131 |
+
(uint64, uint32): uint64,
|
| 132 |
+
(uint64, uint64): uint64,
|
| 133 |
+
(int8, uint8): int16,
|
| 134 |
+
(int8, uint16): int32,
|
| 135 |
+
(int8, uint32): int64,
|
| 136 |
+
(int16, uint8): int16,
|
| 137 |
+
(int16, uint16): int32,
|
| 138 |
+
(int16, uint32): int64,
|
| 139 |
+
(int32, uint8): int32,
|
| 140 |
+
(int32, uint16): int32,
|
| 141 |
+
(int32, uint32): int64,
|
| 142 |
+
(int64, uint8): int64,
|
| 143 |
+
(int64, uint16): int64,
|
| 144 |
+
(int64, uint32): int64,
|
| 145 |
+
(uint8, int8): int16,
|
| 146 |
+
(uint16, int8): int32,
|
| 147 |
+
(uint32, int8): int64,
|
| 148 |
+
(uint8, int16): int16,
|
| 149 |
+
(uint16, int16): int32,
|
| 150 |
+
(uint32, int16): int64,
|
| 151 |
+
(uint8, int32): int32,
|
| 152 |
+
(uint16, int32): int32,
|
| 153 |
+
(uint32, int32): int64,
|
| 154 |
+
(uint8, int64): int64,
|
| 155 |
+
(uint16, int64): int64,
|
| 156 |
+
(uint32, int64): int64,
|
| 157 |
+
(float32, float32): float32,
|
| 158 |
+
(float32, float64): float64,
|
| 159 |
+
(float64, float32): float64,
|
| 160 |
+
(float64, float64): float64,
|
| 161 |
+
(complex64, complex64): complex64,
|
| 162 |
+
(complex64, complex128): complex128,
|
| 163 |
+
(complex128, complex64): complex128,
|
| 164 |
+
(complex128, complex128): complex128,
|
| 165 |
+
(float32, complex64): complex64,
|
| 166 |
+
(float32, complex128): complex128,
|
| 167 |
+
(float64, complex64): complex128,
|
| 168 |
+
(float64, complex128): complex128,
|
| 169 |
+
(complex64, float32): complex64,
|
| 170 |
+
(complex64, float64): complex128,
|
| 171 |
+
(complex128, float32): complex128,
|
| 172 |
+
(complex128, float64): complex128,
|
| 173 |
+
(bool, bool): bool,
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
def _result_type(type1, type2):
|
| 178 |
+
if (type1, type2) in _promotion_table:
|
| 179 |
+
return _promotion_table[type1, type2]
|
| 180 |
+
raise TypeError(f"{type1} and {type2} cannot be type promoted together")
|
lib/python3.12/site-packages/numpy/array_api/_elementwise_functions.py
ADDED
|
@@ -0,0 +1,765 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._dtypes import (
|
| 4 |
+
_boolean_dtypes,
|
| 5 |
+
_floating_dtypes,
|
| 6 |
+
_real_floating_dtypes,
|
| 7 |
+
_complex_floating_dtypes,
|
| 8 |
+
_integer_dtypes,
|
| 9 |
+
_integer_or_boolean_dtypes,
|
| 10 |
+
_real_numeric_dtypes,
|
| 11 |
+
_numeric_dtypes,
|
| 12 |
+
_result_type,
|
| 13 |
+
)
|
| 14 |
+
from ._array_object import Array
|
| 15 |
+
|
| 16 |
+
import numpy as np
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def abs(x: Array, /) -> Array:
|
| 20 |
+
"""
|
| 21 |
+
Array API compatible wrapper for :py:func:`np.abs <numpy.abs>`.
|
| 22 |
+
|
| 23 |
+
See its docstring for more information.
|
| 24 |
+
"""
|
| 25 |
+
if x.dtype not in _numeric_dtypes:
|
| 26 |
+
raise TypeError("Only numeric dtypes are allowed in abs")
|
| 27 |
+
return Array._new(np.abs(x._array))
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
# Note: the function name is different here
|
| 31 |
+
def acos(x: Array, /) -> Array:
|
| 32 |
+
"""
|
| 33 |
+
Array API compatible wrapper for :py:func:`np.arccos <numpy.arccos>`.
|
| 34 |
+
|
| 35 |
+
See its docstring for more information.
|
| 36 |
+
"""
|
| 37 |
+
if x.dtype not in _floating_dtypes:
|
| 38 |
+
raise TypeError("Only floating-point dtypes are allowed in acos")
|
| 39 |
+
return Array._new(np.arccos(x._array))
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
# Note: the function name is different here
|
| 43 |
+
def acosh(x: Array, /) -> Array:
|
| 44 |
+
"""
|
| 45 |
+
Array API compatible wrapper for :py:func:`np.arccosh <numpy.arccosh>`.
|
| 46 |
+
|
| 47 |
+
See its docstring for more information.
|
| 48 |
+
"""
|
| 49 |
+
if x.dtype not in _floating_dtypes:
|
| 50 |
+
raise TypeError("Only floating-point dtypes are allowed in acosh")
|
| 51 |
+
return Array._new(np.arccosh(x._array))
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def add(x1: Array, x2: Array, /) -> Array:
|
| 55 |
+
"""
|
| 56 |
+
Array API compatible wrapper for :py:func:`np.add <numpy.add>`.
|
| 57 |
+
|
| 58 |
+
See its docstring for more information.
|
| 59 |
+
"""
|
| 60 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 61 |
+
raise TypeError("Only numeric dtypes are allowed in add")
|
| 62 |
+
# Call result type here just to raise on disallowed type combinations
|
| 63 |
+
_result_type(x1.dtype, x2.dtype)
|
| 64 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 65 |
+
return Array._new(np.add(x1._array, x2._array))
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
# Note: the function name is different here
|
| 69 |
+
def asin(x: Array, /) -> Array:
|
| 70 |
+
"""
|
| 71 |
+
Array API compatible wrapper for :py:func:`np.arcsin <numpy.arcsin>`.
|
| 72 |
+
|
| 73 |
+
See its docstring for more information.
|
| 74 |
+
"""
|
| 75 |
+
if x.dtype not in _floating_dtypes:
|
| 76 |
+
raise TypeError("Only floating-point dtypes are allowed in asin")
|
| 77 |
+
return Array._new(np.arcsin(x._array))
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
# Note: the function name is different here
|
| 81 |
+
def asinh(x: Array, /) -> Array:
|
| 82 |
+
"""
|
| 83 |
+
Array API compatible wrapper for :py:func:`np.arcsinh <numpy.arcsinh>`.
|
| 84 |
+
|
| 85 |
+
See its docstring for more information.
|
| 86 |
+
"""
|
| 87 |
+
if x.dtype not in _floating_dtypes:
|
| 88 |
+
raise TypeError("Only floating-point dtypes are allowed in asinh")
|
| 89 |
+
return Array._new(np.arcsinh(x._array))
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
# Note: the function name is different here
|
| 93 |
+
def atan(x: Array, /) -> Array:
|
| 94 |
+
"""
|
| 95 |
+
Array API compatible wrapper for :py:func:`np.arctan <numpy.arctan>`.
|
| 96 |
+
|
| 97 |
+
See its docstring for more information.
|
| 98 |
+
"""
|
| 99 |
+
if x.dtype not in _floating_dtypes:
|
| 100 |
+
raise TypeError("Only floating-point dtypes are allowed in atan")
|
| 101 |
+
return Array._new(np.arctan(x._array))
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
# Note: the function name is different here
|
| 105 |
+
def atan2(x1: Array, x2: Array, /) -> Array:
|
| 106 |
+
"""
|
| 107 |
+
Array API compatible wrapper for :py:func:`np.arctan2 <numpy.arctan2>`.
|
| 108 |
+
|
| 109 |
+
See its docstring for more information.
|
| 110 |
+
"""
|
| 111 |
+
if x1.dtype not in _real_floating_dtypes or x2.dtype not in _real_floating_dtypes:
|
| 112 |
+
raise TypeError("Only real floating-point dtypes are allowed in atan2")
|
| 113 |
+
# Call result type here just to raise on disallowed type combinations
|
| 114 |
+
_result_type(x1.dtype, x2.dtype)
|
| 115 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 116 |
+
return Array._new(np.arctan2(x1._array, x2._array))
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
# Note: the function name is different here
|
| 120 |
+
def atanh(x: Array, /) -> Array:
|
| 121 |
+
"""
|
| 122 |
+
Array API compatible wrapper for :py:func:`np.arctanh <numpy.arctanh>`.
|
| 123 |
+
|
| 124 |
+
See its docstring for more information.
|
| 125 |
+
"""
|
| 126 |
+
if x.dtype not in _floating_dtypes:
|
| 127 |
+
raise TypeError("Only floating-point dtypes are allowed in atanh")
|
| 128 |
+
return Array._new(np.arctanh(x._array))
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def bitwise_and(x1: Array, x2: Array, /) -> Array:
|
| 132 |
+
"""
|
| 133 |
+
Array API compatible wrapper for :py:func:`np.bitwise_and <numpy.bitwise_and>`.
|
| 134 |
+
|
| 135 |
+
See its docstring for more information.
|
| 136 |
+
"""
|
| 137 |
+
if (
|
| 138 |
+
x1.dtype not in _integer_or_boolean_dtypes
|
| 139 |
+
or x2.dtype not in _integer_or_boolean_dtypes
|
| 140 |
+
):
|
| 141 |
+
raise TypeError("Only integer or boolean dtypes are allowed in bitwise_and")
|
| 142 |
+
# Call result type here just to raise on disallowed type combinations
|
| 143 |
+
_result_type(x1.dtype, x2.dtype)
|
| 144 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 145 |
+
return Array._new(np.bitwise_and(x1._array, x2._array))
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
# Note: the function name is different here
|
| 149 |
+
def bitwise_left_shift(x1: Array, x2: Array, /) -> Array:
|
| 150 |
+
"""
|
| 151 |
+
Array API compatible wrapper for :py:func:`np.left_shift <numpy.left_shift>`.
|
| 152 |
+
|
| 153 |
+
See its docstring for more information.
|
| 154 |
+
"""
|
| 155 |
+
if x1.dtype not in _integer_dtypes or x2.dtype not in _integer_dtypes:
|
| 156 |
+
raise TypeError("Only integer dtypes are allowed in bitwise_left_shift")
|
| 157 |
+
# Call result type here just to raise on disallowed type combinations
|
| 158 |
+
_result_type(x1.dtype, x2.dtype)
|
| 159 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 160 |
+
# Note: bitwise_left_shift is only defined for x2 nonnegative.
|
| 161 |
+
if np.any(x2._array < 0):
|
| 162 |
+
raise ValueError("bitwise_left_shift(x1, x2) is only defined for x2 >= 0")
|
| 163 |
+
return Array._new(np.left_shift(x1._array, x2._array))
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
# Note: the function name is different here
|
| 167 |
+
def bitwise_invert(x: Array, /) -> Array:
|
| 168 |
+
"""
|
| 169 |
+
Array API compatible wrapper for :py:func:`np.invert <numpy.invert>`.
|
| 170 |
+
|
| 171 |
+
See its docstring for more information.
|
| 172 |
+
"""
|
| 173 |
+
if x.dtype not in _integer_or_boolean_dtypes:
|
| 174 |
+
raise TypeError("Only integer or boolean dtypes are allowed in bitwise_invert")
|
| 175 |
+
return Array._new(np.invert(x._array))
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
def bitwise_or(x1: Array, x2: Array, /) -> Array:
|
| 179 |
+
"""
|
| 180 |
+
Array API compatible wrapper for :py:func:`np.bitwise_or <numpy.bitwise_or>`.
|
| 181 |
+
|
| 182 |
+
See its docstring for more information.
|
| 183 |
+
"""
|
| 184 |
+
if (
|
| 185 |
+
x1.dtype not in _integer_or_boolean_dtypes
|
| 186 |
+
or x2.dtype not in _integer_or_boolean_dtypes
|
| 187 |
+
):
|
| 188 |
+
raise TypeError("Only integer or boolean dtypes are allowed in bitwise_or")
|
| 189 |
+
# Call result type here just to raise on disallowed type combinations
|
| 190 |
+
_result_type(x1.dtype, x2.dtype)
|
| 191 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 192 |
+
return Array._new(np.bitwise_or(x1._array, x2._array))
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
# Note: the function name is different here
|
| 196 |
+
def bitwise_right_shift(x1: Array, x2: Array, /) -> Array:
|
| 197 |
+
"""
|
| 198 |
+
Array API compatible wrapper for :py:func:`np.right_shift <numpy.right_shift>`.
|
| 199 |
+
|
| 200 |
+
See its docstring for more information.
|
| 201 |
+
"""
|
| 202 |
+
if x1.dtype not in _integer_dtypes or x2.dtype not in _integer_dtypes:
|
| 203 |
+
raise TypeError("Only integer dtypes are allowed in bitwise_right_shift")
|
| 204 |
+
# Call result type here just to raise on disallowed type combinations
|
| 205 |
+
_result_type(x1.dtype, x2.dtype)
|
| 206 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 207 |
+
# Note: bitwise_right_shift is only defined for x2 nonnegative.
|
| 208 |
+
if np.any(x2._array < 0):
|
| 209 |
+
raise ValueError("bitwise_right_shift(x1, x2) is only defined for x2 >= 0")
|
| 210 |
+
return Array._new(np.right_shift(x1._array, x2._array))
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
def bitwise_xor(x1: Array, x2: Array, /) -> Array:
|
| 214 |
+
"""
|
| 215 |
+
Array API compatible wrapper for :py:func:`np.bitwise_xor <numpy.bitwise_xor>`.
|
| 216 |
+
|
| 217 |
+
See its docstring for more information.
|
| 218 |
+
"""
|
| 219 |
+
if (
|
| 220 |
+
x1.dtype not in _integer_or_boolean_dtypes
|
| 221 |
+
or x2.dtype not in _integer_or_boolean_dtypes
|
| 222 |
+
):
|
| 223 |
+
raise TypeError("Only integer or boolean dtypes are allowed in bitwise_xor")
|
| 224 |
+
# Call result type here just to raise on disallowed type combinations
|
| 225 |
+
_result_type(x1.dtype, x2.dtype)
|
| 226 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 227 |
+
return Array._new(np.bitwise_xor(x1._array, x2._array))
|
| 228 |
+
|
| 229 |
+
|
| 230 |
+
def ceil(x: Array, /) -> Array:
|
| 231 |
+
"""
|
| 232 |
+
Array API compatible wrapper for :py:func:`np.ceil <numpy.ceil>`.
|
| 233 |
+
|
| 234 |
+
See its docstring for more information.
|
| 235 |
+
"""
|
| 236 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 237 |
+
raise TypeError("Only real numeric dtypes are allowed in ceil")
|
| 238 |
+
if x.dtype in _integer_dtypes:
|
| 239 |
+
# Note: The return dtype of ceil is the same as the input
|
| 240 |
+
return x
|
| 241 |
+
return Array._new(np.ceil(x._array))
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
def conj(x: Array, /) -> Array:
|
| 245 |
+
"""
|
| 246 |
+
Array API compatible wrapper for :py:func:`np.conj <numpy.conj>`.
|
| 247 |
+
|
| 248 |
+
See its docstring for more information.
|
| 249 |
+
"""
|
| 250 |
+
if x.dtype not in _complex_floating_dtypes:
|
| 251 |
+
raise TypeError("Only complex floating-point dtypes are allowed in conj")
|
| 252 |
+
return Array._new(np.conj(x))
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
def cos(x: Array, /) -> Array:
|
| 256 |
+
"""
|
| 257 |
+
Array API compatible wrapper for :py:func:`np.cos <numpy.cos>`.
|
| 258 |
+
|
| 259 |
+
See its docstring for more information.
|
| 260 |
+
"""
|
| 261 |
+
if x.dtype not in _floating_dtypes:
|
| 262 |
+
raise TypeError("Only floating-point dtypes are allowed in cos")
|
| 263 |
+
return Array._new(np.cos(x._array))
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
def cosh(x: Array, /) -> Array:
|
| 267 |
+
"""
|
| 268 |
+
Array API compatible wrapper for :py:func:`np.cosh <numpy.cosh>`.
|
| 269 |
+
|
| 270 |
+
See its docstring for more information.
|
| 271 |
+
"""
|
| 272 |
+
if x.dtype not in _floating_dtypes:
|
| 273 |
+
raise TypeError("Only floating-point dtypes are allowed in cosh")
|
| 274 |
+
return Array._new(np.cosh(x._array))
|
| 275 |
+
|
| 276 |
+
|
| 277 |
+
def divide(x1: Array, x2: Array, /) -> Array:
|
| 278 |
+
"""
|
| 279 |
+
Array API compatible wrapper for :py:func:`np.divide <numpy.divide>`.
|
| 280 |
+
|
| 281 |
+
See its docstring for more information.
|
| 282 |
+
"""
|
| 283 |
+
if x1.dtype not in _floating_dtypes or x2.dtype not in _floating_dtypes:
|
| 284 |
+
raise TypeError("Only floating-point dtypes are allowed in divide")
|
| 285 |
+
# Call result type here just to raise on disallowed type combinations
|
| 286 |
+
_result_type(x1.dtype, x2.dtype)
|
| 287 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 288 |
+
return Array._new(np.divide(x1._array, x2._array))
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def equal(x1: Array, x2: Array, /) -> Array:
|
| 292 |
+
"""
|
| 293 |
+
Array API compatible wrapper for :py:func:`np.equal <numpy.equal>`.
|
| 294 |
+
|
| 295 |
+
See its docstring for more information.
|
| 296 |
+
"""
|
| 297 |
+
# Call result type here just to raise on disallowed type combinations
|
| 298 |
+
_result_type(x1.dtype, x2.dtype)
|
| 299 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 300 |
+
return Array._new(np.equal(x1._array, x2._array))
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
def exp(x: Array, /) -> Array:
|
| 304 |
+
"""
|
| 305 |
+
Array API compatible wrapper for :py:func:`np.exp <numpy.exp>`.
|
| 306 |
+
|
| 307 |
+
See its docstring for more information.
|
| 308 |
+
"""
|
| 309 |
+
if x.dtype not in _floating_dtypes:
|
| 310 |
+
raise TypeError("Only floating-point dtypes are allowed in exp")
|
| 311 |
+
return Array._new(np.exp(x._array))
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
def expm1(x: Array, /) -> Array:
|
| 315 |
+
"""
|
| 316 |
+
Array API compatible wrapper for :py:func:`np.expm1 <numpy.expm1>`.
|
| 317 |
+
|
| 318 |
+
See its docstring for more information.
|
| 319 |
+
"""
|
| 320 |
+
if x.dtype not in _floating_dtypes:
|
| 321 |
+
raise TypeError("Only floating-point dtypes are allowed in expm1")
|
| 322 |
+
return Array._new(np.expm1(x._array))
|
| 323 |
+
|
| 324 |
+
|
| 325 |
+
def floor(x: Array, /) -> Array:
|
| 326 |
+
"""
|
| 327 |
+
Array API compatible wrapper for :py:func:`np.floor <numpy.floor>`.
|
| 328 |
+
|
| 329 |
+
See its docstring for more information.
|
| 330 |
+
"""
|
| 331 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 332 |
+
raise TypeError("Only real numeric dtypes are allowed in floor")
|
| 333 |
+
if x.dtype in _integer_dtypes:
|
| 334 |
+
# Note: The return dtype of floor is the same as the input
|
| 335 |
+
return x
|
| 336 |
+
return Array._new(np.floor(x._array))
|
| 337 |
+
|
| 338 |
+
|
| 339 |
+
def floor_divide(x1: Array, x2: Array, /) -> Array:
|
| 340 |
+
"""
|
| 341 |
+
Array API compatible wrapper for :py:func:`np.floor_divide <numpy.floor_divide>`.
|
| 342 |
+
|
| 343 |
+
See its docstring for more information.
|
| 344 |
+
"""
|
| 345 |
+
if x1.dtype not in _real_numeric_dtypes or x2.dtype not in _real_numeric_dtypes:
|
| 346 |
+
raise TypeError("Only real numeric dtypes are allowed in floor_divide")
|
| 347 |
+
# Call result type here just to raise on disallowed type combinations
|
| 348 |
+
_result_type(x1.dtype, x2.dtype)
|
| 349 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 350 |
+
return Array._new(np.floor_divide(x1._array, x2._array))
|
| 351 |
+
|
| 352 |
+
|
| 353 |
+
def greater(x1: Array, x2: Array, /) -> Array:
|
| 354 |
+
"""
|
| 355 |
+
Array API compatible wrapper for :py:func:`np.greater <numpy.greater>`.
|
| 356 |
+
|
| 357 |
+
See its docstring for more information.
|
| 358 |
+
"""
|
| 359 |
+
if x1.dtype not in _real_numeric_dtypes or x2.dtype not in _real_numeric_dtypes:
|
| 360 |
+
raise TypeError("Only real numeric dtypes are allowed in greater")
|
| 361 |
+
# Call result type here just to raise on disallowed type combinations
|
| 362 |
+
_result_type(x1.dtype, x2.dtype)
|
| 363 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 364 |
+
return Array._new(np.greater(x1._array, x2._array))
|
| 365 |
+
|
| 366 |
+
|
| 367 |
+
def greater_equal(x1: Array, x2: Array, /) -> Array:
|
| 368 |
+
"""
|
| 369 |
+
Array API compatible wrapper for :py:func:`np.greater_equal <numpy.greater_equal>`.
|
| 370 |
+
|
| 371 |
+
See its docstring for more information.
|
| 372 |
+
"""
|
| 373 |
+
if x1.dtype not in _real_numeric_dtypes or x2.dtype not in _real_numeric_dtypes:
|
| 374 |
+
raise TypeError("Only real numeric dtypes are allowed in greater_equal")
|
| 375 |
+
# Call result type here just to raise on disallowed type combinations
|
| 376 |
+
_result_type(x1.dtype, x2.dtype)
|
| 377 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 378 |
+
return Array._new(np.greater_equal(x1._array, x2._array))
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
def imag(x: Array, /) -> Array:
|
| 382 |
+
"""
|
| 383 |
+
Array API compatible wrapper for :py:func:`np.imag <numpy.imag>`.
|
| 384 |
+
|
| 385 |
+
See its docstring for more information.
|
| 386 |
+
"""
|
| 387 |
+
if x.dtype not in _complex_floating_dtypes:
|
| 388 |
+
raise TypeError("Only complex floating-point dtypes are allowed in imag")
|
| 389 |
+
return Array._new(np.imag(x))
|
| 390 |
+
|
| 391 |
+
|
| 392 |
+
def isfinite(x: Array, /) -> Array:
|
| 393 |
+
"""
|
| 394 |
+
Array API compatible wrapper for :py:func:`np.isfinite <numpy.isfinite>`.
|
| 395 |
+
|
| 396 |
+
See its docstring for more information.
|
| 397 |
+
"""
|
| 398 |
+
if x.dtype not in _numeric_dtypes:
|
| 399 |
+
raise TypeError("Only numeric dtypes are allowed in isfinite")
|
| 400 |
+
return Array._new(np.isfinite(x._array))
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
def isinf(x: Array, /) -> Array:
|
| 404 |
+
"""
|
| 405 |
+
Array API compatible wrapper for :py:func:`np.isinf <numpy.isinf>`.
|
| 406 |
+
|
| 407 |
+
See its docstring for more information.
|
| 408 |
+
"""
|
| 409 |
+
if x.dtype not in _numeric_dtypes:
|
| 410 |
+
raise TypeError("Only numeric dtypes are allowed in isinf")
|
| 411 |
+
return Array._new(np.isinf(x._array))
|
| 412 |
+
|
| 413 |
+
|
| 414 |
+
def isnan(x: Array, /) -> Array:
|
| 415 |
+
"""
|
| 416 |
+
Array API compatible wrapper for :py:func:`np.isnan <numpy.isnan>`.
|
| 417 |
+
|
| 418 |
+
See its docstring for more information.
|
| 419 |
+
"""
|
| 420 |
+
if x.dtype not in _numeric_dtypes:
|
| 421 |
+
raise TypeError("Only numeric dtypes are allowed in isnan")
|
| 422 |
+
return Array._new(np.isnan(x._array))
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
def less(x1: Array, x2: Array, /) -> Array:
|
| 426 |
+
"""
|
| 427 |
+
Array API compatible wrapper for :py:func:`np.less <numpy.less>`.
|
| 428 |
+
|
| 429 |
+
See its docstring for more information.
|
| 430 |
+
"""
|
| 431 |
+
if x1.dtype not in _real_numeric_dtypes or x2.dtype not in _real_numeric_dtypes:
|
| 432 |
+
raise TypeError("Only real numeric dtypes are allowed in less")
|
| 433 |
+
# Call result type here just to raise on disallowed type combinations
|
| 434 |
+
_result_type(x1.dtype, x2.dtype)
|
| 435 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 436 |
+
return Array._new(np.less(x1._array, x2._array))
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
def less_equal(x1: Array, x2: Array, /) -> Array:
|
| 440 |
+
"""
|
| 441 |
+
Array API compatible wrapper for :py:func:`np.less_equal <numpy.less_equal>`.
|
| 442 |
+
|
| 443 |
+
See its docstring for more information.
|
| 444 |
+
"""
|
| 445 |
+
if x1.dtype not in _real_numeric_dtypes or x2.dtype not in _real_numeric_dtypes:
|
| 446 |
+
raise TypeError("Only real numeric dtypes are allowed in less_equal")
|
| 447 |
+
# Call result type here just to raise on disallowed type combinations
|
| 448 |
+
_result_type(x1.dtype, x2.dtype)
|
| 449 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 450 |
+
return Array._new(np.less_equal(x1._array, x2._array))
|
| 451 |
+
|
| 452 |
+
|
| 453 |
+
def log(x: Array, /) -> Array:
|
| 454 |
+
"""
|
| 455 |
+
Array API compatible wrapper for :py:func:`np.log <numpy.log>`.
|
| 456 |
+
|
| 457 |
+
See its docstring for more information.
|
| 458 |
+
"""
|
| 459 |
+
if x.dtype not in _floating_dtypes:
|
| 460 |
+
raise TypeError("Only floating-point dtypes are allowed in log")
|
| 461 |
+
return Array._new(np.log(x._array))
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
def log1p(x: Array, /) -> Array:
|
| 465 |
+
"""
|
| 466 |
+
Array API compatible wrapper for :py:func:`np.log1p <numpy.log1p>`.
|
| 467 |
+
|
| 468 |
+
See its docstring for more information.
|
| 469 |
+
"""
|
| 470 |
+
if x.dtype not in _floating_dtypes:
|
| 471 |
+
raise TypeError("Only floating-point dtypes are allowed in log1p")
|
| 472 |
+
return Array._new(np.log1p(x._array))
|
| 473 |
+
|
| 474 |
+
|
| 475 |
+
def log2(x: Array, /) -> Array:
|
| 476 |
+
"""
|
| 477 |
+
Array API compatible wrapper for :py:func:`np.log2 <numpy.log2>`.
|
| 478 |
+
|
| 479 |
+
See its docstring for more information.
|
| 480 |
+
"""
|
| 481 |
+
if x.dtype not in _floating_dtypes:
|
| 482 |
+
raise TypeError("Only floating-point dtypes are allowed in log2")
|
| 483 |
+
return Array._new(np.log2(x._array))
|
| 484 |
+
|
| 485 |
+
|
| 486 |
+
def log10(x: Array, /) -> Array:
|
| 487 |
+
"""
|
| 488 |
+
Array API compatible wrapper for :py:func:`np.log10 <numpy.log10>`.
|
| 489 |
+
|
| 490 |
+
See its docstring for more information.
|
| 491 |
+
"""
|
| 492 |
+
if x.dtype not in _floating_dtypes:
|
| 493 |
+
raise TypeError("Only floating-point dtypes are allowed in log10")
|
| 494 |
+
return Array._new(np.log10(x._array))
|
| 495 |
+
|
| 496 |
+
|
| 497 |
+
def logaddexp(x1: Array, x2: Array) -> Array:
|
| 498 |
+
"""
|
| 499 |
+
Array API compatible wrapper for :py:func:`np.logaddexp <numpy.logaddexp>`.
|
| 500 |
+
|
| 501 |
+
See its docstring for more information.
|
| 502 |
+
"""
|
| 503 |
+
if x1.dtype not in _real_floating_dtypes or x2.dtype not in _real_floating_dtypes:
|
| 504 |
+
raise TypeError("Only real floating-point dtypes are allowed in logaddexp")
|
| 505 |
+
# Call result type here just to raise on disallowed type combinations
|
| 506 |
+
_result_type(x1.dtype, x2.dtype)
|
| 507 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 508 |
+
return Array._new(np.logaddexp(x1._array, x2._array))
|
| 509 |
+
|
| 510 |
+
|
| 511 |
+
def logical_and(x1: Array, x2: Array, /) -> Array:
|
| 512 |
+
"""
|
| 513 |
+
Array API compatible wrapper for :py:func:`np.logical_and <numpy.logical_and>`.
|
| 514 |
+
|
| 515 |
+
See its docstring for more information.
|
| 516 |
+
"""
|
| 517 |
+
if x1.dtype not in _boolean_dtypes or x2.dtype not in _boolean_dtypes:
|
| 518 |
+
raise TypeError("Only boolean dtypes are allowed in logical_and")
|
| 519 |
+
# Call result type here just to raise on disallowed type combinations
|
| 520 |
+
_result_type(x1.dtype, x2.dtype)
|
| 521 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 522 |
+
return Array._new(np.logical_and(x1._array, x2._array))
|
| 523 |
+
|
| 524 |
+
|
| 525 |
+
def logical_not(x: Array, /) -> Array:
|
| 526 |
+
"""
|
| 527 |
+
Array API compatible wrapper for :py:func:`np.logical_not <numpy.logical_not>`.
|
| 528 |
+
|
| 529 |
+
See its docstring for more information.
|
| 530 |
+
"""
|
| 531 |
+
if x.dtype not in _boolean_dtypes:
|
| 532 |
+
raise TypeError("Only boolean dtypes are allowed in logical_not")
|
| 533 |
+
return Array._new(np.logical_not(x._array))
|
| 534 |
+
|
| 535 |
+
|
| 536 |
+
def logical_or(x1: Array, x2: Array, /) -> Array:
|
| 537 |
+
"""
|
| 538 |
+
Array API compatible wrapper for :py:func:`np.logical_or <numpy.logical_or>`.
|
| 539 |
+
|
| 540 |
+
See its docstring for more information.
|
| 541 |
+
"""
|
| 542 |
+
if x1.dtype not in _boolean_dtypes or x2.dtype not in _boolean_dtypes:
|
| 543 |
+
raise TypeError("Only boolean dtypes are allowed in logical_or")
|
| 544 |
+
# Call result type here just to raise on disallowed type combinations
|
| 545 |
+
_result_type(x1.dtype, x2.dtype)
|
| 546 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 547 |
+
return Array._new(np.logical_or(x1._array, x2._array))
|
| 548 |
+
|
| 549 |
+
|
| 550 |
+
def logical_xor(x1: Array, x2: Array, /) -> Array:
|
| 551 |
+
"""
|
| 552 |
+
Array API compatible wrapper for :py:func:`np.logical_xor <numpy.logical_xor>`.
|
| 553 |
+
|
| 554 |
+
See its docstring for more information.
|
| 555 |
+
"""
|
| 556 |
+
if x1.dtype not in _boolean_dtypes or x2.dtype not in _boolean_dtypes:
|
| 557 |
+
raise TypeError("Only boolean dtypes are allowed in logical_xor")
|
| 558 |
+
# Call result type here just to raise on disallowed type combinations
|
| 559 |
+
_result_type(x1.dtype, x2.dtype)
|
| 560 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 561 |
+
return Array._new(np.logical_xor(x1._array, x2._array))
|
| 562 |
+
|
| 563 |
+
|
| 564 |
+
def multiply(x1: Array, x2: Array, /) -> Array:
|
| 565 |
+
"""
|
| 566 |
+
Array API compatible wrapper for :py:func:`np.multiply <numpy.multiply>`.
|
| 567 |
+
|
| 568 |
+
See its docstring for more information.
|
| 569 |
+
"""
|
| 570 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 571 |
+
raise TypeError("Only numeric dtypes are allowed in multiply")
|
| 572 |
+
# Call result type here just to raise on disallowed type combinations
|
| 573 |
+
_result_type(x1.dtype, x2.dtype)
|
| 574 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 575 |
+
return Array._new(np.multiply(x1._array, x2._array))
|
| 576 |
+
|
| 577 |
+
|
| 578 |
+
def negative(x: Array, /) -> Array:
|
| 579 |
+
"""
|
| 580 |
+
Array API compatible wrapper for :py:func:`np.negative <numpy.negative>`.
|
| 581 |
+
|
| 582 |
+
See its docstring for more information.
|
| 583 |
+
"""
|
| 584 |
+
if x.dtype not in _numeric_dtypes:
|
| 585 |
+
raise TypeError("Only numeric dtypes are allowed in negative")
|
| 586 |
+
return Array._new(np.negative(x._array))
|
| 587 |
+
|
| 588 |
+
|
| 589 |
+
def not_equal(x1: Array, x2: Array, /) -> Array:
|
| 590 |
+
"""
|
| 591 |
+
Array API compatible wrapper for :py:func:`np.not_equal <numpy.not_equal>`.
|
| 592 |
+
|
| 593 |
+
See its docstring for more information.
|
| 594 |
+
"""
|
| 595 |
+
# Call result type here just to raise on disallowed type combinations
|
| 596 |
+
_result_type(x1.dtype, x2.dtype)
|
| 597 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 598 |
+
return Array._new(np.not_equal(x1._array, x2._array))
|
| 599 |
+
|
| 600 |
+
|
| 601 |
+
def positive(x: Array, /) -> Array:
|
| 602 |
+
"""
|
| 603 |
+
Array API compatible wrapper for :py:func:`np.positive <numpy.positive>`.
|
| 604 |
+
|
| 605 |
+
See its docstring for more information.
|
| 606 |
+
"""
|
| 607 |
+
if x.dtype not in _numeric_dtypes:
|
| 608 |
+
raise TypeError("Only numeric dtypes are allowed in positive")
|
| 609 |
+
return Array._new(np.positive(x._array))
|
| 610 |
+
|
| 611 |
+
|
| 612 |
+
# Note: the function name is different here
|
| 613 |
+
def pow(x1: Array, x2: Array, /) -> Array:
|
| 614 |
+
"""
|
| 615 |
+
Array API compatible wrapper for :py:func:`np.power <numpy.power>`.
|
| 616 |
+
|
| 617 |
+
See its docstring for more information.
|
| 618 |
+
"""
|
| 619 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 620 |
+
raise TypeError("Only numeric dtypes are allowed in pow")
|
| 621 |
+
# Call result type here just to raise on disallowed type combinations
|
| 622 |
+
_result_type(x1.dtype, x2.dtype)
|
| 623 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 624 |
+
return Array._new(np.power(x1._array, x2._array))
|
| 625 |
+
|
| 626 |
+
|
| 627 |
+
def real(x: Array, /) -> Array:
|
| 628 |
+
"""
|
| 629 |
+
Array API compatible wrapper for :py:func:`np.real <numpy.real>`.
|
| 630 |
+
|
| 631 |
+
See its docstring for more information.
|
| 632 |
+
"""
|
| 633 |
+
if x.dtype not in _complex_floating_dtypes:
|
| 634 |
+
raise TypeError("Only complex floating-point dtypes are allowed in real")
|
| 635 |
+
return Array._new(np.real(x))
|
| 636 |
+
|
| 637 |
+
|
| 638 |
+
def remainder(x1: Array, x2: Array, /) -> Array:
|
| 639 |
+
"""
|
| 640 |
+
Array API compatible wrapper for :py:func:`np.remainder <numpy.remainder>`.
|
| 641 |
+
|
| 642 |
+
See its docstring for more information.
|
| 643 |
+
"""
|
| 644 |
+
if x1.dtype not in _real_numeric_dtypes or x2.dtype not in _real_numeric_dtypes:
|
| 645 |
+
raise TypeError("Only real numeric dtypes are allowed in remainder")
|
| 646 |
+
# Call result type here just to raise on disallowed type combinations
|
| 647 |
+
_result_type(x1.dtype, x2.dtype)
|
| 648 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 649 |
+
return Array._new(np.remainder(x1._array, x2._array))
|
| 650 |
+
|
| 651 |
+
|
| 652 |
+
def round(x: Array, /) -> Array:
|
| 653 |
+
"""
|
| 654 |
+
Array API compatible wrapper for :py:func:`np.round <numpy.round>`.
|
| 655 |
+
|
| 656 |
+
See its docstring for more information.
|
| 657 |
+
"""
|
| 658 |
+
if x.dtype not in _numeric_dtypes:
|
| 659 |
+
raise TypeError("Only numeric dtypes are allowed in round")
|
| 660 |
+
return Array._new(np.round(x._array))
|
| 661 |
+
|
| 662 |
+
|
| 663 |
+
def sign(x: Array, /) -> Array:
|
| 664 |
+
"""
|
| 665 |
+
Array API compatible wrapper for :py:func:`np.sign <numpy.sign>`.
|
| 666 |
+
|
| 667 |
+
See its docstring for more information.
|
| 668 |
+
"""
|
| 669 |
+
if x.dtype not in _numeric_dtypes:
|
| 670 |
+
raise TypeError("Only numeric dtypes are allowed in sign")
|
| 671 |
+
return Array._new(np.sign(x._array))
|
| 672 |
+
|
| 673 |
+
|
| 674 |
+
def sin(x: Array, /) -> Array:
|
| 675 |
+
"""
|
| 676 |
+
Array API compatible wrapper for :py:func:`np.sin <numpy.sin>`.
|
| 677 |
+
|
| 678 |
+
See its docstring for more information.
|
| 679 |
+
"""
|
| 680 |
+
if x.dtype not in _floating_dtypes:
|
| 681 |
+
raise TypeError("Only floating-point dtypes are allowed in sin")
|
| 682 |
+
return Array._new(np.sin(x._array))
|
| 683 |
+
|
| 684 |
+
|
| 685 |
+
def sinh(x: Array, /) -> Array:
|
| 686 |
+
"""
|
| 687 |
+
Array API compatible wrapper for :py:func:`np.sinh <numpy.sinh>`.
|
| 688 |
+
|
| 689 |
+
See its docstring for more information.
|
| 690 |
+
"""
|
| 691 |
+
if x.dtype not in _floating_dtypes:
|
| 692 |
+
raise TypeError("Only floating-point dtypes are allowed in sinh")
|
| 693 |
+
return Array._new(np.sinh(x._array))
|
| 694 |
+
|
| 695 |
+
|
| 696 |
+
def square(x: Array, /) -> Array:
|
| 697 |
+
"""
|
| 698 |
+
Array API compatible wrapper for :py:func:`np.square <numpy.square>`.
|
| 699 |
+
|
| 700 |
+
See its docstring for more information.
|
| 701 |
+
"""
|
| 702 |
+
if x.dtype not in _numeric_dtypes:
|
| 703 |
+
raise TypeError("Only numeric dtypes are allowed in square")
|
| 704 |
+
return Array._new(np.square(x._array))
|
| 705 |
+
|
| 706 |
+
|
| 707 |
+
def sqrt(x: Array, /) -> Array:
|
| 708 |
+
"""
|
| 709 |
+
Array API compatible wrapper for :py:func:`np.sqrt <numpy.sqrt>`.
|
| 710 |
+
|
| 711 |
+
See its docstring for more information.
|
| 712 |
+
"""
|
| 713 |
+
if x.dtype not in _floating_dtypes:
|
| 714 |
+
raise TypeError("Only floating-point dtypes are allowed in sqrt")
|
| 715 |
+
return Array._new(np.sqrt(x._array))
|
| 716 |
+
|
| 717 |
+
|
| 718 |
+
def subtract(x1: Array, x2: Array, /) -> Array:
|
| 719 |
+
"""
|
| 720 |
+
Array API compatible wrapper for :py:func:`np.subtract <numpy.subtract>`.
|
| 721 |
+
|
| 722 |
+
See its docstring for more information.
|
| 723 |
+
"""
|
| 724 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 725 |
+
raise TypeError("Only numeric dtypes are allowed in subtract")
|
| 726 |
+
# Call result type here just to raise on disallowed type combinations
|
| 727 |
+
_result_type(x1.dtype, x2.dtype)
|
| 728 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 729 |
+
return Array._new(np.subtract(x1._array, x2._array))
|
| 730 |
+
|
| 731 |
+
|
| 732 |
+
def tan(x: Array, /) -> Array:
|
| 733 |
+
"""
|
| 734 |
+
Array API compatible wrapper for :py:func:`np.tan <numpy.tan>`.
|
| 735 |
+
|
| 736 |
+
See its docstring for more information.
|
| 737 |
+
"""
|
| 738 |
+
if x.dtype not in _floating_dtypes:
|
| 739 |
+
raise TypeError("Only floating-point dtypes are allowed in tan")
|
| 740 |
+
return Array._new(np.tan(x._array))
|
| 741 |
+
|
| 742 |
+
|
| 743 |
+
def tanh(x: Array, /) -> Array:
|
| 744 |
+
"""
|
| 745 |
+
Array API compatible wrapper for :py:func:`np.tanh <numpy.tanh>`.
|
| 746 |
+
|
| 747 |
+
See its docstring for more information.
|
| 748 |
+
"""
|
| 749 |
+
if x.dtype not in _floating_dtypes:
|
| 750 |
+
raise TypeError("Only floating-point dtypes are allowed in tanh")
|
| 751 |
+
return Array._new(np.tanh(x._array))
|
| 752 |
+
|
| 753 |
+
|
| 754 |
+
def trunc(x: Array, /) -> Array:
|
| 755 |
+
"""
|
| 756 |
+
Array API compatible wrapper for :py:func:`np.trunc <numpy.trunc>`.
|
| 757 |
+
|
| 758 |
+
See its docstring for more information.
|
| 759 |
+
"""
|
| 760 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 761 |
+
raise TypeError("Only real numeric dtypes are allowed in trunc")
|
| 762 |
+
if x.dtype in _integer_dtypes:
|
| 763 |
+
# Note: The return dtype of trunc is the same as the input
|
| 764 |
+
return x
|
| 765 |
+
return Array._new(np.trunc(x._array))
|
lib/python3.12/site-packages/numpy/array_api/_indexing_functions.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._array_object import Array
|
| 4 |
+
from ._dtypes import _integer_dtypes
|
| 5 |
+
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
def take(x: Array, indices: Array, /, *, axis: Optional[int] = None) -> Array:
|
| 9 |
+
"""
|
| 10 |
+
Array API compatible wrapper for :py:func:`np.take <numpy.take>`.
|
| 11 |
+
|
| 12 |
+
See its docstring for more information.
|
| 13 |
+
"""
|
| 14 |
+
if axis is None and x.ndim != 1:
|
| 15 |
+
raise ValueError("axis must be specified when ndim > 1")
|
| 16 |
+
if indices.dtype not in _integer_dtypes:
|
| 17 |
+
raise TypeError("Only integer dtypes are allowed in indexing")
|
| 18 |
+
if indices.ndim != 1:
|
| 19 |
+
raise ValueError("Only 1-dim indices array is supported")
|
| 20 |
+
return Array._new(np.take(x._array, indices._array, axis=axis))
|
lib/python3.12/site-packages/numpy/array_api/_manipulation_functions.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._array_object import Array
|
| 4 |
+
from ._data_type_functions import result_type
|
| 5 |
+
|
| 6 |
+
from typing import List, Optional, Tuple, Union
|
| 7 |
+
|
| 8 |
+
import numpy as np
|
| 9 |
+
|
| 10 |
+
# Note: the function name is different here
|
| 11 |
+
def concat(
|
| 12 |
+
arrays: Union[Tuple[Array, ...], List[Array]], /, *, axis: Optional[int] = 0
|
| 13 |
+
) -> Array:
|
| 14 |
+
"""
|
| 15 |
+
Array API compatible wrapper for :py:func:`np.concatenate <numpy.concatenate>`.
|
| 16 |
+
|
| 17 |
+
See its docstring for more information.
|
| 18 |
+
"""
|
| 19 |
+
# Note: Casting rules here are different from the np.concatenate default
|
| 20 |
+
# (no for scalars with axis=None, no cross-kind casting)
|
| 21 |
+
dtype = result_type(*arrays)
|
| 22 |
+
arrays = tuple(a._array for a in arrays)
|
| 23 |
+
return Array._new(np.concatenate(arrays, axis=axis, dtype=dtype))
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def expand_dims(x: Array, /, *, axis: int) -> Array:
|
| 27 |
+
"""
|
| 28 |
+
Array API compatible wrapper for :py:func:`np.expand_dims <numpy.expand_dims>`.
|
| 29 |
+
|
| 30 |
+
See its docstring for more information.
|
| 31 |
+
"""
|
| 32 |
+
return Array._new(np.expand_dims(x._array, axis))
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def flip(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None) -> Array:
|
| 36 |
+
"""
|
| 37 |
+
Array API compatible wrapper for :py:func:`np.flip <numpy.flip>`.
|
| 38 |
+
|
| 39 |
+
See its docstring for more information.
|
| 40 |
+
"""
|
| 41 |
+
return Array._new(np.flip(x._array, axis=axis))
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
# Note: The function name is different here (see also matrix_transpose).
|
| 45 |
+
# Unlike transpose(), the axes argument is required.
|
| 46 |
+
def permute_dims(x: Array, /, axes: Tuple[int, ...]) -> Array:
|
| 47 |
+
"""
|
| 48 |
+
Array API compatible wrapper for :py:func:`np.transpose <numpy.transpose>`.
|
| 49 |
+
|
| 50 |
+
See its docstring for more information.
|
| 51 |
+
"""
|
| 52 |
+
return Array._new(np.transpose(x._array, axes))
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
# Note: the optional argument is called 'shape', not 'newshape'
|
| 56 |
+
def reshape(x: Array,
|
| 57 |
+
/,
|
| 58 |
+
shape: Tuple[int, ...],
|
| 59 |
+
*,
|
| 60 |
+
copy: Optional[Bool] = None) -> Array:
|
| 61 |
+
"""
|
| 62 |
+
Array API compatible wrapper for :py:func:`np.reshape <numpy.reshape>`.
|
| 63 |
+
|
| 64 |
+
See its docstring for more information.
|
| 65 |
+
"""
|
| 66 |
+
|
| 67 |
+
data = x._array
|
| 68 |
+
if copy:
|
| 69 |
+
data = np.copy(data)
|
| 70 |
+
|
| 71 |
+
reshaped = np.reshape(data, shape)
|
| 72 |
+
|
| 73 |
+
if copy is False and not np.shares_memory(data, reshaped):
|
| 74 |
+
raise AttributeError("Incompatible shape for in-place modification.")
|
| 75 |
+
|
| 76 |
+
return Array._new(reshaped)
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def roll(
|
| 80 |
+
x: Array,
|
| 81 |
+
/,
|
| 82 |
+
shift: Union[int, Tuple[int, ...]],
|
| 83 |
+
*,
|
| 84 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 85 |
+
) -> Array:
|
| 86 |
+
"""
|
| 87 |
+
Array API compatible wrapper for :py:func:`np.roll <numpy.roll>`.
|
| 88 |
+
|
| 89 |
+
See its docstring for more information.
|
| 90 |
+
"""
|
| 91 |
+
return Array._new(np.roll(x._array, shift, axis=axis))
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def squeeze(x: Array, /, axis: Union[int, Tuple[int, ...]]) -> Array:
|
| 95 |
+
"""
|
| 96 |
+
Array API compatible wrapper for :py:func:`np.squeeze <numpy.squeeze>`.
|
| 97 |
+
|
| 98 |
+
See its docstring for more information.
|
| 99 |
+
"""
|
| 100 |
+
return Array._new(np.squeeze(x._array, axis=axis))
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def stack(arrays: Union[Tuple[Array, ...], List[Array]], /, *, axis: int = 0) -> Array:
|
| 104 |
+
"""
|
| 105 |
+
Array API compatible wrapper for :py:func:`np.stack <numpy.stack>`.
|
| 106 |
+
|
| 107 |
+
See its docstring for more information.
|
| 108 |
+
"""
|
| 109 |
+
# Call result type here just to raise on disallowed type combinations
|
| 110 |
+
result_type(*arrays)
|
| 111 |
+
arrays = tuple(a._array for a in arrays)
|
| 112 |
+
return Array._new(np.stack(arrays, axis=axis))
|
lib/python3.12/site-packages/numpy/array_api/_searching_functions.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._array_object import Array
|
| 4 |
+
from ._dtypes import _result_type, _real_numeric_dtypes
|
| 5 |
+
|
| 6 |
+
from typing import Optional, Tuple
|
| 7 |
+
|
| 8 |
+
import numpy as np
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def argmax(x: Array, /, *, axis: Optional[int] = None, keepdims: bool = False) -> Array:
|
| 12 |
+
"""
|
| 13 |
+
Array API compatible wrapper for :py:func:`np.argmax <numpy.argmax>`.
|
| 14 |
+
|
| 15 |
+
See its docstring for more information.
|
| 16 |
+
"""
|
| 17 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 18 |
+
raise TypeError("Only real numeric dtypes are allowed in argmax")
|
| 19 |
+
return Array._new(np.asarray(np.argmax(x._array, axis=axis, keepdims=keepdims)))
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def argmin(x: Array, /, *, axis: Optional[int] = None, keepdims: bool = False) -> Array:
|
| 23 |
+
"""
|
| 24 |
+
Array API compatible wrapper for :py:func:`np.argmin <numpy.argmin>`.
|
| 25 |
+
|
| 26 |
+
See its docstring for more information.
|
| 27 |
+
"""
|
| 28 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 29 |
+
raise TypeError("Only real numeric dtypes are allowed in argmin")
|
| 30 |
+
return Array._new(np.asarray(np.argmin(x._array, axis=axis, keepdims=keepdims)))
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def nonzero(x: Array, /) -> Tuple[Array, ...]:
|
| 34 |
+
"""
|
| 35 |
+
Array API compatible wrapper for :py:func:`np.nonzero <numpy.nonzero>`.
|
| 36 |
+
|
| 37 |
+
See its docstring for more information.
|
| 38 |
+
"""
|
| 39 |
+
return tuple(Array._new(i) for i in np.nonzero(x._array))
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def where(condition: Array, x1: Array, x2: Array, /) -> Array:
|
| 43 |
+
"""
|
| 44 |
+
Array API compatible wrapper for :py:func:`np.where <numpy.where>`.
|
| 45 |
+
|
| 46 |
+
See its docstring for more information.
|
| 47 |
+
"""
|
| 48 |
+
# Call result type here just to raise on disallowed type combinations
|
| 49 |
+
_result_type(x1.dtype, x2.dtype)
|
| 50 |
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
| 51 |
+
return Array._new(np.where(condition._array, x1._array, x2._array))
|
lib/python3.12/site-packages/numpy/array_api/_set_functions.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._array_object import Array
|
| 4 |
+
|
| 5 |
+
from typing import NamedTuple
|
| 6 |
+
|
| 7 |
+
import numpy as np
|
| 8 |
+
|
| 9 |
+
# Note: np.unique() is split into four functions in the array API:
|
| 10 |
+
# unique_all, unique_counts, unique_inverse, and unique_values (this is done
|
| 11 |
+
# to remove polymorphic return types).
|
| 12 |
+
|
| 13 |
+
# Note: The various unique() functions are supposed to return multiple NaNs.
|
| 14 |
+
# This does not match the NumPy behavior, however, this is currently left as a
|
| 15 |
+
# TODO in this implementation as this behavior may be reverted in np.unique().
|
| 16 |
+
# See https://github.com/numpy/numpy/issues/20326.
|
| 17 |
+
|
| 18 |
+
# Note: The functions here return a namedtuple (np.unique() returns a normal
|
| 19 |
+
# tuple).
|
| 20 |
+
|
| 21 |
+
class UniqueAllResult(NamedTuple):
|
| 22 |
+
values: Array
|
| 23 |
+
indices: Array
|
| 24 |
+
inverse_indices: Array
|
| 25 |
+
counts: Array
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
class UniqueCountsResult(NamedTuple):
|
| 29 |
+
values: Array
|
| 30 |
+
counts: Array
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
class UniqueInverseResult(NamedTuple):
|
| 34 |
+
values: Array
|
| 35 |
+
inverse_indices: Array
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def unique_all(x: Array, /) -> UniqueAllResult:
|
| 39 |
+
"""
|
| 40 |
+
Array API compatible wrapper for :py:func:`np.unique <numpy.unique>`.
|
| 41 |
+
|
| 42 |
+
See its docstring for more information.
|
| 43 |
+
"""
|
| 44 |
+
values, indices, inverse_indices, counts = np.unique(
|
| 45 |
+
x._array,
|
| 46 |
+
return_counts=True,
|
| 47 |
+
return_index=True,
|
| 48 |
+
return_inverse=True,
|
| 49 |
+
equal_nan=False,
|
| 50 |
+
)
|
| 51 |
+
# np.unique() flattens inverse indices, but they need to share x's shape
|
| 52 |
+
# See https://github.com/numpy/numpy/issues/20638
|
| 53 |
+
inverse_indices = inverse_indices.reshape(x.shape)
|
| 54 |
+
return UniqueAllResult(
|
| 55 |
+
Array._new(values),
|
| 56 |
+
Array._new(indices),
|
| 57 |
+
Array._new(inverse_indices),
|
| 58 |
+
Array._new(counts),
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def unique_counts(x: Array, /) -> UniqueCountsResult:
|
| 63 |
+
res = np.unique(
|
| 64 |
+
x._array,
|
| 65 |
+
return_counts=True,
|
| 66 |
+
return_index=False,
|
| 67 |
+
return_inverse=False,
|
| 68 |
+
equal_nan=False,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
return UniqueCountsResult(*[Array._new(i) for i in res])
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def unique_inverse(x: Array, /) -> UniqueInverseResult:
|
| 75 |
+
"""
|
| 76 |
+
Array API compatible wrapper for :py:func:`np.unique <numpy.unique>`.
|
| 77 |
+
|
| 78 |
+
See its docstring for more information.
|
| 79 |
+
"""
|
| 80 |
+
values, inverse_indices = np.unique(
|
| 81 |
+
x._array,
|
| 82 |
+
return_counts=False,
|
| 83 |
+
return_index=False,
|
| 84 |
+
return_inverse=True,
|
| 85 |
+
equal_nan=False,
|
| 86 |
+
)
|
| 87 |
+
# np.unique() flattens inverse indices, but they need to share x's shape
|
| 88 |
+
# See https://github.com/numpy/numpy/issues/20638
|
| 89 |
+
inverse_indices = inverse_indices.reshape(x.shape)
|
| 90 |
+
return UniqueInverseResult(Array._new(values), Array._new(inverse_indices))
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def unique_values(x: Array, /) -> Array:
|
| 94 |
+
"""
|
| 95 |
+
Array API compatible wrapper for :py:func:`np.unique <numpy.unique>`.
|
| 96 |
+
|
| 97 |
+
See its docstring for more information.
|
| 98 |
+
"""
|
| 99 |
+
res = np.unique(
|
| 100 |
+
x._array,
|
| 101 |
+
return_counts=False,
|
| 102 |
+
return_index=False,
|
| 103 |
+
return_inverse=False,
|
| 104 |
+
equal_nan=False,
|
| 105 |
+
)
|
| 106 |
+
return Array._new(res)
|
lib/python3.12/site-packages/numpy/array_api/_sorting_functions.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._array_object import Array
|
| 4 |
+
from ._dtypes import _real_numeric_dtypes
|
| 5 |
+
|
| 6 |
+
import numpy as np
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
# Note: the descending keyword argument is new in this function
|
| 10 |
+
def argsort(
|
| 11 |
+
x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True
|
| 12 |
+
) -> Array:
|
| 13 |
+
"""
|
| 14 |
+
Array API compatible wrapper for :py:func:`np.argsort <numpy.argsort>`.
|
| 15 |
+
|
| 16 |
+
See its docstring for more information.
|
| 17 |
+
"""
|
| 18 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 19 |
+
raise TypeError("Only real numeric dtypes are allowed in argsort")
|
| 20 |
+
# Note: this keyword argument is different, and the default is different.
|
| 21 |
+
kind = "stable" if stable else "quicksort"
|
| 22 |
+
if not descending:
|
| 23 |
+
res = np.argsort(x._array, axis=axis, kind=kind)
|
| 24 |
+
else:
|
| 25 |
+
# As NumPy has no native descending sort, we imitate it here. Note that
|
| 26 |
+
# simply flipping the results of np.argsort(x._array, ...) would not
|
| 27 |
+
# respect the relative order like it would in native descending sorts.
|
| 28 |
+
res = np.flip(
|
| 29 |
+
np.argsort(np.flip(x._array, axis=axis), axis=axis, kind=kind),
|
| 30 |
+
axis=axis,
|
| 31 |
+
)
|
| 32 |
+
# Rely on flip()/argsort() to validate axis
|
| 33 |
+
normalised_axis = axis if axis >= 0 else x.ndim + axis
|
| 34 |
+
max_i = x.shape[normalised_axis] - 1
|
| 35 |
+
res = max_i - res
|
| 36 |
+
return Array._new(res)
|
| 37 |
+
|
| 38 |
+
# Note: the descending keyword argument is new in this function
|
| 39 |
+
def sort(
|
| 40 |
+
x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True
|
| 41 |
+
) -> Array:
|
| 42 |
+
"""
|
| 43 |
+
Array API compatible wrapper for :py:func:`np.sort <numpy.sort>`.
|
| 44 |
+
|
| 45 |
+
See its docstring for more information.
|
| 46 |
+
"""
|
| 47 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 48 |
+
raise TypeError("Only real numeric dtypes are allowed in sort")
|
| 49 |
+
# Note: this keyword argument is different, and the default is different.
|
| 50 |
+
kind = "stable" if stable else "quicksort"
|
| 51 |
+
res = np.sort(x._array, axis=axis, kind=kind)
|
| 52 |
+
if descending:
|
| 53 |
+
res = np.flip(res, axis=axis)
|
| 54 |
+
return Array._new(res)
|
lib/python3.12/site-packages/numpy/array_api/_statistical_functions.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._dtypes import (
|
| 4 |
+
_real_floating_dtypes,
|
| 5 |
+
_real_numeric_dtypes,
|
| 6 |
+
_numeric_dtypes,
|
| 7 |
+
)
|
| 8 |
+
from ._array_object import Array
|
| 9 |
+
from ._dtypes import float32, float64, complex64, complex128
|
| 10 |
+
|
| 11 |
+
from typing import TYPE_CHECKING, Optional, Tuple, Union
|
| 12 |
+
|
| 13 |
+
if TYPE_CHECKING:
|
| 14 |
+
from ._typing import Dtype
|
| 15 |
+
|
| 16 |
+
import numpy as np
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def max(
|
| 20 |
+
x: Array,
|
| 21 |
+
/,
|
| 22 |
+
*,
|
| 23 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 24 |
+
keepdims: bool = False,
|
| 25 |
+
) -> Array:
|
| 26 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 27 |
+
raise TypeError("Only real numeric dtypes are allowed in max")
|
| 28 |
+
return Array._new(np.max(x._array, axis=axis, keepdims=keepdims))
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def mean(
|
| 32 |
+
x: Array,
|
| 33 |
+
/,
|
| 34 |
+
*,
|
| 35 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 36 |
+
keepdims: bool = False,
|
| 37 |
+
) -> Array:
|
| 38 |
+
if x.dtype not in _real_floating_dtypes:
|
| 39 |
+
raise TypeError("Only real floating-point dtypes are allowed in mean")
|
| 40 |
+
return Array._new(np.mean(x._array, axis=axis, keepdims=keepdims))
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def min(
|
| 44 |
+
x: Array,
|
| 45 |
+
/,
|
| 46 |
+
*,
|
| 47 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 48 |
+
keepdims: bool = False,
|
| 49 |
+
) -> Array:
|
| 50 |
+
if x.dtype not in _real_numeric_dtypes:
|
| 51 |
+
raise TypeError("Only real numeric dtypes are allowed in min")
|
| 52 |
+
return Array._new(np.min(x._array, axis=axis, keepdims=keepdims))
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def prod(
|
| 56 |
+
x: Array,
|
| 57 |
+
/,
|
| 58 |
+
*,
|
| 59 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 60 |
+
dtype: Optional[Dtype] = None,
|
| 61 |
+
keepdims: bool = False,
|
| 62 |
+
) -> Array:
|
| 63 |
+
if x.dtype not in _numeric_dtypes:
|
| 64 |
+
raise TypeError("Only numeric dtypes are allowed in prod")
|
| 65 |
+
# Note: sum() and prod() always upcast for dtype=None. `np.prod` does that
|
| 66 |
+
# for integers, but not for float32 or complex64, so we need to
|
| 67 |
+
# special-case it here
|
| 68 |
+
if dtype is None:
|
| 69 |
+
if x.dtype == float32:
|
| 70 |
+
dtype = float64
|
| 71 |
+
elif x.dtype == complex64:
|
| 72 |
+
dtype = complex128
|
| 73 |
+
return Array._new(np.prod(x._array, dtype=dtype, axis=axis, keepdims=keepdims))
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def std(
|
| 77 |
+
x: Array,
|
| 78 |
+
/,
|
| 79 |
+
*,
|
| 80 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 81 |
+
correction: Union[int, float] = 0.0,
|
| 82 |
+
keepdims: bool = False,
|
| 83 |
+
) -> Array:
|
| 84 |
+
# Note: the keyword argument correction is different here
|
| 85 |
+
if x.dtype not in _real_floating_dtypes:
|
| 86 |
+
raise TypeError("Only real floating-point dtypes are allowed in std")
|
| 87 |
+
return Array._new(np.std(x._array, axis=axis, ddof=correction, keepdims=keepdims))
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def sum(
|
| 91 |
+
x: Array,
|
| 92 |
+
/,
|
| 93 |
+
*,
|
| 94 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 95 |
+
dtype: Optional[Dtype] = None,
|
| 96 |
+
keepdims: bool = False,
|
| 97 |
+
) -> Array:
|
| 98 |
+
if x.dtype not in _numeric_dtypes:
|
| 99 |
+
raise TypeError("Only numeric dtypes are allowed in sum")
|
| 100 |
+
# Note: sum() and prod() always upcast for dtype=None. `np.sum` does that
|
| 101 |
+
# for integers, but not for float32 or complex64, so we need to
|
| 102 |
+
# special-case it here
|
| 103 |
+
if dtype is None:
|
| 104 |
+
if x.dtype == float32:
|
| 105 |
+
dtype = float64
|
| 106 |
+
elif x.dtype == complex64:
|
| 107 |
+
dtype = complex128
|
| 108 |
+
return Array._new(np.sum(x._array, axis=axis, dtype=dtype, keepdims=keepdims))
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def var(
|
| 112 |
+
x: Array,
|
| 113 |
+
/,
|
| 114 |
+
*,
|
| 115 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 116 |
+
correction: Union[int, float] = 0.0,
|
| 117 |
+
keepdims: bool = False,
|
| 118 |
+
) -> Array:
|
| 119 |
+
# Note: the keyword argument correction is different here
|
| 120 |
+
if x.dtype not in _real_floating_dtypes:
|
| 121 |
+
raise TypeError("Only real floating-point dtypes are allowed in var")
|
| 122 |
+
return Array._new(np.var(x._array, axis=axis, ddof=correction, keepdims=keepdims))
|
lib/python3.12/site-packages/numpy/array_api/_typing.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
This file defines the types for type annotations.
|
| 3 |
+
|
| 4 |
+
These names aren't part of the module namespace, but they are used in the
|
| 5 |
+
annotations in the function signatures. The functions in the module are only
|
| 6 |
+
valid for inputs that match the given type annotations.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from __future__ import annotations
|
| 10 |
+
|
| 11 |
+
__all__ = [
|
| 12 |
+
"Array",
|
| 13 |
+
"Device",
|
| 14 |
+
"Dtype",
|
| 15 |
+
"SupportsDLPack",
|
| 16 |
+
"SupportsBufferProtocol",
|
| 17 |
+
"PyCapsule",
|
| 18 |
+
]
|
| 19 |
+
|
| 20 |
+
import sys
|
| 21 |
+
|
| 22 |
+
from typing import (
|
| 23 |
+
Any,
|
| 24 |
+
Literal,
|
| 25 |
+
Sequence,
|
| 26 |
+
Type,
|
| 27 |
+
Union,
|
| 28 |
+
TypeVar,
|
| 29 |
+
Protocol,
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
from ._array_object import Array
|
| 33 |
+
from numpy import (
|
| 34 |
+
dtype,
|
| 35 |
+
int8,
|
| 36 |
+
int16,
|
| 37 |
+
int32,
|
| 38 |
+
int64,
|
| 39 |
+
uint8,
|
| 40 |
+
uint16,
|
| 41 |
+
uint32,
|
| 42 |
+
uint64,
|
| 43 |
+
float32,
|
| 44 |
+
float64,
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
_T_co = TypeVar("_T_co", covariant=True)
|
| 48 |
+
|
| 49 |
+
class NestedSequence(Protocol[_T_co]):
|
| 50 |
+
def __getitem__(self, key: int, /) -> _T_co | NestedSequence[_T_co]: ...
|
| 51 |
+
def __len__(self, /) -> int: ...
|
| 52 |
+
|
| 53 |
+
Device = Literal["cpu"]
|
| 54 |
+
|
| 55 |
+
Dtype = dtype[Union[
|
| 56 |
+
int8,
|
| 57 |
+
int16,
|
| 58 |
+
int32,
|
| 59 |
+
int64,
|
| 60 |
+
uint8,
|
| 61 |
+
uint16,
|
| 62 |
+
uint32,
|
| 63 |
+
uint64,
|
| 64 |
+
float32,
|
| 65 |
+
float64,
|
| 66 |
+
]]
|
| 67 |
+
|
| 68 |
+
if sys.version_info >= (3, 12):
|
| 69 |
+
from collections.abc import Buffer as SupportsBufferProtocol
|
| 70 |
+
else:
|
| 71 |
+
SupportsBufferProtocol = Any
|
| 72 |
+
|
| 73 |
+
PyCapsule = Any
|
| 74 |
+
|
| 75 |
+
class SupportsDLPack(Protocol):
|
| 76 |
+
def __dlpack__(self, /, *, stream: None = ...) -> PyCapsule: ...
|
lib/python3.12/site-packages/numpy/array_api/_utility_functions.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._array_object import Array
|
| 4 |
+
|
| 5 |
+
from typing import Optional, Tuple, Union
|
| 6 |
+
|
| 7 |
+
import numpy as np
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def all(
|
| 11 |
+
x: Array,
|
| 12 |
+
/,
|
| 13 |
+
*,
|
| 14 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 15 |
+
keepdims: bool = False,
|
| 16 |
+
) -> Array:
|
| 17 |
+
"""
|
| 18 |
+
Array API compatible wrapper for :py:func:`np.all <numpy.all>`.
|
| 19 |
+
|
| 20 |
+
See its docstring for more information.
|
| 21 |
+
"""
|
| 22 |
+
return Array._new(np.asarray(np.all(x._array, axis=axis, keepdims=keepdims)))
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def any(
|
| 26 |
+
x: Array,
|
| 27 |
+
/,
|
| 28 |
+
*,
|
| 29 |
+
axis: Optional[Union[int, Tuple[int, ...]]] = None,
|
| 30 |
+
keepdims: bool = False,
|
| 31 |
+
) -> Array:
|
| 32 |
+
"""
|
| 33 |
+
Array API compatible wrapper for :py:func:`np.any <numpy.any>`.
|
| 34 |
+
|
| 35 |
+
See its docstring for more information.
|
| 36 |
+
"""
|
| 37 |
+
return Array._new(np.asarray(np.any(x._array, axis=axis, keepdims=keepdims)))
|
lib/python3.12/site-packages/numpy/array_api/linalg.py
ADDED
|
@@ -0,0 +1,466 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from ._dtypes import (
|
| 4 |
+
_floating_dtypes,
|
| 5 |
+
_numeric_dtypes,
|
| 6 |
+
float32,
|
| 7 |
+
float64,
|
| 8 |
+
complex64,
|
| 9 |
+
complex128
|
| 10 |
+
)
|
| 11 |
+
from ._manipulation_functions import reshape
|
| 12 |
+
from ._elementwise_functions import conj
|
| 13 |
+
from ._array_object import Array
|
| 14 |
+
|
| 15 |
+
from ..core.numeric import normalize_axis_tuple
|
| 16 |
+
|
| 17 |
+
from typing import TYPE_CHECKING
|
| 18 |
+
if TYPE_CHECKING:
|
| 19 |
+
from ._typing import Literal, Optional, Sequence, Tuple, Union, Dtype
|
| 20 |
+
|
| 21 |
+
from typing import NamedTuple
|
| 22 |
+
|
| 23 |
+
import numpy.linalg
|
| 24 |
+
import numpy as np
|
| 25 |
+
|
| 26 |
+
class EighResult(NamedTuple):
|
| 27 |
+
eigenvalues: Array
|
| 28 |
+
eigenvectors: Array
|
| 29 |
+
|
| 30 |
+
class QRResult(NamedTuple):
|
| 31 |
+
Q: Array
|
| 32 |
+
R: Array
|
| 33 |
+
|
| 34 |
+
class SlogdetResult(NamedTuple):
|
| 35 |
+
sign: Array
|
| 36 |
+
logabsdet: Array
|
| 37 |
+
|
| 38 |
+
class SVDResult(NamedTuple):
|
| 39 |
+
U: Array
|
| 40 |
+
S: Array
|
| 41 |
+
Vh: Array
|
| 42 |
+
|
| 43 |
+
# Note: the inclusion of the upper keyword is different from
|
| 44 |
+
# np.linalg.cholesky, which does not have it.
|
| 45 |
+
def cholesky(x: Array, /, *, upper: bool = False) -> Array:
|
| 46 |
+
"""
|
| 47 |
+
Array API compatible wrapper for :py:func:`np.linalg.cholesky <numpy.linalg.cholesky>`.
|
| 48 |
+
|
| 49 |
+
See its docstring for more information.
|
| 50 |
+
"""
|
| 51 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 52 |
+
# np.linalg.cholesky.
|
| 53 |
+
if x.dtype not in _floating_dtypes:
|
| 54 |
+
raise TypeError('Only floating-point dtypes are allowed in cholesky')
|
| 55 |
+
L = np.linalg.cholesky(x._array)
|
| 56 |
+
if upper:
|
| 57 |
+
U = Array._new(L).mT
|
| 58 |
+
if U.dtype in [complex64, complex128]:
|
| 59 |
+
U = conj(U)
|
| 60 |
+
return U
|
| 61 |
+
return Array._new(L)
|
| 62 |
+
|
| 63 |
+
# Note: cross is the numpy top-level namespace, not np.linalg
|
| 64 |
+
def cross(x1: Array, x2: Array, /, *, axis: int = -1) -> Array:
|
| 65 |
+
"""
|
| 66 |
+
Array API compatible wrapper for :py:func:`np.cross <numpy.cross>`.
|
| 67 |
+
|
| 68 |
+
See its docstring for more information.
|
| 69 |
+
"""
|
| 70 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 71 |
+
raise TypeError('Only numeric dtypes are allowed in cross')
|
| 72 |
+
# Note: this is different from np.cross(), which broadcasts
|
| 73 |
+
if x1.shape != x2.shape:
|
| 74 |
+
raise ValueError('x1 and x2 must have the same shape')
|
| 75 |
+
if x1.ndim == 0:
|
| 76 |
+
raise ValueError('cross() requires arrays of dimension at least 1')
|
| 77 |
+
# Note: this is different from np.cross(), which allows dimension 2
|
| 78 |
+
if x1.shape[axis] != 3:
|
| 79 |
+
raise ValueError('cross() dimension must equal 3')
|
| 80 |
+
return Array._new(np.cross(x1._array, x2._array, axis=axis))
|
| 81 |
+
|
| 82 |
+
def det(x: Array, /) -> Array:
|
| 83 |
+
"""
|
| 84 |
+
Array API compatible wrapper for :py:func:`np.linalg.det <numpy.linalg.det>`.
|
| 85 |
+
|
| 86 |
+
See its docstring for more information.
|
| 87 |
+
"""
|
| 88 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 89 |
+
# np.linalg.det.
|
| 90 |
+
if x.dtype not in _floating_dtypes:
|
| 91 |
+
raise TypeError('Only floating-point dtypes are allowed in det')
|
| 92 |
+
return Array._new(np.linalg.det(x._array))
|
| 93 |
+
|
| 94 |
+
# Note: diagonal is the numpy top-level namespace, not np.linalg
|
| 95 |
+
def diagonal(x: Array, /, *, offset: int = 0) -> Array:
|
| 96 |
+
"""
|
| 97 |
+
Array API compatible wrapper for :py:func:`np.diagonal <numpy.diagonal>`.
|
| 98 |
+
|
| 99 |
+
See its docstring for more information.
|
| 100 |
+
"""
|
| 101 |
+
# Note: diagonal always operates on the last two axes, whereas np.diagonal
|
| 102 |
+
# operates on the first two axes by default
|
| 103 |
+
return Array._new(np.diagonal(x._array, offset=offset, axis1=-2, axis2=-1))
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def eigh(x: Array, /) -> EighResult:
|
| 107 |
+
"""
|
| 108 |
+
Array API compatible wrapper for :py:func:`np.linalg.eigh <numpy.linalg.eigh>`.
|
| 109 |
+
|
| 110 |
+
See its docstring for more information.
|
| 111 |
+
"""
|
| 112 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 113 |
+
# np.linalg.eigh.
|
| 114 |
+
if x.dtype not in _floating_dtypes:
|
| 115 |
+
raise TypeError('Only floating-point dtypes are allowed in eigh')
|
| 116 |
+
|
| 117 |
+
# Note: the return type here is a namedtuple, which is different from
|
| 118 |
+
# np.eigh, which only returns a tuple.
|
| 119 |
+
return EighResult(*map(Array._new, np.linalg.eigh(x._array)))
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def eigvalsh(x: Array, /) -> Array:
|
| 123 |
+
"""
|
| 124 |
+
Array API compatible wrapper for :py:func:`np.linalg.eigvalsh <numpy.linalg.eigvalsh>`.
|
| 125 |
+
|
| 126 |
+
See its docstring for more information.
|
| 127 |
+
"""
|
| 128 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 129 |
+
# np.linalg.eigvalsh.
|
| 130 |
+
if x.dtype not in _floating_dtypes:
|
| 131 |
+
raise TypeError('Only floating-point dtypes are allowed in eigvalsh')
|
| 132 |
+
|
| 133 |
+
return Array._new(np.linalg.eigvalsh(x._array))
|
| 134 |
+
|
| 135 |
+
def inv(x: Array, /) -> Array:
|
| 136 |
+
"""
|
| 137 |
+
Array API compatible wrapper for :py:func:`np.linalg.inv <numpy.linalg.inv>`.
|
| 138 |
+
|
| 139 |
+
See its docstring for more information.
|
| 140 |
+
"""
|
| 141 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 142 |
+
# np.linalg.inv.
|
| 143 |
+
if x.dtype not in _floating_dtypes:
|
| 144 |
+
raise TypeError('Only floating-point dtypes are allowed in inv')
|
| 145 |
+
|
| 146 |
+
return Array._new(np.linalg.inv(x._array))
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
# Note: matmul is the numpy top-level namespace but not in np.linalg
|
| 150 |
+
def matmul(x1: Array, x2: Array, /) -> Array:
|
| 151 |
+
"""
|
| 152 |
+
Array API compatible wrapper for :py:func:`np.matmul <numpy.matmul>`.
|
| 153 |
+
|
| 154 |
+
See its docstring for more information.
|
| 155 |
+
"""
|
| 156 |
+
# Note: the restriction to numeric dtypes only is different from
|
| 157 |
+
# np.matmul.
|
| 158 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 159 |
+
raise TypeError('Only numeric dtypes are allowed in matmul')
|
| 160 |
+
|
| 161 |
+
return Array._new(np.matmul(x1._array, x2._array))
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
# Note: the name here is different from norm(). The array API norm is split
|
| 165 |
+
# into matrix_norm and vector_norm().
|
| 166 |
+
|
| 167 |
+
# The type for ord should be Optional[Union[int, float, Literal[np.inf,
|
| 168 |
+
# -np.inf, 'fro', 'nuc']]], but Literal does not support floating-point
|
| 169 |
+
# literals.
|
| 170 |
+
def matrix_norm(x: Array, /, *, keepdims: bool = False, ord: Optional[Union[int, float, Literal['fro', 'nuc']]] = 'fro') -> Array:
|
| 171 |
+
"""
|
| 172 |
+
Array API compatible wrapper for :py:func:`np.linalg.norm <numpy.linalg.norm>`.
|
| 173 |
+
|
| 174 |
+
See its docstring for more information.
|
| 175 |
+
"""
|
| 176 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 177 |
+
# np.linalg.norm.
|
| 178 |
+
if x.dtype not in _floating_dtypes:
|
| 179 |
+
raise TypeError('Only floating-point dtypes are allowed in matrix_norm')
|
| 180 |
+
|
| 181 |
+
return Array._new(np.linalg.norm(x._array, axis=(-2, -1), keepdims=keepdims, ord=ord))
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
def matrix_power(x: Array, n: int, /) -> Array:
|
| 185 |
+
"""
|
| 186 |
+
Array API compatible wrapper for :py:func:`np.matrix_power <numpy.matrix_power>`.
|
| 187 |
+
|
| 188 |
+
See its docstring for more information.
|
| 189 |
+
"""
|
| 190 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 191 |
+
# np.linalg.matrix_power.
|
| 192 |
+
if x.dtype not in _floating_dtypes:
|
| 193 |
+
raise TypeError('Only floating-point dtypes are allowed for the first argument of matrix_power')
|
| 194 |
+
|
| 195 |
+
# np.matrix_power already checks if n is an integer
|
| 196 |
+
return Array._new(np.linalg.matrix_power(x._array, n))
|
| 197 |
+
|
| 198 |
+
# Note: the keyword argument name rtol is different from np.linalg.matrix_rank
|
| 199 |
+
def matrix_rank(x: Array, /, *, rtol: Optional[Union[float, Array]] = None) -> Array:
|
| 200 |
+
"""
|
| 201 |
+
Array API compatible wrapper for :py:func:`np.matrix_rank <numpy.matrix_rank>`.
|
| 202 |
+
|
| 203 |
+
See its docstring for more information.
|
| 204 |
+
"""
|
| 205 |
+
# Note: this is different from np.linalg.matrix_rank, which supports 1
|
| 206 |
+
# dimensional arrays.
|
| 207 |
+
if x.ndim < 2:
|
| 208 |
+
raise np.linalg.LinAlgError("1-dimensional array given. Array must be at least two-dimensional")
|
| 209 |
+
S = np.linalg.svd(x._array, compute_uv=False)
|
| 210 |
+
if rtol is None:
|
| 211 |
+
tol = S.max(axis=-1, keepdims=True) * max(x.shape[-2:]) * np.finfo(S.dtype).eps
|
| 212 |
+
else:
|
| 213 |
+
if isinstance(rtol, Array):
|
| 214 |
+
rtol = rtol._array
|
| 215 |
+
# Note: this is different from np.linalg.matrix_rank, which does not multiply
|
| 216 |
+
# the tolerance by the largest singular value.
|
| 217 |
+
tol = S.max(axis=-1, keepdims=True)*np.asarray(rtol)[..., np.newaxis]
|
| 218 |
+
return Array._new(np.count_nonzero(S > tol, axis=-1))
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
# Note: this function is new in the array API spec. Unlike transpose, it only
|
| 222 |
+
# transposes the last two axes.
|
| 223 |
+
def matrix_transpose(x: Array, /) -> Array:
|
| 224 |
+
if x.ndim < 2:
|
| 225 |
+
raise ValueError("x must be at least 2-dimensional for matrix_transpose")
|
| 226 |
+
return Array._new(np.swapaxes(x._array, -1, -2))
|
| 227 |
+
|
| 228 |
+
# Note: outer is the numpy top-level namespace, not np.linalg
|
| 229 |
+
def outer(x1: Array, x2: Array, /) -> Array:
|
| 230 |
+
"""
|
| 231 |
+
Array API compatible wrapper for :py:func:`np.outer <numpy.outer>`.
|
| 232 |
+
|
| 233 |
+
See its docstring for more information.
|
| 234 |
+
"""
|
| 235 |
+
# Note: the restriction to numeric dtypes only is different from
|
| 236 |
+
# np.outer.
|
| 237 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 238 |
+
raise TypeError('Only numeric dtypes are allowed in outer')
|
| 239 |
+
|
| 240 |
+
# Note: the restriction to only 1-dim arrays is different from np.outer
|
| 241 |
+
if x1.ndim != 1 or x2.ndim != 1:
|
| 242 |
+
raise ValueError('The input arrays to outer must be 1-dimensional')
|
| 243 |
+
|
| 244 |
+
return Array._new(np.outer(x1._array, x2._array))
|
| 245 |
+
|
| 246 |
+
# Note: the keyword argument name rtol is different from np.linalg.pinv
|
| 247 |
+
def pinv(x: Array, /, *, rtol: Optional[Union[float, Array]] = None) -> Array:
|
| 248 |
+
"""
|
| 249 |
+
Array API compatible wrapper for :py:func:`np.linalg.pinv <numpy.linalg.pinv>`.
|
| 250 |
+
|
| 251 |
+
See its docstring for more information.
|
| 252 |
+
"""
|
| 253 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 254 |
+
# np.linalg.pinv.
|
| 255 |
+
if x.dtype not in _floating_dtypes:
|
| 256 |
+
raise TypeError('Only floating-point dtypes are allowed in pinv')
|
| 257 |
+
|
| 258 |
+
# Note: this is different from np.linalg.pinv, which does not multiply the
|
| 259 |
+
# default tolerance by max(M, N).
|
| 260 |
+
if rtol is None:
|
| 261 |
+
rtol = max(x.shape[-2:]) * np.finfo(x.dtype).eps
|
| 262 |
+
return Array._new(np.linalg.pinv(x._array, rcond=rtol))
|
| 263 |
+
|
| 264 |
+
def qr(x: Array, /, *, mode: Literal['reduced', 'complete'] = 'reduced') -> QRResult:
|
| 265 |
+
"""
|
| 266 |
+
Array API compatible wrapper for :py:func:`np.linalg.qr <numpy.linalg.qr>`.
|
| 267 |
+
|
| 268 |
+
See its docstring for more information.
|
| 269 |
+
"""
|
| 270 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 271 |
+
# np.linalg.qr.
|
| 272 |
+
if x.dtype not in _floating_dtypes:
|
| 273 |
+
raise TypeError('Only floating-point dtypes are allowed in qr')
|
| 274 |
+
|
| 275 |
+
# Note: the return type here is a namedtuple, which is different from
|
| 276 |
+
# np.linalg.qr, which only returns a tuple.
|
| 277 |
+
return QRResult(*map(Array._new, np.linalg.qr(x._array, mode=mode)))
|
| 278 |
+
|
| 279 |
+
def slogdet(x: Array, /) -> SlogdetResult:
|
| 280 |
+
"""
|
| 281 |
+
Array API compatible wrapper for :py:func:`np.linalg.slogdet <numpy.linalg.slogdet>`.
|
| 282 |
+
|
| 283 |
+
See its docstring for more information.
|
| 284 |
+
"""
|
| 285 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 286 |
+
# np.linalg.slogdet.
|
| 287 |
+
if x.dtype not in _floating_dtypes:
|
| 288 |
+
raise TypeError('Only floating-point dtypes are allowed in slogdet')
|
| 289 |
+
|
| 290 |
+
# Note: the return type here is a namedtuple, which is different from
|
| 291 |
+
# np.linalg.slogdet, which only returns a tuple.
|
| 292 |
+
return SlogdetResult(*map(Array._new, np.linalg.slogdet(x._array)))
|
| 293 |
+
|
| 294 |
+
# Note: unlike np.linalg.solve, the array API solve() only accepts x2 as a
|
| 295 |
+
# vector when it is exactly 1-dimensional. All other cases treat x2 as a stack
|
| 296 |
+
# of matrices. The np.linalg.solve behavior of allowing stacks of both
|
| 297 |
+
# matrices and vectors is ambiguous c.f.
|
| 298 |
+
# https://github.com/numpy/numpy/issues/15349 and
|
| 299 |
+
# https://github.com/data-apis/array-api/issues/285.
|
| 300 |
+
|
| 301 |
+
# To workaround this, the below is the code from np.linalg.solve except
|
| 302 |
+
# only calling solve1 in the exactly 1D case.
|
| 303 |
+
def _solve(a, b):
|
| 304 |
+
from ..linalg.linalg import (_makearray, _assert_stacked_2d,
|
| 305 |
+
_assert_stacked_square, _commonType,
|
| 306 |
+
isComplexType, get_linalg_error_extobj,
|
| 307 |
+
_raise_linalgerror_singular)
|
| 308 |
+
from ..linalg import _umath_linalg
|
| 309 |
+
|
| 310 |
+
a, _ = _makearray(a)
|
| 311 |
+
_assert_stacked_2d(a)
|
| 312 |
+
_assert_stacked_square(a)
|
| 313 |
+
b, wrap = _makearray(b)
|
| 314 |
+
t, result_t = _commonType(a, b)
|
| 315 |
+
|
| 316 |
+
# This part is different from np.linalg.solve
|
| 317 |
+
if b.ndim == 1:
|
| 318 |
+
gufunc = _umath_linalg.solve1
|
| 319 |
+
else:
|
| 320 |
+
gufunc = _umath_linalg.solve
|
| 321 |
+
|
| 322 |
+
# This does nothing currently but is left in because it will be relevant
|
| 323 |
+
# when complex dtype support is added to the spec in 2022.
|
| 324 |
+
signature = 'DD->D' if isComplexType(t) else 'dd->d'
|
| 325 |
+
with np.errstate(call=_raise_linalgerror_singular, invalid='call',
|
| 326 |
+
over='ignore', divide='ignore', under='ignore'):
|
| 327 |
+
r = gufunc(a, b, signature=signature)
|
| 328 |
+
|
| 329 |
+
return wrap(r.astype(result_t, copy=False))
|
| 330 |
+
|
| 331 |
+
def solve(x1: Array, x2: Array, /) -> Array:
|
| 332 |
+
"""
|
| 333 |
+
Array API compatible wrapper for :py:func:`np.linalg.solve <numpy.linalg.solve>`.
|
| 334 |
+
|
| 335 |
+
See its docstring for more information.
|
| 336 |
+
"""
|
| 337 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 338 |
+
# np.linalg.solve.
|
| 339 |
+
if x1.dtype not in _floating_dtypes or x2.dtype not in _floating_dtypes:
|
| 340 |
+
raise TypeError('Only floating-point dtypes are allowed in solve')
|
| 341 |
+
|
| 342 |
+
return Array._new(_solve(x1._array, x2._array))
|
| 343 |
+
|
| 344 |
+
def svd(x: Array, /, *, full_matrices: bool = True) -> SVDResult:
|
| 345 |
+
"""
|
| 346 |
+
Array API compatible wrapper for :py:func:`np.linalg.svd <numpy.linalg.svd>`.
|
| 347 |
+
|
| 348 |
+
See its docstring for more information.
|
| 349 |
+
"""
|
| 350 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 351 |
+
# np.linalg.svd.
|
| 352 |
+
if x.dtype not in _floating_dtypes:
|
| 353 |
+
raise TypeError('Only floating-point dtypes are allowed in svd')
|
| 354 |
+
|
| 355 |
+
# Note: the return type here is a namedtuple, which is different from
|
| 356 |
+
# np.svd, which only returns a tuple.
|
| 357 |
+
return SVDResult(*map(Array._new, np.linalg.svd(x._array, full_matrices=full_matrices)))
|
| 358 |
+
|
| 359 |
+
# Note: svdvals is not in NumPy (but it is in SciPy). It is equivalent to
|
| 360 |
+
# np.linalg.svd(compute_uv=False).
|
| 361 |
+
def svdvals(x: Array, /) -> Union[Array, Tuple[Array, ...]]:
|
| 362 |
+
if x.dtype not in _floating_dtypes:
|
| 363 |
+
raise TypeError('Only floating-point dtypes are allowed in svdvals')
|
| 364 |
+
return Array._new(np.linalg.svd(x._array, compute_uv=False))
|
| 365 |
+
|
| 366 |
+
# Note: tensordot is the numpy top-level namespace but not in np.linalg
|
| 367 |
+
|
| 368 |
+
# Note: axes must be a tuple, unlike np.tensordot where it can be an array or array-like.
|
| 369 |
+
def tensordot(x1: Array, x2: Array, /, *, axes: Union[int, Tuple[Sequence[int], Sequence[int]]] = 2) -> Array:
|
| 370 |
+
# Note: the restriction to numeric dtypes only is different from
|
| 371 |
+
# np.tensordot.
|
| 372 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 373 |
+
raise TypeError('Only numeric dtypes are allowed in tensordot')
|
| 374 |
+
|
| 375 |
+
return Array._new(np.tensordot(x1._array, x2._array, axes=axes))
|
| 376 |
+
|
| 377 |
+
# Note: trace is the numpy top-level namespace, not np.linalg
|
| 378 |
+
def trace(x: Array, /, *, offset: int = 0, dtype: Optional[Dtype] = None) -> Array:
|
| 379 |
+
"""
|
| 380 |
+
Array API compatible wrapper for :py:func:`np.trace <numpy.trace>`.
|
| 381 |
+
|
| 382 |
+
See its docstring for more information.
|
| 383 |
+
"""
|
| 384 |
+
if x.dtype not in _numeric_dtypes:
|
| 385 |
+
raise TypeError('Only numeric dtypes are allowed in trace')
|
| 386 |
+
|
| 387 |
+
# Note: trace() works the same as sum() and prod() (see
|
| 388 |
+
# _statistical_functions.py)
|
| 389 |
+
if dtype is None:
|
| 390 |
+
if x.dtype == float32:
|
| 391 |
+
dtype = float64
|
| 392 |
+
elif x.dtype == complex64:
|
| 393 |
+
dtype = complex128
|
| 394 |
+
# Note: trace always operates on the last two axes, whereas np.trace
|
| 395 |
+
# operates on the first two axes by default
|
| 396 |
+
return Array._new(np.asarray(np.trace(x._array, offset=offset, axis1=-2, axis2=-1, dtype=dtype)))
|
| 397 |
+
|
| 398 |
+
# Note: vecdot is not in NumPy
|
| 399 |
+
def vecdot(x1: Array, x2: Array, /, *, axis: int = -1) -> Array:
|
| 400 |
+
if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
|
| 401 |
+
raise TypeError('Only numeric dtypes are allowed in vecdot')
|
| 402 |
+
ndim = max(x1.ndim, x2.ndim)
|
| 403 |
+
x1_shape = (1,)*(ndim - x1.ndim) + tuple(x1.shape)
|
| 404 |
+
x2_shape = (1,)*(ndim - x2.ndim) + tuple(x2.shape)
|
| 405 |
+
if x1_shape[axis] != x2_shape[axis]:
|
| 406 |
+
raise ValueError("x1 and x2 must have the same size along the given axis")
|
| 407 |
+
|
| 408 |
+
x1_, x2_ = np.broadcast_arrays(x1._array, x2._array)
|
| 409 |
+
x1_ = np.moveaxis(x1_, axis, -1)
|
| 410 |
+
x2_ = np.moveaxis(x2_, axis, -1)
|
| 411 |
+
|
| 412 |
+
res = x1_[..., None, :] @ x2_[..., None]
|
| 413 |
+
return Array._new(res[..., 0, 0])
|
| 414 |
+
|
| 415 |
+
|
| 416 |
+
# Note: the name here is different from norm(). The array API norm is split
|
| 417 |
+
# into matrix_norm and vector_norm().
|
| 418 |
+
|
| 419 |
+
# The type for ord should be Optional[Union[int, float, Literal[np.inf,
|
| 420 |
+
# -np.inf]]] but Literal does not support floating-point literals.
|
| 421 |
+
def vector_norm(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False, ord: Optional[Union[int, float]] = 2) -> Array:
|
| 422 |
+
"""
|
| 423 |
+
Array API compatible wrapper for :py:func:`np.linalg.norm <numpy.linalg.norm>`.
|
| 424 |
+
|
| 425 |
+
See its docstring for more information.
|
| 426 |
+
"""
|
| 427 |
+
# Note: the restriction to floating-point dtypes only is different from
|
| 428 |
+
# np.linalg.norm.
|
| 429 |
+
if x.dtype not in _floating_dtypes:
|
| 430 |
+
raise TypeError('Only floating-point dtypes are allowed in norm')
|
| 431 |
+
|
| 432 |
+
# np.linalg.norm tries to do a matrix norm whenever axis is a 2-tuple or
|
| 433 |
+
# when axis=None and the input is 2-D, so to force a vector norm, we make
|
| 434 |
+
# it so the input is 1-D (for axis=None), or reshape so that norm is done
|
| 435 |
+
# on a single dimension.
|
| 436 |
+
a = x._array
|
| 437 |
+
if axis is None:
|
| 438 |
+
# Note: np.linalg.norm() doesn't handle 0-D arrays
|
| 439 |
+
a = a.ravel()
|
| 440 |
+
_axis = 0
|
| 441 |
+
elif isinstance(axis, tuple):
|
| 442 |
+
# Note: The axis argument supports any number of axes, whereas
|
| 443 |
+
# np.linalg.norm() only supports a single axis for vector norm.
|
| 444 |
+
normalized_axis = normalize_axis_tuple(axis, x.ndim)
|
| 445 |
+
rest = tuple(i for i in range(a.ndim) if i not in normalized_axis)
|
| 446 |
+
newshape = axis + rest
|
| 447 |
+
a = np.transpose(a, newshape).reshape(
|
| 448 |
+
(np.prod([a.shape[i] for i in axis], dtype=int), *[a.shape[i] for i in rest]))
|
| 449 |
+
_axis = 0
|
| 450 |
+
else:
|
| 451 |
+
_axis = axis
|
| 452 |
+
|
| 453 |
+
res = Array._new(np.linalg.norm(a, axis=_axis, ord=ord))
|
| 454 |
+
|
| 455 |
+
if keepdims:
|
| 456 |
+
# We can't reuse np.linalg.norm(keepdims) because of the reshape hacks
|
| 457 |
+
# above to avoid matrix norm logic.
|
| 458 |
+
shape = list(x.shape)
|
| 459 |
+
_axis = normalize_axis_tuple(range(x.ndim) if axis is None else axis, x.ndim)
|
| 460 |
+
for i in _axis:
|
| 461 |
+
shape[i] = 1
|
| 462 |
+
res = reshape(res, tuple(shape))
|
| 463 |
+
|
| 464 |
+
return res
|
| 465 |
+
|
| 466 |
+
__all__ = ['cholesky', 'cross', 'det', 'diagonal', 'eigh', 'eigvalsh', 'inv', 'matmul', 'matrix_norm', 'matrix_power', 'matrix_rank', 'matrix_transpose', 'outer', 'pinv', 'qr', 'slogdet', 'solve', 'svd', 'svdvals', 'tensordot', 'trace', 'vecdot', 'vector_norm']
|
lib/python3.12/site-packages/numpy/array_api/setup.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def configuration(parent_package="", top_path=None):
|
| 2 |
+
from numpy.distutils.misc_util import Configuration
|
| 3 |
+
|
| 4 |
+
config = Configuration("array_api", parent_package, top_path)
|
| 5 |
+
config.add_subpackage("tests")
|
| 6 |
+
return config
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
if __name__ == "__main__":
|
| 10 |
+
from numpy.distutils.core import setup
|
| 11 |
+
|
| 12 |
+
setup(configuration=configuration)
|
lib/python3.12/site-packages/numpy/array_api/tests/__init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Tests for the array API namespace.
|
| 3 |
+
|
| 4 |
+
Note, full compliance with the array API can be tested with the official array API test
|
| 5 |
+
suite https://github.com/data-apis/array-api-tests. This test suite primarily
|
| 6 |
+
focuses on those things that are not tested by the official test suite.
|
| 7 |
+
"""
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (495 Bytes). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_array_object.cpython-312.pyc
ADDED
|
Binary file (28.3 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_creation_functions.cpython-312.pyc
ADDED
|
Binary file (13.6 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_data_type_functions.cpython-312.pyc
ADDED
|
Binary file (2.35 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_elementwise_functions.cpython-312.pyc
ADDED
|
Binary file (4.6 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_indexing_functions.cpython-312.pyc
ADDED
|
Binary file (1.27 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_manipulation_functions.cpython-312.pyc
ADDED
|
Binary file (2.68 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_set_functions.cpython-312.pyc
ADDED
|
Binary file (1.23 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_sorting_functions.cpython-312.pyc
ADDED
|
Binary file (1.23 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/__pycache__/test_validation.cpython-312.pyc
ADDED
|
Binary file (1.68 kB). View file
|
|
|
lib/python3.12/site-packages/numpy/array_api/tests/test_array_object.py
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import operator
|
| 2 |
+
|
| 3 |
+
from numpy.testing import assert_raises, suppress_warnings
|
| 4 |
+
import numpy as np
|
| 5 |
+
import pytest
|
| 6 |
+
|
| 7 |
+
from .. import ones, asarray, reshape, result_type, all, equal
|
| 8 |
+
from .._array_object import Array
|
| 9 |
+
from .._dtypes import (
|
| 10 |
+
_all_dtypes,
|
| 11 |
+
_boolean_dtypes,
|
| 12 |
+
_real_floating_dtypes,
|
| 13 |
+
_floating_dtypes,
|
| 14 |
+
_complex_floating_dtypes,
|
| 15 |
+
_integer_dtypes,
|
| 16 |
+
_integer_or_boolean_dtypes,
|
| 17 |
+
_real_numeric_dtypes,
|
| 18 |
+
_numeric_dtypes,
|
| 19 |
+
int8,
|
| 20 |
+
int16,
|
| 21 |
+
int32,
|
| 22 |
+
int64,
|
| 23 |
+
uint64,
|
| 24 |
+
bool as bool_,
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def test_validate_index():
|
| 29 |
+
# The indexing tests in the official array API test suite test that the
|
| 30 |
+
# array object correctly handles the subset of indices that are required
|
| 31 |
+
# by the spec. But the NumPy array API implementation specifically
|
| 32 |
+
# disallows any index not required by the spec, via Array._validate_index.
|
| 33 |
+
# This test focuses on testing that non-valid indices are correctly
|
| 34 |
+
# rejected. See
|
| 35 |
+
# https://data-apis.org/array-api/latest/API_specification/indexing.html
|
| 36 |
+
# and the docstring of Array._validate_index for the exact indexing
|
| 37 |
+
# behavior that should be allowed. This does not test indices that are
|
| 38 |
+
# already invalid in NumPy itself because Array will generally just pass
|
| 39 |
+
# such indices directly to the underlying np.ndarray.
|
| 40 |
+
|
| 41 |
+
a = ones((3, 4))
|
| 42 |
+
|
| 43 |
+
# Out of bounds slices are not allowed
|
| 44 |
+
assert_raises(IndexError, lambda: a[:4])
|
| 45 |
+
assert_raises(IndexError, lambda: a[:-4])
|
| 46 |
+
assert_raises(IndexError, lambda: a[:3:-1])
|
| 47 |
+
assert_raises(IndexError, lambda: a[:-5:-1])
|
| 48 |
+
assert_raises(IndexError, lambda: a[4:])
|
| 49 |
+
assert_raises(IndexError, lambda: a[-4:])
|
| 50 |
+
assert_raises(IndexError, lambda: a[4::-1])
|
| 51 |
+
assert_raises(IndexError, lambda: a[-4::-1])
|
| 52 |
+
|
| 53 |
+
assert_raises(IndexError, lambda: a[...,:5])
|
| 54 |
+
assert_raises(IndexError, lambda: a[...,:-5])
|
| 55 |
+
assert_raises(IndexError, lambda: a[...,:5:-1])
|
| 56 |
+
assert_raises(IndexError, lambda: a[...,:-6:-1])
|
| 57 |
+
assert_raises(IndexError, lambda: a[...,5:])
|
| 58 |
+
assert_raises(IndexError, lambda: a[...,-5:])
|
| 59 |
+
assert_raises(IndexError, lambda: a[...,5::-1])
|
| 60 |
+
assert_raises(IndexError, lambda: a[...,-5::-1])
|
| 61 |
+
|
| 62 |
+
# Boolean indices cannot be part of a larger tuple index
|
| 63 |
+
assert_raises(IndexError, lambda: a[a[:,0]==1,0])
|
| 64 |
+
assert_raises(IndexError, lambda: a[a[:,0]==1,...])
|
| 65 |
+
assert_raises(IndexError, lambda: a[..., a[0]==1])
|
| 66 |
+
assert_raises(IndexError, lambda: a[[True, True, True]])
|
| 67 |
+
assert_raises(IndexError, lambda: a[(True, True, True),])
|
| 68 |
+
|
| 69 |
+
# Integer array indices are not allowed (except for 0-D)
|
| 70 |
+
idx = asarray([[0, 1]])
|
| 71 |
+
assert_raises(IndexError, lambda: a[idx])
|
| 72 |
+
assert_raises(IndexError, lambda: a[idx,])
|
| 73 |
+
assert_raises(IndexError, lambda: a[[0, 1]])
|
| 74 |
+
assert_raises(IndexError, lambda: a[(0, 1), (0, 1)])
|
| 75 |
+
assert_raises(IndexError, lambda: a[[0, 1]])
|
| 76 |
+
assert_raises(IndexError, lambda: a[np.array([[0, 1]])])
|
| 77 |
+
|
| 78 |
+
# Multiaxis indices must contain exactly as many indices as dimensions
|
| 79 |
+
assert_raises(IndexError, lambda: a[()])
|
| 80 |
+
assert_raises(IndexError, lambda: a[0,])
|
| 81 |
+
assert_raises(IndexError, lambda: a[0])
|
| 82 |
+
assert_raises(IndexError, lambda: a[:])
|
| 83 |
+
|
| 84 |
+
def test_operators():
|
| 85 |
+
# For every operator, we test that it works for the required type
|
| 86 |
+
# combinations and raises TypeError otherwise
|
| 87 |
+
binary_op_dtypes = {
|
| 88 |
+
"__add__": "numeric",
|
| 89 |
+
"__and__": "integer_or_boolean",
|
| 90 |
+
"__eq__": "all",
|
| 91 |
+
"__floordiv__": "real numeric",
|
| 92 |
+
"__ge__": "real numeric",
|
| 93 |
+
"__gt__": "real numeric",
|
| 94 |
+
"__le__": "real numeric",
|
| 95 |
+
"__lshift__": "integer",
|
| 96 |
+
"__lt__": "real numeric",
|
| 97 |
+
"__mod__": "real numeric",
|
| 98 |
+
"__mul__": "numeric",
|
| 99 |
+
"__ne__": "all",
|
| 100 |
+
"__or__": "integer_or_boolean",
|
| 101 |
+
"__pow__": "numeric",
|
| 102 |
+
"__rshift__": "integer",
|
| 103 |
+
"__sub__": "numeric",
|
| 104 |
+
"__truediv__": "floating",
|
| 105 |
+
"__xor__": "integer_or_boolean",
|
| 106 |
+
}
|
| 107 |
+
# Recompute each time because of in-place ops
|
| 108 |
+
def _array_vals():
|
| 109 |
+
for d in _integer_dtypes:
|
| 110 |
+
yield asarray(1, dtype=d)
|
| 111 |
+
for d in _boolean_dtypes:
|
| 112 |
+
yield asarray(False, dtype=d)
|
| 113 |
+
for d in _floating_dtypes:
|
| 114 |
+
yield asarray(1.0, dtype=d)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
BIG_INT = int(1e30)
|
| 118 |
+
for op, dtypes in binary_op_dtypes.items():
|
| 119 |
+
ops = [op]
|
| 120 |
+
if op not in ["__eq__", "__ne__", "__le__", "__ge__", "__lt__", "__gt__"]:
|
| 121 |
+
rop = "__r" + op[2:]
|
| 122 |
+
iop = "__i" + op[2:]
|
| 123 |
+
ops += [rop, iop]
|
| 124 |
+
for s in [1, 1.0, 1j, BIG_INT, False]:
|
| 125 |
+
for _op in ops:
|
| 126 |
+
for a in _array_vals():
|
| 127 |
+
# Test array op scalar. From the spec, the following combinations
|
| 128 |
+
# are supported:
|
| 129 |
+
|
| 130 |
+
# - Python bool for a bool array dtype,
|
| 131 |
+
# - a Python int within the bounds of the given dtype for integer array dtypes,
|
| 132 |
+
# - a Python int or float for real floating-point array dtypes
|
| 133 |
+
# - a Python int, float, or complex for complex floating-point array dtypes
|
| 134 |
+
|
| 135 |
+
if ((dtypes == "all"
|
| 136 |
+
or dtypes == "numeric" and a.dtype in _numeric_dtypes
|
| 137 |
+
or dtypes == "real numeric" and a.dtype in _real_numeric_dtypes
|
| 138 |
+
or dtypes == "integer" and a.dtype in _integer_dtypes
|
| 139 |
+
or dtypes == "integer_or_boolean" and a.dtype in _integer_or_boolean_dtypes
|
| 140 |
+
or dtypes == "boolean" and a.dtype in _boolean_dtypes
|
| 141 |
+
or dtypes == "floating" and a.dtype in _floating_dtypes
|
| 142 |
+
)
|
| 143 |
+
# bool is a subtype of int, which is why we avoid
|
| 144 |
+
# isinstance here.
|
| 145 |
+
and (a.dtype in _boolean_dtypes and type(s) == bool
|
| 146 |
+
or a.dtype in _integer_dtypes and type(s) == int
|
| 147 |
+
or a.dtype in _real_floating_dtypes and type(s) in [float, int]
|
| 148 |
+
or a.dtype in _complex_floating_dtypes and type(s) in [complex, float, int]
|
| 149 |
+
)):
|
| 150 |
+
if a.dtype in _integer_dtypes and s == BIG_INT:
|
| 151 |
+
assert_raises(OverflowError, lambda: getattr(a, _op)(s))
|
| 152 |
+
else:
|
| 153 |
+
# Only test for no error
|
| 154 |
+
with suppress_warnings() as sup:
|
| 155 |
+
# ignore warnings from pow(BIG_INT)
|
| 156 |
+
sup.filter(RuntimeWarning,
|
| 157 |
+
"invalid value encountered in power")
|
| 158 |
+
getattr(a, _op)(s)
|
| 159 |
+
else:
|
| 160 |
+
assert_raises(TypeError, lambda: getattr(a, _op)(s))
|
| 161 |
+
|
| 162 |
+
# Test array op array.
|
| 163 |
+
for _op in ops:
|
| 164 |
+
for x in _array_vals():
|
| 165 |
+
for y in _array_vals():
|
| 166 |
+
# See the promotion table in NEP 47 or the array
|
| 167 |
+
# API spec page on type promotion. Mixed kind
|
| 168 |
+
# promotion is not defined.
|
| 169 |
+
if (x.dtype == uint64 and y.dtype in [int8, int16, int32, int64]
|
| 170 |
+
or y.dtype == uint64 and x.dtype in [int8, int16, int32, int64]
|
| 171 |
+
or x.dtype in _integer_dtypes and y.dtype not in _integer_dtypes
|
| 172 |
+
or y.dtype in _integer_dtypes and x.dtype not in _integer_dtypes
|
| 173 |
+
or x.dtype in _boolean_dtypes and y.dtype not in _boolean_dtypes
|
| 174 |
+
or y.dtype in _boolean_dtypes and x.dtype not in _boolean_dtypes
|
| 175 |
+
or x.dtype in _floating_dtypes and y.dtype not in _floating_dtypes
|
| 176 |
+
or y.dtype in _floating_dtypes and x.dtype not in _floating_dtypes
|
| 177 |
+
):
|
| 178 |
+
assert_raises(TypeError, lambda: getattr(x, _op)(y))
|
| 179 |
+
# Ensure in-place operators only promote to the same dtype as the left operand.
|
| 180 |
+
elif (
|
| 181 |
+
_op.startswith("__i")
|
| 182 |
+
and result_type(x.dtype, y.dtype) != x.dtype
|
| 183 |
+
):
|
| 184 |
+
assert_raises(TypeError, lambda: getattr(x, _op)(y))
|
| 185 |
+
# Ensure only those dtypes that are required for every operator are allowed.
|
| 186 |
+
elif (dtypes == "all" and (x.dtype in _boolean_dtypes and y.dtype in _boolean_dtypes
|
| 187 |
+
or x.dtype in _numeric_dtypes and y.dtype in _numeric_dtypes)
|
| 188 |
+
or (dtypes == "real numeric" and x.dtype in _real_numeric_dtypes and y.dtype in _real_numeric_dtypes)
|
| 189 |
+
or (dtypes == "numeric" and x.dtype in _numeric_dtypes and y.dtype in _numeric_dtypes)
|
| 190 |
+
or dtypes == "integer" and x.dtype in _integer_dtypes and y.dtype in _integer_dtypes
|
| 191 |
+
or dtypes == "integer_or_boolean" and (x.dtype in _integer_dtypes and y.dtype in _integer_dtypes
|
| 192 |
+
or x.dtype in _boolean_dtypes and y.dtype in _boolean_dtypes)
|
| 193 |
+
or dtypes == "boolean" and x.dtype in _boolean_dtypes and y.dtype in _boolean_dtypes
|
| 194 |
+
or dtypes == "floating" and x.dtype in _floating_dtypes and y.dtype in _floating_dtypes
|
| 195 |
+
):
|
| 196 |
+
getattr(x, _op)(y)
|
| 197 |
+
else:
|
| 198 |
+
assert_raises(TypeError, lambda: getattr(x, _op)(y))
|
| 199 |
+
|
| 200 |
+
unary_op_dtypes = {
|
| 201 |
+
"__abs__": "numeric",
|
| 202 |
+
"__invert__": "integer_or_boolean",
|
| 203 |
+
"__neg__": "numeric",
|
| 204 |
+
"__pos__": "numeric",
|
| 205 |
+
}
|
| 206 |
+
for op, dtypes in unary_op_dtypes.items():
|
| 207 |
+
for a in _array_vals():
|
| 208 |
+
if (
|
| 209 |
+
dtypes == "numeric"
|
| 210 |
+
and a.dtype in _numeric_dtypes
|
| 211 |
+
or dtypes == "integer_or_boolean"
|
| 212 |
+
and a.dtype in _integer_or_boolean_dtypes
|
| 213 |
+
):
|
| 214 |
+
# Only test for no error
|
| 215 |
+
getattr(a, op)()
|
| 216 |
+
else:
|
| 217 |
+
assert_raises(TypeError, lambda: getattr(a, op)())
|
| 218 |
+
|
| 219 |
+
# Finally, matmul() must be tested separately, because it works a bit
|
| 220 |
+
# different from the other operations.
|
| 221 |
+
def _matmul_array_vals():
|
| 222 |
+
for a in _array_vals():
|
| 223 |
+
yield a
|
| 224 |
+
for d in _all_dtypes:
|
| 225 |
+
yield ones((3, 4), dtype=d)
|
| 226 |
+
yield ones((4, 2), dtype=d)
|
| 227 |
+
yield ones((4, 4), dtype=d)
|
| 228 |
+
|
| 229 |
+
# Scalars always error
|
| 230 |
+
for _op in ["__matmul__", "__rmatmul__", "__imatmul__"]:
|
| 231 |
+
for s in [1, 1.0, False]:
|
| 232 |
+
for a in _matmul_array_vals():
|
| 233 |
+
if (type(s) in [float, int] and a.dtype in _floating_dtypes
|
| 234 |
+
or type(s) == int and a.dtype in _integer_dtypes):
|
| 235 |
+
# Type promotion is valid, but @ is not allowed on 0-D
|
| 236 |
+
# inputs, so the error is a ValueError
|
| 237 |
+
assert_raises(ValueError, lambda: getattr(a, _op)(s))
|
| 238 |
+
else:
|
| 239 |
+
assert_raises(TypeError, lambda: getattr(a, _op)(s))
|
| 240 |
+
|
| 241 |
+
for x in _matmul_array_vals():
|
| 242 |
+
for y in _matmul_array_vals():
|
| 243 |
+
if (x.dtype == uint64 and y.dtype in [int8, int16, int32, int64]
|
| 244 |
+
or y.dtype == uint64 and x.dtype in [int8, int16, int32, int64]
|
| 245 |
+
or x.dtype in _integer_dtypes and y.dtype not in _integer_dtypes
|
| 246 |
+
or y.dtype in _integer_dtypes and x.dtype not in _integer_dtypes
|
| 247 |
+
or x.dtype in _floating_dtypes and y.dtype not in _floating_dtypes
|
| 248 |
+
or y.dtype in _floating_dtypes and x.dtype not in _floating_dtypes
|
| 249 |
+
or x.dtype in _boolean_dtypes
|
| 250 |
+
or y.dtype in _boolean_dtypes
|
| 251 |
+
):
|
| 252 |
+
assert_raises(TypeError, lambda: x.__matmul__(y))
|
| 253 |
+
assert_raises(TypeError, lambda: y.__rmatmul__(x))
|
| 254 |
+
assert_raises(TypeError, lambda: x.__imatmul__(y))
|
| 255 |
+
elif x.shape == () or y.shape == () or x.shape[1] != y.shape[0]:
|
| 256 |
+
assert_raises(ValueError, lambda: x.__matmul__(y))
|
| 257 |
+
assert_raises(ValueError, lambda: y.__rmatmul__(x))
|
| 258 |
+
if result_type(x.dtype, y.dtype) != x.dtype:
|
| 259 |
+
assert_raises(TypeError, lambda: x.__imatmul__(y))
|
| 260 |
+
else:
|
| 261 |
+
assert_raises(ValueError, lambda: x.__imatmul__(y))
|
| 262 |
+
else:
|
| 263 |
+
x.__matmul__(y)
|
| 264 |
+
y.__rmatmul__(x)
|
| 265 |
+
if result_type(x.dtype, y.dtype) != x.dtype:
|
| 266 |
+
assert_raises(TypeError, lambda: x.__imatmul__(y))
|
| 267 |
+
elif y.shape[0] != y.shape[1]:
|
| 268 |
+
# This one fails because x @ y has a different shape from x
|
| 269 |
+
assert_raises(ValueError, lambda: x.__imatmul__(y))
|
| 270 |
+
else:
|
| 271 |
+
x.__imatmul__(y)
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
def test_python_scalar_construtors():
|
| 275 |
+
b = asarray(False)
|
| 276 |
+
i = asarray(0)
|
| 277 |
+
f = asarray(0.0)
|
| 278 |
+
c = asarray(0j)
|
| 279 |
+
|
| 280 |
+
assert bool(b) == False
|
| 281 |
+
assert int(i) == 0
|
| 282 |
+
assert float(f) == 0.0
|
| 283 |
+
assert operator.index(i) == 0
|
| 284 |
+
|
| 285 |
+
# bool/int/float/complex should only be allowed on 0-D arrays.
|
| 286 |
+
assert_raises(TypeError, lambda: bool(asarray([False])))
|
| 287 |
+
assert_raises(TypeError, lambda: int(asarray([0])))
|
| 288 |
+
assert_raises(TypeError, lambda: float(asarray([0.0])))
|
| 289 |
+
assert_raises(TypeError, lambda: complex(asarray([0j])))
|
| 290 |
+
assert_raises(TypeError, lambda: operator.index(asarray([0])))
|
| 291 |
+
|
| 292 |
+
# bool should work on all types of arrays
|
| 293 |
+
assert bool(b) is bool(i) is bool(f) is bool(c) is False
|
| 294 |
+
|
| 295 |
+
# int should fail on complex arrays
|
| 296 |
+
assert int(b) == int(i) == int(f) == 0
|
| 297 |
+
assert_raises(TypeError, lambda: int(c))
|
| 298 |
+
|
| 299 |
+
# float should fail on complex arrays
|
| 300 |
+
assert float(b) == float(i) == float(f) == 0.0
|
| 301 |
+
assert_raises(TypeError, lambda: float(c))
|
| 302 |
+
|
| 303 |
+
# complex should work on all types of arrays
|
| 304 |
+
assert complex(b) == complex(i) == complex(f) == complex(c) == 0j
|
| 305 |
+
|
| 306 |
+
# index should only work on integer arrays
|
| 307 |
+
assert operator.index(i) == 0
|
| 308 |
+
assert_raises(TypeError, lambda: operator.index(b))
|
| 309 |
+
assert_raises(TypeError, lambda: operator.index(f))
|
| 310 |
+
assert_raises(TypeError, lambda: operator.index(c))
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
def test_device_property():
|
| 314 |
+
a = ones((3, 4))
|
| 315 |
+
assert a.device == 'cpu'
|
| 316 |
+
|
| 317 |
+
assert all(equal(a.to_device('cpu'), a))
|
| 318 |
+
assert_raises(ValueError, lambda: a.to_device('gpu'))
|
| 319 |
+
|
| 320 |
+
assert all(equal(asarray(a, device='cpu'), a))
|
| 321 |
+
assert_raises(ValueError, lambda: asarray(a, device='gpu'))
|
| 322 |
+
|
| 323 |
+
def test_array_properties():
|
| 324 |
+
a = ones((1, 2, 3))
|
| 325 |
+
b = ones((2, 3))
|
| 326 |
+
assert_raises(ValueError, lambda: a.T)
|
| 327 |
+
|
| 328 |
+
assert isinstance(b.T, Array)
|
| 329 |
+
assert b.T.shape == (3, 2)
|
| 330 |
+
|
| 331 |
+
assert isinstance(a.mT, Array)
|
| 332 |
+
assert a.mT.shape == (1, 3, 2)
|
| 333 |
+
assert isinstance(b.mT, Array)
|
| 334 |
+
assert b.mT.shape == (3, 2)
|
| 335 |
+
|
| 336 |
+
def test___array__():
|
| 337 |
+
a = ones((2, 3), dtype=int16)
|
| 338 |
+
assert np.asarray(a) is a._array
|
| 339 |
+
b = np.asarray(a, dtype=np.float64)
|
| 340 |
+
assert np.all(np.equal(b, np.ones((2, 3), dtype=np.float64)))
|
| 341 |
+
assert b.dtype == np.float64
|
| 342 |
+
|
| 343 |
+
def test_allow_newaxis():
|
| 344 |
+
a = ones(5)
|
| 345 |
+
indexed_a = a[None, :]
|
| 346 |
+
assert indexed_a.shape == (1, 5)
|
| 347 |
+
|
| 348 |
+
def test_disallow_flat_indexing_with_newaxis():
|
| 349 |
+
a = ones((3, 3, 3))
|
| 350 |
+
with pytest.raises(IndexError):
|
| 351 |
+
a[None, 0, 0]
|
| 352 |
+
|
| 353 |
+
def test_disallow_mask_with_newaxis():
|
| 354 |
+
a = ones((3, 3, 3))
|
| 355 |
+
with pytest.raises(IndexError):
|
| 356 |
+
a[None, asarray(True)]
|
| 357 |
+
|
| 358 |
+
@pytest.mark.parametrize("shape", [(), (5,), (3, 3, 3)])
|
| 359 |
+
@pytest.mark.parametrize("index", ["string", False, True])
|
| 360 |
+
def test_error_on_invalid_index(shape, index):
|
| 361 |
+
a = ones(shape)
|
| 362 |
+
with pytest.raises(IndexError):
|
| 363 |
+
a[index]
|
| 364 |
+
|
| 365 |
+
def test_mask_0d_array_without_errors():
|
| 366 |
+
a = ones(())
|
| 367 |
+
a[asarray(True)]
|
| 368 |
+
|
| 369 |
+
@pytest.mark.parametrize(
|
| 370 |
+
"i", [slice(5), slice(5, 0), asarray(True), asarray([0, 1])]
|
| 371 |
+
)
|
| 372 |
+
def test_error_on_invalid_index_with_ellipsis(i):
|
| 373 |
+
a = ones((3, 3, 3))
|
| 374 |
+
with pytest.raises(IndexError):
|
| 375 |
+
a[..., i]
|
| 376 |
+
with pytest.raises(IndexError):
|
| 377 |
+
a[i, ...]
|
| 378 |
+
|
| 379 |
+
def test_array_keys_use_private_array():
|
| 380 |
+
"""
|
| 381 |
+
Indexing operations convert array keys before indexing the internal array
|
| 382 |
+
|
| 383 |
+
Fails when array_api array keys are not converted into NumPy-proper arrays
|
| 384 |
+
in __getitem__(). This is achieved by passing array_api arrays with 0-sized
|
| 385 |
+
dimensions, which NumPy-proper treats erroneously - not sure why!
|
| 386 |
+
|
| 387 |
+
TODO: Find and use appropriate __setitem__() case.
|
| 388 |
+
"""
|
| 389 |
+
a = ones((0, 0), dtype=bool_)
|
| 390 |
+
assert a[a].shape == (0,)
|
| 391 |
+
|
| 392 |
+
a = ones((0,), dtype=bool_)
|
| 393 |
+
key = ones((0, 0), dtype=bool_)
|
| 394 |
+
with pytest.raises(IndexError):
|
| 395 |
+
a[key]
|