diff --git a/spec/API_specification/array_api/elementwise_functions.py b/spec/API_specification/array_api/elementwise_functions.py index e76be8d65..925abb09d 100644 --- a/spec/API_specification/array_api/elementwise_functions.py +++ b/spec/API_specification/array_api/elementwise_functions.py @@ -929,15 +929,15 @@ def log(x: array, /) -> array: """ def log1p(x: array, /) -> array: - """ - Calculates an implementation-dependent approximation to ``log(1+x)``, where ``log`` refers to the natural (base ``e``) logarithm, having domain ``[-1, +infinity]`` and codomain ``[-infinity, +infinity]``, for each element ``x_i`` of the input array ``x``. + r""" + Calculates an implementation-dependent approximation to ``log(1+x)``, where ``log`` refers to the natural (base ``e``) logarithm, for each element ``x_i`` of the input array ``x``. .. note:: The purpose of this function is to calculate ``log(1+x)`` more accurately when `x` is close to zero. Accordingly, conforming implementations should avoid implementing this function as simply ``log(1+x)``. See FDLIBM, or some other IEEE 754-2019 compliant mathematical library, for a potential reference implementation. **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 less than ``-1``, the result is ``NaN``. @@ -946,15 +946,41 @@ def log1p(x: array, /) -> array: - If ``x_i`` is ``+0``, the result is ``+0``. - 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 ``-1`` and ``b`` is ``+0``, the result is ``-infinity + 0j``. + - If ``a`` is a finite number and ``b`` is ``+infinity``, the result is ``+infinity + πj/2``. + - If ``a`` is a finite number and ``b`` is ``NaN``, the result is ``NaN + NaN j``. + - If ``a`` is ``-infinity`` and ``b`` is a positive (i.e., greater than ``0``) finite number, the result is ``+infinity + πj``. + - If ``a`` is ``+infinity`` and ``b`` is a positive (i.e., greater than ``0``) finite number, the result is ``+infinity + 0j``. + - If ``a`` is ``-infinity`` and ``b`` is ``+infinity``, the result is ``+infinity + 3πj/4``. + - If ``a`` is ``+infinity`` and ``b`` is ``+infinity``, the result is ``+infinity + πj/4``. + - If ``a`` is either ``+infinity`` or ``-infinity`` and ``b`` is ``NaN``, the result is ``+infinity + NaN j``. + - If ``a`` is ``NaN`` and ``b`` is a finite number, the result is ``NaN + NaN j``. + - If ``a`` is ``NaN`` and ``b`` is ``+infinity``, the result is ``+infinity + NaN j``. + - If ``a`` is ``NaN`` and ``b`` is ``NaN``, the result is ``NaN + NaN j``. + + .. note:: + For complex floating-point operands, ``log1p(conj(x))`` must equal ``conj(log1p(x))``. + + .. note:: + By convention, the branch cut of the natural logarithm is the negative real axis :math:`(-\infty, 0)`. + + The natural logarithm is a continuous function from above the branch cut, taking into account the sign of the imaginary component. + + Accordingly, for complex arguments, the function returns the natural logarithm in the range of a strip in the interval :math:`[-\pi j, +\pi j]` along the imaginary axis and mathematically unbounded along the real axis. + + *Note: branch cuts have provisional status* (see :ref:`branch-cuts`). + 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 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 result for each element in ``x``. The returned array must have a floating-point data type determined by :ref:`type-promotion`. """ def log2(x: array, /) -> array: