diff options
| -rw-r--r-- | include/maths/complex.h (renamed from src/maths/complex.h) | 0 | ||||
| -rw-r--r-- | include/maths/matrix.h (renamed from src/maths/matrix.h) | 1 | ||||
| -rw-r--r-- | include/maths/vector.h (renamed from src/maths/vector.h) | 0 | ||||
| -rw-r--r-- | include/psi.h (renamed from src/psi.h) | 0 | ||||
| -rw-r--r-- | premake5.lua | 8 | ||||
| -rw-r--r-- | src/maths/complex.rs | 180 | ||||
| -rw-r--r-- | src/maths/numeric.rs | 101 | ||||
| -rw-r--r-- | src/maths/vector_ops.rs | 107 |
8 files changed, 7 insertions, 390 deletions
diff --git a/src/maths/complex.h b/include/maths/complex.h index c94f64a..c94f64a 100644 --- a/src/maths/complex.h +++ b/include/maths/complex.h diff --git a/src/maths/matrix.h b/include/maths/matrix.h index 1076310..c4e5530 100644 --- a/src/maths/matrix.h +++ b/include/maths/matrix.h @@ -14,6 +14,7 @@ struct PsiMatrix struct PsiMatrix psi_new_matrix(size_t rows, size_t cols); struct PsiMatrix psi_new_matrix_from(const struct PsiComplex *data, size_t rows, size_t cols); +struct PsiMatrix psi_identity_matrix(size_t size); struct PsiMatrix psi_clone_matrix(struct PsiMatrix m); void psi_free_matrix(struct PsiMatrix *m); diff --git a/src/maths/vector.h b/include/maths/vector.h index d452ef1..d452ef1 100644 --- a/src/maths/vector.h +++ b/include/maths/vector.h diff --git a/src/psi.h b/include/psi.h index 8c62319..8c62319 100644 --- a/src/psi.h +++ b/include/psi.h diff --git a/premake5.lua b/premake5.lua index 8038a9a..f2d2d2d 100644 --- a/premake5.lua +++ b/premake5.lua @@ -65,11 +65,15 @@ project "psi" setup_c_target() files { + "include/**.h", "src/**.h", "src/**.c", } - includedirs "src" + includedirs { + "include", + "src", + } filter { "system:macosx or system:linux" } buildoptions { @@ -103,7 +107,7 @@ project "tester" } includedirs { - "src", + "include", "tester", } diff --git a/src/maths/complex.rs b/src/maths/complex.rs deleted file mode 100644 index 31eae69..0000000 --- a/src/maths/complex.rs +++ /dev/null @@ -1,180 +0,0 @@ -use crate::Float; -use core::{fmt, ops}; - -#[macro_export] -macro_rules! complex { - ($real:expr, $imaginary:expr) => { - $crate::Complex::new($real, $imaginary) - }; -} - -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, - pub imaginary: T, -} - -impl<T: Float + fmt::Debug> fmt::Debug for Complex<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "Complex {{ real: {:?}, imaginary: {:?} }}", - self.real, self.imaginary - ) - } -} - -impl<T: Float + fmt::Display> fmt::Display for Complex<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} + {}i", self.real, self.imaginary) - } -} - -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(), - } - } -} - -impl<T: Float> Complex<T> { - pub fn new(real: T, imaginary: T) -> Complex<T> { - Complex { real, imaginary } - } - - pub fn get_conjugate(&self) -> Complex<T> { - 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 norm2(&self) -> T { - self.real * self.real + self.imaginary * self.imaginary - } - - pub fn abs(&self) -> T { - T::sqrt(self.norm2()) - } -} - -impl_ops!(Add, add, +); -impl_ops!(Sub, sub, -); - -impl<T: Float> ops::Mul for Complex<T> { - type Output = Complex<T>; - - fn mul(self, other: Complex<T>) -> Complex<T> { - // (a + bi) * (c + di) = (ac - bd) + (ad + bc)i - 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> { - // (a + bi) / (c + di) = ((ac + bd) + (bc - ad)i) / (c² + d²) - 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!(AddAssign, add_assign, +, assign); -impl_ops!(SubAssign, sub_assign, -, assign); - -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_imag = self.real * other.imaginary + self.imaginary * other.real; - self.real = new_real; - self.imaginary = new_imag; - } -} - -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_imag = (self.imaginary * other.real - self.real * other.imaginary) / denom; - self.real = new_real; - self.imaginary = new_imag; - } -} - -impl_ops!(Add, add, +, real); -impl_ops!(Sub, sub, -, real); -impl_ops!(Mul, mul, *, real); -impl_ops!(Div, div, /, real); diff --git a/src/maths/numeric.rs b/src/maths/numeric.rs deleted file mode 100644 index f5a649e..0000000 --- a/src/maths/numeric.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::Complex; -use core::ops; - -macro_rules! impl_numeric { - ($($t:ty),*) => { - $( - impl Numeric for $t { - fn zero() -> Self { - 0 as $t - } - - fn one() -> Self { - 1 as $t - } - } - )* - }; -} - -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),*) => { - $( - impl Float for $t { - fn sqrt(self) -> Self { - $sqrt_fn(self) - } - - fn atan2(y: Self, x: Self) -> Self { - $atan2_fn(y, x) - } - } - )* - }; -} - -macro_rules! impl_cfloat { - ($($t:ty, $sqrt_fn:path, $atan2_fn:path, $cos_fn:path, $sin_fn:path),*) => { - $( - impl Float for Complex<$t> { - fn sqrt(self) -> Self { - let r = self.abs(); - let theta = self.phase(); - - let sqrt_r = $sqrt_fn(r); - let sqrt_theta = theta / 2.0; - - Complex::new( - sqrt_r * $cos_fn(sqrt_theta), - sqrt_r * $sin_fn(sqrt_theta), - ) - } - - fn atan2(y: Self, x: Self) -> Self { - Complex::new( - $atan2_fn(y.real, x.real), - $atan2_fn(y.imaginary, x.imaginary), - ) - } - } - )* - }; -} - -pub trait Numeric: - Copy - + PartialOrd - + ops::Add<Output = Self> - + ops::Mul<Output = Self> - + ops::Sub<Output = Self> - + ops::Div<Output = Self> - + ops::Neg<Output = Self> - + ops::AddAssign - + ops::SubAssign - + ops::MulAssign - + ops::DivAssign -{ - fn zero() -> Self; - fn one() -> Self; -} - -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_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 { - fn sqrt(self) -> Self; - fn atan2(y: Self, x: Self) -> Self; -} diff --git a/src/maths/vector_ops.rs b/src/maths/vector_ops.rs deleted file mode 100644 index 1e7148c..0000000 --- a/src/maths/vector_ops.rs +++ /dev/null @@ -1,107 +0,0 @@ -use super::{Float, Matrix}; -use crate::{ColumnVector, RowVector, VectorImpl}; -use core::ops; - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::Add<&VectorImpl<T, ROWS, COLS>> - for VectorImpl<T, ROWS, COLS> -{ - type Output = Option<VectorImpl<T, ROWS, COLS>>; - - fn add(self, other: &VectorImpl<T, ROWS, COLS>) -> Self::Output { - self.add_to(other) - } -} - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::Sub<&VectorImpl<T, ROWS, COLS>> - for VectorImpl<T, ROWS, COLS> -{ - type Output = Option<VectorImpl<T, ROWS, COLS>>; - - fn sub(self, other: &VectorImpl<T, ROWS, COLS>) -> Self::Output { - self.subtract(other) - } -} - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::Mul<T> for VectorImpl<T, ROWS, COLS> { - type Output = VectorImpl<T, ROWS, COLS>; - - fn mul(self, scalar: T) -> Self::Output { - self.scale(scalar) - } -} - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::Div<T> for VectorImpl<T, ROWS, COLS> { - type Output = VectorImpl<T, ROWS, COLS>; - - fn div(self, scalar: T) -> Self::Output { - self.scale(T::one() / scalar) - } -} - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::AddAssign<VectorImpl<T, ROWS, COLS>> - for VectorImpl<T, ROWS, COLS> -{ - fn add_assign(&mut self, other: VectorImpl<T, ROWS, COLS>) { - if let Some(result) = self.add_to(&other) { - *self = result; - } - } -} - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::SubAssign<VectorImpl<T, ROWS, COLS>> - for VectorImpl<T, ROWS, COLS> -{ - fn sub_assign(&mut self, other: VectorImpl<T, ROWS, COLS>) { - if let Some(result) = self.subtract(&other) { - *self = result; - } - } -} - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::MulAssign<T> - for VectorImpl<T, ROWS, COLS> -{ - fn mul_assign(&mut self, scalar: T) { - *self = self.scale(scalar); - } -} - -impl<T: Float, const ROWS: usize, const COLS: usize> ops::DivAssign<T> - for VectorImpl<T, ROWS, COLS> -{ - fn div_assign(&mut self, scalar: T) { - *self = self.scale(T::one() / scalar); - } -} - -impl<T: Float> ops::Mul<&Matrix<T>> for RowVector<T> { - type Output = Option<RowVector<T>>; - - fn mul(self, matrix: &Matrix<T>) -> Self::Output { - self.mul_matrix(matrix) - } -} - -impl<T: Float> ops::Mul<&Matrix<T>> for ColumnVector<T> { - type Output = Option<ColumnVector<T>>; - - fn mul(self, matrix: &Matrix<T>) -> Self::Output { - self.mul_matrix(matrix) - } -} - -impl<T: Float> ops::MulAssign<&Matrix<T>> for RowVector<T> { - fn mul_assign(&mut self, matrix: &Matrix<T>) { - if let Some(result) = self.mul_matrix(matrix) { - *self = result; - } - } -} - -impl<T: Float> ops::MulAssign<&Matrix<T>> for ColumnVector<T> { - fn mul_assign(&mut self, matrix: &Matrix<T>) { - if let Some(result) = self.mul_matrix(matrix) { - *self = result; - } - } -} |
