diff options
Diffstat (limited to 'Demo/classes/Complex.py')
-rwxr-xr-x | Demo/classes/Complex.py | 418 |
1 files changed, 209 insertions, 209 deletions
diff --git a/Demo/classes/Complex.py b/Demo/classes/Complex.py index bfb0d95..4585f62 100755 --- a/Demo/classes/Complex.py +++ b/Demo/classes/Complex.py @@ -16,8 +16,8 @@ # ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true # if z is a tuple(re, im) it will also be converted # PolarToComplex([r [,phi [,fullcircle]]]) -> -# the complex number z for which r == z.radius() and phi == z.angle(fullcircle) -# (r and phi default to 0) +# the complex number z for which r == z.radius() and phi == z.angle(fullcircle) +# (r and phi default to 0) # exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z). # # Complex numbers have the following methods: @@ -69,230 +69,230 @@ twopi = math.pi*2.0 halfpi = math.pi/2.0 def IsComplex(obj): - return hasattr(obj, 're') and hasattr(obj, 'im') + return hasattr(obj, 're') and hasattr(obj, 'im') def ToComplex(obj): - if IsComplex(obj): - return obj - elif type(obj) == types.TupleType: - return apply(Complex, obj) - else: - return Complex(obj) + if IsComplex(obj): + return obj + elif type(obj) == types.TupleType: + return apply(Complex, obj) + else: + return Complex(obj) def PolarToComplex(r = 0, phi = 0, fullcircle = twopi): - phi = phi * (twopi / fullcircle) - return Complex(math.cos(phi)*r, math.sin(phi)*r) + phi = phi * (twopi / fullcircle) + return Complex(math.cos(phi)*r, math.sin(phi)*r) def Re(obj): - if IsComplex(obj): - return obj.re - else: - return obj + if IsComplex(obj): + return obj.re + else: + return obj def Im(obj): - if IsComplex(obj): - return obj.im - else: - return obj + if IsComplex(obj): + return obj.im + else: + return obj class Complex: - def __init__(self, re=0, im=0): - if IsComplex(re): - im = i + Complex(0, re.im) - re = re.re - if IsComplex(im): - re = re - im.im - im = im.re - self.__dict__['re'] = re - self.__dict__['im'] = im - - def __setattr__(self, name, value): - raise TypeError, 'Complex numbers are immutable' - - def __hash__(self): - if not self.im: return hash(self.re) - mod = sys.maxint + 1L - return int((hash(self.re) + 2L*hash(self.im) + mod) % (2L*mod) - mod) - - def __repr__(self): - if not self.im: - return 'Complex(%s)' % `self.re` - else: - return 'Complex(%s, %s)' % (`self.re`, `self.im`) - - def __str__(self): - if not self.im: - return `self.re` - else: - return 'Complex(%s, %s)' % (`self.re`, `self.im`) - - def __neg__(self): - return Complex(-self.re, -self.im) - - def __pos__(self): - return self - - def __abs__(self): - # XXX could be done differently to avoid overflow! - return math.sqrt(self.re*self.re + self.im*self.im) - - def __int__(self): - if self.im: - raise ValueError, "can't convert Complex with nonzero im to int" - return int(self.re) - - def __long__(self): - if self.im: - raise ValueError, "can't convert Complex with nonzero im to long" - return long(self.re) - - def __float__(self): - if self.im: - raise ValueError, "can't convert Complex with nonzero im to float" - return float(self.re) - - def __cmp__(self, other): - other = ToComplex(other) - return cmp((self.re, self.im), (other.re, other.im)) - - def __rcmp__(self, other): - other = ToComplex(other) - return cmp(other, self) - - def __nonzero__(self): - return not (self.re == self.im == 0) - - abs = radius = __abs__ - - def angle(self, fullcircle = twopi): - return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi) - - phi = angle - - def __add__(self, other): - other = ToComplex(other) - return Complex(self.re + other.re, self.im + other.im) - - __radd__ = __add__ - - def __sub__(self, other): - other = ToComplex(other) - return Complex(self.re - other.re, self.im - other.im) - - def __rsub__(self, other): - other = ToComplex(other) - return other - self - - def __mul__(self, other): - other = ToComplex(other) - return Complex(self.re*other.re - self.im*other.im, - self.re*other.im + self.im*other.re) - - __rmul__ = __mul__ - - def __div__(self, other): - other = ToComplex(other) - d = float(other.re*other.re + other.im*other.im) - if not d: raise ZeroDivisionError, 'Complex division' - return Complex((self.re*other.re + self.im*other.im) / d, - (self.im*other.re - self.re*other.im) / d) - - def __rdiv__(self, other): - other = ToComplex(other) - return other / self - - def __pow__(self, n, z=None): - if z is not None: - raise TypeError, 'Complex does not support ternary pow()' - if IsComplex(n): - if n.im: - if self.im: raise TypeError, 'Complex to the Complex power' - else: return exp(math.log(self.re)*n) - n = n.re - r = pow(self.abs(), n) - phi = n*self.angle() - return Complex(math.cos(phi)*r, math.sin(phi)*r) - - def __rpow__(self, base): - base = ToComplex(base) - return pow(base, self) - + def __init__(self, re=0, im=0): + if IsComplex(re): + im = i + Complex(0, re.im) + re = re.re + if IsComplex(im): + re = re - im.im + im = im.re + self.__dict__['re'] = re + self.__dict__['im'] = im + + def __setattr__(self, name, value): + raise TypeError, 'Complex numbers are immutable' + + def __hash__(self): + if not self.im: return hash(self.re) + mod = sys.maxint + 1L + return int((hash(self.re) + 2L*hash(self.im) + mod) % (2L*mod) - mod) + + def __repr__(self): + if not self.im: + return 'Complex(%s)' % `self.re` + else: + return 'Complex(%s, %s)' % (`self.re`, `self.im`) + + def __str__(self): + if not self.im: + return `self.re` + else: + return 'Complex(%s, %s)' % (`self.re`, `self.im`) + + def __neg__(self): + return Complex(-self.re, -self.im) + + def __pos__(self): + return self + + def __abs__(self): + # XXX could be done differently to avoid overflow! + return math.sqrt(self.re*self.re + self.im*self.im) + + def __int__(self): + if self.im: + raise ValueError, "can't convert Complex with nonzero im to int" + return int(self.re) + + def __long__(self): + if self.im: + raise ValueError, "can't convert Complex with nonzero im to long" + return long(self.re) + + def __float__(self): + if self.im: + raise ValueError, "can't convert Complex with nonzero im to float" + return float(self.re) + + def __cmp__(self, other): + other = ToComplex(other) + return cmp((self.re, self.im), (other.re, other.im)) + + def __rcmp__(self, other): + other = ToComplex(other) + return cmp(other, self) + + def __nonzero__(self): + return not (self.re == self.im == 0) + + abs = radius = __abs__ + + def angle(self, fullcircle = twopi): + return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi) + + phi = angle + + def __add__(self, other): + other = ToComplex(other) + return Complex(self.re + other.re, self.im + other.im) + + __radd__ = __add__ + + def __sub__(self, other): + other = ToComplex(other) + return Complex(self.re - other.re, self.im - other.im) + + def __rsub__(self, other): + other = ToComplex(other) + return other - self + + def __mul__(self, other): + other = ToComplex(other) + return Complex(self.re*other.re - self.im*other.im, + self.re*other.im + self.im*other.re) + + __rmul__ = __mul__ + + def __div__(self, other): + other = ToComplex(other) + d = float(other.re*other.re + other.im*other.im) + if not d: raise ZeroDivisionError, 'Complex division' + return Complex((self.re*other.re + self.im*other.im) / d, + (self.im*other.re - self.re*other.im) / d) + + def __rdiv__(self, other): + other = ToComplex(other) + return other / self + + def __pow__(self, n, z=None): + if z is not None: + raise TypeError, 'Complex does not support ternary pow()' + if IsComplex(n): + if n.im: + if self.im: raise TypeError, 'Complex to the Complex power' + else: return exp(math.log(self.re)*n) + n = n.re + r = pow(self.abs(), n) + phi = n*self.angle() + return Complex(math.cos(phi)*r, math.sin(phi)*r) + + def __rpow__(self, base): + base = ToComplex(base) + return pow(base, self) + def exp(z): - r = math.exp(z.re) - return Complex(math.cos(z.im)*r,math.sin(z.im)*r) + r = math.exp(z.re) + return Complex(math.cos(z.im)*r,math.sin(z.im)*r) def checkop(expr, a, b, value, fuzz = 1e-6): - import sys - print ' ', a, 'and', b, - try: - result = eval(expr) - except: - result = sys.exc_type - print '->', result - if (type(result) == type('') or type(value) == type('')): - ok = result == value - else: - ok = abs(result - value) <= fuzz - if not ok: - print '!!\t!!\t!! should be', value, 'diff', abs(result - value) + import sys + print ' ', a, 'and', b, + try: + result = eval(expr) + except: + result = sys.exc_type + print '->', result + if (type(result) == type('') or type(value) == type('')): + ok = result == value + else: + ok = abs(result - value) <= fuzz + if not ok: + print '!!\t!!\t!! should be', value, 'diff', abs(result - value) def test(): - testsuite = { - 'a+b': [ - (1, 10, 11), - (1, Complex(0,10), Complex(1,10)), - (Complex(0,10), 1, Complex(1,10)), - (Complex(0,10), Complex(1), Complex(1,10)), - (Complex(1), Complex(0,10), Complex(1,10)), - ], - 'a-b': [ - (1, 10, -9), - (1, Complex(0,10), Complex(1,-10)), - (Complex(0,10), 1, Complex(-1,10)), - (Complex(0,10), Complex(1), Complex(-1,10)), - (Complex(1), Complex(0,10), Complex(1,-10)), - ], - 'a*b': [ - (1, 10, 10), - (1, Complex(0,10), Complex(0, 10)), - (Complex(0,10), 1, Complex(0,10)), - (Complex(0,10), Complex(1), Complex(0,10)), - (Complex(1), Complex(0,10), Complex(0,10)), - ], - 'a/b': [ - (1., 10, 0.1), - (1, Complex(0,10), Complex(0, -0.1)), - (Complex(0, 10), 1, Complex(0, 10)), - (Complex(0, 10), Complex(1), Complex(0, 10)), - (Complex(1), Complex(0,10), Complex(0, -0.1)), - ], - 'pow(a,b)': [ - (1, 10, 1), - (1, Complex(0,10), 1), - (Complex(0,10), 1, Complex(0,10)), - (Complex(0,10), Complex(1), Complex(0,10)), - (Complex(1), Complex(0,10), 1), - (2, Complex(4,0), 16), - ], - 'cmp(a,b)': [ - (1, 10, -1), - (1, Complex(0,10), 1), - (Complex(0,10), 1, -1), - (Complex(0,10), Complex(1), -1), - (Complex(1), Complex(0,10), 1), - ], - } - exprs = testsuite.keys() - exprs.sort() - for expr in exprs: - print expr + ':' - t = (expr,) - for item in testsuite[expr]: - apply(checkop, t+item) - + testsuite = { + 'a+b': [ + (1, 10, 11), + (1, Complex(0,10), Complex(1,10)), + (Complex(0,10), 1, Complex(1,10)), + (Complex(0,10), Complex(1), Complex(1,10)), + (Complex(1), Complex(0,10), Complex(1,10)), + ], + 'a-b': [ + (1, 10, -9), + (1, Complex(0,10), Complex(1,-10)), + (Complex(0,10), 1, Complex(-1,10)), + (Complex(0,10), Complex(1), Complex(-1,10)), + (Complex(1), Complex(0,10), Complex(1,-10)), + ], + 'a*b': [ + (1, 10, 10), + (1, Complex(0,10), Complex(0, 10)), + (Complex(0,10), 1, Complex(0,10)), + (Complex(0,10), Complex(1), Complex(0,10)), + (Complex(1), Complex(0,10), Complex(0,10)), + ], + 'a/b': [ + (1., 10, 0.1), + (1, Complex(0,10), Complex(0, -0.1)), + (Complex(0, 10), 1, Complex(0, 10)), + (Complex(0, 10), Complex(1), Complex(0, 10)), + (Complex(1), Complex(0,10), Complex(0, -0.1)), + ], + 'pow(a,b)': [ + (1, 10, 1), + (1, Complex(0,10), 1), + (Complex(0,10), 1, Complex(0,10)), + (Complex(0,10), Complex(1), Complex(0,10)), + (Complex(1), Complex(0,10), 1), + (2, Complex(4,0), 16), + ], + 'cmp(a,b)': [ + (1, 10, -1), + (1, Complex(0,10), 1), + (Complex(0,10), 1, -1), + (Complex(0,10), Complex(1), -1), + (Complex(1), Complex(0,10), 1), + ], + } + exprs = testsuite.keys() + exprs.sort() + for expr in exprs: + print expr + ':' + t = (expr,) + for item in testsuite[expr]: + apply(checkop, t+item) + if __name__ == '__main__': - test() + test() |