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.

Was it helpful?

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top