@@ -128,6 +128,107 @@ impl_householder_work!(c32, lapack_sys::cgeqrf_, lapack_sys::cgelqf_);
128
128
impl_householder_work ! ( f64 , lapack_sys:: dgeqrf_, lapack_sys:: dgelqf_) ;
129
129
impl_householder_work ! ( f32 , lapack_sys:: sgeqrf_, lapack_sys:: sgelqf_) ;
130
130
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
+
131
232
macro_rules! impl_qr {
132
233
( $scalar: ty, $qrf: path, $lqf: path, $gqr: path, $glq: path) => {
133
234
impl QR_ for $scalar {
0 commit comments