2 /* Complex object implementation */
4 /* Borrows heavily from floatobject.c */
6 /* Submitted by Jim Hugunin */
8 #ifndef WITHOUT_COMPLEX
17 /* elementary operations on complex numbers */
19 static Py_complex c_1
= {1., 0.};
21 Py_complex
c_sum(Py_complex a
, Py_complex b
)
24 r
.real
= a
.real
+ b
.real
;
25 r
.imag
= a
.imag
+ b
.imag
;
29 Py_complex
c_diff(Py_complex a
, Py_complex b
)
32 r
.real
= a
.real
- b
.real
;
33 r
.imag
= a
.imag
- b
.imag
;
37 Py_complex
c_neg(Py_complex a
)
45 Py_complex
c_prod(Py_complex a
, Py_complex b
)
48 r
.real
= a
.real
*b
.real
- a
.imag
*b
.imag
;
49 r
.imag
= a
.real
*b
.imag
+ a
.imag
*b
.real
;
53 Py_complex
c_quot(Py_complex a
, Py_complex b
)
56 double d
= b
.real
*b
.real
+ b
.imag
*b
.imag
;
59 r
.real
= (a
.real
*b
.real
+ a
.imag
*b
.imag
)/d
;
60 r
.imag
= (a
.imag
*b
.real
- a
.real
*b
.imag
)/d
;
64 Py_complex
c_pow(Py_complex a
, Py_complex b
)
67 double vabs
,len
,at
,phase
;
68 if (b
.real
== 0. && b
.imag
== 0.) {
72 else if (a
.real
== 0. && a
.imag
== 0.) {
73 if (b
.imag
!= 0. || b
.real
< 0.)
79 vabs
= hypot(a
.real
,a
.imag
);
80 len
= pow(vabs
,b
.real
);
81 at
= atan2(a
.imag
, a
.real
);
84 len
/= exp(at
*b
.imag
);
85 phase
+= b
.imag
*log(vabs
);
87 r
.real
= len
*cos(phase
);
88 r
.imag
= len
*sin(phase
);
93 static Py_complex
c_powu(Py_complex x
, long n
)
99 while (mask
> 0 && n
>= mask
) {
108 static Py_complex
c_powi(Py_complex x
, long n
)
112 if (n
> 100 || n
< -100) {
113 cn
.real
= (double) n
;
120 return c_quot(c_1
,c_powu(x
,-n
));
125 PyComplex_FromCComplex(Py_complex cval
)
127 register PyComplexObject
*op
;
129 /* PyObject_New is inlined */
130 op
= (PyComplexObject
*) PyObject_MALLOC(sizeof(PyComplexObject
));
132 return PyErr_NoMemory();
133 PyObject_INIT(op
, &PyComplex_Type
);
135 return (PyObject
*) op
;
139 PyComplex_FromDoubles(double real
, double imag
)
144 return PyComplex_FromCComplex(c
);
148 PyComplex_RealAsDouble(PyObject
*op
)
150 if (PyComplex_Check(op
)) {
151 return ((PyComplexObject
*)op
)->cval
.real
;
154 return PyFloat_AsDouble(op
);
159 PyComplex_ImagAsDouble(PyObject
*op
)
161 if (PyComplex_Check(op
)) {
162 return ((PyComplexObject
*)op
)->cval
.imag
;
170 PyComplex_AsCComplex(PyObject
*op
)
173 if (PyComplex_Check(op
)) {
174 return ((PyComplexObject
*)op
)->cval
;
177 cv
.real
= PyFloat_AsDouble(op
);
184 complex_dealloc(PyObject
*op
)
191 complex_buf_repr(char *buf
, PyComplexObject
*v
)
193 if (v
->cval
.real
== 0.)
194 sprintf(buf
, "%.12gj", v
->cval
.imag
);
196 sprintf(buf
, "(%.12g%+.12gj)", v
->cval
.real
, v
->cval
.imag
);
200 complex_print(PyComplexObject
*v
, FILE *fp
, int flags
)
201 /* flags -- not used but required by interface */
204 complex_buf_repr(buf
, v
);
210 complex_repr(PyComplexObject
*v
)
213 complex_buf_repr(buf
, v
);
214 return PyString_FromString(buf
);
218 complex_compare(PyComplexObject
*v
, PyComplexObject
*w
)
220 /* Note: "greater" and "smaller" have no meaning for complex numbers,
221 but Python requires that they be defined nevertheless. */
225 if (i
.real
== j
.real
&& i
.imag
== j
.imag
)
227 else if (i
.real
!= j
.real
)
228 return (i
.real
< j
.real
) ? -1 : 1;
230 return (i
.imag
< j
.imag
) ? -1 : 1;
234 complex_hash(PyComplexObject
*v
)
236 long hashreal
, hashimag
, combined
;
237 hashreal
= _Py_HashDouble(v
->cval
.real
);
240 hashimag
= _Py_HashDouble(v
->cval
.imag
);
243 /* Note: if the imaginary part is 0, hashimag is 0 now,
244 * so the following returns hashreal unchanged. This is
245 * important because numbers of different types that
246 * compare equal must have the same hash value, so that
247 * hash(x + 0*j) must equal hash(x).
249 combined
= hashreal
+ 1000003 * hashimag
;
256 complex_add(PyComplexObject
*v
, PyComplexObject
*w
)
259 PyFPE_START_PROTECT("complex_add", return 0)
260 result
= c_sum(v
->cval
,w
->cval
);
261 PyFPE_END_PROTECT(result
)
262 return PyComplex_FromCComplex(result
);
266 complex_sub(PyComplexObject
*v
, PyComplexObject
*w
)
269 PyFPE_START_PROTECT("complex_sub", return 0)
270 result
= c_diff(v
->cval
,w
->cval
);
271 PyFPE_END_PROTECT(result
)
272 return PyComplex_FromCComplex(result
);
276 complex_mul(PyComplexObject
*v
, PyComplexObject
*w
)
279 PyFPE_START_PROTECT("complex_mul", return 0)
280 result
= c_prod(v
->cval
,w
->cval
);
281 PyFPE_END_PROTECT(result
)
282 return PyComplex_FromCComplex(result
);
286 complex_div(PyComplexObject
*v
, PyComplexObject
*w
)
289 PyFPE_START_PROTECT("complex_div", return 0)
291 quot
= c_quot(v
->cval
,w
->cval
);
292 PyFPE_END_PROTECT(quot
)
294 PyErr_SetString(PyExc_ZeroDivisionError
, "complex division");
297 return PyComplex_FromCComplex(quot
);
301 complex_remainder(PyComplexObject
*v
, PyComplexObject
*w
)
305 div
= c_quot(v
->cval
,w
->cval
); /* The raw divisor value. */
307 PyErr_SetString(PyExc_ZeroDivisionError
, "complex remainder");
310 div
.real
= floor(div
.real
); /* Use the floor of the real part. */
312 mod
= c_diff(v
->cval
, c_prod(w
->cval
, div
));
314 return PyComplex_FromCComplex(mod
);
319 complex_divmod(PyComplexObject
*v
, PyComplexObject
*w
)
324 div
= c_quot(v
->cval
,w
->cval
); /* The raw divisor value. */
326 PyErr_SetString(PyExc_ZeroDivisionError
, "complex divmod()");
329 div
.real
= floor(div
.real
); /* Use the floor of the real part. */
331 mod
= c_diff(v
->cval
, c_prod(w
->cval
, div
));
332 d
= PyComplex_FromCComplex(div
);
333 m
= PyComplex_FromCComplex(mod
);
334 z
= Py_BuildValue("(OO)", d
, m
);
341 complex_pow(PyComplexObject
*v
, PyObject
*w
, PyComplexObject
*z
)
347 if ((PyObject
*)z
!=Py_None
) {
348 PyErr_SetString(PyExc_ValueError
, "complex modulo");
351 PyFPE_START_PROTECT("complex_pow", return 0)
353 exponent
= ((PyComplexObject
*)w
)->cval
;
354 int_exponent
= (long)exponent
.real
;
355 if (exponent
.imag
== 0. && exponent
.real
== int_exponent
)
356 p
= c_powi(v
->cval
,int_exponent
);
358 p
= c_pow(v
->cval
,exponent
);
361 if (errno
== ERANGE
) {
362 PyErr_SetString(PyExc_ValueError
,
363 "0.0 to a negative or complex power");
366 return PyComplex_FromCComplex(p
);
370 complex_neg(PyComplexObject
*v
)
373 neg
.real
= -v
->cval
.real
;
374 neg
.imag
= -v
->cval
.imag
;
375 return PyComplex_FromCComplex(neg
);
379 complex_pos(PyComplexObject
*v
)
382 return (PyObject
*)v
;
386 complex_abs(PyComplexObject
*v
)
389 PyFPE_START_PROTECT("complex_abs", return 0)
390 result
= hypot(v
->cval
.real
,v
->cval
.imag
);
391 PyFPE_END_PROTECT(result
)
392 return PyFloat_FromDouble(result
);
396 complex_nonzero(PyComplexObject
*v
)
398 return v
->cval
.real
!= 0.0 || v
->cval
.imag
!= 0.0;
402 complex_coerce(PyObject
**pv
, PyObject
**pw
)
406 if (PyInt_Check(*pw
)) {
407 cval
.real
= (double)PyInt_AsLong(*pw
);
408 *pw
= PyComplex_FromCComplex(cval
);
412 else if (PyLong_Check(*pw
)) {
413 cval
.real
= PyLong_AsDouble(*pw
);
414 *pw
= PyComplex_FromCComplex(cval
);
418 else if (PyFloat_Check(*pw
)) {
419 cval
.real
= PyFloat_AsDouble(*pw
);
420 *pw
= PyComplex_FromCComplex(cval
);
424 return 1; /* Can't do it */
428 complex_int(PyObject
*v
)
430 PyErr_SetString(PyExc_TypeError
,
431 "can't convert complex to int; use e.g. int(abs(z))");
436 complex_long(PyObject
*v
)
438 PyErr_SetString(PyExc_TypeError
,
439 "can't convert complex to long; use e.g. long(abs(z))");
444 complex_float(PyObject
*v
)
446 PyErr_SetString(PyExc_TypeError
,
447 "can't convert complex to float; use e.g. abs(z)");
452 complex_conjugate(PyObject
*self
, PyObject
*args
)
455 if (!PyArg_ParseTuple(args
, ":conjugate"))
457 c
= ((PyComplexObject
*)self
)->cval
;
459 return PyComplex_FromCComplex(c
);
462 static PyMethodDef complex_methods
[] = {
463 {"conjugate", complex_conjugate
, 1},
464 {NULL
, NULL
} /* sentinel */
469 complex_getattr(PyComplexObject
*self
, char *name
)
471 if (strcmp(name
, "real") == 0)
472 return (PyObject
*)PyFloat_FromDouble(self
->cval
.real
);
473 else if (strcmp(name
, "imag") == 0)
474 return (PyObject
*)PyFloat_FromDouble(self
->cval
.imag
);
475 else if (strcmp(name
, "__members__") == 0)
476 return Py_BuildValue("[ss]", "imag", "real");
477 return Py_FindMethod(complex_methods
, (PyObject
*)self
, name
);
480 static PyNumberMethods complex_as_number
= {
481 (binaryfunc
)complex_add
, /*nb_add*/
482 (binaryfunc
)complex_sub
, /*nb_subtract*/
483 (binaryfunc
)complex_mul
, /*nb_multiply*/
484 (binaryfunc
)complex_div
, /*nb_divide*/
485 (binaryfunc
)complex_remainder
, /*nb_remainder*/
486 (binaryfunc
)complex_divmod
, /*nb_divmod*/
487 (ternaryfunc
)complex_pow
, /*nb_power*/
488 (unaryfunc
)complex_neg
, /*nb_negative*/
489 (unaryfunc
)complex_pos
, /*nb_positive*/
490 (unaryfunc
)complex_abs
, /*nb_absolute*/
491 (inquiry
)complex_nonzero
, /*nb_nonzero*/
498 (coercion
)complex_coerce
, /*nb_coerce*/
499 (unaryfunc
)complex_int
, /*nb_int*/
500 (unaryfunc
)complex_long
, /*nb_long*/
501 (unaryfunc
)complex_float
, /*nb_float*/
506 PyTypeObject PyComplex_Type
= {
507 PyObject_HEAD_INIT(&PyType_Type
)
510 sizeof(PyComplexObject
),
512 (destructor
)complex_dealloc
, /*tp_dealloc*/
513 (printfunc
)complex_print
, /*tp_print*/
514 (getattrfunc
)complex_getattr
, /*tp_getattr*/
516 (cmpfunc
)complex_compare
, /*tp_compare*/
517 (reprfunc
)complex_repr
, /*tp_repr*/
518 &complex_as_number
, /*tp_as_number*/
519 0, /*tp_as_sequence*/
521 (hashfunc
)complex_hash
, /*tp_hash*/