use super::complex_type::Complex;
impl Complex {
pub fn new(re: f64, im: f64) -> Self {
Self { re, im }
}
pub fn zero() -> Self {
Self::new(0.0, 0.0)
}
pub fn one() -> Self {
Self::new(1.0, 0.0)
}
pub fn i() -> Self {
Self::new(0.0, 1.0)
}
pub fn conj(self) -> Self {
Self::new(self.re, -self.im)
}
pub fn add(self, other: Self) -> Self {
Self::new(self.re + other.re, self.im + other.im)
}
pub fn sub(self, other: Self) -> Self {
Self::new(self.re - other.re, self.im - other.im)
}
pub fn mul(self, other: Self) -> Self {
Self::new(
self.re * other.re - self.im * other.im,
self.re * other.im + self.im * other.re,
)
}
pub fn scale(self, s: f64) -> Self {
Self::new(self.re * s, self.im * s)
}
pub fn neg(self) -> Self {
Self::new(-self.re, -self.im)
}
pub fn exp(self) -> Self {
let ea = self.re.exp();
Self::new(ea * self.im.cos(), ea * self.im.sin())
}
pub fn log(self) -> Option<Self> {
if self.norm_sq() < f64::EPSILON {
return None;
}
Some(Self::new(self.abs().ln(), self.arg()))
}
pub fn sqrt(self) -> Self {
if self.im == 0.0 && self.re >= 0.0 {
return Self::new(self.re.sqrt(), 0.0);
}
let r = self.abs();
let theta = self.arg() / 2.0;
Self::new(r.sqrt() * theta.cos(), r.sqrt() * theta.sin())
}
pub fn sin(self) -> Self {
let iz = Self::i().mul(self);
let e1 = iz.exp();
let e2 = iz.neg().exp();
e1.sub(e2).div(Self::new(0.0, 2.0)).unwrap_or(Self::zero())
}
pub fn from_polar(r: f64, theta: f64) -> Self {
Self::new(r * theta.cos(), r * theta.sin())
}
}