mirror of
https://github.com/SinTan1729/matrix-basic.git
synced 2024-12-26 05:48:36 -06:00
new: Added determinant method
This commit is contained in:
parent
f0c10ec7d0
commit
dfc15a399c
3 changed files with 68 additions and 7 deletions
|
@ -6,3 +6,4 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
num = "0.4.0"
|
||||||
|
|
|
@ -19,4 +19,12 @@ mod tests {
|
||||||
let c = Matrix::from(vec![vec![1, 2, 4], vec![2, 2, 5]]).unwrap();
|
let c = Matrix::from(vec![vec![1, 2, 4], vec![2, 2, 5]]).unwrap();
|
||||||
assert_eq!(a + b, c);
|
assert_eq!(a + b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn det_test() {
|
||||||
|
let a = Matrix::from(vec![vec![1, 2, 0], vec![0, 3, 5], vec![0, 0, 10]]).unwrap();
|
||||||
|
let b = Matrix::from(vec![vec![1, 2, 0], vec![0, 3, 5]]).unwrap();
|
||||||
|
assert_eq!(a.det(), Ok(30));
|
||||||
|
assert!(b.det().is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
|
use num::{traits::Zero, Integer};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Debug, Display, Formatter},
|
fmt::{self, Debug, Display, Formatter},
|
||||||
ops::{Add, Mul},
|
ops::{Add, Mul, Sub},
|
||||||
result::Result,
|
result::Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Matrix<T: Mul + Add> {
|
pub struct Matrix<T: Mul + Add + Sub> {
|
||||||
entries: Vec<Vec<T>>,
|
entries: Vec<Vec<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Mul + Add> Matrix<T> {
|
impl<T: Mul + Add + Sub + Zero> Matrix<T> {
|
||||||
pub fn from(entries: Vec<Vec<T>>) -> Result<Matrix<T>, &'static str> {
|
pub fn from(entries: Vec<Vec<T>>) -> Result<Matrix<T>, &'static str> {
|
||||||
let mut equal_rows = true;
|
let mut equal_rows = true;
|
||||||
let row_len = entries[0].len();
|
let row_len = entries[0].len();
|
||||||
|
@ -34,7 +35,7 @@ impl<T: Mul + Add> Matrix<T> {
|
||||||
self.entries[0].len()
|
self.entries[0].len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transpose(&self) -> Matrix<T>
|
pub fn transpose(&self) -> Self
|
||||||
where
|
where
|
||||||
T: Copy,
|
T: Copy,
|
||||||
{
|
{
|
||||||
|
@ -62,15 +63,66 @@ impl<T: Mul + Add> Matrix<T> {
|
||||||
{
|
{
|
||||||
self.transpose().entries
|
self.transpose().entries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_square(&self) -> bool {
|
||||||
|
self.height() == self.width()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn submatrix(&self, i: usize, j: usize) -> Self
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
{
|
||||||
|
let mut out = Vec::new();
|
||||||
|
for (m, row) in self.rows().iter().enumerate() {
|
||||||
|
if m == i {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut new_row = Vec::new();
|
||||||
|
for (n, entry) in row.iter().enumerate() {
|
||||||
|
if n != j {
|
||||||
|
new_row.push(*entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.push(new_row);
|
||||||
|
}
|
||||||
|
Matrix { entries: out }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn det(&self) -> Result<T, &'static str>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
T: Mul<Output = T>,
|
||||||
|
T: Sub<Output = T>,
|
||||||
|
{
|
||||||
|
if self.is_square() {
|
||||||
|
let out = if self.width() == 1 {
|
||||||
|
self.entries[0][0]
|
||||||
|
} else {
|
||||||
|
let n = 0..self.width();
|
||||||
|
let mut out = T::zero();
|
||||||
|
for i in n {
|
||||||
|
if i.is_even() {
|
||||||
|
out = out + (self.entries[0][i] * self.submatrix(0, i).det().unwrap());
|
||||||
|
} else {
|
||||||
|
out = out - (self.entries[0][i] * self.submatrix(0, i).det().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out
|
||||||
|
};
|
||||||
|
Ok(out)
|
||||||
|
} else {
|
||||||
|
Err("Provided matrix isn't square.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Debug + Mul + Add> Display for Matrix<T> {
|
impl<T: Debug + Mul + Add + Sub> Display for Matrix<T> {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "{:?}", self.entries)
|
write!(f, "{:?}", self.entries)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Mul<Output = T> + Add<Output = T> + Copy> Mul for Matrix<T> {
|
impl<T: Mul<Output = T> + Add + Sub + Copy + Zero> Mul for Matrix<T> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn mul(self, other: Self) -> Self {
|
fn mul(self, other: Self) -> Self {
|
||||||
let width = self.width();
|
let width = self.width();
|
||||||
|
@ -94,7 +146,7 @@ impl<T: Mul<Output = T> + Add<Output = T> + Copy> Mul for Matrix<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Add<Output = T> + Mul + Copy> Add for Matrix<T> {
|
impl<T: Add<Output = T> + Sub + Mul + Copy + Zero> Add for Matrix<T> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn add(self, other: Self) -> Self {
|
fn add(self, other: Self) -> Self {
|
||||||
if self.height() == other.height() && self.width() == other.width() {
|
if self.height() == other.height() && self.width() == other.width() {
|
||||||
|
|
Loading…
Reference in a new issue