| 1129 | |
| 1130 | #[inline] |
| 1131 | pub fn inverse(self) -> Option<Self> { |
| 1132 | if N == 2 { |
| 1133 | if self.determinant().abs() <= f32::EPSILON { |
| 1134 | return None; |
| 1135 | } |
| 1136 | return Some(Self(matrix_from_rows_2( |
| 1137 | Matrix2::from_rows(matrix_rows_2(self.0)) |
| 1138 | .inverse() |
| 1139 | .to_rows(), |
| 1140 | ))); |
| 1141 | } |
| 1142 | if N == 3 { |
| 1143 | if self.determinant().abs() <= f32::EPSILON { |
| 1144 | return None; |
| 1145 | } |
| 1146 | return Some(Self(matrix_from_rows_3( |
| 1147 | Matrix3::from_rows(matrix_rows_3(self.0)) |
| 1148 | .inverse() |
| 1149 | .to_rows(), |
| 1150 | ))); |
| 1151 | } |
| 1152 | if N == 4 { |
| 1153 | if self.determinant().abs() <= f32::EPSILON { |
| 1154 | return None; |
| 1155 | } |
| 1156 | return Some(Self(matrix_from_rows_4( |
| 1157 | Matrix4::from_rows(matrix_rows_4(self.0)) |
| 1158 | .inverse() |
| 1159 | .to_rows(), |
| 1160 | ))); |
| 1161 | } |
| 1162 | |
| 1163 | let mut lhs = self.0; |
| 1164 | let mut rhs = Self::identity().0; |
| 1165 | for pivot in 0..N { |
| 1166 | let mut best = pivot; |
| 1167 | let mut best_abs = lhs[pivot][pivot].abs(); |
| 1168 | for (r, row) in lhs.iter().enumerate().skip(pivot + 1) { |
| 1169 | let abs = row[pivot].abs(); |
| 1170 | if abs > best_abs { |
| 1171 | best = r; |
| 1172 | best_abs = abs; |
| 1173 | } |
| 1174 | } |
| 1175 | if best_abs <= f32::EPSILON { |
| 1176 | return None; |
| 1177 | } |
| 1178 | if best != pivot { |
| 1179 | lhs.swap(pivot, best); |
| 1180 | rhs.swap(pivot, best); |
| 1181 | } |
| 1182 | |
| 1183 | let pivot_value = lhs[pivot][pivot]; |
| 1184 | for c in 0..N { |
| 1185 | lhs[pivot][c] /= pivot_value; |
| 1186 | rhs[pivot][c] /= pivot_value; |
| 1187 | } |
| 1188 | |