@@ -8,17 +8,17 @@ use crate::{inner::*, norm::*};
88use num_traits:: One ;
99
1010/// Calc a reflactor `w` from a vector `x`
11- pub fn calc_reflector < A , S > ( x : & mut ArrayBase < S , Ix1 > ) -> A
11+ pub fn calc_reflector < A , S > ( x : & mut ArrayBase < S , Ix1 > )
1212where
1313 A : Scalar + Lapack ,
1414 S : DataMut < Elem = A > ,
1515{
16+ assert ! ( x. len( ) > 0 ) ;
1617 let norm = x. norm_l2 ( ) ;
1718 let alpha = -x[ 0 ] . mul_real ( norm / x[ 0 ] . abs ( ) ) ;
1819 x[ 0 ] -= alpha;
1920 let inv_rev_norm = A :: Real :: one ( ) / x. norm_l2 ( ) ;
2021 azip ! ( mut a( x) in { * a = a. mul_real( inv_rev_norm) } ) ;
21- alpha
2222}
2323
2424/// Take a reflection `P = I - 2ww^T`
@@ -108,7 +108,12 @@ impl<A: Scalar + Lapack> Householder<A> {
108108 let res = a. slice ( s ! [ k..] ) . norm_l2 ( ) ;
109109 let mut c = Array1 :: zeros ( k + 1 ) ;
110110 azip ! ( mut c( c. slice_mut( s![ ..k] ) ) , a( a. slice( s![ ..k] ) ) in { * c = a } ) ;
111- c[ k] = A :: from_real ( res) ;
111+ if k < a. len ( ) {
112+ let ak = a[ k] ;
113+ c[ k] = -ak. mul_real ( res / ak. abs ( ) ) ;
114+ } else {
115+ c[ k] = A :: from_real ( res) ;
116+ }
112117 c
113118 }
114119
@@ -157,30 +162,37 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
157162 self . compose_coefficients ( & a)
158163 }
159164
160- fn append < S > ( & mut self , mut a : ArrayBase < S , Ix1 > ) -> AppendResult < A >
165+ fn div_append < S > ( & mut self , a : & mut ArrayBase < S , Ix1 > ) -> AppendResult < A >
161166 where
162167 S : DataMut < Elem = A > ,
163168 {
164169 assert_eq ! ( a. len( ) , self . dim) ;
165170 let k = self . len ( ) ;
166-
167- self . forward_reflection ( & mut a) ;
168- let mut coef = Array :: zeros ( k + 1 ) ;
169- for i in 0 ..k {
170- coef[ i] = a[ i] ;
171- }
172- if self . is_full ( ) {
173- return AppendResult :: Dependent ( coef) ; // coef[k] must be zero in this case
171+ self . forward_reflection ( a) ;
172+ let coef = self . compose_coefficients ( a) ;
173+ if coef[ k] . abs ( ) < self . tol {
174+ return AppendResult :: Dependent ( coef) ;
174175 }
176+ calc_reflector ( & mut a. slice_mut ( s ! [ k..] ) ) ;
177+ self . v . push ( a. to_owned ( ) ) ;
178+ self . construct_residual ( a) ;
179+ AppendResult :: Added ( coef)
180+ }
175181
176- let alpha = calc_reflector ( & mut a. slice_mut ( s ! [ k..] ) ) ;
177- coef[ k] = alpha;
178-
179- if alpha. abs ( ) < self . tol {
180- // linearly dependent
182+ fn append < S > ( & mut self , a : ArrayBase < S , Ix1 > ) -> AppendResult < A >
183+ where
184+ S : Data < Elem = A > ,
185+ {
186+ assert_eq ! ( a. len( ) , self . dim) ;
187+ let mut a = a. into_owned ( ) ;
188+ let k = self . len ( ) ;
189+ self . forward_reflection ( & mut a) ;
190+ let coef = self . compose_coefficients ( & a) ;
191+ if coef[ k] . abs ( ) < self . tol {
181192 return AppendResult :: Dependent ( coef) ;
182193 }
183- self . v . push ( a. into_owned ( ) ) ;
194+ calc_reflector ( & mut a. slice_mut ( s ! [ k..] ) ) ;
195+ self . v . push ( a. to_owned ( ) ) ;
184196 AppendResult :: Added ( coef)
185197 }
186198
0 commit comments