1pub mod m3;
5pub mod m4;
6
7use num::Float;
8
9use crate::v::{v3::Vector3, v4::Vector4};
10
11pub fn cofactor<F: Float + std::fmt::Debug>(
13 m: &Vec<Vec<F>>, i: usize, j: usize) -> F {
14if m.len() == 2 {
19 return [[m[1][1]], [-m[1][0]], [-m[0][1]], [m[0][0]]][i][j];
20 }
21 let d = det(
22 &m.iter().enumerate().flat_map(|(ri, r)|
23 if i == ri { vec![] } else {
25 vec![r.iter().enumerate().flat_map(|(cj, &c)|
26 if j == cj { vec![] } else { vec![c] }
28 ).collect::<Vec<_>>()]
29 }
30 ).collect::<Vec<_>>()
31 );
32 if (i + j) % 2 == 0 { d } else { -d }
33}
34
35pub fn transpose<F: Float + std::fmt::Debug>(m: &Vec<Vec<F>>) -> Vec<Vec<F>> {
37 (0..m[0].len()).into_iter().map(|j|
38 (0..m.len()).into_iter().map(|i|
39 m[i][j]
40 ).collect::<Vec<_>>()
41 ).collect::<Vec<_>>()
42}
43
44pub fn det<F: Float + std::fmt::Debug>(m: &Vec<Vec<F>>) -> F {
46if m.len() == 2 { return m[0][0] * m[1][1] - m[0][1] * m[1][0]; } let mut d = <F>::from(0).unwrap();
52 for (cj, &c) in m[0].iter().enumerate() {
53 d = d + c * cofactor(m, 0, cj); }
55 d
56}
57
58pub fn inv<F: Float + std::fmt::Debug>(m: &Vec<Vec<F>>, p: F) ->
62 Option<Vec<Vec<F>>> {
63 assert_eq!(m.len(), m[0].len());
64 assert!(m.len() >= 2);
65 let d = det(m);
66 if crate::prec_eq_f(d, p, <F>::from(0).unwrap()) { return None; }
67 Some(transpose(&m.iter().enumerate().map(|(ri, r)|
68 r.iter().enumerate().map(|(cj, _c)|
69 cofactor(m, ri, cj) / d
70 ).collect::<Vec<_>>()
71 ).collect::<Vec<_>>()))
72}
73
74pub trait TMatrix<F: Float + std::fmt::Debug> {
76 fn colmajor3(_m: Vec<Vector3<F>>) -> Self where Self: Sized { panic!("cm3") }
78 fn rowmajor3(_m: Vec<Vector3<F>>) -> Self where Self: Sized { panic!("rm3") }
80 fn colmajor4(_m: Vec<Vector4<F>>) -> Self where Self: Sized { panic!("cm4") }
82 fn rowmajor4(_m: Vec<Vector4<F>>) -> Self where Self: Sized { panic!("rm4") }
84 fn col_major(m: &Vec<Vec<F>>) -> Self;
86 fn row_major(m: &Vec<Vec<F>>) -> Self;
88 fn new(m: &Vec<Vec<F>>) -> Self;
90 fn identity() -> Self;
92 fn prec_eq(&self, e: F, m: &impl TMatrix<F>) -> bool;
94 fn mev3(&self) -> &[Vector3<F>] { panic!("mev3") }
96 fn mev4(&self) -> &[Vector4<F>] { panic!("mev4") }
98 fn dot_m(&self, m: &impl TMatrix<F>) -> Self;
100 fn rowv3(&self, _j: usize) -> Vector3<F> { panic!("rowv3") }
102 fn colv3(&self, _i: usize) -> Vector3<F> { panic!("colv3") }
104 fn rowv4(&self, _j: usize) -> Vector4<F> { panic!("rowv4") }
106 fn colv4(&self, _i: usize) -> Vector4<F> { panic!("colv4") }
108 fn to_vec(&self) -> Vec<Vec<F>>;
110 fn transpose(&self) -> Self where Self: Sized {
112 Self::col_major(&self.to_vec())
113 }
114 fn det(&self) -> F {
116 crate::m::det(&self.to_vec())
117 }
118 fn inv(&self, p: F) -> Option<Self> where Self: Sized {
121 match crate::m::inv(&self.to_vec(), p) {
122 None => None,
123 Some(m) => Some(Self::new(&m))
124 }
125 }
126}