Сортировка собственной системы, полученной из згеев - PullRequest
0 голосов
/ 12 января 2012

Я использую процедуру Лапака zgeev , чтобы получить (сложные) собственные значения и собственные векторы несимметричной комплексной матрицы в фортране. Полученный массив собственных векторов находится в некотором произвольном порядке. Я хотел бы изменить порядок как массив собственных значений и соответствующие столбцы в матрице собственных векторов так что собственные значения находятся в порядке возрастания относительно реальной части каждое собственное значение. Я мог бы, конечно, свернуть свою собственную процедуру сортировки, но я был интересно, была ли уже где-нибудь рутина Фортрана, которая может я, может быть, даже как часть Lapack.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2013

Я написал один несколько дней назад, но сортировка была сделана в соответствии с реальными значениями. Это реализация Quicksort. Убедитесь, что вы вводите функцию, которую хотите использовать в качестве ключа для сортировки.

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
0 голосов
/ 13 января 2012

Вы можете просто взглянуть на конец zsteqr.f (эрмитовский тридигаональный решатель) и обобщить это. Соответствующий бит кода

*        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

Так что я думаю, вам просто нужно изменить строку сравнения (но не проверено)

Ian

...