📄 ztgevc.f
字号:
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 + -