Skip to content

Commit ae57857

Browse files
committed
QWork and QWorkImpl
1 parent cc369fb commit ae57857

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

lax/src/qr.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,107 @@ impl_householder_work!(c32, lapack_sys::cgeqrf_, lapack_sys::cgelqf_);
128128
impl_householder_work!(f64, lapack_sys::dgeqrf_, lapack_sys::dgelqf_);
129129
impl_householder_work!(f32, lapack_sys::sgeqrf_, lapack_sys::sgelqf_);
130130

131+
pub struct QWork<T: Scalar> {
132+
pub layout: MatrixLayout,
133+
pub work: Vec<MaybeUninit<T>>,
134+
}
135+
136+
pub trait QWorkImpl: Sized {
137+
type Elem: Scalar;
138+
fn new(layout: MatrixLayout) -> Result<Self>;
139+
fn calc(&mut self, a: &mut [Self::Elem], tau: &mut [Self::Elem]) -> Result<()>;
140+
}
141+
142+
macro_rules! impl_q_work {
143+
($s:ty, $gqr:path, $glq:path) => {
144+
impl QWorkImpl for QWork<$s> {
145+
type Elem = $s;
146+
147+
fn new(layout: MatrixLayout) -> Result<Self> {
148+
let m = layout.lda();
149+
let n = layout.len();
150+
let k = m.min(n);
151+
let mut info = 0;
152+
let mut work_size = [Self::Elem::zero()];
153+
match layout {
154+
MatrixLayout::F { .. } => unsafe {
155+
$gqr(
156+
&m,
157+
&k,
158+
&k,
159+
std::ptr::null_mut(),
160+
&m,
161+
std::ptr::null_mut(),
162+
AsPtr::as_mut_ptr(&mut work_size),
163+
&(-1),
164+
&mut info,
165+
)
166+
},
167+
MatrixLayout::C { .. } => unsafe {
168+
$glq(
169+
&k,
170+
&n,
171+
&k,
172+
std::ptr::null_mut(),
173+
&m,
174+
std::ptr::null_mut(),
175+
AsPtr::as_mut_ptr(&mut work_size),
176+
&(-1),
177+
&mut info,
178+
)
179+
},
180+
}
181+
let lwork = work_size[0].to_usize().unwrap();
182+
let work = vec_uninit(lwork);
183+
Ok(QWork { layout, work })
184+
}
185+
186+
fn calc(&mut self, a: &mut [Self::Elem], tau: &mut [Self::Elem]) -> Result<()> {
187+
let m = self.layout.lda();
188+
let n = self.layout.len();
189+
let k = m.min(n);
190+
let lwork = self.work.len().to_i32().unwrap();
191+
let mut info = 0;
192+
match self.layout {
193+
MatrixLayout::F { .. } => unsafe {
194+
$gqr(
195+
&m,
196+
&k,
197+
&k,
198+
AsPtr::as_mut_ptr(a),
199+
&m,
200+
AsPtr::as_ptr(&tau),
201+
AsPtr::as_mut_ptr(&mut self.work),
202+
&lwork,
203+
&mut info,
204+
)
205+
},
206+
MatrixLayout::C { .. } => unsafe {
207+
$glq(
208+
&k,
209+
&n,
210+
&k,
211+
AsPtr::as_mut_ptr(a),
212+
&m,
213+
AsPtr::as_ptr(&tau),
214+
AsPtr::as_mut_ptr(&mut self.work),
215+
&lwork,
216+
&mut info,
217+
)
218+
},
219+
}
220+
info.as_lapack_result()?;
221+
Ok(())
222+
}
223+
}
224+
};
225+
}
226+
227+
impl_q_work!(c64, lapack_sys::zungqr_, lapack_sys::zunglq_);
228+
impl_q_work!(c32, lapack_sys::cungqr_, lapack_sys::cunglq_);
229+
impl_q_work!(f64, lapack_sys::dorgqr_, lapack_sys::dorglq_);
230+
impl_q_work!(f32, lapack_sys::sorgqr_, lapack_sys::sorglq_);
231+
131232
macro_rules! impl_qr {
132233
($scalar:ty, $qrf:path, $lqf:path, $gqr:path, $glq:path) => {
133234
impl QR_ for $scalar {

0 commit comments

Comments
 (0)