1 /* Complex math module */
3 /* much code borrowed from mathmodule.c */
8 #define M_PI (3.141592653589793239)
11 /* First, the C functions that do the real work */
14 static Py_complex c_one
= {1., 0.};
15 static Py_complex c_half
= {0.5, 0.};
16 static Py_complex c_i
= {0., 1.};
17 static Py_complex c_halfi
= {0., 0.5};
19 /* forward declarations */
20 static Py_complex
c_log(Py_complex
);
21 static Py_complex
c_prodi(Py_complex
);
22 static Py_complex
c_sqrt(Py_complex
);
28 return c_neg(c_prodi(c_log(c_sum(x
,c_prod(c_i
,
29 c_sqrt(c_diff(c_one
,c_prod(x
,x
))))))));
32 PyDoc_STRVAR(c_acos_doc
,
35 "Return the arc cosine of x.");
43 z
= c_log(c_prod(z
, c_sum(c_sqrt(c_sum(x
,c_one
)),
44 c_sqrt(c_diff(x
,c_one
)))));
48 PyDoc_STRVAR(c_acosh_doc
,
51 "Return the hyperbolic arccosine of x.");
57 /* -i * log[(sqrt(1-x**2) + i*x] */
58 const Py_complex squared
= c_prod(x
, x
);
59 const Py_complex sqrt_1_minus_x_sq
= c_sqrt(c_diff(c_one
, squared
));
60 return c_neg(c_prodi(c_log(
61 c_sum(sqrt_1_minus_x_sq
, c_prodi(x
))
65 PyDoc_STRVAR(c_asin_doc
,
68 "Return the arc sine of x.");
76 z
= c_log(c_prod(z
, c_sum(c_sqrt(c_sum(x
, c_i
)),
77 c_sqrt(c_diff(x
, c_i
)))));
81 PyDoc_STRVAR(c_asinh_doc
,
84 "Return the hyperbolic arc sine of x.");
90 return c_prod(c_halfi
,c_log(c_quot(c_sum(c_i
,x
),c_diff(c_i
,x
))));
93 PyDoc_STRVAR(c_atan_doc
,
96 "Return the arc tangent of x.");
100 c_atanh(Py_complex x
)
102 return c_prod(c_half
,c_log(c_quot(c_sum(c_one
,x
),c_diff(c_one
,x
))));
105 PyDoc_STRVAR(c_atanh_doc
,
108 "Return the hyperbolic arc tangent of x.");
115 r
.real
= cos(x
.real
)*cosh(x
.imag
);
116 r
.imag
= -sin(x
.real
)*sinh(x
.imag
);
120 PyDoc_STRVAR(c_cos_doc
,
123 "Return the cosine of x.");
130 r
.real
= cos(x
.imag
)*cosh(x
.real
);
131 r
.imag
= sin(x
.imag
)*sinh(x
.real
);
135 PyDoc_STRVAR(c_cosh_doc
,
138 "Return the hyperbolic cosine of x.");
145 double l
= exp(x
.real
);
146 r
.real
= l
*cos(x
.imag
);
147 r
.imag
= l
*sin(x
.imag
);
151 PyDoc_STRVAR(c_exp_doc
,
154 "Return the exponential value e**x.");
161 double l
= hypot(x
.real
,x
.imag
);
162 r
.imag
= atan2(x
.imag
, x
.real
);
167 PyDoc_STRVAR(c_log_doc
,
170 "Return the natural logarithm of x.");
174 c_log10(Py_complex x
)
177 double l
= hypot(x
.real
,x
.imag
);
178 r
.imag
= atan2(x
.imag
, x
.real
)/log(10.);
183 PyDoc_STRVAR(c_log10_doc
,
186 "Return the base-10 logarithm of x.");
189 /* internal function not available from Python */
191 c_prodi(Py_complex x
)
204 r
.real
= sin(x
.real
) * cosh(x
.imag
);
205 r
.imag
= cos(x
.real
) * sinh(x
.imag
);
209 PyDoc_STRVAR(c_sin_doc
,
212 "Return the sine of x.");
219 r
.real
= cos(x
.imag
) * sinh(x
.real
);
220 r
.imag
= sin(x
.imag
) * cosh(x
.real
);
224 PyDoc_STRVAR(c_sinh_doc
,
227 "Return the hyperbolic sine of 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 PyDoc_STRVAR(c_sqrt_doc
,
259 "Return the square root of x.");
266 double sr
,cr
,shi
,chi
;
278 r
.real
= (rs
*rc
+ is
*ic
) / d
;
279 r
.imag
= (is
*rc
- rs
*ic
) / d
;
283 PyDoc_STRVAR(c_tan_doc
,
286 "Return the tangent of x.");
293 double si
,ci
,shr
,chr
;
305 r
.real
= (rs
*rc
+ is
*ic
) / d
;
306 r
.imag
= (is
*rc
- rs
*ic
) / d
;
310 PyDoc_STRVAR(c_tanh_doc
,
313 "Return the hyperbolic tangent of x.");
316 /* And now the glue to make them available from Python: */
322 PyErr_SetString(PyExc_ValueError
, "math domain error");
323 else if (errno
== ERANGE
)
324 PyErr_SetString(PyExc_OverflowError
, "math range error");
325 else /* Unexpected math error */
326 PyErr_SetFromErrno(PyExc_ValueError
);
331 math_1(PyObject
*args
, Py_complex (*func
)(Py_complex
))
334 if (!PyArg_ParseTuple(args
, "D", &x
))
337 PyFPE_START_PROTECT("complex function", return 0)
340 Py_ADJUST_ERANGE2(x
.real
, x
.imag
);
344 return PyComplex_FromCComplex(x
);
347 #define FUNC1(stubname, func) \
348 static PyObject * stubname(PyObject *self, PyObject *args) { \
349 return math_1(args, func); \
352 FUNC1(cmath_acos
, c_acos
)
353 FUNC1(cmath_acosh
, c_acosh
)
354 FUNC1(cmath_asin
, c_asin
)
355 FUNC1(cmath_asinh
, c_asinh
)
356 FUNC1(cmath_atan
, c_atan
)
357 FUNC1(cmath_atanh
, c_atanh
)
358 FUNC1(cmath_cos
, c_cos
)
359 FUNC1(cmath_cosh
, c_cosh
)
360 FUNC1(cmath_exp
, c_exp
)
361 FUNC1(cmath_log
, c_log
)
362 FUNC1(cmath_log10
, c_log10
)
363 FUNC1(cmath_sin
, c_sin
)
364 FUNC1(cmath_sinh
, c_sinh
)
365 FUNC1(cmath_sqrt
, c_sqrt
)
366 FUNC1(cmath_tan
, c_tan
)
367 FUNC1(cmath_tanh
, c_tanh
)
370 PyDoc_STRVAR(module_doc
,
371 "This module is always available. It provides access to mathematical\n"
372 "functions for complex numbers.");
374 static PyMethodDef cmath_methods
[] = {
375 {"acos", cmath_acos
, METH_VARARGS
, c_acos_doc
},
376 {"acosh", cmath_acosh
, METH_VARARGS
, c_acosh_doc
},
377 {"asin", cmath_asin
, METH_VARARGS
, c_asin_doc
},
378 {"asinh", cmath_asinh
, METH_VARARGS
, c_asinh_doc
},
379 {"atan", cmath_atan
, METH_VARARGS
, c_atan_doc
},
380 {"atanh", cmath_atanh
, METH_VARARGS
, c_atanh_doc
},
381 {"cos", cmath_cos
, METH_VARARGS
, c_cos_doc
},
382 {"cosh", cmath_cosh
, METH_VARARGS
, c_cosh_doc
},
383 {"exp", cmath_exp
, METH_VARARGS
, c_exp_doc
},
384 {"log", cmath_log
, METH_VARARGS
, c_log_doc
},
385 {"log10", cmath_log10
, METH_VARARGS
, c_log10_doc
},
386 {"sin", cmath_sin
, METH_VARARGS
, c_sin_doc
},
387 {"sinh", cmath_sinh
, METH_VARARGS
, c_sinh_doc
},
388 {"sqrt", cmath_sqrt
, METH_VARARGS
, c_sqrt_doc
},
389 {"tan", cmath_tan
, METH_VARARGS
, c_tan_doc
},
390 {"tanh", cmath_tanh
, METH_VARARGS
, c_tanh_doc
},
391 {NULL
, NULL
} /* sentinel */
399 m
= Py_InitModule3("cmath", cmath_methods
, module_doc
);
401 PyModule_AddObject(m
, "pi",
402 PyFloat_FromDouble(atan(1.0) * 4.0));
403 PyModule_AddObject(m
, "e", PyFloat_FromDouble(exp(1.0)));