1use crate::Matrix;
2use std::error::Error;
3
4impl<T> Matrix<T>
5where T: std::ops::Mul<Output=T>
6+ std::ops::Sub<Output=T>
7+ Clone
8+ std::cmp::PartialOrd
9+ std::ops::Div<Output=Result<T, Box<dyn Error>>>
10+ std::ops::Add<Output=T> + std::fmt::Debug {
11
12 pub fn inverse_div_err(&self, neg_one: T, zero: T, one: T) -> Result<Matrix<T>, Box<dyn Error>> {
13
14 let (rows, columns) = self.dimensions()?;
15
16 if rows == columns {
17
18 let determinant = self.determinant(neg_one.clone())?;
19
20 if determinant != zero {
21
22 let minors_matrix = self.minors(neg_one.clone())?;
23
24 let cofactors_matrix = minors_matrix.cofactors(neg_one)?;
25
26 let transpose_matrix = cofactors_matrix.transpose()?;
27
28 let inv_det = (one / determinant)?;
29
30 let inverse_matrix = transpose_matrix * inv_det;
31
32 Ok(inverse_matrix)
33
34 } else {
35
36 Err("Matrix is not invertible!")?
37
38 }
39
40 } else {
41
42 Err("Non Square matrix!")?
43
44 }
45
46 }
47
48}
49
50impl<T> Matrix<T>
51where T: std::ops::Mul<Output=T>
52+ std::ops::Sub<Output=T>
53+ Clone
54+ std::cmp::PartialOrd
55+ std::ops::Div<Output=T>
56+ std::ops::Add<Output=T> + std::fmt::Debug {
57
58 pub fn inverse(&self, neg_one: T, zero: T, one: T) -> Result<Matrix<T>, Box<dyn Error>> {
59
60 let (rows, columns) = self.dimensions()?;
61
62 if rows == columns {
63
64 let determinant = self.determinant(neg_one.clone())?;
65
66 if determinant != zero {
67
68 let minors_matrix = self.minors(neg_one.clone())?;
69
70 let cofactors_matrix = minors_matrix.cofactors(neg_one)?;
71
72 let transpose_matrix = cofactors_matrix.transpose()?;
73
74 let inv_det = one / determinant;
75
76 let inverse_matrix = transpose_matrix * inv_det;
77
78 Ok(inverse_matrix)
79
80 } else {
81
82 Err("Matrix is not invertible!")?
83
84 }
85
86 } else {
87
88 Err("Non Square matrix!")?
89
90 }
91
92 }
93
94}
95
96#[cfg(test)]
97mod tests {
98
99 use crate::Fraction;
100 use super::*;
101
102 #[test]
103 fn test_matrix_inverse_0() {
104
105 let a = Matrix(vec![
106 vec![Fraction::from(&1_u8), (&2_u8).into(), (&3_u8).into()],
107 vec![(&4_u8).into(), (&5_u8).into(), (&6_u8).into()],
108 vec![(&7_u8).into(), (&2_u8).into(), (&9_u8).into()],
109 ]);
110
111 let i = Matrix(vec![
112 vec![("-11/12").try_into().unwrap(), ("1/3").try_into().unwrap(), ("1/12").try_into().unwrap()],
113 vec![("-1/6").try_into().unwrap(), ("1/3").try_into().unwrap(), ("-1/6").try_into().unwrap()],
114 vec![("3/4").try_into().unwrap(), ("-1/3").try_into().unwrap(), ("1/12").try_into().unwrap()],
115 ]);
116
117 assert_eq!(
118 a.inverse_div_err(
119 ("-1/1").try_into().unwrap(),
120 (&0_u8).into(),
121 (&1_u8).into()
122 ).unwrap(),
123 i
124 );
125
126 }
127
128 }