11//! Arnoldi iteration
22
33use super :: * ;
4- use crate :: norm:: Norm ;
4+ use crate :: { norm:: Norm , operator :: LinearOperator } ;
55use num_traits:: One ;
66use std:: iter:: * ;
77
@@ -13,7 +13,7 @@ pub struct Arnoldi<A, S, F, Ortho>
1313where
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>
2929where
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>
7373where
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 > )
117101where
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 > )
128111where
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