blob: 8e3c31eabbb53b77df4a42f2894bc7d509425039 [file] [log] [blame]
Guido van Rossum71aa32f1996-01-12 01:34:57 +00001/* Complex math module */
2
3/* much code borrowed from mathmodule.c */
4
Roger E. Masse24070ca1996-12-09 22:59:53 +00005#include "Python.h"
Christian Heimes53876d92008-04-19 00:31:39 +00006/* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from
7 float.h. We assume that FLT_RADIX is either 2 or 16. */
8#include <float.h>
Guido van Rossum71aa32f1996-01-12 01:34:57 +00009
Christian Heimes53876d92008-04-19 00:31:39 +000010#if (FLT_RADIX != 2 && FLT_RADIX != 16)
11#error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16"
Guido van Rossum71aa32f1996-01-12 01:34:57 +000012#endif
13
Christian Heimes53876d92008-04-19 00:31:39 +000014#ifndef M_LN2
15#define M_LN2 (0.6931471805599453094) /* natural log of 2 */
16#endif
Guido van Rossum71aa32f1996-01-12 01:34:57 +000017
Christian Heimes53876d92008-04-19 00:31:39 +000018#ifndef M_LN10
19#define M_LN10 (2.302585092994045684) /* natural log of 10 */
20#endif
21
22/*
23 CM_LARGE_DOUBLE is used to avoid spurious overflow in the sqrt, log,
24 inverse trig and inverse hyperbolic trig functions. Its log is used in the
25 evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unecessary
26 overflow.
27 */
28
29#define CM_LARGE_DOUBLE (DBL_MAX/4.)
30#define CM_SQRT_LARGE_DOUBLE (sqrt(CM_LARGE_DOUBLE))
31#define CM_LOG_LARGE_DOUBLE (log(CM_LARGE_DOUBLE))
32#define CM_SQRT_DBL_MIN (sqrt(DBL_MIN))
33
34/*
35 CM_SCALE_UP is an odd integer chosen such that multiplication by
36 2**CM_SCALE_UP is sufficient to turn a subnormal into a normal.
37 CM_SCALE_DOWN is (-(CM_SCALE_UP+1)/2). These scalings are used to compute
38 square roots accurately when the real and imaginary parts of the argument
39 are subnormal.
40*/
41
42#if FLT_RADIX==2
43#define CM_SCALE_UP (2*(DBL_MANT_DIG/2) + 1)
44#elif FLT_RADIX==16
45#define CM_SCALE_UP (4*DBL_MANT_DIG+1)
46#endif
47#define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2)
Guido van Rossum71aa32f1996-01-12 01:34:57 +000048
49/* forward declarations */
Christian Heimes53876d92008-04-19 00:31:39 +000050static Py_complex c_asinh(Py_complex);
51static Py_complex c_atanh(Py_complex);
52static Py_complex c_cosh(Py_complex);
53static Py_complex c_sinh(Py_complex);
Jeremy Hylton938ace62002-07-17 16:30:39 +000054static Py_complex c_sqrt(Py_complex);
Christian Heimes53876d92008-04-19 00:31:39 +000055static Py_complex c_tanh(Py_complex);
Raymond Hettingerb67ad7e2004-06-14 07:40:10 +000056static PyObject * math_error(void);
Guido van Rossum71aa32f1996-01-12 01:34:57 +000057
Christian Heimes53876d92008-04-19 00:31:39 +000058/* Code to deal with special values (infinities, NaNs, etc.). */
59
60/* special_type takes a double and returns an integer code indicating
61 the type of the double as follows:
62*/
63
64enum special_types {
65 ST_NINF, /* 0, negative infinity */
66 ST_NEG, /* 1, negative finite number (nonzero) */
67 ST_NZERO, /* 2, -0. */
68 ST_PZERO, /* 3, +0. */
69 ST_POS, /* 4, positive finite number (nonzero) */
70 ST_PINF, /* 5, positive infinity */
71 ST_NAN, /* 6, Not a Number */
72};
73
74static enum special_types
75special_type(double d)
76{
77 if (Py_IS_FINITE(d)) {
78 if (d != 0) {
79 if (copysign(1., d) == 1.)
80 return ST_POS;
81 else
82 return ST_NEG;
83 }
84 else {
85 if (copysign(1., d) == 1.)
86 return ST_PZERO;
87 else
88 return ST_NZERO;
89 }
90 }
91 if (Py_IS_NAN(d))
92 return ST_NAN;
93 if (copysign(1., d) == 1.)
94 return ST_PINF;
95 else
96 return ST_NINF;
97}
98
99#define SPECIAL_VALUE(z, table) \
100 if (!Py_IS_FINITE((z).real) || !Py_IS_FINITE((z).imag)) { \
101 errno = 0; \
102 return table[special_type((z).real)] \
103 [special_type((z).imag)]; \
104 }
105
106#define P Py_MATH_PI
107#define P14 0.25*Py_MATH_PI
108#define P12 0.5*Py_MATH_PI
109#define P34 0.75*Py_MATH_PI
110#ifdef MS_WINDOWS
111/* On Windows HUGE_VAL is an extern variable and not a constant. Since the
112 special value arrays need a constant we have to roll our own infinity
113 and nan. */
114# define INF (DBL_MAX*DBL_MAX)
115# define N (INF*0.)
116#else
117# define INF Py_HUGE_VAL
118# define N Py_NAN
119#endif /* MS_WINDOWS */
120#define U -9.5426319407711027e33 /* unlikely value, used as placeholder */
121
122/* First, the C functions that do the real work. Each of the c_*
123 functions computes and returns the C99 Annex G recommended result
124 and also sets errno as follows: errno = 0 if no floating-point
125 exception is associated with the result; errno = EDOM if C99 Annex
126 G recommends raising divide-by-zero or invalid for this result; and
127 errno = ERANGE where the overflow floating-point signal should be
128 raised.
129*/
130
131static Py_complex acos_special_values[7][7] = {
132 {{P34,INF},{P,INF}, {P,INF}, {P,-INF}, {P,-INF}, {P34,-INF},{N,INF}},
133 {{P12,INF},{U,U}, {U,U}, {U,U}, {U,U}, {P12,-INF},{N,N}},
134 {{P12,INF},{U,U}, {P12,0.},{P12,-0.},{U,U}, {P12,-INF},{P12,N}},
135 {{P12,INF},{U,U}, {P12,0.},{P12,-0.},{U,U}, {P12,-INF},{P12,N}},
136 {{P12,INF},{U,U}, {U,U}, {U,U}, {U,U}, {P12,-INF},{N,N}},
137 {{P14,INF},{0.,INF},{0.,INF},{0.,-INF},{0.,-INF},{P14,-INF},{N,INF}},
138 {{N,INF}, {N,N}, {N,N}, {N,N}, {N,N}, {N,-INF}, {N,N}}
139};
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000140
Tim Peters14e26402001-02-20 20:15:19 +0000141static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000142c_acos(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000143{
Christian Heimes53876d92008-04-19 00:31:39 +0000144 Py_complex s1, s2, r;
145
146 SPECIAL_VALUE(z, acos_special_values);
147
148 if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
149 /* avoid unnecessary overflow for large arguments */
150 r.real = atan2(fabs(z.imag), z.real);
151 /* split into cases to make sure that the branch cut has the
152 correct continuity on systems with unsigned zeros */
153 if (z.real < 0.) {
154 r.imag = -copysign(log(hypot(z.real/2., z.imag/2.)) +
155 M_LN2*2., z.imag);
156 } else {
157 r.imag = copysign(log(hypot(z.real/2., z.imag/2.)) +
158 M_LN2*2., -z.imag);
159 }
160 } else {
161 s1.real = 1.-z.real;
162 s1.imag = -z.imag;
163 s1 = c_sqrt(s1);
164 s2.real = 1.+z.real;
165 s2.imag = z.imag;
166 s2 = c_sqrt(s2);
167 r.real = 2.*atan2(s1.real, s2.real);
168 r.imag = asinh(s2.real*s1.imag - s2.imag*s1.real);
169 }
170 errno = 0;
171 return r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000172}
173
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000174PyDoc_STRVAR(c_acos_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000175"acos(x)\n"
176"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000177"Return the arc cosine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000178
179
Christian Heimes53876d92008-04-19 00:31:39 +0000180static Py_complex acosh_special_values[7][7] = {
181 {{INF,-P34},{INF,-P}, {INF,-P}, {INF,P}, {INF,P}, {INF,P34},{INF,N}},
182 {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12},{N,N}},
183 {{INF,-P12},{U,U}, {0.,-P12},{0.,P12},{U,U}, {INF,P12},{N,N}},
184 {{INF,-P12},{U,U}, {0.,-P12},{0.,P12},{U,U}, {INF,P12},{N,N}},
185 {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12},{N,N}},
186 {{INF,-P14},{INF,-0.},{INF,-0.},{INF,0.},{INF,0.},{INF,P14},{INF,N}},
187 {{INF,N}, {N,N}, {N,N}, {N,N}, {N,N}, {INF,N}, {N,N}}
188};
189
Tim Peters14e26402001-02-20 20:15:19 +0000190static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000191c_acosh(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000192{
Christian Heimes53876d92008-04-19 00:31:39 +0000193 Py_complex s1, s2, r;
194
195 SPECIAL_VALUE(z, acosh_special_values);
196
197 if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
198 /* avoid unnecessary overflow for large arguments */
199 r.real = log(hypot(z.real/2., z.imag/2.)) + M_LN2*2.;
200 r.imag = atan2(z.imag, z.real);
201 } else {
202 s1.real = z.real - 1.;
203 s1.imag = z.imag;
204 s1 = c_sqrt(s1);
205 s2.real = z.real + 1.;
206 s2.imag = z.imag;
207 s2 = c_sqrt(s2);
208 r.real = asinh(s1.real*s2.real + s1.imag*s2.imag);
209 r.imag = 2.*atan2(s1.imag, s2.real);
210 }
211 errno = 0;
212 return r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000213}
214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000215PyDoc_STRVAR(c_acosh_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000216"acosh(x)\n"
217"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000218"Return the hyperbolic arccosine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000219
220
Tim Peters14e26402001-02-20 20:15:19 +0000221static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000222c_asin(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000223{
Christian Heimes53876d92008-04-19 00:31:39 +0000224 /* asin(z) = -i asinh(iz) */
225 Py_complex s, r;
226 s.real = -z.imag;
227 s.imag = z.real;
228 s = c_asinh(s);
229 r.real = s.imag;
230 r.imag = -s.real;
231 return r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000232}
233
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000234PyDoc_STRVAR(c_asin_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000235"asin(x)\n"
236"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000237"Return the arc sine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000238
239
Christian Heimes53876d92008-04-19 00:31:39 +0000240static Py_complex asinh_special_values[7][7] = {
241 {{-INF,-P14},{-INF,-0.},{-INF,-0.},{-INF,0.},{-INF,0.},{-INF,P14},{-INF,N}},
242 {{-INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {-INF,P12},{N,N}},
243 {{-INF,-P12},{U,U}, {-0.,-0.}, {-0.,0.}, {U,U}, {-INF,P12},{N,N}},
244 {{INF,-P12}, {U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,P12}, {N,N}},
245 {{INF,-P12}, {U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
246 {{INF,-P14}, {INF,-0.}, {INF,-0.}, {INF,0.}, {INF,0.}, {INF,P14}, {INF,N}},
247 {{INF,N}, {N,N}, {N,-0.}, {N,0.}, {N,N}, {INF,N}, {N,N}}
248};
249
Tim Peters14e26402001-02-20 20:15:19 +0000250static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000251c_asinh(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000252{
Christian Heimes53876d92008-04-19 00:31:39 +0000253 Py_complex s1, s2, r;
254
255 SPECIAL_VALUE(z, asinh_special_values);
256
257 if (fabs(z.real) > CM_LARGE_DOUBLE || fabs(z.imag) > CM_LARGE_DOUBLE) {
258 if (z.imag >= 0.) {
259 r.real = copysign(log(hypot(z.real/2., z.imag/2.)) +
260 M_LN2*2., z.real);
261 } else {
262 r.real = -copysign(log(hypot(z.real/2., z.imag/2.)) +
263 M_LN2*2., -z.real);
264 }
265 r.imag = atan2(z.imag, fabs(z.real));
266 } else {
267 s1.real = 1.+z.imag;
268 s1.imag = -z.real;
269 s1 = c_sqrt(s1);
270 s2.real = 1.-z.imag;
271 s2.imag = z.real;
272 s2 = c_sqrt(s2);
273 r.real = asinh(s1.real*s2.imag-s2.real*s1.imag);
274 r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag);
275 }
276 errno = 0;
277 return r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000278}
279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000280PyDoc_STRVAR(c_asinh_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000281"asinh(x)\n"
282"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000283"Return the hyperbolic arc sine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000284
285
Tim Peters14e26402001-02-20 20:15:19 +0000286static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000287c_atan(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000288{
Christian Heimes53876d92008-04-19 00:31:39 +0000289 /* atan(z) = -i atanh(iz) */
290 Py_complex s, r;
291 s.real = -z.imag;
292 s.imag = z.real;
293 s = c_atanh(s);
294 r.real = s.imag;
295 r.imag = -s.real;
296 return r;
297}
298
299/* Windows screws up atan2 for inf and nan */
300static double
301c_atan2(Py_complex z)
302{
303 if (Py_IS_NAN(z.real) || Py_IS_NAN(z.imag))
304 return Py_NAN;
305 if (Py_IS_INFINITY(z.imag)) {
306 if (Py_IS_INFINITY(z.real)) {
307 if (copysign(1., z.real) == 1.)
308 /* atan2(+-inf, +inf) == +-pi/4 */
309 return copysign(0.25*Py_MATH_PI, z.imag);
310 else
311 /* atan2(+-inf, -inf) == +-pi*3/4 */
312 return copysign(0.75*Py_MATH_PI, z.imag);
313 }
314 /* atan2(+-inf, x) == +-pi/2 for finite x */
315 return copysign(0.5*Py_MATH_PI, z.imag);
316 }
317 return atan2(z.imag, z.real);
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000318}
319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000320PyDoc_STRVAR(c_atan_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000321"atan(x)\n"
322"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000323"Return the arc tangent of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000324
325
Christian Heimes53876d92008-04-19 00:31:39 +0000326static Py_complex atanh_special_values[7][7] = {
327 {{-0.,-P12},{-0.,-P12},{-0.,-P12},{-0.,P12},{-0.,P12},{-0.,P12},{-0.,N}},
328 {{-0.,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {-0.,P12},{N,N}},
329 {{-0.,-P12},{U,U}, {-0.,-0.}, {-0.,0.}, {U,U}, {-0.,P12},{-0.,N}},
330 {{0.,-P12}, {U,U}, {0.,-0.}, {0.,0.}, {U,U}, {0.,P12}, {0.,N}},
331 {{0.,-P12}, {U,U}, {U,U}, {U,U}, {U,U}, {0.,P12}, {N,N}},
332 {{0.,-P12}, {0.,-P12}, {0.,-P12}, {0.,P12}, {0.,P12}, {0.,P12}, {0.,N}},
333 {{0.,-P12}, {N,N}, {N,N}, {N,N}, {N,N}, {0.,P12}, {N,N}}
334};
335
Tim Peters14e26402001-02-20 20:15:19 +0000336static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000337c_atanh(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000338{
Christian Heimes53876d92008-04-19 00:31:39 +0000339 Py_complex r;
340 double ay, h;
341
342 SPECIAL_VALUE(z, atanh_special_values);
343
344 /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */
345 if (z.real < 0.) {
346 return c_neg(c_atanh(c_neg(z)));
347 }
348
349 ay = fabs(z.imag);
350 if (z.real > CM_SQRT_LARGE_DOUBLE || ay > CM_SQRT_LARGE_DOUBLE) {
351 /*
352 if abs(z) is large then we use the approximation
353 atanh(z) ~ 1/z +/- i*pi/2 (+/- depending on the sign
354 of z.imag)
355 */
356 h = hypot(z.real/2., z.imag/2.); /* safe from overflow */
357 r.real = z.real/4./h/h;
358 /* the two negations in the next line cancel each other out
359 except when working with unsigned zeros: they're there to
360 ensure that the branch cut has the correct continuity on
361 systems that don't support signed zeros */
362 r.imag = -copysign(Py_MATH_PI/2., -z.imag);
363 errno = 0;
364 } else if (z.real == 1. && ay < CM_SQRT_DBL_MIN) {
365 /* C99 standard says: atanh(1+/-0.) should be inf +/- 0i */
366 if (ay == 0.) {
367 r.real = INF;
368 r.imag = z.imag;
369 errno = EDOM;
370 } else {
371 r.real = -log(sqrt(ay)/sqrt(hypot(ay, 2.)));
372 r.imag = copysign(atan2(2., -ay)/2, z.imag);
373 errno = 0;
374 }
375 } else {
376 r.real = log1p(4.*z.real/((1-z.real)*(1-z.real) + ay*ay))/4.;
377 r.imag = -atan2(-2.*z.imag, (1-z.real)*(1+z.real) - ay*ay)/2.;
378 errno = 0;
379 }
380 return r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000381}
382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000383PyDoc_STRVAR(c_atanh_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000384"atanh(x)\n"
385"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000386"Return the hyperbolic arc tangent of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000387
388
Tim Peters14e26402001-02-20 20:15:19 +0000389static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000390c_cos(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000391{
Christian Heimes53876d92008-04-19 00:31:39 +0000392 /* cos(z) = cosh(iz) */
Guido van Rossum9e720e31996-07-21 02:31:35 +0000393 Py_complex r;
Christian Heimes53876d92008-04-19 00:31:39 +0000394 r.real = -z.imag;
395 r.imag = z.real;
396 r = c_cosh(r);
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000397 return r;
398}
399
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000400PyDoc_STRVAR(c_cos_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000401"cos(x)\n"
402"n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000403"Return the cosine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000404
405
Christian Heimes53876d92008-04-19 00:31:39 +0000406/* cosh(infinity + i*y) needs to be dealt with specially */
407static Py_complex cosh_special_values[7][7] = {
408 {{INF,N},{U,U},{INF,0.}, {INF,-0.},{U,U},{INF,N},{INF,N}},
409 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
410 {{N,0.}, {U,U},{1.,0.}, {1.,-0.}, {U,U},{N,0.}, {N,0.}},
411 {{N,0.}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,0.}, {N,0.}},
412 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
413 {{INF,N},{U,U},{INF,-0.},{INF,0.}, {U,U},{INF,N},{INF,N}},
414 {{N,N}, {N,N},{N,0.}, {N,0.}, {N,N},{N,N}, {N,N}}
415};
416
Tim Peters14e26402001-02-20 20:15:19 +0000417static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000418c_cosh(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000419{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000420 Py_complex r;
Christian Heimes53876d92008-04-19 00:31:39 +0000421 double x_minus_one;
422
423 /* special treatment for cosh(+/-inf + iy) if y is not a NaN */
424 if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
425 if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag) &&
426 (z.imag != 0.)) {
427 if (z.real > 0) {
428 r.real = copysign(INF, cos(z.imag));
429 r.imag = copysign(INF, sin(z.imag));
430 }
431 else {
432 r.real = copysign(INF, cos(z.imag));
433 r.imag = -copysign(INF, sin(z.imag));
434 }
435 }
436 else {
437 r = cosh_special_values[special_type(z.real)]
438 [special_type(z.imag)];
439 }
440 /* need to set errno = EDOM if y is +/- infinity and x is not
441 a NaN */
442 if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real))
443 errno = EDOM;
444 else
445 errno = 0;
446 return r;
447 }
448
449 if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
450 /* deal correctly with cases where cosh(z.real) overflows but
451 cosh(z) does not. */
452 x_minus_one = z.real - copysign(1., z.real);
453 r.real = cos(z.imag) * cosh(x_minus_one) * Py_MATH_E;
454 r.imag = sin(z.imag) * sinh(x_minus_one) * Py_MATH_E;
455 } else {
456 r.real = cos(z.imag) * cosh(z.real);
457 r.imag = sin(z.imag) * sinh(z.real);
458 }
459 /* detect overflow, and set errno accordingly */
460 if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
461 errno = ERANGE;
462 else
463 errno = 0;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000464 return r;
465}
466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000467PyDoc_STRVAR(c_cosh_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000468"cosh(x)\n"
469"n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000470"Return the hyperbolic cosine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000471
472
Christian Heimes53876d92008-04-19 00:31:39 +0000473/* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for
474 finite y */
475static Py_complex exp_special_values[7][7] = {
476 {{0.,0.},{U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,0.},{0.,0.}},
477 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
478 {{N,N}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,N}, {N,N}},
479 {{N,N}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{N,N}, {N,N}},
480 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
481 {{INF,N},{U,U},{INF,-0.},{INF,0.},{U,U},{INF,N},{INF,N}},
482 {{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
483};
484
Tim Peters14e26402001-02-20 20:15:19 +0000485static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000486c_exp(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000487{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000488 Py_complex r;
Christian Heimes53876d92008-04-19 00:31:39 +0000489 double l;
490
491 if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
492 if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
493 && (z.imag != 0.)) {
494 if (z.real > 0) {
495 r.real = copysign(INF, cos(z.imag));
496 r.imag = copysign(INF, sin(z.imag));
497 }
498 else {
499 r.real = copysign(0., cos(z.imag));
500 r.imag = copysign(0., sin(z.imag));
501 }
502 }
503 else {
504 r = exp_special_values[special_type(z.real)]
505 [special_type(z.imag)];
506 }
507 /* need to set errno = EDOM if y is +/- infinity and x is not
508 a NaN and not -infinity */
509 if (Py_IS_INFINITY(z.imag) &&
510 (Py_IS_FINITE(z.real) ||
511 (Py_IS_INFINITY(z.real) && z.real > 0)))
512 errno = EDOM;
513 else
514 errno = 0;
515 return r;
516 }
517
518 if (z.real > CM_LOG_LARGE_DOUBLE) {
519 l = exp(z.real-1.);
520 r.real = l*cos(z.imag)*Py_MATH_E;
521 r.imag = l*sin(z.imag)*Py_MATH_E;
522 } else {
523 l = exp(z.real);
524 r.real = l*cos(z.imag);
525 r.imag = l*sin(z.imag);
526 }
527 /* detect overflow, and set errno accordingly */
528 if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
529 errno = ERANGE;
530 else
531 errno = 0;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000532 return r;
533}
534
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000535PyDoc_STRVAR(c_exp_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000536"exp(x)\n"
537"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000538"Return the exponential value e**x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000539
540
Christian Heimes53876d92008-04-19 00:31:39 +0000541static Py_complex log_special_values[7][7] = {
542 {{INF,-P34},{INF,-P}, {INF,-P}, {INF,P}, {INF,P}, {INF,P34}, {INF,N}},
543 {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
544 {{INF,-P12},{U,U}, {-INF,-P}, {-INF,P}, {U,U}, {INF,P12}, {N,N}},
545 {{INF,-P12},{U,U}, {-INF,-0.},{-INF,0.},{U,U}, {INF,P12}, {N,N}},
546 {{INF,-P12},{U,U}, {U,U}, {U,U}, {U,U}, {INF,P12}, {N,N}},
547 {{INF,-P14},{INF,-0.},{INF,-0.}, {INF,0.}, {INF,0.},{INF,P14}, {INF,N}},
548 {{INF,N}, {N,N}, {N,N}, {N,N}, {N,N}, {INF,N}, {N,N}}
549};
550
Tim Peters14e26402001-02-20 20:15:19 +0000551static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000552c_log(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000553{
Christian Heimes53876d92008-04-19 00:31:39 +0000554 /*
555 The usual formula for the real part is log(hypot(z.real, z.imag)).
556 There are four situations where this formula is potentially
557 problematic:
558
559 (1) the absolute value of z is subnormal. Then hypot is subnormal,
560 so has fewer than the usual number of bits of accuracy, hence may
561 have large relative error. This then gives a large absolute error
562 in the log. This can be solved by rescaling z by a suitable power
563 of 2.
564
565 (2) the absolute value of z is greater than DBL_MAX (e.g. when both
566 z.real and z.imag are within a factor of 1/sqrt(2) of DBL_MAX)
567 Again, rescaling solves this.
568
569 (3) the absolute value of z is close to 1. In this case it's
570 difficult to achieve good accuracy, at least in part because a
571 change of 1ulp in the real or imaginary part of z can result in a
572 change of billions of ulps in the correctly rounded answer.
573
574 (4) z = 0. The simplest thing to do here is to call the
575 floating-point log with an argument of 0, and let its behaviour
576 (returning -infinity, signaling a floating-point exception, setting
577 errno, or whatever) determine that of c_log. So the usual formula
578 is fine here.
579
580 */
581
Guido van Rossum9e720e31996-07-21 02:31:35 +0000582 Py_complex r;
Christian Heimes53876d92008-04-19 00:31:39 +0000583 double ax, ay, am, an, h;
584
585 SPECIAL_VALUE(z, log_special_values);
586
587 ax = fabs(z.real);
588 ay = fabs(z.imag);
589
590 if (ax > CM_LARGE_DOUBLE || ay > CM_LARGE_DOUBLE) {
591 r.real = log(hypot(ax/2., ay/2.)) + M_LN2;
592 } else if (ax < DBL_MIN && ay < DBL_MIN) {
593 if (ax > 0. || ay > 0.) {
594 /* catch cases where hypot(ax, ay) is subnormal */
595 r.real = log(hypot(ldexp(ax, DBL_MANT_DIG),
596 ldexp(ay, DBL_MANT_DIG))) - DBL_MANT_DIG*M_LN2;
597 }
598 else {
599 /* log(+/-0. +/- 0i) */
600 r.real = -INF;
601 r.imag = atan2(z.imag, z.real);
602 errno = EDOM;
603 return r;
604 }
605 } else {
606 h = hypot(ax, ay);
607 if (0.71 <= h && h <= 1.73) {
608 am = ax > ay ? ax : ay; /* max(ax, ay) */
609 an = ax > ay ? ay : ax; /* min(ax, ay) */
610 r.real = log1p((am-1)*(am+1)+an*an)/2.;
611 } else {
612 r.real = log(h);
613 }
614 }
615 r.imag = atan2(z.imag, z.real);
616 errno = 0;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000617 return r;
618}
619
Guido van Rossumc6e22901998-12-04 19:26:43 +0000620
Tim Peters14e26402001-02-20 20:15:19 +0000621static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000622c_log10(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000623{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000624 Py_complex r;
Christian Heimes53876d92008-04-19 00:31:39 +0000625 int errno_save;
626
627 r = c_log(z);
628 errno_save = errno; /* just in case the divisions affect errno */
629 r.real = r.real / M_LN10;
630 r.imag = r.imag / M_LN10;
631 errno = errno_save;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000632 return r;
633}
634
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000635PyDoc_STRVAR(c_log10_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000636"log10(x)\n"
637"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000638"Return the base-10 logarithm of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000639
640
Tim Peters14e26402001-02-20 20:15:19 +0000641static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000642c_sin(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000643{
Christian Heimes53876d92008-04-19 00:31:39 +0000644 /* sin(z) = -i sin(iz) */
645 Py_complex s, r;
646 s.real = -z.imag;
647 s.imag = z.real;
648 s = c_sinh(s);
649 r.real = s.imag;
650 r.imag = -s.real;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000651 return r;
652}
653
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000654PyDoc_STRVAR(c_sin_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000655"sin(x)\n"
656"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000657"Return the sine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000658
659
Christian Heimes53876d92008-04-19 00:31:39 +0000660/* sinh(infinity + i*y) needs to be dealt with specially */
661static Py_complex sinh_special_values[7][7] = {
662 {{INF,N},{U,U},{-INF,-0.},{-INF,0.},{U,U},{INF,N},{INF,N}},
663 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
664 {{0.,N}, {U,U},{-0.,-0.}, {-0.,0.}, {U,U},{0.,N}, {0.,N}},
665 {{0.,N}, {U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,N}, {0.,N}},
666 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
667 {{INF,N},{U,U},{INF,-0.}, {INF,0.}, {U,U},{INF,N},{INF,N}},
668 {{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
669};
670
Tim Peters14e26402001-02-20 20:15:19 +0000671static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000672c_sinh(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000673{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000674 Py_complex r;
Christian Heimes53876d92008-04-19 00:31:39 +0000675 double x_minus_one;
676
677 /* special treatment for sinh(+/-inf + iy) if y is finite and
678 nonzero */
679 if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
680 if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
681 && (z.imag != 0.)) {
682 if (z.real > 0) {
683 r.real = copysign(INF, cos(z.imag));
684 r.imag = copysign(INF, sin(z.imag));
685 }
686 else {
687 r.real = -copysign(INF, cos(z.imag));
688 r.imag = copysign(INF, sin(z.imag));
689 }
690 }
691 else {
692 r = sinh_special_values[special_type(z.real)]
693 [special_type(z.imag)];
694 }
695 /* need to set errno = EDOM if y is +/- infinity and x is not
696 a NaN */
697 if (Py_IS_INFINITY(z.imag) && !Py_IS_NAN(z.real))
698 errno = EDOM;
699 else
700 errno = 0;
701 return r;
702 }
703
704 if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
705 x_minus_one = z.real - copysign(1., z.real);
706 r.real = cos(z.imag) * sinh(x_minus_one) * Py_MATH_E;
707 r.imag = sin(z.imag) * cosh(x_minus_one) * Py_MATH_E;
708 } else {
709 r.real = cos(z.imag) * sinh(z.real);
710 r.imag = sin(z.imag) * cosh(z.real);
711 }
712 /* detect overflow, and set errno accordingly */
713 if (Py_IS_INFINITY(r.real) || Py_IS_INFINITY(r.imag))
714 errno = ERANGE;
715 else
716 errno = 0;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000717 return r;
718}
719
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000720PyDoc_STRVAR(c_sinh_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000721"sinh(x)\n"
722"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000723"Return the hyperbolic sine of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000724
725
Christian Heimes53876d92008-04-19 00:31:39 +0000726static Py_complex sqrt_special_values[7][7] = {
727 {{INF,-INF},{0.,-INF},{0.,-INF},{0.,INF},{0.,INF},{INF,INF},{N,INF}},
728 {{INF,-INF},{U,U}, {U,U}, {U,U}, {U,U}, {INF,INF},{N,N}},
729 {{INF,-INF},{U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,INF},{N,N}},
730 {{INF,-INF},{U,U}, {0.,-0.}, {0.,0.}, {U,U}, {INF,INF},{N,N}},
731 {{INF,-INF},{U,U}, {U,U}, {U,U}, {U,U}, {INF,INF},{N,N}},
732 {{INF,-INF},{INF,-0.},{INF,-0.},{INF,0.},{INF,0.},{INF,INF},{INF,N}},
733 {{INF,-INF},{N,N}, {N,N}, {N,N}, {N,N}, {INF,INF},{N,N}}
734};
735
Tim Peters14e26402001-02-20 20:15:19 +0000736static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000737c_sqrt(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000738{
Christian Heimes53876d92008-04-19 00:31:39 +0000739 /*
740 Method: use symmetries to reduce to the case when x = z.real and y
741 = z.imag are nonnegative. Then the real part of the result is
742 given by
743
744 s = sqrt((x + hypot(x, y))/2)
745
746 and the imaginary part is
747
748 d = (y/2)/s
749
750 If either x or y is very large then there's a risk of overflow in
751 computation of the expression x + hypot(x, y). We can avoid this
752 by rewriting the formula for s as:
753
754 s = 2*sqrt(x/8 + hypot(x/8, y/8))
755
756 This costs us two extra multiplications/divisions, but avoids the
757 overhead of checking for x and y large.
758
759 If both x and y are subnormal then hypot(x, y) may also be
760 subnormal, so will lack full precision. We solve this by rescaling
761 x and y by a sufficiently large power of 2 to ensure that x and y
762 are normal.
763 */
764
765
Guido van Rossum9e720e31996-07-21 02:31:35 +0000766 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000767 double s,d;
Christian Heimes53876d92008-04-19 00:31:39 +0000768 double ax, ay;
769
770 SPECIAL_VALUE(z, sqrt_special_values);
771
772 if (z.real == 0. && z.imag == 0.) {
773 r.real = 0.;
774 r.imag = z.imag;
775 return r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000776 }
Christian Heimes53876d92008-04-19 00:31:39 +0000777
778 ax = fabs(z.real);
779 ay = fabs(z.imag);
780
781 if (ax < DBL_MIN && ay < DBL_MIN && (ax > 0. || ay > 0.)) {
782 /* here we catch cases where hypot(ax, ay) is subnormal */
783 ax = ldexp(ax, CM_SCALE_UP);
784 s = ldexp(sqrt(ax + hypot(ax, ldexp(ay, CM_SCALE_UP))),
785 CM_SCALE_DOWN);
786 } else {
787 ax /= 8.;
788 s = 2.*sqrt(ax + hypot(ax, ay/8.));
789 }
790 d = ay/(2.*s);
791
792 if (z.real >= 0.) {
793 r.real = s;
794 r.imag = copysign(d, z.imag);
795 } else {
796 r.real = d;
797 r.imag = copysign(s, z.imag);
798 }
799 errno = 0;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000800 return r;
801}
802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000803PyDoc_STRVAR(c_sqrt_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000804"sqrt(x)\n"
805"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000806"Return the square root of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000807
808
Tim Peters14e26402001-02-20 20:15:19 +0000809static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000810c_tan(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000811{
Christian Heimes53876d92008-04-19 00:31:39 +0000812 /* tan(z) = -i tanh(iz) */
813 Py_complex s, r;
814 s.real = -z.imag;
815 s.imag = z.real;
816 s = c_tanh(s);
817 r.real = s.imag;
818 r.imag = -s.real;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000819 return r;
820}
821
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000822PyDoc_STRVAR(c_tan_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000823"tan(x)\n"
824"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000825"Return the tangent of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000826
827
Christian Heimes53876d92008-04-19 00:31:39 +0000828/* tanh(infinity + i*y) needs to be dealt with specially */
829static Py_complex tanh_special_values[7][7] = {
830 {{-1.,0.},{U,U},{-1.,-0.},{-1.,0.},{U,U},{-1.,0.},{-1.,0.}},
831 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
832 {{N,N}, {U,U},{-0.,-0.},{-0.,0.},{U,U},{N,N}, {N,N}},
833 {{N,N}, {U,U},{0.,-0.}, {0.,0.}, {U,U},{N,N}, {N,N}},
834 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
835 {{1.,0.}, {U,U},{1.,-0.}, {1.,0.}, {U,U},{1.,0.}, {1.,0.}},
836 {{N,N}, {N,N},{N,-0.}, {N,0.}, {N,N},{N,N}, {N,N}}
837};
838
Tim Peters14e26402001-02-20 20:15:19 +0000839static Py_complex
Christian Heimes53876d92008-04-19 00:31:39 +0000840c_tanh(Py_complex z)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000841{
Christian Heimes53876d92008-04-19 00:31:39 +0000842 /* Formula:
843
844 tanh(x+iy) = (tanh(x)(1+tan(y)^2) + i tan(y)(1-tanh(x))^2) /
845 (1+tan(y)^2 tanh(x)^2)
846
847 To avoid excessive roundoff error, 1-tanh(x)^2 is better computed
848 as 1/cosh(x)^2. When abs(x) is large, we approximate 1-tanh(x)^2
849 by 4 exp(-2*x) instead, to avoid possible overflow in the
850 computation of cosh(x).
851
852 */
853
Guido van Rossum9e720e31996-07-21 02:31:35 +0000854 Py_complex r;
Christian Heimes53876d92008-04-19 00:31:39 +0000855 double tx, ty, cx, txty, denom;
856
857 /* special treatment for tanh(+/-inf + iy) if y is finite and
858 nonzero */
859 if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) {
860 if (Py_IS_INFINITY(z.real) && Py_IS_FINITE(z.imag)
861 && (z.imag != 0.)) {
862 if (z.real > 0) {
863 r.real = 1.0;
864 r.imag = copysign(0.,
865 2.*sin(z.imag)*cos(z.imag));
866 }
867 else {
868 r.real = -1.0;
869 r.imag = copysign(0.,
870 2.*sin(z.imag)*cos(z.imag));
871 }
872 }
873 else {
874 r = tanh_special_values[special_type(z.real)]
875 [special_type(z.imag)];
876 }
877 /* need to set errno = EDOM if z.imag is +/-infinity and
878 z.real is finite */
879 if (Py_IS_INFINITY(z.imag) && Py_IS_FINITE(z.real))
880 errno = EDOM;
881 else
882 errno = 0;
883 return r;
884 }
885
886 /* danger of overflow in 2.*z.imag !*/
887 if (fabs(z.real) > CM_LOG_LARGE_DOUBLE) {
888 r.real = copysign(1., z.real);
889 r.imag = 4.*sin(z.imag)*cos(z.imag)*exp(-2.*fabs(z.real));
890 } else {
891 tx = tanh(z.real);
892 ty = tan(z.imag);
893 cx = 1./cosh(z.real);
894 txty = tx*ty;
895 denom = 1. + txty*txty;
896 r.real = tx*(1.+ty*ty)/denom;
897 r.imag = ((ty/denom)*cx)*cx;
898 }
899 errno = 0;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000900 return r;
901}
902
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000903PyDoc_STRVAR(c_tanh_doc,
Tim Peters14e26402001-02-20 20:15:19 +0000904"tanh(x)\n"
905"\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000906"Return the hyperbolic tangent of x.");
Guido van Rossumc6e22901998-12-04 19:26:43 +0000907
Christian Heimes53876d92008-04-19 00:31:39 +0000908
Raymond Hettingerb67ad7e2004-06-14 07:40:10 +0000909static PyObject *
910cmath_log(PyObject *self, PyObject *args)
911{
912 Py_complex x;
913 Py_complex y;
914
915 if (!PyArg_ParseTuple(args, "D|D", &x, &y))
916 return NULL;
917
918 errno = 0;
919 PyFPE_START_PROTECT("complex function", return 0)
920 x = c_log(x);
921 if (PyTuple_GET_SIZE(args) == 2)
922 x = c_quot(x, c_log(y));
923 PyFPE_END_PROTECT(x)
924 if (errno != 0)
925 return math_error();
Raymond Hettingerb67ad7e2004-06-14 07:40:10 +0000926 return PyComplex_FromCComplex(x);
927}
928
929PyDoc_STRVAR(cmath_log_doc,
930"log(x[, base]) -> the logarithm of x to the given base.\n\
931If the base not specified, returns the natural logarithm (base e) of x.");
932
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000933
934/* And now the glue to make them available from Python: */
935
Roger E. Masse24070ca1996-12-09 22:59:53 +0000936static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000937math_error(void)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000938{
939 if (errno == EDOM)
Roger E. Masse24070ca1996-12-09 22:59:53 +0000940 PyErr_SetString(PyExc_ValueError, "math domain error");
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000941 else if (errno == ERANGE)
Roger E. Masse24070ca1996-12-09 22:59:53 +0000942 PyErr_SetString(PyExc_OverflowError, "math range error");
943 else /* Unexpected math error */
Tim Peters14e26402001-02-20 20:15:19 +0000944 PyErr_SetFromErrno(PyExc_ValueError);
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000945 return NULL;
946}
947
Roger E. Masse24070ca1996-12-09 22:59:53 +0000948static PyObject *
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000949math_1(PyObject *args, Py_complex (*func)(Py_complex))
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000950{
Christian Heimes53876d92008-04-19 00:31:39 +0000951 Py_complex x,r ;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000952 if (!PyArg_ParseTuple(args, "D", &x))
953 return NULL;
954 errno = 0;
Christian Heimes53876d92008-04-19 00:31:39 +0000955 PyFPE_START_PROTECT("complex function", return 0);
956 r = (*func)(x);
957 PyFPE_END_PROTECT(r);
958 if (errno == EDOM) {
959 PyErr_SetString(PyExc_ValueError, "math domain error");
960 return NULL;
961 }
962 else if (errno == ERANGE) {
963 PyErr_SetString(PyExc_OverflowError, "math range error");
964 return NULL;
965 }
966 else {
967 return PyComplex_FromCComplex(r);
968 }
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000969}
970
971#define FUNC1(stubname, func) \
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000972 static PyObject * stubname(PyObject *self, PyObject *args) { \
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000973 return math_1(args, func); \
974 }
975
976FUNC1(cmath_acos, c_acos)
977FUNC1(cmath_acosh, c_acosh)
978FUNC1(cmath_asin, c_asin)
979FUNC1(cmath_asinh, c_asinh)
980FUNC1(cmath_atan, c_atan)
981FUNC1(cmath_atanh, c_atanh)
982FUNC1(cmath_cos, c_cos)
983FUNC1(cmath_cosh, c_cosh)
984FUNC1(cmath_exp, c_exp)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000985FUNC1(cmath_log10, c_log10)
986FUNC1(cmath_sin, c_sin)
987FUNC1(cmath_sinh, c_sinh)
988FUNC1(cmath_sqrt, c_sqrt)
989FUNC1(cmath_tan, c_tan)
990FUNC1(cmath_tanh, c_tanh)
991
Christian Heimes53876d92008-04-19 00:31:39 +0000992static PyObject *
993cmath_phase(PyObject *self, PyObject *args)
994{
995 Py_complex z;
996 double phi;
997 if (!PyArg_ParseTuple(args, "D:phase", &z))
998 return NULL;
999 errno = 0;
1000 PyFPE_START_PROTECT("arg function", return 0)
1001 phi = c_atan2(z);
1002 PyFPE_END_PROTECT(r)
1003 if (errno != 0)
1004 return math_error();
1005 else
1006 return PyFloat_FromDouble(phi);
1007}
1008
1009PyDoc_STRVAR(cmath_phase_doc,
1010"phase(z) -> float\n\n\
1011Return argument, also known as the phase angle, of a complex.");
1012
1013static PyObject *
1014cmath_polar(PyObject *self, PyObject *args)
1015{
1016 Py_complex z;
1017 double r, phi;
1018 if (!PyArg_ParseTuple(args, "D:polar", &z))
1019 return NULL;
1020 PyFPE_START_PROTECT("polar function", return 0)
1021 phi = c_atan2(z); /* should not cause any exception */
1022 r = c_abs(z); /* sets errno to ERANGE on overflow; otherwise 0 */
1023 PyFPE_END_PROTECT(r)
1024 if (errno != 0)
1025 return math_error();
1026 else
1027 return Py_BuildValue("dd", r, phi);
1028}
1029
1030PyDoc_STRVAR(cmath_polar_doc,
1031"polar(z) -> r: float, phi: float\n\n\
1032Convert a complex from rectangular coordinates to polar coordinates. r is\n\
1033the distance from 0 and phi the phase angle.");
1034
1035/*
1036 rect() isn't covered by the C99 standard, but it's not too hard to
1037 figure out 'spirit of C99' rules for special value handing:
1038
1039 rect(x, t) should behave like exp(log(x) + it) for positive-signed x
1040 rect(x, t) should behave like -exp(log(-x) + it) for negative-signed x
1041 rect(nan, t) should behave like exp(nan + it), except that rect(nan, 0)
1042 gives nan +- i0 with the sign of the imaginary part unspecified.
1043
1044*/
1045
1046static Py_complex rect_special_values[7][7] = {
1047 {{INF,N},{U,U},{-INF,0.},{-INF,-0.},{U,U},{INF,N},{INF,N}},
1048 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
1049 {{0.,0.},{U,U},{-0.,0.}, {-0.,-0.}, {U,U},{0.,0.},{0.,0.}},
1050 {{0.,0.},{U,U},{0.,-0.}, {0.,0.}, {U,U},{0.,0.},{0.,0.}},
1051 {{N,N}, {U,U},{U,U}, {U,U}, {U,U},{N,N}, {N,N}},
1052 {{INF,N},{U,U},{INF,-0.},{INF,0.}, {U,U},{INF,N},{INF,N}},
1053 {{N,N}, {N,N},{N,0.}, {N,0.}, {N,N},{N,N}, {N,N}}
1054};
1055
1056static PyObject *
1057cmath_rect(PyObject *self, PyObject *args)
1058{
1059 Py_complex z;
1060 double r, phi;
1061 if (!PyArg_ParseTuple(args, "dd:rect", &r, &phi))
1062 return NULL;
1063 errno = 0;
1064 PyFPE_START_PROTECT("rect function", return 0)
1065
1066 /* deal with special values */
1067 if (!Py_IS_FINITE(r) || !Py_IS_FINITE(phi)) {
1068 /* if r is +/-infinity and phi is finite but nonzero then
1069 result is (+-INF +-INF i), but we need to compute cos(phi)
1070 and sin(phi) to figure out the signs. */
1071 if (Py_IS_INFINITY(r) && (Py_IS_FINITE(phi)
1072 && (phi != 0.))) {
1073 if (r > 0) {
1074 z.real = copysign(INF, cos(phi));
1075 z.imag = copysign(INF, sin(phi));
1076 }
1077 else {
1078 z.real = -copysign(INF, cos(phi));
1079 z.imag = -copysign(INF, sin(phi));
1080 }
1081 }
1082 else {
1083 z = rect_special_values[special_type(r)]
1084 [special_type(phi)];
1085 }
1086 /* need to set errno = EDOM if r is a nonzero number and phi
1087 is infinite */
1088 if (r != 0. && !Py_IS_NAN(r) && Py_IS_INFINITY(phi))
1089 errno = EDOM;
1090 else
1091 errno = 0;
1092 }
1093 else {
1094 z.real = r * cos(phi);
1095 z.imag = r * sin(phi);
1096 errno = 0;
1097 }
1098
1099 PyFPE_END_PROTECT(z)
1100 if (errno != 0)
1101 return math_error();
1102 else
1103 return PyComplex_FromCComplex(z);
1104}
1105
1106PyDoc_STRVAR(cmath_rect_doc,
1107"rect(r, phi) -> z: complex\n\n\
1108Convert from polar coordinates to rectangular coordinates.");
1109
1110static PyObject *
1111cmath_isnan(PyObject *self, PyObject *args)
1112{
1113 Py_complex z;
1114 if (!PyArg_ParseTuple(args, "D:isnan", &z))
1115 return NULL;
1116 return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag));
1117}
1118
1119PyDoc_STRVAR(cmath_isnan_doc,
1120"isnan(z) -> bool\n\
1121Checks if the real or imaginary part of z not a number (NaN)");
1122
1123static PyObject *
1124cmath_isinf(PyObject *self, PyObject *args)
1125{
1126 Py_complex z;
1127 if (!PyArg_ParseTuple(args, "D:isnan", &z))
1128 return NULL;
1129 return PyBool_FromLong(Py_IS_INFINITY(z.real) ||
1130 Py_IS_INFINITY(z.imag));
1131}
1132
1133PyDoc_STRVAR(cmath_isinf_doc,
1134"isinf(z) -> bool\n\
1135Checks if the real or imaginary part of z is infinite.");
1136
Guido van Rossum71aa32f1996-01-12 01:34:57 +00001137
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001138PyDoc_STRVAR(module_doc,
Tim Peters14e26402001-02-20 20:15:19 +00001139"This module is always available. It provides access to mathematical\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001140"functions for complex numbers.");
Guido van Rossumc6e22901998-12-04 19:26:43 +00001141
Roger E. Masse24070ca1996-12-09 22:59:53 +00001142static PyMethodDef cmath_methods[] = {
Tim Peters14e26402001-02-20 20:15:19 +00001143 {"acos", cmath_acos, METH_VARARGS, c_acos_doc},
1144 {"acosh", cmath_acosh, METH_VARARGS, c_acosh_doc},
1145 {"asin", cmath_asin, METH_VARARGS, c_asin_doc},
1146 {"asinh", cmath_asinh, METH_VARARGS, c_asinh_doc},
1147 {"atan", cmath_atan, METH_VARARGS, c_atan_doc},
1148 {"atanh", cmath_atanh, METH_VARARGS, c_atanh_doc},
1149 {"cos", cmath_cos, METH_VARARGS, c_cos_doc},
1150 {"cosh", cmath_cosh, METH_VARARGS, c_cosh_doc},
1151 {"exp", cmath_exp, METH_VARARGS, c_exp_doc},
Christian Heimes53876d92008-04-19 00:31:39 +00001152 {"isinf", cmath_isinf, METH_VARARGS, cmath_isinf_doc},
1153 {"isnan", cmath_isnan, METH_VARARGS, cmath_isnan_doc},
Raymond Hettingerb67ad7e2004-06-14 07:40:10 +00001154 {"log", cmath_log, METH_VARARGS, cmath_log_doc},
Tim Peters14e26402001-02-20 20:15:19 +00001155 {"log10", cmath_log10, METH_VARARGS, c_log10_doc},
Christian Heimes53876d92008-04-19 00:31:39 +00001156 {"phase", cmath_phase, METH_VARARGS, cmath_phase_doc},
1157 {"polar", cmath_polar, METH_VARARGS, cmath_polar_doc},
1158 {"rect", cmath_rect, METH_VARARGS, cmath_rect_doc},
Tim Peters14e26402001-02-20 20:15:19 +00001159 {"sin", cmath_sin, METH_VARARGS, c_sin_doc},
1160 {"sinh", cmath_sinh, METH_VARARGS, c_sinh_doc},
1161 {"sqrt", cmath_sqrt, METH_VARARGS, c_sqrt_doc},
1162 {"tan", cmath_tan, METH_VARARGS, c_tan_doc},
1163 {"tanh", cmath_tanh, METH_VARARGS, c_tanh_doc},
Guido van Rossum71aa32f1996-01-12 01:34:57 +00001164 {NULL, NULL} /* sentinel */
1165};
1166
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001167PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001168initcmath(void)
Guido van Rossum71aa32f1996-01-12 01:34:57 +00001169{
Fred Drakef4e34842002-04-01 03:45:06 +00001170 PyObject *m;
Tim Peters14e26402001-02-20 20:15:19 +00001171
Guido van Rossumc6e22901998-12-04 19:26:43 +00001172 m = Py_InitModule3("cmath", cmath_methods, module_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00001173 if (m == NULL)
1174 return;
Fred Drakef4e34842002-04-01 03:45:06 +00001175
1176 PyModule_AddObject(m, "pi",
Christian Heimes53876d92008-04-19 00:31:39 +00001177 PyFloat_FromDouble(Py_MATH_PI));
1178 PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
Guido van Rossum71aa32f1996-01-12 01:34:57 +00001179}