diff --git a/src/lib.rs b/src/lib.rs index 12f9d79..0f6b59f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -193,6 +193,40 @@ impl Matrix { Ok(()) } + pub fn sub_matrix( + &self, + start: (usize, usize), + end: (usize, usize), + ) -> Result { + if start.0 >= self.rows || start.1 >= self.columns { + return Err(MatrixError::IndexOutOfRange); + } + + if end.0 >= self.rows || end.1 >= self.columns { + return Err(MatrixError::IndexOutOfRange); + } + + if end.0 <= start.0 || end.1 <= start.1 { + return Err(MatrixError::IndexOutOfRange); + } + + let mut new_data: Vec = Vec::new(); + + for i in start.0..end.0 { + for k in start.1..end.1 { + new_data.push(*self.get(i, k)?); + } + } + + let new_matrix = Matrix { + rows: (end.0 + 1) - start.0, + columns: (end.1 + 1) - start.1, + data: new_data, + }; + + Ok(new_matrix) + } + fn partial_pivoting(&mut self, col: usize, sign: &mut Fraction) -> Result { if col >= self.columns { return Err(MatrixError::ColumnOutOfRange); @@ -331,6 +365,34 @@ impl Matrix { return Ok(determinant); } + + pub fn inverse(&self) -> Result { + if self.columns != self.rows { + return Err(MatrixError::NotSquared); + } + + let mut inverse = Matrix { + rows: self.rows, + columns: self.columns, + data: self.data.clone(), + }; + + for i in 0..inverse.rows { + let mut new_column: Vec = vec![Fraction::from(0i64); inverse.rows]; + + new_column[i] = Fraction::from(1i64); + + inverse.insert_column(inverse.columns - 1, new_column)?; + } + + let inverse = inverse.gauss_jordan_elimination()?; + + // Gets the interesting part that was affected by the gaussian elimination + let inverse = + inverse.sub_matrix((0, self.columns), (self.rows + 1, inverse.columns - 1))?; + + Ok(inverse) + } } impl Add for Matrix {