diff --git a/src/linalg/cholesky.rs b/src/linalg/cholesky.rs index 312fd6cd..36e164ea 100644 --- a/src/linalg/cholesky.rs +++ b/src/linalg/cholesky.rs @@ -140,9 +140,9 @@ where } /// Computes the determinant of the decomposed matrix. - pub fn determinant(&self) -> N::SimdRealField { + pub fn determinant(&self) -> T::SimdRealField { let dim = self.chol.nrows(); - let mut prod_diag = N::one(); + let mut prod_diag = T::one(); for i in 0..dim { prod_diag *= unsafe { *self.chol.get_unchecked((i, i)) }; } diff --git a/src/linalg/pow.rs b/src/linalg/pow.rs index edcf55dd..33759a90 100644 --- a/src/linalg/pow.rs +++ b/src/linalg/pow.rs @@ -2,23 +2,27 @@ use std::ops::DivAssign; -use crate::{allocator::Allocator, DefaultAllocator, DimMin, MatrixN}; +use crate::{ + allocator::Allocator, + storage::{Storage, StorageMut}, + DefaultAllocator, DimMin, Matrix, OMatrix, +}; use num::PrimInt; use simba::scalar::ComplexField; -impl MatrixN +impl Matrix where D: DimMin, - DefaultAllocator: Allocator, - DefaultAllocator: Allocator, + S: StorageMut, + DefaultAllocator: Allocator + Allocator, { /// Attempts to raise this matrix to an integral power `e` in-place. If this /// matrix is non-invertible and `e` is negative, it leaves this matrix /// untouched and returns `Err(())`. Otherwise, it returns `Ok(())` and /// overwrites this matrix with the result. #[must_use] - pub fn pow_mut(&mut self, mut e: T) -> Result<(), ()> { - let zero = T::zero(); + pub fn pow_mut(&mut self, mut e: I) -> Result<(), ()> { + let zero = I::zero(); // A matrix raised to the zeroth power is just the identity. if e == zero { @@ -34,18 +38,19 @@ where } } - let one = T::one(); - let two = T::from(2u8).unwrap(); + let one = I::one(); + let two = I::from(2u8).unwrap(); // We use the buffer to hold the result of multiplier ^ 2, thus avoiding // extra allocations. - let mut multiplier = self.clone(); - let mut buf = self.clone(); + let mut multiplier = self.clone_owned(); + let mut buf = self.clone_owned(); // Exponentiation by squares. loop { if e % two == one { - *self *= &multiplier; + self.mul_to(&multiplier, &mut buf); + self.copy_from(&buf); } e /= two; @@ -57,12 +62,20 @@ where } } } +} +impl> Matrix +where + D: DimMin, + S: StorageMut, + DefaultAllocator: Allocator + Allocator, +{ /// Attempts to raise this matrix to an integral power `e`. If this matrix /// is non-invertible and `e` is negative, it returns `None`. Otherwise, it /// returns the result as a new matrix. Uses exponentiation by squares. - pub fn pow(&self, e: T) -> Option { - let mut clone = self.clone(); + #[must_use] + pub fn pow(&self, e: I) -> Option> { + let mut clone = self.clone_owned(); match clone.pow_mut(e) { Ok(()) => Some(clone), diff --git a/tests/linalg/cholesky.rs b/tests/linalg/cholesky.rs index bb578d49..6fd83912 100644 --- a/tests/linalg/cholesky.rs +++ b/tests/linalg/cholesky.rs @@ -92,7 +92,7 @@ macro_rules! gen_tests( #[test] fn cholesky_determinant_static(_n in PROPTEST_MATRIX_DIM) { - let m = RandomSDP::new(U4, || random::<$scalar>().0).unwrap(); + let m = RandomSDP::new(Const::<4>, || random::<$scalar>().0).unwrap(); let lu_det = m.clone().lu().determinant(); assert_relative_eq!(lu_det.imaginary(), 0., epsilon = 1.0e-7); let chol_det = m.cholesky().unwrap().determinant();