aboutsummaryrefslogtreecommitdiff
path: root/libpsi-core/src/maths
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2024-10-12 17:31:16 +0200
committerhachem <im@hachem.wtf>2024-10-12 17:31:16 +0200
commitb04d0578c59299598c298f3ca83af3278b13f08c (patch)
tree88fb6e933bb952d4eefc07589464e3a897252d42 /libpsi-core/src/maths
parent64d6a8c70b8d61a22136fd10f0c61ec349315694 (diff)
Refactor 2: Complex
Diffstat (limited to 'libpsi-core/src/maths')
-rw-r--r--libpsi-core/src/maths/complex.rs94
-rw-r--r--libpsi-core/src/maths/complex_ops.rs147
-rw-r--r--libpsi-core/src/maths/mod.rs4
-rw-r--r--libpsi-core/src/maths/numeric.rs24
4 files changed, 98 insertions, 171 deletions
diff --git a/libpsi-core/src/maths/complex.rs b/libpsi-core/src/maths/complex.rs
index bb19510..86e4788 100644
--- a/libpsi-core/src/maths/complex.rs
+++ b/libpsi-core/src/maths/complex.rs
@@ -1,7 +1,5 @@
use crate::Float;
-use core::fmt;
-
-use super::Numeric;
+use core::{fmt, ops};
#[macro_export]
macro_rules! complex {
@@ -10,6 +8,51 @@ macro_rules! complex {
};
}
+macro_rules! impl_ops {
+ ($trait:ident, $method:ident, $op:tt) => {
+ impl<T: Float> ops::$trait for Complex<T> {
+ type Output = Complex<T>;
+
+ fn $method(self, other: Complex<T>) -> Complex<T> {
+ Complex {
+ real: self.real $op other.real,
+ imaginary: self.imaginary $op other.imaginary,
+ }
+ }
+ }
+ };
+
+ ($trait:ident, $method:ident, $op:tt, real) => {
+ impl<T: Float> ops::$trait<T> for Complex<T> {
+ type Output = Complex<T>;
+
+ fn $method(self, other: T) -> Complex<T> {
+ Complex {
+ real: self.real $op other,
+ imaginary: self.imaginary,
+ }
+ }
+ }
+ };
+
+ ($trait_assign:ident, $method_assign:ident, $op:tt, assign) => {
+ impl<T: Float> ops::$trait_assign for Complex<T> {
+ fn $method_assign(&mut self, other: Complex<T>) {
+ self.real = self.real $op other.real;
+ self.imaginary = self.imaginary $op other.imaginary;
+ }
+ }
+ };
+
+ ($trait_assign:ident, $method_assign:ident, $op:tt, assign_real) => {
+ impl<T: Float> ops::$trait_assign<T> for Complex<T> {
+ fn $method_assign(&mut self, other: T) {
+ self.real = self.real $op other;
+ }
+ }
+ };
+}
+
#[derive(Copy, Clone, PartialOrd, PartialEq)]
pub struct Complex<T: Float> {
pub real: T,
@@ -32,23 +75,23 @@ impl<T: Float + fmt::Display> fmt::Display for Complex<T> {
}
}
-impl Numeric for Complex<f32> {
- fn zero() -> Self {
- Complex::new(0.0, 0.0)
- }
+impl<T: Float> ops::Neg for Complex<T> {
+ type Output = Complex<T>;
- fn one() -> Self {
- Complex::new(1.0, 0.0)
+ fn neg(self) -> Complex<T> {
+ Complex {
+ real: -self.real,
+ imaginary: -self.imaginary,
+ }
}
}
-impl Numeric for Complex<f64> {
- fn zero() -> Self {
- Complex::new(0.0, 0.0)
- }
-
- fn one() -> Self {
- Complex::new(1.0, 0.0)
+impl<T: Float> From<T> for Complex<T> {
+ fn from(real: T) -> Complex<T> {
+ Complex {
+ real,
+ imaginary: T::zero(),
+ }
}
}
@@ -72,11 +115,26 @@ impl<T: Float> Complex<T> {
T::atan2(self.imaginary, self.real)
}
- pub fn norm(&self) -> T {
+ pub fn norm2(&self) -> T {
self.real * self.real + self.imaginary * self.imaginary
}
pub fn abs(&self) -> T {
- T::sqrt(self.norm())
+ T::sqrt(self.norm2())
}
}
+
+impl_ops!(Add, add, +);
+impl_ops!(Sub, sub, -);
+impl_ops!(Mul, mul, *);
+impl_ops!(Div, div, /);
+
+impl_ops!(AddAssign, add_assign, +, assign);
+impl_ops!(SubAssign, sub_assign, -, assign);
+impl_ops!(MulAssign, mul_assign, *, assign);
+impl_ops!(DivAssign, div_assign, /, assign);
+
+impl_ops!(Add, add, +, real);
+impl_ops!(Sub, sub, -, real);
+impl_ops!(Mul, mul, *, real);
+impl_ops!(Div, div, /, real);
diff --git a/libpsi-core/src/maths/complex_ops.rs b/libpsi-core/src/maths/complex_ops.rs
deleted file mode 100644
index bfcf920..0000000
--- a/libpsi-core/src/maths/complex_ops.rs
+++ /dev/null
@@ -1,147 +0,0 @@
-use super::{Complex, Float};
-use core::ops;
-
-impl<T: Float> ops::Neg for Complex<T> {
- type Output = Complex<T>;
-
- fn neg(self) -> Complex<T> {
- Complex {
- real: -self.real,
- imaginary: -self.imaginary,
- }
- }
-}
-
-impl<T: Float> From<T> for Complex<T> {
- fn from(real: T) -> Complex<T> {
- Complex {
- real,
- imaginary: T::zero(),
- }
- }
-}
-
-// Complex-Complex
-impl<T: Float> ops::Add for Complex<T> {
- type Output = Complex<T>;
-
- fn add(self, other: Complex<T>) -> Complex<T> {
- Complex {
- real: self.real - other.real,
- imaginary: self.imaginary - other.imaginary,
- }
- }
-}
-
-impl<T: Float> ops::Sub for Complex<T> {
- type Output = Complex<T>;
-
- fn sub(self, other: Complex<T>) -> Complex<T> {
- Complex {
- real: self.real - other.real,
- imaginary: self.imaginary - other.imaginary,
- }
- }
-}
-
-impl<T: Float> ops::Mul for Complex<T> {
- type Output = Complex<T>;
-
- fn mul(self, other: Complex<T>) -> Complex<T> {
- Complex {
- real: self.real * other.real - self.imaginary * other.imaginary,
- imaginary: self.real * other.imaginary + self.imaginary * other.real,
- }
- }
-}
-
-impl<T: Float> ops::Div for Complex<T> {
- type Output = Complex<T>;
-
- fn div(self, other: Complex<T>) -> Complex<T> {
- 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,
- }
- }
-}
-
-// Complex-Complex, Assign
-impl<T: Float> ops::AddAssign for Complex<T> {
- fn add_assign(&mut self, other: Complex<T>) {
- self.real += other.real;
- self.imaginary += other.imaginary;
- }
-}
-
-impl<T: Float> ops::SubAssign for Complex<T> {
- fn sub_assign(&mut self, other: Complex<T>) {
- self.real -= other.real;
- self.imaginary -= other.imaginary;
- }
-}
-
-impl<T: Float> ops::MulAssign for Complex<T> {
- fn mul_assign(&mut self, other: Complex<T>) {
- 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<T: Float> ops::DivAssign for Complex<T> {
- fn div_assign(&mut self, other: Complex<T>) {
- 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;
- }
-}
-
-// Real-Complex
-impl<T: Float> ops::Add<T> for Complex<T> {
- type Output = Complex<T>;
-
- fn add(self, other: T) -> Complex<T> {
- Complex {
- real: self.real + other,
- imaginary: self.imaginary,
- }
- }
-}
-
-impl<T: Float> ops::Sub<T> for Complex<T> {
- type Output = Complex<T>;
-
- fn sub(self, other: T) -> Complex<T> {
- Complex {
- real: self.real - other,
- imaginary: self.imaginary,
- }
- }
-}
-
-impl<T: Float> ops::Mul<T> for Complex<T> {
- type Output = Complex<T>;
-
- fn mul(self, other: T) -> Complex<T> {
- Complex {
- real: self.real * other,
- imaginary: self.imaginary * other,
- }
- }
-}
-
-impl<T: Float> ops::Div<T> for Complex<T> {
- type Output = Complex<T>;
-
- fn div(self, other: T) -> Complex<T> {
- Complex {
- real: self.real / other,
- imaginary: self.imaginary / other,
- }
- }
-}
diff --git a/libpsi-core/src/maths/mod.rs b/libpsi-core/src/maths/mod.rs
index 32c8f9c..701ecd2 100644
--- a/libpsi-core/src/maths/mod.rs
+++ b/libpsi-core/src/maths/mod.rs
@@ -1,11 +1,9 @@
pub mod complex;
-pub mod complex_ops;
+pub mod numeric;
pub mod matrix;
pub mod matrix_ops;
-pub mod numeric;
-
pub mod vector;
pub mod vector_ops;
diff --git a/libpsi-core/src/maths/numeric.rs b/libpsi-core/src/maths/numeric.rs
index e6f3247..0fd4380 100644
--- a/libpsi-core/src/maths/numeric.rs
+++ b/libpsi-core/src/maths/numeric.rs
@@ -17,6 +17,22 @@ macro_rules! impl_numeric {
};
}
+macro_rules! impl_cnumeric {
+ ($($t:ty),*) => {
+ $(
+ impl Numeric for Complex<$t> {
+ fn zero() -> Self {
+ Complex::new(0.0, 0.0)
+ }
+
+ fn one() -> Self {
+ Complex::new(1.0, 0.0)
+ }
+ }
+ )*
+ };
+}
+
macro_rules! impl_float {
($($t:ty, $sqrt_fn:path, $atan2_fn:path),*) => {
$(
@@ -33,7 +49,7 @@ macro_rules! impl_float {
};
}
-macro_rules! impl_complex {
+macro_rules! impl_cfloat {
($($t:ty, $sqrt_fn:path, $atan2_fn:path, $cos_fn:path, $sin_fn:path),*) => {
$(
impl Float for Complex<$t> {
@@ -79,10 +95,12 @@ pub trait Numeric:
}
impl_numeric!(i32, i64, f32, f64);
+impl_cnumeric!(f32, f64);
+
impl_float!(f32, libm::sqrtf, libm::atan2f);
impl_float!(f64, libm::sqrt, libm::atan2);
-impl_complex!(f32, libm::sqrtf, libm::atan2f, libm::cosf, libm::sinf);
-impl_complex!(f64, libm::sqrt, libm::atan2, libm::cos, libm::sin);
+impl_cfloat!(f32, libm::sqrtf, libm::atan2f, libm::cosf, libm::sinf);
+impl_cfloat!(f64, libm::sqrt, libm::atan2, libm::cos, libm::sin);
pub trait Integer: Numeric {}
pub trait Float: Numeric {