14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Complex numbers 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# --------------- 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# [Now that Python has a complex data type built-in, this is not very 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# useful, but it's still a nice example class] 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# This module represents complex numbers as instances of the class Complex. 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# A Complex instance z has two data attribues, z.re (the real part) and z.im 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# (the imaginary part). In fact, z.re and z.im can have any value -- all 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# arithmetic operators work regardless of the type of z.re and z.im (as long 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# as they support numerical operations). 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# The following functions exist (Complex is actually a class): 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Complex([re [,im]) -> creates a complex number from a real and an imaginary part 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes) 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# if z is a tuple(re, im) it will also be converted 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# PolarToComplex([r [,phi [,fullcircle]]]) -> 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# the complex number z for which r == z.radius() and phi == z.angle(fullcircle) 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# (r and phi default to 0) 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z). 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Complex numbers have the following methods: 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z.abs() -> absolute value of z 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z.radius() == z.abs() 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z.phi([fullcircle]) == z.angle(fullcircle) 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# These standard functions and unary operators accept complex arguments: 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# abs(z) 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# -z 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# +z 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# not z 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# repr(z) == `z` 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# str(z) 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# the result equals hash(z.re) 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Note that hex(z) and oct(z) are not defined. 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# These conversions accept complex arguments only if their imaginary part is zero: 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# int(z) 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# long(z) 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# float(z) 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# The following operators accept two complex numbers, or one complex number 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# and one real number (int, long or float): 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z1 + z2 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z1 - z2 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z1 * z2 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# z1 / z2 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# pow(z1, z2) 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# cmp(z1, z2) 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Note that z1 % z2 and divmod(z1, z2) are not defined, 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# nor are shift and mask operations. 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# The standard module math does not support complex numbers. 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# The cmath modules should be used instead. 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Idea: 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# add a class Polar(r, phi) and mixed-mode arithmetic which 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# chooses the most appropriate type for the result: 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Complex for +,-,cmp 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Polar for *,/,pow 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport math 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtwopi = math.pi*2.0 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmhalfpi = math.pi/2.0 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef IsComplex(obj): 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return hasattr(obj, 're') and hasattr(obj, 'im') 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef ToComplex(obj): 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if IsComplex(obj): 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return obj 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elif isinstance(obj, tuple): 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(*obj) 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(obj) 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef PolarToComplex(r = 0, phi = 0, fullcircle = twopi): 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm phi = phi * (twopi / fullcircle) 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(math.cos(phi)*r, math.sin(phi)*r) 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef Re(obj): 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if IsComplex(obj): 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return obj.re 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return obj 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef Im(obj): 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if IsComplex(obj): 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return obj.im 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Complex: 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, re=0, im=0): 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _re = 0 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _im = 0 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if IsComplex(re): 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _re = re.re 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _im = re.im 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _re = re 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if IsComplex(im): 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _re = _re - im.im 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _im = _im + im.re 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _im = _im + im 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # this class is immutable, so setting self.re directly is 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # not possible. 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__dict__['re'] = _re 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__dict__['im'] = _im 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __setattr__(self, name, value): 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError, 'Complex numbers are immutable' 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __hash__(self): 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self.im: 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return hash(self.re) 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return hash((self.re, self.im)) 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __repr__(self): 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self.im: 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Complex(%r)' % (self.re,) 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Complex(%r, %r)' % (self.re, self.im) 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __str__(self): 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not self.im: 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return repr(self.re) 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 'Complex(%r, %r)' % (self.re, self.im) 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __neg__(self): 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(-self.re, -self.im) 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __pos__(self): 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __abs__(self): 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return math.hypot(self.re, self.im) 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __int__(self): 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.im: 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "can't convert Complex with nonzero im to int" 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return int(self.re) 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __long__(self): 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.im: 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "can't convert Complex with nonzero im to long" 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return long(self.re) 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __float__(self): 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.im: 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise ValueError, "can't convert Complex with nonzero im to float" 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return float(self.re) 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __cmp__(self, other): 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return cmp((self.re, self.im), (other.re, other.im)) 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rcmp__(self, other): 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return cmp(other, self) 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __nonzero__(self): 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return not (self.re == self.im == 0) 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm abs = radius = __abs__ 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def angle(self, fullcircle = twopi): 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi) 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm phi = angle 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __add__(self, other): 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(self.re + other.re, self.im + other.im) 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __radd__ = __add__ 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __sub__(self, other): 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(self.re - other.re, self.im - other.im) 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rsub__(self, other): 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return other - self 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __mul__(self, other): 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(self.re*other.re - self.im*other.im, 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.re*other.im + self.im*other.re) 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm __rmul__ = __mul__ 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __div__(self, other): 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d = float(other.re*other.re + other.im*other.im) 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not d: raise ZeroDivisionError, 'Complex division' 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex((self.re*other.re + self.im*other.im) / d, 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (self.im*other.re - self.re*other.im) / d) 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rdiv__(self, other): 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm other = ToComplex(other) 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return other / self 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __pow__(self, n, z=None): 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if z is not None: 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise TypeError, 'Complex does not support ternary pow()' 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if IsComplex(n): 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n.im: 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.im: raise TypeError, 'Complex to the Complex power' 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: return exp(math.log(self.re)*n) 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = n.re 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = pow(self.abs(), n) 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm phi = n*self.angle() 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(math.cos(phi)*r, math.sin(phi)*r) 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __rpow__(self, base): 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm base = ToComplex(base) 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return pow(base, self) 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef exp(z): 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = math.exp(z.re) 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return Complex(math.cos(z.im)*r,math.sin(z.im)*r) 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef checkop(expr, a, b, value, fuzz = 1e-6): 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print ' ', a, 'and', b, 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result = eval(expr) 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except: 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm result = sys.exc_type 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print '->', result 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(result, str) or isinstance(value, str): 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ok = (result == value) 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ok = abs(result - value) <= fuzz 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not ok: 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print '!!\t!!\t!! should be', value, 'diff', abs(result - value) 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test(): 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print 'test constructors' 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm constructor_test = ( 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # "expect" is an array [re,im] "got" the Complex. 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (0,0), Complex() ), 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (0,0), Complex() ), 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (1,0), Complex(1) ), 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (0,1), Complex(0,1) ), 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (1,2), Complex(Complex(1,2)) ), 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (1,3), Complex(Complex(1,2),1) ), 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (0,0), Complex(0,Complex(0,0)) ), 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (3,4), Complex(3,Complex(4)) ), 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (-1,3), Complex(1,Complex(3,2)) ), 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ( (-7,6), Complex(Complex(1,2),Complex(4,8)) ) ) 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cnt = [0,0] 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for t in constructor_test: 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cnt[0] += 1 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ((t[0][0]!=t[1].re)or(t[0][1]!=t[1].im)): 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print " expected", t[0], "got", t[1] 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cnt[1] += 1 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print " ", cnt[1], "of", cnt[0], "tests failed" 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # test operators 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm testsuite = { 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'a+b': [ 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, 10, 11), 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, Complex(0,10), Complex(1,10)), 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), 1, Complex(1,10)), 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), Complex(1), Complex(1,10)), 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(1), Complex(0,10), Complex(1,10)), 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'a-b': [ 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, 10, -9), 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, Complex(0,10), Complex(1,-10)), 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), 1, Complex(-1,10)), 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), Complex(1), Complex(-1,10)), 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(1), Complex(0,10), Complex(1,-10)), 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'a*b': [ 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, 10, 10), 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, Complex(0,10), Complex(0, 10)), 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), 1, Complex(0,10)), 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), Complex(1), Complex(0,10)), 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(1), Complex(0,10), Complex(0,10)), 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'a/b': [ 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1., 10, 0.1), 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, Complex(0,10), Complex(0, -0.1)), 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0, 10), 1, Complex(0, 10)), 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0, 10), Complex(1), Complex(0, 10)), 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(1), Complex(0,10), Complex(0, -0.1)), 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'pow(a,b)': [ 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, 10, 1), 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, Complex(0,10), 1), 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), 1, Complex(0,10)), 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), Complex(1), Complex(0,10)), 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(1), Complex(0,10), 1), 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (2, Complex(4,0), 16), 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'cmp(a,b)': [ 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, 10, -1), 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (1, Complex(0,10), 1), 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), 1, -1), 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(0,10), Complex(1), -1), 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Complex(1), Complex(0,10), 1), 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for expr in sorted(testsuite): 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print expr + ':' 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t = (expr,) 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for item in testsuite[expr]: 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm checkop(*(t+item)) 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == '__main__': 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test() 321