@@ -14,14 +14,14 @@ pub struct Householder<A: Scalar> {
1414 v : Vec < Array1 < A > > ,
1515}
1616
17- impl < A : Scalar > Householder < A > {
17+ impl < A : Scalar + Lapack > Householder < A > {
1818 /// Create a new orthogonalizer
1919 pub fn new ( dim : usize ) -> Self {
2020 Householder { dim, v : Vec :: new ( ) }
2121 }
2222
2323 /// 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 > ) {
2525 assert ! ( k < self . v. len( ) ) ;
2626 assert_eq ! ( a. len( ) , self . dim, "Input array size mismaches to the dimension" ) ;
2727
@@ -32,6 +32,42 @@ impl<A: Scalar> Householder<A> {
3232 a_slice[ l] -= c * w[ l] ;
3333 }
3434 }
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+ }
3571}
3672
3773impl < A : Scalar + Lapack > Orthogonalizer for Householder < A > {
@@ -45,18 +81,18 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
4581 self . v . len ( )
4682 }
4783
48- fn orthogonalize < S > ( & self , a : & mut ArrayBase < S , Ix1 > ) -> A :: Real
84+ fn coeff < S > ( & self , a : ArrayBase < S , Ix1 > ) -> Array1 < A >
4985 where
50- S : DataMut < Elem = A > ,
86+ S : Data < Elem = A > ,
5187 {
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
6096 }
6197
6298 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> {
65101 {
66102 assert_eq ! ( a. len( ) , self . dim) ;
67103 let k = self . len ( ) ;
68- let alpha = self . orthogonalize ( & mut a) ;
104+ self . forward_reflection ( & mut a) ;
105+ let alpha = self . eval_residual ( & a) ;
69106 let mut coef = Array :: zeros ( k + 1 ) ;
70107 for i in 0 ..k {
71108 coef[ i] = a[ i] ;
@@ -98,9 +135,7 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
98135 let mut a = Array :: zeros ( ( self . dim ( ) , self . len ( ) ) ) ;
99136 for ( i, mut col) in a. axis_iter_mut ( Axis ( 1 ) ) . enumerate ( ) {
100137 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) ;
104139 }
105140 a
106141 }
0 commit comments