use std::ops::*; pub trait Number: Add + Sub + Mul + Div + Neg + Clone + Sized { } impl Number for T {} /// angles are assumed to always be in radians pub type Angle = f64; #[derive(Debug, Clone, PartialEq)] pub struct Complex{ real: f64, imaginary: f64, } impl Complex { pub const IMAGINARY_UNIT: Self = Self { real:0.0, imaginary: 0.0}; /// computes the absolute value of a complex number pub fn abs(&self) -> f64 { (self.real.powi(2) + self.imaginary.powi(2)).sqrt() } /// returns a unit vector that is angle a away from the positive x axis pub fn unit_angle(a: Angle) -> Self { Self { real: a.cos(), imaginary: a.sin(), } } } impl From for Complex { fn from(value: f64) -> Self { Self { real: value, imaginary: 0.0 } } } impl Add for Complex { type Output = Self; fn add(self, rhs: Self) -> Self::Output { Self { real: self.real + rhs.real, imaginary: self.imaginary + rhs.imaginary } } } impl AddAssign for Complex { fn add_assign(&mut self, rhs: Self) { *self = self.clone() + rhs; } } impl Sub for Complex { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { Self { real: self.real - rhs.real, imaginary: self.imaginary - rhs.imaginary } } } impl SubAssign for Complex { fn sub_assign(&mut self, rhs: Self) { *self = self.clone() - rhs; } } impl Mul for Complex { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { Self { real: self.real * rhs.real - self.imaginary * rhs.imaginary, imaginary: self.real * rhs.imaginary + self.imaginary * rhs.real, } } } impl Div for Complex { type Output = Self; fn div(self, rhs: Self) -> Self::Output { Self { real: self.real / rhs.real - self.imaginary / rhs.imaginary, imaginary: self.real / rhs.imaginary + self.imaginary / rhs.real, } } }