对从 zgeev 获得的特征系统进行排序

发布于 2024-12-26 13:08:44 字数 269 浏览 2 评论 0原文

我正在使用 Lapack 例程 zgeev 来获取(复)特征值和 Fortran 中非对称复矩阵的特征向量。得到的数组 特征向量的顺序是任意的。我想重新订购 特征值数组和特征向量矩阵中的相应列 使得特征值相对于实部按升序排列 每个特征值。我当然可以推出自己的排序程序,但我 想知道是否已经有一个 Fortran 例程可以做到这一点 我,甚至可能是 lapack 的一部分。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

洋洋洒洒 2025-01-02 13:08:44

您可以只查看 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

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

ら栖息 2025-01-02 13:08:44

前几天写了一篇,不过是按照真实值排序的。这是快速排序的一个实现。确保输入要用作排序键的函数。

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文