From 75f882f860fdc65723d5263d0df033ceae1131d4 Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Fri, 2 Apr 2021 15:58:25 -0600 Subject: [PATCH] determinants can not function const_generics are not done and I can not use 2 methods in one due to the errors --- matrix/src/lib.rs | 79 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/matrix/src/lib.rs b/matrix/src/lib.rs index 3fd5409..7e28e5c 100644 --- a/matrix/src/lib.rs +++ b/matrix/src/lib.rs @@ -47,8 +47,19 @@ impl Matrix { } } - pub fn determinant(&self) -> f32 { - self.matrix[0][0] * self.matrix[1][1] - self.matrix[0][1] * self.matrix[1][0] + pub fn determinant(&self) -> f32 where + [(); H - 1]: , + [(); W - 1]: , + { + if W == 2 { + self.matrix[0][0] * self.matrix[1][1] - self.matrix[0][1] * self.matrix[1][0] + } else { + let mut sum = 0.0; + for (col, val) in self.matrix[0].iter().enumerate().take(W) { + sum += val * self.cofactor(0, col); + } + sum + } } fn zero_skip(&self, val: usize) -> usize { @@ -67,24 +78,34 @@ impl Matrix { } } - pub fn minor(&self, row: usize, col: usize) -> f32 + pub fn minor(&self, row: usize, col: usize) -> f32 where + [(); H - 1]: , + [(); W - 1]: , + [(); H - 1]: , + [(); W - 1]: , { - let t = self.zero_skip(row); - let b = self.bound_skip(row, H - 1); - let l = self.zero_skip(col); - let r = self.bound_skip(col, W - 1); + let m = self.sub_matrix(row, col); + let det = m.determinant(); + det + // let t = self.zero_skip(row); + // let b = self.bound_skip(row, H - 1); + // let l = self.zero_skip(col); + // let r = self.bound_skip(col, W - 1); - let tl = self.matrix[t][l]; - let br = self.matrix[b][r]; - let tr = self.matrix[t][r]; - let bl = self.matrix[b][l]; + // let tl = self.matrix[t][l]; + // let br = self.matrix[b][r]; + // let tr = self.matrix[t][r]; + // let bl = self.matrix[b][l]; - tl * br - tr * bl + // tl * br - tr * bl } - pub fn cofactor(&self, row: usize, col: usize) -> f32 { + pub fn cofactor(&self, row: usize, col: usize) -> f32 where + [(); H - 1]: , + [(); W - 1]: , + { let minor = self.minor(row, col); - if row + col % 1 == 0 { + if (row + col) & 0x1 == 0 { minor } else { minor * -1.0 @@ -457,6 +478,34 @@ mod tests { assert_eq!(-12.0, m.cofactor(0, 0)); assert_eq!(25.0, m.minor(1, 0)); assert_eq!(-25.0, m.cofactor(1, 0)); - } + + #[test] + fn determinant_3x3() { + let m = Matrix::from_array([ + [1.0, 2.0, 6.0], + [-5.0, 8.0, -4.0], + [2.0, 6.0, 4.0], + ]); + assert_eq!(56.0, m.cofactor(0, 0)); + assert_eq!(12.0, m.cofactor(0, 1)); + assert_eq!(-46.0, m.cofactor(0, 2)); + assert_eq!(-196.0, m.determinant()); + } + + #[test] + fn determinant_4x4() { + let m = Matrix::from_array([ + [-2.0, -8.0, 3.0, 5.0], + [-3.0, 1.0, 7.0, 3.0], + [1.0, 2.0, -9.0, 6.0], + [-6.0, 7.0, 7.0, -9.0], + ]); + assert_eq!(690.0, m.cofactor(0, 0)); + assert_eq!(447.0, m.cofactor(0, 1)); + assert_eq!(210.0, m.cofactor(0, 2)); + assert_eq!(51.0, m.cofactor(0, 3)); + assert_eq!(-4071.0, m.determinant()); + } + }