summaryrefslogtreecommitdiff
path: root/src/matrix.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/matrix.rs')
-rw-r--r--src/matrix.rs195
1 files changed, 102 insertions, 93 deletions
diff --git a/src/matrix.rs b/src/matrix.rs
index ec347c9..9227917 100644
--- a/src/matrix.rs
+++ b/src/matrix.rs
@@ -25,6 +25,102 @@ pub struct Matrix {
/// Data stored in the matrix, you should not access this directly
data: Vec<Vec<i32>>,
}
+impl Matrix {
+ /// Matrix initialiser function.
+ ///
+ /// Accepts a new array of data as a list of rows.
+ ///
+ /// TODOs
+ /// - Add row length check
+ pub fn new(data: Vec<Vec<i32>>) -> Matrix {
+ Matrix {
+ nrows: data.len(),
+ ncols: data[0].len(),
+ data,
+ }
+ }
+ /// Query one element at selected position.
+ ///
+ /// Returns `None` if index is out of bounds.
+ pub fn get(&self, row_index: usize, column_index: usize) -> Option<i32> {
+ let r = self.data.get(row_index)?;
+ let n = r.get(column_index)?;
+ Some(*n)
+ }
+
+ /// Update one element at selected position.
+ ///
+ /// Returns `Err()` if index is out of bounds.
+ pub fn set(
+ &mut self,
+ row_index: usize,
+ column_index: usize,
+ new_data: i32,
+ ) -> Result<(), MatrixSetValueError> {
+ self.data[row_index][column_index] = new_data;
+ Ok(())
+ }
+
+ /// Checks if this is a square matrix.
+ pub fn is_square(&self) -> bool {
+ self.nrows == self.ncols
+ }
+ fn splice(&self, at_index: usize) -> Matrix {
+ let mut data: Vec<Vec<i32>> = Vec::new();
+ for i in 0..self.data.len() {
+ if i == 0 {
+ 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)
+ }
+
+ /// Evaluates any N-by-N matrix.
+ ///
+ /// This function panics if the matrix is not square!
+ pub fn determinant(&self) -> i32 {
+ if !self.is_square() {
+ panic!()
+ };
+ if self.nrows == 2 && self.ncols == 2 {
+ return self.data[0][0] * self.data[1][1] - self.data[0][1] * self.data[1][0];
+ }
+ 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
+ }
+
+ /// Evaluates the tranpose of the matrix.
+ ///
+ /// Each row becomes a column, each column becomes a row.
+ 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,
+ }
+ }
+}
impl FromStr for Matrix {
type Err = ParseMatrixError;
@@ -120,100 +216,13 @@ impl<'a, 'b> Mul<&'b Matrix> for &'a Matrix {
}
}
-impl Matrix {
- /// Matrix initialiser function.
- ///
- /// Accepts a new array of data as a list of rows.
- ///
- /// TODOs
- /// - Add row length check
- pub fn new(data: Vec<Vec<i32>>) -> Matrix {
+impl From<Vec<i32>> for Matrix {
+ fn from(value: Vec<i32>) -> Self {
Matrix {
- nrows: data.len(),
- ncols: data[0].len(),
- data,
- }
- }
-
- /// Query one element at selected position.
- ///
- /// Returns `None` if index is out of bounds.
- pub fn get(&self, row_index: usize, column_index: usize) -> Option<i32> {
- let r = self.data.get(row_index)?;
- let n = r.get(column_index)?;
- Some(*n)
- }
-
- /// Update one element at selected position.
- ///
- /// Returns `Err()` if index is out of bounds.
- pub fn set(
- &mut self,
- row_index: usize,
- column_index: usize,
- new_data: i32,
- ) -> Result<(), MatrixSetValueError> {
- self.data[row_index][column_index] = new_data;
- Ok(())
- }
-
- /// Checks if this is a square matrix.
- pub fn is_square(&self) -> bool {
- self.nrows == self.ncols
- }
- fn splice(&self, at_index: usize) -> Matrix {
- let mut data: Vec<Vec<i32>> = Vec::new();
- for i in 0..self.data.len() {
- if i == 0 {
- 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)
- }
-
- /// Evaluates any N-by-N matrix.
- ///
- /// This function panics if the matrix is not square!
- pub fn determinant(&self) -> i32 {
- if !self.is_square() {
- panic!()
- };
- if self.nrows == 2 && self.ncols == 2 {
- return self.data[0][0] * self.data[1][1] - self.data[0][1] * self.data[1][0];
- }
- 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
- }
-
- /// Evaluates the tranpose of the matrix.
- ///
- /// Each row becomes a column, each column becomes a row.
- 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,
+ nrows: value.len(),
+ ncols: 1,
+ data: vec![value],
}
}
}
+