Skip to content

Commit dfa19d7

Browse files
committed
Add QR_
1 parent 3e18871 commit dfa19d7

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

src/impl2/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
pub mod opnorm;
3+
pub mod qr;
34
pub use self::opnorm::*;
5+
pub use self::qr::*;
46

57
pub trait LapackScalar: OperatorNorm_ {}
68
impl<A> LapackScalar for A where A: OperatorNorm_ {}

src/impl2/opnorm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use lapack::c;
44
use lapack::c::Layout::ColumnMajor as cm;
55

66
use types::*;
7-
use layout::*;
7+
use layout::Layout;
88

99
#[repr(u8)]
1010
pub enum NormType {

src/impl2/qr.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//! Implement QR decomposition
2+
3+
use std::cmp::min;
4+
use num_traits::Zero;
5+
use lapack::c;
6+
7+
use types::*;
8+
use error::*;
9+
use layout::Layout;
10+
11+
pub trait QR_: Sized {
12+
fn householder(Layout, a: &mut [Self]) -> Result<Vec<Self>>;
13+
fn q(Layout, a: &mut [Self], tau: &[Self]) -> Result<()>;
14+
fn qr(Layout, a: &mut [Self]) -> Result<Vec<Self>>;
15+
}
16+
17+
macro_rules! impl_qr {
18+
($scalar:ty, $qrf:path, $gqr:path) => {
19+
impl QR_ for $scalar {
20+
fn householder(l: Layout, mut a: &mut [Self]) -> Result<Vec<Self>> {
21+
let (row, col) = l.size();
22+
let k = min(row, col);
23+
let mut tau = vec![Self::zero(); k as usize];
24+
let info = $qrf(l.lapacke_layout(), row, col, &mut a, l.lda(), &mut tau);
25+
if info == 0 {
26+
Ok(tau)
27+
} else {
28+
Err(LapackError::new(info).into())
29+
}
30+
}
31+
32+
fn q(l: Layout, mut a: &mut [Self], tau: &[Self]) -> Result<()> {
33+
let (row, col) = l.size();
34+
let k = min(row, col);
35+
let info = $gqr(l.lapacke_layout(), row, k, k, &mut a, l.lda(), &tau);
36+
if info == 0 {
37+
Ok(())
38+
} else {
39+
Err(LapackError::new(info).into())
40+
}
41+
}
42+
43+
fn qr(l: Layout, mut a: &mut [Self]) -> Result<Vec<Self>> {
44+
let tau = Self::householder(l, a)?;
45+
let r = Vec::from(&*a);
46+
Self::q(l, a, &tau)?;
47+
Ok(r)
48+
}
49+
}
50+
}} // endmacro
51+
52+
impl_qr!(f64, c::dgeqrf, c::dorgqr);
53+
impl_qr!(f32, c::sgeqrf, c::sorgqr);
54+
impl_qr!(c64, c::zgeqrf, c::zungqr);
55+
impl_qr!(c32, c::cgeqrf, c::cungqr);

src/layout.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11

22
use ndarray::*;
3+
use lapack::c;
34

45
use super::error::*;
56

67
pub type LDA = i32;
78
pub type Col = i32;
89
pub type Row = i32;
910

11+
#[derive(Debug, Clone, Copy)]
1012
pub enum Layout {
1113
C((Row, LDA)),
1214
F((Col, LDA)),
@@ -19,6 +21,28 @@ impl Layout {
1921
Layout::F((col, lda)) => (lda, col),
2022
}
2123
}
24+
25+
pub fn row(&self) -> Row {
26+
self.size().0
27+
}
28+
29+
pub fn col(&self) -> Col {
30+
self.size().1
31+
}
32+
33+
pub fn lda(&self) -> LDA {
34+
match *self {
35+
Layout::C((_, lda)) => lda,
36+
Layout::F((_, lda)) => lda,
37+
}
38+
}
39+
40+
pub fn lapacke_layout(&self) -> c::Layout {
41+
match *self {
42+
Layout::C(_) => c::Layout::RowMajor,
43+
Layout::F(_) => c::Layout::ColumnMajor,
44+
}
45+
}
2246
}
2347

2448
pub trait AllocatedArray {

0 commit comments

Comments
 (0)