Skip to content

Commit 6f34109

Browse files
committed
I finally got the time to update and merge Mark's and my trunk-math branch. The patch is collaborated work of Mark Dickinson and me. It was mostly done a few months ago. The patch fixes a lot of loose ends and edge cases related to operations with NaN, INF, very small values and complex math.
The patch also adds acosh, asinh, atanh, log1p and copysign to all platforms. Finally it fixes differences between platforms like different results or exceptions for edge cases. Have fun :)
1 parent 858a770 commit 6f34109

25 files changed

+5100
-1157
lines changed

Doc/library/cmath.rst

+107-13
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,81 @@ method: these methods are used to convert the object to a complex or
1414
floating-point number, respectively, and the function is then applied to the
1515
result of the conversion.
1616

17-
The functions are:
17+
.. note::
1818

19+
On platforms with hardware and system-level support for signed
20+
zeros, functions involving branch cuts are continuous on *both*
21+
sides of the branch cut: the sign of the zero distinguishes one
22+
side of the branch cut from the other. On platforms that do not
23+
support signed zeros the continuity is as specified below.
24+
25+
26+
Complex coordinates
27+
-------------------
28+
29+
Complex numbers can be expressed by two important coordinate systems.
30+
Python's :class:`complex` type uses rectangular coordinates where a number
31+
on the complex plain is defined by two floats, the real part and the imaginary
32+
part.
33+
34+
Definition::
35+
36+
z = x + 1j * y
37+
38+
x := real(z)
39+
y := imag(z)
40+
41+
In engineering the polar coordinate system is popular for complex numbers. In
42+
polar coordinates a complex number is defined by the radius *r* and the phase
43+
angle *φ*. The radius *r* is the absolute value of the complex, which can be
44+
viewed as distance from (0, 0). The radius *r* is always 0 or a positive float.
45+
The phase angle *φ* is the counter clockwise angle from the positive x axis,
46+
e.g. *1* has the angle *0*, *1j* has the angle *π/2* and *-1* the angle **.
47+
48+
.. note::
49+
While :func:`phase` and func:`polar` return ** for a negative real they
50+
may return ** for a complex with a very small negative imaginary
51+
part, e.g. *-1-1E-300j*.
52+
53+
54+
Definition::
55+
56+
z = r * exp(1j * φ)
57+
z = r * cis(φ)
58+
59+
r := abs(z) := sqrt(real(z)**2 + imag(z)**2)
60+
phi := phase(z) := atan2(imag(z), real(z))
61+
cis(φ) := cos(φ) + 1j * sin(φ)
62+
63+
64+
.. function:: phase(x)
65+
66+
Return phase, also known as the argument, of a complex.
67+
68+
.. versionadded:: 2.6
69+
70+
71+
.. function:: polar(x)
72+
73+
Convert a :class:`complex` from rectangular coordinates to polar
74+
coordinates. The function returns a tuple with the two elements
75+
*r* and *phi*. *r* is the distance from 0 and *phi* the phase
76+
angle.
77+
78+
.. versionadded:: 2.6
79+
80+
81+
.. function:: rect(r, phi)
82+
83+
Convert from polar coordinates to rectangular coordinates and return
84+
a :class:`complex`.
85+
86+
.. versionadded:: 2.6
87+
88+
89+
90+
cmath functions
91+
---------------
1992

2093
.. function:: acos(x)
2194

@@ -37,30 +110,35 @@ The functions are:
37110

38111
.. function:: asinh(x)
39112

40-
Return the hyperbolic arc sine of *x*. There are two branch cuts, extending
41-
left from ``±1j`` to ``±∞j``, both continuous from above. These branch cuts
42-
should be considered a bug to be corrected in a future release. The correct
43-
branch cuts should extend along the imaginary axis, one from ``1j`` up to
44-
``∞j`` and continuous from the right, and one from ``-1j`` down to ``-∞j``
45-
and continuous from the left.
113+
Return the hyperbolic arc sine of *x*. There are two branch cuts:
114+
One extends from ``1j`` along the imaginary axis to ``∞j``,
115+
continuous from the right. The other extends from ``-1j`` along
116+
the imaginary axis to ``-∞j``, continuous from the left.
117+
118+
.. versionchanged:: 2.6
119+
branch cuts moved to match those recommended by the C99 standard
46120

47121

48122
.. function:: atan(x)
49123

50124
Return the arc tangent of *x*. There are two branch cuts: One extends from
51-
``1j`` along the imaginary axis to ``∞j``, continuous from the left. The
125+
``1j`` along the imaginary axis to ``∞j``, continuous from the right. The
52126
other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous
53-
from the left. (This should probably be changed so the upper cut becomes
54-
continuous from the other side.)
127+
from the left.
128+
129+
.. versionchanged:: 2.6
130+
direction of continuity of upper cut reversed
55131

56132

57133
.. function:: atanh(x)
58134

59135
Return the hyperbolic arc tangent of *x*. There are two branch cuts: One
60-
extends from ``1`` along the real axis to ````, continuous from above. The
136+
extends from ``1`` along the real axis to ````, continuous from below. The
61137
other extends from ``-1`` along the real axis to ``-∞``, continuous from
62-
above. (This should probably be changed so the right cut becomes continuous
63-
from the other side.)
138+
above.
139+
140+
.. versionchanged:: 2.6
141+
direction of continuity of right cut reversed
64142

65143

66144
.. function:: cos(x)
@@ -78,6 +156,21 @@ The functions are:
78156
Return the exponential value ``e**x``.
79157

80158

