From 53287a755cc8bcef8b4c1324f1ed1f34224e15c4 Mon Sep 17 00:00:00 2001 From: hachem Date: Sun, 22 Sep 2024 10:11:02 +0200 Subject: rename project to psi --- libpsi/src/maths/complex.rs | 219 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 libpsi/src/maths/complex.rs (limited to 'libpsi/src/maths/complex.rs') diff --git a/libpsi/src/maths/complex.rs b/libpsi/src/maths/complex.rs new file mode 100644 index 0000000..28a3121 --- /dev/null +++ b/libpsi/src/maths/complex.rs @@ -0,0 +1,219 @@ +use crate::Float; +use core::{fmt, ops}; + +#[macro_export] +macro_rules! complex { + ($real:expr, $imaginary:expr) => { + $crate::Complex::new($real, $imaginary) + }; +} + +#[derive(Copy, Clone, PartialOrd, PartialEq)] +pub struct Complex { + pub real: T, + pub imaginary: T, +} + +impl fmt::Debug for Complex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "Complex {{ real: {:?}, imaginary: {:?} }}", + self.real, self.imaginary + ) + } +} + +impl fmt::Display for Complex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} + {}i", self.real, self.imaginary) + } +} + +impl Complex { + pub fn new(real: T, imaginary: T) -> Complex { + Complex { real, imaginary } + } + + pub fn get_conjugate(&self) -> Complex { + Complex { + real: self.real, + imaginary: -self.imaginary, + } + } + + pub fn conjugate(&mut self) { + self.imaginary = -self.imaginary; + } + + pub fn phase(&self) -> T { + T::atan2(self.imaginary, self.real) + } + + pub fn norm(&self) -> T { + self.real * self.real + self.imaginary * self.imaginary + } + + pub fn abs(&self) -> T { + T::sqrt(self.norm()) + } +} + +impl ops::Neg for Complex { + type Output = Complex; + + fn neg(self) -> Complex { + Complex { + real: -self.real, + imaginary: -self.imaginary, + } + } +} + +impl ops::Add for Complex { + type Output = Complex; + + fn add(self, other: Complex) -> Complex { + Complex { + real: self.real + other.real, + imaginary: self.imaginary + other.imaginary, + } + } +} + +impl ops::Sub for Complex { + type Output = Complex; + + fn sub(self, other: Complex) -> Complex { + Complex { + real: self.real - other.real, + imaginary: self.imaginary - other.imaginary, + } + } +} + +impl ops::Mul for Complex { + type Output = Complex; + + fn mul(self, other: Complex) -> Complex { + Complex { + real: self.real * other.real - self.imaginary * other.imaginary, + imaginary: self.real * other.imaginary + self.imaginary * other.real, + } + } +} + +impl ops::Div for Complex { + type Output = Complex; + + fn div(self, other: Complex) -> Complex { + let denom = other.real * other.real + other.imaginary * other.imaginary; + Complex { + real: (self.real * other.real + self.imaginary * other.imaginary) / denom, + imaginary: (self.imaginary * other.real - self.real * other.imaginary) / denom, + } + } +} + +impl ops::Add for Complex { + type Output = Complex; + + fn add(self, other: T) -> Complex { + Complex { + real: self.real + other, + imaginary: self.imaginary, + } + } +} + +impl ops::Sub for Complex { + type Output = Complex; + + fn sub(self, other: T) -> Complex { + Complex { + real: self.real - other, + imaginary: self.imaginary, + } + } +} + +impl ops::Mul for Complex { + type Output = Complex; + + fn mul(self, other: T) -> Complex { + Complex { + real: self.real * other, + imaginary: self.imaginary * other, + } + } +} + +impl ops::Div for Complex { + type Output = Complex; + + fn div(self, other: T) -> Complex { + Complex { + real: self.real / other, + imaginary: self.imaginary / other, + } + } +} + +impl ops::AddAssign for Complex { + fn add_assign(&mut self, other: Complex) { + self.real += other.real; + self.imaginary += other.imaginary; + } +} + +impl ops::SubAssign for Complex { + fn sub_assign(&mut self, other: Complex) { + self.real -= other.real; + self.imaginary -= other.imaginary; + } +} + +impl ops::MulAssign for Complex { + fn mul_assign(&mut self, other: Complex) { + let new_real = self.real * other.real - self.imaginary * other.imaginary; + let new_imaginary = self.real * other.imaginary + self.imaginary * other.real; + self.real = new_real; + self.imaginary = new_imaginary; + } +} + +impl ops::DivAssign for Complex { + fn div_assign(&mut self, other: Complex) { + let denom = other.real * other.real + other.imaginary * other.imaginary; + let new_real = (self.real * other.real + self.imaginary * other.imaginary) / denom; + let new_imaginary = (self.imaginary * other.real - self.real * other.imaginary) / denom; + self.real = new_real; + self.imaginary = new_imaginary; + } +} + +impl ops::AddAssign for Complex { + fn add_assign(&mut self, other: T) { + self.real += other; + } +} + +impl ops::SubAssign for Complex { + fn sub_assign(&mut self, other: T) { + self.real -= other; + } +} + +impl ops::MulAssign for Complex { + fn mul_assign(&mut self, other: T) { + self.real *= other; + self.imaginary *= other; + } +} + +impl ops::DivAssign for Complex { + fn div_assign(&mut self, other: T) { + self.real /= other; + self.imaginary /= other; + } +} -- cgit v1.3