From cf3131d606ced84244aaec132e96a7cf3a858abc Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Thu, 6 Feb 2025 01:43:42 -0800 Subject: [PATCH 1/7] docs: clarify `clip` behavior when arguments have different data types Ref: https://github.com/data-apis/array-api/pull/814#issuecomment-2639228207 --- src/array_api_stubs/_draft/elementwise_functions.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index 40775d6a3..6355ca88a 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -824,9 +824,9 @@ def clip( 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 ``x`` (see :ref:`broadcasting`). Should have a real-valued data type. Default: ``None``. + lower-bound of the range to which to clamp. If ``None``, no lower bound must be applied. Must be compatible with ``x`` (see :ref:`broadcasting`). Should have the same data type as ``x``. 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 ``x`` (see :ref:`broadcasting`). Should have a real-valued data type. Default: ``None``. + upper-bound of the range to which to clamp. If ``None``, no upper bound must be applied. Must be compatible with ``x`` (see :ref:`broadcasting`). Should have the same data type as ``x``. Default: ``None``. Returns ------- @@ -836,10 +836,12 @@ def clip( Notes ----- + - This function is conceptually equivalent to ``maximum(minimum(x, max), min)`` when ``x``, ``min``, and ``max`` have the same data type. + - For scalar ``min`` and/or ``max``, the scalar values must be converted to zero-dimensional arrays having the same data type as ``x`` prior to broadcasting. - 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`` has an integral data type and a broadcasted element in ``min`` or ``max`` is outside the bounds of the data type of ``x``, 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. + - If ``x`` and either ``min`` or ``max`` have different data types and/or data type kinds (e.g., integer versus floating-point), behavior is unspecified and thus implementation-dependent. **Special cases** From 26bbc05c0a41ffa17d21027102afa609c1de7c3b Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Thu, 6 Feb 2025 01:55:00 -0800 Subject: [PATCH 2/7] docs: clarify three-way broadcast and backport --- src/array_api_stubs/_2023_12/elementwise_functions.py | 4 ++-- src/array_api_stubs/_draft/elementwise_functions.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/array_api_stubs/_2023_12/elementwise_functions.py b/src/array_api_stubs/_2023_12/elementwise_functions.py index f44838f63..2972fa623 100644 --- a/src/array_api_stubs/_2023_12/elementwise_functions.py +++ b/src/array_api_stubs/_2023_12/elementwise_functions.py @@ -791,9 +791,9 @@ def clip( 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``. + lower-bound of the range to which to clamp. If ``None``, no lower bound must be applied. Must be compatible with ``x`` and ``max`` (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``. + upper-bound of the range to which to clamp. If ``None``, no upper bound must be applied. Must be compatible with ``x`` and ``min`` (see :ref:`broadcasting`). Should have a real-valued data type. Default: ``None``. Returns ------- diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index 6355ca88a..0eced2fd5 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -824,9 +824,9 @@ def clip( 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 ``x`` (see :ref:`broadcasting`). Should have the same data type as ``x``. Default: ``None``. + lower-bound of the range to which to clamp. If ``None``, no lower bound must be applied. Must be compatible with ``x`` and ``max`` (see :ref:`broadcasting`). Should have the same data type as ``x``. 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 ``x`` (see :ref:`broadcasting`). Should have the same data type as ``x``. Default: ``None``. + upper-bound of the range to which to clamp. If ``None``, no upper bound must be applied. Must be compatible with ``x`` and ``min`` (see :ref:`broadcasting`). Should have the same data type as ``x``. Default: ``None``. Returns ------- From f9f5d8bc18ff8de123cfd05a46c9ed49a4cf7818 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Thu, 6 Feb 2025 02:04:58 -0800 Subject: [PATCH 3/7] docs: clarify type promotion behavior --- src/array_api_stubs/_draft/elementwise_functions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index 0eced2fd5..a181ea685 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -837,11 +837,11 @@ def clip( ----- - This function is conceptually equivalent to ``maximum(minimum(x, max), min)`` when ``x``, ``min``, and ``max`` have the same data type. - - For scalar ``min`` and/or ``max``, the scalar values must be converted to zero-dimensional arrays having the same data type as ``x`` prior to broadcasting. - 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. + - For scalar ``min`` and/or ``max``, the scalar values should follow type promotion rules (see :ref:`type-promotion`). 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 - If ``x`` has an integral data type and a broadcasted element in ``min`` or ``max`` is outside the bounds of the data type of ``x``, behavior is unspecified and thus implementation-dependent. - - If ``x`` and either ``min`` or ``max`` have different data types and/or data type kinds (e.g., integer versus floating-point), behavior is unspecified and thus implementation-dependent. + - If ``x`` and either ``min`` or ``max`` is an array having a different data type, behavior is unspecified and thus implementation-dependent. **Special cases** From cce67fc4f0de5c92e26b15856379b729a6fdc817 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Thu, 6 Feb 2025 02:05:42 -0800 Subject: [PATCH 4/7] docs: add conjunction --- src/array_api_stubs/_draft/elementwise_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index a181ea685..9dfa37d5f 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -839,7 +839,7 @@ def clip( - This function is conceptually equivalent to ``maximum(minimum(x, max), min)`` when ``x``, ``min``, and ``max`` have the same data type. - 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. - - For scalar ``min`` and/or ``max``, the scalar values should follow type promotion rules (see :ref:`type-promotion`). 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 + - For scalar ``min`` and/or ``max``, the scalar values should follow type promotion rules (see :ref:`type-promotion`). Hence, 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 - If ``x`` has an integral data type and a broadcasted element in ``min`` or ``max`` is outside the bounds of the data type of ``x``, behavior is unspecified and thus implementation-dependent. - If ``x`` and either ``min`` or ``max`` is an array having a different data type, behavior is unspecified and thus implementation-dependent. From 97482ab6b6d1349d83e1bbb84c0b54b99006096c Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Thu, 6 Feb 2025 02:06:37 -0800 Subject: [PATCH 5/7] docs: update copy --- src/array_api_stubs/_draft/elementwise_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index 9dfa37d5f..31d0dea36 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -839,7 +839,7 @@ def clip( - This function is conceptually equivalent to ``maximum(minimum(x, max), min)`` when ``x``, ``min``, and ``max`` have the same data type. - 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. - - For scalar ``min`` and/or ``max``, the scalar values should follow type promotion rules (see :ref:`type-promotion`). Hence, 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 + - For scalar ``min`` and/or ``max``, the scalar values should follow type promotion rules for operations involving arrays and scalar operands (see :ref:`type-promotion`). Hence, 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. - If ``x`` has an integral data type and a broadcasted element in ``min`` or ``max`` is outside the bounds of the data type of ``x``, behavior is unspecified and thus implementation-dependent. - If ``x`` and either ``min`` or ``max`` is an array having a different data type, behavior is unspecified and thus implementation-dependent. From c4bbc397a9670500ac4730de60b3095d7b1dd9b3 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Thu, 6 Feb 2025 02:07:21 -0800 Subject: [PATCH 6/7] docs: update copy --- src/array_api_stubs/_draft/elementwise_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index 31d0dea36..1a46a2dcf 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -841,7 +841,7 @@ def clip( - If a broadcasted element in ``min`` is greater than a corresponding broadcasted element in ``max``, behavior is unspecified and thus implementation-dependent. - For scalar ``min`` and/or ``max``, the scalar values should follow type promotion rules for operations involving arrays and scalar operands (see :ref:`type-promotion`). Hence, 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. - If ``x`` has an integral data type and a broadcasted element in ``min`` or ``max`` is outside the bounds of the data type of ``x``, behavior is unspecified and thus implementation-dependent. - - If ``x`` and either ``min`` or ``max`` is an array having a different data type, behavior is unspecified and thus implementation-dependent. + - If either ``min`` or ``max`` is an array having a different data type than ``x``, behavior is unspecified and thus implementation-dependent. **Special cases** From 2009335989e5d6b181301073389cd11cacd04ed2 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Thu, 6 Feb 2025 02:10:11 -0800 Subject: [PATCH 7/7] docs: relax the output array data type requirement --- src/array_api_stubs/_draft/elementwise_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array_api_stubs/_draft/elementwise_functions.py b/src/array_api_stubs/_draft/elementwise_functions.py index 1a46a2dcf..a35c04db5 100644 --- a/src/array_api_stubs/_draft/elementwise_functions.py +++ b/src/array_api_stubs/_draft/elementwise_functions.py @@ -831,7 +831,7 @@ def clip( Returns ------- out: array - an array containing element-wise results. The returned array must have the same data type as ``x``. + an array containing element-wise results. The returned array should have the same data type as ``x``. Notes -----