Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add design document on complex number ordering #527

Merged
merged 9 commits into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions spec/API_specification/array_api/array_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@ def __ge__(self: array, other: Union[int, float, array], /) -> array:
"""
Computes the truth value of ``self_i >= other_i`` for each element of an array instance with the respective element of the array ``other``.

.. 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
----------
self: array
Expand Down Expand Up @@ -465,6 +468,9 @@ def __gt__(self: array, other: Union[int, float, array], /) -> array:
"""
Computes the truth value of ``self_i > other_i`` for each element of an array instance with the respective element of the array ``other``.

.. 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
----------
self: array
Expand Down Expand Up @@ -538,6 +544,9 @@ def __le__(self: array, other: Union[int, float, array], /) -> array:
"""
Computes the truth value of ``self_i <= other_i`` for each element of an array instance with the respective element of the array ``other``.

.. 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
----------
self: array
Expand Down Expand Up @@ -580,6 +589,9 @@ def __lt__(self: array, other: Union[int, float, array], /) -> array:
"""
Computes the truth value of ``self_i < other_i`` for each element of an array instance with the respective element of the array ``other``.

.. 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
----------
self: array
Expand Down
12 changes: 12 additions & 0 deletions spec/API_specification/array_api/elementwise_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,9 @@ def greater(x1: array, x2: array, /) -> array:
"""
Computes the truth value of ``x1_i > x2_i`` for each element ``x1_i`` of the input array ``x1`` with 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
Expand All @@ -796,6 +799,9 @@ def greater_equal(x1: array, x2: array, /) -> array:
"""
Computes the truth value of ``x1_i >= x2_i`` for each element ``x1_i`` of the input array ``x1`` with 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
Expand Down Expand Up @@ -873,6 +879,9 @@ def less(x1: array, x2: array, /) -> array:
"""
Computes the truth value of ``x1_i < x2_i`` for each element ``x1_i`` of the input array ``x1`` with 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
Expand All @@ -890,6 +899,9 @@ def less_equal(x1: array, x2: array, /) -> array:
"""
Computes the truth value of ``x1_i <= x2_i`` for each element ``x1_i`` of the input array ``x1`` with 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
Expand Down
14 changes: 12 additions & 2 deletions spec/API_specification/array_api/searching_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

def argmax(x: array, /, *, axis: Optional[int] = None, keepdims: bool = False) -> array:
"""
Returns the indices of the maximum values along a specified axis. When the maximum value occurs multiple times, only the indices corresponding to the first occurrence are returned.
Returns the indices of the maximum values along a specified axis.

When the maximum value occurs multiple times, only the indices corresponding to the first occurrence are returned.

.. 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
----------
Expand All @@ -21,7 +26,12 @@ def argmax(x: array, /, *, axis: Optional[int] = None, keepdims: bool = False) -

def argmin(x: array, /, *, axis: Optional[int] = None, keepdims: bool = False) -> array:
"""
Returns the indices of the minimum values along a specified axis. When the minimum value occurs multiple times, only the indices corresponding to the first occurrence are returned.
Returns the indices of the minimum values along a specified axis.

When the minimum value occurs multiple times, only the indices corresponding to the first occurrence are returned.

.. 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
----------
Expand Down
10 changes: 8 additions & 2 deletions spec/API_specification/array_api/sorting_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ def argsort(x: array, /, *, axis: int = -1, descending: bool = False, stable: bo
"""
Returns the indices that sort an array ``x`` along a specified axis.

.. 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
----------
x : array
input array.
input array. Should have a real-valued data type.
axis: int
axis along which to sort. If set to ``-1``, the function must sort along the last axis. Default: ``-1``.
descending: bool
Expand All @@ -25,10 +28,13 @@ def sort(x: array, /, *, axis: int = -1, descending: bool = False, stable: bool
"""
Returns a sorted copy of an input array ``x``.

.. 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
----------
x: array
input array.
input array. Should have a real-valued data type.
axis: int
axis along which to sort. If set to ``-1``, the function must sort along the last axis. Default: ``-1``.
descending: bool
Expand Down
6 changes: 6 additions & 0 deletions spec/API_specification/array_api/statistical_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ def max(x: array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keep
.. note::
When the number of elements over which to compute the maximum value is zero, the maximum value is implementation-defined. Specification-compliant libraries may choose to raise an error, return a sentinel value (e.g., if ``x`` is a floating-point input array, return ``NaN``), or return the minimum possible value for the input array ``x`` data type (e.g., if ``x`` is a floating-point array, return ``-infinity``).

.. 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`).

**Special Cases**

For floating-point operands,
Expand Down Expand Up @@ -64,6 +67,9 @@ def min(x: array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keep
.. note::
When the number of elements over which to compute the minimum value is zero, the minimum value is implementation-defined. Specification-compliant libraries may choose to raise an error, return a sentinel value (e.g., if ``x`` is a floating-point input array, return ``NaN``), or return the maximum possible value for the input array ``x`` data type (e.g., if ``x`` is a floating-point array, return ``+infinity``).

.. 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`).

**Special Cases**

For floating-point operands,
Expand Down
19 changes: 19 additions & 0 deletions spec/design_topics/complex_number_ordering.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.. _complex-number-ordering:

Complex Number Ordering
=======================

Given a set :math:`\{a_1, \ldots, a_n\}`, an order relation must satisfy the following properties:

1. **Reflexive**: for any :math:`a` in the set, :math:`a \leq a`.
2. **Transitive**: for any :math:`a`, :math:`b`, and :math:`c` in the set, if :math:`a \leq b` and :math:`b \leq c`, then :math:`a \leq c`.
3. **Antisymmetric**: for any :math:`a` and :math:`b` in the set, if :math:`a \leq b` and :math:`b \leq a`, then :math:`a = b`.
4. **Total Order**: in addition to the *partial order* established by 1-3, for any :math:`a` and :math:`b` in the set, either :math:`a \leq b` or :math:`b \leq a` (or both).
5. **Compatible with Addition**: for all :math:`a`, :math:`b`, and :math:`c` in the set, if :math:`a \leq b`, then :math:`a + c \leq b + c`.
6. **Compatible with Multiplication**: for all :math:`a`, :math:`b`, and :math:`c` in the set, if :math:`a \leq b` and :math:`0 \leq c`, then :math:`ac \leq bc`.

Defining an order relation for complex numbers which satisfies all six properties defined above is not possible. Accordingly, this specification does not require that a conforming implementation of the array API standard adopt any specific complex number order relation.

In order to satisfy backward compatibility guarantees, conforming implementations of the array API standard may choose to define an ordering for complex numbers (e.g., lexicographic); however, consumers of the array API standard should **not** assume that complex number ordering is consistent between implementations or even supported.

If a conforming implementation chooses to define an ordering for complex numbers, the ordering must be clearly documented.
1 change: 1 addition & 0 deletions spec/design_topics/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ Design topics & constraints
static_typing
accuracy
branch_cuts
complex_number_ordering
C_API
parallelism