Complex.py :  » Mobile » Python-for-PalmOS » Python-1.5.2+reduced-1.0 » Demo » classes » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Mobile » Python for PalmOS 
Python for PalmOS » Python 1.5.2 reduced 1.0 » Demo » classes » Complex.py
# Complex numbers
# ---------------

# [Now that Python has a complex data type built-in, this is not very
# useful, but it's still a nice example class]

# This module represents complex numbers as instances of the class Complex.
# A Complex instance z has two data attribues, z.re (the real part) and z.im
# (the imaginary part).  In fact, z.re and z.im can have any value -- all
# arithmetic operators work regardless of the type of z.re and z.im (as long
# as they support numerical operations).
#
# The following functions exist (Complex is actually a class):
# Complex([re [,im]) -> creates a complex number from a real and an imaginary part
# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes)
# 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)
# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z).
#
# Complex numbers have the following methods:
# z.abs() -> absolute value of z
# z.radius() == z.abs()
# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units
# z.phi([fullcircle]) == z.angle(fullcircle)
#
# These standard functions and unary operators accept complex arguments:
# abs(z)
# -z
# +z
# not z
# repr(z) == `z`
# str(z)
# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero
#            the result equals hash(z.re)
# Note that hex(z) and oct(z) are not defined.
#
# These conversions accept complex arguments only if their imaginary part is zero:
# int(z)
# long(z)
# float(z)
#
# The following operators accept two complex numbers, or one complex number
# and one real number (int, long or float):
# z1 + z2
# z1 - z2
# z1 * z2
# z1 / z2
# pow(z1, z2)
# cmp(z1, z2)
# Note that z1 % z2 and divmod(z1, z2) are not defined,
# nor are shift and mask operations.
#
# The standard module math does not support complex numbers.
# (I suppose it would be easy to implement a cmath module.)
#
# Idea:
# add a class Polar(r, phi) and mixed-mode arithmetic which
# chooses the most appropriate type for the result:
# Complex for +,-,cmp
# Polar   for *,/,pow


import types, math

twopi = math.pi*2.0
halfpi = math.pi/2.0

def IsComplex(obj):
  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)

def PolarToComplex(r = 0, phi = 0, fullcircle = twopi):
  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

def Im(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 exp(z):
  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)


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)
  

if __name__ == '__main__':
  test()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.