⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ztgevc.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 2 页
字号:
      SUBROUTINE ZTGEVC( SIDE, HOWMNY, SELECT, N, A, LDA, B, LDB, VL,     $                   LDVL, VR, LDVR, MM, M, WORK, RWORK, INFO )**  -- LAPACK routine (instrumented to count operations, version 3.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     June 30, 1999**     .. Scalar Arguments ..      CHARACTER          HOWMNY, SIDE      INTEGER            INFO, LDA, LDB, LDVL, LDVR, M, MM, N*     ..*     .. Array Arguments ..      LOGICAL            SELECT( * )      DOUBLE PRECISION   RWORK( * )      COMPLEX*16         A( LDA, * ), B( LDB, * ), VL( LDVL, * ),     $                   VR( LDVR, * ), WORK( * )*     ..**     ----------------------- Begin Timing Code ------------------------*     Common block to return operation count and iteration count*     ITCNT is initialized to 0, OPS is only incremented*     OPST is used to accumulate small contributions to OPS*     to avoid roundoff error*     .. Common blocks ..      COMMON             / LATIME / OPS, ITCNT*     ..*     .. Scalars in Common ..      DOUBLE PRECISION   ITCNT, OPS*     ..*     ------------------------ End Timing Code -------------------------***  Purpose*  =======**  ZTGEVC computes some or all of the right and/or left generalized*  eigenvectors of a pair of complex upper triangular matrices (A,B).**  The right generalized eigenvector x and the left generalized*  eigenvector y of (A,B) corresponding to a generalized eigenvalue*  w are defined by:**          (A - wB) * x = 0  and  y**H * (A - wB) = 0**  where y**H denotes the conjugate tranpose of y.**  If an eigenvalue w is determined by zero diagonal elements of both A*  and B, a unit vector is returned as the corresponding eigenvector.**  If all eigenvectors are requested, the routine may either return*  the matrices X and/or Y of right or left eigenvectors of (A,B), or*  the products Z*X and/or Q*Y, where Z and Q are input unitary*  matrices.  If (A,B) was obtained from the generalized Schur*  factorization of an original pair of matrices*     (A0,B0) = (Q*A*Z**H,Q*B*Z**H),*  then Z*X and Q*Y are the matrices of right or left eigenvectors of*  A.**  Arguments*  =========**  SIDE    (input) CHARACTER*1*          = 'R': compute right eigenvectors only;*          = 'L': compute left eigenvectors only;*          = 'B': compute both right and left eigenvectors.**  HOWMNY  (input) CHARACTER*1*          = 'A': compute all right and/or left eigenvectors;*          = 'B': compute all right and/or left eigenvectors, and*                 backtransform them using the input matrices supplied*                 in VR and/or VL;*          = 'S': compute selected right and/or left eigenvectors,*                 specified by the logical array SELECT.**  SELECT  (input) LOGICAL array, dimension (N)*          If HOWMNY='S', SELECT specifies the eigenvectors to be*          computed.*          If HOWMNY='A' or 'B', SELECT is not referenced.*          To select the eigenvector corresponding to the j-th*          eigenvalue, SELECT(j) must be set to .TRUE..**  N       (input) INTEGER*          The order of the matrices A and B.  N >= 0.**  A       (input) COMPLEX*16 array, dimension (LDA,N)*          The upper triangular matrix A.**  LDA     (input) INTEGER*          The leading dimension of array A.  LDA >= max(1,N).**  B       (input) COMPLEX*16 array, dimension (LDB,N)*          The upper triangular matrix B.  B must have real diagonal*          elements.**  LDB     (input) INTEGER*          The leading dimension of array B.  LDB >= max(1,N).**  VL      (input/output) COMPLEX*16 array, dimension (LDVL,MM)*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must*          contain an N-by-N matrix Q (usually the unitary matrix Q*          of left Schur vectors returned by ZHGEQZ).*          On exit, if SIDE = 'L' or 'B', VL contains:*          if HOWMNY = 'A', the matrix Y of left eigenvectors of (A,B);*          if HOWMNY = 'B', the matrix Q*Y;*          if HOWMNY = 'S', the left eigenvectors of (A,B) specified by*                      SELECT, stored consecutively in the columns of*                      VL, in the same order as their eigenvalues.*          If SIDE = 'R', VL is not referenced.**  LDVL    (input) INTEGER*          The leading dimension of array VL.*          LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise.**  VR      (input/output) COMPLEX*16 array, dimension (LDVR,MM)*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must*          contain an N-by-N matrix Q (usually the unitary matrix Z*          of right Schur vectors returned by ZHGEQZ).*          On exit, if SIDE = 'R' or 'B', VR contains:*          if HOWMNY = 'A', the matrix X of right eigenvectors of (A,B);*          if HOWMNY = 'B', the matrix Z*X;*          if HOWMNY = 'S', the right eigenvectors of (A,B) specified by*                      SELECT, stored consecutively in the columns of*                      VR, in the same order as their eigenvalues.*          If SIDE = 'L', VR is not referenced.**  LDVR    (input) INTEGER*          The leading dimension of the array VR.*          LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.**  MM      (input) INTEGER*          The leading dimension of the array VR.*          LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.**  M       (output) INTEGER*          The number of columns in the arrays VL and/or VR actually*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M*          is set to N.  Each selected eigenvector occupies one column.**  WORK    (workspace) COMPLEX*16 array, dimension (2*N)**  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)**  INFO    (output) INTEGER*          = 0:  successful exit.*          < 0:  if INFO = -i, the i-th argument had an illegal value.**  =====================================================================**     .. Parameters ..      DOUBLE PRECISION   ZERO, ONE      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )      COMPLEX*16         CZERO, CONE      PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),     $                   CONE = ( 1.0D+0, 0.0D+0 ) )*     ..*     .. Local Scalars ..      LOGICAL            COMPL, COMPR, ILALL, ILBACK, ILBBAD, ILCOMP,     $                   LSA, LSB      INTEGER            I, IBEG, IEIG, IEND, IHWMNY, IM, IOPST, ISIDE,     $                   ISRC, J, JE, JR      DOUBLE PRECISION   ACOEFA, ACOEFF, ANORM, ASCALE, BCOEFA, BIG,     $                   BIGNUM, BNORM, BSCALE, DMIN, SAFMIN, SBETA,     $                   SCALE, SMALL, TEMP, ULP, XMAX      COMPLEX*16         BCOEFF, CA, CB, D, SALPHA, SUM, SUMA, SUMB, X*     ..*     .. External Functions ..      LOGICAL            LSAME      DOUBLE PRECISION   DLAMCH      COMPLEX*16         ZLADIV      EXTERNAL           LSAME, DLAMCH, ZLADIV*     ..*     .. External Subroutines ..      EXTERNAL           DLABAD, XERBLA, ZGEMV*     ..*     .. Intrinsic Functions ..      INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN*     ..*     .. Statement Functions ..      DOUBLE PRECISION   ABS1*     ..*     .. Statement Function definitions ..      ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )*     ..*     .. Executable Statements ..**     Decode and Test the input parameters*      IF( LSAME( HOWMNY, 'A' ) ) THEN         IHWMNY = 1         ILALL = .TRUE.         ILBACK = .FALSE.      ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN         IHWMNY = 2         ILALL = .FALSE.         ILBACK = .FALSE.      ELSE IF( LSAME( HOWMNY, 'B' ) .OR. LSAME( HOWMNY, 'T' ) ) THEN         IHWMNY = 3         ILALL = .TRUE.         ILBACK = .TRUE.      ELSE         IHWMNY = -1      END IF*      IF( LSAME( SIDE, 'R' ) ) THEN         ISIDE = 1         COMPL = .FALSE.         COMPR = .TRUE.      ELSE IF( LSAME( SIDE, 'L' ) ) THEN         ISIDE = 2         COMPL = .TRUE.         COMPR = .FALSE.      ELSE IF( LSAME( SIDE, 'B' ) ) THEN         ISIDE = 3         COMPL = .TRUE.         COMPR = .TRUE.      ELSE         ISIDE = -1      END IF*      INFO = 0      IF( ISIDE.LT.0 ) THEN         INFO = -1      ELSE IF( IHWMNY.LT.0 ) THEN         INFO = -2      ELSE IF( N.LT.0 ) THEN         INFO = -4      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN         INFO = -6      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN         INFO = -8      END IF      IF( INFO.NE.0 ) THEN         CALL XERBLA( 'ZTGEVC', -INFO )         RETURN      END IF**     Count the number of eigenvectors*      IF( .NOT.ILALL ) THEN         IM = 0         DO 10 J = 1, N            IF( SELECT( J ) )     $         IM = IM + 1   10    CONTINUE      ELSE         IM = N      END IF**     Check diagonal of B*      ILBBAD = .FALSE.      DO 20 J = 1, N         IF( DIMAG( B( J, J ) ).NE.ZERO )     $      ILBBAD = .TRUE.   20 CONTINUE*      IF( ILBBAD ) THEN         INFO = -7      ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN         INFO = -10      ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN         INFO = -12      ELSE IF( MM.LT.IM ) THEN         INFO = -13      END IF      IF( INFO.NE.0 ) THEN         CALL XERBLA( 'ZTGEVC', -INFO )         RETURN      END IF**     Quick return if possible*      M = IM      IF( N.EQ.0 )     $   RETURN**     Machine Constants*      SAFMIN = DLAMCH( 'Safe minimum' )      BIG = ONE / SAFMIN      CALL DLABAD( SAFMIN, BIG )      ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )      SMALL = SAFMIN*N / ULP      BIG = ONE / SMALL      BIGNUM = ONE / ( SAFMIN*N )**     Compute the 1-norm of each column of the strictly upper triangular*     part of A and B to check for possible overflow in the triangular*     solver.*      ANORM = ABS1( A( 1, 1 ) )      BNORM = ABS1( B( 1, 1 ) )      RWORK( 1 ) = ZERO      RWORK( N+1 ) = ZERO      DO 40 J = 2, N         RWORK( J ) = ZERO         RWORK( N+J ) = ZERO         DO 30 I = 1, J - 1            RWORK( J ) = RWORK( J ) + ABS1( A( I, J ) )            RWORK( N+J ) = RWORK( N+J ) + ABS1( B( I, J ) )   30    CONTINUE         ANORM = MAX( ANORM, RWORK( J )+ABS1( A( J, J ) ) )         BNORM = MAX( BNORM, RWORK( N+J )+ABS1( B( J, J ) ) )   40 CONTINUE*      ASCALE = ONE / MAX( ANORM, SAFMIN )      BSCALE = ONE / MAX( BNORM, SAFMIN )*     ---------------------- Begin Timing Code -------------------------      OPS = OPS + DBLE( 2*N**2+2*N+6 )*     ----------------------- End Timing Code --------------------------**     Left eigenvectors*      IF( COMPL ) THEN         IEIG = 0**        Main loop over eigenvalues*         DO 140 JE = 1, N            IF( ILALL ) THEN               ILCOMP = .TRUE.            ELSE               ILCOMP = SELECT( JE )            END IF            IF( ILCOMP ) THEN               IEIG = IEIG + 1*               IF( ABS1( A( JE, JE ) ).LE.SAFMIN .AND.     $             ABS( DBLE( B( JE, JE ) ) ).LE.SAFMIN ) THEN**                 Singular matrix pencil -- return unit eigenvector*                  DO 50 JR = 1, N                     VL( JR, IEIG ) = CZERO   50             CONTINUE                  VL( IEIG, IEIG ) = CONE                  GO TO 140               END IF**              Non-singular eigenvalue:*              Compute coefficients  a  and  b  in*                   H*                 y  ( a A - b B ) = 0*               TEMP = ONE / MAX( ABS1( A( JE, JE ) )*ASCALE,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -