@@ -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+
21123macro_rules! impl_qr {
22124 ( $scalar: ty, $qrf: path, $lqf: path, $gqr: path, $glq: path) => {
23125 impl QR_ for $scalar {
0 commit comments