diff --git a/src/base/properties.rs b/src/base/properties.rs index ab0ceff2..8041a7af 100644 --- a/src/base/properties.rs +++ b/src/base/properties.rs @@ -119,4 +119,23 @@ where // TODO: improve this? self.clone_owned().try_inverse().is_some() } + + /// Returns `true` if this matrix is hermitian. + #[inline] + #[must_use] + pub fn is_hermitian(&self) -> bool { + self.is_square() && self.transpose().conjugate().eq(self) + } + + /// Returns `true` if this matrix is unitary. + #[inline] + #[must_use] + pub fn is_unitary(&self, eps: T::Epsilon) -> bool + where + T: Zero + One + RelativeEq, + T::Epsilon: Clone, + { + let r = self.transpose().conjugate() * self; + self.is_square() && r.is_identity(eps) + } } diff --git a/tests/core/matrix.rs b/tests/core/matrix.rs index 50c0e426..52355311 100644 --- a/tests/core/matrix.rs +++ b/tests/core/matrix.rs @@ -201,6 +201,24 @@ fn identity() { assert!(!not_id3.is_identity(0.0)); } +#[test] +fn is_hermitian() { + let a = Matrix2::new(1.0, 2.0, 3.0, 4.0); + let b = Matrix2::new(1.0, 2.0, 2.0, 1.0); + + assert!(!a.is_hermitian()); + assert!(b.is_hermitian()); +} + +#[test] +fn is_unitary() { + let a = Matrix2::new(1.0, 2.0, 3.0, 4.0); + let b = Matrix2::new(0.0, 1.0, 1.0, 0.0); + + assert!(!a.is_unitary(1.0e-7)); + assert!(b.is_unitary(1.0e-7)); +} + #[test] fn coordinates() { let a = Matrix3x4::new(11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34);