Skip to content

Commit 2a1ddc7

Browse files
committed
HouseholderWork for c64
1 parent 0b133cf commit 2a1ddc7

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

lax/src/qr.rs

+102
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,108 @@ pub trait QR_: Sized {
1818
fn qr(l: MatrixLayout, a: &mut [Self]) -> Result<Vec<Self>>;
1919
}
2020

21+
pub struct HouseholderWork<T: Scalar> {
22+
pub m: i32,
23+
pub n: i32,
24+
pub layout: MatrixLayout,
25+
pub tau: Vec<MaybeUninit<T>>,
26+
pub work: Vec<MaybeUninit<T>>,
27+
}
28+
29+
pub trait HouseholderWorkImpl: Sized {
30+
type Elem: Scalar;
31+
fn new(l: MatrixLayout) -> Result<Self>;
32+
fn calc(&mut self, a: &mut [Self::Elem]) -> Result<&[Self::Elem]>;
33+
fn eval(self, a: &mut [Self::Elem]) -> Result<Vec<Self::Elem>>;
34+
}
35+
36+
impl HouseholderWorkImpl for HouseholderWork<c64> {
37+
type Elem = c64;
38+
39+
fn new(layout: MatrixLayout) -> Result<Self> {
40+
let m = layout.lda();
41+
let n = layout.len();
42+
let k = m.min(n);
43+
let mut tau = vec_uninit(k as usize);
44+
let mut info = 0;
45+
let mut work_size = [Self::Elem::zero()];
46+
match layout {
47+
MatrixLayout::F { .. } => unsafe {
48+
lapack_sys::zgeqrf_(
49+
&m,
50+
&n,
51+
std::ptr::null_mut(),
52+
&m,
53+
AsPtr::as_mut_ptr(&mut tau),
54+
AsPtr::as_mut_ptr(&mut work_size),
55+
&(-1),
56+
&mut info,
57+
)
58+
},
59+
MatrixLayout::C { .. } => unsafe {
60+
lapack_sys::zgelqf_(
61+
&m,
62+
&n,
63+
std::ptr::null_mut(),
64+
&m,
65+
AsPtr::as_mut_ptr(&mut tau),
66+
AsPtr::as_mut_ptr(&mut work_size),
67+
&(-1),
68+
&mut info,
69+
)
70+
},
71+
}
72+
info.as_lapack_result()?;
73+
let lwork = work_size[0].to_usize().unwrap();
74+
let work = vec_uninit(lwork);
75+
Ok(HouseholderWork {
76+
n,
77+
m,
78+
layout,
79+
tau,
80+
work,
81+
})
82+
}
83+
84+
fn calc(&mut self, a: &mut [Self::Elem]) -> Result<&[Self::Elem]> {
85+
let lwork = self.work.len().to_i32().unwrap();
86+
let mut info = 0;
87+
match self.layout {
88+
MatrixLayout::F { .. } => unsafe {
89+
lapack_sys::zgeqrf_(
90+
&self.m,
91+
&self.n,
92+
AsPtr::as_mut_ptr(a),
93+
&self.m,
94+
AsPtr::as_mut_ptr(&mut self.tau),
95+
AsPtr::as_mut_ptr(&mut self.work),
96+
&lwork,
97+
&mut info,
98+
);
99+
},
100+
MatrixLayout::C { .. } => unsafe {
101+
lapack_sys::zgelqf_(
102+
&self.m,
103+
&self.n,
104+
AsPtr::as_mut_ptr(a),
105+
&self.m,
106+
AsPtr::as_mut_ptr(&mut self.tau),
107+
AsPtr::as_mut_ptr(&mut self.work),
108+
&lwork,
109+
&mut info,
110+
);
111+
},
112+
}
113+
info.as_lapack_result()?;
114+
Ok(unsafe { self.tau.slice_assume_init_ref() })
115+
}
116+
117+
fn eval(mut self, a: &mut [Self::Elem]) -> Result<Vec<Self::Elem>> {
118+
let _eig = self.calc(a)?;
119+
Ok(unsafe { self.tau.assume_init() })
120+
}
121+
}
122+
21123
macro_rules! impl_qr {
22124
($scalar:ty, $qrf:path, $lqf:path, $gqr:path, $glq:path) => {
23125
impl QR_ for $scalar {

0 commit comments

Comments
 (0)