Sorting eigensystem obtained from zgeev
Question
I'm using the Lapack routine zgeev to obtain the (complex) eigenvalues and eigenvectors of a non-symmetric complex matrix in Fortran. The resulting array of eigenvectors is in some arbitrary order. I would like to reorder both the array of eigenvalues and the corresponding columns in the matrix of eigenvectors so that the eigenvalues are in ascending order with respect to the real part of each eigenvalue. I could of course roll my own sorting routine, but I was wondering if there was already a Fortran routine somewhere that can do this for me, maybe even as part of lapack.
Solution
You could just look at the end of zsteqr.f (the hermitian tridigaonal solver) and generalise that. The relevant bit of code is
* Use Selection Sort to minimize swaps of eigenvectors
*
DO 180 II = 2, N
I = II - 1
K = I
P = D( I )
DO 170 J = II, N
IF( D( J ).LT.P ) THEN
K = J
P = D( J )
END IF
170 CONTINUE
IF( K.NE.I ) THEN
D( K ) = D( I )
D( I ) = P
CALL ZSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
END IF
180 CONTINUE
So I think you just have to change the comparison line (but untested)
Ian
OTHER TIPS
I wrote one a few days ago, but the sorting was done according to the real values. This is an implementation of Quicksort. Make sure you input the function you want to be used as the key for sorting.
RECURSIVE SUBROUTINE ZQSORT(N,ARRAY)
IMPLICIT NONE
INTEGER(4), INTENT(IN) :: N
COMPLEX(8), INTENT(INOUT) :: ARRAY(N)
complex(8) :: PIVOT
COMPLEX(8) :: TEMP
INTEGER(4) :: LEFT,RIGHT
IF (N.GT.1) THEN
PIVOT=ARRAY(N/2) !INTEGER DIVISION
LEFT=1
RIGHT=N
DO WHILE (LEFT.LE.RIGHT)
DO WHILE (REAL(ARRAY(LEFT)).LT.REAL(PIVOT)) !REAL(Z) IS THE KEY USED FOR SORTING HERE
LEFT=LEFT+1
END DO
DO WHILE (REAL(ARRAY(RIGHT)).GT.REAL(PIVOT))! AGAIN KEY APPEARS HERE
RIGHT=RIGHT-1
END DO
IF (LEFT.LE.RIGHT) THEN
TEMP=ARRAY(LEFT) !
ARRAY(LEFT) = ARRAY(RIGHT) !SWAPPING THE ELEMENTS WITH INDICES LEFT<-->RIGHT
ARRAY(RIGHT)= TEMP !
LEFT = LEFT+1
RIGHT= RIGHT-1
END IF
CALL ZQSORT(RIGHT,ARRAY(1:RIGHT))
CALL ZQSORT(N-LEFT+1,ARRAY(LEFT:N))
END DO
END IF
RETURN
END SUBROUTINE ZQSORT