Matrix can now be of size 1x1, can take minor of 2x2 matrix, minor tests modifications
This commit is contained in:
parent
17e0edb3ca
commit
7dfef8b718
2 changed files with 38 additions and 43 deletions
|
@ -14,13 +14,16 @@ pub struct Matrix<T: Num> {
|
||||||
|
|
||||||
impl<T: Num + Clone> Matrix<T> {
|
impl<T: Num + Clone> Matrix<T> {
|
||||||
pub fn new_filled(val: T, width: usize, height: usize) -> Self {
|
pub fn new_filled(val: T, width: usize, height: usize) -> Self {
|
||||||
|
if width == 0 {
|
||||||
|
panic!("Matrix width must be greater than 0, but got {}", width)
|
||||||
|
}
|
||||||
|
if height == 0 {
|
||||||
|
panic!("Matrix height must be greater than 0, but got {}", width)
|
||||||
|
}
|
||||||
let Some(size) = width.checked_mul(height)
|
let Some(size) = width.checked_mul(height)
|
||||||
else {
|
else {
|
||||||
panic!("Total matrix size for width {} and height {} exceeds usize limit", width, height)
|
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]);
|
let data = Box::new(vec![val; size]);
|
||||||
Self { width, data }
|
Self { width, data }
|
||||||
}
|
}
|
||||||
|
@ -48,15 +51,14 @@ impl<T: Num + Clone> Matrix<T> {
|
||||||
|
|
||||||
impl<T: Num> Matrix<T> {
|
impl<T: Num> Matrix<T> {
|
||||||
pub fn new(mut data: Vec<T>, width: usize) -> Self {
|
pub fn new(mut data: Vec<T>, width: usize) -> Self {
|
||||||
if width <= 0 {
|
if width == 0 {
|
||||||
panic!("Matrix width must be greater than 0, but got {}", width)
|
panic!("Matrix width must be greater than 0, but got {}", width)
|
||||||
}
|
}
|
||||||
let height = data.len() / width;
|
if data.len() < width {
|
||||||
let size = width * height;
|
panic!("Data vector must be greater than or equal to width, but got length {} for width {}", data.len(), width)
|
||||||
if size < 2 {
|
|
||||||
panic!("Total matrix size must be greater than 1, but got {}", size)
|
|
||||||
}
|
}
|
||||||
data.truncate(size);
|
let odd_elements = data.len() % width;
|
||||||
|
data.truncate(data.len() - odd_elements);
|
||||||
Self { width, data: Box::new(data) }
|
Self { width, data: Box::new(data) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,23 +102,23 @@ impl<T: Num> Matrix<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_row(&mut self, i: usize) {
|
pub fn remove_row(&mut self, i: usize) {
|
||||||
if self.height() <= 2 {
|
if self.height() == 1 {
|
||||||
panic!("Unable to remove row of a matrix with height {}", self.height());
|
panic!("Unable to remove row of a matrix with height 1");
|
||||||
}
|
}
|
||||||
let row_start = i * self.width;
|
let row_start = i * self.width;
|
||||||
self.data.drain(row_start..row_start+self.width);
|
self.data.drain(row_start..row_start+self.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_last_row(&mut self) {
|
pub fn remove_last_row(&mut self) {
|
||||||
if self.height() <= 2 {
|
if self.height() == 1 {
|
||||||
panic!("Unable to remove row of a matrix with height {}", self.height());
|
panic!("Unable to remove row of a matrix with height 1");
|
||||||
}
|
}
|
||||||
self.data.truncate(self.data.len() - self.width);
|
self.data.truncate(self.data.len() - self.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_column(&mut self, j: usize) {
|
pub fn remove_column(&mut self, j: usize) {
|
||||||
if self.width <= 2 {
|
if self.width == 1 {
|
||||||
panic!("Unable to remove column of a matrix with height {}", self.width);
|
panic!("Unable to remove column of a matrix with width 1");
|
||||||
}
|
}
|
||||||
for i in 0..self.height() {
|
for i in 0..self.height() {
|
||||||
let remove_at = i * (self.width - 1) + j;
|
let remove_at = i * (self.width - 1) + j;
|
||||||
|
@ -178,9 +180,15 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "size must be greater")]
|
#[should_panic(expected = "width must be greater than 0")]
|
||||||
fn size_too_small() {
|
fn width_zero() {
|
||||||
Matrix::<i32>::new_zeroes(1, 1);
|
Matrix::<i32>::new_zeroes(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "height must be greater than 0")]
|
||||||
|
fn height_zero() {
|
||||||
|
Matrix::<i32>::new_zeroes(1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -310,18 +318,17 @@ mod tests {
|
||||||
#[should_panic(expected = "Unable to remove")]
|
#[should_panic(expected = "Unable to remove")]
|
||||||
fn remove_row_wrong_height() {
|
fn remove_row_wrong_height() {
|
||||||
matrix![2;
|
matrix![2;
|
||||||
1, 2,
|
1, 2
|
||||||
3, 4
|
].remove_row(0);
|
||||||
].remove_row(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Unable to remove")]
|
#[should_panic(expected = "Unable to remove")]
|
||||||
fn remove_column_wrong_height() {
|
fn remove_column_wrong_height() {
|
||||||
matrix![2;
|
matrix![1;
|
||||||
1, 2,
|
1,
|
||||||
3, 4
|
3
|
||||||
].remove_column(1);
|
].remove_column(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -4,15 +4,12 @@ use num::Num;
|
||||||
|
|
||||||
impl<T: Num + Clone> Matrix<T> {
|
impl<T: Num + Clone> Matrix<T> {
|
||||||
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 == 1 {
|
||||||
panic!("Matrix width must be greater than 1 to form its minor, but got {}", self.width)
|
panic!("Unable to take minor of a matrix with width 1")
|
||||||
}
|
}
|
||||||
let height = self.height();
|
let height = self.height();
|
||||||
if height < 2 {
|
if height == 1 {
|
||||||
panic!("Matrix height must be greater than 1 to form its minor, but got {}", height)
|
panic!("Unable to take minor of a matrix with height 1")
|
||||||
}
|
|
||||||
if self.width == 2 && height == 2 {
|
|
||||||
panic!("Unable to form minor of a 2x2 matrix");
|
|
||||||
}
|
}
|
||||||
let minor_width = self.width - 1;
|
let minor_width = self.width - 1;
|
||||||
let mut minor_data = Box::new(Vec::with_capacity(minor_width * (height - 1)));
|
let mut minor_data = Box::new(Vec::with_capacity(minor_width * (height - 1)));
|
||||||
|
@ -62,22 +59,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "minor of a 2x2 matrix")]
|
#[should_panic(expected = "Unable to take minor of a matrix with width 1")]
|
||||||
fn minor_2x2_panic() {
|
|
||||||
matrix![2;
|
|
||||||
1, 2,
|
|
||||||
3, 4
|
|
||||||
].minor(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic(expected = "width must be greater")]
|
|
||||||
fn minor_1xn_panic() {
|
fn minor_1xn_panic() {
|
||||||
matrix![1; 1, 2, 3, 4].minor(0, 0);
|
matrix![1; 1, 2, 3, 4].minor(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "height must be greater")]
|
#[should_panic(expected = "Unable to take minor of a matrix with height 1")]
|
||||||
fn minor_nx1_panic() {
|
fn minor_nx1_panic() {
|
||||||
matrix![4; 1, 2, 3, 4].minor(0, 0);
|
matrix![4; 1, 2, 3, 4].minor(0, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue