8000 gh-85417: Clarify behaviour on branch cuts in cmath module (#102046) · miss-islington/cpython@b513c46 · GitHub
  • [go: up one dir, main page]

    Skip to content

    Commit b513c46

    Browse files
    authored
    pythongh-85417: Clarify behaviour on branch cuts in cmath module (python#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
    1 parent 32df540 commit b513c46

    File tree

    2 files changed

    +39
    -28
    lines changed

    2 files changed

    +39
    -28
    lines changed

    Doc/library/cmath.rst

    Lines changed: 38 additions & 28 deletions
    Original file line numberDiff line numberDiff line change
    @@ -15,11 +15,27 @@ the function is then applied to the result of the conversion.
    1515

    1616
    .. note::
    1717

    18-
    On platforms with hardware and system-level support for signed
    19-
    zeros, functions involving branch cuts are continuous on *both*
    20-
    sides of the branch cut: the sign of the zero distinguishes one
    21-
    side of the branch cut from the other. On platforms that do not
    22-
    support signed zeros the continuity is as specified below.
    18+
    For functions involving branch cuts, we have the problem of deciding how to
    19+
    define those functions on the cut itself. Following Kahan's "Branch cuts for
    20+
    complex elementary functions" paper, as well as Annex G of C99 and later C
    21+
    standards, we use the sign of zero to distinguish one side of the branch cut
    22+
    from the other: for a branch cut along (a portion of) the real axis we look
    23+
    at the sign of the imaginary part, while for a branch cut along the
    24+
    imaginary axis we look at the sign of the real part.
    25+
    26+
    For example, the :func:`cmath.sqrt` function has a branch cut along the
    27+
    negative real axis. An argument of ``complex(-2.0, -0.0)`` is treated as
    28+
    though it lies *below* the branch cut, and so gives a result on the negative
    29+
    imaginary axis::
    30+
    31+
    >>> cmath.sqrt(complex(-2.0, -0.0))
    32+
    -1.4142135623730951j
    33+
    34+
    But an argument of ``complex(-2.0, 0.0)`` is treated as though it lies above
    35+
    the branch cut::
    36+
    37+
    >>> cmath.sqrt(complex(-2.0, 0.0))
    38+
    1.4142135623730951j
    2339

    2440

    2541
    Conversions to and from polar coordinates
    @@ -44,14 +60,11 @@ rectangular coordinates to polar coordinates and back.
    4460

    4561
    .. function:: phase(x)
    4662

    47-
    Return the phase of *x* (also known as the *argument* of *x*), as a
    48-
    float. ``phase(x)`` is equivalent to ``math.atan2(x.imag,
    49-
    x.real)``. The result lies in the range [-\ *π*, *π*], and the branch
    50-
    cut for this operation lies along the negative real axis,
    51-
    continuous from above. On systems with support for signed zeros
    52-
    (which includes most systems in current use), this means that the
    53-
    sign of the result is the same as the sign of ``x.imag``, even when
    54-
    ``x.imag`` is zero::
    63+
    Return the phase of *x* (also known as the *argument* of *x*), as a float.
    64+
    ``phase(x)`` is equivalent to ``math.atan2(x.imag, x.real)``. The result
    65+
    lies in the range [-\ *π*, *π*], and the branch cut for this operation lies
    66+
    along the negative real axis. The sign of the result is the same as the
    67+
    sign of ``x.imag``, even when ``x.imag`` is zero::
    5568

    5669
    >>> phase(complex(-1.0, 0.0))
    5770
    3.141592653589793
    @@ -92,8 +105,8 @@ Power and logarithmic functions
    92105
    .. function:: log(x[, base])
    93106

    94107
    Returns the logarithm of *x* to the given *base*. If the *base* is not
    95-
    specified, returns the natural logarithm of *x*. There is one branch cut, from 0
    96-
    along the negative real axis to -∞, continuous from above.
    108+
    specified, returns the natural logarithm of *x*. There is one branch cut,
    109+
    from 0 along the negative real axis to -∞.
    97110

    98111

    99112
    .. function:: log10(x)
    @@ -112,9 +125,9 @@ Trigonometric functions
    112125

    113126
    .. function:: acos(x)
    114127

    115-
    Return the arc cosine of *x*. There are two branch cuts: One extends right from
    116-
    1 along the real axis to ∞, continuous from below. The other extends left from
    117-
    -1 along the real axis to -∞, continuous from above.
    128+
    Return the arc cosine of *x*. There are two branch cuts: One extends right
    129+
    from 1 along the real axis to ∞. The other extends left from -1 along the
    130+
    real axis to -∞.
    118131

    119132

    120133
    .. function:: asin(x)
    @@ -125,9 +138,8 @@ Trigonometric functions
    125138
    .. function:: atan(x)
    126139

    127140
    Return the arc tangent of *x*. There are two branch cuts: One extends from
    128-
    ``1j`` along the imaginary axis to ``∞j``, continuous from the right. The
    129-
    other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous
    130-
    from the left.
    141+
    ``1j`` along the imaginary axis to ``∞j``. The other extends from ``-1j``
    142+
    along the imaginary axis to ``-∞j``.
    131143

    132144

    133145
    .. function:: cos(x)
    @@ -151,23 +163,21 @@ Hyperbolic functions
    151163
    .. function:: acosh(x)
    152164

    153165
    Return the inverse hyperbolic cosine of *x*. There is one branch cut,
    154-
    extending left from 1 along the real axis to -∞, continuous from above.
    166+
    extending left from 1 along the real axis to -∞.
    155167

    156168

    157169
    .. function:: asinh(x)
    158170

    159171
    Return the inverse hyperbolic sine of *x*. There are two branch cuts:
    160-
    One extends from ``1j`` along the imaginary axis to ``∞j``,
    161-
    continuous from the right. The other extends from ``-1j`` along
    162-
    the imaginary axis to ``-∞j``, continuous from the left.
    172+
    One extends from ``1j`` along the imaginary axis to ``∞j``. The other
    173+
    extends from ``-1j`` along the imaginary axis to ``-∞j``.
    163174

    164175

    165176
    .. function:: atanh(x)
    166177

    167178
    Return the inverse hyperbolic tangent of *x*. There are two branch cuts: One
    168-
    extends from ``1`` along the real axis to ````, continuous from below. The
    169-
    other extends from ``-1`` along the real axis to ``-∞``, continuous from
    170-
    above.
    179+
    extends from ``1`` along the real axis to ````. The other extends from
    180+
    ``-1`` along the real axis to ``-∞``.
    171181

    172182

    173183
    .. function:: cosh(x)
    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1 @@
    1+
    Update :mod:`cmath` documentation to clarify behaviour on branch cuts.

    0 commit comments

    Comments
     (0)
    0