@@ -18,6 +18,108 @@ pub trait QR_: Sized {
18
18
fn qr ( l : MatrixLayout , a : & mut [ Self ] ) -> Result < Vec < Self > > ;
19
19
}
20
20
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
+
21
123
macro_rules! impl_qr {
22
124
( $scalar: ty, $qrf: path, $lqf: path, $gqr: path, $glq: path) => {
23
125
impl QR_ for $scalar {
0 commit comments