diff options
Diffstat (limited to 'libpsi-core/src')
| -rw-r--r-- | libpsi-core/src/maths/complex.rs | 94 | ||||
| -rw-r--r-- | libpsi-core/src/maths/complex_ops.rs | 147 | ||||
| -rw-r--r-- | libpsi-core/src/maths/mod.rs | 4 | ||||
| -rw-r--r-- | libpsi-core/src/maths/numeric.rs | 24 |
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 { |
