Skip to content

Commit

Permalink
Merge pull request #343 from rust-ndarray/lax-qr-strict
Browse files Browse the repository at this point in the history
Merge `QR_` to `Lapack` trait, add strict memory management API
  • Loading branch information
termoshtt authored Sep 26, 2022
2 parents 0b133cf + f0b2c86 commit b74552e
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 152 deletions.
36 changes: 33 additions & 3 deletions lax/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ pub mod layout;
pub mod eig;
pub mod eigh;
pub mod eigh_generalized;
pub mod qr;

mod alloc;
mod cholesky;
mod least_squares;
mod opnorm;
mod qr;
mod rcond;
mod solve;
mod solveh;
Expand All @@ -108,7 +108,6 @@ pub use self::cholesky::*;
pub use self::flags::*;
pub use self::least_squares::*;
pub use self::opnorm::*;
pub use self::qr::*;
pub use self::rcond::*;
pub use self::solve::*;
pub use self::solveh::*;
Expand All @@ -126,7 +125,6 @@ pub type Pivot = Vec<i32>;
/// Trait for primitive types which implements LAPACK subroutines
pub trait Lapack:
OperatorNorm_
+ QR_
+ SVD_
+ SVDDC_
+ Solve_
Expand Down Expand Up @@ -160,6 +158,18 @@ pub trait Lapack:
a: &mut [Self],
b: &mut [Self],
) -> Result<Vec<Self::Real>>;

/// Execute Householder reflection as the first step of QR-decomposition
///
/// For C-continuous array,
/// this will call LQ-decomposition of the transposed matrix $ A^T = LQ^T $
fn householder(l: MatrixLayout, a: &mut [Self]) -> Result<Vec<Self>>;

/// Reconstruct Q-matrix from Householder-reflectors
fn q(l: MatrixLayout, a: &mut [Self], tau: &[Self]) -> Result<()>;

/// Execute QR-decomposition at once
fn qr(l: MatrixLayout, a: &mut [Self]) -> Result<Vec<Self>>;
}

macro_rules! impl_lapack {
Expand Down Expand Up @@ -198,6 +208,26 @@ macro_rules! impl_lapack {
let work = EighGeneralizedWork::<$s>::new(calc_eigenvec, layout)?;
work.eval(uplo, a, b)
}

fn householder(l: MatrixLayout, a: &mut [Self]) -> Result<Vec<Self>> {
use qr::*;
let work = HouseholderWork::<$s>::new(l)?;
work.eval(a)
}

fn q(l: MatrixLayout, a: &mut [Self], tau: &[Self]) -> Result<()> {
use qr::*;
let mut work = QWork::<$s>::new(l)?;
work.calc(a, tau)?;
Ok(())
}

fn qr(l: MatrixLayout, a: &mut [Self]) -> Result<Vec<Self>> {
let tau = Self::householder(l, a)?;
let r = Vec::from(&*a);
Self::q(l, a, &tau)?;
Ok(r)
}
}
};
}
Expand Down
Loading

0 comments on commit b74552e

Please # to comment.