[pypy-svn] r4796 - pypy/trunk/src/pypy/module
hpk at codespeak.net
hpk at codespeak.net
Tue Jun 1 12:59:18 CEST 2004
Author: hpk
Date: Tue Jun 1 12:59:18 2004
New Revision: 4796
Modified:
pypy/trunk/src/pypy/module/__builtin__module.py
Log:
pasted 'class complex' from appspace/complexobject.py into
the builtins.
Modified: pypy/trunk/src/pypy/module/__builtin__module.py
==============================================================================
--- pypy/trunk/src/pypy/module/__builtin__module.py (original)
+++ pypy/trunk/src/pypy/module/__builtin__module.py Tue Jun 1 12:59:18 2004
@@ -572,6 +572,361 @@
return x
raise AttributeError, attr
+class complex(object):
+ """complex(real[, imag]) -> complex number
+
+ Create a complex number from a real part and an optional imaginary part.
+ This is equivalent to (real + imag*1j) where imag defaults to 0."""
+ PREC_REPR = 0 # 17
+ PREC_STR = 0 # 12
+
+ def __init__(self, real=0.0, imag=None):
+ if isinstance(real, str) and imag is not None:
+ msg = "complex() can't take second arg if first is a string"
+ raise TypeError, msg
+
+ if isinstance(imag, str):
+ msg = "complex() second arg can't be a string"
+ raise TypeError, msg
+
+ if isinstance(real, str):
+ real, imag = self._makeComplexFromString(real)
+ self.__dict__['real'] = real
+ self.__dict__['imag'] = imag
+ else:
+ if imag is None:
+ imag = 0.
+ self.__dict__['real'] = float(real)
+ self.__dict__['imag'] = float(imag)
+
+
+ def __setattr__(self, name, value):
+ if name in ('real', 'imag'):
+ raise TypeError, "readonly attribute"
+ else:
+ raise TypeError, "'complex' object has no attribute %s" % name
+
+ def _makeComplexFromString(self, string):
+ import re
+ pat = re.compile(" *([\+\-]?\d*\.?\d*)([\+\-]?\d*\.?\d*)[jJ] *")
+ m = pat.match(string)
+ x, y = m.groups()
+ if len(y) == 1 and y in '+-':
+ y = y + '1.0'
+ x, y = map(float, [x, y])
+ return x, y
+
+
+ def __description(self, precision):
+ sign = '+'
+ if self.imag < 0.:
+ sign = ''
+ if self.real != 0.:
+ format = "(%%%02dg%%s%%%02dgj)" % (precision, precision)
+ args = (self.real, sign, self.imag)
+ else:
+ format = "%%%02dgj" % precision
+ args = self.imag
+ return format % args
+
+
+ def __repr__(self):
+ return self.__description(self.PREC_REPR)
+
+
+ def __str__(self):
+ return self.__description(self.PREC_STR)
+
+
+ def __hash__(self):
+ hashreal = hash(self.real)
+ hashimag = hash(self.imag)
+
+ # Note: if the imaginary part is 0, hashimag is 0 now,
+ # so the following returns hashreal unchanged. This is
+ # important because numbers of different types that
+ # compare equal must have the same hash value, so that
+ # hash(x + 0*j) must equal hash(x).
+
+ combined = hashreal + 1000003 * hashimag
+ if combined == -1:
+ combined = -2
+
+ return combined
+
+
+ def __add__(self, other):
+ self, other = self.__coerce__(other)
+ real = self.real + other.real
+ imag = self.imag + other.imag
+ return complex(real, imag)
+
+
+ def __sub__(self, other):
+ self, other = self.__coerce__(other)
+ real = self.real - other.real
+ imag = self.imag - other.imag
+ return complex(real, imag)
+
+
+ def __mul__(self, other):
+ if other.__class__ != complex:
+ return complex(other*self.real, other*self.imag)
+
+ real = self.real*other.real - self.imag*other.imag
+ imag = self.real*other.imag + self.imag*other.real
+ return complex(real, imag)
+
+
+ def __div__(self, other):
+ if other.__class__ != complex:
+ return complex(self.real/other, self.imag/other)
+
+ if other.real < 0:
+ abs_breal = -other.real
+ else:
+ abs_breal = other.real
+
+ if other.imag < 0:
+ abs_bimag = -other.imag
+ else:
+ abs_bimag = other.imag
+
+ if abs_breal >= abs_bimag:
+ # divide tops and bottom by other.real
+ if abs_breal == 0.0:
+ real = imag = 0.0
+ else:
+ ratio = other.imag / other.real
+ denom = other.real + other.imag * ratio
+ real = (self.real + self.imag * ratio) / denom
+ imag = (self.imag - self.real * ratio) / denom
+ else:
+ # divide tops and bottom by other.imag
+ ratio = other.real / other.imag
+ denom = other.real * ratio + other.imag
+ assert other.imag != 0.0
+ real = (self.real * ratio + self.imag) / denom
+ imag = (self.imag * ratio - self.real) / denom
+
+ return complex(real, imag)
+
+
+ def __floordiv__(self, other):
+ return self / other
+
+
+ def __truediv__(self, other):
+ return self / other
+
+
+ def __mod__(self, other):
+ import warnings, math
+ warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning)
+
+ if other.real == 0. and other.imag == 0.:
+ raise ZeroDivisionError, "complex remainder"
+
+ div = self/other # The raw divisor value.
+ div = complex(math.floor(div.real), 0.0)
+ mod = self - div*other
+
+ if mod.__class__ == complex:
+ return mod
+ else:
+ return complex(mod)
+
+
+ def __divmod__(self, other):
+ import warnings, math
+ warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning)
+
+ if other.real == 0. and other.imag == 0.:
+ raise ZeroDivisionError, "complex remainder"
+
+ div = self/other # The raw divisor value.
+ div = complex(math.floor(div.real), 0.0)
+ mod = self - div*other
+ return div, mod
+
+
+ def __pow__(self, other):
+ import math
+ if other.__class__ != complex:
+ other = complex(other, 0)
+
+ a, b = self, other
+
+ if b.real == 0. and b.imag == 0.:
+ real = 1.
+ imag = 0.
+ elif a.real == 0. and a.imag == 0.:
+ real = 0.
+ imag = 0.
+ else:
+ vabs = math.hypot(a.real,a.imag)
+ len = math.pow(vabs,b.real)
+ at = math.atan2(a.imag, a.real)
+ phase = at*b.real
+ if b.imag != 0.0:
+ len /= math.exp(at*b.imag)
+ phase += b.imag*math.log(vabs)
+ real = len*math.cos(phase)
+ imag = len*math.sin(phase)
+
+ return complex(real, imag)
+
+
+ def __neg__(self):
+ return complex(-self.real, -self.imag)
+
+
+ def __pos__(self):
+ return complex(self.real, self.imag)
+
+
+ def __abs__(self):
+ import math
+ result = math.hypot(self.real, self.imag)
+ return float(result)
+
+
+ def __nonzero__(self):
+ return self.real != 0.0 or self.imag != 0.0
+
+
+ def __coerce__(self, other):
+ typ = type(other)
+
+ if typ is int:
+ return self, complex(float(other))
+ elif typ is long:
+ return self, complex(float(other))
+ elif typ is float:
+ return self, complex(other)
+ elif other.__class__ == complex:
+ return self, other
+ elif typ is complex:
+ return self, complex(other.real, other.imag)
+
+ raise TypeError, "number %r coercion failed" % typ
+
+
+ def conjugate(self):
+ return complex(self.real, -self.imag)
+
+ def __eq__(self, other):
+ self, other = self.__coerce__(other)
+ return self.real == other.real and self.imag == other.imag
+
+ def __ne__(self, other):
+ self, other = self.__coerce__(other)
+ return self.real != other.real or self.imag != other.imag
+
+
+ # unsupported operations
+
+ def __lt__(self, other):
+ raise TypeError, "cannot compare complex numbers using <, <=, >, >="
+
+
+ def __le__(self, other):
+ raise TypeError, "cannot compare complex numbers using <, <=, >, >="
+
+
+ def __gt__(self, other):
+ raise TypeError, "cannot compare complex numbers using <, <=, >, >="
+
+
+ def __ge__(self, other):
+ raise TypeError, "cannot compare complex numbers using <, <=, >, >="
+
+
+ def __int__(self):
+ raise TypeError, "can't convert complex to int; use e.g. int(abs(z))"
+
+
+ def __long__(self):
+ raise TypeError, "can't convert complex to long; use e.g. long(abs(z))"
+
+
+ def __float__(self):
+ raise TypeError, "can't convert complex to float; use e.g. float(abs(z))"
+
+
+ def _unsupportedOp(self, other, op):
+ selfTypeName = type(self).__name__
+ otherTypeName = type(other).__name__
+ args = (op, selfTypeName, otherTypeName)
+ msg = "unsupported operand type(s) for %s: '%s' and '%s'" % args
+ raise TypeError, msg
+
+
+ def __and__(self, other):
+ self._unsupportedOp(self, other, "&")
+
+
+ def __or__(self, other):
+ self._unsupportedOp(self, other, "|")
+
+
+ def __xor__(self, other):
+ self._unsupportedOp(self, other, "^")
+
+
+ def __rshift__(self, other):
+ self._unsupportedOp(self, other, ">>")
+
+
+ def __lshift__(self, other):
+ self._unsupportedOp(self, other, "<<")
+
+
+ def __iand__(self, other):
+ self._unsupportedOp(self, other, "&=")
+
+
+ def __ior__(self, other):
+ self._unsupportedOp(self, other, "|=")
+
+
+ def __ixor__(self, other):
+ self._unsupportedOp(self, other, "^=")
+
+
+ def __irshift__(self, other):
+ self._unsupportedOp(self, other, ">>=")
+
+
+ def __ilshift__(self, other):
+ self._unsupportedOp(self, other, "<<=")
+
+
+ # augmented assignment operations
+
+ def __iadd__(self, other):
+ return self + other
+
+
+ def __isub__(self, other):
+ return self - other
+
+
+ def __imul__(self, other):
+ return self * other
+
+
+ def __idiv__(self, other):
+ return self / other
+
+
+# def __new__(self, ...):
+# pass
+
+
+# test mod, divmod
+
+# add radd, rsub, rmul, rdiv...
# ________________________________________________________________________
## def app___import__(*args):
More information about the Pypy-commit
mailing list