1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Complex object implementation */
34 /* Borrows heavily from floatobject.c */
36 /* Submitted by Jim Hugunin */
38 #ifndef WITHOUT_COMPLEX
48 /* elementary operations on complex numbers */
50 static Py_complex c_1
= {1., 0.};
56 r
.real
= a
.real
+ b
.real
;
57 r
.imag
= a
.imag
+ b
.imag
;
61 Py_complex
c_diff(a
,b
)
65 r
.real
= a
.real
- b
.real
;
66 r
.imag
= a
.imag
- b
.imag
;
79 Py_complex
c_prod(a
,b
)
83 r
.real
= a
.real
*b
.real
- a
.imag
*b
.imag
;
84 r
.imag
= a
.real
*b
.imag
+ a
.imag
*b
.real
;
88 Py_complex
c_quot(a
,b
)
92 double d
= b
.real
*b
.real
+ b
.imag
*b
.imag
;
95 r
.real
= (a
.real
*b
.real
+ a
.imag
*b
.imag
)/d
;
96 r
.imag
= (a
.imag
*b
.real
- a
.real
*b
.imag
)/d
;
100 Py_complex
c_pow(a
,b
)
104 double vabs
,len
,at
,phase
;
105 if (b
.real
== 0. && b
.imag
== 0.) {
109 else if (a
.real
== 0. && a
.imag
== 0.) {
110 if (b
.imag
!= 0. || b
.real
< 0.)
116 vabs
= hypot(a
.real
,a
.imag
);
117 len
= pow(vabs
,b
.real
);
118 at
= atan2(a
.imag
, a
.real
);
121 len
/= exp(at
*b
.imag
);
122 phase
+= b
.imag
*log(vabs
);
124 r
.real
= len
*cos(phase
);
125 r
.imag
= len
*sin(phase
);
130 static Py_complex
c_powu(x
, n
)
138 while (mask
> 0 && n
>= mask
) {
147 static Py_complex
c_powi(x
, n
)
153 if (n
> 100 || n
< -100) {
154 cn
.real
= (double) n
;
161 return c_quot(c_1
,c_powu(x
,-n
));
166 PyComplex_FromCComplex(cval
)
169 register PyComplexObject
*op
=
170 (PyComplexObject
*) malloc(sizeof(PyComplexObject
));
172 return PyErr_NoMemory();
173 op
->ob_type
= &PyComplex_Type
;
175 _Py_NewReference((PyObject
*)op
);
176 return (PyObject
*) op
;
180 PyComplex_FromDoubles(real
, imag
)
186 return PyComplex_FromCComplex(c
);
190 PyComplex_RealAsDouble(op
)
193 if (PyComplex_Check(op
)) {
194 return ((PyComplexObject
*)op
)->cval
.real
;
196 return PyFloat_AsDouble(op
);
201 PyComplex_ImagAsDouble(op
)
204 if (PyComplex_Check(op
)) {
205 return ((PyComplexObject
*)op
)->cval
.imag
;
212 PyComplex_AsCComplex(op
)
216 if (PyComplex_Check(op
)) {
217 return ((PyComplexObject
*)op
)->cval
;
219 cv
.real
= PyFloat_AsDouble(op
);
234 complex_buf_repr(buf
, v
)
238 if (v
->cval
.real
== 0.)
239 sprintf(buf
, "%.12gj", v
->cval
.imag
);
241 sprintf(buf
, "(%.12g%+.12gj)", v
->cval
.real
, v
->cval
.imag
);
245 complex_print(v
, fp
, flags
)
248 int flags
; /* Not used but required by interface */
251 complex_buf_repr(buf
, v
);
261 complex_buf_repr(buf
, v
);
262 return PyString_FromString(buf
);
266 complex_compare(v
, w
)
267 PyComplexObject
*v
, *w
;
269 /* Note: "greater" and "smaller" have no meaning for complex numbers,
270 but Python requires that they be defined nevertheless. */
274 if (i
.real
== j
.real
&& i
.imag
== j
.imag
)
276 else if (i
.real
!= j
.real
)
277 return (i
.real
< j
.real
) ? -1 : 1;
279 return (i
.imag
< j
.imag
) ? -1 : 1;
286 double intpart
, fractpart
;
289 /* This is designed so that Python numbers with the same
290 value hash to the same value, otherwise comparisons
291 of mapping keys will turn out weird */
293 #ifdef MPW /* MPW C modf expects pointer to extended as second argument */
296 fractpart
= modf(v
->cval
.real
, &e
);
300 fractpart
= modf(v
->cval
.real
, &intpart
);
303 if (fractpart
== 0.0 && v
->cval
.imag
== 0.0) {
304 if (intpart
> 0x7fffffffL
|| -intpart
> 0x7fffffffL
) {
305 /* Convert to long int and use its hash... */
306 PyObject
*w
= PyLong_FromDouble(v
->cval
.real
);
309 x
= PyObject_Hash(w
);
316 fractpart
= frexp(fractpart
, &expo
);
317 fractpart
= fractpart
* 2147483648.0; /* 2**31 */
318 hipart
= (long)fractpart
; /* Take the top 32 bits */
319 fractpart
= (fractpart
- (double)hipart
) * 2147483648.0;
320 /* Get the next 32 bits */
321 x
= hipart
+ (long)fractpart
+ (long)intpart
+ (expo
<< 15);
322 /* Combine everything */
324 if (v
->cval
.imag
!= 0.0) { /* Hash the imaginary part */
325 /* XXX Note that this hashes complex(x, y)
326 to the same value as complex(y, x).
327 Still better than it used to be :-) */
331 fractpart
= modf(v
->cval
.imag
, &e
);
335 fractpart
= modf(v
->cval
.imag
, &intpart
);
337 fractpart
= frexp(fractpart
, &expo
);
338 fractpart
= fractpart
* 2147483648.0; /* 2**31 */
339 hipart
= (long)fractpart
; /* Take the top 32 bits */
341 (fractpart
- (double)hipart
) * 2147483648.0;
342 /* Get the next 32 bits */
343 x
^= hipart
+ (long)fractpart
+
344 (long)intpart
+ (expo
<< 15);
345 /* Combine everything */
359 PyFPE_START_PROTECT("complex_add", return 0)
360 result
= c_sum(v
->cval
,w
->cval
);
361 PyFPE_END_PROTECT(result
)
362 return PyComplex_FromCComplex(result
);
371 PyFPE_START_PROTECT("complex_sub", return 0)
372 result
= c_diff(v
->cval
,w
->cval
);
373 PyFPE_END_PROTECT(result
)
374 return PyComplex_FromCComplex(result
);
383 PyFPE_START_PROTECT("complex_mul", return 0)
384 result
= c_prod(v
->cval
,w
->cval
);
385 PyFPE_END_PROTECT(result
)
386 return PyComplex_FromCComplex(result
);
395 PyFPE_START_PROTECT("complex_div", return 0)
397 quot
= c_quot(v
->cval
,w
->cval
);
398 PyFPE_END_PROTECT(quot
)
400 PyErr_SetString(PyExc_ZeroDivisionError
, "complex division");
403 return PyComplex_FromCComplex(quot
);
407 complex_remainder(v
, w
)
413 div
= c_quot(v
->cval
,w
->cval
); /* The raw divisor value. */
415 PyErr_SetString(PyExc_ZeroDivisionError
, "complex remainder");
418 div
.real
= floor(div
.real
); /* Use the floor of the real part. */
420 mod
= c_diff(v
->cval
, c_prod(w
->cval
, div
));
422 return PyComplex_FromCComplex(mod
);
434 div
= c_quot(v
->cval
,w
->cval
); /* The raw divisor value. */
436 PyErr_SetString(PyExc_ZeroDivisionError
, "complex divmod()");
439 div
.real
= floor(div
.real
); /* Use the floor of the real part. */
441 mod
= c_diff(v
->cval
, c_prod(w
->cval
, div
));
442 d
= PyComplex_FromCComplex(div
);
443 m
= PyComplex_FromCComplex(mod
);
444 z
= Py_BuildValue("(OO)", d
, m
);
460 if ((PyObject
*)z
!=Py_None
) {
461 PyErr_SetString(PyExc_ValueError
, "complex modulo");
465 PyFPE_START_PROTECT("complex_pow", return 0)
467 exponent
= ((PyComplexObject
*)w
)->cval
;
468 int_exponent
= (long)exponent
.real
;
469 if (exponent
.imag
== 0. && exponent
.real
== int_exponent
)
470 p
= c_powi(v
->cval
,int_exponent
);
472 p
= c_pow(v
->cval
,exponent
);
475 if (errno
== ERANGE
) {
476 PyErr_SetString(PyExc_ValueError
,
477 "0.0 to a negative or complex power");
481 return PyComplex_FromCComplex(p
);
489 neg
.real
= -v
->cval
.real
;
490 neg
.imag
= -v
->cval
.imag
;
491 return PyComplex_FromCComplex(neg
);
499 return (PyObject
*)v
;
507 PyFPE_START_PROTECT("complex_abs", return 0)
508 result
= hypot(v
->cval
.real
,v
->cval
.imag
);
509 PyFPE_END_PROTECT(result
)
510 return PyFloat_FromDouble(result
);
517 return v
->cval
.real
!= 0.0 || v
->cval
.imag
!= 0.0;
521 complex_coerce(pv
, pw
)
527 if (PyInt_Check(*pw
)) {
528 cval
.real
= (double)PyInt_AsLong(*pw
);
529 *pw
= PyComplex_FromCComplex(cval
);
533 else if (PyLong_Check(*pw
)) {
534 cval
.real
= PyLong_AsDouble(*pw
);
535 *pw
= PyComplex_FromCComplex(cval
);
539 else if (PyFloat_Check(*pw
)) {
540 cval
.real
= PyFloat_AsDouble(*pw
);
541 *pw
= PyComplex_FromCComplex(cval
);
545 return 1; /* Can't do it */
552 PyErr_SetString(PyExc_TypeError
,
553 "can't convert complex to int; use e.g. int(abs(z))");
561 PyErr_SetString(PyExc_TypeError
,
562 "can't convert complex to long; use e.g. long(abs(z))");
570 PyErr_SetString(PyExc_TypeError
,
571 "can't convert complex to float; use e.g. abs(z)");
576 complex_conjugate(self
, args
)
581 if (!PyArg_ParseTuple(args
, ""))
583 c
= ((PyComplexObject
*)self
)->cval
;
585 return PyComplex_FromCComplex(c
);
588 static PyMethodDef complex_methods
[] = {
589 {"conjugate", complex_conjugate
, 1},
590 {NULL
, NULL
} /* sentinel */
595 complex_getattr(self
, name
)
596 PyComplexObject
*self
;
599 if (strcmp(name
, "real") == 0)
600 return (PyObject
*)PyFloat_FromDouble(self
->cval
.real
);
601 else if (strcmp(name
, "imag") == 0)
602 return (PyObject
*)PyFloat_FromDouble(self
->cval
.imag
);
603 else if (strcmp(name
, "__members__") == 0)
604 return Py_BuildValue("[ss]", "imag", "real");
605 return Py_FindMethod(complex_methods
, (PyObject
*)self
, name
);
608 static PyNumberMethods complex_as_number
= {
609 (binaryfunc
)complex_add
, /*nb_add*/
610 (binaryfunc
)complex_sub
, /*nb_subtract*/
611 (binaryfunc
)complex_mul
, /*nb_multiply*/
612 (binaryfunc
)complex_div
, /*nb_divide*/
613 (binaryfunc
)complex_remainder
, /*nb_remainder*/
614 (binaryfunc
)complex_divmod
, /*nb_divmod*/
615 (ternaryfunc
)complex_pow
, /*nb_power*/
616 (unaryfunc
)complex_neg
, /*nb_negative*/
617 (unaryfunc
)complex_pos
, /*nb_positive*/
618 (unaryfunc
)complex_abs
, /*nb_absolute*/
619 (inquiry
)complex_nonzero
, /*nb_nonzero*/
626 (coercion
)complex_coerce
, /*nb_coerce*/
627 (unaryfunc
)complex_int
, /*nb_int*/
628 (unaryfunc
)complex_long
, /*nb_long*/
629 (unaryfunc
)complex_float
, /*nb_float*/
634 PyTypeObject PyComplex_Type
= {
635 PyObject_HEAD_INIT(&PyType_Type
)
638 sizeof(PyComplexObject
),
640 (destructor
)complex_dealloc
, /*tp_dealloc*/
641 (printfunc
)complex_print
, /*tp_print*/
642 (getattrfunc
)complex_getattr
, /*tp_getattr*/
644 (cmpfunc
)complex_compare
, /*tp_compare*/
645 (reprfunc
)complex_repr
, /*tp_repr*/
646 &complex_as_number
, /*tp_as_number*/
647 0, /*tp_as_sequence*/
649 (hashfunc
)complex_hash
, /*tp_hash*/