1+ //! Eigenvalue decomposition for general matrices
2+
3+ use lapacke;
4+ use num_traits:: Zero ;
5+
6+ use crate :: error:: * ;
7+ use crate :: layout:: MatrixLayout ;
8+ use crate :: types:: * ;
9+
10+ use super :: into_result;
11+
12+ /// Wraps `*geev` for real/complex
13+ pub trait Eig_ : Scalar {
14+ unsafe fn eig ( calc_v : bool , l : MatrixLayout , a : & mut [ Self ] ) -> Result < ( Vec < Self :: Complex > , Vec < Self > ) > ;
15+ }
16+
17+ macro_rules! impl_eig_complex {
18+ ( $scalar: ty, $ev: path) => {
19+ impl Eig_ for $scalar {
20+ unsafe fn eig( calc_v: bool , l: MatrixLayout , mut a: & mut [ Self ] ) -> Result <( Vec <Self :: Complex >, Vec <Self :: Complex >) > {
21+ let ( n, _) = l. size( ) ;
22+ let jobvl = if calc_v { b'V' } else { b'N' } ;
23+ let mut w = vec![ Self :: Complex :: zero( ) ; n as usize ] ;
24+ let mut vl = vec![ Self :: Complex :: zero( ) ; ( n * n) as usize ] ;
25+ let mut vr = Vec :: new( ) ;
26+ let info = $ev( l. lapacke_layout( ) , jobvl, b'N' , n, & mut a, n, & mut w, & mut vl, n, & mut vr, n) ;
27+ into_result( info, ( w, vl) )
28+ }
29+ }
30+ } ;
31+ }
32+
33+ macro_rules! impl_eig_real {
34+ ( $scalar: ty, $ev: path, $cn: ty) => {
35+ impl Eig_ for $scalar {
36+ unsafe fn eig( calc_v: bool , l: MatrixLayout , mut a: & mut [ Self ] ) -> Result <( Vec <Self :: Complex >, Vec <Self :: Real >) > {
37+ let ( n, _) = l. size( ) ;
38+ let jobvl = if calc_v { b'V' } else { b'N' } ;
39+ let mut wr = vec![ Self :: Real :: zero( ) ; n as usize ] ;
40+ let mut wi = vec![ Self :: Real :: zero( ) ; n as usize ] ;
41+ let mut vl = vec![ Self :: Real :: zero( ) ; ( n * n) as usize ] ;
42+ let mut vr = Vec :: new( ) ;
43+ let info = $ev( l. lapacke_layout( ) , jobvl, b'N' , n, & mut a, n, & mut wr, & mut wi, & mut vl, n, & mut vr, n) ;
44+ let w: Vec <$cn> = wr. iter( ) . zip( wi. iter( ) ) . map( |( & r, & i) | <$cn>:: new( r, i) ) . collect( ) ;
45+ into_result( info, ( w, vl) )
46+ }
47+ }
48+ } ;
49+ }
50+
51+ impl_eig_real ! ( f64 , lapacke:: dgeev, c64) ;
52+ impl_eig_real ! ( f32 , lapacke:: sgeev, c32) ;
53+ impl_eig_complex ! ( c64, lapacke:: zgeev) ;
54+ impl_eig_complex ! ( c32, lapacke:: cgeev) ;
0 commit comments