Skip to content

Commit 5be4fa7

Browse files
committed
Introduce decompose method for Orthogonalizer
1 parent bfecc99 commit 5be4fa7

3 files changed

Lines changed: 69 additions & 49 deletions

File tree

src/krylov/householder.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,27 @@ impl<A: Scalar + Lapack> Householder<A> {
9292
}
9393
}
9494

95-
fn eval_residual<S>(&self, a: &ArrayBase<S, Ix1>) -> A::Real
95+
/// Compose coefficients array using reflected vector
96+
fn compose_coefficients<S>(&self, a: &ArrayBase<S, Ix1>) -> Coefficients<A>
9697
where
9798
S: Data<Elem = A>,
9899
{
99-
let l = self.v.len();
100-
a.slice(s![l..]).norm_l2()
100+
let k = self.len();
101+
let res = a.slice(s![k..]).norm_l2();
102+
let mut c = Array1::zeros(k + 1);
103+
azip!(mut c(c.slice_mut(s![..k])), a(a.slice(s![..k])) in { *c = a });
104+
c[k] = A::from_real(res);
105+
c
106+
}
107+
108+
/// Construct the residual vector from reflected vector
109+
fn construct_residual<S>(&self, a: &mut ArrayBase<S, Ix1>)
110+
where
111+
S: DataMut<Elem = A>,
112+
{
113+
let k = self.len();
114+
azip!(mut a( a.slice_mut(s![..k])) in { *a = A::zero() });
115+
self.backward_reflection(a);
101116
}
102117
}
103118

@@ -112,18 +127,23 @@ impl<A: Scalar + Lapack> Orthogonalizer for Householder<A> {
112127
self.v.len()
113128
}
114129

130+
fn decompose<S>(&self, a: &mut ArrayBase<S, Ix1>) -> Array1<A>
131+
where
132+
S: DataMut<Elem = A>,
133+
{
134+
self.forward_reflection(a);
135+
let coef = self.compose_coefficients(a);
136+
self.construct_residual(a);
137+
coef
138+
}
139+
115140
fn coeff<S>(&self, a: ArrayBase<S, Ix1>) -> Array1<A>
116141
where
117142
S: Data<Elem = A>,
118143
{
119144
let mut a = a.into_owned();
120145
self.forward_reflection(&mut a);
121-
let res = self.eval_residual(&a);
122-
let k = self.len();
123-
let mut c = Array1::zeros(k + 1);
124-
azip!(mut c(c.slice_mut(s![..k])), a(a.slice(s![..k])) in { *c = a });
125-
c[k] = A::from_real(res);
126-
c
146+
self.compose_coefficients(&a)
127147
}
128148

129149
fn append<S>(&mut self, mut a: ArrayBase<S, Ix1>, rtol: A::Real) -> Result<Array1<A>, Array1<A>>

