use std::{fmt::{Formatter, Result as FmtResult}, ops::{Add, Div, Mul, Sub}};
use std::fmt::{Display};
#[derive(Copy, Clone, Debug, Default)]
pub struct Complex {
pub real: f64,
pub imag: f64,
}
impl Complex {
pub fn new(real: f64, imag: f64) -> Self {
Complex { real, imag }
}
#[inline]
pub fn norm_squared(&self) -> f64 {
self.real * self.real + self.imag * self.imag
}
#[inline]
pub fn norm(&self) -> f64 {
self.norm_squared().sqrt()
}
pub fn real(&self) -> f64 {
self.real
}
pub fn imag(&self) -> f64 {
self.imag
}
}
impl Add for Complex {
type Output = Complex;
#[inline]
fn add(self, rhs: Complex) -> Complex {
Complex {
real: self.real + rhs.real,
imag: self.imag + rhs.imag
}
}
}
impl Sub for Complex {
type Output = Complex;
#[inline]
fn sub(self, rhs: Complex) -> Complex {
Complex {
real: self.real - rhs.real,
imag: self.imag - rhs.imag
}
}
}
impl Mul for Complex {
type Output = Complex;
#[inline]
fn mul(self, rhs: Complex) -> Complex {
Complex {
real: self.real * rhs.real - self.imag * rhs.imag,
imag: self.real * rhs.imag + self.imag * rhs.real
}
}
}
impl Div for Complex {
type Output = Complex;
#[inline]
fn div(self, rhs: Complex) -> Complex {
let denom = rhs.real * rhs.real + rhs.imag * rhs.imag;
Complex {
real: (self.real * rhs.real + self.imag * rhs.imag) / denom,
imag: (self.imag * rhs.real - self.real * rhs.imag) / denom
}
}
}
impl Display for Complex {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match (self.real == 0.0, self.imag == 0.0, f.precision()) {
(true, true, _) => write!(f, "0"),
(true, false, Some(p)) => write!(f, "{:.prec$}i", self.imag, prec = p),
(true, false, None) => write!(f, "{}i", self.imag),
(false, true, Some(p)) => write!(f, "{:.prec$}", self.real, prec = p),
(false, true, None) => write!(f, "{}", self.real),
(false, false, Some(p)) if self.imag < 0.0 => {
write!(f, "{:.prec$}{:.prec$}i", self.real, self.imag, prec = p)
}
(false, false, Some(p)) => {
write!(f, "{:.prec$}+{:.prec$}i", self.real, self.imag, prec = p)
}
(false, false, None) if self.imag < 0.0 => write!(f, "{}{}i", self.real, self.imag),
(false, false, None) => write!(f, "{}+{}i", self.real, self.imag),
}
}
}