From b310b800f0099e8180120fe8d2c15009c6efdf3b Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 13 Jun 2022 02:23:46 -0700 Subject: [PATCH 1/3] Add complex number support to `cosh` --- .gitignore | 1 + .../array_api/elementwise_functions.py | 41 ++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) 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 diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index 7acefaf52..41bfc4241 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -427,12 +427,17 @@ def cos(x: array, /) -> array: """ def cosh(x: array, /) -> array: - """ - Calculates an implementation-dependent approximation to the hyperbolic cosine, having domain ``[-infinity, +infinity]`` and codomain ``[-infinity, +infinity]``, for each element ``x_i`` in the input array ``x``. + r""" + Calculates an implementation-dependent approximation to the hyperbolic cosine for each element ``x_i`` in the input array ``x``. + + The mathematical definition of the hyperbolic cosine is + + .. math:: + \operatorname{cosh}(x) = \frac{e^x + e^{-x}}{2} **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``. @@ -440,15 +445,41 @@ def cosh(x: array, /) -> array: - If ``x_i`` is ``+infinity``, the result is ``+infinity``. - If ``x_i`` is ``-infinity``, the result is ``+infinity``. + 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 either ``+0`` or ``-0`` and ``b`` is ``+infinity``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). + - If ``a`` is either ``+0`` or ``-0`` and ``b`` is ``NaN``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). + - If ``a`` is a nonzero finite number and ``b`` is ``+infinity``, the result is ``NaN + NaN j``. + - If ``a`` is a nonzero 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 nonzero finite number, the result is ``+infinity * cis(x_i)``. + - If ``a`` is ``+infinity`` and ``b`` is ``+infinity``, the result is ``+infinity + NaN j`` (sign of the real component is unspecified). + - If ``a`` is ``+infinity`` and ``b`` is ``NaN``, the result is ``+infinity + NaN j``. + - If ``a`` is ``NaN`` and ``b`` is either ``+0`` or ``-0``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). + - If ``a`` is ``NaN`` and ``b`` is a nonzero finite number, 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 hyperbolic cosine is an entire function in the complex plane and has no branch cuts. The function is periodic, with period :math:`2\pi j` with respect to the imaginary component. + + .. note:: + For complex floating-point operands, ``cosh(conj(x))`` must equal ``conj(cosh(x))``. + + .. note:: + For all operands, ``cosh(x)`` must equal ``cosh(-x)``. + Parameters ---------- x: array - input array whose elements each represent a hyperbolic angle. Should have a real-valued floating-point data type. + input array whose elements each represent a hyperbolic angle. Should have a floating-point data type. Returns ------- out: array - an array containing the hyperbolic cosine of 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 hyperbolic cosine of each element in ``x``. The returned array must have a floating-point data type determined by :ref:`type-promotion`. """ def divide(x1: array, x2: array, /) -> array: From ee0d552bcfdbf587f11988ba017ba57a0cb80553 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 13 Jun 2022 02:25:16 -0700 Subject: [PATCH 2/3] Add missing comma --- 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 41bfc4241..d30329657 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -463,7 +463,7 @@ def cosh(x: array, /) -> array: where ``cis(x_i)`` is ``cos(x_i) + sin(x_i)*1j``. .. note:: - The hyperbolic cosine is an entire function in the complex plane and has no branch cuts. The function is periodic, with period :math:`2\pi j` with respect to the imaginary component. + The hyperbolic cosine is an entire function in the complex plane and has no branch cuts. The function is periodic, with period :math:`2\pi j`, with respect to the imaginary component. .. note:: For complex floating-point operands, ``cosh(conj(x))`` must equal ``conj(cosh(x))``. From 990f3118a71ab4ccf02eb61329ce802ff0ceca5d Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Mon, 20 Jun 2022 01:48:42 -0700 Subject: [PATCH 3/3] Move notes and fix special cases --- .../array_api/elementwise_functions.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index d30329657..43e5132d7 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -437,6 +437,9 @@ def cosh(x: array, /) -> array: **Special cases** + .. note:: + For all operands, ``cosh(x)`` must equal ``cosh(-x)``. + For real-valued floating-point operands, - If ``x_i`` is ``NaN``, the result is ``NaN``. @@ -447,30 +450,27 @@ def cosh(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``. - - If ``a`` is either ``+0`` or ``-0`` and ``b`` is ``+infinity``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). - - If ``a`` is either ``+0`` or ``-0`` and ``b`` is ``NaN``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). + .. note:: + For complex floating-point operands, ``cosh(conj(x))`` must equal ``conj(cosh(x))``. + + - If ``a`` is ``+0`` and ``b`` is ``+0``, the result is ``1 + 0j``. + - If ``a`` is ``+0`` and ``b`` is ``+infinity``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). + - If ``a`` is ``+0`` and ``b`` is ``NaN``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). - If ``a`` is a nonzero finite number and ``b`` is ``+infinity``, the result is ``NaN + NaN j``. - If ``a`` is a nonzero 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 nonzero finite number, the result is ``+infinity * cis(x_i)``. + - If ``a`` is ``+infinity`` and ``b`` is ``+0``, the result is ``+infinity + 0j``. + - 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 ``+infinity + NaN j`` (sign of the real component is unspecified). - If ``a`` is ``+infinity`` and ``b`` is ``NaN``, the result is ``+infinity + NaN j``. - If ``a`` is ``NaN`` and ``b`` is either ``+0`` or ``-0``, the result is ``NaN + 0j`` (sign of the imaginary component is unspecified). - If ``a`` is ``NaN`` and ``b`` is a nonzero finite number, 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 hyperbolic cosine is an entire function in the complex plane and has no branch cuts. The function is periodic, with period :math:`2\pi j`, with respect to the imaginary component. - .. note:: - For complex floating-point operands, ``cosh(conj(x))`` must equal ``conj(cosh(x))``. - - .. note:: - For all operands, ``cosh(x)`` must equal ``cosh(-x)``. - Parameters ---------- x: array