simplify Matrix::is_identity while also improving performance

This commit is contained in:
Max Verevkin 2021-09-26 19:34:19 +03:00
parent 7f236d88aa
commit 5cbff59f80
5 changed files with 8 additions and 41 deletions

View File

@ -63,50 +63,18 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
T::Epsilon: Clone, T::Epsilon: Clone,
{ {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let d;
if nrows > ncols {
d = ncols;
for i in d..nrows {
for j in 0..ncols {
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone()) {
return false;
}
}
}
} else {
// nrows <= ncols
d = nrows;
for j in 0..ncols {
for i in 0..nrows { for i in 0..nrows {
for j in d..ncols { let el = unsafe { self.get_unchecked((i, j)) };
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone()) { if (i == j && !relative_eq!(*el, T::one(), epsilon = eps.clone()))
return false; || (i != j && !relative_eq!(*el, T::zero(), epsilon = eps.clone()))
}
}
}
}
// Off-diagonal elements of the sub-square matrix.
for i in 1..d {
for j in 0..i {
// TODO: use unsafe indexing.
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone())
|| !relative_eq!(self[(j, i)], T::zero(), epsilon = eps.clone())
{ {
return false; return false;
} }
} }
} }
// Diagonal elements of the sub-square matrix.
for i in 0..d {
if !relative_eq!(self[(i, i)], T::one(), epsilon = eps.clone()) {
return false;
}
}
true true
} }
} }

View File

@ -351,7 +351,7 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for DualQuaternion<T> {
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.clone().to_vector().ulps_eq(&other.clone().to_vector(), epsilon.clone(), max_ulps.clone()) || self.clone().to_vector().ulps_eq(&other.clone().to_vector(), epsilon.clone(), max_ulps) ||
// Account for the double-covering of S², i.e. q = -q. // Account for the double-covering of S², i.e. q = -q.
self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.ulps_eq(&-b.clone(), epsilon.clone(), max_ulps)) self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.ulps_eq(&-b.clone(), epsilon.clone(), max_ulps))
} }

View File

@ -629,7 +629,7 @@ where
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.translation self.translation
.ulps_eq(&other.translation, epsilon.clone(), max_ulps.clone()) .ulps_eq(&other.translation, epsilon.clone(), max_ulps)
&& self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps) && self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps)
} }
} }

View File

@ -415,7 +415,7 @@ where
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.isometry self.isometry
.ulps_eq(&other.isometry, epsilon.clone(), max_ulps.clone()) .ulps_eq(&other.isometry, epsilon.clone(), max_ulps)
&& self.scaling.ulps_eq(&other.scaling, epsilon, max_ulps) && self.scaling.ulps_eq(&other.scaling, epsilon, max_ulps)
} }
} }

View File

@ -458,8 +458,7 @@ impl<T: RealField> UlpsEq for UnitComplex<T> {
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.re self.re.ulps_eq(&other.re, epsilon.clone(), max_ulps)
.ulps_eq(&other.re, epsilon.clone(), max_ulps.clone())
&& self.im.ulps_eq(&other.im, epsilon, max_ulps) && self.im.ulps_eq(&other.im, epsilon, max_ulps)
} }
} }