diff --git a/src/lib.rs b/src/lib.rs index 70013b6..76b5b7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ -use core::panic; use fractions::Fraction; use std::fmt::{Debug, Display}; use std::ops::Add; @@ -48,50 +47,34 @@ impl Matrix { return Ok(&self.data[index]); } - pub fn get_row(&self, row: usize) -> Result, MatrixError> { + pub fn get_row(&self, row: usize) -> Result, MatrixError> { if row >= self.rows { return Err(MatrixError::RowOutOfRange); } - let mut index = 0; - let mut data = Vec::new(); + let start = row * self.columns; + let end = start + self.columns; - index += self.columns * row; - for i in 0..self.columns { - data.push(self.data[index + i]); - } - - return Ok(data); + return Ok(self.data[start..end].iter()); } - pub fn get_column(&self, column: usize) -> Result, MatrixError> { + pub fn get_column( + &self, + column: usize, + ) -> Result, MatrixError> { if column >= self.columns { return Err(MatrixError::ColumnOutOfRange); } - let index = column; - let mut data = Vec::new(); - - for i in 0..self.rows { - data.push(self.data[(i * self.columns) + index]) - } - - return Ok(data); + Ok((0..self.rows).map(move |i| &self.data[i * self.columns + column])) } - pub fn get_diagonal(&self) -> Result, MatrixError> { + pub fn get_diagonal(&self) -> Result, MatrixError> { if self.columns != self.rows { return Err(MatrixError::NotSquared); } - let mut data = Vec::new(); - - let mut index; - for i in 0..self.columns { - index = i + (i * self.columns); - data.push(self.data[index]); - } - return Ok(data); + Ok((0..self.rows).map(move |i| &self.data[i * self.columns + i])) } pub fn set(&mut self, row: usize, column: usize, data: Fraction) -> Option { @@ -140,16 +123,11 @@ impl Matrix { return Some(MatrixError::RowOutOfRange); } - //Get copy of row2 - let temp = self.get_row(row2).unwrap(); - let mut index1 = 0; - let mut index2 = 0; - //Move from row1 to row2 - index1 += self.columns * row1; - index2 += self.columns * row2; + let start1 = row1 * self.columns; + let start2 = row2 * self.columns; + for i in 0..self.columns { - self.data[index2 + i] = self.data[index1 + i]; - self.data[index1 + i] = temp[i]; + self.data.swap(start1 + i, start2 + i); } None @@ -160,11 +138,11 @@ impl Matrix { return Some(MatrixError::ColumnOutOfRange); } - //Get copy of column2 - let temp = self.get_column(column2).unwrap(); for i in 0..self.rows { - self.data[column2 + (i * self.columns)] = self.data[column1 + (i * self.columns)]; - self.data[column1 + (i * self.columns)] = temp[i]; + let idx1 = column1 + i * self.columns; + let idx2 = column2 + i * self.columns; + + self.data.swap(idx1, idx2); } None @@ -218,8 +196,7 @@ impl Matrix { let row_i = trig_matrix.get_row(i)?; let new_row = row_x - .iter() - .zip(row_i.iter()) + .zip(row_i) .map(|(a, b)| *a - m * *b) .collect::>(); @@ -233,7 +210,6 @@ impl Matrix { let determinant = sign * trig_matrix .get_diagonal()? - .iter() .copied() .fold(Fraction::from(1i64), |acc, x| acc * x); @@ -288,19 +264,21 @@ impl Mul for Matrix { fn mul(self, other: Self) -> Self::Output { if self.columns != other.rows { - panic!("Matrix dimentions are inadecuate."); + return Err(MatrixError::InvalidSizeForMul); } let mut new_data: Vec = Vec::new(); for i in 0..self.rows { - let current_row = self.get_row(i)?; - for k in 0..other.columns { let current_column = other.get_column(k)?; + let current_row = self.get_row(i)?; + let mut new_value = Fraction::new(0, 1).unwrap(); - for (a, b) in current_row.iter().zip(current_column.iter()) { + + for (a, b) in current_row.zip(current_column) { new_value = new_value + (*a * *b); } + new_data.push(new_value); } }