@@ -17,13 +17,29 @@ pub trait Eig_: Scalar {
1717macro_rules! impl_eig_complex {
1818 ( $scalar: ty, $ev: path) => {
1919 impl Eig_ for $scalar {
20- unsafe fn eig( calc_v: bool , l: MatrixLayout , mut a: & mut [ Self ] ) -> Result <( Vec <Self :: Complex >, Vec <Self :: Complex >) > {
20+ unsafe fn eig(
21+ calc_v: bool ,
22+ l: MatrixLayout ,
23+ mut a: & mut [ Self ] ,
24+ ) -> Result <( Vec <Self :: Complex >, Vec <Self :: Complex >) > {
2125 let ( n, _) = l. size( ) ;
2226 let jobvr = if calc_v { b'V' } else { b'N' } ;
2327 let mut w = vec![ Self :: Complex :: zero( ) ; n as usize ] ;
2428 let mut vl = Vec :: new( ) ;
2529 let mut vr = vec![ Self :: Complex :: zero( ) ; ( n * n) as usize ] ;
26- let info = $ev( l. lapacke_layout( ) , b'N' , jobvr, n, & mut a, n, & mut w, & mut vl, n, & mut vr, n) ;
30+ let info = $ev(
31+ l. lapacke_layout( ) ,
32+ b'N' ,
33+ jobvr,
34+ n,
35+ & mut a,
36+ n,
37+ & mut w,
38+ & mut vl,
39+ n,
40+ & mut vr,
41+ n,
42+ ) ;
2743 into_result( info, ( w, vr) )
2844 }
2945 }
@@ -33,49 +49,75 @@ macro_rules! impl_eig_complex {
3349macro_rules! impl_eig_real {
3450 ( $scalar: ty, $ev: path) => {
3551 impl Eig_ for $scalar {
36- unsafe fn eig( calc_v: bool , l: MatrixLayout , mut a: & mut [ Self ] ) -> Result <( Vec <Self :: Complex >, Vec <Self :: Complex >) > {
52+ unsafe fn eig(
53+ calc_v: bool ,
54+ l: MatrixLayout ,
55+ mut a: & mut [ Self ] ,
56+ ) -> Result <( Vec <Self :: Complex >, Vec <Self :: Complex >) > {
3757 let ( n, _) = l. size( ) ;
3858 let jobvr = if calc_v { b'V' } else { b'N' } ;
3959 let mut wr = vec![ Self :: Real :: zero( ) ; n as usize ] ;
4060 let mut wi = vec![ Self :: Real :: zero( ) ; n as usize ] ;
4161 let mut vl = Vec :: new( ) ;
4262 let mut vr = vec![ Self :: Real :: zero( ) ; ( n * n) as usize ] ;
43- let info = $ev( l. lapacke_layout( ) , b'N' , jobvr, n, & mut a, n, & mut wr, & mut wi, & mut vl, n, & mut vr, n) ;
44- let w: Vec <Self :: Complex > = wr. iter( ) . zip( wi. iter( ) ) . map( |( & r, & i) | Self :: Complex :: new( r, i) ) . collect( ) ;
63+ let info = $ev(
64+ l. lapacke_layout( ) ,
65+ b'N' ,
66+ jobvr,
67+ n,
68+ & mut a,
69+ n,
70+ & mut wr,
71+ & mut wi,
72+ & mut vl,
73+ n,
74+ & mut vr,
75+ n,
76+ ) ;
77+ let w: Vec <Self :: Complex > = wr
78+ . iter( )
79+ . zip( wi. iter( ) )
80+ . map( |( & r, & i) | Self :: Complex :: new( r, i) )
81+ . collect( ) ;
4582 // If the j-th eigenvalue is real, then
4683 // eigenvector = [ vr[j], vr[j+n], vr[j+2*n], ... ].
4784 //
48- // If the j-th and (j+1)-st eigenvalues form a complex conjugate pair,
85+ // If the j-th and (j+1)-st eigenvalues form a complex conjugate pair,
4986 // eigenvector(j) = [ vr[j] + i*vr[j+1], vr[j+n] + i*vr[j+n+1], vr[j+2*n] + i*vr[j+2*n+1], ... ] and
5087 // eigenvector(j+1) = [ vr[j] - i*vr[j+1], vr[j+n] - i*vr[j+n+1], vr[j+2*n] - i*vr[j+2*n+1], ... ].
51- //
88+ //
5289 // Therefore, if eigenvector(j) is written as [ v_{j0}, v_{j1}, v_{j2}, ... ],
53- // you have to make
90+ // you have to make
5491 // v = vec![ v_{00}, v_{10}, v_{20}, ..., v_{jk}, v_{(j+1)k}, v_{(j+2)k}, ... ] (v.len() = n*n)
5592 // based on wi and vr.
5693 // After that, v is converted to Array2 (see ../eig.rs).
5794 let n = n as usize ;
5895 let mut flg = false ;
59- let conj: Vec <i8 > = wi. iter( ) . map( |& i| {
60- if flg {
61- flg = false ;
62- -1
63- } else if i != 0.0 {
64- flg = true ;
65- 1
66- } else {
67- 0
68- }
69- } ) . collect( ) ;
70- let v: Vec <Self :: Complex > = ( 0 ..n* n) . map( |i| {
71- let j = i % n;
72- match conj[ j] {
73- 1 => Self :: Complex :: new( vr[ i] , vr[ i+1 ] ) ,
74- -1 => Self :: Complex :: new( vr[ i-1 ] , -vr[ i] ) ,
75- _ => Self :: Complex :: new( vr[ i] , 0.0 ) ,
76- }
77- } ) . collect( ) ;
78-
96+ let conj: Vec <i8 > = wi
97+ . iter( )
98+ . map( |& i| {
99+ if flg {
100+ flg = false ;
101+ -1
102+ } else if i != 0.0 {
103+ flg = true ;
104+ 1
105+ } else {
106+ 0
107+ }
108+ } )
109+ . collect( ) ;
110+ let v: Vec <Self :: Complex > = ( 0 ..n * n)
111+ . map( |i| {
112+ let j = i % n;
113+ match conj[ j] {
114+ 1 => Self :: Complex :: new( vr[ i] , vr[ i + 1 ] ) ,
115+ -1 => Self :: Complex :: new( vr[ i - 1 ] , -vr[ i] ) ,
116+ _ => Self :: Complex :: new( vr[ i] , 0.0 ) ,
117+ }
118+ } )
119+ . collect( ) ;
120+
79121 into_result( info, ( w, v) )
80122 }
81123 }
@@ -85,4 +127,4 @@ macro_rules! impl_eig_real {
85127impl_eig_real ! ( f64 , lapacke:: dgeev) ;
86128impl_eig_real ! ( f32 , lapacke:: sgeev) ;
87129impl_eig_complex ! ( c64, lapacke:: zgeev) ;
88- impl_eig_complex ! ( c32, lapacke:: cgeev) ;
130+ impl_eig_complex ! ( c32, lapacke:: cgeev) ;
0 commit comments