diff options
Diffstat (limited to 'libmu/src/maths')
| -rw-r--r-- | libmu/src/maths/matrix.rs | 32 | ||||
| -rw-r--r-- | libmu/src/maths/vector.rs | 90 |
2 files changed, 120 insertions, 2 deletions
diff --git a/libmu/src/maths/matrix.rs b/libmu/src/maths/matrix.rs index 7662652..9724086 100644 --- a/libmu/src/maths/matrix.rs +++ b/libmu/src/maths/matrix.rs @@ -1,6 +1,38 @@ use super::Float; use core::{fmt, ops}; +#[macro_export] +macro_rules! matrix { + ($( $( $x:expr ),* );* ) => {{ + let data = vec![ + $( + $( + $x, + )* + )* + ]; + + let rows = <[()]>::len(&[$( $crate::count_items!($($x),*) ),*]); + let cols = $crate::count_items!($($x),*); + + $crate::Matrix::new(rows, cols, data) + }}; +} + +#[macro_export] +macro_rules! count_items { + ($($item:expr),*) => { + <[()]>::len(&[$( $crate::replace_expr!($item ())),*]) + }; +} + +#[macro_export] +macro_rules! replace_expr { + ($_t:tt $sub:expr) => { + $sub + }; +} + pub struct Matrix<T: Float> { pub data: Vec<T>, pub rows: usize, diff --git a/libmu/src/maths/vector.rs b/libmu/src/maths/vector.rs index 1504013..682907e 100644 --- a/libmu/src/maths/vector.rs +++ b/libmu/src/maths/vector.rs @@ -1,8 +1,26 @@ -// TODO(Hachem): matrix multiplication with vector - use super::{Float, Matrix}; use core::ops; +#[macro_export] +macro_rules! row_vector { + ($($x:expr),*) => { + RowVector::new(vec![$($x),*]) + }; + ($($x:expr,)*) => { + RowVector::new(vec![$($x),*]) + }; +} + +#[macro_export] +macro_rules! column_vector { + ($($x:expr),*) => { + ColumnVector::new(vec![$($x),*]) + }; + ($($x:expr,)*) => { + ColumnVector::new(vec![$($x),*]) + }; +} + pub trait Vector<T: Float> { fn new(data: Vec<T>) -> Self; fn get(&self, index: usize) -> T; @@ -27,12 +45,48 @@ pub type RowVector<T> = VectorImpl<T, 1, 0>; pub type ColumnVector<T> = VectorImpl<T, 0, 1>; impl<T: Float> ColumnVector<T> { + pub fn mul_matrix(&self, matrix: &Matrix<T>) -> Option<ColumnVector<T>> { + if matrix.cols != self.size() { + return None; + } + + let mut result = ColumnVector::new(vec![T::zero(); matrix.rows]); + + for i in 0..matrix.rows { + let mut sum = T::zero(); + for j in 0..matrix.cols { + sum = sum + (matrix.get(i, j) * self.get(j)); + } + result.set(i, sum); + } + + Some(result) + } + pub fn transpose(&self) -> RowVector<T> { RowVector::new(self.0.clone()) } } impl<T: Float> RowVector<T> { + pub fn mul_matrix(&self, matrix: &Matrix<T>) -> Option<RowVector<T>> { + if self.size() != matrix.rows { + return None; + } + + let mut result = RowVector::new(vec![T::zero(); matrix.cols]); + + for j in 0..matrix.cols { + let mut sum = T::zero(); + for i in 0..matrix.rows { + sum = sum + (self.get(i) * matrix.get(i, j)); + } + result.set(j, sum); + } + + Some(result) + } + pub fn transpose(&self) -> ColumnVector<T> { ColumnVector::new(self.0.clone()) } @@ -244,3 +298,35 @@ impl<T: Float> VectorMatrix<T> for ColumnVector<T> { Self::new(matrix.data.clone()) } } + +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; + } + } +} |
