def __mul__(self, other): if isinstance(other, numbers.Real): return type(self)(self.real * other, self.imag * other) if isinstance(other, numbers.Complex): return type(self)(self.real * other.real - self.imag * other.imag, self.real * other.imag + self.imag * other.real) return NotImplemented
def __truediv__(self, other): if isinstance(other, numbers.Real): return type(self)(self.real / other, self.imag / other) if isinstance(other, numbers.Complex): denom = other.real**2 + other.imag**2 return type(self)( (self.real * other.real + self.imag * other.imag) / denom, (self.imag * other.real - self.real * other.imag) / denom) return NotImplemented
def __rpow__(self, other): if isinstance(other, numbers.Complex): a = ((other**2) **(self.real / 2)) * math.e**(-self.imag * cmath.phase(other)) b = 0.5 * self.imag * math.log(other** 2) + self.real * cmath.phase(other) return type(self)(1, 0) * (a * cmath.cos(b)) + type(self)( 0, 1) * (a * cmath.sin(b)) return NotImplemented
def __pow__(self, other): i = type(self)(0, 1) one = type(self)(1, 0) if isinstance(other, numbers.Real): r = abs(self) theta = cmath.phase(self) return (r**other) * (one * math.cos(other * theta) + i * (math.sin(other * theta))) elif isinstance(other, numbers.Complex): r = abs(self) theta = cmath.phase(self) return (r**other) * (one * cmath.cos(other * theta) + i * (cmath.sin(other * theta))) return NotImplemented
def __pos__(self): return type(self)(self)
def __neg__(self): return type(self)(-self.real, -self.imag)
def __add__(self, other): if isinstance(other, numbers.Complex): return type(self)(self.real + other.real, self.imag + other.imag) if isinstance(other, numbers.Real): return type(self)(self.real + other, self.imag) return NotImplemented
def __reversed__(self): return type(self)(self.imag, self.real)
def __rmod__(self, other): if isinstance(other, numbers.Complex): return other + self * type(self).__ceil__(-other / self) return NotImplemented
def __round__(self, n=None): return type(self)(round(self.real, n), round(self.imag, n))
def __ceil__(self): return type(self)(math.ceil(self.real), math.ceil(self.imag))
def __floor__(self): return type(self)(math.floor(self.real), math.floor(self.imag))
def __repr__(self): return '{type.__name__}({self.real!r}, {self.imag!r})'.format( self=self, type=type(self))
def conjugate(self): return type(self)(self.real, -self.imag)