| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import math
- class complex:
- def __init__(self, real, imag=0):
- self._real = float(real)
- self._imag = float(imag)
- @property
- def real(self):
- return self._real
-
- @property
- def imag(self):
- return self._imag
- def conjugate(self):
- return complex(self.real, -self.imag)
-
- def __repr__(self):
- s = ['(', str(self.real)]
- s.append('-' if self.imag < 0 else '+')
- s.append(str(abs(self.imag)))
- s.append('j)')
- return ''.join(s)
-
- def __eq__(self, other):
- if type(other) is complex:
- return self.real == other.real and self.imag == other.imag
- if type(other) in (int, float):
- return self.real == other and self.imag == 0
- return NotImplemented
-
- def __add__(self, other):
- if type(other) is complex:
- return complex(self.real + other.real, self.imag + other.imag)
- if type(other) in (int, float):
- return complex(self.real + other, self.imag)
- return NotImplemented
-
- def __radd__(self, other):
- return self.__add__(other)
-
- def __sub__(self, other):
- if type(other) is complex:
- return complex(self.real - other.real, self.imag - other.imag)
- if type(other) in (int, float):
- return complex(self.real - other, self.imag)
- return NotImplemented
-
- def __rsub__(self, other):
- if type(other) is complex:
- return complex(other.real - self.real, other.imag - self.imag)
- if type(other) in (int, float):
- return complex(other - self.real, -self.imag)
- return NotImplemented
-
- def __mul__(self, other):
- if type(other) is complex:
- return complex(self.real * other.real - self.imag * other.imag,
- self.real * other.imag + self.imag * other.real)
- if type(other) in (int, float):
- return complex(self.real * other, self.imag * other)
- return NotImplemented
-
- def __rmul__(self, other):
- return self.__mul__(other)
-
- def __pow__(self, other: int | float):
- if type(other) in (int, float):
- return complex(self.__abs__() ** other * math.cos(other * phase(self)),
- self.__abs__() ** other * math.sin(other * phase(self)))
- return NotImplemented
-
- def __abs__(self) -> float:
- return math.sqrt(self.real ** 2 + self.imag ** 2)
- def __neg__(self):
- return complex(-self.real, -self.imag)
-
- def __hash__(self):
- return hash((self.real, self.imag))
- # Conversions to and from polar coordinates
- def phase(z: complex):
- return math.atan2(z.imag, z.real)
- def polar(z: complex):
- return z.__abs__(), phase(z)
- def rect(r: float, phi: float):
- return r * math.cos(phi) + r * math.sin(phi) * 1j
- # Power and logarithmic functions
- def exp(z: complex):
- return math.exp(z.real) * rect(1, z.imag)
- def log(z: complex, base=2.718281828459045):
- return math.log(z.__abs__(), base) + phase(z) * 1j
- def log10(z: complex):
- return log(z, 10)
- def sqrt(z: complex):
- return z ** 0.5
- # Trigonometric functions
- def acos(z: complex):
- return -1j * log(z + sqrt(z * z - 1))
- def asin(z: complex):
- return -1j * log(1j * z + sqrt(1 - z * z))
- def atan(z: complex):
- return 1j / 2 * log((1 - 1j * z) / (1 + 1j * z))
- def cos(z: complex):
- return (exp(z) + exp(-z)) / 2
- def sin(z: complex):
- return (exp(z) - exp(-z)) / (2 * 1j)
- def tan(z: complex):
- return sin(z) / cos(z)
- # Hyperbolic functions
- def acosh(z: complex):
- return log(z + sqrt(z * z - 1))
- def asinh(z: complex):
- return log(z + sqrt(z * z + 1))
- def atanh(z: complex):
- return 1 / 2 * log((1 + z) / (1 - z))
- def cosh(z: complex):
- return (exp(z) + exp(-z)) / 2
- def sinh(z: complex):
- return (exp(z) - exp(-z)) / 2
- def tanh(z: complex):
- return sinh(z) / cosh(z)
- # Classification functions
- def isfinite(z: complex):
- return math.isfinite(z.real) and math.isfinite(z.imag)
- def isinf(z: complex):
- return math.isinf(z.real) or math.isinf(z.imag)
- def isnan(z: complex):
- return math.isnan(z.real) or math.isnan(z.imag)
- def isclose(a: complex, b: complex):
- return math.isclose(a.real, b.real) and math.isclose(a.imag, b.imag)
- # Constants
- pi = math.pi
- e = math.e
- tau = 2 * pi
- inf = math.inf
- infj = complex(0, inf)
- nan = math.nan
- nanj = complex(0, nan)
|