diff options
Diffstat (limited to 'src/types/matrix.rs')
-rw-r--r-- | src/types/matrix.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/types/matrix.rs b/src/types/matrix.rs new file mode 100644 index 0000000..ff292fc --- /dev/null +++ b/src/types/matrix.rs @@ -0,0 +1,75 @@ +use std::str::FromStr; +/// Matrix +pub struct Matrix { + pub nrows: usize, + pub ncols: usize, + pub data: Vec<Vec<i32>>, +} +impl Matrix { + pub fn new(data: Vec<Vec<i32>>) -> Matrix { + Matrix { + nrows: data[0].len(), + ncols: data.len(), + data, + } + } + pub fn from_str(s: String) -> Matrix { + let mut d: Vec<Vec<i32>> = Vec::new(); + let rows_iter = s.split('\n'); + for (_i, txt) in rows_iter.enumerate() { + let mut r: Vec<i32> = Vec::new(); + for (_j, ch) in txt.split(',').enumerate() { + let parsed = match i32::from_str(ch) { + Ok(n) => n, + Err(e) => panic!("Err: {}", e), + }; + r.push(parsed); + } + d.push(r); + } + Matrix::new(d) + } + pub fn is_square(&self) -> bool { + &self.nrows == &self.ncols + } + pub fn splice(&self, at_index: usize) -> Matrix { + let mut data: Vec<Vec<i32>> = Vec::new(); + for i in 0..self.data.len() { + if i == at_index {continue;} + let mut r: Vec<i32> = Vec::new(); + for j in 0..self.data[i].len() { + if j == at_index {continue;} + r.push(self.data[i][j]); + } + data.push(r); + } + Matrix::new(data) + } + pub fn determinant(&self) -> i32 { + if self.nrows == 2 && self.nrows == 2 { + return &self.data[0][0] * &self.data[0][1] - &self.data[1][0] * &self.data[1][1]; + } + let mut tmp = 0; + for (i, n) in self.data[0].iter().enumerate() { + let mult = if i % 2 == 0 { -*n } else { *n }; + let eval = self.splice(i).determinant(); + tmp += mult * eval; + } + tmp + } + pub fn transpose(&self) -> Matrix { + let mut new_data = Vec::<Vec<i32>>::new(); + for i in 0..self.nrows { + let mut new_row = Vec::<i32>::new(); + for j in 0..self.ncols { + new_row.push(self.data[j][i]); + } + new_data.push(new_row); + } + Matrix { + nrows: self.ncols, + ncols: self.nrows, + data: new_data, + } + } +} |