@@ -14,14 +14,14 @@ pub struct Householder<A: Scalar> {
14
14
v : Vec < Array1 < A > > ,
15
15
}
16
16
17
- impl < A : Scalar > Householder < A > {
17
+ impl < A : Scalar + Lapack > Householder < A > {
18
18
/// Create a new orthogonalizer
19
19
pub fn new ( dim : usize ) -> Self {
20
20
Householder { dim, v : Vec :: new ( ) }
21
21
}
22
22
23
23
/// Take a Reflection `P = I - 2ww^T`
24
- fn reflect < S : DataMut < Elem = A > > ( & self , k : usize , a : & mut ArrayBase < S , Ix1 > ) {
24
+ fn fundamental_reflection < S : DataMut < Elem = A > > ( & self , k : usize , a : & mut ArrayBase < S , Ix1 > ) {
25
25
assert ! ( k < self . v. len( ) ) ;
26
26
assert_eq ! ( a. len( ) , self . dim, "Input array size mismaches to the dimension" ) ;
27
27
@@ -32,6 +32,42 @@ impl<A: Scalar> Householder<A> {
32
32
a_slice[ l] -= c * w[ l] ;
33
33
}
34
34
}
35
+
36
+ /// Take forward reflection `P = P_l ... P_1`
37
+ pub fn forward_reflection < S > ( & self , a : & mut ArrayBase < S , Ix1 > )
38
+ where
39
+ S : DataMut < Elem = A > ,
40
+ {
41
+ assert ! ( a. len( ) == self . dim) ;
42
+ let l = self . v . len ( ) ;
43
+ for k in 0 ..l {
44
+ self . fundamental_reflection ( k, a) ;
45
+ }
46
+ }
47
+
48
+ /// Take backward reflection `P = P_1 ... P_l`
49
+ pub fn backward_reflection < S > ( & self , a : & mut ArrayBase < S , Ix1 > )
50
+ where
51
+ S : DataMut < Elem = A > ,
52
+ {
53
+ assert ! ( a. len( ) == self . dim) ;
54
+ let l = self . v . len ( ) ;
55
+ for k in ( 0 ..l) . rev ( ) {
56
+ self . fundamental_reflection ( k, a) ;
57
+ }
58
+ }
59
+
60
+ fn eval_residual < S > ( & self , a : & ArrayBase < S , Ix1 > ) -> A :: Real
61
+ where
62
+ S : Data < Elem = A > ,
63
+ {
64
+ let l = self . v . len ( ) ;
65
+ if l == self . dim {
66
+ Zero :: zero ( )
67
+ } else {
68
+ a. slice ( s ! [ l..] ) . norm_l2 ( )
69
+ }
70
+ }
35
71
}
36
72
37
73
impl < A : Scalar + Lapack > Orthogonalizer for Householder < A > {
@@ -45,18 +81,18 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
45
81
self . v . len ( )
46
82
}
47
83
48
- fn orthogonalize < S > ( & self , a : & mut ArrayBase < S , Ix1 > ) -> A :: Real
84
+ fn coeff < S > ( & self , a : ArrayBase < S , Ix1 > ) -> Array1 < A >
49
85
where
50
- S : DataMut < Elem = A > ,
86
+ S : Data < Elem = A > ,
51
87
{
52
- for k in 0 .. self . len ( ) {
53
- self . reflect ( k , a) ;
54
- }
55
- if self . is_full ( ) {
56
- return Zero :: zero ( ) ;
57
- }
58
- // residual norm
59
- a . slice ( s ! [ self . len ( ) .. ] ) . norm_l2 ( )
88
+ let mut a = a . into_owned ( ) ;
89
+ self . forward_reflection ( & mut a) ;
90
+ let res = self . eval_residual ( & a ) ;
91
+ let k = self . len ( ) ;
92
+ let mut c = Array1 :: zeros ( k + 1 ) ;
93
+ azip ! ( mut c ( c . slice_mut ( s! [ ..k ] ) ) , a ( a . slice ( s! [ ..k ] ) ) in { * c = a } ) ;
94
+ c [ k ] = A :: from_real ( res ) ;
95
+ c
60
96
}
61
97
62
98
fn append < S > ( & mut self , mut a : ArrayBase < S , Ix1 > , rtol : A :: Real ) -> Result < Array1 < A > , Array1 < A > >
@@ -65,7 +101,8 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
65
101
{
66
102
assert_eq ! ( a. len( ) , self . dim) ;
67
103
let k = self . len ( ) ;
68
- let alpha = self . orthogonalize ( & mut a) ;
104
+ self . forward_reflection ( & mut a) ;
105
+ let alpha = self . eval_residual ( & a) ;
69
106
let mut coef = Array :: zeros ( k + 1 ) ;
70
107
for i in 0 ..k {
71
108
coef[ i] = a[ i] ;
@@ -98,9 +135,7 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
98
135
let mut a = Array :: zeros ( ( self . dim ( ) , self . len ( ) ) ) ;
99
136
for ( i, mut col) in a. axis_iter_mut ( Axis ( 1 ) ) . enumerate ( ) {
100
137
col[ i] = A :: one ( ) ;
101
- for l in ( 0 ..self . len ( ) ) . rev ( ) {
102
- self . reflect ( l, & mut col) ;
103
- }
138
+ self . backward_reflection ( & mut col) ;
104
139
}
105
140
a
106
141
}
0 commit comments