@@ -42,26 +42,40 @@ macro_rules! impl_eig_real {
42
42
let mut vr = vec![ Self :: Real :: zero( ) ; ( n * n) as usize ] ;
43
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
44
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).
45
57
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
59
66
} else {
60
- for j in 0 ..n {
61
- v[ n* j+i] = Self :: Complex :: new( vr[ n* j+i] , 0.0 ) ;
62
- }
67
+ 0
63
68
}
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
+
65
79
into_result( info, ( w, v) )
66
80
}
67
81
}
0 commit comments