@@ -4,7 +4,7 @@ use num_traits::Zero;
44
55/// Iterative orthogonalizer using Householder reflection
66#[ derive( Debug , Clone ) ]
7- pub struct Householder < A > {
7+ pub struct Householder < A : Scalar > {
88 dim : usize ,
99 v : Vec < Array1 < A > > ,
1010}
@@ -18,21 +18,19 @@ impl<A: Scalar> Householder<A> {
1818 fn reflect < S : DataMut < Elem = A > > ( & self , k : usize , a : & mut ArrayBase < S , Ix1 > ) {
1919 assert ! ( k < self . v. len( ) ) ;
2020 assert_eq ! ( a. len( ) , self . dim) ;
21+
2122 let w = self . v [ k] . slice ( s ! [ k..] ) ;
22- let c = A :: from ( 2.0 ) . unwrap ( ) * w. inner ( & a. slice ( s ! [ k..] ) ) ;
23- for l in k..self . dim {
24- a[ l] -= c * w[ l - k] ;
23+ let mut a_slice = a. slice_mut ( s ! [ k..] ) ;
24+ let c = A :: from ( 2.0 ) . unwrap ( ) * w. inner ( & a_slice) ;
25+ for l in 0 ..self . dim - k {
26+ a_slice[ l] -= c * w[ l] ;
2527 }
2628 }
2729}
2830
2931impl < A : Scalar + Lapack > Orthogonalizer for Householder < A > {
3032 type Elem = A ;
3133
32- fn new ( dim : usize ) -> Self {
33- Self { dim, v : Vec :: new ( ) }
34- }
35-
3634 fn dim ( & self ) -> usize {
3735 self . dim
3836 }
@@ -48,8 +46,7 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
4846 for k in 0 ..self . len ( ) {
4947 self . reflect ( k, a) ;
5048 }
51- if a. len ( ) >= self . len ( ) {
52- // full rank
49+ if self . is_full ( ) {
5350 return Zero :: zero ( ) ;
5451 }
5552 // residual norm
@@ -60,12 +57,30 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
6057 where
6158 S : DataMut < Elem = A > ,
6259 {
63- let residual = self . orthogonalize ( & mut a) ;
64- let coef = a. slice ( s ! [ ..self . len( ) ] ) . into_owned ( ) ;
65- if residual < rtol {
60+ assert_eq ! ( a. len( ) , self . dim) ;
61+ let alpha = self . orthogonalize ( & mut a) ;
62+
63+ // Generate coefficient vector
64+ let mut coef = Array :: zeros ( self . len ( ) + 1 ) ;
65+ for i in 0 ..self . len ( ) {
66+ coef[ i] = a[ i] ;
67+ }
68+ coef[ self . len ( ) ] = A :: from_real ( alpha) ;
69+
70+ if alpha < rtol {
6671 return Err ( coef) ;
6772 }
73+
74+ // Add reflector
75+ let k = self . len ( ) ;
76+ let xi = a[ k] . re ( ) ;
77+ a[ k] = A :: from ( if xi > Zero :: zero ( ) { xi + alpha } else { xi - alpha } ) . unwrap ( ) ;
78+ let norm = a. slice ( s ! [ k..] ) . norm_l2 ( ) ;
79+ dbg ! ( alpha) ;
80+ dbg ! ( norm) ;
81+ azip ! ( mut a ( a. slice_mut( s![ k..] ) ) in { * a = a. div_real( norm) } ) ;
6882 self . v . push ( a. into_owned ( ) ) ;
83+ dbg ! ( & self . v) ;
6984 Ok ( coef)
7085 }
7186
@@ -98,6 +113,7 @@ mod tests {
98113 assert ! ( householder. append( array![ 1.0 , 2.0 , 0.0 ] , 1e-9 ) . is_err( ) ) ;
99114
100115 if let Err ( coef) = householder. append ( array ! [ 1.0 , 2.0 , 0.0 ] , 1e-9 ) {
116+ dbg ! ( & coef) ;
101117 close_l2 ( & coef, & array ! [ 2.0 , 1.0 , 0.0 ] , 1e-9 ) . unwrap ( ) ;
102118 }
103119 }
0 commit comments