diff --git a/rustapps/advanced_calculator/src/linalg/matrix.rs b/rustapps/advanced_calculator/src/linalg/matrix.rs new file mode 100644 index 0000000..b191136 --- /dev/null +++ b/rustapps/advanced_calculator/src/linalg/matrix.rs @@ -0,0 +1,42 @@ +/// Represents a matrix. +#[derive(Debug, Clone)] +pub struct Matrix { + rows: usize, + cols: usize, + data: Vec, +} + +impl Matrix { + /// Creates a new matrix. + pub fn new(rows: usize, cols: usize, data: Vec) -> Self { + assert_eq!(rows * cols, data.len()); + Matrix { rows, cols, data } + } + + /// Adds two matrices. + pub fn add(&self, other: &Matrix) -> Matrix { + assert_eq!(self.rows, other.rows); + assert_eq!(self.cols, other.cols); + let data: Vec = self + .data + .iter() + .zip(&other.data) + .map(|(a, b)| a + b) + .collect(); + Matrix::new(self.rows, self.cols, data) + } + + /// Multiplies two matrices. + pub fn multiply(&self, other: &Matrix) -> Matrix { + assert_eq!(self.cols, other.rows); + let mut data = vec![0.0; self.rows * other.cols]; + for i in 0..self.rows { + for j in 0..other.cols { + data[i * other.cols + j] = (0..self.cols) + .map(|k| self.data[i * self.cols + k] * other.data[k * other.cols + j]) + .sum(); + } + } + Matrix::new(self.rows, other.cols, data) + } +} diff --git a/rustapps/advanced_calculator/src/linalg/vector.rs b/rustapps/advanced_calculator/src/linalg/vector.rs new file mode 100644 index 0000000..8d930a6 --- /dev/null +++ b/rustapps/advanced_calculator/src/linalg/vector.rs @@ -0,0 +1,47 @@ +/// Represents a vector. +#[derive(Debug, Clone)] +pub struct Vector { + data: Vec, +} + +impl Vector { + /// Creates a new vector. + pub fn new(data: Vec) -> Self { + Vector { data } + } + + /// Adds two vectors. + pub fn add(&self, other: &Vector) -> Vector { + assert_eq!(self.data.len(), other.data.len()); + let data: Vec = self + .data + .iter() + .zip(&other.data) + .map(|(a, b)| a + b) + .collect(); + Vector::new(data) + } + + /// Computes the dot product of two vectors. + pub fn dot(&self, other: &Vector) -> f64 { + assert_eq!(self.data.len(), other.data.len()); + self.data.iter().zip(&other.data).map(|(a, b)| a * b).sum() + } + + /// Computes the cross product of two vectors (only for 3D vectors). + pub fn cross(&self, other: &Vector) -> Vector { + assert_eq!(self.data.len(), 3); + assert_eq!(other.data.len(), 3); + let data = vec![ + self.data[1] * other.data[2] - self.data[2] * other.data[1], + self.data[2] * other.data[0] - self.data[0] * other.data[2], + self.data[0] * other.data[1] - self.data[1] * other.data[0], + ]; + Vector::new(data) + } + + /// Computes the magnitude of the vector. + pub fn magnitude(&self) -> f64 { + self.data.iter().map(|x| x * x).sum::().sqrt() + } +}