From 7850b410da3f89bdce0636b7b2f438c1f97c6d31 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Tue, 18 Oct 2022 09:48:43 +0100 Subject: [PATCH 01/15] Introduce conservative `x.__complex__()` --- spec/API_specification/array_api/array_object.py | 15 +++++++++++++++ spec/API_specification/array_object.rst | 1 + 2 files changed, 16 insertions(+) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 94dac2d1d..ae94c8ca1 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -237,6 +237,21 @@ def __bool__(self: array, /) -> bool: a Python ``bool`` object representing the single element of the array. """ + def __complex__(self: array, /) -> bool: + """ + Converts a zero-dimensional complex array to a Python ``complex`` object. + + Parameters + ---------- + self: array + zero-dimensional array instance. Must have a complex data type. + + Returns + ------- + out: complex + a Python ``complex`` object representing the single element of the array. + """ + def __dlpack__(self: array, /, *, stream: Optional[Union[int, Any]] = None) -> PyCapsule: """ Exports the array for consumption by :func:`~array_api.from_dlpack` as a DLPack capsule. diff --git a/spec/API_specification/array_object.rst b/spec/API_specification/array_object.rst index 758e08582..b45e41987 100644 --- a/spec/API_specification/array_object.rst +++ b/spec/API_specification/array_object.rst @@ -283,6 +283,7 @@ Methods array.__and__ array.__array_namespace__ array.__bool__ + array.__complex__ array.__dlpack__ array.__dlpack_device__ array.__eq__ From 8d669b2c8fd415428136940029d67e6f53a4657e Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Tue, 18 Oct 2022 10:31:01 +0100 Subject: [PATCH 02/15] Don't hard require same-kind arrays for builtin cast methods --- spec/API_specification/array_api/array_object.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index ae94c8ca1..8c51fafc2 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -229,7 +229,7 @@ def __bool__(self: array, /) -> bool: Parameters ---------- self: array - zero-dimensional array instance. Must have a boolean data type. + zero-dimensional array instance. Should have a boolean data type. Returns ------- @@ -244,7 +244,7 @@ def __complex__(self: array, /) -> bool: Parameters ---------- self: array - zero-dimensional array instance. Must have a complex data type. + zero-dimensional array instance. Should have a complex data type. Returns ------- @@ -361,7 +361,7 @@ def __float__(self: array, /) -> float: Parameters ---------- self: array - zero-dimensional array instance. Must have a real-valued floating-point data type. + zero-dimensional array instance. Should have a real-valued floating-point data type. Returns ------- @@ -498,7 +498,7 @@ def __index__(self: array, /) -> int: Parameters ---------- self: array - zero-dimensional array instance. Must have an integer data type. + zero-dimensional array instance. Should have an integer data type. Returns ------- @@ -513,7 +513,7 @@ def __int__(self: array, /) -> int: Parameters ---------- self: array - zero-dimensional array instance. Must have an integer data type. + zero-dimensional array instance. Should have an integer data type. Returns ------- From e7e6c6d708f83bff3ff13d274b4199d41833c50f Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Wed, 2 Nov 2022 18:35:50 +0000 Subject: [PATCH 03/15] Align casting methods with Python behaviour --- .../array_api/array_object.py | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 8c51fafc2..26633a58b 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -224,12 +224,15 @@ def __array_namespace__(self: array, /, *, api_version: Optional[str] = None) -> def __bool__(self: array, /) -> bool: """ - Converts a zero-dimensional boolean array to a Python ``bool`` object. + Converts a zero-dimensional array to a Python ``bool`` object. + + .. note:: + When casting a real-valued input array to ``bool``, a value of ``0`` must cast to ``False``, and a non-zero value must cast to ``True``. Parameters ---------- self: array - zero-dimensional array instance. Should have a boolean data type. + zero-dimensional array instance. Returns ------- @@ -237,19 +240,22 @@ def __bool__(self: array, /) -> bool: a Python ``bool`` object representing the single element of the array. """ - def __complex__(self: array, /) -> bool: + def __complex__(self: array, /) -> complex: """ - Converts a zero-dimensional complex array to a Python ``complex`` object. + Converts a zero-dimensional array to a Python ``complex`` object. + + .. note:: + When casting a boolean input array, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. Parameters ---------- self: array - zero-dimensional array instance. Should have a complex data type. + zero-dimensional array instance. Returns ------- out: complex - a Python ``complex`` object representing the single element of the array. + a Python ``complex`` object representing the single element of the array. If ``self`` has a real-valued or boolean data type, ``out`` must represent the element of ``self`` in the real component. """ def __dlpack__(self: array, /, *, stream: Optional[Union[int, Any]] = None) -> PyCapsule: @@ -356,12 +362,18 @@ def __eq__(self: array, other: Union[int, float, bool, array], /) -> array: def __float__(self: array, /) -> float: """ - Converts a zero-dimensional floating-point array to a Python ``float`` object. + Converts a zero-dimensional array to a Python ``float`` object. + + .. note:: + Casting integer values outside the representable bounds of Python's float type is not specified and is implementation-dependent. + + .. note:: + When casting a boolean input array, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. Parameters ---------- self: array - zero-dimensional array instance. Should have a real-valued floating-point data type. + zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex data type, the function must raise a ``TypeError``. Returns ------- @@ -488,9 +500,9 @@ def __gt__(self: array, other: Union[int, float, array], /) -> array: Element-wise results must equal the results returned by the equivalent element-wise function :func:`~array_api.greater`. """ - def __index__(self: array, /) -> int: + def __index__(self: array, /) -> Union[int, bool]: """ - Converts a zero-dimensional integer array to a Python ``int`` object. + Converts a zero-dimensional array to a Python object used in indexing. .. note:: This method is called to implement `operator.index() `_. See also `PEP 357 `_. @@ -498,27 +510,47 @@ def __index__(self: array, /) -> int: Parameters ---------- self: array - zero-dimensional array instance. Should have an integer data type. + zero-dimensional array instance. Should have an integer or boolean data type. If ``self`` has a floating-point or complex data type, the function must raise a ``TypeError``. Returns ------- - out: int - a Python ``int`` object representing the single element of the array instance. + out: Union[int, bool] + a Python object representing the single element of the array instance. If ``self`` has an integer data type, ``out`` must be a Python ``int`` object. If ``self`` has a boolean data type, ``out`` must be a Python ``bool`` object. """ def __int__(self: array, /) -> int: """ - Converts a zero-dimensional integer array to a Python ``int`` object. + Converts a zero-dimensional array to a Python ``int`` object. + + .. note:: + Casting floating-point values outside the representable bounds of Python's non-arbitary integer type is not specified and is implementation-dependent. + + .. note:: + When casting a boolean input array, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. + + **Special cases** + + For floating-point operands, + + - If ``self`` is a finite number, the result is the integer part of ``self``. Parameters ---------- self: array - zero-dimensional array instance. Should have an integer data type. + zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex data type, the function must raise a ``TypeError``. Returns ------- out: int a Python ``int`` object representing the single element of the array instance. + + + **Raises** + + For floating-point operands, + + - If ``self`` is either ``+infinity`` or ``-infinity``, raise ``OverflowError``. + - If ``self`` is ``NaN``, raise ``ValueError``. """ def __invert__(self: array, /) -> array: From d6723c9b349334046d65013a5d28e4a3dc908a80 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 3 Nov 2022 09:23:11 +0000 Subject: [PATCH 04/15] Remove unnecessary `__int__` note on out-of-scope beyond bounds --- spec/API_specification/array_api/array_object.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 26633a58b..25266844f 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -522,9 +522,6 @@ def __int__(self: array, /) -> int: """ Converts a zero-dimensional array to a Python ``int`` object. - .. note:: - Casting floating-point values outside the representable bounds of Python's non-arbitary integer type is not specified and is implementation-dependent. - .. note:: When casting a boolean input array, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. From 29ffb390c9e50963edfa89fa3121c686108022ce Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 3 Nov 2022 09:43:01 +0000 Subject: [PATCH 05/15] `__index__`: leave bool arrays unspecified and restrict out to `int` --- spec/API_specification/array_api/array_object.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 25266844f..b68fd8bf2 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -500,9 +500,9 @@ def __gt__(self: array, other: Union[int, float, array], /) -> array: Element-wise results must equal the results returned by the equivalent element-wise function :func:`~array_api.greater`. """ - def __index__(self: array, /) -> Union[int, bool]: + def __index__(self: array, /) -> int: """ - Converts a zero-dimensional array to a Python object used in indexing. + Converts a zero-dimensional integer array to a Python ``int`` object. .. note:: This method is called to implement `operator.index() `_. See also `PEP 357 `_. @@ -510,12 +510,12 @@ def __index__(self: array, /) -> Union[int, bool]: Parameters ---------- self: array - zero-dimensional array instance. Should have an integer or boolean data type. If ``self`` has a floating-point or complex data type, the function must raise a ``TypeError``. + zero-dimensional array instance. Should have an integer data type. If ``self`` has a floating-point or complex data type, the function must raise a ``TypeError``. Returns ------- - out: Union[int, bool] - a Python object representing the single element of the array instance. If ``self`` has an integer data type, ``out`` must be a Python ``int`` object. If ``self`` has a boolean data type, ``out`` must be a Python ``bool`` object. + out: int + a Python ``int`` object representing the single element of the array instance. """ def __int__(self: array, /) -> int: From 10bf219f3166c2f935eddd631ff0c18b25665401 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 3 Nov 2022 09:45:48 +0000 Subject: [PATCH 06/15] Update `__complex__` note with complex results --- spec/API_specification/array_api/array_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index b68fd8bf2..49220a083 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -245,7 +245,7 @@ def __complex__(self: array, /) -> complex: Converts a zero-dimensional array to a Python ``complex`` object. .. note:: - When casting a boolean input array, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. + When casting a boolean input array, a value of ``True`` must cast to ``1+0j``, and a value of ``False`` must cast to ``0+0j``. Parameters ---------- From b35e3bbc040d5fd5fa9c92dcae977991d4b7f652 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 3 Nov 2022 10:39:16 +0000 Subject: [PATCH 07/15] Clarify `__bool__` note language --- spec/API_specification/array_api/array_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 49220a083..97c62aa9e 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -227,7 +227,7 @@ def __bool__(self: array, /) -> bool: Converts a zero-dimensional array to a Python ``bool`` object. .. note:: - When casting a real-valued input array to ``bool``, a value of ``0`` must cast to ``False``, and a non-zero value must cast to ``True``. + When casting a real-valued input array to ``bool``, a value equal to ``0`` must cast to ``False``, and a value not equal to ``0`` must cast to ``True``. Parameters ---------- From d25bcc484f42f832651180c5b633abb50bfdfc11 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 3 Nov 2022 12:09:32 +0000 Subject: [PATCH 08/15] "real-valued" -> "numeric" input array in `__bool__` note --- spec/API_specification/array_api/array_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 97c62aa9e..a0d6f8d03 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -227,7 +227,7 @@ def __bool__(self: array, /) -> bool: Converts a zero-dimensional array to a Python ``bool`` object. .. note:: - When casting a real-valued input array to ``bool``, a value equal to ``0`` must cast to ``False``, and a value not equal to ``0`` must cast to ``True``. + When casting a numeric input array to ``bool``, a value equal to ``0`` must cast to ``False``, and a value not equal to ``0`` must cast to ``True``. Parameters ---------- From e476516751d170825ded9476457fce7fd43a9287 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Tue, 15 Nov 2022 10:33:11 +0000 Subject: [PATCH 09/15] Clearer and spec-consistent language for casting methods Co-authored-by: Athan --- spec/API_specification/array_api/array_object.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index a0d6f8d03..a9dd7f9d0 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -227,7 +227,7 @@ def __bool__(self: array, /) -> bool: Converts a zero-dimensional array to a Python ``bool`` object. .. note:: - When casting a numeric input array to ``bool``, a value equal to ``0`` must cast to ``False``, and a value not equal to ``0`` must cast to ``True``. + If ``self`` has a numeric data type, a value equal to ``0`` must cast to ``False``, and a value not equal to ``0`` must cast to ``True``. Parameters ---------- @@ -245,7 +245,7 @@ def __complex__(self: array, /) -> complex: Converts a zero-dimensional array to a Python ``complex`` object. .. note:: - When casting a boolean input array, a value of ``True`` must cast to ``1+0j``, and a value of ``False`` must cast to ``0+0j``. + If ``self`` has a boolean data type, a value of ``True`` must cast to ``1+0j``, and a value of ``False`` must cast to ``0+0j``. Parameters ---------- @@ -255,7 +255,7 @@ def __complex__(self: array, /) -> complex: Returns ------- out: complex - a Python ``complex`` object representing the single element of the array. If ``self`` has a real-valued or boolean data type, ``out`` must represent the element of ``self`` in the real component. + a Python ``complex`` object representing the single element of the array instance. If ``self`` has a real-valued or boolean data type, the real component of the return value must equal the element of ``self`` and the imaginary component must be ``0``. """ def __dlpack__(self: array, /, *, stream: Optional[Union[int, Any]] = None) -> PyCapsule: @@ -368,12 +368,12 @@ def __float__(self: array, /) -> float: Casting integer values outside the representable bounds of Python's float type is not specified and is implementation-dependent. .. note:: - When casting a boolean input array, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. + If ``self`` has a boolean data type, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. Parameters ---------- self: array - zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex data type, the function must raise a ``TypeError``. + zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex floating-point data type, the function must raise a ``TypeError``. Returns ------- @@ -510,7 +510,7 @@ def __index__(self: array, /) -> int: Parameters ---------- self: array - zero-dimensional array instance. Should have an integer data type. If ``self`` has a floating-point or complex data type, the function must raise a ``TypeError``. + zero-dimensional array instance. Should have an integer data type. If ``self`` has a floating-point data type, the function must raise a ``TypeError``. Returns ------- @@ -523,7 +523,7 @@ def __int__(self: array, /) -> int: Converts a zero-dimensional array to a Python ``int`` object. .. note:: - When casting a boolean input array, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. + If ``self`` has a boolean data type, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. **Special cases** @@ -534,7 +534,7 @@ def __int__(self: array, /) -> int: Parameters ---------- self: array - zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex data type, the function must raise a ``TypeError``. + zero-dimensional array instance. Should have a real-valued or boolean data type. If ``self`` has a complex floating-point data type, the function must raise a ``TypeError``. Returns ------- From 8212e6747c0994f68e5e15cce09d2f084c3857c9 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Tue, 15 Nov 2022 10:40:49 +0000 Subject: [PATCH 10/15] Special case neg zeros in `x.__int__()` --- spec/API_specification/array_api/array_object.py | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index a9dd7f9d0..5b2186298 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -530,6 +530,7 @@ def __int__(self: array, /) -> int: For floating-point operands, - If ``self`` is a finite number, the result is the integer part of ``self``. + - If ``self`` is ``-0``, the result is ``0``. Parameters ---------- From 5ffd63514da6803bf1120bb458ff9b40b00207bf Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 17 Nov 2022 11:04:11 +0000 Subject: [PATCH 11/15] Special cases over note in `x.__bool__()` --- spec/API_specification/array_api/array_object.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 5b2186298..516c855dd 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -226,8 +226,15 @@ def __bool__(self: array, /) -> bool: """ Converts a zero-dimensional array to a Python ``bool`` object. - .. note:: - If ``self`` has a numeric data type, a value equal to ``0`` must cast to ``False``, and a value not equal to ``0`` must cast to ``True``. + **Special cases** + + For real-valued floating-point operands, + + - If ``self`` is ``NaN``, the result is ``True``. + - If ``self`` is either ``+infinity`` or ``-infinity``, the result is ``True``. + - If ``self`` is either ``+0`` or ``-0``, the result is ``False``. + + For complex floating-point operands, special cases must be handled as if the operation is implemented as ``bool(real(self)) and bool(imag(self))``. Parameters ---------- From 9971768caafaee655e2576639d77c5840912ddc2 Mon Sep 17 00:00:00 2001 From: Matthew Barber Date: Thu, 17 Nov 2022 11:10:58 +0000 Subject: [PATCH 12/15] Special cases over notes for boolean cross-kind casting --- .../array_api/array_object.py | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 516c855dd..75d18b4a9 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -251,8 +251,12 @@ def __complex__(self: array, /) -> complex: """ Converts a zero-dimensional array to a Python ``complex`` object. - .. note:: - If ``self`` has a boolean data type, a value of ``True`` must cast to ``1+0j``, and a value of ``False`` must cast to ``0+0j``. + **Special cases** + + For boolean operands, + + - If ``self`` is ``True``, the result is ``1+0j``. + - If ``self`` is ``False``, the result is ``0+0j``. Parameters ---------- @@ -374,8 +378,12 @@ def __float__(self: array, /) -> float: .. note:: Casting integer values outside the representable bounds of Python's float type is not specified and is implementation-dependent. - .. note:: - If ``self`` has a boolean data type, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. + **Special cases** + + For boolean operands, + + - If ``self`` is ``True``, the result is ``1``. + - If ``self`` is ``False``, the result is ``0``. Parameters ---------- @@ -529,11 +537,13 @@ def __int__(self: array, /) -> int: """ Converts a zero-dimensional array to a Python ``int`` object. - .. note:: - If ``self`` has a boolean data type, a value of ``True`` must cast to ``1``, and a value of ``False`` must cast to ``0``. - **Special cases** + For boolean operands, + + - If ``self`` is ``True``, the result is ``1``. + - If ``self`` is ``False``, the result is ``0``. + For floating-point operands, - If ``self`` is a finite number, the result is the integer part of ``self``. From 1ca2e6643e5cd0609ce831facec96dc2ad0df1d4 Mon Sep 17 00:00:00 2001 From: Athan Date: Wed, 14 Dec 2022 11:24:55 -0800 Subject: [PATCH 13/15] Add missing backticks --- spec/API_specification/array_api/array_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 75d18b4a9..adef02a8c 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -234,7 +234,7 @@ def __bool__(self: array, /) -> bool: - If ``self`` is either ``+infinity`` or ``-infinity``, the result is ``True``. - If ``self`` is either ``+0`` or ``-0``, the result is ``False``. - For complex floating-point operands, special cases must be handled as if the operation is implemented as ``bool(real(self)) and bool(imag(self))``. + For complex floating-point operands, special cases must be handled as if the operation is implemented as ``bool(real(self))`` and ``bool(imag(self))``. Parameters ---------- From 0628b17433c08486c3554dfa5c3da8f4d87cde33 Mon Sep 17 00:00:00 2001 From: Athan Date: Wed, 14 Dec 2022 11:36:36 -0800 Subject: [PATCH 14/15] Update copy --- spec/API_specification/array_api/array_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index adef02a8c..63f5e44ac 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -234,7 +234,7 @@ def __bool__(self: array, /) -> bool: - If ``self`` is either ``+infinity`` or ``-infinity``, the result is ``True``. - If ``self`` is either ``+0`` or ``-0``, the result is ``False``. - For complex floating-point operands, special cases must be handled as if the operation is implemented as ``bool(real(self))`` and ``bool(imag(self))``. + For complex floating-point operands, special cases must be handled as if the operation is implemented as the logical AND of ``bool(real(self))`` and ``bool(imag(self))``. Parameters ---------- From a77175bb2ee29320e66e053f4bf12004008c1a4d Mon Sep 17 00:00:00 2001 From: Athan Date: Wed, 14 Dec 2022 11:58:13 -0800 Subject: [PATCH 15/15] Add special cases for real-valued floating-point operands --- spec/API_specification/array_api/array_object.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spec/API_specification/array_api/array_object.py b/spec/API_specification/array_api/array_object.py index 63f5e44ac..dd70a1beb 100644 --- a/spec/API_specification/array_api/array_object.py +++ b/spec/API_specification/array_api/array_object.py @@ -257,6 +257,13 @@ def __complex__(self: array, /) -> complex: - If ``self`` is ``True``, the result is ``1+0j``. - If ``self`` is ``False``, the result is ``0+0j``. + + For real-valued floating-point operands, + + - If ``self`` is ``NaN``, the result is ``NaN + NaN j``. + - If ``self`` is ``+infinity``, the result is ``+infinity + 0j``. + - If ``self`` is ``-infinity``, the result is ``-infinity + 0j``. + - If ``self`` is a finite number, the result is ``self + 0j``. Parameters ---------- @@ -266,7 +273,7 @@ def __complex__(self: array, /) -> complex: Returns ------- out: complex - a Python ``complex`` object representing the single element of the array instance. If ``self`` has a real-valued or boolean data type, the real component of the return value must equal the element of ``self`` and the imaginary component must be ``0``. + a Python ``complex`` object representing the single element of the array instance. """ def __dlpack__(self: array, /, *, stream: Optional[Union[int, Any]] = None) -> PyCapsule: