blob: 14661f1262a212f5db0c36e7aa171dfb55800ea4 [file] [log] [blame]
Guido van Rossumf9fca921996-01-12 00:47:05 +00001/* Complex object implementation */
2
3/* Borrows heavily from floatobject.c */
4
5#ifndef WITHOUT_COMPLEX
6
7#include "allobjects.h"
8#include "modsupport.h"
9
10#include <errno.h>
11#include "mymath.h"
12
13#ifdef i860
14/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
15#undef HUGE_VAL
16#endif
17
18#ifdef HUGE_VAL
19#define CHECK(x) if (errno != 0) ; \
20 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
21 else errno = ERANGE
22#else
23#define CHECK(x) /* Don't know how to check */
24#endif
25
26#ifdef HAVE_LIMITS_H
27#include <limits.h>
28#endif
29
30#ifndef LONG_MAX
31#define LONG_MAX 0X7FFFFFFFL
32#endif
33
34#ifndef LONG_MIN
35#define LONG_MIN (-LONG_MAX-1)
36#endif
37
38#ifdef __NeXT__
39#ifdef __sparc__
40/*
41 * This works around a bug in the NS/Sparc 3.3 pre-release
42 * limits.h header file.
43 * 10-Feb-1995 bwarsaw@cnri.reston.va.us
44 */
45#undef LONG_MIN
46#define LONG_MIN (-LONG_MAX-1)
47#endif
48#endif
49
50#if !defined(__STDC__) && !defined(macintosh)
51extern double fmod PROTO((double, double));
52extern double pow PROTO((double, double));
53#endif
54
55
56/* elementary operations on complex numbers */
57
Guido van Rossum363078a1996-05-24 20:45:01 +000058static int c_error;
Guido van Rossum9e720e31996-07-21 02:31:35 +000059static Py_complex c_1 = {1., 0.};
Guido van Rossumf9fca921996-01-12 00:47:05 +000060
Guido van Rossum9e720e31996-07-21 02:31:35 +000061Py_complex c_sum(a,b)
62 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000063{
Guido van Rossum9e720e31996-07-21 02:31:35 +000064 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000065 r.real = a.real + b.real;
66 r.imag = a.imag + b.imag;
67 return r;
68}
69
Guido van Rossum9e720e31996-07-21 02:31:35 +000070Py_complex c_diff(a,b)
71 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000072{
Guido van Rossum9e720e31996-07-21 02:31:35 +000073 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000074 r.real = a.real - b.real;
75 r.imag = a.imag - b.imag;
76 return r;
77}
78
Guido van Rossum9e720e31996-07-21 02:31:35 +000079Py_complex c_neg(a)
80 Py_complex a;
Guido van Rossumf9fca921996-01-12 00:47:05 +000081{
Guido van Rossum9e720e31996-07-21 02:31:35 +000082 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000083 r.real = -a.real;
84 r.imag = -a.imag;
85 return r;
86}
87
Guido van Rossum9e720e31996-07-21 02:31:35 +000088Py_complex c_prod(a,b)
89 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000090{
Guido van Rossum9e720e31996-07-21 02:31:35 +000091 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +000092 r.real = a.real*b.real - a.imag*b.imag;
93 r.imag = a.real*b.imag + a.imag*b.real;
94 return r;
95}
96
Guido van Rossum9e720e31996-07-21 02:31:35 +000097Py_complex c_quot(a,b)
98 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +000099{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000100 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000101 double d = b.real*b.real + b.imag*b.imag;
102 if (d == 0.)
103 c_error = 1;
104 r.real = (a.real*b.real + a.imag*b.imag)/d;
105 r.imag = (a.imag*b.real - a.real*b.imag)/d;
106 return r;
107}
108
Guido van Rossum9e720e31996-07-21 02:31:35 +0000109Py_complex c_pow(a,b)
110 Py_complex a,b;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000111{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000112 Py_complex r;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000113 double vabs,len,at,phase;
114 if (b.real == 0. && b.imag == 0.) {
115 r.real = 1.;
116 r.imag = 0.;
117 }
118 else if (a.real == 0. && a.imag == 0.) {
119 if (b.imag != 0. || b.real < 0.)
120 c_error = 2;
121 r.real = 0.;
122 r.imag = 0.;
123 }
124 else {
125 vabs = hypot(a.real,a.imag);
126 len = pow(vabs,b.real);
127 at = atan2(a.imag, a.real);
128 phase = at*b.real;
129 if (b.imag != 0.0) {
130 len /= exp(at*b.imag);
131 phase += b.imag*log(vabs);
132 }
133 r.real = len*cos(phase);
134 r.imag = len*sin(phase);
135 }
136 return r;
137}
138
Guido van Rossum9e720e31996-07-21 02:31:35 +0000139static Py_complex c_powu(x, n)
140 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000141 long n;
142{
Guido van Rossum926518b1996-08-19 19:30:45 +0000143 Py_complex r, p;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000144 long mask = 1;
Guido van Rossum926518b1996-08-19 19:30:45 +0000145 r = c_1;
146 p = x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000147 while (mask > 0 && n >= mask) {
148 if (n & mask)
149 r = c_prod(r,p);
150 mask <<= 1;
151 p = c_prod(p,p);
152 }
153 return r;
154}
155
Guido van Rossum9e720e31996-07-21 02:31:35 +0000156static Py_complex c_powi(x, n)
157 Py_complex x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000158 long n;
159{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000160 Py_complex cn;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000161
162 if (n > 100 || n < -100) {
163 cn.real = (double) n;
164 cn.imag = 0.;
165 return c_pow(x,cn);
166 }
167 else if (n > 0)
168 return c_powu(x,n);
169 else
170 return c_quot(c_1,c_powu(x,-n));
171
172}
173
174PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000175PyComplex_FromCComplex(cval)
176 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000177{
Guido van Rossum926518b1996-08-19 19:30:45 +0000178 register complexobject *op =
179 (complexobject *) malloc(sizeof(complexobject));
Guido van Rossumf9fca921996-01-12 00:47:05 +0000180 if (op == NULL)
181 return err_nomem();
182 op->ob_type = &Complextype;
183 op->cval = cval;
184 NEWREF(op);
185 return (object *) op;
186}
187
188PyObject *
Guido van Rossum926518b1996-08-19 19:30:45 +0000189PyComplex_FromDoubles(real, imag)
190 double real, imag;
191{
192 Py_complex c;
193 c.real = real;
194 c.imag = imag;
195 return PyComplex_FromCComplex(c);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000196}
197
198double
Guido van Rossum926518b1996-08-19 19:30:45 +0000199PyComplex_RealAsDouble(op)
200 PyObject *op;
201{
202 if (PyComplex_Check(op)) {
203 return ((PyComplexObject *)op)->cval.real;
204 } else {
205 return PyFloat_AsDouble(op);
206 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000207}
208
209double
Guido van Rossum926518b1996-08-19 19:30:45 +0000210PyComplex_ImagAsDouble(op)
211 PyObject *op;
212{
213 if (PyComplex_Check(op)) {
214 return ((PyComplexObject *)op)->cval.imag;
215 } else {
216 return 0.0;
217 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000218}
219
Guido van Rossum9e720e31996-07-21 02:31:35 +0000220Py_complex
Guido van Rossum926518b1996-08-19 19:30:45 +0000221PyComplex_AsCComplex(op)
222 PyObject *op;
223{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000224 Py_complex cv;
Guido van Rossumcf3d1081996-01-12 01:21:14 +0000225 if (PyComplex_Check(op)) {
226 return ((PyComplexObject *)op)->cval;
227 } else {
228 cv.real = PyFloat_AsDouble(op);
229 cv.imag = 0.;
230 return cv;
231 }
232}
233
Guido van Rossumf9fca921996-01-12 00:47:05 +0000234static void
235complex_dealloc(op)
236 object *op;
237{
238 DEL(op);
239}
240
241
Guido van Rossum363078a1996-05-24 20:45:01 +0000242static void
Guido van Rossumf9fca921996-01-12 00:47:05 +0000243complex_buf_repr(buf, v)
244 char *buf;
245 complexobject *v;
246{
247 if (v->cval.real == 0.)
Guido van Rossum72418791996-01-25 16:21:31 +0000248 sprintf(buf, "%.12gj", v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000249 else
Guido van Rossum72418791996-01-25 16:21:31 +0000250 sprintf(buf, "(%.12g%+.12gj)", v->cval.real, v->cval.imag);
Guido van Rossumf9fca921996-01-12 00:47:05 +0000251}
252
253static int
254complex_print(v, fp, flags)
255 complexobject *v;
256 FILE *fp;
257 int flags; /* Not used but required by interface */
258{
259 char buf[100];
260 complex_buf_repr(buf, v);
261 fputs(buf, fp);
262 return 0;
263}
264
265static object *
266complex_repr(v)
267 complexobject *v;
268{
269 char buf[100];
270 complex_buf_repr(buf, v);
271 return newstringobject(buf);
272}
273
274static int
275complex_compare(v, w)
276 complexobject *v, *w;
277{
278/* Note: "greater" and "smaller" have no meaning for complex numbers,
279 but Python requires that they be defined nevertheless. */
Guido van Rossum926518b1996-08-19 19:30:45 +0000280 Py_complex i, j;
281 i = v->cval;
282 j = w->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000283 if (i.real == j.real && i.imag == j.imag)
284 return 0;
285 else if (i.real != j.real)
286 return (i.real < j.real) ? -1 : 1;
287 else
288 return (i.imag < j.imag) ? -1 : 1;
289}
290
291static long
292complex_hash(v)
293 complexobject *v;
294{
295 double intpart, fractpart;
296 int expo;
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000297 long hipart, x;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000298 /* This is designed so that Python numbers with the same
299 value hash to the same value, otherwise comparisons
300 of mapping keys will turn out weird */
301
302#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
303{
304 extended e;
305 fractpart = modf(v->cval.real, &e);
306 intpart = e;
307}
308#else
309 fractpart = modf(v->cval.real, &intpart);
310#endif
311
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000312 if (fractpart == 0.0 && v->cval.imag == 0.0) {
Guido van Rossumf9fca921996-01-12 00:47:05 +0000313 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
314 /* Convert to long int and use its hash... */
315 object *w = dnewlongobject(v->cval.real);
316 if (w == NULL)
317 return -1;
318 x = hashobject(w);
319 DECREF(w);
320 return x;
321 }
322 x = (long)intpart;
323 }
324 else {
325 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000326 fractpart = fractpart * 2147483648.0; /* 2**31 */
327 hipart = (long)fractpart; /* Take the top 32 bits */
328 fractpart = (fractpart - (double)hipart) * 2147483648.0;
329 /* Get the next 32 bits */
330 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
331 /* Combine everything */
332
333 if (v->cval.imag != 0.0) { /* Hash the imaginary part */
334 /* XXX Note that this hashes complex(x, y)
335 to the same value as complex(y, x).
336 Still better than it used to be :-) */
337#ifdef MPW
338 {
339 extended e;
340 fractpart = modf(v->cval.imag, &e);
341 intpart = e;
342 }
343#else
344 fractpart = modf(v->cval.imag, &intpart);
345#endif
346 fractpart = frexp(fractpart, &expo);
347 fractpart = fractpart * 2147483648.0; /* 2**31 */
348 hipart = (long)fractpart; /* Take the top 32 bits */
349 fractpart =
350 (fractpart - (double)hipart) * 2147483648.0;
351 /* Get the next 32 bits */
352 x ^= hipart + (long)fractpart +
353 (long)intpart + (expo << 15);
354 /* Combine everything */
355 }
Guido van Rossumf9fca921996-01-12 00:47:05 +0000356 }
357 if (x == -1)
358 x = -2;
359 return x;
360}
361
362static object *
363complex_add(v, w)
364 complexobject *v;
365 complexobject *w;
366{
367 return newcomplexobject(c_sum(v->cval,w->cval));
368}
369
370static object *
371complex_sub(v, w)
372 complexobject *v;
373 complexobject *w;
374{
375 return newcomplexobject(c_diff(v->cval,w->cval));
376}
377
378static object *
379complex_mul(v, w)
380 complexobject *v;
381 complexobject *w;
382{
383 return newcomplexobject(c_prod(v->cval,w->cval));
384}
385
386static object *
387complex_div(v, w)
388 complexobject *v;
389 complexobject *w;
390{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000391 Py_complex quot;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000392 c_error = 0;
393 quot = c_quot(v->cval,w->cval);
394 if (c_error == 1) {
Guido van Rossum3be12e91996-09-12 20:56:18 +0000395 err_setstr(ZeroDivisionError, "complex division");
Guido van Rossumf9fca921996-01-12 00:47:05 +0000396 return NULL;
397 }
398 return newcomplexobject(quot);
399}
400
Guido van Rossumee09fc11996-09-11 13:55:55 +0000401static object *
402complex_remainder(v, w)
403 complexobject *v;
404 complexobject *w;
405{
Guido van Rossum3be12e91996-09-12 20:56:18 +0000406 Py_complex div, mod;
Guido van Rossum24048581996-09-12 21:02:02 +0000407 c_error = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000408 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
409 if (c_error == 1) {
410 err_setstr(ZeroDivisionError, "complex remainder");
411 return NULL;
412 }
413 div.real = floor(div.real); /* Use the floor of the real part. */
414 div.imag = 0.0;
415 mod = c_diff(v->cval, c_prod(w->cval, div));
416
417 return newcomplexobject(mod);
Guido van Rossumee09fc11996-09-11 13:55:55 +0000418}
419
Guido van Rossumee09fc11996-09-11 13:55:55 +0000420
Guido van Rossum3be12e91996-09-12 20:56:18 +0000421static object *
422complex_divmod(v, w)
423 complexobject *v;
424 complexobject *w;
425{
426 Py_complex div, mod;
427 PyObject *d, *m, *z;
Guido van Rossum24048581996-09-12 21:02:02 +0000428 c_error = 0;
Guido van Rossum3be12e91996-09-12 20:56:18 +0000429 div = c_quot(v->cval,w->cval); /* The raw divisor value. */
430 if (c_error == 1) {
431 err_setstr(ZeroDivisionError, "complex divmod()");
432 return NULL;
433 }
434 div.real = floor(div.real); /* Use the floor of the real part. */
435 div.imag = 0.0;
436 mod = c_diff(v->cval, c_prod(w->cval, div));
437 d = newcomplexobject(div);
438 m = newcomplexobject(mod);
439 z = mkvalue("(OO)", d, m);
440 Py_XDECREF(d);
441 Py_XDECREF(m);
442 return z;
443}
Guido van Rossumf9fca921996-01-12 00:47:05 +0000444
445static object *
446complex_pow(v, w, z)
447 complexobject *v;
448 object *w;
449 complexobject *z;
450{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000451 Py_complex p;
452 Py_complex exponent;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000453 long int_exponent;
454
455 if ((object *)z!=None) {
456 err_setstr(ValueError, "complex modulo");
457 return NULL;
458 }
459
460 c_error = 0;
461 exponent = ((complexobject*)w)->cval;
462 int_exponent = (long)exponent.real;
463 if (exponent.imag == 0. && exponent.real == int_exponent)
464 p = c_powi(v->cval,int_exponent);
465 else
466 p = c_pow(v->cval,exponent);
467
468 if (c_error == 2) {
469 err_setstr(ValueError, "0.0 to a negative or complex power");
470 return NULL;
471 }
472
473 return newcomplexobject(p);
474}
475
476static object *
477complex_neg(v)
478 complexobject *v;
479{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000480 Py_complex neg;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000481 neg.real = -v->cval.real;
482 neg.imag = -v->cval.imag;
483 return newcomplexobject(neg);
484}
485
486static object *
487complex_pos(v)
488 complexobject *v;
489{
490 INCREF(v);
491 return (object *)v;
492}
493
494static object *
495complex_abs(v)
496 complexobject *v;
497{
498 return newfloatobject(hypot(v->cval.real,v->cval.imag));
499}
500
501static int
502complex_nonzero(v)
503 complexobject *v;
504{
505 return v->cval.real != 0.0 && v->cval.imag != 0.0;
506}
507
508static int
509complex_coerce(pv, pw)
510 object **pv;
511 object **pw;
512{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000513 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000514 cval.imag = 0.;
515 if (is_intobject(*pw)) {
516 cval.real = (double)getintvalue(*pw);
517 *pw = newcomplexobject(cval);
518 INCREF(*pv);
519 return 0;
520 }
521 else if (is_longobject(*pw)) {
522 cval.real = dgetlongvalue(*pw);
523 *pw = newcomplexobject(cval);
524 INCREF(*pv);
525 return 0;
526 }
527 else if (is_floatobject(*pw)) {
528 cval.real = getfloatvalue(*pw);
529 *pw = newcomplexobject(cval);
530 INCREF(*pv);
531 return 0;
532 }
533 return 1; /* Can't do it */
534}
535
536static object *
537complex_int(v)
538 object *v;
539{
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000540 err_setstr(TypeError,
541 "can't convert complex to int; use e.g. int(abs(z))");
542 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000543}
544
545static object *
546complex_long(v)
547 object *v;
548{
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000549 err_setstr(TypeError,
550 "can't convert complex to long; use e.g. long(abs(z))");
551 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000552}
553
554static object *
555complex_float(v)
556 object *v;
557{
Guido van Rossumd4ab3cd1996-09-11 22:54:37 +0000558 err_setstr(TypeError,
559 "can't convert complex to float; use e.g. abs(z)");
560 return NULL;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000561}
562
Guido van Rossumf9fca921996-01-12 00:47:05 +0000563static object *
564complex_conjugate(self)
565 object *self;
566{
Guido van Rossum926518b1996-08-19 19:30:45 +0000567 Py_complex c;
568 c = ((complexobject *)self)->cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000569 c.imag = -c.imag;
570 return newcomplexobject(c);
571}
572
573static PyMethodDef complex_methods[] = {
574 {"conjugate", (PyCFunction)complex_conjugate, 1},
575 {NULL, NULL} /* sentinel */
576};
577
578
579static object *
580complex_getattr(self, name)
581 complexobject *self;
582 char *name;
583{
Guido van Rossum9e720e31996-07-21 02:31:35 +0000584 Py_complex cval;
Guido van Rossumf9fca921996-01-12 00:47:05 +0000585 if (strcmp(name, "real") == 0)
586 return (object *)newfloatobject(self->cval.real);
587 else if (strcmp(name, "imag") == 0)
588 return (object *)newfloatobject(self->cval.imag);
589 else if (strcmp(name, "conj") == 0) {
590 cval.real = self->cval.real;
591 cval.imag = -self->cval.imag;
592 return (object *)newcomplexobject(cval);
593 }
594 return findmethod(complex_methods, (object *)self, name);
595}
596
597static number_methods complex_as_number = {
598 (binaryfunc)complex_add, /*nb_add*/
599 (binaryfunc)complex_sub, /*nb_subtract*/
600 (binaryfunc)complex_mul, /*nb_multiply*/
601 (binaryfunc)complex_div, /*nb_divide*/
Guido van Rossumee09fc11996-09-11 13:55:55 +0000602 (binaryfunc)complex_remainder, /*nb_remainder*/
603 (binaryfunc)complex_divmod, /*nb_divmod*/
Guido van Rossumf9fca921996-01-12 00:47:05 +0000604 (ternaryfunc)complex_pow, /*nb_power*/
605 (unaryfunc)complex_neg, /*nb_negative*/
606 (unaryfunc)complex_pos, /*nb_positive*/
607 (unaryfunc)complex_abs, /*nb_absolute*/
608 (inquiry)complex_nonzero, /*nb_nonzero*/
609 0, /*nb_invert*/
610 0, /*nb_lshift*/
611 0, /*nb_rshift*/
612 0, /*nb_and*/
613 0, /*nb_xor*/
614 0, /*nb_or*/
615 (coercion)complex_coerce, /*nb_coerce*/
616 (unaryfunc)complex_int, /*nb_int*/
617 (unaryfunc)complex_long, /*nb_long*/
618 (unaryfunc)complex_float, /*nb_float*/
619 0, /*nb_oct*/
620 0, /*nb_hex*/
621};
622
623typeobject Complextype = {
624 OB_HEAD_INIT(&Typetype)
625 0,
626 "complex",
627 sizeof(complexobject),
628 0,
629 (destructor)complex_dealloc, /*tp_dealloc*/
630 (printfunc)complex_print, /*tp_print*/
631 (getattrfunc)complex_getattr, /*tp_getattr*/
632 0, /*tp_setattr*/
633 (cmpfunc)complex_compare, /*tp_compare*/
634 (reprfunc)complex_repr, /*tp_repr*/
635 &complex_as_number, /*tp_as_number*/
636 0, /*tp_as_sequence*/
637 0, /*tp_as_mapping*/
638 (hashfunc)complex_hash, /*tp_hash*/
639};
640
641#endif