feat(from): impl From i32 vector
This commit is contained in:
parent
333c6c7281
commit
4c2ebb1afd
1 changed files with 102 additions and 93 deletions
195
src/matrix.rs
195
src/matrix.rs
|
|
@ -25,6 +25,102 @@ pub struct Matrix {
|
||||||
/// Data stored in the matrix, you should not access this directly
|
/// Data stored in the matrix, you should not access this directly
|
||||||
data: Vec<Vec<i32>>,
|
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 {
|
impl FromStr for Matrix {
|
||||||
type Err = ParseMatrixError;
|
type Err = ParseMatrixError;
|
||||||
|
|
@ -120,100 +216,13 @@ impl<'a, 'b> Mul<&'b Matrix> for &'a Matrix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Matrix {
|
impl From<Vec<i32>> for Matrix {
|
||||||
/// Matrix initialiser function.
|
fn from(value: Vec<i32>) -> Self {
|
||||||
///
|
|
||||||
/// 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 {
|
Matrix {
|
||||||
nrows: data.len(),
|
nrows: value.len(),
|
||||||
ncols: data[0].len(),
|
ncols: 1,
|
||||||
data,
|
data: vec![value],
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue