use std::num::{Zero, One}; use mat::{Mat1, Mat2, Mat3}; use traits::division_ring::DivisionRing; use traits::inv::Inv; // some specializations: impl Inv for Mat1 { #[inline] fn inverse(&self) -> Option> { let mut res : Mat1 = copy *self; if res.inplace_inverse() { Some(res) } else { None } } #[inline] fn inplace_inverse(&mut self) -> bool { if self.mij[0].is_zero() { false } else { self.mij[0] = One::one::() / self.mij[0]; true } } } impl Inv for Mat2 { #[inline] fn inverse(&self) -> Option> { let mut res : Mat2 = copy *self; if res.inplace_inverse() { Some(res) } else { None } } #[inline] fn inplace_inverse(&mut self) -> bool { let det = self.mij[0 * 2 + 0] * self.mij[1 * 2 + 1] - self.mij[1 * 2 + 0] * self.mij[0 * 2 + 1]; if det.is_zero() { false } else { *self = Mat2::new([self.mij[1 * 2 + 1] / det , -self.mij[0 * 2 + 1] / det, -self.mij[1 * 2 + 0] / det, self.mij[0 * 2 + 0] / det]); true } } } impl Inv for Mat3 { #[inline] fn inverse(&self) -> Option> { let mut res = copy *self; if res.inplace_inverse() { Some(res) } else { None } } #[inline] fn inplace_inverse(&mut self) -> bool { let minor_m12_m23 = self.mij[1 * 3 + 1] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 1] * self.mij[1 * 3 + 2]; let minor_m11_m23 = self.mij[1 * 3 + 0] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 0] * self.mij[1 * 3 + 2]; let minor_m11_m22 = self.mij[1 * 3 + 0] * self.mij[2 * 3 + 1] - self.mij[2 * 3 + 0] * self.mij[1 * 3 + 1]; let det = self.mij[0 * 3 + 0] * minor_m12_m23 - self.mij[0 * 3 + 1] * minor_m11_m23 + self.mij[0 * 3 + 2] * minor_m11_m22; if det.is_zero() { false } else { *self = Mat3::new( [ (minor_m12_m23 / det), ((self.mij[0 * 3 + 2] * self.mij[2 * 3 + 1] - self.mij[2 * 3 + 2] * self.mij[0 * 3 + 1]) / det), ((self.mij[0 * 3 + 1] * self.mij[1 * 3 + 2] - self.mij[1 * 3 + 1] * self.mij[0 * 3 + 2]) / det), (-minor_m11_m23 / det), ((self.mij[0 * 3 + 0] * self.mij[2 * 3 + 2] - self.mij[2 * 3 + 0] * self.mij[0 * 3 + 2]) / det), ((self.mij[0 * 3 + 2] * self.mij[1 * 3 + 0] - self.mij[1 * 3 + 2] * self.mij[0 * 3 + 0]) / det), (minor_m11_m22 / det), ((self.mij[0 * 3 + 1] * self.mij[2 * 3 + 0] - self.mij[2 * 3 + 1] * self.mij[0 * 3 + 0]) / det), ((self.mij[0 * 3 + 0] * self.mij[1 * 3 + 1] - self.mij[1 * 3 + 0] * self.mij[0 * 3 + 1]) / det) ] ); true } } }