@@ -4,6 +4,25 @@ use super::*;
4
4
use crate :: { generate:: * , inner:: * , norm:: Norm } ;
5
5
6
6
/// Iterative orthogonalizer using modified Gram-Schmit procedure
7
+ ///
8
+ /// ```rust
9
+ /// # use ndarray::*;
10
+ /// # use ndarray_linalg::{mgs::*, krylov::*, *};
11
+ /// let mut mgs = MGS::new(3);
12
+ /// let coef = mgs.append(array![0.0, 1.0, 0.0], 1e-9).unwrap();
13
+ /// close_l2(&coef, &array![1.0], 1e-9);
14
+ ///
15
+ /// let coef = mgs.append(array![1.0, 1.0, 0.0], 1e-9).unwrap();
16
+ /// close_l2(&coef, &array![1.0, 1.0], 1e-9);
17
+ ///
18
+ /// // Fail if the vector is linearly dependent
19
+ /// assert!(mgs.append(array![1.0, 2.0, 0.0], 1e-9).is_err());
20
+ ///
21
+ /// // You can get coefficients of dependent vector
22
+ /// if let Err(coef) = mgs.append(array![1.0, 2.0, 0.0], 1e-9) {
23
+ /// close_l2(&coef, &array![2.0, 1.0, 0.0], 1e-9);
24
+ /// }
25
+ /// ```
7
26
#[ derive( Debug , Clone ) ]
8
27
pub struct MGS < A > {
9
28
/// Dimension of base space
@@ -20,36 +39,20 @@ impl<A: Scalar> MGS<A> {
20
39
q : Vec :: new ( ) ,
21
40
}
22
41
}
42
+ }
43
+
44
+ impl < A : Scalar + Lapack > Orthogonalizer for MGS < A > {
45
+ type Elem = A ;
23
46
24
- /// Dimension of input array
25
- pub fn dim ( & self ) -> usize {
47
+ fn dim ( & self ) -> usize {
26
48
self . dimension
27
49
}
28
50
29
- /// Number of cached basis
30
- ///
31
- /// ```rust
32
- /// # use ndarray::*;
33
- /// # use ndarray_linalg::{mgs::*, *};
34
- /// const N: usize = 3;
35
- /// let mut mgs = MGS::<f32>::new(N);
36
- /// assert_eq!(mgs.dim(), N);
37
- /// assert_eq!(mgs.len(), 0);
38
- ///
39
- /// mgs.append(array![0.0, 1.0, 0.0], 1e-9).unwrap();
40
- /// assert_eq!(mgs.len(), 1);
41
- /// ```
42
- pub fn len ( & self ) -> usize {
51
+ fn len ( & self ) -> usize {
43
52
self . q . len ( )
44
53
}
45
54
46
- /// Orthogonalize given vector using current basis
47
- ///
48
- /// Panic
49
- /// -------
50
- /// - if the size of the input array mismatches to the dimension
51
- ///
52
- pub fn orthogonalize < S > ( & self , a : & mut ArrayBase < S , Ix1 > ) -> Array1 < A >
55
+ fn orthogonalize < S > ( & self , a : & mut ArrayBase < S , Ix1 > ) -> Array1 < A >
53
56
where
54
57
A : Lapack ,
55
58
S : DataMut < Elem = A > ,
@@ -67,32 +70,7 @@ impl<A: Scalar> MGS<A> {
67
70
coef
68
71
}
69
72
70
- /// Add new vector if the residual is larger than relative tolerance
71
- ///
72
- /// ```rust
73
- /// # use ndarray::*;
74
- /// # use ndarray_linalg::{mgs::*, *};
75
- /// let mut mgs = MGS::new(3);
76
- /// let coef = mgs.append(array![0.0, 1.0, 0.0], 1e-9).unwrap();
77
- /// close_l2(&coef, &array![1.0], 1e-9);
78
- ///
79
- /// let coef = mgs.append(array![1.0, 1.0, 0.0], 1e-9).unwrap();
80
- /// close_l2(&coef, &array![1.0, 1.0], 1e-9);
81
- ///
82
- /// // Fail if the vector is linearly dependent
83
- /// assert!(mgs.append(array![1.0, 2.0, 0.0], 1e-9).is_err());
84
- ///
85
- /// // You can get coefficients of dependent vector
86
- /// if let Err(coef) = mgs.append(array![1.0, 2.0, 0.0], 1e-9) {
87
- /// close_l2(&coef, &array![2.0, 1.0, 0.0], 1e-9);
88
- /// }
89
- /// ```
90
- ///
91
- /// Panic
92
- /// -------
93
- /// - if the size of the input array mismatches to the dimension
94
- ///
95
- pub fn append < S > ( & mut self , a : ArrayBase < S , Ix1 > , rtol : A :: Real ) -> Result < Array1 < A > , Array1 < A > >
73
+ fn append < S > ( & mut self , a : ArrayBase < S , Ix1 > , rtol : A :: Real ) -> Result < Array1 < A > , Array1 < A > >
96
74
where
97
75
A : Lapack ,
98
76
S : Data < Elem = A > ,
@@ -109,8 +87,7 @@ impl<A: Scalar> MGS<A> {
109
87
Ok ( coef)
110
88
}
111
89
112
- /// Get orthogonal basis as Q matrix
113
- pub fn get_q ( & self ) -> Q < A > {
90
+ fn get_q ( & self ) -> Q < A > {
114
91
hstack ( & self . q ) . unwrap ( )
115
92
}
116
93
}
@@ -126,27 +103,6 @@ where
126
103
A : Scalar + Lapack ,
127
104
S : Data < Elem = A > ,
128
105
{
129
- let mut ortho = MGS :: new ( dim) ;
130
- let mut coefs = Vec :: new ( ) ;
131
- for a in iter {
132
- match ortho. append ( a, rtol) {
133
- Ok ( coef) => coefs. push ( coef) ,
134
- Err ( coef) => match strategy {
135
- Strategy :: Terminate => break ,
136
- Strategy :: Skip => continue ,
137
- Strategy :: Full => coefs. push ( coef) ,
138
- } ,
139
- }
140
- }
141
- let n = ortho. len ( ) ;
142
- let m = coefs. len ( ) ;
143
- let mut r = Array2 :: zeros ( ( n, m) . f ( ) ) ;
144
- for j in 0 ..m {
145
- for i in 0 ..n {
146
- if i < coefs[ j] . len ( ) {
147
- r[ ( i, j) ] = coefs[ j] [ i] ;
148
- }
149
- }
150
- }
151
- ( ortho. get_q ( ) , r)
106
+ let mgs = MGS :: new ( dim) ;
107
+ qr ( iter, mgs, rtol, strategy)
152
108
}
0 commit comments