diff --git a/doc-requirements.txt b/doc-requirements.txt index 488aa3e81..08ced9aa2 100644 --- a/doc-requirements.txt +++ b/doc-requirements.txt @@ -1,8 +1,7 @@ -sphinx==4.3.0 +sphinx==6.2.1 sphinx-material==0.0.30 myst-parser sphinx_markdown_tables sphinx_copybutton sphinx_favicon -docutils<0.18 sphinx-math-dollar diff --git a/spec/2021.12/assumptions.md b/spec/2021.12/assumptions.md index 3a90710ea..b11482c5a 100644 --- a/spec/2021.12/assumptions.md +++ b/spec/2021.12/assumptions.md @@ -26,7 +26,7 @@ of functions to be predictable from input dtypes only rather than input values. The only dependency that's assumed in this standard is that on Python itself. Python >= 3.8 is assumed, motivated by the use of positional-only parameters -(see [function and method signatures](API_specification/function_and_method_signatures.md)). +(see [function and method signatures](API_specification/function_and_method_signatures.rst)). Importantly, array libraries are not assumed to be aware of each other, or of a common array-specific layer. The [use cases](use_cases.md) do not require @@ -39,7 +39,7 @@ for that is: Array libraries may know how to interoperate with each other, for example by constructing their own array type from that of another library or by shared -memory use of an array (see [Data interchange mechanisms](design_topics/data_interchange.md)). +memory use of an array (see [Data interchange mechanisms](design_topics/data_interchange.rst)). This can be done without a dependency though - only adherence to a protocol is enough. diff --git a/spec/2021.12/purpose_and_scope.md b/spec/2021.12/purpose_and_scope.md index 4678ba064..0debbc08a 100644 --- a/spec/2021.12/purpose_and_scope.md +++ b/spec/2021.12/purpose_and_scope.md @@ -151,7 +151,7 @@ standard is shown in this diagram: _Rationale: this is an important topic for some array-consuming libraries, but there is no widely shared C/Cython API and hence it doesn't make sense at this point in time to standardize anything. See - the [C API section](design_topics/C_API.md) for more details._ + the [C API section](design_topics/C_API.rst) for more details._ 4. Standardization of these dtypes is out of scope: bfloat16, complex, extended precision floating point, datetime, string, object and void dtypes. diff --git a/spec/2021.12/use_cases.md b/spec/2021.12/use_cases.md index 26f7a529c..e24aa50db 100644 --- a/spec/2021.12/use_cases.md +++ b/spec/2021.12/use_cases.md @@ -59,7 +59,7 @@ array implementation as a dependency. It's clear that SciPy functionality that relies on compiled extensions (C, C++, Cython, Fortran) directly can't easily be run on another array library -than NumPy (see [C API](design_topics/C_API.md) for more details about this topic). Pure Python +than NumPy (see [C API](design_topics/C_API.rst) for more details about this topic). Pure Python code can work though. There's two main possibilities: 1. Testing with another package, manually or in CI, and simply provide a list diff --git a/spec/2022.12/API_specification/array_object.rst b/spec/2022.12/API_specification/array_object.rst index b15bbdc43..45aec9b34 100644 --- a/spec/2022.12/API_specification/array_object.rst +++ b/spec/2022.12/API_specification/array_object.rst @@ -163,7 +163,8 @@ A conforming implementation of the array API standard must provide and support a - `operator.ne(x1, x2) `_ - `operator.__ne__(x1, x2) `_ -Comparison operators should be defined for arrays having any data type. +:meth:`.array.__lt__`, :meth:`.array.__le__`, :meth:`.array.__gt__`, :meth:`.array.__ge__` are only defined for arrays having real-valued data types. Other comparison operators should be defined for arrays having any data type. +For backward compatibility, conforming implementations may support complex numbers; however, inequality comparison of complex numbers is unspecified and thus implementation-dependent (see :ref:`complex-number-ordering`). In-place Operators ~~~~~~~~~~~~~~~~~~ diff --git a/spec/2022.12/assumptions.md b/spec/2022.12/assumptions.md index 3a90710ea..b11482c5a 100644 --- a/spec/2022.12/assumptions.md +++ b/spec/2022.12/assumptions.md @@ -26,7 +26,7 @@ of functions to be predictable from input dtypes only rather than input values. The only dependency that's assumed in this standard is that on Python itself. Python >= 3.8 is assumed, motivated by the use of positional-only parameters -(see [function and method signatures](API_specification/function_and_method_signatures.md)). +(see [function and method signatures](API_specification/function_and_method_signatures.rst)). Importantly, array libraries are not assumed to be aware of each other, or of a common array-specific layer. The [use cases](use_cases.md) do not require @@ -39,7 +39,7 @@ for that is: Array libraries may know how to interoperate with each other, for example by constructing their own array type from that of another library or by shared -memory use of an array (see [Data interchange mechanisms](design_topics/data_interchange.md)). +memory use of an array (see [Data interchange mechanisms](design_topics/data_interchange.rst)). This can be done without a dependency though - only adherence to a protocol is enough. diff --git a/spec/2022.12/purpose_and_scope.md b/spec/2022.12/purpose_and_scope.md index 38287f270..f375c9512 100644 --- a/spec/2022.12/purpose_and_scope.md +++ b/spec/2022.12/purpose_and_scope.md @@ -151,7 +151,7 @@ standard is shown in this diagram: _Rationale: this is an important topic for some array-consuming libraries, but there is no widely shared C/Cython API and hence it doesn't make sense at this point in time to standardize anything. See - the [C API section](design_topics/C_API.md) for more details._ + the [C API section](design_topics/C_API.rst) for more details._ 4. Standardization of these dtypes is out of scope: bfloat16, extended precision floating point, datetime, string, object and void dtypes. diff --git a/spec/2022.12/use_cases.md b/spec/2022.12/use_cases.md index 26f7a529c..e24aa50db 100644 --- a/spec/2022.12/use_cases.md +++ b/spec/2022.12/use_cases.md @@ -59,7 +59,7 @@ array implementation as a dependency. It's clear that SciPy functionality that relies on compiled extensions (C, C++, Cython, Fortran) directly can't easily be run on another array library -than NumPy (see [C API](design_topics/C_API.md) for more details about this topic). Pure Python +than NumPy (see [C API](design_topics/C_API.rst) for more details about this topic). Pure Python code can work though. There's two main possibilities: 1. Testing with another package, manually or in CI, and simply provide a list diff --git a/spec/draft/API_specification/array_object.rst b/spec/draft/API_specification/array_object.rst index 0fadf9fc5..f8a586ade 100644 --- a/spec/draft/API_specification/array_object.rst +++ b/spec/draft/API_specification/array_object.rst @@ -163,7 +163,8 @@ A conforming implementation of the array API standard must provide and support a - `operator.ne(x1, x2) `_ - `operator.__ne__(x1, x2) `_ -Comparison operators should be defined for arrays having any data type. +:meth:`.array.__lt__`, :meth:`.array.__le__`, :meth:`.array.__gt__`, :meth:`.array.__ge__` are only defined for arrays having real-valued data types. Other comparison operators should be defined for arrays having any data type. +For backward compatibility, conforming implementations may support complex numbers; however, inequality comparison of complex numbers is unspecified and thus implementation-dependent (see :ref:`complex-number-ordering`). In-place Operators ~~~~~~~~~~~~~~~~~~ diff --git a/spec/draft/API_specification/elementwise_functions.rst b/spec/draft/API_specification/elementwise_functions.rst index b3f08727b..f0b69cfcb 100644 --- a/spec/draft/API_specification/elementwise_functions.rst +++ b/spec/draft/API_specification/elementwise_functions.rst @@ -33,6 +33,7 @@ Objects in API bitwise_right_shift bitwise_xor ceil + clip conj copysign cos @@ -60,6 +61,8 @@ Objects in API logical_not logical_or logical_xor + maximum + minimum multiply negative not_equal diff --git a/spec/draft/API_specification/function_and_method_signatures.rst b/spec/draft/API_specification/function_and_method_signatures.rst index 86d0819a6..0eca2ac69 100644 --- a/spec/draft/API_specification/function_and_method_signatures.rst +++ b/spec/draft/API_specification/function_and_method_signatures.rst @@ -5,7 +5,7 @@ Function and method signatures Function signatures in this standard adhere to the following: -1. Positional parameters must be `positional-only `_ parameters. +1. Positional parameters should be `positional-only `_ parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. @@ -20,7 +20,7 @@ Function signatures in this standard adhere to the following: namespace >= 3.8. Alternatively, they can add guidance to their users in the documentation to use the functions as if they were positional-only. -2. Optional parameters must be `keyword-only `_ arguments. +2. Optional parameters should be `keyword-only `_ arguments. *Rationale: this leads to more readable code, and it makes it easier to evolve an API over time by adding keywords without having to worry about @@ -30,8 +30,8 @@ Function signatures in this standard adhere to the following: is called ``x``. For functions that have multiple array parameters, those parameters are called ``xi`` with ``i = 1, 2, ...`` (i.e., ``x1``, ``x2``). -4. Type annotations are left out of the signatures themselves for readability; however, - they are added to individual parameter descriptions. For code which aims to +4. Signatures include type annotations. The type annotations are also added to + individual parameter and return value descriptions. For code which aims to adhere to the standard, adding type annotations is strongly recommended. A function signature and description will look like: @@ -57,3 +57,7 @@ A function signature and description will look like: Method signatures will follow the same conventions modulo the addition of ``self``. + +Note that there are a few exceptions to rules (1) and (2), in cases where +it enhances readability or use of the non-default form of the parameter in +question is commonly used in code written for existing array libraries. diff --git a/spec/draft/API_specification/searching_functions.rst b/spec/draft/API_specification/searching_functions.rst index 01ab4e82a..c952f1aad 100644 --- a/spec/draft/API_specification/searching_functions.rst +++ b/spec/draft/API_specification/searching_functions.rst @@ -23,4 +23,5 @@ Objects in API argmax argmin nonzero + searchsorted where diff --git a/spec/draft/API_specification/statistical_functions.rst b/spec/draft/API_specification/statistical_functions.rst index 23cd2cb1d..20e02b3f9 100644 --- a/spec/draft/API_specification/statistical_functions.rst +++ b/spec/draft/API_specification/statistical_functions.rst @@ -18,6 +18,7 @@ Objects in API :toctree: generated :template: method.rst + cumulative_sum max mean min diff --git a/spec/draft/assumptions.md b/spec/draft/assumptions.md index 3a90710ea..b11482c5a 100644 --- a/spec/draft/assumptions.md +++ b/spec/draft/assumptions.md @@ -26,7 +26,7 @@ of functions to be predictable from input dtypes only rather than input values. The only dependency that's assumed in this standard is that on Python itself. Python >= 3.8 is assumed, motivated by the use of positional-only parameters -(see [function and method signatures](API_specification/function_and_method_signatures.md)). +(see [function and method signatures](API_specification/function_and_method_signatures.rst)). Importantly, array libraries are not assumed to be aware of each other, or of a common array-specific layer. The [use cases](use_cases.md) do not require @@ -39,7 +39,7 @@ for that is: Array libraries may know how to interoperate with each other, for example by constructing their own array type from that of another library or by shared -memory use of an array (see [Data interchange mechanisms](design_topics/data_interchange.md)). +memory use of an array (see [Data interchange mechanisms](design_topics/data_interchange.rst)). This can be done without a dependency though - only adherence to a protocol is enough. diff --git a/spec/draft/design_topics/data_interchange.rst b/spec/draft/design_topics/data_interchange.rst index 8686042c8..3b3040672 100644 --- a/spec/draft/design_topics/data_interchange.rst +++ b/spec/draft/design_topics/data_interchange.rst @@ -84,3 +84,22 @@ page gives a high-level specification for data exchange in Python using DLPack. are recommended to do so using the same syntax and semantics as outlined below. They are not required to return an array object from ``from_dlpack`` which conforms to this standard. + +Non-supported use cases +----------------------- + +Use of DLPack requires that the data can be represented by a strided, in-memory +layout on a single device. This covers usage by a large range of, but not all, +known and possible array libraries. Use cases that are not supported by DLPack +include: + +- Distributed arrays, i.e., the data residing on multiple nodes or devices, +- Sparse arrays, i.e., sparse representations where a data value (typically + zero) is implicit. + +There may be other reasons why it is not possible or desirable for an +implementation to materialize the array as strided data in memory. In such +cases, the implementation may raise a `BufferError` in the `__dlpack__` or +`__dlpack_device__` method. In case an implementation is never able to export +its array data via DLPack, it may omit `__dlpack__` and `__dlpack_device__` +completely, and hence `from_dlpack` may raise an `AttributeError`. diff --git a/spec/draft/extensions/index.rst b/spec/draft/extensions/index.rst index 30d9cfa90..3b9409954 100644 --- a/spec/draft/extensions/index.rst +++ b/spec/draft/extensions/index.rst @@ -24,11 +24,10 @@ the implementer, e.g. via a regular submodule that is imported under the The functions in an extension must adhere to the same conventions as those in the array API standard. See :ref:`api-specification`. - -Extensions ----------- +------------------------------------------------------------------------------ .. toctree:: + :caption: Extension modules: :maxdepth: 1 fourier_transform_functions diff --git a/spec/draft/purpose_and_scope.md b/spec/draft/purpose_and_scope.md index 38287f270..f375c9512 100644 --- a/spec/draft/purpose_and_scope.md +++ b/spec/draft/purpose_and_scope.md @@ -151,7 +151,7 @@ standard is shown in this diagram: _Rationale: this is an important topic for some array-consuming libraries, but there is no widely shared C/Cython API and hence it doesn't make sense at this point in time to standardize anything. See - the [C API section](design_topics/C_API.md) for more details._ + the [C API section](design_topics/C_API.rst) for more details._ 4. Standardization of these dtypes is out of scope: bfloat16, extended precision floating point, datetime, string, object and void dtypes. diff --git a/spec/draft/use_cases.md b/spec/draft/use_cases.md index 26f7a529c..e24aa50db 100644 --- a/spec/draft/use_cases.md +++ b/spec/draft/use_cases.md @@ -59,7 +59,7 @@ array implementation as a dependency. It's clear that SciPy functionality that relies on compiled extensions (C, C++, Cython, Fortran) directly can't easily be run on another array library -than NumPy (see [C API](design_topics/C_API.md) for more details about this topic). Pure Python +than NumPy (see [C API](design_topics/C_API.rst) for more details about this topic). Pure Python code can work though. There's two main possibilities: 1. Testing with another package, manually or in CI, and simply provide a list diff --git a/src/_array_api_conf.py b/src/_array_api_conf.py index d3a136eaa..9c5722f94 100644 --- a/src/_array_api_conf.py +++ b/src/_array_api_conf.py @@ -52,12 +52,14 @@ nitpick_ignore = [ ("py:class", "collections.abc.Sequence"), ("py:class", "Optional[Union[int, float, Literal[inf, - inf, 'fro', 'nuc']]]"), + ("py:class", "int | float | ~typing.Literal[inf, -inf, 'fro', 'nuc'] | None"), ("py:class", "Union[int, float, Literal[inf, - inf]]"), ( "py:obj", "typing.Optional[typing.Union[int, float, typing.Literal[inf, - inf, 'fro', 'nuc']]]", ), ("py:obj", "typing.Union[int, float, typing.Literal[inf, - inf]]"), + ("py:class", "int | float | ~typing.Literal[inf, -inf]"), ("py:class", "enum.Enum"), ("py:class", "ellipsis"), ] diff --git a/src/array_api_stubs/_2022_12/fft.py b/src/array_api_stubs/_2022_12/fft.py index 7979095fe..f79aa155e 100644 --- a/src/array_api_stubs/_2022_12/fft.py +++ b/src/array_api_stubs/_2022_12/fft.py @@ -1,3 +1,20 @@ +__all__ = [ + "fft", + "ifft", + "fftn", + "ifftn", + "rfft", + "irfft", + "rfftn", + "irfftn", + "hfft", + "ihfft", + "fftfreq", + "rfftfreq", + "fftshift", + "ifftshift", +] + from ._types import Tuple, Union, Sequence, array, Optional, Literal, device @@ -13,24 +30,22 @@ def fft( Computes the one-dimensional discrete Fourier transform. .. note:: - Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (length, axis, and normalization mode). + Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (number of elements, axis, and normalization mode). Parameters ---------- x: array - input array. Should have a floating-point data type. - n: int - length of the transformed axis of the output. If + input array. Should have a complex-valued floating-point data type. + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -43,7 +58,7 @@ def fft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- @@ -64,24 +79,22 @@ def ifft( Computes the one-dimensional inverse discrete Fourier transform. .. note:: - Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same (length, axis, and normalization mode). + Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (number of elements, axis, and normalization mode). Parameters ---------- x: array - input array. Should have a floating-point data type. - n: int - length of the transformed axis of the output. If + input array. Should have a complex-valued floating-point data type. + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the inverse Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -94,7 +107,7 @@ def ifft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- @@ -107,8 +120,8 @@ def fftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -120,24 +133,19 @@ def fftn( Parameters ---------- x: array - input array. Should have a floating-point data type. - s: Sequence[int] - size of each transformed axis of the output. If - - - ``s[i]`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``s[i]``. - - ``s[i]`` is less than the size of the input array along a corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``s[i]``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array. + input array. Should have a complex-valued floating-point data type. + s: Optional[Sequence[int]] + number of elements over which to compute the transform along the axes (dimensions) specified by ``axes``. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``. - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. + - If ``s[i]`` is greater than ``M[i]``, axis ``i`` must be zero-padded to size ``s[i]``. + - If ``s[i]`` is less than ``M[i]``, axis ``i`` must be trimmed to size ``s[i]``. + - If ``s[i]`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` must be used when computing the transform. - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. - - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -152,7 +160,7 @@ def fftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axes (dimensions) specified by ``axes``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axes specified by ``axes`` which must have size ``s[i]``. Notes ----- @@ -165,8 +173,8 @@ def ifftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -178,24 +186,19 @@ def ifftn( Parameters ---------- x: array - input array. Should have a floating-point data type. - s: Sequence[int] - size of each transformed axis of the output. If - - - ``s[i]`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``s[i]``. - - ``s[i]`` is less than the size of the input array along a corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``s[i]``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array. - - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. + input array. Should have a complex-valued floating-point data type. + s: Optional[Sequence[int]] + number of elements over which to compute the transform along the axes (dimensions) specified by ``axes``. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``. - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. + - If ``s[i]`` is greater than ``M[i]``, axis ``i`` must be zero-padded to size ``s[i]``. + - If ``s[i]`` is less than ``M[i]``, axis ``i`` must be trimmed to size ``s[i]``. + - If ``s[i]`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` must be used when computing the transform. - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] specify the normalization mode. Should be one of the following modes: @@ -210,7 +213,7 @@ def ifftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axes (dimensions) specified by ``axes``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axes specified by ``axes`` which must have size ``s[i]``. Notes ----- @@ -231,24 +234,22 @@ def rfft( Computes the one-dimensional discrete Fourier transform for real-valued input. .. note:: - Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and normalization mode) and consistent length. + Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and and normalization mode) and consistent values for the number of elements over which to compute the transforms. Parameters ---------- x: array input array. Must have a real-valued floating-point data type. - n: int - length of the transformed axis of the **input**. If + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -261,7 +262,7 @@ def rfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a complex floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``float64``, then the returned array must have a ``complex128`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n//2 + 1``. Notes ----- @@ -282,24 +283,22 @@ def irfft( Computes the one-dimensional inverse of ``rfft`` for complex-valued input. .. note:: - Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and normalization mode) and consistent length. + Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and and normalization mode) and consistent values for the number of elements over which to compute the transforms. Parameters ---------- x: array input array. Should have a complex-valued floating-point data type. - n: int - length of the transformed axis of the **output**. If + n: Optional[int] + number of elements along the transformed axis (dimension) specified by ``axis`` in the **output array**. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``2*(M-1)``. - - ``n//2+1`` is greater than the length of the input array, the input array is zero-padded to length ``n//2+1``. - - ``n//2+1`` is less than the length of the input array, the input array is trimmed to length ``n//2+1``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length ``2*(m-1)``, where ``m`` is the length of the input along the axis specified by ``axis``. + - If ``n//2+1`` is greater than ``M``, the axis of the input array specified by ``axis`` must be zero-padded to size ``n//2+1``. + - If ``n//2+1`` is less than ``M``, the axis of the input array specified by ``axis`` must be trimmed to size ``n//2+1``. + - If ``n//2+1`` equals ``M``, all elements along the axis of the input array specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the inverse Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -312,11 +311,13 @@ def irfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. The length along the transformed axis is ``n`` (if given) or ``2*(m-1)`` (otherwise). + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then the returned array must have a ``float64`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- + - In order to return an array having an odd number of elements along the transformed axis, the function must be provided an odd integer for ``n``. + .. versionadded:: 2022.12 """ @@ -325,8 +326,8 @@ def rfftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -339,23 +340,18 @@ def rfftn( ---------- x: array input array. Must have a real-valued floating-point data type. - s: Sequence[int] - size of each transformed axis of the **input**. If - - - ``s[i]`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``s[i]``. - - ``s[i]`` is less than the size of the input array along a corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``s[i]``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array. + s: Optional[Sequence[int]] + number of elements over which to compute the transform along axes (dimensions) specified by ``axes``. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``. - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. + - If ``s[i]`` is greater than ``M[i]``, axis ``i`` must be zero-padded to size ``s[i]``. + - If ``s[i]`` is less than ``M[i]``, axis ``i`` must be trimmed to size ``s[i]``. + - If ``s[i]`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` must be used when computing the transform. - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. - - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -370,7 +366,7 @@ def rfftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a complex-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axes (dimension) specified by ``axes``. The returned array must have a complex floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``float64``, then the returned array must have a ``complex128`` data type). The returned array must have the same shape as ``x``, except for the last transformed axis which must have size ``s[-1]//2 + 1`` and the remaining transformed axes which must have size ``s[i]``. Notes ----- @@ -383,8 +379,8 @@ def irfftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -397,23 +393,18 @@ def irfftn( ---------- x: array input array. Should have a complex-valued floating-point data type. - s: Sequence[int] - size of each transformed axis of the **output**. ``n=s[i]`` is also the number of input points used along the axis (dimension) ``i``, except for the last axis, where ``n=s[-1]//2+1`` points of the input are used. If + s: Optional[Sequence[int]] + number of elements along the transformed axes (dimensions) specified by ``axes`` in the **output array**. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``, except for the last transformed axis in which ``s[i]`` equals ``2*(M[i]-1)``. For each ``i``, let ``n`` equal ``s[i]``, except for the last transformed axis in which ``n`` equals ``s[i]//2+1``. - - ``n`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``n``. - - ``n`` is less than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``n``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array, except for the last axis which is trimmed to ``2*(m-1)``, where ``m`` is the length of the input along the axis. + - If ``n`` is greater than ``M[i]``, axis ``i`` of the input array must be zero-padded to size ``n``. + - If ``n`` is less than ``M[i]``, axis ``i`` of the input array must be trimmed to size ``n``. + - If ``n`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` of the input array must be used when computing the transform. - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. - - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. - - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -428,11 +419,13 @@ def irfftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. The length along the last transformed axis is ``s[-1]`` (if given) or ``2*(m - 1)`` (otherwise), and all other axes ``s[i]``. + an array transformed along the axes (dimension) specified by ``axes``. The returned array must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then the returned array must have a ``float64`` data type). The returned array must have the same shape as ``x``, except for the transformed axes which must have size ``s[i]``. Notes ----- + - In order to return an array having an odd number of elements along the last transformed axis, the function must be provided an odd integer for ``s[-1]``. + .. versionadded:: 2022.12 """ @@ -451,19 +444,17 @@ def hfft( Parameters ---------- x: array - input array. Should have a floating-point data type. - n: int - length of the transformed axis of the **output**. If + input array. Should have a complex-valued floating-point data type. + n: Optional[int] + number of elements along the transformed axis (dimension) specified by ``axis`` in the **output array**. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``2*(M-1)``. - - ``n//2+1`` is greater than the length of the input array, the input array is zero-padded to length ``n//2+1``. - - ``n//2+1`` is less than the length of the input array, the input array is trimmed to length ``n//2+1``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length ``2*(m-1)``, where ``m`` is the length of the input along the axis specified by ``axis``. + - If ``n//2+1`` is greater than ``M``, the axis of the input array specified by ``axis`` must be zero-padded to length ``n//2+1``. + - If ``n//2+1`` is less than ``M``, the axis of the input array specified by ``axis`` must be trimmed to size ``n//2+1``. + - If ``n//2+1`` equals ``M``, all elements along the axis of the input array specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -476,7 +467,7 @@ def hfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then the returned array must have a ``float64`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- @@ -500,18 +491,16 @@ def ihfft( ---------- x: array input array. Must have a real-valued floating-point data type. - n: int - length of the transformed axis of the **input**. If + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -524,7 +513,7 @@ def ihfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a complex floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``float64``, then the returned array must have a ``complex128`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n//2 + 1``. Notes ----- @@ -535,9 +524,9 @@ def ihfft( def fftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> array: """ - Returns the discrete Fourier transform sample frequencies. + Computes the discrete Fourier transform sample frequencies. - For a Fourier transform of length ``n`` and length unit of ``d`` the frequencies are described as: + For a Fourier transform of length ``n`` and length unit of ``d``, the frequencies are described as: .. code-block:: @@ -556,7 +545,7 @@ def fftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> ar Returns ------- out: array - an array of length ``n`` containing the sample frequencies. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. + an array of shape ``(n,)`` containing the sample frequencies. The returned array must have the default real-valued floating-point data type. Notes ----- @@ -567,9 +556,9 @@ def fftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> ar def rfftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> array: """ - Returns the discrete Fourier transform sample frequencies (for ``rfft`` and ``irfft``). + Computes the discrete Fourier transform sample frequencies (for ``rfft`` and ``irfft``). - For a Fourier transform of length ``n`` and length unit of ``d`` the frequencies are described as: + For a Fourier transform of length ``n`` and length unit of ``d``, the frequencies are described as: .. code-block:: @@ -590,7 +579,7 @@ def rfftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> a Returns ------- out: array - an array of length ``n//2+1`` containing the sample frequencies. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. + an array of shape ``(n//2+1,)`` containing the sample frequencies. The returned array must have the default real-valued floating-point data type. Notes ----- @@ -599,9 +588,9 @@ def rfftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> a """ -def fftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: +def fftshift(x: array, /, *, axes: Optional[Union[int, Sequence[int]]] = None) -> array: """ - Shift the zero-frequency component to the center of the spectrum. + Shifts the zero-frequency component to the center of the spectrum. This function swaps half-spaces for all axes (dimensions) specified by ``axes``. @@ -612,13 +601,13 @@ def fftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: ---------- x: array input array. Should have a floating-point data type. - axes: Union[int, Sequence[int]] + axes: Optional[Union[int, Sequence[int]]] axes over which to shift. If ``None``, the function must shift all axes. Default: ``None``. Returns ------- out: array - the shifted array. The returned array must have the same data type as ``x``. + the shifted array. The returned array must have the same data type and shape as ``x``. Notes ----- @@ -627,7 +616,9 @@ def fftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: """ -def ifftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: +def ifftshift( + x: array, /, *, axes: Optional[Union[int, Sequence[int]]] = None +) -> array: """ Inverse of ``fftshift``. @@ -638,34 +629,16 @@ def ifftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: ---------- x: array input array. Should have a floating-point data type. - axes: Union[int, Sequence[int]] + axes: Optional[Union[int, Sequence[int]]] axes over which to perform the inverse shift. If ``None``, the function must shift all axes. Default: ``None``. Returns ------- out: array - the shifted array. The returned array must have the same data type as ``x``. + the shifted array. The returned array must have the same data type and shape as ``x``. Notes ----- .. versionadded:: 2022.12 """ - - -__all__ = [ - "fft", - "ifft", - "fftn", - "ifftn", - "rfft", - "irfft", - "rfftn", - "irfftn", - "hfft", - "ihfft", - "fftfreq", - "rfftfreq", - "fftshift", - "ifftshift", -] diff --git a/src/array_api_stubs/_2022_12/linear_algebra_functions.py b/src/array_api_stubs/_2022_12/linear_algebra_functions.py index 110a19ce1..d5329db76 100644 --- a/src/array_api_stubs/_2022_12/linear_algebra_functions.py +++ b/src/array_api_stubs/_2022_12/linear_algebra_functions.py @@ -122,9 +122,9 @@ def vecdot(x1: array, x2: array, /, *, axis: int = -1) -> array: Let :math:`\mathbf{a}` be a vector in ``x1`` and :math:`\mathbf{b}` be a corresponding vector in ``x2``. The dot product is defined as .. math:: - \mathbf{a} \cdot \mathbf{b} = \sum_{i=0}^{n-1} a_i\overline{b_i} + \mathbf{a} \cdot \mathbf{b} = \sum_{i=0}^{n-1} \overline{a_i}b_i - over the dimension specified by ``axis`` and where :math:`n` is the dimension size and :math:`\overline{b_i}` denotes the complex conjugate if :math:`b_i` is complex and the identity if :math:`b_i` is real-valued. + over the dimension specified by ``axis`` and where :math:`n` is the dimension size and :math:`\overline{a_i}` denotes the complex conjugate if :math:`a_i` is complex and the identity if :math:`a_i` is real-valued. Parameters ---------- diff --git a/src/array_api_stubs/_draft/creation_functions.py b/src/array_api_stubs/_draft/creation_functions.py index 5e2bb44e6..69733a646 100644 --- a/src/array_api_stubs/_draft/creation_functions.py +++ b/src/array_api_stubs/_draft/creation_functions.py @@ -232,6 +232,20 @@ def from_dlpack(x: object, /) -> array: :class: note The returned array may be either a copy or a view. See :ref:`data-interchange` for details. + + Raises + ------ + BufferError + The ``__dlpack__`` and ``__dlpack_device__`` methods on the input array + may raise ``BufferError`` when the data cannot be exported as DLPack + (e.g., incompatible dtype or strides). It may also raise other errors + when export fails for other reasons (e.g., not enough memory available + to materialize the data). ``from_dlpack`` must propagate such + exceptions. + AttributeError + If the ``__dlpack__`` and ``__dlpack_device__`` methods are not present + on the input array. This may happen for libraries that are never able + to export their data with DLPack. """ diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index 5ff0c45d6..c71b6674b 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -15,6 +15,7 @@ "bitwise_right_shift", "bitwise_xor", "ceil", + "clip", "conj", "copysign", "cos", @@ -42,6 +43,8 @@ "logical_not", "logical_or", "logical_xor", + "maximum", + "minimum", "multiply", "negative", "not_equal", @@ -63,7 +66,7 @@ ] -from ._types import array +from ._types import Optional, Union, array def abs(x: array, /) -> array: @@ -773,6 +776,38 @@ def ceil(x: array, /) -> array: """ +def clip( + x: array, + /, + min: Optional[Union[int, float, array]] = None, + max: Optional[Union[int, float, array]] = None, +) -> array: + r""" + Clamps each element ``x_i`` of the input array ``x`` to the range ``[min, max]``. + + Parameters + ---------- + x: array + input array. Should have a real-valued data type. + min: Optional[Union[int, float, array]] + lower-bound of the range to which to clamp. If ``None``, no lower bound must be applied. Must be compatible with ``x1`` (see :ref:`broadcasting`). Should have a real-valued data type. Default: ``None``. + max: Optional[Union[int, float, array]] + upper-bound of the range to which to clamp. If ``None``, no upper bound must be applied. Must be compatible with ``x1`` (see :ref:`broadcasting`). Should have a real-valued data type. Default: ``None``. + + Returns + ------- + out: array + an array containing element-wise results. The returned array must have the same data type as ``x``. + + Notes + ----- + + - If both ``min`` and ``max`` are ``None``, the elements of the returned array must equal the respective elements in ``x``. + - If a broadcasted element in ``min`` is greater than a corresponding broadcasted element in ``max``, behavior is unspecified and thus implementation-dependent. + - If ``x`` and either ``min`` or ``max`` have different data type kinds (e.g., integer versus floating-point), behavior is unspecified and thus implementation-dependent. + """ + + def conj(x: array, /) -> array: """ Returns the complex conjugate for each element ``x_i`` of the input array ``x``. @@ -1820,6 +1855,66 @@ def logical_xor(x1: array, x2: array, /) -> array: """ +def maximum(x1: array, x2: array, /) -> array: + r""" + Computes the maximum value for each element ``x1_i`` of the input array ``x1`` relative to the respective element ``x2_i`` of the input array ``x2``. + + .. note:: + For backward compatibility, conforming implementations may support complex numbers; however, inequality comparison of complex numbers is unspecified and thus implementation-dependent (see :ref:`complex-number-ordering`). + + Parameters + ---------- + x1: array + first input array. Should have a real-valued data type. + x2: array + second input array. Must be compatible with ``x1`` (see :ref:`broadcasting`). Should have a real-valued data type. + + Returns + ------- + out: array + an array containing the element-wise maximum values. The returned array must have a data type determined by :ref:`type-promotion`. + + Notes + ----- + + **Special Cases** + + For floating-point operands, + + - If either ``x1_i`` or ``x2_i`` is ``NaN``, the result is ``NaN``. + """ + + +def minimum(x1: array, x2: array, /) -> array: + r""" + Computes the minimum value for each element ``x1_i`` of the input array ``x1`` relative to the respective element ``x2_i`` of the input array ``x2``. + + .. note:: + For backward compatibility, conforming implementations may support complex numbers; however, inequality comparison of complex numbers is unspecified and thus implementation-dependent (see :ref:`complex-number-ordering`). + + Parameters + ---------- + x1: array + first input array. Should have a real-valued data type. + x2: array + second input array. Must be compatible with ``x1`` (see :ref:`broadcasting`). Should have a real-valued data type. + + Returns + ------- + out: array + an array containing the element-wise minimum values. The returned array must have a data type determined by :ref:`type-promotion`. + + Notes + ----- + + **Special Cases** + + For floating-point operands, + + - If either ``x1_i`` or ``x2_i`` is ``NaN``, the result is ``NaN``. + """ + + def multiply(x1: array, x2: array, /) -> array: r""" Calculates the product for each element ``x1_i`` of the input array ``x1`` with the respective element ``x2_i`` of the input array ``x2``. diff --git a/src/array_api_stubs/_draft/fft.py b/src/array_api_stubs/_draft/fft.py index 4a59392d5..f79aa155e 100644 --- a/src/array_api_stubs/_draft/fft.py +++ b/src/array_api_stubs/_draft/fft.py @@ -30,24 +30,22 @@ def fft( Computes the one-dimensional discrete Fourier transform. .. note:: - Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (length, axis, and normalization mode). + Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (number of elements, axis, and normalization mode). Parameters ---------- x: array - input array. Should have a floating-point data type. - n: int - length of the transformed axis of the output. If + input array. Should have a complex-valued floating-point data type. + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -60,7 +58,7 @@ def fft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- @@ -81,24 +79,22 @@ def ifft( Computes the one-dimensional inverse discrete Fourier transform. .. note:: - Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same (length, axis, and normalization mode). + Applying the one-dimensional inverse discrete Fourier transform to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``ifft(fft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (number of elements, axis, and normalization mode). Parameters ---------- x: array - input array. Should have a floating-point data type. - n: int - length of the transformed axis of the output. If + input array. Should have a complex-valued floating-point data type. + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the inverse Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -111,7 +107,7 @@ def ifft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- @@ -124,8 +120,8 @@ def fftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -137,24 +133,19 @@ def fftn( Parameters ---------- x: array - input array. Should have a floating-point data type. - s: Sequence[int] - size of each transformed axis of the output. If - - - ``s[i]`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``s[i]``. - - ``s[i]`` is less than the size of the input array along a corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``s[i]``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array. - - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. + input array. Should have a complex-valued floating-point data type. + s: Optional[Sequence[int]] + number of elements over which to compute the transform along the axes (dimensions) specified by ``axes``. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``. - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. + - If ``s[i]`` is greater than ``M[i]``, axis ``i`` must be zero-padded to size ``s[i]``. + - If ``s[i]`` is less than ``M[i]``, axis ``i`` must be trimmed to size ``s[i]``. + - If ``s[i]`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` must be used when computing the transform. - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -169,7 +160,7 @@ def fftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axes (dimensions) specified by ``axes``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axes specified by ``axes`` which must have size ``s[i]``. Notes ----- @@ -182,8 +173,8 @@ def ifftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -195,24 +186,19 @@ def ifftn( Parameters ---------- x: array - input array. Should have a floating-point data type. - s: Sequence[int] - size of each transformed axis of the output. If - - - ``s[i]`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``s[i]``. - - ``s[i]`` is less than the size of the input array along a corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``s[i]``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array. - - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. + input array. Should have a complex-valued floating-point data type. + s: Optional[Sequence[int]] + number of elements over which to compute the transform along the axes (dimensions) specified by ``axes``. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``. - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. + - If ``s[i]`` is greater than ``M[i]``, axis ``i`` must be zero-padded to size ``s[i]``. + - If ``s[i]`` is less than ``M[i]``, axis ``i`` must be trimmed to size ``s[i]``. + - If ``s[i]`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` must be used when computing the transform. - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] specify the normalization mode. Should be one of the following modes: @@ -227,7 +213,7 @@ def ifftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a complex floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axes (dimensions) specified by ``axes``. The returned array must have the same data type as ``x`` and must have the same shape as ``x``, except for the axes specified by ``axes`` which must have size ``s[i]``. Notes ----- @@ -248,24 +234,22 @@ def rfft( Computes the one-dimensional discrete Fourier transform for real-valued input. .. note:: - Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and normalization mode) and consistent length. + Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and and normalization mode) and consistent values for the number of elements over which to compute the transforms. Parameters ---------- x: array input array. Must have a real-valued floating-point data type. - n: int - length of the transformed axis of the **input**. If + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -278,7 +262,7 @@ def rfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a complex floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``float64``, then the returned array must have a ``complex128`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n//2 + 1``. Notes ----- @@ -299,24 +283,22 @@ def irfft( Computes the one-dimensional inverse of ``rfft`` for complex-valued input. .. note:: - Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and normalization mode) and consistent length. + Applying the one-dimensional inverse discrete Fourier transform for real-valued input to the output of this function must return the original (i.e., non-transformed) input array within numerical accuracy (i.e., ``irfft(rfft(x)) == x``), provided that the transform and inverse transform are performed with the same arguments (axis and and normalization mode) and consistent values for the number of elements over which to compute the transforms. Parameters ---------- x: array input array. Should have a complex-valued floating-point data type. - n: int - length of the transformed axis of the **output**. If + n: Optional[int] + number of elements along the transformed axis (dimension) specified by ``axis`` in the **output array**. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``2*(M-1)``. - - ``n//2+1`` is greater than the length of the input array, the input array is zero-padded to length ``n//2+1``. - - ``n//2+1`` is less than the length of the input array, the input array is trimmed to length ``n//2+1``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length ``2*(m-1)``, where ``m`` is the length of the input along the axis specified by ``axis``. + - If ``n//2+1`` is greater than ``M``, the axis of the input array specified by ``axis`` must be zero-padded to size ``n//2+1``. + - If ``n//2+1`` is less than ``M``, the axis of the input array specified by ``axis`` must be trimmed to size ``n//2+1``. + - If ``n//2+1`` equals ``M``, all elements along the axis of the input array specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the inverse Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -329,11 +311,13 @@ def irfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. The length along the transformed axis is ``n`` (if given) or ``2*(m-1)`` (otherwise). + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then the returned array must have a ``float64`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- + - In order to return an array having an odd number of elements along the transformed axis, the function must be provided an odd integer for ``n``. + .. versionadded:: 2022.12 """ @@ -342,8 +326,8 @@ def rfftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -356,23 +340,18 @@ def rfftn( ---------- x: array input array. Must have a real-valued floating-point data type. - s: Sequence[int] - size of each transformed axis of the **input**. If - - - ``s[i]`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``s[i]``. - - ``s[i]`` is less than the size of the input array along a corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``s[i]``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array. + s: Optional[Sequence[int]] + number of elements over which to compute the transform along axes (dimensions) specified by ``axes``. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``. - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. + - If ``s[i]`` is greater than ``M[i]``, axis ``i`` must be zero-padded to size ``s[i]``. + - If ``s[i]`` is less than ``M[i]``, axis ``i`` must be trimmed to size ``s[i]``. + - If ``s[i]`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` must be used when computing the transform. - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. - - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -387,7 +366,7 @@ def rfftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a complex-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axes (dimension) specified by ``axes``. The returned array must have a complex floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``float64``, then the returned array must have a ``complex128`` data type). The returned array must have the same shape as ``x``, except for the last transformed axis which must have size ``s[-1]//2 + 1`` and the remaining transformed axes which must have size ``s[i]``. Notes ----- @@ -400,8 +379,8 @@ def irfftn( x: array, /, *, - s: Sequence[int] = None, - axes: Sequence[int] = None, + s: Optional[Sequence[int]] = None, + axes: Optional[Sequence[int]] = None, norm: Literal["backward", "ortho", "forward"] = "backward", ) -> array: """ @@ -414,23 +393,18 @@ def irfftn( ---------- x: array input array. Should have a complex-valued floating-point data type. - s: Sequence[int] - size of each transformed axis of the **output**. ``n=s[i]`` is also the number of input points used along the axis (dimension) ``i``, except for the last axis, where ``n=s[-1]//2+1`` points of the input are used. If - - - ``n`` is greater than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is zero-padded to size ``n``. - - ``n`` is less than the size of the input array along the corresponding axis (dimension) ``i``, the input array along the axis ``i`` is trimmed to size ``n``. - - ``s[i]`` is ``-1``, the whole input array along the axis ``i`` is used (no padding/trimming). - - ``s`` is not provided, the size of each transformed axis (dimension) in the output array must equal the size of the corresponding axis in the input array, except for the last axis which is trimmed to ``2*(m-1)``, where ``m`` is the length of the input along the axis. - - If ``s`` is not ``None``, ``axes`` must not be ``None`` either, and ``s[i]`` corresponds to the size along the transformed axis specified by ``axes[i]``. + s: Optional[Sequence[int]] + number of elements along the transformed axes (dimensions) specified by ``axes`` in the **output array**. Let ``i`` be the index of the nth axis specified by ``axes`` and ``M[i]`` be the size of the input array along axis ``i``. When ``s`` is ``None``, the function must set ``s`` equal to a sequence of integers, such that, for all ``i``, ``s[i]`` equals ``M[i]``, except for the last transformed axis in which ``s[i]`` equals ``2*(M[i]-1)``. For each ``i``, let ``n`` equal ``s[i]``, except for the last transformed axis in which ``n`` equals ``s[i]//2+1``. - Default: ``None``. - axes: Sequence[int] - axes (dimensions) over which to compute the Fourier transform. If ``None``, all axes must be transformed. + - If ``n`` is greater than ``M[i]``, axis ``i`` of the input array must be zero-padded to size ``n``. + - If ``n`` is less than ``M[i]``, axis ``i`` of the input array must be trimmed to size ``n``. + - If ``n`` equals ``M[i]`` or ``-1``, all elements along axis ``i`` of the input array must be used when computing the transform. - If ``s`` is specified, the corresponding ``axes`` to be transformed must be explicitly specified too. + If ``s`` is not ``None``, ``axes`` must not be ``None``. Default: ``None``. + axes: Optional[Sequence[int]] + axes (dimensions) over which to compute the transform. A valid axis must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an axis is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). - Default: ``None``. + If ``s`` is provided, the corresponding ``axes`` to be transformed must also be provided. If ``axes`` is ``None``, the function must compute the transform over all axes. Default: ``None``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -445,11 +419,13 @@ def irfftn( Returns ------- out: array - an array transformed along the axes (dimension) indicated by ``axes``. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. The length along the last transformed axis is ``s[-1]`` (if given) or ``2*(m - 1)`` (otherwise), and all other axes ``s[i]``. + an array transformed along the axes (dimension) specified by ``axes``. The returned array must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then the returned array must have a ``float64`` data type). The returned array must have the same shape as ``x``, except for the transformed axes which must have size ``s[i]``. Notes ----- + - In order to return an array having an odd number of elements along the last transformed axis, the function must be provided an odd integer for ``s[-1]``. + .. versionadded:: 2022.12 """ @@ -468,19 +444,17 @@ def hfft( Parameters ---------- x: array - input array. Should have a floating-point data type. - n: int - length of the transformed axis of the **output**. If + input array. Should have a complex-valued floating-point data type. + n: Optional[int] + number of elements along the transformed axis (dimension) specified by ``axis`` in the **output array**. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``2*(M-1)``. - - ``n//2+1`` is greater than the length of the input array, the input array is zero-padded to length ``n//2+1``. - - ``n//2+1`` is less than the length of the input array, the input array is trimmed to length ``n//2+1``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length ``2*(m-1)``, where ``m`` is the length of the input along the axis specified by ``axis``. + - If ``n//2+1`` is greater than ``M``, the axis of the input array specified by ``axis`` must be zero-padded to length ``n//2+1``. + - If ``n//2+1`` is less than ``M``, the axis of the input array specified by ``axis`` must be trimmed to size ``n//2+1``. + - If ``n//2+1`` equals ``M``, all elements along the axis of the input array specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -493,7 +467,7 @@ def hfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a real-valued floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``complex128``, then the returned array must have a ``float64`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n``. Notes ----- @@ -517,18 +491,16 @@ def ihfft( ---------- x: array input array. Must have a real-valued floating-point data type. - n: int - length of the transformed axis of the **input**. If + n: Optional[int] + number of elements over which to compute the transform along the axis (dimension) specified by ``axis``. Let ``M`` be the size of the input array along the axis specified by ``axis``. When ``n`` is ``None``, the function must set ``n`` equal to ``M``. - - ``n`` is greater than the length of the input array, the input array is zero-padded to length ``n``. - - ``n`` is less than the length of the input array, the input array is trimmed to length ``n``. - - ``n`` is not provided, the length of the transformed axis of the output must equal the length of the input along the axis specified by ``axis``. + - If ``n`` is greater than ``M``, the axis specified by ``axis`` must be zero-padded to size ``n``. + - If ``n`` is less than ``M``, the axis specified by ``axis`` must be trimmed to size ``n``. + - If ``n`` equals ``M``, all elements along the axis specified by ``axis`` must be used when computing the transform. Default: ``None``. axis: int - axis (dimension) over which to compute the Fourier transform. If not set, the last axis (dimension) is used. - - Default: ``-1``. + axis (dimension) of the input array over which to compute the transform. A valid ``axis`` must be an integer on the interval ``[-N, N)``, where ``N`` is the rank (number of dimensions) of ``x``. If an ``axis`` is specified as a negative integer, the function must determine the axis along which to compute the transform by counting backward from the last dimension (where ``-1`` refers to the last dimension). Default: ``-1``. norm: Literal['backward', 'ortho', 'forward'] normalization mode. Should be one of the following modes: @@ -541,7 +513,7 @@ def ihfft( Returns ------- out: array - an array transformed along the axis (dimension) indicated by ``axis``. The returned array must have a complex-valued floating-point data type determined by :ref:`type-promotion`. + an array transformed along the axis (dimension) specified by ``axis``. The returned array must have a complex floating-point data type whose precision matches the precision of ``x`` (e.g., if ``x`` is ``float64``, then the returned array must have a ``complex128`` data type). The returned array must have the same shape as ``x``, except for the axis specified by ``axis`` which must have size ``n//2 + 1``. Notes ----- @@ -552,9 +524,9 @@ def ihfft( def fftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> array: """ - Returns the discrete Fourier transform sample frequencies. + Computes the discrete Fourier transform sample frequencies. - For a Fourier transform of length ``n`` and length unit of ``d`` the frequencies are described as: + For a Fourier transform of length ``n`` and length unit of ``d``, the frequencies are described as: .. code-block:: @@ -573,7 +545,7 @@ def fftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> ar Returns ------- out: array - an array of length ``n`` containing the sample frequencies. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. + an array of shape ``(n,)`` containing the sample frequencies. The returned array must have the default real-valued floating-point data type. Notes ----- @@ -584,9 +556,9 @@ def fftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> ar def rfftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> array: """ - Returns the discrete Fourier transform sample frequencies (for ``rfft`` and ``irfft``). + Computes the discrete Fourier transform sample frequencies (for ``rfft`` and ``irfft``). - For a Fourier transform of length ``n`` and length unit of ``d`` the frequencies are described as: + For a Fourier transform of length ``n`` and length unit of ``d``, the frequencies are described as: .. code-block:: @@ -607,7 +579,7 @@ def rfftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> a Returns ------- out: array - an array of length ``n//2+1`` containing the sample frequencies. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. + an array of shape ``(n//2+1,)`` containing the sample frequencies. The returned array must have the default real-valued floating-point data type. Notes ----- @@ -616,9 +588,9 @@ def rfftfreq(n: int, /, *, d: float = 1.0, device: Optional[device] = None) -> a """ -def fftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: +def fftshift(x: array, /, *, axes: Optional[Union[int, Sequence[int]]] = None) -> array: """ - Shift the zero-frequency component to the center of the spectrum. + Shifts the zero-frequency component to the center of the spectrum. This function swaps half-spaces for all axes (dimensions) specified by ``axes``. @@ -629,13 +601,13 @@ def fftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: ---------- x: array input array. Should have a floating-point data type. - axes: Union[int, Sequence[int]] + axes: Optional[Union[int, Sequence[int]]] axes over which to shift. If ``None``, the function must shift all axes. Default: ``None``. Returns ------- out: array - the shifted array. The returned array must have the same data type as ``x``. + the shifted array. The returned array must have the same data type and shape as ``x``. Notes ----- @@ -644,7 +616,9 @@ def fftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: """ -def ifftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: +def ifftshift( + x: array, /, *, axes: Optional[Union[int, Sequence[int]]] = None +) -> array: """ Inverse of ``fftshift``. @@ -655,13 +629,13 @@ def ifftshift(x: array, /, *, axes: Union[int, Sequence[int]] = None) -> array: ---------- x: array input array. Should have a floating-point data type. - axes: Union[int, Sequence[int]] + axes: Optional[Union[int, Sequence[int]]] axes over which to perform the inverse shift. If ``None``, the function must shift all axes. Default: ``None``. Returns ------- out: array - the shifted array. The returned array must have the same data type as ``x``. + the shifted array. The returned array must have the same data type and shape as ``x``. Notes ----- diff --git a/src/array_api_stubs/_draft/indexing_functions.py b/src/array_api_stubs/_draft/indexing_functions.py index 3f4c25215..f3bf0fc14 100644 --- a/src/array_api_stubs/_draft/indexing_functions.py +++ b/src/array_api_stubs/_draft/indexing_functions.py @@ -16,6 +16,10 @@ def take(x: array, indices: array, /, *, axis: Optional[int] = None) -> array: input array. indices: array array indices. The array must be one-dimensional and have an integer data type. + + .. note:: + This specification does not require bounds checking. The behavior for out-of-bounds indices is left unspecified. + axis: int axis over which to select values. If ``axis`` is negative, the function must determine the axis along which to select values by counting from the last dimension. diff --git a/src/array_api_stubs/_draft/linear_algebra_functions.py b/src/array_api_stubs/_draft/linear_algebra_functions.py index 079a90ee6..96f082bd5 100644 --- a/src/array_api_stubs/_draft/linear_algebra_functions.py +++ b/src/array_api_stubs/_draft/linear_algebra_functions.py @@ -126,9 +126,9 @@ def vecdot(x1: array, x2: array, /, *, axis: int = -1) -> array: Let :math:`\mathbf{a}` be a vector in ``x1`` and :math:`\mathbf{b}` be a corresponding vector in ``x2``. The dot product is defined as .. math:: - \mathbf{a} \cdot \mathbf{b} = \sum_{i=0}^{n-1} a_i\overline{b_i} + \mathbf{a} \cdot \mathbf{b} = \sum_{i=0}^{n-1} \overline{a_i}b_i - over the dimension specified by ``axis`` and where :math:`n` is the dimension size and :math:`\overline{b_i}` denotes the complex conjugate if :math:`b_i` is complex and the identity if :math:`b_i` is real-valued. + over the dimension specified by ``axis`` and where :math:`n` is the dimension size and :math:`\overline{a_i}` denotes the complex conjugate if :math:`a_i` is complex and the identity if :math:`a_i` is real-valued. Parameters ---------- diff --git a/src/array_api_stubs/_draft/searching_functions.py b/src/array_api_stubs/_draft/searching_functions.py index e586a7656..dda000e74 100644 --- a/src/array_api_stubs/_draft/searching_functions.py +++ b/src/array_api_stubs/_draft/searching_functions.py @@ -1,7 +1,7 @@ -__all__ = ["argmax", "argmin", "nonzero", "where"] +__all__ = ["argmax", "argmin", "nonzero", "searchsorted", "where"] -from ._types import Optional, Tuple, array +from ._types import Optional, Tuple, Literal, array def argmax(x: array, /, *, axis: Optional[int] = None, keepdims: bool = False) -> array: @@ -87,6 +87,56 @@ def nonzero(x: array, /) -> Tuple[array, ...]: """ +def searchsorted( + x1: array, + x2: array, + /, + *, + side: Literal["left", "right"] = "left", + sorter: Optional[array] = None, +) -> array: + """ + Finds the indices into ``x1`` such that, if the corresponding elements in ``x2`` were inserted before the indices, the order of ``x1``, when sorted in ascending order, would be preserved. + + Parameters + ---------- + x1: array + input array. Must be a one-dimensional array. Should have a real-valued data type. If ``sorter`` is ``None``, must be sorted in ascending order; otherwise, ``sorter`` must be an array of indices that sort ``x1`` in ascending order. + x2: array + array containing search values. Should have a real-valued data type. + side: Literal['left', 'right'] + argument controlling which index is returned if a value lands exactly on an edge. + + Let ``x`` be an array of rank ``N`` where ``v`` is an individual element given by ``v = x2[n,m,...,j]``. + + If ``side == 'left'``, then + + - each returned index ``i`` must satisfy the index condition ``x1[i-1] < v <= x1[i]``. + - if no index satisfies the index condition, then the returned index for that element must be ``0``. + + Otherwise, if ``side == 'right'``, then + + - each returned index ``i`` must satisfy the index condition ``x1[i-1] <= v < x1[i]``. + - if no index satisfies the index condition, then the returned index for that element must be ``N``, where ``N`` is the number of elements in ``x1``. + + Default: ``'left'``. + sorter: Optional[array] + array of indices that sort ``x1`` in ascending order. The array must have the same shape as ``x1`` and have an integer data type. Default: ``None``. + + Returns + ------- + out: array + an array of indices with the same shape as ``x2``. The returned array must have the default array index data type. + + Notes + ----- + + For real-valued floating-point arrays, the sort order of NaNs and signed zeros is unspecified and thus implementation-dependent. Accordingly, when a real-valued floating-point array contains NaNs and signed zeros, what constitutes ascending order may vary among specification-conforming array libraries. + + While behavior for arrays containing NaNs and signed zeros is implementation-dependent, specification-conforming libraries should, however, ensure consistency with ``sort`` and ``argsort`` (i.e., if a value in ``x2`` is inserted into ``x1`` according to the corresponding index in the output array and ``sort`` is invoked on the resultant array, the sorted result should be an array in the same order). + """ + + def where(condition: array, x1: array, x2: array, /) -> array: """ Returns elements chosen from ``x1`` or ``x2`` depending on ``condition``. diff --git a/src/array_api_stubs/_draft/statistical_functions.py b/src/array_api_stubs/_draft/statistical_functions.py index 92cdb5755..14952402c 100644 --- a/src/array_api_stubs/_draft/statistical_functions.py +++ b/src/array_api_stubs/_draft/statistical_functions.py @@ -1,9 +1,67 @@ -__all__ = ["max", "mean", "min", "prod", "std", "sum", "var"] +__all__ = ["cumulative_sum", "max", "mean", "min", "prod", "std", "sum", "var"] from ._types import Optional, Tuple, Union, array, dtype +def cumulative_sum( + x: array, + /, + *, + axis: Optional[int] = None, + dtype: Optional[dtype] = None, + include_initial: bool = False, +) -> array: + """ + Calculates the cumulative sum of elements in the input array ``x``. + + Parameters + ---------- + x: array + input array. Should have a numeric data type. + axis: Optional[int] + axis along which a cumulative sum must be computed. If ``axis`` is negative, the function must determine the axis along which to compute a cumulative sum by counting from the last dimension. + + If ``x`` is a one-dimensional array, providing an ``axis`` is optional; however, if ``x`` has more than one dimension, providing an ``axis`` is required. + dtype: Optional[dtype] + data type of the returned array. If ``None``, + + - if the default data type corresponding to the data type "kind" (integer, real-valued floating-point, or complex floating-point) of ``x`` has a smaller range of values than the data type of ``x`` (e.g., ``x`` has data type ``int64`` and the default data type is ``int32``, or ``x`` has data type ``uint64`` and the default data type is ``int64``), the returned array must have the same data type as ``x``. + + - if the default data type corresponding to the data type "kind" of ``x`` has the same or a larger range of values than the data type of ``x``, + + - if ``x`` has a real-valued floating-point data type, the returned array must have the default real-valued floating-point data type. + - if ``x`` has a complex floating-point data type, the returned array must have the default complex floating-point data type. + - if ``x`` has a signed integer data type (e.g., ``int16``), the returned array must have the default integer data type. + - if ``x`` has an unsigned integer data type (e.g., ``uint16``), the returned array must have an unsigned integer data type having the same number of bits as the default integer data type (e.g., if the default integer data type is ``int32``, the returned array must have a ``uint32`` data type). + + If the data type (either specified or resolved) differs from the data type of ``x``, the input array should be cast to the specified data type before computing the sum. Default: ``None``. + + .. note:: + keyword argument is intended to help prevent data type overflows. + + include_initial: bool + boolean indicating whether to include the initial value as the first value in the output. By convention, the initial value must be the additive identity (i.e., zero). Default: ``False``. + + Returns + ------- + out: array + an array containing the cumulative sums. The returned array must have a data type as described by the ``dtype`` parameter above. + + Let ``N`` be the size of the axis along which to compute the cumulative sum. The returned array must have a shape determined according to the following rules: + + - if ``include_initial`` is ``True``, the returned array must have the same shape as ``x``, except the size of the axis along which to compute the cumulative sum must be ``N+1``. + - if ``include_initial`` is ``False``, the returned array must have the same shape as ``x``. + + Notes + ----- + + **Special Cases** + + For both real-valued and complex floating-point operands, special cases must be handled as if the operation is implemented by successive application of :func:`~array_api.add`. + """ + + def max( x: array, /,