History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Modules/cmathmodule.c (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Modules/cmathmodule.c+426−0
@@ -0,0 +1,426 @@
1+/* Complex math module */
2+
3+/* much code borrowed from mathmodule.c */
4+
5+#include "Python.h"
6+
7+#ifndef M_PI
8+#define M_PI (3.141592653589793239)
9+#endif
10+
11+/* First, the C functions that do the real work */
12+
13+/* constants */
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};
18+
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);
23+static PyObject * math_error(void);
24+
25+
26+static Py_complex
27+c_acos(Py_complex x)
28+{
29+ return c_neg(c_prodi(c_log(c_sum(x,c_prod(c_i,
30+ c_sqrt(c_diff(c_one,c_prod(x,x))))))));
31+}
32+
33+PyDoc_STRVAR(c_acos_doc,
34+"acos(x)\n"
35+"\n"
36+"Return the arc cosine of x.");
37+
38+
39+static Py_complex
40+c_acosh(Py_complex x)
41+{
42+ Py_complex z;
43+ z = c_sqrt(c_half);
44+ z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x,c_one)),
45+ c_sqrt(c_diff(x,c_one)))));
46+ return c_sum(z, z);
47+}
48+
49+PyDoc_STRVAR(c_acosh_doc,
50+"acosh(x)\n"
51+"\n"
52+"Return the hyperbolic arccosine of x.");
53+
54+
55+static Py_complex
56+c_asin(Py_complex x)
57+{
58+ /* -i * log[(sqrt(1-x**2) + i*x] */
59+ const Py_complex squared = c_prod(x, x);
60+ const Py_complex sqrt_1_minus_x_sq = c_sqrt(c_diff(c_one, squared));
61+ return c_neg(c_prodi(c_log(
62+ c_sum(sqrt_1_minus_x_sq, c_prodi(x))
63+ ) ) );
64+}
65+
66+PyDoc_STRVAR(c_asin_doc,
67+"asin(x)\n"
68+"\n"
69+"Return the arc sine of x.");
70+
71+
72+static Py_complex
73+c_asinh(Py_complex x)
74+{
75+ Py_complex z;
76+ z = c_sqrt(c_half);
77+ z = c_log(c_prod(z, c_sum(c_sqrt(c_sum(x, c_i)),
78+ c_sqrt(c_diff(x, c_i)))));
79+ return c_sum(z, z);
80+}
81+
82+PyDoc_STRVAR(c_asinh_doc,
83+"asinh(x)\n"
84+"\n"
85+"Return the hyperbolic arc sine of x.");
86+
87+
88+static Py_complex
89+c_atan(Py_complex x)
90+{
91+ return c_prod(c_halfi,c_log(c_quot(c_sum(c_i,x),c_diff(c_i,x))));
92+}
93+
94+PyDoc_STRVAR(c_atan_doc,
95+"atan(x)\n"
96+"\n"
97+"Return the arc tangent of x.");
98+
99+
100+static Py_complex
101+c_atanh(Py_complex x)
102+{
103+ return c_prod(c_half,c_log(c_quot(c_sum(c_one,x),c_diff(c_one,x))));
104+}
105+
106+PyDoc_STRVAR(c_atanh_doc,
107+"atanh(x)\n"
108+"\n"
109+"Return the hyperbolic arc tangent of x.");
110+
111+
112+static Py_complex
113+c_cos(Py_complex x)
114+{
115+ Py_complex r;
116+ r.real = cos(x.real)*cosh(x.imag);
117+ r.imag = -sin(x.real)*sinh(x.imag);
118+ return r;
119+}
120+
121+PyDoc_STRVAR(c_cos_doc,
122+"cos(x)\n"
123+"n"
124+"Return the cosine of x.");
125+
126+
127+static Py_complex
128+c_cosh(Py_complex x)
129+{
130+ Py_complex r;
131+ r.real = cos(x.imag)*cosh(x.real);
132+ r.imag = sin(x.imag)*sinh(x.real);
133+ return r;
134+}
135+
136+PyDoc_STRVAR(c_cosh_doc,
137+"cosh(x)\n"
138+"n"
139+"Return the hyperbolic cosine of x.");
140+
141+
142+static Py_complex
143+c_exp(Py_complex x)
144+{
145+ Py_complex r;
146+ double l = exp(x.real);
147+ r.real = l*cos(x.imag);
148+ r.imag = l*sin(x.imag);
149+ return r;
150+}
151+
152+PyDoc_STRVAR(c_exp_doc,
153+"exp(x)\n"
154+"\n"
155+"Return the exponential value e**x.");
156+
157+
158+static Py_complex
159+c_log(Py_complex x)
160+{
161+ Py_complex r;
162+ double l = hypot(x.real,x.imag);
163+ r.imag = atan2(x.imag, x.real);
164+ r.real = log(l);
165+ return r;
166+}
167+
168+
169+static Py_complex
170+c_log10(Py_complex x)
171+{
172+ Py_complex r;
173+ double l = hypot(x.real,x.imag);
174+ r.imag = atan2(x.imag, x.real)/log(10.);
175+ r.real = log10(l);
176+ return r;
177+}
178+
179+PyDoc_STRVAR(c_log10_doc,
180+"log10(x)\n"
181+"\n"
182+"Return the base-10 logarithm of x.");
183+
184+
185+/* internal function not available from Python */
186+static Py_complex
187+c_prodi(Py_complex x)
188+{
189+ Py_complex r;
190+ r.real = -x.imag;
191+ r.imag = x.real;
192+ return r;
193+}
194+
195+
196+static Py_complex
197+c_sin(Py_complex x)
198+{
199+ Py_complex r;
200+ r.real = sin(x.real) * cosh(x.imag);
201+ r.imag = cos(x.real) * sinh(x.imag);
202+ return r;
203+}
204+
205+PyDoc_STRVAR(c_sin_doc,
206+"sin(x)\n"
207+"\n"
208+"Return the sine of x.");
209+
210+
211+static Py_complex
212+c_sinh(Py_complex x)
213+{
214+ Py_complex r;
215+ r.real = cos(x.imag) * sinh(x.real);
216+ r.imag = sin(x.imag) * cosh(x.real);
217+ return r;
218+}
219+
220+PyDoc_STRVAR(c_sinh_doc,
221+"sinh(x)\n"
222+"\n"
223+"Return the hyperbolic sine of x.");
224+
225+
226+static Py_complex
227+c_sqrt(Py_complex x)
228+{
229+ Py_complex r;
230+ double s,d;
231+ if (x.real == 0. && x.imag == 0.)
232+ r = x;
233+ else {
234+ s = sqrt(0.5*(fabs(x.real) + hypot(x.real,x.imag)));
235+ d = 0.5*x.imag/s;
236+ if (x.real > 0.) {
237+ r.real = s;
238+ r.imag = d;
239+ }
240+ else if (x.imag >= 0.) {
241+ r.real = d;
242+ r.imag = s;
243+ }
244+ else {
245+ r.real = -d;
246+ r.imag = -s;
247+ }
248+ }
249+ return r;
250+}
251+
252+PyDoc_STRVAR(c_sqrt_doc,
253+"sqrt(x)\n"
254+"\n"
255+"Return the square root of x.");
256+
257+
258+static Py_complex
259+c_tan(Py_complex x)
260+{
261+ Py_complex r;
262+ double sr,cr,shi,chi;
263+ double rs,is,rc,ic;
264+ double d;
265+ sr = sin(x.real);
266+ cr = cos(x.real);
267+ shi = sinh(x.imag);
268+ chi = cosh(x.imag);
269+ rs = sr * chi;
270+ is = cr * shi;
271+ rc = cr * chi;
272+ ic = -sr * shi;
273+ d = rc*rc + ic * ic;
274+ r.real = (rs*rc + is*ic) / d;
275+ r.imag = (is*rc - rs*ic) / d;
276+ return r;
277+}
278+
279+PyDoc_STRVAR(c_tan_doc,
280+"tan(x)\n"
281+"\n"
282+"Return the tangent of x.");
283+
284+
285+static Py_complex
286+c_tanh(Py_complex x)
287+{
288+ Py_complex r;
289+ double si,ci,shr,chr;
290+ double rs,is,rc,ic;
291+ double d;
292+ si = sin(x.imag);
293+ ci = cos(x.imag);
294+ shr = sinh(x.real);
295+ chr = cosh(x.real);
296+ rs = ci * shr;
297+ is = si * chr;
298+ rc = ci * chr;
299+ ic = si * shr;
300+ d = rc*rc + ic*ic;
301+ r.real = (rs*rc + is*ic) / d;
302+ r.imag = (is*rc - rs*ic) / d;
303+ return r;
304+}
305+
306+PyDoc_STRVAR(c_tanh_doc,
307+"tanh(x)\n"
308+"\n"
309+"Return the hyperbolic tangent of x.");
310+
311+static PyObject *
312+cmath_log(PyObject *self, PyObject *args)
313+{
314+ Py_complex x;
315+ Py_complex y;
316+
317+ if (!PyArg_ParseTuple(args, "D|D", &x, &y))
318+ return NULL;
319+
320+ errno = 0;
321+ PyFPE_START_PROTECT("complex function", return 0)
322+ x = c_log(x);
323+ if (PyTuple_GET_SIZE(args) == 2)
324+ x = c_quot(x, c_log(y));
325+ PyFPE_END_PROTECT(x)
326+ if (errno != 0)
327+ return math_error();
328+ Py_ADJUST_ERANGE2(x.real, x.imag);
329+ return PyComplex_FromCComplex(x);
330+}
331+
332+PyDoc_STRVAR(cmath_log_doc,
333+"log(x[, base]) -> the logarithm of x to the given base.\n\
334+If the base not specified, returns the natural logarithm (base e) of x.");
335+
336+
337+/* And now the glue to make them available from Python: */
338+
339+static PyObject *
340+math_error(void)
341+{
342+ if (errno == EDOM)
343+ PyErr_SetString(PyExc_ValueError, "math domain error");
344+ else if (errno == ERANGE)
345+ PyErr_SetString(PyExc_OverflowError, "math range error");
346+ else /* Unexpected math error */
347+ PyErr_SetFromErrno(PyExc_ValueError);
348+ return NULL;
349+}
350+
351+static PyObject *
352+math_1(PyObject *args, Py_complex (*func)(Py_complex))
353+{
354+ Py_complex x;
355+ if (!PyArg_ParseTuple(args, "D", &x))
356+ return NULL;
357+ errno = 0;
358+ PyFPE_START_PROTECT("complex function", return 0)
359+ x = (*func)(x);
360+ PyFPE_END_PROTECT(x)
361+ Py_ADJUST_ERANGE2(x.real, x.imag);
362+ if (errno != 0)
363+ return math_error();
364+ else
365+ return PyComplex_FromCComplex(x);
366+}
367+
368+#define FUNC1(stubname, func) \
369+ static PyObject * stubname(PyObject *self, PyObject *args) { \
370+ return math_1(args, func); \
371+ }
372+
373+FUNC1(cmath_acos, c_acos)
374+FUNC1(cmath_acosh, c_acosh)
375+FUNC1(cmath_asin, c_asin)
376+FUNC1(cmath_asinh, c_asinh)
377+FUNC1(cmath_atan, c_atan)
378+FUNC1(cmath_atanh, c_atanh)
379+FUNC1(cmath_cos, c_cos)
380+FUNC1(cmath_cosh, c_cosh)
381+FUNC1(cmath_exp, c_exp)
382+FUNC1(cmath_log10, c_log10)
383+FUNC1(cmath_sin, c_sin)
384+FUNC1(cmath_sinh, c_sinh)
385+FUNC1(cmath_sqrt, c_sqrt)
386+FUNC1(cmath_tan, c_tan)
387+FUNC1(cmath_tanh, c_tanh)
388+
389+
390+PyDoc_STRVAR(module_doc,
391+"This module is always available. It provides access to mathematical\n"
392+"functions for complex numbers.");
393+
394+static PyMethodDef cmath_methods[] = {
395+ {"acos", cmath_acos, METH_VARARGS, c_acos_doc},
396+ {"acosh", cmath_acosh, METH_VARARGS, c_acosh_doc},
397+ {"asin", cmath_asin, METH_VARARGS, c_asin_doc},
398+ {"asinh", cmath_asinh, METH_VARARGS, c_asinh_doc},
399+ {"atan", cmath_atan, METH_VARARGS, c_atan_doc},
400+ {"atanh", cmath_atanh, METH_VARARGS, c_atanh_doc},
401+ {"cos", cmath_cos, METH_VARARGS, c_cos_doc},
402+ {"cosh", cmath_cosh, METH_VARARGS, c_cosh_doc},
403+ {"exp", cmath_exp, METH_VARARGS, c_exp_doc},
404+ {"log", cmath_log, METH_VARARGS, cmath_log_doc},
405+ {"log10", cmath_log10, METH_VARARGS, c_log10_doc},
406+ {"sin", cmath_sin, METH_VARARGS, c_sin_doc},
407+ {"sinh", cmath_sinh, METH_VARARGS, c_sinh_doc},
408+ {"sqrt", cmath_sqrt, METH_VARARGS, c_sqrt_doc},
409+ {"tan", cmath_tan, METH_VARARGS, c_tan_doc},
410+ {"tanh", cmath_tanh, METH_VARARGS, c_tanh_doc},
411+ {NULL, NULL} /* sentinel */
412+};
413+
414+PyMODINIT_FUNC
415+initcmath(void)
416+{
417+ PyObject *m;
418+
419+ m = Py_InitModule3("cmath", cmath_methods, module_doc);
420+ if (m == NULL)
421+ return;
422+
423+ PyModule_AddObject(m, "pi",
424+ PyFloat_FromDouble(atan(1.0) * 4.0));
425+ PyModule_AddObject(m, "e", PyFloat_FromDouble(exp(1.0)));
426+}