159+
.. function:: isinf(x)
160+
161+
Return *True* if the real or the imaginary part of x is positive
162+
or negative infinity.
163+
164+
.. versionadded:: 2.6
165+
166+
167+
.. function:: isnan(x)
168+
169+
Return *True* if the real or imaginary part of x is not a number (NaN).
170+
171+
.. versionadded:: 2.6
172+
173+
81174
.. function:: log(x[, base])
82175

83176
Returns the logarithm of *x* to the given *base*. If the *base* is not
@@ -154,3 +247,4 @@ cuts for numerical purposes, a good reference should be the following:
154247
nothing's sign bit. In Iserles, A., and Powell, M. (eds.), The state of the art
155248
in numerical analysis. Clarendon Press (1987) pp165-211.
156249

250+

Doc/library/math.rst

+45-2
Original file line numberDiff line numberDiff line change
@@ -139,14 +139,26 @@ Power and logarithmic functions:
139139
*base* argument added.
140140

141141

142+
.. function:: log1p(x)
143+
144+
Return the natural logarithm of *1+x* (base *e*). The
145+
result is calculated in a way which is accurate for *x* near zero.
146+
147+
.. versionadded:: 2.6
148+
149+
142150
.. function:: log10(x)
143151

144152
Return the base-10 logarithm of *x*.
145153

146154

147155
.. function:: pow(x, y)
148156

149-
Return ``x**y``.
157+
Return ``x**y``. ``1.0**y`` returns *1.0*, even for ``1.0**nan``. ``0**y``
158+
returns *0.* for all positive *y*, *0* and *NAN*.
159+
160+
.. versionchanged:: 2.6
161+
The outcome of ``1**nan`` and ``0**nan`` was undefined.
150162

151163

152164
.. function:: sqrt(x)
@@ -197,6 +209,13 @@ Trigonometric functions:
197209
Return the sine of *x* radians.
198210

199211

212+
.. function:: asinh(x)
213+
214+
Return the inverse hyperbolic sine of *x*, in radians.
215+
216+
.. versionadded:: 2.6
217+
218+
200219
.. function:: tan(x)
201220

202221
Return the tangent of *x* radians.
@@ -221,6 +240,13 @@ Hyperbolic functions:
221240
Return the hyperbolic cosine of *x*.
222241

223242

243+
.. function:: acosh(x)
244+
245+
Return the inverse hyperbolic cosine of *x*, in radians.
246+
247+
.. versionadded:: 2.6
248+
249+
224250
.. function:: sinh(x)
225251

226252
Return the hyperbolic sine of *x*.
@@ -230,6 +256,14 @@ Hyperbolic functions:
230256

231257
Return the hyperbolic tangent of *x*.
232258

259+
260+
.. function:: atanh(x)
261+
262+
Return the inverse hyperbolic tangent of *x*, in radians.
263+
264+
.. versionadded:: 2.6
265+
266+
233267
The module also defines two mathematical constants:
234268

235269

@@ -242,6 +276,7 @@ The module also defines two mathematical constants:
242276

243277
The mathematical constant *e*.
244278

279+
245280
.. note::
246281

247282
The :mod:`math` module consists mostly of thin wrappers around the platform C
@@ -255,9 +290,17 @@ The module also defines two mathematical constants:
255290
:exc:`OverflowError` isn't defined, and in cases where ``math.log(0)`` raises
256291
:exc:`OverflowError`, ``math.log(0L)`` may raise :exc:`ValueError` instead.
257292

293+
All functions return a quite *NaN* if at least one of the args is *NaN*.
294+
Signaling *NaN*s raise an exception. The exception type still depends on the
295+
platform and libm implementation. It's usually :exc:`ValueError` for *EDOM*
296+
and :exc:`OverflowError` for errno *ERANGE*.
297+
298+
..versionchanged:: 2.6
299+
In earlier versions of Python the outcome of an operation with NaN as
300+
input depended on platform and libm implementation.
301+
258302

259303
.. seealso::
260304

261305
Module :mod:`cmath`
262306
Complex number versions of many of these functions.
263-

Include/Python.h

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC)
7474
#error "PYMALLOC_DEBUG requires WITH_PYMALLOC"
7575
#endif
76+
#include "pymath.h"
7677
#include "pymem.h"
7778

7879
#include "object.h"

Include/complexobject.h

+2
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ typedef struct {
1919
#define c_prod _Py_c_prod
2020
#define c_quot _Py_c_quot
2121
#define c_pow _Py_c_pow
22+
#define c_abs _Py_c_abs
2223

2324
PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex);
2425
PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex);
2526
PyAPI_FUNC(Py_complex) c_neg(Py_complex);
2627
PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex);
2728
PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex);
2829
PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex);
30+
PyAPI_FUNC(double) c_abs(Py_complex);
2931

3032

3133
/* Complex object interface */

Include/floatobject.h

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ PyAPI_DATA(PyTypeObject) PyFloat_Type;
2121
#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type)
2222
#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type)
2323

24+
#ifdef Py_NAN
25+
#define Py_RETURN_NAN PyFloat_FromDouble(Py_NAN)
26+
#endif
27+
28+
#define Py_RETURN_INF(sign) do \
29+
if (copysign(1., sign) == 1.) { \
30+
return PyFloat_FromDouble(Py_HUGE_VAL); \
31+
} else { \
32+
return PyFloat_FromDouble(-Py_HUGE_VAL); \
33+
} while(0)
34+
2435
PyAPI_FUNC(double) PyFloat_GetMax(void);
2536
PyAPI_FUNC(double) PyFloat_GetMin(void);
2637
PyAPI_FUNC(PyObject *) PyFloat_GetInfo(void);

0 commit comments

Comments
 (0)