blob: b6a65857610dd64228685e52d2666134824aef51 [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"
Guido van Rossum71aa32f1996-01-12 01:34:57 +00006
Guido van Rossum71aa32f1996-01-12 01:34:57 +00007#include "mymath.h"
8
9#ifdef i860
10/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
11#undef HUGE_VAL
12#endif
13
14#ifdef HUGE_VAL
15#define CHECK(x) if (errno != 0) ; \
16 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
17 else errno = ERANGE
18#else
19#define CHECK(x) /* Don't know how to check */
20#endif
21
22#ifndef M_PI
23#define M_PI (3.141592653589793239)
24#endif
25
26/* First, the C functions that do the real work */
27
28/* constants */
Guido van Rossum9e720e31996-07-21 02:31:35 +000029static Py_complex c_1 = {1., 0.};
30static Py_complex c_half = {0.5, 0.};
31static Py_complex c_i = {0., 1.};
32static Py_complex c_i2 = {0., 0.5};
Guido van Rossuma376cc51996-12-05 23:43:35 +000033#if 0
Guido van Rossum9e720e31996-07-21 02:31:35 +000034static Py_complex c_mi = {0., -1.};
35static Py_complex c_pi2 = {M_PI/2., 0.};
Guido van Rossuma376cc51996-12-05 23:43:35 +000036#endif
Guido van Rossum71aa32f1996-01-12 01:34:57 +000037
38/* forward declarations */
Guido van Rossum9e720e31996-07-21 02:31:35 +000039staticforward Py_complex c_log();
40staticforward Py_complex c_prodi();
41staticforward Py_complex c_sqrt();
Guido van Rossum71aa32f1996-01-12 01:34:57 +000042
43
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +000044static Py_complex c_acos(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +000045{
46 return c_neg(c_prodi(c_log(c_sum(x,c_prod(c_i,
47 c_sqrt(c_diff(c_1,c_prod(x,x))))))));
48}
49
Guido van Rossumc6e22901998-12-04 19:26:43 +000050static char c_acos_doc [] =
51"acos(x)\n\
52\n\
53Return the arc cosine of x.";
54
55
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +000056static Py_complex c_acosh(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +000057{
Guido van Rossumf385c5e2000-06-30 02:29:22 +000058 Py_complex z;
59 z = c_sqrt(c_half);
60 z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x,c_1)),
61 c_sqrt(c_diff(x,c_1)))));
62 return c_sum(z, z);
Guido van Rossum71aa32f1996-01-12 01:34:57 +000063}
64
Guido van Rossumc6e22901998-12-04 19:26:43 +000065static char c_acosh_doc [] =
66"acosh(x)\n\
67\n\
Fred Drake0e11c491999-03-16 14:17:48 +000068Return the hyperbolic arccosine of x.";
Guido van Rossumc6e22901998-12-04 19:26:43 +000069
70
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +000071static Py_complex c_asin(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +000072{
Guido van Rossumf385c5e2000-06-30 02:29:22 +000073 Py_complex z;
74 z = c_sqrt(c_half);
75 z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x,c_i)),
76 c_sqrt(c_diff(x,c_i)))));
77 return c_sum(z, z);
Guido van Rossum71aa32f1996-01-12 01:34:57 +000078}
79
Guido van Rossumc6e22901998-12-04 19:26:43 +000080static char c_asin_doc [] =
81"asin(x)\n\
82\n\
83Return the arc sine of x.";
84
85
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +000086static Py_complex c_asinh(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +000087{
Guido van Rossum11a50711999-01-14 19:11:11 +000088 /* Break up long expression for WATCOM */
89 Py_complex z;
Guido van Rossumf385c5e2000-06-30 02:29:22 +000090 z = c_sum(c_1,c_prod(x, x));
91 return c_log(c_sum(c_sqrt(z), x));
Guido van Rossum71aa32f1996-01-12 01:34:57 +000092}
93
Guido van Rossumc6e22901998-12-04 19:26:43 +000094static char c_asinh_doc [] =
95"asinh(x)\n\
96\n\
97Return the hyperbolic arc sine of x.";
98
99
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000100static Py_complex c_atan(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000101{
102 return c_prod(c_i2,c_log(c_quot(c_sum(c_i,x),c_diff(c_i,x))));
103}
104
Guido van Rossumc6e22901998-12-04 19:26:43 +0000105static char c_atan_doc [] =
106"atan(x)\n\
107\n\
108Return the arc tangent of x.";
109
110
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000111static Py_complex c_atanh(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000112{
113 return c_prod(c_half,c_log(c_quot(c_sum(c_1,x),c_diff(c_1,x))));
114}
115
Guido van Rossumc6e22901998-12-04 19:26:43 +0000116static char c_atanh_doc [] =
117"atanh(x)\n\
118\n\
119Return the hyperbolic arc tangent of x.";
120
121
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000122static Py_complex c_cos(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000123{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000124 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000125 r.real = cos(x.real)*cosh(x.imag);
126 r.imag = -sin(x.real)*sinh(x.imag);
127 return r;
128}
129
Guido van Rossumc6e22901998-12-04 19:26:43 +0000130static char c_cos_doc [] =
131"cos(x)\n\
132\n\
133Return the cosine of x.";
134
135
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000136static Py_complex c_cosh(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000137{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000138 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000139 r.real = cos(x.imag)*cosh(x.real);
140 r.imag = sin(x.imag)*sinh(x.real);
141 return r;
142}
143
Guido van Rossumc6e22901998-12-04 19:26:43 +0000144static char c_cosh_doc [] =
145"cosh(x)\n\
146\n\
147Return the hyperbolic cosine of x.";
148
149
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000150static Py_complex c_exp(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000151{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000152 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000153 double l = exp(x.real);
154 r.real = l*cos(x.imag);
155 r.imag = l*sin(x.imag);
156 return r;
157}
158
Guido van Rossumc6e22901998-12-04 19:26:43 +0000159static char c_exp_doc [] =
160"exp(x)\n\
161\n\
162Return the exponential value e**x.";
163
164
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000165static Py_complex c_log(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000166{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000167 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000168 double l = hypot(x.real,x.imag);
169 r.imag = atan2(x.imag, x.real);
170 r.real = log(l);
171 return r;
172}
173
Guido van Rossumc6e22901998-12-04 19:26:43 +0000174static char c_log_doc [] =
175"log(x)\n\
176\n\
177Return the natural logarithm of x.";
178
179
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000180static Py_complex c_log10(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000181{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000182 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000183 double l = hypot(x.real,x.imag);
184 r.imag = atan2(x.imag, x.real)/log(10.);
185 r.real = log10(l);
186 return r;
187}
188
Guido van Rossumc6e22901998-12-04 19:26:43 +0000189static char c_log10_doc [] =
190"log10(x)\n\
191\n\
192Return the base-10 logarithm of x.";
193
194
195/* internal function not available from Python */
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000196static Py_complex c_prodi(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000197{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000198 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000199 r.real = -x.imag;
200 r.imag = x.real;
201 return r;
202}
203
Guido van Rossumc6e22901998-12-04 19:26:43 +0000204
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000205static Py_complex c_sin(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000206{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000207 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000208 r.real = sin(x.real)*cosh(x.imag);
209 r.imag = cos(x.real)*sinh(x.imag);
210 return r;
211}
212
Guido van Rossumc6e22901998-12-04 19:26:43 +0000213static char c_sin_doc [] =
214"sin(x)\n\
215\n\
216Return the sine of x.";
217
218
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000219static Py_complex c_sinh(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000220{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000221 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000222 r.real = cos(x.imag)*sinh(x.real);
223 r.imag = sin(x.imag)*cosh(x.real);
224 return r;
225}
226
Guido van Rossumc6e22901998-12-04 19:26:43 +0000227static char c_sinh_doc [] =
228"sinh(x)\n\
229\n\
230Return the hyperbolic sine of x.";
231
232
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000233static Py_complex c_sqrt(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000234{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000235 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000236 double s,d;
237 if (x.real == 0. && x.imag == 0.)
238 r = x;
239 else {
240 s = sqrt(0.5*(fabs(x.real) + hypot(x.real,x.imag)));
241 d = 0.5*x.imag/s;
242 if (x.real > 0.) {
243 r.real = s;
244 r.imag = d;
245 }
246 else if (x.imag >= 0.) {
247 r.real = d;
248 r.imag = s;
249 }
250 else {
251 r.real = -d;
252 r.imag = -s;
253 }
254 }
255 return r;
256}
257
Guido van Rossumc6e22901998-12-04 19:26:43 +0000258static char c_sqrt_doc [] =
259"sqrt(x)\n\
260\n\
261Return the square root of x.";
262
263
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000264static Py_complex c_tan(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000265{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000266 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000267 double sr,cr,shi,chi;
268 double rs,is,rc,ic;
269 double d;
270 sr = sin(x.real);
271 cr = cos(x.real);
272 shi = sinh(x.imag);
273 chi = cosh(x.imag);
274 rs = sr*chi;
275 is = cr*shi;
276 rc = cr*chi;
277 ic = -sr*shi;
278 d = rc*rc + ic*ic;
279 r.real = (rs*rc+is*ic)/d;
280 r.imag = (is*rc-rs*ic)/d;
281 return r;
282}
283
Guido van Rossumc6e22901998-12-04 19:26:43 +0000284static char c_tan_doc [] =
285"tan(x)\n\
286\n\
287Return the tangent of x.";
288
289
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000290static Py_complex c_tanh(Py_complex x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000291{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000292 Py_complex r;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000293 double si,ci,shr,chr;
294 double rs,is,rc,ic;
295 double d;
296 si = sin(x.imag);
297 ci = cos(x.imag);
298 shr = sinh(x.real);
299 chr = cosh(x.real);
300 rs = ci*shr;
301 is = si*chr;
302 rc = ci*chr;
303 ic = si*shr;
304 d = rc*rc + ic*ic;
305 r.real = (rs*rc+is*ic)/d;
306 r.imag = (is*rc-rs*ic)/d;
307 return r;
308}
309
Guido van Rossumc6e22901998-12-04 19:26:43 +0000310static char c_tanh_doc [] =
311"tanh(x)\n\
312\n\
313Return the hyperbolic tangent of x.";
314
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000315
316/* And now the glue to make them available from Python: */
317
Roger E. Masse24070ca1996-12-09 22:59:53 +0000318static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000319math_error(void)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000320{
321 if (errno == EDOM)
Roger E. Masse24070ca1996-12-09 22:59:53 +0000322 PyErr_SetString(PyExc_ValueError, "math domain error");
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000323 else if (errno == ERANGE)
Roger E. Masse24070ca1996-12-09 22:59:53 +0000324 PyErr_SetString(PyExc_OverflowError, "math range error");
325 else /* Unexpected math error */
326 PyErr_SetFromErrno(PyExc_ValueError);
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000327 return NULL;
328}
329
Roger E. Masse24070ca1996-12-09 22:59:53 +0000330static PyObject *
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000331math_1(PyObject *args, Py_complex (*func)(Py_complex))
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000332{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000333 Py_complex x;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000334 if (!PyArg_ParseTuple(args, "D", &x))
335 return NULL;
336 errno = 0;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000337 PyFPE_START_PROTECT("complex function", return 0)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000338 x = (*func)(x);
Guido van Rossum45b83911997-03-14 04:32:50 +0000339 PyFPE_END_PROTECT(x)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000340 CHECK(x.real);
341 CHECK(x.imag);
342 if (errno != 0)
343 return math_error();
344 else
Roger E. Masse24070ca1996-12-09 22:59:53 +0000345 return PyComplex_FromCComplex(x);
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000346}
347
348#define FUNC1(stubname, func) \
Peter Schneider-Kampf1ca8982000-07-10 09:31:34 +0000349 static PyObject * stubname(PyObject *self, PyObject *args) { \
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000350 return math_1(args, func); \
351 }
352
353FUNC1(cmath_acos, c_acos)
354FUNC1(cmath_acosh, c_acosh)
355FUNC1(cmath_asin, c_asin)
356FUNC1(cmath_asinh, c_asinh)
357FUNC1(cmath_atan, c_atan)
358FUNC1(cmath_atanh, c_atanh)
359FUNC1(cmath_cos, c_cos)
360FUNC1(cmath_cosh, c_cosh)
361FUNC1(cmath_exp, c_exp)
362FUNC1(cmath_log, c_log)
363FUNC1(cmath_log10, c_log10)
364FUNC1(cmath_sin, c_sin)
365FUNC1(cmath_sinh, c_sinh)
366FUNC1(cmath_sqrt, c_sqrt)
367FUNC1(cmath_tan, c_tan)
368FUNC1(cmath_tanh, c_tanh)
369
370
Guido van Rossumc6e22901998-12-04 19:26:43 +0000371static char module_doc [] =
372"This module is always available. It provides access to mathematical\n\
373functions for complex numbers.";
374
375
Roger E. Masse24070ca1996-12-09 22:59:53 +0000376static PyMethodDef cmath_methods[] = {
Guido van Rossumc6e22901998-12-04 19:26:43 +0000377 {"acos", cmath_acos, 1, c_acos_doc},
378 {"acosh", cmath_acosh, 1, c_acosh_doc},
379 {"asin", cmath_asin, 1, c_asin_doc},
380 {"asinh", cmath_asinh, 1, c_asinh_doc},
381 {"atan", cmath_atan, 1, c_atan_doc},
382 {"atanh", cmath_atanh, 1, c_atanh_doc},
383 {"cos", cmath_cos, 1, c_cos_doc},
384 {"cosh", cmath_cosh, 1, c_cosh_doc},
385 {"exp", cmath_exp, 1, c_exp_doc},
386 {"log", cmath_log, 1, c_log_doc},
387 {"log10", cmath_log10, 1, c_log10_doc},
388 {"sin", cmath_sin, 1, c_sin_doc},
389 {"sinh", cmath_sinh, 1, c_sinh_doc},
390 {"sqrt", cmath_sqrt, 1, c_sqrt_doc},
391 {"tan", cmath_tan, 1, c_tan_doc},
392 {"tanh", cmath_tanh, 1, c_tanh_doc},
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000393 {NULL, NULL} /* sentinel */
394};
395
Guido van Rossum3886bb61998-12-04 18:50:17 +0000396DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000397initcmath(void)
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000398{
Roger E. Masse24070ca1996-12-09 22:59:53 +0000399 PyObject *m, *d, *v;
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000400
Guido van Rossumc6e22901998-12-04 19:26:43 +0000401 m = Py_InitModule3("cmath", cmath_methods, module_doc);
Roger E. Masse24070ca1996-12-09 22:59:53 +0000402 d = PyModule_GetDict(m);
403 PyDict_SetItemString(d, "pi",
404 v = PyFloat_FromDouble(atan(1.0) * 4.0));
405 Py_DECREF(v);
406 PyDict_SetItemString(d, "e", v = PyFloat_FromDouble(exp(1.0)));
407 Py_DECREF(v);
Guido van Rossum71aa32f1996-01-12 01:34:57 +0000408}