diff --git a/src/solve.rs b/src/solve.rs index 9e8ce307..115a3ba7 100644 --- a/src/solve.rs +++ b/src/solve.rs @@ -70,7 +70,7 @@ pub use lapack_traits::{Pivot, Transpose}; /// /// If you plan to solve many equations with the same `A` matrix but different /// `b` vectors, it's faster to factor the `A` matrix once using the -/// `Factorize` trait, and then solve using the `Factorized` struct. +/// `Factorize` trait, and then solve using the `LUFactorized` struct. pub trait Solve { /// Solves a system of linear equations `A * x = b` where `A` is `self`, `b` /// is the argument, and `x` is the successful result. @@ -125,7 +125,7 @@ pub trait Solve { } /// Represents the LU factorization of a matrix `A` as `A = P*L*U`. -pub struct Factorized { +pub struct LUFactorized { /// The factors `L` and `U`; the unit diagonal elements of `L` are not /// stored. pub a: ArrayBase, @@ -133,7 +133,7 @@ pub struct Factorized { pub ipiv: Pivot, } -impl Solve for Factorized +impl Solve for LUFactorized where A: Scalar, S: Data, @@ -213,36 +213,19 @@ where } } -impl Factorized -where - A: Scalar, - S: DataMut, -{ - /// Computes the inverse of the factorized matrix. - pub fn into_inverse(mut self) -> Result> { - unsafe { - A::inv( - self.a.square_layout()?, - self.a.as_allocated_mut()?, - &self.ipiv, - )? - }; - Ok(self.a) - } -} /// An interface for computing LU factorizations of matrix refs. pub trait Factorize { /// Computes the LU factorization `A = P*L*U`, where `P` is a permutation /// matrix. - fn factorize(&self) -> Result>; + fn factorize(&self) -> Result>; } /// An interface for computing LU factorizations of matrices. pub trait FactorizeInto { /// Computes the LU factorization `A = P*L*U`, where `P` is a permutation /// matrix. - fn factorize_into(self) -> Result>; + fn factorize_into(self) -> Result>; } impl FactorizeInto for ArrayBase @@ -250,9 +233,9 @@ where A: Scalar, S: DataMut, { - fn factorize_into(mut self) -> Result> { + fn factorize_into(mut self) -> Result> { let ipiv = unsafe { A::lu(self.layout()?, self.as_allocated_mut()?)? }; - Ok(Factorized { + Ok(LUFactorized { a: self, ipiv: ipiv, }) @@ -264,10 +247,10 @@ where A: Scalar, Si: Data, { - fn factorize(&self) -> Result>> { + fn factorize(&self) -> Result>> { let mut a: Array2 = replicate(self); let ipiv = unsafe { A::lu(a.layout()?, a.as_allocated_mut()?)? }; - Ok(Factorized { a: a, ipiv: ipiv }) + Ok(LUFactorized { a: a, ipiv: ipiv }) } } @@ -285,6 +268,41 @@ pub trait InverseInto { fn inv_into(self) -> Result; } +impl InverseInto for LUFactorized +where + A: Scalar, + S: DataMut, +{ + type Output = ArrayBase; + + fn inv_into(mut self) -> Result> { + unsafe { + A::inv( + self.a.square_layout()?, + self.a.as_allocated_mut()?, + &self.ipiv, + )? + }; + Ok(self.a) + } +} + +impl Inverse for LUFactorized +where + A: Scalar, + S: Data, +{ + type Output = Array2; + + fn inv(&self) -> Result> { + let f = LUFactorized { + a: replicate(&self.a), + ipiv: self.ipiv.clone(), + }; + f.inv_into() + } +} + impl InverseInto for ArrayBase where A: Scalar, @@ -294,7 +312,7 @@ where fn inv_into(self) -> Result { let f = self.factorize_into()?; - f.into_inverse() + f.inv_into() } } @@ -307,6 +325,6 @@ where fn inv(&self) -> Result { let f = self.factorize()?; - f.into_inverse() + f.inv_into() } } diff --git a/src/solveh.rs b/src/solveh.rs index 291b251c..c326005e 100644 --- a/src/solveh.rs +++ b/src/solveh.rs @@ -63,7 +63,7 @@ pub use lapack_traits::{Pivot, UPLO}; /// If you plan to solve many equations with the same Hermitian (or real /// symmetric) coefficient matrix `A` but different `b` vectors, it's faster to /// factor the `A` matrix once using the `FactorizeH` trait, and then solve -/// using the `FactorizedH` struct. +/// using the `BKFactorized` struct. pub trait SolveH { /// Solves a system of linear equations `A * x = b` with Hermitian (or real /// symmetric) matrix `A`, where `A` is `self`, `b` is the argument, and @@ -89,12 +89,12 @@ pub trait SolveH { /// Represents the Bunch–Kaufman factorization of a Hermitian (or real /// symmetric) matrix as `A = P * U * D * U^H * P^T`. -pub struct FactorizedH { +pub struct BKFactorized { pub a: ArrayBase, pub ipiv: Pivot, } -impl SolveH for FactorizedH +impl SolveH for BKFactorized where A: Scalar, S: Data, @@ -131,36 +131,12 @@ where } -impl FactorizedH -where - A: Scalar, - S: DataMut, -{ - /// Computes the inverse of the factorized matrix. - /// - /// **Warning: The inverse is stored only in the upper triangular portion - /// of the result matrix!** If you want the lower triangular portion to be - /// correct, you must fill it in according to the results in the upper - /// triangular portion. - pub fn into_inverseh(mut self) -> Result> { - unsafe { - A::invh( - self.a.square_layout()?, - UPLO::Upper, - self.a.as_allocated_mut()?, - &self.ipiv, - )? - }; - Ok(self.a) - } -} - /// An interface for computing the Bunch–Kaufman factorization of Hermitian (or /// real symmetric) matrix refs. pub trait FactorizeH { /// Computes the Bunch–Kaufman factorization of a Hermitian (or real /// symmetric) matrix. - fn factorizeh(&self) -> Result>; + fn factorizeh(&self) -> Result>; } /// An interface for computing the Bunch–Kaufman factorization of Hermitian (or @@ -168,7 +144,7 @@ pub trait FactorizeH { pub trait FactorizeHInto { /// Computes the Bunch–Kaufman factorization of a Hermitian (or real /// symmetric) matrix. - fn factorizeh_into(self) -> Result>; + fn factorizeh_into(self) -> Result>; } impl FactorizeHInto for ArrayBase @@ -176,9 +152,9 @@ where A: Scalar, S: DataMut, { - fn factorizeh_into(mut self) -> Result> { + fn factorizeh_into(mut self) -> Result> { let ipiv = unsafe { A::bk(self.layout()?, UPLO::Upper, self.as_allocated_mut()?)? }; - Ok(FactorizedH { + Ok(BKFactorized { a: self, ipiv: ipiv, }) @@ -190,10 +166,10 @@ where A: Scalar, Si: Data, { - fn factorizeh(&self) -> Result>> { + fn factorizeh(&self) -> Result>> { let mut a: Array2 = replicate(self); let ipiv = unsafe { A::bk(a.layout()?, UPLO::Upper, a.as_allocated_mut()?)? }; - Ok(FactorizedH { a: a, ipiv: ipiv }) + Ok(BKFactorized { a: a, ipiv: ipiv }) } } @@ -221,6 +197,42 @@ pub trait InverseHInto { fn invh_into(self) -> Result; } +impl InverseHInto for BKFactorized +where + A: Scalar, + S: DataMut, +{ + type Output = ArrayBase; + + fn invh_into(mut self) -> Result> { + unsafe { + A::invh( + self.a.square_layout()?, + UPLO::Upper, + self.a.as_allocated_mut()?, + &self.ipiv, + )? + }; + Ok(self.a) + } +} + +impl InverseH for BKFactorized +where + A: Scalar, + S: Data, +{ + type Output = Array2; + + fn invh(&self) -> Result { + let f = BKFactorized { + a: replicate(&self.a), + ipiv: self.ipiv.clone(), + }; + f.invh_into() + } +} + impl InverseHInto for ArrayBase where A: Scalar, @@ -230,7 +242,7 @@ where fn invh_into(self) -> Result { let f = self.factorizeh_into()?; - f.into_inverseh() + f.invh_into() } } @@ -243,6 +255,6 @@ where fn invh(&self) -> Result { let f = self.factorizeh()?; - f.into_inverseh() + f.invh_into() } }