Added into_iter, iter and iter_mut methods to Matrix, restructured math modules

This commit is contained in:
Egor 2024-05-13 11:34:59 +03:00
parent 1c4b7dfff3
commit 883df942ea
5 changed files with 96 additions and 77 deletions

View file

@ -3,24 +3,11 @@ use std::ops::{Index, IndexMut};
use num::Num; use num::Num;
pub struct Matrix<T: Num> { pub struct Matrix<T: Num> {
pub(super) width: usize, width: usize,
pub(super) data: Box<Vec<T>> data: Box<Vec<T>>
} }
impl<T: Num + Copy> Matrix<T> { impl<T: Num + Copy> Matrix<T> {
pub fn new(mut data: Vec<T>, width: usize) -> Self {
if width <= 0 {
panic!("Matrix width must be greater than 0, but got {}", width)
}
let height = data.len() / width;
let size = width * height;
if size < 2 {
panic!("Total matrix size must be greater than 1, but got {}", size)
}
data.truncate(size);
Self { width, data: Box::new(data) }
}
pub fn new_filled(val: T, width: usize, height: usize) -> Self { pub fn new_filled(val: T, width: usize, height: usize) -> Self {
let Some(size) = width.checked_mul(height) let Some(size) = width.checked_mul(height)
else { else {
@ -36,6 +23,25 @@ impl<T: Num + Copy> Matrix<T> {
pub fn new_zeroes(width: usize, height: usize) -> Self { pub fn new_zeroes(width: usize, height: usize) -> Self {
Self::new_filled(T::zero(), width, height) Self::new_filled(T::zero(), width, height)
} }
}
impl<T: Num> Matrix<T> {
pub fn new(mut data: Vec<T>, width: usize) -> Self {
if width <= 0 {
panic!("Matrix width must be greater than 0, but got {}", width)
}
let height = data.len() / width;
let size = width * height;
if size < 2 {
panic!("Total matrix size must be greater than 1, but got {}", size)
}
data.truncate(size);
Self { width, data: Box::new(data) }
}
pub(super) fn new_unchecked(data: Vec<T>, width: usize) -> Self {
Self { width, data: Box::new(data) }
}
pub fn width(&self) -> usize { pub fn width(&self) -> usize {
self.width self.width
@ -45,6 +51,10 @@ impl<T: Num + Copy> Matrix<T> {
self.data.len() / self.width self.data.len() / self.width
} }
pub fn size(&self) -> usize {
self.data.len()
}
pub fn minor(&self, row_index: usize, column_index: usize) -> Self { pub fn minor(&self, row_index: usize, column_index: usize) -> Self {
if self.width < 2 { if self.width < 2 {
panic!("Matrix width must be greater than 1 to form its minor, but got {}", self.width) panic!("Matrix width must be greater than 1 to form its minor, but got {}", self.width)
@ -54,17 +64,26 @@ impl<T: Num + Copy> Matrix<T> {
panic!("Matrix height must be greater than 1 to form its minor, but got {}", height) panic!("Matrix height must be greater than 1 to form its minor, but got {}", height)
} }
let minor_width = self.width - 1; let minor_width = self.width - 1;
let minor_size = minor_width * (height - 1); let mut minor_data = Vec::with_capacity(minor_width * (height - 1));
if minor_size < 2 {
panic!("Minor total size must be greater than 2, but got {}", minor_size)
}
let mut minor_data = Vec::with_capacity(minor_size);
for i in 0..row_index { for i in 0..row_index {
if i == row_index { continue; }
let row = &self[i]; let row = &self[i];
todo!() todo!()
} }
Self { width: minor_width, data: Box::new(minor_data) } Self { width: minor_width, data: Box::new(minor_data) }
} }
pub fn into_iter(self) -> std::vec::IntoIter<T> {
self.data.into_iter()
}
pub fn iter(&self) -> std::slice::Iter<T> {
self.data.iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<T> {
self.data.iter_mut()
}
} }
impl<T: Num> Index<usize> for Matrix<T> { impl<T: Num> Index<usize> for Matrix<T> {
@ -109,6 +128,7 @@ mod tests {
#[should_panic] #[should_panic]
fn size_too_big() { fn size_too_big() {
Matrix::<i32>::new_zeroes(usize::MAX, 2); Matrix::<i32>::new_zeroes(usize::MAX, 2);
let a = vec![0].into_iter();
} }
#[test] #[test]

View file

@ -1,2 +0,0 @@
pub mod matrix;
pub mod sq_matrix;

View file

@ -1,54 +0,0 @@
use num::Num;
use super::matrix::Matrix;
pub struct SquareMatrix<T: Num + Copy> {
matrix: Matrix<T>
}
impl<T: Num + Copy> SquareMatrix<T> {
pub fn new(mut data: Vec<T>, order: usize) -> Self {
let size = Self::check_size(order);
data.truncate(size);
Self {
matrix: Matrix {
width: order,
data: Box::new(data)
}
}
}
pub fn new_filled(val: T, order: usize) -> Self {
let size = Self::check_size(order);
let data = Box::new(vec![val; size]);
Self {
matrix: Matrix {
width: order, data
}
}
}
pub fn new_zeroes(order: usize) -> Self {
Self::new_filled(T::zero(), order)
}
fn check_size(order: usize) -> usize {
if order < 2 {
panic!("Square matrix must have at least order of 2, but got {}", order)
}
let Some(size) = order.checked_mul(order)
else {
panic!("Total matrix size for order {} exceeds usize limit", order)
};
return size;
}
pub fn order(&self) -> usize {
self.matrix.width
}
}
macro_rules! sq_matrix {
[ $o:expr; $( $x:expr ),+ ] => {
SquareMatrix::new(vec![$( $x, )+], $o)
};
}

View file

@ -1 +1,5 @@
pub mod matrix; mod matrix;
pub use matrix::Matrix;
mod sq_matrix;
pub use sq_matrix::SquareMatrix;

51
src/math/sq_matrix.rs Normal file
View file

@ -0,0 +1,51 @@
use num::Num;
use super::matrix::Matrix;
pub struct SquareMatrix<T: Num> {
matrix: Matrix<T>
}
impl<T: Num + Copy> SquareMatrix<T> {
pub fn new_filled(val: T, order: usize) -> Self {
let size = check_size(order);
let data = vec![val; size];
Self {
matrix: Matrix::new_unchecked(data, order)
}
}
pub fn new_zeroes(order: usize) -> Self {
Self::new_filled(T::zero(), order)
}
}
impl<T: Num> SquareMatrix<T> {
pub fn new(mut data: Vec<T>, order: usize) -> Self {
let size = check_size(order);
data.truncate(size);
Self {
matrix: Matrix::new_unchecked(data, order)
}
}
pub fn order(&self) -> usize {
self.matrix.width()
}
}
fn check_size(order: usize) -> usize {
if order < 2 {
panic!("Square matrix must have at least order of 2, but got {}", order)
}
let Some(size) = order.checked_mul(order)
else {
panic!("Total matrix size for order {} exceeds usize limit", order)
};
return size;
}
macro_rules! sq_matrix {
[ $o:expr; $( $x:expr ),+ ] => {
SquareMatrix::new(vec![$( $x, )+], $o)
};
}