@@ -18,6 +18,116 @@ 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
+ macro_rules! impl_householder_work {
37
+ ( $s: ty, $qrf: path, $lqf: path) => {
38
+ impl HouseholderWorkImpl for HouseholderWork <$s> {
39
+ type Elem = $s;
40
+
41
+ fn new( layout: MatrixLayout ) -> Result <Self > {
42
+ let m = layout. lda( ) ;
43
+ let n = layout. len( ) ;
44
+ let k = m. min( n) ;
45
+ let mut tau = vec_uninit( k as usize ) ;
46
+ let mut info = 0 ;
47
+ let mut work_size = [ Self :: Elem :: zero( ) ] ;
48
+ match layout {
49
+ MatrixLayout :: F { .. } => unsafe {
50
+ $qrf(
51
+ & m,
52
+ & n,
53
+ std:: ptr:: null_mut( ) ,
54
+ & m,
55
+ AsPtr :: as_mut_ptr( & mut tau) ,
56
+ AsPtr :: as_mut_ptr( & mut work_size) ,
57
+ & ( -1 ) ,
58
+ & mut info,
59
+ )
60
+ } ,
61
+ MatrixLayout :: C { .. } => unsafe {
62
+ $lqf(
63
+ & m,
64
+ & n,
65
+ std:: ptr:: null_mut( ) ,
66
+ & m,
67
+ AsPtr :: as_mut_ptr( & mut tau) ,
68
+ AsPtr :: as_mut_ptr( & mut work_size) ,
69
+ & ( -1 ) ,
70
+ & mut info,
71
+ )
72
+ } ,
73
+ }
74
+ info. as_lapack_result( ) ?;
75
+ let lwork = work_size[ 0 ] . to_usize( ) . unwrap( ) ;
76
+ let work = vec_uninit( lwork) ;
77
+ Ok ( HouseholderWork {
78
+ n,
79
+ m,
80
+ layout,
81
+ tau,
82
+ work,
83
+ } )
84
+ }
85
+
86
+ fn calc( & mut self , a: & mut [ Self :: Elem ] ) -> Result <& [ Self :: Elem ] > {
87
+ let lwork = self . work. len( ) . to_i32( ) . unwrap( ) ;
88
+ let mut info = 0 ;
89
+ match self . layout {
90
+ MatrixLayout :: F { .. } => unsafe {
91
+ $qrf(
92
+ & self . m,
93
+ & self . n,
94
+ AsPtr :: as_mut_ptr( a) ,
95
+ & self . m,
96
+ AsPtr :: as_mut_ptr( & mut self . tau) ,
97
+ AsPtr :: as_mut_ptr( & mut self . work) ,
98
+ & lwork,
99
+ & mut info,
100
+ ) ;
101
+ } ,
102
+ MatrixLayout :: C { .. } => unsafe {
103
+ $lqf(
104
+ & self . m,
105
+ & self . n,
106
+ AsPtr :: as_mut_ptr( a) ,
107
+ & self . m,
108
+ AsPtr :: as_mut_ptr( & mut self . tau) ,
109
+ AsPtr :: as_mut_ptr( & mut self . work) ,
110
+ & lwork,
111
+ & mut info,
112
+ ) ;
113
+ } ,
114
+ }
115
+ info. as_lapack_result( ) ?;
116
+ Ok ( unsafe { self . tau. slice_assume_init_ref( ) } )
117
+ }
118
+
119
+ fn eval( mut self , a: & mut [ Self :: Elem ] ) -> Result <Vec <Self :: Elem >> {
120
+ let _eig = self . calc( a) ?;
121
+ Ok ( unsafe { self . tau. assume_init( ) } )
122
+ }
123
+ }
124
+ } ;
125
+ }
126
+ impl_householder_work ! ( c64, lapack_sys:: zgeqrf_, lapack_sys:: zgelqf_) ;
127
+ impl_householder_work ! ( c32, lapack_sys:: cgeqrf_, lapack_sys:: cgelqf_) ;
128
+ impl_householder_work ! ( f64 , lapack_sys:: dgeqrf_, lapack_sys:: dgelqf_) ;
129
+ impl_householder_work ! ( f32 , lapack_sys:: sgeqrf_, lapack_sys:: sgelqf_) ;
130
+
21
131
macro_rules! impl_qr {
22
132
( $scalar: ty, $qrf: path, $lqf: path, $gqr: path, $glq: path) => {
23
133
impl QR_ for $scalar {
0 commit comments