From 03f6211e69ef2bc819951d9403e294758851f1e6 Mon Sep 17 00:00:00 2001 From: LaEntropiaa Date: Wed, 29 Oct 2025 15:11:33 -0600 Subject: [PATCH] Holy shit, we got determinant, it works now, added a few mwthods (tested all) for helping, also started testing get_determinant, had errors with precision so now i implement Float trait from num_traits so that there are no precision errors (also caused lots of trouble changing the tests) --- src/lib.rs | 468 +++++++++++++++++++++++++++++++++++----------------- src/main.rs | 4 +- 2 files changed, 323 insertions(+), 149 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ca16a82..182bdc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use num_traits::{Num, NumAssign}; +use num_traits::{Num, NumAssign, Signed, Float}; use core::panic; use std::fmt::{self, Debug}; use std::ops::Add; @@ -7,13 +7,13 @@ use std::ops::Mul; #[derive(PartialEq, Eq, Debug)] -pub struct Matrix { +pub struct Matrix> { rows: usize, columns: usize, data: Vec, } -impl Matrix { +impl> Matrix { pub fn new(rows: usize, columns: usize, default: T) -> Self { Self { rows, @@ -64,6 +64,21 @@ impl Matrix Vec { + if self.columns != self.rows { + panic!("The matrix needs to be squared for getting diagonal.") + } + + let mut data = Vec::new(); + + let mut index = 0; + for i in 0..self.columns { + index = i + (i * self.columns); + data.push(self.data[index]); + } + return data; + } + pub fn set(&mut self, row: usize, column: usize, data: T) -> () { if row >= self.rows || column >= self.columns { panic!("Index given is out of range.") @@ -74,7 +89,33 @@ impl Matrix) -> () { + if row >= self.rows { + panic!("Row index given is out of bounds.") + } + if data.len() != self.columns { + panic!("Data is not the required size") + } + + for i in 0..data.len() { + self.set(row, i, data[i]); + } + } + + pub fn set_column(&mut self, column: usize, data: Vec) -> () { + if column >= self.columns { + panic!("Column index given is out of bouds.") + } + if data.len() != self.rows { + panic!("Data is not the required size") + } + + for i in 0..data.len() { + self.set(i, column, data[i]); + } + } + pub fn exchange_rows(&mut self, row1: usize, row2: usize) -> () { if row1 >= self.rows || row2 >= self.rows { panic!("Row index is out of bounds."); @@ -117,23 +158,62 @@ impl Matrix>(); + trig_matrix.set_row(x, new_row); + x += 1; + } } - return self.data[0]; + // YES, now we got ourselves a triangular matrix, now we just + // take the product of the diagonal and multiply by sign, that's + // the determinant :) + println!("{trig_matrix}"); + let determinant = sign * trig_matrix.get_diagonal().iter().copied().product::(); + + return determinant; } } -impl Add for Matrix { +impl> Add for Matrix { type Output = Self; fn add(self, other: Self) -> Self::Output { @@ -154,7 +234,7 @@ impl Add for } } -impl Sub for Matrix { +impl> Sub for Matrix { type Output = Self; fn sub(self, other: Self) -> Self::Output { @@ -175,7 +255,7 @@ impl Sub for } } -impl Mul for Matrix { +impl> Mul for Matrix { type Output = Self; fn mul(self, other: Self) -> Self::Output { @@ -205,7 +285,7 @@ impl Mul for } } -impl fmt::Display for Matrix { +impl> fmt::Display for Matrix { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut display = String::new(); let mut index = 0; @@ -227,9 +307,9 @@ mod tests { #[test] fn sum_two_matrix_1() { - let mut matrix1 = Matrix::new(4, 4, 2); - let matrix2 = Matrix::new(4, 4, 3); - let result_matrix = Matrix::new(4, 4, 5); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let matrix2 = Matrix::new(4, 4, 3.0); + let result_matrix = Matrix::new(4, 4, 5.0); matrix1 = matrix1 + matrix2; @@ -238,12 +318,12 @@ mod tests { #[test] fn sum_two_matrix_2() { - let mut matrix1 = Matrix::new(4, 4, 2); - let mut matrix2 = Matrix::new(4, 4, 0); - let mut result_matrix = Matrix::new(4, 4, 2); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let mut matrix2 = Matrix::new(4, 4, 0.0); + let mut result_matrix = Matrix::new(4, 4, 2.0); - result_matrix.set(0, 0, 9); - matrix2.set(0, 0, 7); + result_matrix.set(0, 0, 9.0); + matrix2.set(0, 0, 7.0); matrix1 = matrix1 + matrix2; assert_eq!(matrix1, result_matrix); @@ -252,17 +332,17 @@ mod tests { #[test] #[should_panic] fn sum_two_matrix_3() { - let mut matrix1 = Matrix::new(4, 4, 2); - let matrix2 = Matrix::new(4, 5, 0); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let matrix2 = Matrix::new(4, 5, 0.0); matrix1 = matrix1 + matrix2; } #[test] fn substract_two_matrix_1() { - let mut matrix1 = Matrix::new(4, 4, 2); - let matrix2 = Matrix::new(4, 4, 3); - let result_matrix = Matrix::new(4, 4, -1); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let matrix2 = Matrix::new(4, 4, 3.0); + let result_matrix = Matrix::new(4, 4, -1.0); matrix1 = matrix1 - matrix2; @@ -271,12 +351,12 @@ mod tests { #[test] fn substract_two_matrix_2() { - let mut matrix1 = Matrix::new(4, 4, 2); - let mut matrix2 = Matrix::new(4, 4, 0); - let mut result_matrix = Matrix::new(4, 4, 2); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let mut matrix2 = Matrix::new(4, 4, 0.0); + let mut result_matrix = Matrix::new(4, 4, 2.0); - result_matrix.set(0, 0, -5); - matrix2.set(0, 0, 7); + result_matrix.set(0, 0, -5.0); + matrix2.set(0, 0, 7.0); matrix1 = matrix1 - matrix2; assert_eq!(matrix1, result_matrix); @@ -285,87 +365,87 @@ mod tests { #[test] #[should_panic] fn substract_two_matrix_3() { - let mut matrix1 = Matrix::new(4, 4, 2); - let matrix2 = Matrix::new(4, 5, 0); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let matrix2 = Matrix::new(4, 5, 0.0); matrix1 = matrix1 - matrix2; } #[test] fn get_row_1() { - let mut matrix1 = Matrix::new(3, 4, 0); - matrix1.set(0, 0, 8); - matrix1.set(0, 1, 7); - matrix1.set(0, 2, 9); - matrix1.set(0, 3, 6); + let mut matrix1 = Matrix::new(3, 4, 0.0); + matrix1.set(0, 0, 8.0); + matrix1.set(0, 1, 7.0); + matrix1.set(0, 2, 9.0); + matrix1.set(0, 3, 6.0); - let data = vec![8, 7 , 9, 6]; + let data = vec![8.0, 7.0 , 9.0, 6.0]; assert_eq!(matrix1.get_row(0), data); } #[test] fn get_row_2() { - let mut matrix1 = Matrix::new(4, 4, 0); + let mut matrix1 = Matrix::new(3, 4, 0.0); - matrix1.set(3, 0, 8); - matrix1.set(3, 1, 7); - matrix1.set(3, 2, 9); - matrix1.set(3, 3, 6); + matrix1.set(2, 0, 8.0); + matrix1.set(2, 1, 7.0); + matrix1.set(2, 2, 9.0); + matrix1.set(2, 3, 6.0); - let data = vec![8, 7, 9, 6]; + let data = vec![8.0, 7.0, 9.0, 6.0]; - assert_eq!(matrix1.get_row(3), data); + assert_eq!(matrix1.get_row(2), data); } #[test] #[should_panic] fn get_row_3() { - let matrix1 = Matrix::new(4, 4, 0); + let matrix1 = Matrix::new(3, 4, 0.0); let _data = matrix1.get_row(4); } #[test] fn get_column_1() { - let mut matrix1 = Matrix::new(4, 3, 0); - matrix1.set(0, 0, 8); - matrix1.set(1, 0, 7); - matrix1.set(2, 0, 9); - matrix1.set(3, 0, 6); + let mut matrix1 = Matrix::new(4, 3, 0.0); + matrix1.set(0, 0, 8.0); + matrix1.set(1, 0, 7.0); + matrix1.set(2, 0, 9.0); + matrix1.set(3, 0, 6.0); - let data = vec![8, 7 , 9, 6]; + let data = vec![8.0, 7.0 , 9.0, 6.0]; assert_eq!(matrix1.get_column(0), data); } #[test] fn get_column_2() { - let mut matrix1 = Matrix::new(4, 4, 0); + let mut matrix1 = Matrix::new(4, 3, 0.0); - matrix1.set(0, 3, 8); - matrix1.set(1, 3, 7); - matrix1.set(2, 3, 9); - matrix1.set(3, 3, 6); + matrix1.set(0, 2, 8.0); + matrix1.set(1, 2, 7.0); + matrix1.set(2, 2, 9.0); + matrix1.set(3, 2, 6.0); - let data = vec![8, 7, 9, 6]; + let data = vec![8.0, 7.0, 9.0, 6.0]; - assert_eq!(matrix1.get_column(3), data); + assert_eq!(matrix1.get_column(2), data); } #[test] #[should_panic] fn get_column_3() { - let matrix1 = Matrix::new(4, 4, 0); + let matrix1 = Matrix::new(4, 4, 0.0); let _data = matrix1.get_column(4); } #[test] fn mult_matrix_1() { - let mut matrix1 = Matrix::new(4, 4, 2); - let matrix2 = Matrix::new(4, 4, 2); - let result_matrix = Matrix::new(4, 4, 16); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let matrix2 = Matrix::new(4, 4, 2.0); + let result_matrix = Matrix::new(4, 4, 16.0); matrix1 = matrix1 * matrix2; @@ -374,52 +454,52 @@ mod tests { #[test] fn mult_matrix_2() { - let mut matrix1 = Matrix::new(4, 4, 2); - let mut matrix2 = Matrix::new(4, 3, 4); - let mut result_matrix = Matrix::new(4, 3, 0); + let mut matrix1 = Matrix::new(4, 4, 2.0); + let mut matrix2 = Matrix::new(4, 3, 4.0); + let mut result_matrix = Matrix::new(4, 3, 0.0); - matrix1.set(0, 0, 6); - matrix1.set(0, 1, 8); - matrix1.set(0, 2, 9); - matrix1.set(0, 3, 5); - matrix1.set(1, 0, 3); - matrix1.set(1, 1, 8); - matrix1.set(1, 2, 4); - matrix1.set(1, 3, 7); - matrix1.set(2, 0, 4); - matrix1.set(2, 1, 5); - matrix1.set(2, 2, 6); - matrix1.set(2, 3, 4); - matrix1.set(3, 0, 6); - matrix1.set(3, 1, 2); - matrix1.set(3, 2, 2); - matrix1.set(3, 3, 9); + matrix1.set(0, 0, 6.0); + matrix1.set(0, 1, 8.0); + matrix1.set(0, 2, 9.0); + matrix1.set(0, 3, 5.0); + matrix1.set(1, 0, 3.0); + matrix1.set(1, 1, 8.0); + matrix1.set(1, 2, 4.0); + matrix1.set(1, 3, 7.0); + matrix1.set(2, 0, 4.0); + matrix1.set(2, 1, 5.0); + matrix1.set(2, 2, 6.0); + matrix1.set(2, 3, 4.0); + matrix1.set(3, 0, 6.0); + matrix1.set(3, 1, 2.0); + matrix1.set(3, 2, 2.0); + matrix1.set(3, 3, 9.0); - matrix2.set(0, 0, 7); - matrix2.set(0, 1, 6); - matrix2.set(0, 2, 1); - matrix2.set(1, 0, 6); - matrix2.set(1, 1, 4); - matrix2.set(1, 2, 8); - matrix2.set(2, 0, 3); - matrix2.set(2, 1, 0); - matrix2.set(2, 2, 6); - matrix2.set(3, 0, 1); - matrix2.set(3, 1, 1); - matrix2.set(3, 2, 1); + matrix2.set(0, 0, 7.0); + matrix2.set(0, 1, 6.0); + matrix2.set(0, 2, 1.0); + matrix2.set(1, 0, 6.0); + matrix2.set(1, 1, 4.0); + matrix2.set(1, 2, 8.0); + matrix2.set(2, 0, 3.0); + matrix2.set(2, 1, 0.0); + matrix2.set(2, 2, 6.0); + matrix2.set(3, 0, 1.0); + matrix2.set(3, 1, 1.0); + matrix2.set(3, 2, 1.0); - result_matrix.set(0, 0, 122); - result_matrix.set(0, 1, 73); - result_matrix.set(0, 2, 129); - result_matrix.set(1, 0, 88); - result_matrix.set(1, 1, 57); - result_matrix.set(1, 2, 98); - result_matrix.set(2, 0, 80); - result_matrix.set(2, 1, 48); - result_matrix.set(2, 2, 84); - result_matrix.set(3, 0, 69); - result_matrix.set(3, 1, 53); - result_matrix.set(3, 2, 43); + result_matrix.set(0, 0, 122.0); + result_matrix.set(0, 1, 73.0); + result_matrix.set(0, 2, 129.0); + result_matrix.set(1, 0, 88.0); + result_matrix.set(1, 1, 57.0); + result_matrix.set(1, 2, 98.0); + result_matrix.set(2, 0, 80.0); + result_matrix.set(2, 1, 48.0); + result_matrix.set(2, 2, 84.0); + result_matrix.set(3, 0, 69.0); + result_matrix.set(3, 1, 53.0); + result_matrix.set(3, 2, 43.0); matrix1 = matrix1 * matrix2; @@ -428,20 +508,20 @@ mod tests { #[test] fn exchange_rows_1() { - let mut matrix = Matrix::new(3, 4, 5); - matrix.set(0, 0, 1); - matrix.set(0, 1, 2); - matrix.set(0, 2, 3); - matrix.set(0, 3, 4); - matrix.set(1, 0, 5); - matrix.set(1, 1, 6); - matrix.set(1, 2, 7); - matrix.set(1, 3, 8); + let mut matrix = Matrix::new(3, 4, 5.0); + matrix.set(0, 0, 1.0); + matrix.set(0, 1, 2.0); + matrix.set(0, 2, 3.0); + matrix.set(0, 3, 4.0); + matrix.set(1, 0, 5.0); + matrix.set(1, 1, 6.0); + matrix.set(1, 2, 7.0); + matrix.set(1, 3, 8.0); matrix.exchange_rows(0, 1); - let row1 = vec![1, 2, 3, 4]; - let row2 = vec![5, 6, 7, 8]; + let row1 = vec![1.0, 2.0, 3.0, 4.0]; + let row2 = vec![5.0, 6.0, 7.0, 8.0]; assert_eq!(row1, matrix.get_row(1)); assert_eq!(row2, matrix.get_row(0)); @@ -449,20 +529,20 @@ mod tests { #[test] fn exchange_rows_2() { - let mut matrix = Matrix::new(3, 4, 5); - matrix.set(0, 0, 1); - matrix.set(0, 1, 2); - matrix.set(0, 2, 3); - matrix.set(0, 3, 4); - matrix.set(2, 0, 5); - matrix.set(2, 1, 6); - matrix.set(2, 2, 7); - matrix.set(2, 3, 8); + let mut matrix = Matrix::new(3, 4, 5.0); + matrix.set(0, 0, 1.0); + matrix.set(0, 1, 2.0); + matrix.set(0, 2, 3.0); + matrix.set(0, 3, 4.0); + matrix.set(2, 0, 5.0); + matrix.set(2, 1, 6.0); + matrix.set(2, 2, 7.0); + matrix.set(2, 3, 8.0); matrix.exchange_rows(0, 2); - let row1 = vec![1, 2, 3, 4]; - let row2 = vec![5, 6, 7, 8]; + let row1 = vec![1.0, 2.0, 3.0, 4.0]; + let row2 = vec![5.0, 6.0, 7.0, 8.0]; assert_eq!(row1, matrix.get_row(2)); assert_eq!(row2, matrix.get_row(0)); @@ -470,18 +550,18 @@ mod tests { #[test] fn exchange_columns_1() { - let mut matrix = Matrix::new(3, 4, 5); - matrix.set(0, 0, 1); - matrix.set(1, 0, 2); - matrix.set(2, 0, 3); - matrix.set(0, 1, 4); - matrix.set(1, 1, 5); - matrix.set(2, 1, 6); + let mut matrix = Matrix::new(3, 4, 5.0); + matrix.set(0, 0, 1.0); + matrix.set(1, 0, 2.0); + matrix.set(2, 0, 3.0); + matrix.set(0, 1, 4.0); + matrix.set(1, 1, 5.0); + matrix.set(2, 1, 6.0); matrix.exchange_columns(0, 1); - let column1 = vec![1, 2, 3]; - let column2 = vec![4, 5, 6]; + let column1 = vec![1.0, 2.0, 3.0]; + let column2 = vec![4.0, 5.0, 6.0]; assert_eq!(column1, matrix.get_column(1)); assert_eq!(column2, matrix.get_column(0)); @@ -489,20 +569,114 @@ mod tests { #[test] fn exchange_columns_2() { - let mut matrix = Matrix::new(3, 4, 5); - matrix.set(0, 0, 1); - matrix.set(1, 0, 2); - matrix.set(2, 0, 3); - matrix.set(0, 3, 4); - matrix.set(1, 3, 5); - matrix.set(2, 3, 6); + let mut matrix = Matrix::new(3, 4, 5.0); + matrix.set(0, 0, 1.0); + matrix.set(1, 0, 2.0); + matrix.set(2, 0, 3.0); + matrix.set(0, 3, 4.0); + matrix.set(1, 3, 5.0); + matrix.set(2, 3, 6.0); matrix.exchange_columns(0, 3); - let column1 = vec![1, 2, 3]; - let column2 = vec![4, 5, 6]; + let column1 = vec![1.0, 2.0, 3.0]; + let column2 = vec![4.0, 5.0, 6.0]; assert_eq!(column1, matrix.get_column(3)); assert_eq!(column2, matrix.get_column(0)); } + + #[test] + fn set_row_1() { + let mut matrix = Matrix::new(3, 4, 5.0); + let vec1 = vec![1.0, 2.0, 3.0, 4.0]; + matrix.set_row(0, vec1); + + let vec2 = vec![1.0, 2.0, 3.0, 4.0]; + let row = matrix.get_row(0); + assert_eq!(row, vec2); + } + + #[test] + fn set_row_2() { + let mut matrix = Matrix::new(3, 4, 5.0); + let vec1 = vec![1.0, 2.0, 3.0, 4.0]; + matrix.set_row(2, vec1); + + let vec2 = vec![1.0, 2.0, 3.0, 4.0]; + let row = matrix.get_row(2); + assert_eq!(row, vec2); + } + + #[test] + fn set_column_1() { + let mut matrix = Matrix::new(3, 4, 5.0); + let vec1 = vec![1.0, 2.0, 3.0]; + matrix.set_column(0, vec1); + + let vec2 = vec![1.0, 2.0, 3.0]; + let column = matrix.get_column(0); + assert_eq!(column, vec2); + } + + #[test] + fn set_column_2() { + let mut matrix = Matrix::new(3, 4, 5.0); + let vec1 = vec![1.0, 2.0, 3.0]; + matrix.set_column(3, vec1); + + let vec2 = vec![1.0, 2.0, 3.0]; + let column = matrix.get_column(3); + assert_eq!(column, vec2); + } + + #[test] + fn get_diagonal_1() { + let mut matrix = Matrix::new(3, 3, 8.0); + matrix.set(0, 0, 1.0); + matrix.set(1, 1, 2.0); + matrix.set(2, 2, 3.0); + + let vec1 = vec![1.0, 2.0, 3.0]; + assert_eq!(matrix.get_diagonal(), vec1); + } + + #[test] + fn get_diagonal_2() { + let mut matrix = Matrix::new(4, 4, 8.0); + matrix.set(0, 0, 1.0); + matrix.set(1, 1, 2.0); + matrix.set(2, 2, 3.0); + matrix.set(3, 3, 4.0); + + let vec1 = vec![1.0, 2.0, 3.0, 4.0]; + assert_eq!(matrix.get_diagonal(), vec1); + } + + #[test] + fn get_determinant_1() { + let mut matrix = Matrix::new(2, 2, 0.0); + matrix.set(0, 0, 2.0); + matrix.set(1, 0, 4.0); + matrix.set(0, 1, 3.0); + matrix.set(1, 1, 5.0); + + assert_eq!(matrix.get_determinant(), -2.0); + } + + #[test] + fn get_determinant_2() { + let mut matrix = Matrix::new(3, 3, 0.0); + matrix.set(0, 0, 3.0); + matrix.set(1, 0, 4.0); + matrix.set(2, 0, 7.0); + matrix.set(0, 1, 2.0); + matrix.set(1, 1, 5.0); + matrix.set(2, 1, 8.0); + matrix.set(0, 2, 1.0); + matrix.set(1, 2, 6.0); + matrix.set(2, 2, 9.0); + + assert_eq!(matrix.get_determinant(), 0.0); + } } diff --git a/src/main.rs b/src/main.rs index cdd08d9..2c03b9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use matrix::Matrix; fn main() { println!("Hola mundo que rollo wey"); - let mut matriz1 = Matrix::new(10, 15, 0); - matriz1.set(5, 5, 40); + let mut matriz1 = Matrix::new(10, 15, 0.0); + matriz1.set(5, 5, 40.0); println!("{}", matriz1); }