From b23b0fc9a7b69cf762a2f7dbd5a38270782fe5da Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Sun, 12 Jun 2022 23:04:18 -0700 Subject: [PATCH 1/8] Update ignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 73e203a64..86bab2717 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ node_modules/ __pycache__/ *.pyc spec/**/generated +tmp/ \ No newline at end of file From ba07d69bf7f44e9ddb8085841fdc821ebf193609 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Sun, 12 Jun 2022 23:04:31 -0700 Subject: [PATCH 2/8] Add complex number support to `exp` --- .../array_api/elementwise_functions.py | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index 7acefaf52..10979eac8 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -223,8 +223,8 @@ def atan2(x1: array, x2: array, /) -> array: - If ``x1_i`` is greater than ``0``, ``x1_i`` is a finite number, and ``x2_i`` is ``-infinity``, the result is an implementation-dependent approximation to ``+π``. - If ``x1_i`` is less than ``0``, ``x1_i`` is a finite number, and ``x2_i`` is ``+infinity``, the result is ``-0``. - If ``x1_i`` is less than ``0``, ``x1_i`` is a finite number, and ``x2_i`` is ``-infinity``, the result is an implementation-dependent approximation to ``-π``. - - If ``x1_i`` is ``+infinity`` and ``x2_i`` is finite, the result is an implementation-dependent approximation to ``+π/2``. - - If ``x1_i`` is ``-infinity`` and ``x2_i`` is finite, the result is an implementation-dependent approximation to ``-π/2``. + - If ``x1_i`` is ``+infinity`` and ``x2_i`` is a finite number, the result is an implementation-dependent approximation to ``+π/2``. + - If ``x1_i`` is ``-infinity`` and ``x2_i`` is a finite number, the result is an implementation-dependent approximation to ``-π/2``. - If ``x1_i`` is ``+infinity`` and ``x2_i`` is ``+infinity``, the result is an implementation-dependent approximation to ``+π/4``. - If ``x1_i`` is ``+infinity`` and ``x2_i`` is ``-infinity``, the result is an implementation-dependent approximation to ``+3π/4``. - If ``x1_i`` is ``-infinity`` and ``x2_i`` is ``+infinity``, the result is an implementation-dependent approximation to ``-π/4``. @@ -523,7 +523,7 @@ def exp(x: array, /) -> array: **Special cases** - For floating-point operands, + For real-valued floating-point operands, - If ``x_i`` is ``NaN``, the result is ``NaN``. - If ``x_i`` is ``+0``, the result is ``1``. @@ -531,6 +531,25 @@ def exp(x: array, /) -> array: - If ``x_i`` is ``+infinity``, the result is ``+infinity``. - If ``x_i`` is ``-infinity``, the result is ``+0``. + For complex floating-point operands, let ``a = real(x_i)``, ``b = imag(x_i)``, and + + - If ``a`` is either ``+0`` or ``-0`` and ``b`` is either ``+0`` or ``-0``, the result is ``1+0j``. + - If ``a`` is a finite number and ``b`` is ``+infinity``, the result is ``NaN + NaN j``. + - If ``a`` is a finite number and ``b`` is ``NaN``, the result is ``NaN + NaN j``. + - If ``a`` is ``+infinity`` and ``b`` is either ``+0`` or ``-0``, the result is ``infinity + 0j``. + - If ``a`` is ``-infinity`` and ``b`` is a finite number, the result is ``0 + 0j``. + - If ``a`` is ``+infinity`` and ``b`` is a nonzero finite number, the result is ``infinity + infinity j``. + - If ``a`` is ``-infinity`` and ``b`` is ``+infinity``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified). + - If ``a`` is ``+infinity`` and ``b`` is ``+infinity``, the result is ``infinity + NaN j`` (sign of real component is unspecified). + - If ``a`` is ``-infinity`` and ``b`` is ``NaN``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified). + - If ``a`` is ``+infinity`` and ``b`` is ``NaN``, the result is ``infinity + NaN j`` (sign of real component is unspecified). + - If ``a`` is ``NaN`` and ``b`` is either ``+0`` or ``-0``, the result is ``NaN + 0j``. + - If ``a`` is ``NaN`` and ``b`` is not equal to ``0``, the result is ``NaN + NaN j``. + - If ``a`` is ``NaN`` and ``b`` is ``NaN``, the result is ``NaN + NaN j``. + + .. note:: + The exponential function is an entire function in the complex plane and has no branch cuts. + Parameters ---------- x: array From bffddb20291b8e795cdd6ac19ba26a26cade80ab Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Sun, 12 Jun 2022 23:37:52 -0700 Subject: [PATCH 3/8] Update input and output data types --- spec/API_specification/array_api/elementwise_functions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index 10979eac8..853aab35b 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -553,12 +553,12 @@ def exp(x: array, /) -> array: Parameters ---------- x: array - input array. Should have a real-valued floating-point data type. + input array. Should have a floating-point data type. Returns ------- out: array - an array containing the evaluated exponential function result for each element in ``x``. The returned array must have a real-valued floating-point data type determined by :ref:`type-promotion`. + an array containing the evaluated exponential function result for each element in ``x``. The returned array must have a floating-point data type determined by :ref:`type-promotion`. """ def expm1(x: array, /) -> array: From d10b63bf9af3c462cb27d0ec8c7164bbef818b10 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 13 Jun 2022 00:08:32 -0700 Subject: [PATCH 4/8] Update description to accommodate complex number input --- spec/API_specification/array_api/elementwise_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index 853aab35b..0ac9e0381 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -519,7 +519,7 @@ def equal(x1: array, x2: array, /) -> array: def exp(x: array, /) -> array: """ - Calculates an implementation-dependent approximation to the exponential function, having domain ``[-infinity, +infinity]`` and codomain ``[+0, +infinity]``, for each element ``x_i`` of the input array ``x`` (``e`` raised to the power of ``x_i``, where ``e`` is the base of the natural logarithm). + Calculates an implementation-dependent approximation to the exponential function for each element ``x_i`` of the input array ``x`` (``e`` raised to the power of ``x_i``, where ``e`` is the base of the natural logarithm). **Special cases** From f84e176d14eb0f62d28becb873585711c6f0f9e6 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 13 Jun 2022 01:56:41 -0700 Subject: [PATCH 5/8] Add note concerning complex conjugation --- spec/API_specification/array_api/elementwise_functions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index 0ac9e0381..94714495f 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -550,6 +550,9 @@ def exp(x: array, /) -> array: .. note:: The exponential function is an entire function in the complex plane and has no branch cuts. + .. note:: + For complex floating-point operands, ``exp(conj(x))`` must equal ``conj(exp(x))``. + Parameters ---------- x: array From cb2c8df2e76c61be36099c6060dfc7dbab6302c3 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 13 Jun 2022 02:38:02 -0700 Subject: [PATCH 6/8] Specify special case in terms of `cis` function --- spec/API_specification/array_api/elementwise_functions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index 94714495f..a124dbf48 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -537,8 +537,8 @@ def exp(x: array, /) -> array: - If ``a`` is a finite number and ``b`` is ``+infinity``, the result is ``NaN + NaN j``. - If ``a`` is a finite number and ``b`` is ``NaN``, the result is ``NaN + NaN j``. - If ``a`` is ``+infinity`` and ``b`` is either ``+0`` or ``-0``, the result is ``infinity + 0j``. - - If ``a`` is ``-infinity`` and ``b`` is a finite number, the result is ``0 + 0j``. - - If ``a`` is ``+infinity`` and ``b`` is a nonzero finite number, the result is ``infinity + infinity j``. + - If ``a`` is ``-infinity`` and ``b`` is a finite number, the result is ``+0 * cis(x_i)``. + - If ``a`` is ``+infinity`` and ``b`` is a nonzero finite number, the result is ``+infinity * cis(x_i)``. - If ``a`` is ``-infinity`` and ``b`` is ``+infinity``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified). - If ``a`` is ``+infinity`` and ``b`` is ``+infinity``, the result is ``infinity + NaN j`` (sign of real component is unspecified). - If ``a`` is ``-infinity`` and ``b`` is ``NaN``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified). @@ -547,6 +547,8 @@ def exp(x: array, /) -> array: - If ``a`` is ``NaN`` and ``b`` is not equal to ``0``, the result is ``NaN + NaN j``. - If ``a`` is ``NaN`` and ``b`` is ``NaN``, the result is ``NaN + NaN j``. + where ``cis(x_i)`` is ``cos(x_i) + sin(x_i)*1j``. + .. note:: The exponential function is an entire function in the complex plane and has no branch cuts. From 2b5028c57699ea36a8d471c83fda8131cf73635b Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 20 Jun 2022 00:03:57 -0700 Subject: [PATCH 7/8] Fix special cases and move note --- .../array_api/elementwise_functions.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index a124dbf48..73af8e958 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -533,28 +533,28 @@ def exp(x: array, /) -> array: For complex floating-point operands, let ``a = real(x_i)``, ``b = imag(x_i)``, and - - If ``a`` is either ``+0`` or ``-0`` and ``b`` is either ``+0`` or ``-0``, the result is ``1+0j``. + .. note:: + For complex floating-point operands, ``exp(conj(x))`` must equal ``conj(exp(x))``. + + - If ``a`` is either ``+0`` or ``-0`` and ``b`` is ``+0``, the result is ``1+0j``. - If ``a`` is a finite number and ``b`` is ``+infinity``, the result is ``NaN + NaN j``. - If ``a`` is a finite number and ``b`` is ``NaN``, the result is ``NaN + NaN j``. - - If ``a`` is ``+infinity`` and ``b`` is either ``+0`` or ``-0``, the result is ``infinity + 0j``. + - If ``a`` is ``+infinity`` and ``b`` is ``+0``, the result is ``infinity + 0j``. - If ``a`` is ``-infinity`` and ``b`` is a finite number, the result is ``+0 * cis(x_i)``. - If ``a`` is ``+infinity`` and ``b`` is a nonzero finite number, the result is ``+infinity * cis(x_i)``. - If ``a`` is ``-infinity`` and ``b`` is ``+infinity``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified). - If ``a`` is ``+infinity`` and ``b`` is ``+infinity``, the result is ``infinity + NaN j`` (sign of real component is unspecified). - If ``a`` is ``-infinity`` and ``b`` is ``NaN``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified). - If ``a`` is ``+infinity`` and ``b`` is ``NaN``, the result is ``infinity + NaN j`` (sign of real component is unspecified). - - If ``a`` is ``NaN`` and ``b`` is either ``+0`` or ``-0``, the result is ``NaN + 0j``. + - If ``a`` is ``NaN`` and ``b`` is ``+0``, the result is ``NaN + 0j``. - If ``a`` is ``NaN`` and ``b`` is not equal to ``0``, the result is ``NaN + NaN j``. - If ``a`` is ``NaN`` and ``b`` is ``NaN``, the result is ``NaN + NaN j``. - where ``cis(x_i)`` is ``cos(x_i) + sin(x_i)*1j``. + where ``cis(v)`` is ``cos(v) + sin(v)*1j``. .. note:: The exponential function is an entire function in the complex plane and has no branch cuts. - .. note:: - For complex floating-point operands, ``exp(conj(x))`` must equal ``conj(exp(x))``. - Parameters ---------- x: array From 99089113d2b982d46d39070f4da788091a53c2db Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 20 Jun 2022 00:37:50 -0700 Subject: [PATCH 8/8] Fix `cis` argument --- spec/API_specification/array_api/elementwise_functions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index 73af8e958..d5a560417 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -536,12 +536,12 @@ def exp(x: array, /) -> array: .. note:: For complex floating-point operands, ``exp(conj(x))`` must equal ``conj(exp(x))``. - - If ``a`` is either ``+0`` or ``-0`` and ``b`` is ``+0``, the result is ``1+0j``. + - If ``a`` is either ``+0`` or ``-0`` and ``b`` is ``+0``, the result is ``1 + 0j``. - If ``a`` is a finite number and ``b`` is ``+infinity``, the result is ``NaN + NaN j``. - If ``a`` is a finite number and ``b`` is ``NaN``, the result is ``NaN + NaN j``. - If ``a`` is ``+infinity`` and ``b`` is ``+0``, the result is ``infinity + 0j``. - - If ``a`` is ``-infinity`` and ``b`` is a finite number, the result is ``+0 * cis(x_i)``. - - If ``a`` is ``+infinity`` and ``b`` is a nonzero finite number, the result is ``+infinity * cis(x_i)``. + - If ``a`` is ``-infinity`` and ``b`` is a finite number, the result is ``+0 * cis(b)``. + - If ``a`` is ``+infinity`` and ``b`` is a nonzero finite number, the result is ``+infinity * cis(b)``. - If ``a`` is ``-infinity`` and ``b`` is ``+infinity``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified). - If ``a`` is ``+infinity`` and ``b`` is ``+infinity``, the result is ``infinity + NaN j`` (sign of real component is unspecified). - If ``a`` is ``-infinity`` and ``b`` is ``NaN``, the result is ``0 + 0j`` (signs of real and imaginary components are unspecified).