Added SquareMatrix struct, started implemeting some methods for Matrix
This commit is contained in:
parent
93579e28f0
commit
1c4b7dfff3
4 changed files with 186 additions and 63 deletions
|
@ -1,63 +0,0 @@
|
||||||
use num::{Integer, Num};
|
|
||||||
|
|
||||||
pub struct Matrix<T: Num + Copy> {
|
|
||||||
width: usize, height: usize,
|
|
||||||
data: Box<Vec<T>>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Num + Copy> Matrix<T> {
|
|
||||||
pub fn new(width: usize, data: Vec<T>) -> Self {
|
|
||||||
if width == 0 {
|
|
||||||
panic!("Matrix width must not be 0")
|
|
||||||
}
|
|
||||||
let (height, append_zeroes) = data.len().div_rem(&width);
|
|
||||||
let mut matrix = Self { width, height, data: Box::new(data) };
|
|
||||||
if append_zeroes == 0 { return matrix; }
|
|
||||||
matrix.height += 1;
|
|
||||||
for _ in 0..append_zeroes {
|
|
||||||
matrix.data.push(T::zero());
|
|
||||||
}
|
|
||||||
return matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_filled(val: T, width: usize, height: usize) -> Self {
|
|
||||||
let Some(size) = width.checked_mul(height)
|
|
||||||
else {
|
|
||||||
panic!("Total matrix size for width {} and height {} exceeds usize limit", width, height)
|
|
||||||
};
|
|
||||||
if size < 2 {
|
|
||||||
panic!("Total matrix size must be greater than 1, but got {}", size)
|
|
||||||
}
|
|
||||||
let data = Box::new(vec![val; size]);
|
|
||||||
Self { width, height, data }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_zeroes(width: usize, height: usize) -> Self {
|
|
||||||
Self::new_filled(T::zero(), width, height)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn width(&self) -> usize {
|
|
||||||
self.width
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn height(&self) -> usize {
|
|
||||||
self.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn size_too_big() {
|
|
||||||
Matrix::<i32>::new_zeroes(usize::MAX, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn size_too_small() {
|
|
||||||
Matrix::<i32>::new_zeroes(1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
130
src/math/matrix/matrix.rs
Normal file
130
src/math/matrix/matrix.rs
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
|
use num::Num;
|
||||||
|
|
||||||
|
pub struct Matrix<T: Num> {
|
||||||
|
pub(super) width: usize,
|
||||||
|
pub(super) data: Box<Vec<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 {
|
||||||
|
let Some(size) = width.checked_mul(height)
|
||||||
|
else {
|
||||||
|
panic!("Total matrix size for width {} and height {} exceeds usize limit", width, height)
|
||||||
|
};
|
||||||
|
if size < 2 {
|
||||||
|
panic!("Total matrix size must be greater than 1, but got {}", size)
|
||||||
|
}
|
||||||
|
let data = Box::new(vec![val; size]);
|
||||||
|
Self { width, data }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_zeroes(width: usize, height: usize) -> Self {
|
||||||
|
Self::new_filled(T::zero(), width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn width(&self) -> usize {
|
||||||
|
self.width
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn height(&self) -> usize {
|
||||||
|
self.data.len() / self.width
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn minor(&self, row_index: usize, column_index: usize) -> Self {
|
||||||
|
if self.width < 2 {
|
||||||
|
panic!("Matrix width must be greater than 1 to form its minor, but got {}", self.width)
|
||||||
|
}
|
||||||
|
let height = self.height();
|
||||||
|
if height < 2 {
|
||||||
|
panic!("Matrix height must be greater than 1 to form its minor, but got {}", height)
|
||||||
|
}
|
||||||
|
let minor_width = self.width - 1;
|
||||||
|
let minor_size = 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 {
|
||||||
|
let row = &self[i];
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
Self { width: minor_width, data: Box::new(minor_data) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Num> Index<usize> for Matrix<T> {
|
||||||
|
type Output = [T];
|
||||||
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
|
let row_start = index * self.width;
|
||||||
|
&self.data[row_start..row_start + self.width]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Num> IndexMut<usize> for Matrix<T> {
|
||||||
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||||
|
let row_start = index * self.width;
|
||||||
|
&mut self.data[row_start..row_start + self.width]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Num> Index<(usize, usize)> for Matrix<T> {
|
||||||
|
type Output = T;
|
||||||
|
fn index(&self, index: (usize, usize)) -> &Self::Output {
|
||||||
|
&self.data[index.0 * self.width + index.1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Num> IndexMut<(usize, usize)> for Matrix<T> {
|
||||||
|
fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
|
||||||
|
&mut self.data[index.0 * self.width + index.1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! matrix {
|
||||||
|
[ $w:expr; $( $x:expr ),+ ] => {
|
||||||
|
Matrix::new(vec![$( $x, )+], $w)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn size_too_big() {
|
||||||
|
Matrix::<i32>::new_zeroes(usize::MAX, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn size_too_small() {
|
||||||
|
Matrix::<i32>::new_zeroes(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn new_test() {
|
||||||
|
let matrix = matrix![3;
|
||||||
|
1, 2, 3,
|
||||||
|
4, 5, 6,
|
||||||
|
7, 8, 9, 10
|
||||||
|
];
|
||||||
|
assert_eq!(matrix.width(), 3);
|
||||||
|
assert_eq!(matrix.height(), 3);
|
||||||
|
}
|
||||||
|
}
|
2
src/math/matrix/mod.rs
Normal file
2
src/math/matrix/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod matrix;
|
||||||
|
pub mod sq_matrix;
|
54
src/math/matrix/sq_matrix.rs
Normal file
54
src/math/matrix/sq_matrix.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue