]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.10] gh-85417: Clarify behaviour on branch cuts in cmath module (GH-102046) (#102275)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sun, 26 Feb 2023 11:55:13 +0000 (03:55 -0800)
committerGitHub <noreply@github.com>
Sun, 26 Feb 2023 11:55:13 +0000 (11:55 +0000)
gh-85417: Clarify behaviour on branch cuts in cmath module (GH-102046)

This PR updates the cmath module documentation to reflect the reality that Python is almost always (and as far as I can tell, that "almost" can be omitted) running on a machine whose C double supports signed zeros.

* Removes misleading references to functions being continuous from above / below / the left / the right at branch cuts
* Expands the note on branch cuts at the top of the module documentation to explain the double-sided sign-of-zero-based behaviour
(cherry picked from commit b513c46d998344dc07eb6d510782c2e23d2b859e)

Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
Doc/library/cmath.rst
Misc/NEWS.d/next/Documentation/2023-02-19-10-33-01.gh-issue-85417.kYO8u3.rst [new file with mode: 0644]

index 28cd96b0e12da9c71cd78fad1730e9f7cd4f66be..5ed7a09b3e9db28487aa317ac969c5efe9b07840 100644 (file)
@@ -15,11 +15,27 @@ the function is then applied to the result of the conversion.
 
 .. note::
 
-   On platforms with hardware and system-level support for signed
-   zeros, functions involving branch cuts are continuous on *both*
-   sides of the branch cut: the sign of the zero distinguishes one
-   side of the branch cut from the other.  On platforms that do not
-   support signed zeros the continuity is as specified below.
+   For functions involving branch cuts, we have the problem of deciding how to
+   define those functions on the cut itself. Following Kahan's "Branch cuts for
+   complex elementary functions" paper, as well as Annex G of C99 and later C
+   standards, we use the sign of zero to distinguish one side of the branch cut
+   from the other: for a branch cut along (a portion of) the real axis we look
+   at the sign of the imaginary part, while for a branch cut along the
+   imaginary axis we look at the sign of the real part.
+
+   For example, the :func:`cmath.sqrt` function has a branch cut along the
+   negative real axis. An argument of ``complex(-2.0, -0.0)`` is treated as
+   though it lies *below* the branch cut, and so gives a result on the negative
+   imaginary axis::
+
+      >>> cmath.sqrt(complex(-2.0, -0.0))
+      -1.4142135623730951j
+
+   But an argument of ``complex(-2.0, 0.0)`` is treated as though it lies above
+   the branch cut::
+
+      >>> cmath.sqrt(complex(-2.0, 0.0))
+      1.4142135623730951j
 
 
 Conversions to and from polar coordinates
@@ -44,14 +60,11 @@ rectangular coordinates to polar coordinates and back.
 
 .. function:: phase(x)
 
-   Return the phase of *x* (also known as the *argument* of *x*), as a
-   float.  ``phase(x)`` is equivalent to ``math.atan2(x.imag,
-   x.real)``.  The result lies in the range [-\ *π*, *π*], and the branch
-   cut for this operation lies along the negative real axis,
-   continuous from above.  On systems with support for signed zeros
-   (which includes most systems in current use), this means that the
-   sign of the result is the same as the sign of ``x.imag``, even when
-   ``x.imag`` is zero::
+   Return the phase of *x* (also known as the *argument* of *x*), as a float.
+   ``phase(x)`` is equivalent to ``math.atan2(x.imag, x.real)``.  The result
+   lies in the range [-\ *π*, *π*], and the branch cut for this operation lies
+   along the negative real axis.  The sign of the result is the same as the
+   sign of ``x.imag``, even when ``x.imag`` is zero::
 
       >>> phase(complex(-1.0, 0.0))
       3.141592653589793
@@ -92,8 +105,8 @@ Power and logarithmic functions
 .. function:: log(x[, base])
 
    Returns the logarithm of *x* to the given *base*. If the *base* is not
-   specified, returns the natural logarithm of *x*. There is one branch cut, from 0
-   along the negative real axis to -∞, continuous from above.
+   specified, returns the natural logarithm of *x*. There is one branch cut,
+   from 0 along the negative real axis to -∞.
 
 
 .. function:: log10(x)
@@ -112,9 +125,9 @@ Trigonometric functions
 
 .. function:: acos(x)
 
-   Return the arc cosine of *x*. There are two branch cuts: One extends right from
-   1 along the real axis to ∞, continuous from below. The other extends left from
-   -1 along the real axis to -∞, continuous from above.
+   Return the arc cosine of *x*. There are two branch cuts: One extends right
+   from 1 along the real axis to ∞. The other extends left from -1 along the
+   real axis to -∞.
 
 
 .. function:: asin(x)
@@ -125,9 +138,8 @@ Trigonometric functions
 .. function:: atan(x)
 
    Return the arc tangent of *x*. There are two branch cuts: One extends from
-   ``1j`` along the imaginary axis to ``∞j``, continuous from the right. The
-   other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous
-   from the left.
+   ``1j`` along the imaginary axis to ``∞j``. The other extends from ``-1j``
+   along the imaginary axis to ``-∞j``.
 
 
 .. function:: cos(x)
@@ -151,23 +163,21 @@ Hyperbolic functions
 .. function:: acosh(x)
 
    Return the inverse hyperbolic cosine of *x*. There is one branch cut,
-   extending left from 1 along the real axis to -∞, continuous from above.
+   extending left from 1 along the real axis to -∞.
 
 
 .. function:: asinh(x)
 
    Return the inverse hyperbolic sine of *x*. There are two branch cuts:
-   One extends from ``1j`` along the imaginary axis to ``∞j``,
-   continuous from the right.  The other extends from ``-1j`` along
-   the imaginary axis to ``-∞j``, continuous from the left.
+   One extends from ``1j`` along the imaginary axis to ``∞j``.  The other
+   extends from ``-1j`` along the imaginary axis to ``-∞j``.
 
 
 .. function:: atanh(x)
 
    Return the inverse hyperbolic tangent of *x*. There are two branch cuts: One
-   extends from ``1`` along the real axis to ``∞``, continuous from below. The
-   other extends from ``-1`` along the real axis to ``-∞``, continuous from
-   above.
+   extends from ``1`` along the real axis to ``∞``. The other extends from
+   ``-1`` along the real axis to ``-∞``.
 
 
 .. function:: cosh(x)
diff --git a/Misc/NEWS.d/next/Documentation/2023-02-19-10-33-01.gh-issue-85417.kYO8u3.rst b/Misc/NEWS.d/next/Documentation/2023-02-19-10-33-01.gh-issue-85417.kYO8u3.rst
new file mode 100644 (file)
index 0000000..a5532df
--- /dev/null
@@ -0,0 +1 @@
+Update :mod:`cmath` documentation to clarify behaviour on branch cuts.