2 /* Complex object implementation */
4 /* Borrows heavily from floatobject.c */
6 /* Submitted by Jim Hugunin */
8 #ifndef WITHOUT_COMPLEX
13 /* elementary operations on complex numbers */
15 static Py_complex c_1
= {1., 0.};
17 Py_complex
c_sum(Py_complex a
, Py_complex b
)
20 r
.real
= a
.real
+ b
.real
;
21 r
.imag
= a
.imag
+ b
.imag
;
25 Py_complex
c_diff(Py_complex a
, Py_complex b
)
28 r
.real
= a
.real
- b
.real
;
29 r
.imag
= a
.imag
- b
.imag
;
33 Py_complex
c_neg(Py_complex a
)
41 Py_complex
c_prod(Py_complex a
, Py_complex b
)
44 r
.real
= a
.real
*b
.real
- a
.imag
*b
.imag
;
45 r
.imag
= a
.real
*b
.imag
+ a
.imag
*b
.real
;
49 Py_complex
c_quot(Py_complex a
, Py_complex b
)
52 double d
= b
.real
*b
.real
+ b
.imag
*b
.imag
;
55 r
.real
= (a
.real
*b
.real
+ a
.imag
*b
.imag
)/d
;
56 r
.imag
= (a
.imag
*b
.real
- a
.real
*b
.imag
)/d
;
60 Py_complex
c_pow(Py_complex a
, Py_complex b
)
63 double vabs
,len
,at
,phase
;
64 if (b
.real
== 0. && b
.imag
== 0.) {
68 else if (a
.real
== 0. && a
.imag
== 0.) {
69 if (b
.imag
!= 0. || b
.real
< 0.)
75 vabs
= hypot(a
.real
,a
.imag
);
76 len
= pow(vabs
,b
.real
);
77 at
= atan2(a
.imag
, a
.real
);
80 len
/= exp(at
*b
.imag
);
81 phase
+= b
.imag
*log(vabs
);
83 r
.real
= len
*cos(phase
);
84 r
.imag
= len
*sin(phase
);
89 static Py_complex
c_powu(Py_complex x
, long n
)
95 while (mask
> 0 && n
>= mask
) {
104 static Py_complex
c_powi(Py_complex x
, long n
)
108 if (n
> 100 || n
< -100) {
109 cn
.real
= (double) n
;
116 return c_quot(c_1
,c_powu(x
,-n
));
121 PyComplex_FromCComplex(Py_complex cval
)
123 register PyComplexObject
*op
;
125 /* PyObject_New is inlined */
126 op
= (PyComplexObject
*) PyObject_MALLOC(sizeof(PyComplexObject
));
128 return PyErr_NoMemory();
129 PyObject_INIT(op
, &PyComplex_Type
);
131 return (PyObject
*) op
;
135 PyComplex_FromDoubles(double real
, double imag
)
140 return PyComplex_FromCComplex(c
);
144 PyComplex_RealAsDouble(PyObject
*op
)
146 if (PyComplex_Check(op
)) {
147 return ((PyComplexObject
*)op
)->cval
.real
;
150 return PyFloat_AsDouble(op
);
155 PyComplex_ImagAsDouble(PyObject
*op
)
157 if (PyComplex_Check(op
)) {
158 return ((PyComplexObject
*)op
)->cval
.imag
;
166 PyComplex_AsCComplex(PyObject
*op
)
169 if (PyComplex_Check(op
)) {
170 return ((PyComplexObject
*)op
)->cval
;
173 cv
.real
= PyFloat_AsDouble(op
);
180 complex_dealloc(PyObject
*op
)
187 complex_buf_repr(char *buf
, PyComplexObject
*v
)
189 if (v
->cval
.real
== 0.)
190 sprintf(buf
, "%.12gj", v
->cval
.imag
);
192 sprintf(buf
, "(%.12g%+.12gj)", v
->cval
.real
, v
->cval
.imag
);
196 complex_print(PyComplexObject
*v
, FILE *fp
, int flags
)
197 /* flags -- not used but required by interface */
200 complex_buf_repr(buf
, v
);
206 complex_repr(PyComplexObject
*v
)
209 complex_buf_repr(buf
, v
);
210 return PyString_FromString(buf
);
214 complex_hash(PyComplexObject
*v
)
216 long hashreal
, hashimag
, combined
;
217 hashreal
= _Py_HashDouble(v
->cval
.real
);
220 hashimag
= _Py_HashDouble(v
->cval
.imag
);
223 /* Note: if the imaginary part is 0, hashimag is 0 now,
224 * so the following returns hashreal unchanged. This is
225 * important because numbers of different types that
226 * compare equal must have the same hash value, so that
227 * hash(x + 0*j) must equal hash(x).
229 combined
= hashreal
+ 1000003 * hashimag
;
236 complex_add(PyComplexObject
*v
, PyComplexObject
*w
)
239 PyFPE_START_PROTECT("complex_add", return 0)
240 result
= c_sum(v
->cval
,w
->cval
);
241 PyFPE_END_PROTECT(result
)
242 return PyComplex_FromCComplex(result
);
246 complex_sub(PyComplexObject
*v
, PyComplexObject
*w
)
249 PyFPE_START_PROTECT("complex_sub", return 0)
250 result
= c_diff(v
->cval
,w
->cval
);
251 PyFPE_END_PROTECT(result
)
252 return PyComplex_FromCComplex(result
);
256 complex_mul(PyComplexObject
*v
, PyComplexObject
*w
)
259 PyFPE_START_PROTECT("complex_mul", return 0)
260 result
= c_prod(v
->cval
,w
->cval
);
261 PyFPE_END_PROTECT(result
)
262 return PyComplex_FromCComplex(result
);
266 complex_div(PyComplexObject
*v
, PyComplexObject
*w
)
269 PyFPE_START_PROTECT("complex_div", return 0)
271 quot
= c_quot(v
->cval
,w
->cval
);
272 PyFPE_END_PROTECT(quot
)
274 PyErr_SetString(PyExc_ZeroDivisionError
, "complex division");
277 return PyComplex_FromCComplex(quot
);
281 complex_remainder(PyComplexObject
*v
, PyComplexObject
*w
)
285 div
= c_quot(v
->cval
,w
->cval
); /* The raw divisor value. */
287 PyErr_SetString(PyExc_ZeroDivisionError
, "complex remainder");
290 div
.real
= floor(div
.real
); /* Use the floor of the real part. */
292 mod
= c_diff(v
->cval
, c_prod(w
->cval
, div
));
294 return PyComplex_FromCComplex(mod
);
299 complex_divmod(PyComplexObject
*v
, PyComplexObject
*w
)
304 div
= c_quot(v
->cval
,w
->cval
); /* The raw divisor value. */
306 PyErr_SetString(PyExc_ZeroDivisionError
, "complex divmod()");
309 div
.real
= floor(div
.real
); /* Use the floor of the real part. */
311 mod
= c_diff(v
->cval
, c_prod(w
->cval
, div
));
312 d
= PyComplex_FromCComplex(div
);
313 m
= PyComplex_FromCComplex(mod
);
314 z
= Py_BuildValue("(OO)", d
, m
);
321 complex_pow(PyComplexObject
*v
, PyObject
*w
, PyComplexObject
*z
)
327 if ((PyObject
*)z
!=Py_None
) {
328 PyErr_SetString(PyExc_ValueError
, "complex modulo");
331 PyFPE_START_PROTECT("complex_pow", return 0)
333 exponent
= ((PyComplexObject
*)w
)->cval
;
334 int_exponent
= (long)exponent
.real
;
335 if (exponent
.imag
== 0. && exponent
.real
== int_exponent
)
336 p
= c_powi(v
->cval
,int_exponent
);
338 p
= c_pow(v
->cval
,exponent
);
341 if (errno
== ERANGE
) {
342 PyErr_SetString(PyExc_ValueError
,
343 "0.0 to a negative or complex power");
346 return PyComplex_FromCComplex(p
);
350 complex_neg(PyComplexObject
*v
)
353 neg
.real
= -v
->cval
.real
;
354 neg
.imag
= -v
->cval
.imag
;
355 return PyComplex_FromCComplex(neg
);
359 complex_pos(PyComplexObject
*v
)
362 return (PyObject
*)v
;
366 complex_abs(PyComplexObject
*v
)
369 PyFPE_START_PROTECT("complex_abs", return 0)
370 result
= hypot(v
->cval
.real
,v
->cval
.imag
);
371 PyFPE_END_PROTECT(result
)
372 return PyFloat_FromDouble(result
);
376 complex_nonzero(PyComplexObject
*v
)
378 return v
->cval
.real
!= 0.0 || v
->cval
.imag
!= 0.0;
382 complex_coerce(PyObject
**pv
, PyObject
**pw
)
386 if (PyInt_Check(*pw
)) {
387 cval
.real
= (double)PyInt_AsLong(*pw
);
388 *pw
= PyComplex_FromCComplex(cval
);
392 else if (PyLong_Check(*pw
)) {
393 cval
.real
= PyLong_AsDouble(*pw
);
394 *pw
= PyComplex_FromCComplex(cval
);
398 else if (PyFloat_Check(*pw
)) {
399 cval
.real
= PyFloat_AsDouble(*pw
);
400 *pw
= PyComplex_FromCComplex(cval
);
404 return 1; /* Can't do it */
408 complex_richcompare(PyObject
*v
, PyObject
*w
, int op
)
414 if (op
!= Py_EQ
&& op
!= Py_NE
) {
415 PyErr_SetString(PyExc_TypeError
,
416 "cannot compare complex numbers using <, <=, >, >=");
420 c
= PyNumber_CoerceEx(&v
, &w
);
424 Py_INCREF(Py_NotImplemented
);
425 return Py_NotImplemented
;
427 if (!PyComplex_Check(v
) || !PyComplex_Check(w
)) {
430 Py_INCREF(Py_NotImplemented
);
431 return Py_NotImplemented
;
434 i
= ((PyComplexObject
*)v
)->cval
;
435 j
= ((PyComplexObject
*)w
)->cval
;
439 if ((i
.real
== j
.real
&& i
.imag
== j
.imag
) == (op
== Py_EQ
))
449 complex_int(PyObject
*v
)
451 PyErr_SetString(PyExc_TypeError
,
452 "can't convert complex to int; use e.g. int(abs(z))");
457 complex_long(PyObject
*v
)
459 PyErr_SetString(PyExc_TypeError
,
460 "can't convert complex to long; use e.g. long(abs(z))");
465 complex_float(PyObject
*v
)
467 PyErr_SetString(PyExc_TypeError
,
468 "can't convert complex to float; use e.g. abs(z)");
473 complex_conjugate(PyObject
*self
, PyObject
*args
)
476 if (!PyArg_ParseTuple(args
, ":conjugate"))
478 c
= ((PyComplexObject
*)self
)->cval
;
480 return PyComplex_FromCComplex(c
);
483 static PyMethodDef complex_methods
[] = {
484 {"conjugate", complex_conjugate
, 1},
485 {NULL
, NULL
} /* sentinel */
490 complex_getattr(PyComplexObject
*self
, char *name
)
492 if (strcmp(name
, "real") == 0)
493 return (PyObject
*)PyFloat_FromDouble(self
->cval
.real
);
494 else if (strcmp(name
, "imag") == 0)
495 return (PyObject
*)PyFloat_FromDouble(self
->cval
.imag
);
496 else if (strcmp(name
, "__members__") == 0)
497 return Py_BuildValue("[ss]", "imag", "real");
498 return Py_FindMethod(complex_methods
, (PyObject
*)self
, name
);
501 static PyNumberMethods complex_as_number
= {
502 (binaryfunc
)complex_add
, /* nb_add */
503 (binaryfunc
)complex_sub
, /* nb_subtract */
504 (binaryfunc
)complex_mul
, /* nb_multiply */
505 (binaryfunc
)complex_div
, /* nb_divide */
506 (binaryfunc
)complex_remainder
, /* nb_remainder */
507 (binaryfunc
)complex_divmod
, /* nb_divmod */
508 (ternaryfunc
)complex_pow
, /* nb_power */
509 (unaryfunc
)complex_neg
, /* nb_negative */
510 (unaryfunc
)complex_pos
, /* nb_positive */
511 (unaryfunc
)complex_abs
, /* nb_absolute */
512 (inquiry
)complex_nonzero
, /* nb_nonzero */
519 (coercion
)complex_coerce
, /* nb_coerce */
520 (unaryfunc
)complex_int
, /* nb_int */
521 (unaryfunc
)complex_long
, /* nb_long */
522 (unaryfunc
)complex_float
, /* nb_float */
527 PyTypeObject PyComplex_Type
= {
528 PyObject_HEAD_INIT(&PyType_Type
)
531 sizeof(PyComplexObject
),
533 (destructor
)complex_dealloc
, /* tp_dealloc */
534 (printfunc
)complex_print
, /* tp_print */
535 (getattrfunc
)complex_getattr
, /* tp_getattr */
538 (reprfunc
)complex_repr
, /* tp_repr */
539 &complex_as_number
, /* tp_as_number */
540 0, /* tp_as_sequence */
541 0, /* tp_as_mapping */
542 (hashfunc
)complex_hash
, /* tp_hash */
547 0, /* tp_as_buffer */
548 Py_TPFLAGS_DEFAULT
, /* tp_flags */
552 complex_richcompare
, /* tp_richcompare */