1 /* Complex math module */
3 /* much code borrowed from mathmodule.c */
8 /* Cray APP has bogus definition of HUGE_VAL in <math.h> */
13 #define CHECK(x) if (errno != 0) ; \
14 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
17 #define CHECK(x) /* Don't know how to check */
21 #define M_PI (3.141592653589793239)
24 /* First, the C functions that do the real work */
27 static Py_complex c_1
= {1., 0.};
28 static Py_complex c_half
= {0.5, 0.};
29 static Py_complex c_i
= {0., 1.};
30 static Py_complex c_i2
= {0., 0.5};
32 static Py_complex c_mi
= {0., -1.};
33 static Py_complex c_pi2
= {M_PI
/2., 0.};
36 /* forward declarations */
37 staticforward Py_complex
c_log(Py_complex
);
38 staticforward Py_complex
c_prodi(Py_complex
);
39 staticforward Py_complex
c_sqrt(Py_complex
);
42 static Py_complex
c_acos(Py_complex x
)
44 return c_neg(c_prodi(c_log(c_sum(x
,c_prod(c_i
,
45 c_sqrt(c_diff(c_1
,c_prod(x
,x
))))))));
48 static char c_acos_doc
[] =
51 Return the arc cosine of x.";
54 static Py_complex
c_acosh(Py_complex x
)
58 z
= c_log(c_prod(z
, c_sum(c_sqrt(c_sum(x
,c_1
)),
59 c_sqrt(c_diff(x
,c_1
)))));
63 static char c_acosh_doc
[] =
66 Return the hyperbolic arccosine of x.";
69 static Py_complex
c_asin(Py_complex x
)
73 z
= c_log(c_prod(z
, c_sum(c_sqrt(c_sum(x
,c_i
)),
74 c_sqrt(c_diff(x
,c_i
)))));
78 static char c_asin_doc
[] =
81 Return the arc sine of x.";
84 static Py_complex
c_asinh(Py_complex x
)
86 /* Break up long expression for WATCOM */
88 z
= c_sum(c_1
,c_prod(x
, x
));
89 return c_log(c_sum(c_sqrt(z
), x
));
92 static char c_asinh_doc
[] =
95 Return the hyperbolic arc sine of x.";
98 static Py_complex
c_atan(Py_complex x
)
100 return c_prod(c_i2
,c_log(c_quot(c_sum(c_i
,x
),c_diff(c_i
,x
))));
103 static char c_atan_doc
[] =
106 Return the arc tangent of x.";
109 static Py_complex
c_atanh(Py_complex x
)
111 return c_prod(c_half
,c_log(c_quot(c_sum(c_1
,x
),c_diff(c_1
,x
))));
114 static char c_atanh_doc
[] =
117 Return the hyperbolic arc tangent of x.";
120 static Py_complex
c_cos(Py_complex x
)
123 r
.real
= cos(x
.real
)*cosh(x
.imag
);
124 r
.imag
= -sin(x
.real
)*sinh(x
.imag
);
128 static char c_cos_doc
[] =
131 Return the cosine of x.";
134 static Py_complex
c_cosh(Py_complex x
)
137 r
.real
= cos(x
.imag
)*cosh(x
.real
);
138 r
.imag
= sin(x
.imag
)*sinh(x
.real
);
142 static char c_cosh_doc
[] =
145 Return the hyperbolic cosine of x.";
148 static Py_complex
c_exp(Py_complex x
)
151 double l
= exp(x
.real
);
152 r
.real
= l
*cos(x
.imag
);
153 r
.imag
= l
*sin(x
.imag
);
157 static char c_exp_doc
[] =
160 Return the exponential value e**x.";
163 static Py_complex
c_log(Py_complex x
)
166 double l
= hypot(x
.real
,x
.imag
);
167 r
.imag
= atan2(x
.imag
, x
.real
);
172 static char c_log_doc
[] =
175 Return the natural logarithm of x.";
178 static Py_complex
c_log10(Py_complex x
)
181 double l
= hypot(x
.real
,x
.imag
);
182 r
.imag
= atan2(x
.imag
, x
.real
)/log(10.);
187 static char c_log10_doc
[] =
190 Return the base-10 logarithm of x.";
193 /* internal function not available from Python */
194 static Py_complex
c_prodi(Py_complex x
)
203 static Py_complex
c_sin(Py_complex x
)
206 r
.real
= sin(x
.real
)*cosh(x
.imag
);
207 r
.imag
= cos(x
.real
)*sinh(x
.imag
);
211 static char c_sin_doc
[] =
214 Return the sine of x.";
217 static Py_complex
c_sinh(Py_complex x
)
220 r
.real
= cos(x
.imag
)*sinh(x
.real
);
221 r
.imag
= sin(x
.imag
)*cosh(x
.real
);
225 static char c_sinh_doc
[] =
228 Return the hyperbolic sine of x.";
231 static Py_complex
c_sqrt(Py_complex x
)
235 if (x
.real
== 0. && x
.imag
== 0.)
238 s
= sqrt(0.5*(fabs(x
.real
) + hypot(x
.real
,x
.imag
)));
244 else if (x
.imag
>= 0.) {
256 static char c_sqrt_doc
[] =
259 Return the square root of x.";
262 static Py_complex
c_tan(Py_complex x
)
265 double sr
,cr
,shi
,chi
;
277 r
.real
= (rs
*rc
+is
*ic
)/d
;
278 r
.imag
= (is
*rc
-rs
*ic
)/d
;
282 static char c_tan_doc
[] =
285 Return the tangent of x.";
288 static Py_complex
c_tanh(Py_complex x
)
291 double si
,ci
,shr
,chr
;
303 r
.real
= (rs
*rc
+is
*ic
)/d
;
304 r
.imag
= (is
*rc
-rs
*ic
)/d
;
308 static char c_tanh_doc
[] =
311 Return the hyperbolic tangent of x.";
314 /* And now the glue to make them available from Python: */
320 PyErr_SetString(PyExc_ValueError
, "math domain error");
321 else if (errno
== ERANGE
)
322 PyErr_SetString(PyExc_OverflowError
, "math range error");
323 else /* Unexpected math error */
324 PyErr_SetFromErrno(PyExc_ValueError
);
329 math_1(PyObject
*args
, Py_complex (*func
)(Py_complex
))
332 if (!PyArg_ParseTuple(args
, "D", &x
))
335 PyFPE_START_PROTECT("complex function", return 0)
343 return PyComplex_FromCComplex(x
);
346 #define FUNC1(stubname, func) \
347 static PyObject * stubname(PyObject *self, PyObject *args) { \
348 return math_1(args, func); \
351 FUNC1(cmath_acos
, c_acos
)
352 FUNC1(cmath_acosh
, c_acosh
)
353 FUNC1(cmath_asin
, c_asin
)
354 FUNC1(cmath_asinh
, c_asinh
)
355 FUNC1(cmath_atan
, c_atan
)
356 FUNC1(cmath_atanh
, c_atanh
)
357 FUNC1(cmath_cos
, c_cos
)
358 FUNC1(cmath_cosh
, c_cosh
)
359 FUNC1(cmath_exp
, c_exp
)
360 FUNC1(cmath_log
, c_log
)
361 FUNC1(cmath_log10
, c_log10
)
362 FUNC1(cmath_sin
, c_sin
)
363 FUNC1(cmath_sinh
, c_sinh
)
364 FUNC1(cmath_sqrt
, c_sqrt
)
365 FUNC1(cmath_tan
, c_tan
)
366 FUNC1(cmath_tanh
, c_tanh
)
369 static char module_doc
[] =
370 "This module is always available. It provides access to mathematical\n\
371 functions for complex numbers.";
374 static PyMethodDef cmath_methods
[] = {
376 METH_VARARGS
, c_acos_doc
},
377 {"acosh", cmath_acosh
,
378 METH_VARARGS
, c_acosh_doc
},
380 METH_VARARGS
, c_asin_doc
},
381 {"asinh", cmath_asinh
,
382 METH_VARARGS
, c_asinh_doc
},
384 METH_VARARGS
, c_atan_doc
},
385 {"atanh", cmath_atanh
,
386 METH_VARARGS
, c_atanh_doc
},
388 METH_VARARGS
, c_cos_doc
},
390 METH_VARARGS
, c_cosh_doc
},
392 METH_VARARGS
, c_exp_doc
},
394 METH_VARARGS
, c_log_doc
},
395 {"log10", cmath_log10
,
396 METH_VARARGS
, c_log10_doc
},
398 METH_VARARGS
, c_sin_doc
},
400 METH_VARARGS
, c_sinh_doc
},
402 METH_VARARGS
, c_sqrt_doc
},
404 METH_VARARGS
, c_tan_doc
},
406 METH_VARARGS
, c_tanh_doc
},
407 {NULL
, NULL
} /* sentinel */
415 m
= Py_InitModule3("cmath", cmath_methods
, module_doc
);
416 d
= PyModule_GetDict(m
);
417 PyDict_SetItemString(d
, "pi",
418 v
= PyFloat_FromDouble(atan(1.0) * 4.0));
420 PyDict_SetItemString(d
, "e", v
= PyFloat_FromDouble(exp(1.0)));