1
1
//! Arnoldi iteration
2
2
3
3
use super :: * ;
4
- use crate :: norm:: Norm ;
4
+ use crate :: { norm:: Norm , operator :: LinearOperator } ;
5
5
use num_traits:: One ;
6
6
use std:: iter:: * ;
7
7
@@ -13,7 +13,7 @@ pub struct Arnoldi<A, S, F, Ortho>
13
13
where
14
14
A : Scalar ,
15
15
S : DataMut < Elem = A > ,
16
- F : Fn ( & mut ArrayBase < S , Ix1 > ) ,
16
+ F : LinearOperator < Elem = A > ,
17
17
Ortho : Orthogonalizer < Elem = A > ,
18
18
{
19
19
a : F ,
@@ -29,7 +29,7 @@ impl<A, S, F, Ortho> Arnoldi<A, S, F, Ortho>
29
29
where
30
30
A : Scalar + Lapack ,
31
31
S : DataMut < Elem = A > ,
32
- F : Fn ( & mut ArrayBase < S , Ix1 > ) ,
32
+ F : LinearOperator < Elem = A > ,
33
33
Ortho : Orthogonalizer < Elem = A > ,
34
34
{
35
35
/// 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>
73
73
where
74
74
A : Scalar + Lapack ,
75
75
S : DataMut < Elem = A > ,
76
- F : Fn ( & mut ArrayBase < S , Ix1 > ) ,
76
+ F : LinearOperator < Elem = A > ,
77
77
Ortho : Orthogonalizer < Elem = A > ,
78
78
{
79
79
type Item = Array1 < A > ;
80
80
81
81
fn next ( & mut self ) -> Option < Self :: Item > {
82
- ( self . a ) ( & mut self . v ) ;
82
+ self . a . apply_mut ( & mut self . v ) ;
83
83
let result = self . ortho . div_append ( & mut self . v ) ;
84
84
let norm = self . v . norm_l2 ( ) ;
85
85
azip ! ( mut v( & mut self . v) in { * v = v. div_real( norm) } ) ;
@@ -96,40 +96,22 @@ where
96
96
}
97
97
}
98
98
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
-
115
99
/// 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 > )
117
101
where
118
102
A : Scalar + Lapack ,
119
- S1 : Data < Elem = A > ,
120
- S2 : DataMut < Elem = A > ,
103
+ S : DataMut < Elem = A > ,
121
104
{
122
105
let householder = Householder :: new ( v. len ( ) , tol) ;
123
- Arnoldi :: new ( mul_mat ( a ) , v, householder) . complete ( )
106
+ Arnoldi :: new ( a , v, householder) . complete ( )
124
107
}
125
108
126
109
/// 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 > )
128
111
where
129
112
A : Scalar + Lapack ,
130
- S1 : Data < Elem = A > ,
131
- S2 : DataMut < Elem = A > ,
113
+ S : DataMut < Elem = A > ,
132
114
{
133
115
let mgs = MGS :: new ( v. len ( ) , tol) ;
134
- Arnoldi :: new ( mul_mat ( a ) , v, mgs) . complete ( )
116
+ Arnoldi :: new ( a , v, mgs) . complete ( )
135
117
}
0 commit comments