1- use crate :: { generate :: * , inner :: * , norm :: Norm , types:: * } ;
1+ use crate :: types:: * ;
22use ndarray:: * ;
33
4- /// Iterative orthogonalizer using modified Gram-Schmit procedure
5- #[ derive( Debug , Clone ) ]
6- pub struct MGS < A > {
7- /// Dimension of base space
8- dimension : usize ,
9- /// Basis of spanned space
10- q : Vec < Array1 < A > > ,
11- }
4+ mod householder;
5+ mod mgs;
6+
7+ pub use householder:: Householder ;
8+ pub use mgs:: MGS ;
129
1310/// Q-matrix (unitary)
1411pub type Q < A > = Array2 < A > ;
1512/// R-matrix (upper triangle)
1613pub type R < A > = Array2 < A > ;
1714
18- impl < A : Scalar > MGS < A > {
19- /// Create empty linear space
20- ///
21- /// ```rust
22- /// # use ndarray_linalg::*;
23- /// const N: usize = 5;
24- /// let mgs = arnoldi::MGS::<f32>::new(N);
25- /// assert_eq!(mgs.dim(), N);
26- /// assert_eq!(mgs.len(), 0);
27- /// ```
28- pub fn new ( dimension : usize ) -> Self {
29- Self {
30- dimension,
31- q : Vec :: new ( ) ,
32- }
33- }
15+ pub trait Orthogonalizer {
16+ type Elem : Scalar ;
3417
35- pub fn dim ( & self ) -> usize {
36- self . dimension
37- }
18+ /// Create empty linear space
19+ fn new ( dim : usize ) -> Self ;
3820
39- pub fn len ( & self ) -> usize {
40- self . q . len ( )
41- }
21+ fn dim ( & self ) -> usize ;
22+ fn len ( & self ) -> usize ;
4223
43- /// Orthogonalize given vector using current basis
24+ /// Orthogonalize given vector
4425 ///
4526 /// Panic
4627 /// -------
4728 /// - if the size of the input array mismaches to the dimension
48- pub fn orthogonalize < S > ( & self , a : & mut ArrayBase < S , Ix1 > ) -> Array1 < A >
29+ ///
30+ fn orthogonalize < S > ( & self , a : & mut ArrayBase < S , Ix1 > ) -> <Self :: Elem as Scalar >:: Real
4931 where
50- A : Lapack ,
51- S : DataMut < Elem = A > ,
52- {
53- assert_eq ! ( a. len( ) , self . dim( ) ) ;
54- let mut coef = Array1 :: zeros ( self . len ( ) + 1 ) ;
55- for i in 0 ..self . len ( ) {
56- let q = & self . q [ i] ;
57- let c = q. inner ( & a) ;
58- azip ! ( mut a ( & mut * a) , q ( q) in { * a = * a - c * q } ) ;
59- coef[ i] = c;
60- }
61- let nrm = a. norm_l2 ( ) ;
62- coef[ self . len ( ) ] = A :: from_real ( nrm) ;
63- coef
64- }
32+ S : DataMut < Elem = Self :: Elem > ;
6533
6634 /// Add new vector if the residual is larger than relative tolerance
6735 ///
6836 /// ```rust
6937 /// # use ndarray::*;
70- /// # use ndarray_linalg::* ;
71- /// let mut mgs = arnoldi ::MGS::new(3);
38+ /// # use ndarray_linalg::{*, krylov::*} ;
39+ /// let mut mgs = krylov ::MGS::new(3);
7240 /// let coef = mgs.append(array![0.0, 1.0, 0.0], 1e-9).unwrap();
7341 /// close_l2(&coef, &array![1.0], 1e-9).unwrap();
7442 ///
@@ -86,27 +54,16 @@ impl<A: Scalar> MGS<A> {
8654 /// -------
8755 /// - if the size of the input array mismaches to the dimension
8856 ///
89- pub fn append < S > ( & mut self , a : ArrayBase < S , Ix1 > , rtol : A :: Real ) -> Result < Array1 < A > , Array1 < A > >
57+ fn append < S > (
58+ & mut self ,
59+ a : ArrayBase < S , Ix1 > ,
60+ rtol : <Self :: Elem as Scalar >:: Real ,
61+ ) -> Result < Array1 < Self :: Elem > , Array1 < Self :: Elem > >
9062 where
91- A : Lapack ,
92- S : Data < Elem = A > ,
93- {
94- let mut a = a. into_owned ( ) ;
95- let coef = self . orthogonalize ( & mut a) ;
96- let nrm = coef[ coef. len ( ) - 1 ] . re ( ) ;
97- if nrm < rtol {
98- // Linearly dependent
99- return Err ( coef) ;
100- }
101- azip ! ( mut a in { * a = * a / A :: from_real( nrm) } ) ;
102- self . q . push ( a) ;
103- Ok ( coef)
104- }
63+ S : DataMut < Elem = Self :: Elem > ;
10564
106- /// Get orthogonal basis as Q matrix
107- pub fn get_q ( & self ) -> Q < A > {
108- hstack ( & self . q ) . unwrap ( )
109- }
65+ /// Get Q-matrix of generated basis
66+ fn get_q ( & self ) -> Q < Self :: Elem > ;
11067}
11168
11269/// Strategy for linearly dependent vectors appearing in iterative QR decomposition
@@ -132,7 +89,7 @@ pub enum Strategy {
13289}
13390
13491/// Online QR decomposition of vectors using modified Gram-Schmit algorithm
135- pub fn mgs < A , S > (
92+ pub fn qr < A , S > (
13693 iter : impl Iterator < Item = ArrayBase < S , Ix1 > > ,
13794 dim : usize ,
13895 rtol : A :: Real ,
@@ -145,7 +102,7 @@ where
145102 let mut ortho = MGS :: new ( dim) ;
146103 let mut coefs = Vec :: new ( ) ;
147104 for a in iter {
148- match ortho. append ( a, rtol) {
105+ match ortho. append ( a. into_owned ( ) , rtol) {
149106 Ok ( coef) => coefs. push ( coef) ,
150107 Err ( coef) => match strategy {
151108 Strategy :: Terminate => break ,
0 commit comments