@@ -42,26 +42,40 @@ macro_rules! impl_eig_real {
4242 let mut vr = vec![ Self :: Real :: zero( ) ; ( n * n) as usize ] ;
4343 let info = $ev( l. lapacke_layout( ) , b'N' , jobvr, n, & mut a, n, & mut wr, & mut wi, & mut vl, n, & mut vr, n) ;
4444 let w: Vec <Self :: Complex > = wr. iter( ) . zip( wi. iter( ) ) . map( |( & r, & i) | Self :: Complex :: new( r, i) ) . collect( ) ;
45+ // If the j-th eigenvalue is real, then
46+ // eigenvector = [ vr[j], vr[j+n], vr[j+2*n], ... ].
47+ //
48+ // If the j-th and (j+1)-st eigenvalues form a complex conjugate pair,
49+ // 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
50+ // 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+ //
52+ // Therefore, if eigenvector(j) is written as [ v_{j0}, v_{j1}, v_{j2}, ... ],
53+ // you have to make
54+ // v = vec![ v_{00}, v_{10}, v_{20}, ..., v_{jk}, v_{(j+1)k}, v_{(j+2)k}, ... ] (v.len() = n*n)
55+ // based on wi and vr.
56+ // After that, v is converted to Array2 (see ../eig.rs).
4557 let n = n as usize ;
46- let mut conj = false ;
47- let mut v = vec![ Self :: Complex :: zero( ) ; n * n] ;
48- for ( i, c) in w. iter( ) . enumerate( ) {
49- if conj {
50- for j in 0 ..n {
51- v[ n* j+i] = Self :: Complex :: new( vr[ n* j+i-1 ] , -vr[ n* j+i] ) ;
52- }
53- conj = false ;
54- } else if c. im != 0.0 {
55- conj = true ;
56- for j in 0 ..n {
57- v[ n* j+i] = Self :: Complex :: new( vr[ n* j+i] , vr[ n* j+i+1 ] ) ;
58- }
58+ 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
5966 } else {
60- for j in 0 ..n {
61- v[ n* j+i] = Self :: Complex :: new( vr[ n* j+i] , 0.0 ) ;
62- }
67+ 0
6368 }
64- }
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+
6579 into_result( info, ( w, v) )
6680 }
6781 }
0 commit comments