Skip to content

Commit 59133a4

Browse files
committed
Use LinearOperator on Arnoldi
1 parent eefd18e commit 59133a4

File tree

1 file changed

+11
-29
lines changed

1 file changed

+11
-29
lines changed

src/krylov/arnoldi.rs

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Arnoldi iteration
22
33
use super::*;
4-
use crate::norm::Norm;
4+
use crate::{norm::Norm, operator::LinearOperator};
55
use num_traits::One;
66
use std::iter::*;
77

@@ -13,7 +13,7 @@ pub struct Arnoldi<A, S, F, Ortho>
1313
where
1414
A: Scalar,
1515
S: DataMut<Elem = A>,
16-
F: Fn(&mut ArrayBase<S, Ix1>),
16+
F: LinearOperator<Elem = A>,
1717
Ortho: Orthogonalizer<Elem = A>,
1818
{
1919
a: F,
@@ -29,7 +29,7 @@ impl<A, S, F, Ortho> Arnoldi<A, S, F, Ortho>
2929
where
3030
A: Scalar + Lapack,
3131
S: DataMut<Elem = A>,
32-
F: Fn(&mut ArrayBase<S, Ix1>),
32+
F: LinearOperator<Elem = A>,
3333
Ortho: Orthogonalizer<Elem = A>,
3434
{
3535
/// Create an Arnoldi iterator from any linear operator `a`
@@ -73,13 +73,13 @@ impl<A, S, F, Ortho> Iterator for Arnoldi<A, S, F, Ortho>
7373
where
7474
A: Scalar + Lapack,
7575
S: DataMut<Elem = A>,
76-
F: Fn(&mut ArrayBase<S, Ix1>),
76+
F: LinearOperator<Elem = A>,
7777
Ortho: Orthogonalizer<Elem = A>,
7878
{
7979
type Item = Array1<A>;
8080

8181
fn next(&mut self) -> Option<Self::Item> {
82-
(self.a)(&mut self.v);
82+
self.a.apply_mut(&mut self.v);
8383
let result = self.ortho.div_append(&mut self.v);
8484
let norm = self.v.norm_l2();
8585
azip!(mut v(&mut self.v) in { *v = v.div_real(norm) });
@@ -96,40 +96,22 @@ where
9696
}
9797
}
9898

99-
/// Interpret a matrix as a linear operator
100-
pub fn mul_mat<A, S1, S2>(a: ArrayBase<S1, Ix2>) -> impl Fn(&mut ArrayBase<S2, Ix1>)
101-
where
102-
A: Scalar,
103-
S1: Data<Elem = A>,
104-
S2: DataMut<Elem = A>,
105-
{
106-
let (n, m) = a.dim();
107-
assert_eq!(n, m, "Input matrix must be square");
108-
move |x| {
109-
assert_eq!(m, x.len(), "Input matrix and vector sizes mismatch");
110-
let ax = a.dot(x);
111-
azip!(mut x(x), ax in { *x = ax });
112-
}
113-
}
114-
11599
/// Utility to execute Arnoldi iteration with Householder reflection
116-
pub fn arnoldi_householder<A, S1, S2>(a: ArrayBase<S1, Ix2>, v: ArrayBase<S2, Ix1>, tol: A::Real) -> (Q<A>, H<A>)
100+
pub fn arnoldi_householder<A, S>(a: impl LinearOperator<Elem = A>, v: ArrayBase<S, Ix1>, tol: A::Real) -> (Q<A>, H<A>)
117101
where
118102
A: Scalar + Lapack,
119-
S1: Data<Elem = A>,
120-
S2: DataMut<Elem = A>,
103+
S: DataMut<Elem = A>,
121104
{
122105
let householder = Householder::new(v.len(), tol);
123-
Arnoldi::new(mul_mat(a), v, householder).complete()
106+
Arnoldi::new(a, v, householder).complete()
124107
}
125108

126109
/// Utility to execute Arnoldi iteration with modified Gram-Schmit orthogonalizer
127-
pub fn arnoldi_mgs<A, S1, S2>(a: ArrayBase<S1, Ix2>, v: ArrayBase<S2, Ix1>, tol: A::Real) -> (Q<A>, H<A>)
110+
pub fn arnoldi_mgs<A, S>(a: impl LinearOperator<Elem = A>, v: ArrayBase<S, Ix1>, tol: A::Real) -> (Q<A>, H<A>)
128111
where
129112
A: Scalar + Lapack,
130-
S1: Data<Elem = A>,
131-
S2: DataMut<Elem = A>,
113+
S: DataMut<Elem = A>,
132114
{
133115
let mgs = MGS::new(v.len(), tol);
134-
Arnoldi::new(mul_mat(a), v, mgs).complete()
116+
Arnoldi::new(a, v, mgs).complete()
135117
}

0 commit comments

Comments
 (0)