src/krylov/mgs.rs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,20 @@ impl<A: Scalar + Lapack> MGS<A> {
2020
q: Vec::new(),
2121
}
2222
}
23+
}
24+
25+
impl<A: Scalar + Lapack> Orthogonalizer for MGS<A> {
26+
type Elem = A;
27+
28+
fn dim(&self) -> usize {
29+
self.dimension
30+
}
31+
32+
fn len(&self) -> usize {
33+
self.q.len()
34+
}
2335

24-
/// Orthogonalize given vector against to the current basis
25-
///
26-
/// - Returned array is coefficients and residual norm
27-
/// - `a` will contain the residual vector
28-
///
29-
pub fn orthogonalize<S>(&self, a: &mut ArrayBase<S, Ix1>) -> Array1<A>
36+
fn decompose<S>(&self, a: &mut ArrayBase<S, Ix1>) -> Array1<A>
3037
where
3138
S: DataMut<Elem = A>,
3239
{
@@ -42,26 +49,14 @@ impl<A: Scalar + Lapack> MGS<A> {
4249
coef[self.len()] = A::from_real(nrm);
4350
coef
4451
}
45-
}
46-
47-
impl<A: Scalar + Lapack> Orthogonalizer for MGS<A> {
48-
type Elem = A;
49-
50-
fn dim(&self) -> usize {
51-
self.dimension
52-
}
53-
54-
fn len(&self) -> usize {
55-
self.q.len()
56-
}
5752

5853
fn coeff<S>(&self, a: ArrayBase<S, Ix1>) -> Array1<A>
5954
where
6055
A: Lapack,
6156
S: Data<Elem = A>,
6257
{
6358
let mut a = a.into_owned();
64-
self.orthogonalize(&mut a)
59+
self.decompose(&mut a)
6560
}
6661

6762
fn append<S>(&mut self, a: ArrayBase<S, Ix1>, rtol: A::Real) -> Result<Array1<A>, Array1<A>>
@@ -70,7 +65,7 @@ impl<A: Scalar + Lapack> Orthogonalizer for MGS<A> {
7065
S: Data<Elem = A>,
7166
{
7267
let mut a = a.into_owned();
73-
let coef = self.orthogonalize(&mut a);
68+
let coef = self.decompose(&mut a);
7469
let nrm = coef[coef.len() - 1].re();
7570
if nrm < rtol {
7671
// Linearly dependent

src/krylov/mod.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,19 @@ pub type Q<A> = Array2<A>;
2323
///
2424
pub type R<A> = Array2<A>;
2525

26+
/// Array type for coefficients to the current basis
27+
///
28+
/// - The length must be `self.len() + 1`
29+
/// - Last component is the residual norm
30+
///
31+
pub type Coefficients<A> = Array1<A>;
32+
2633
/// Trait for creating orthogonal basis from iterator of arrays
2734
///
35+
/// Panic
36+
/// -------
37+
/// - if the size of the input array mismatches to the dimension
38+
///
2839
/// Example
2940
/// -------
3041
///
@@ -64,37 +75,31 @@ pub trait Orthogonalizer {
6475
self.len() == 0
6576
}
6677

67-
/// Calculate the coefficient to the given basis and residual norm
78+
/// Decompose given vector into the span of current basis and
79+
/// its tangent space
6880
///
69-
/// - The length of the returned array must be `self.len() + 1`
70-
/// - Last component is the residual norm
81+
/// - `a` becomes the tangent vector
82+
/// - The Coefficients to the current basis is returned.
7183
///
72-
/// Panic
73-
/// -------
74-
/// - if the size of the input array mismatches to the dimension
84+
fn decompose<S>(&self, a: &mut ArrayBase<S, Ix1>) -> Coefficients<Self::Elem>
85+
where
86+
S: DataMut<Elem = Self::Elem>;
87+
88+
/// Calculate the coefficient to the current basis basis
89+
///
90+
/// - This will be faster than `decompose` because the construction of the residual vector may
91+
/// requires more Calculation
7592
///
76-
fn coeff<S>(&self, a: ArrayBase<S, Ix1>) -> Array1<Self::Elem>
93+
fn coeff<S>(&self, a: ArrayBase<S, Ix1>) -> Coefficients<Self::Elem>
7794
where
7895
S: Data<Elem = Self::Elem>;
7996

8097
/// Add new vector if the residual is larger than relative tolerance
81-
///
82-
/// Returns
83-
/// --------
84-
/// Coefficients to the `i`-th Q-vector
85-
///
86-
/// - The size of array must be `self.len() + 1`
87-
/// - The last element is the residual norm of input vector
88-
///
89-
/// Panic
90-
/// -------
91-
/// - if the size of the input array mismatches to the dimension
92-
///
9398
fn append<S>(
9499
&mut self,
95100
a: ArrayBase<S, Ix1>,
96101
rtol: <Self::Elem as Scalar>::Real,
97-
) -> Result<Array1<Self::Elem>, Array1<Self::Elem>>
102+
) -> Result<Coefficients<Self::Elem>, Coefficients<Self::Elem>>
98103
where
99104
S: DataMut<Elem = Self::Elem>;
100105

0 commit comments

Comments
 (0)