📄 zhseqr.f
字号:
SUBROUTINE ZHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, W, Z, LDZ, $ WORK, LWORK, 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 COMPZ, JOB INTEGER IHI, ILO, INFO, LDH, LDZ, LWORK, N* ..* .. Array Arguments .. COMPLEX*16 H( LDH, * ), W( * ), WORK( * ), Z( LDZ, * )* ..* Common block to return operation count.* .. Common blocks .. COMMON / LATIME / OPS, ITCNT* ..* .. Scalars in Common .. DOUBLE PRECISION ITCNT, OPS* ..** Purpose* =======** ZHSEQR computes the eigenvalues of a complex upper Hessenberg* matrix H, and, optionally, the matrices T and Z from the Schur* decomposition H = Z T Z**H, where T is an upper triangular matrix* (the Schur form), and Z is the unitary matrix of Schur vectors.** Optionally Z may be postmultiplied into an input unitary matrix Q,* so that this routine can give the Schur factorization of a matrix A* which has been reduced to the Hessenberg form H by the unitary* matrix Q: A = Q*H*Q**H = (QZ)*T*(QZ)**H.** Arguments* =========** JOB (input) CHARACTER*1* = 'E': compute eigenvalues only;* = 'S': compute eigenvalues and the Schur form T.** COMPZ (input) CHARACTER*1* = 'N': no Schur vectors are computed;* = 'I': Z is initialized to the unit matrix and the matrix Z* of Schur vectors of H is returned;* = 'V': Z must contain an unitary matrix Q on entry, and* the product Q*Z is returned.** N (input) INTEGER* The order of the matrix H. N >= 0.** ILO (input) INTEGER* IHI (input) INTEGER* It is assumed that H is already upper triangular in rows* and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally* set by a previous call to ZGEBAL, and then passed to CGEHRD* when the matrix output by ZGEBAL is reduced to Hessenberg* form. Otherwise ILO and IHI should be set to 1 and N* respectively.* 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.** H (input/output) COMPLEX*16 array, dimension (LDH,N)* On entry, the upper Hessenberg matrix H.* On exit, if JOB = 'S', H contains the upper triangular matrix* T from the Schur decomposition (the Schur form). If* JOB = 'E', the contents of H are unspecified on exit.** LDH (input) INTEGER* The leading dimension of the array H. LDH >= max(1,N).** W (output) COMPLEX*16 array, dimension (N)* The computed eigenvalues. If JOB = 'S', the eigenvalues are* stored in the same order as on the diagonal of the Schur form* returned in H, with W(i) = H(i,i).** Z (input/output) COMPLEX*16 array, dimension (LDZ,N)* If COMPZ = 'N': Z is not referenced.* If COMPZ = 'I': on entry, Z need not be set, and on exit, Z* contains the unitary matrix Z of the Schur vectors of H.* If COMPZ = 'V': on entry Z must contain an N-by-N matrix Q,* which is assumed to be equal to the unit matrix except for* the submatrix Z(ILO:IHI,ILO:IHI); on exit Z contains Q*Z.* Normally Q is the unitary matrix generated by ZUNGHR after* the call to ZGEHRD which formed the Hessenberg matrix H.** LDZ (input) INTEGER* The leading dimension of the array Z.* LDZ >= max(1,N) if COMPZ = 'I' or 'V'; LDZ >= 1 otherwise.** WORK (workspace/output) COMPLEX*16 array, dimension (LWORK)* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.** LWORK (input) INTEGER* The dimension of the array WORK. LWORK >= max(1,N).** If LWORK = -1, then a workspace query is assumed; the routine* only calculates the optimal size of the WORK array, returns* this value as the first entry of the WORK array, and no error* message related to LWORK is issued by XERBLA.** INFO (output) INTEGER* = 0: successful exit* < 0: if INFO = -i, the i-th argument had an illegal value* > 0: if INFO = i, ZHSEQR failed to compute all the* eigenvalues in a total of 30*(IHI-ILO+1) iterations;* elements 1:ilo-1 and i+1:n of W contain those* eigenvalues which have been successfully computed.** =====================================================================** .. Parameters .. COMPLEX*16 ZERO, ONE PARAMETER ( ZERO = ( 0.0D+0, 0.0D+0 ), $ ONE = ( 1.0D+0, 0.0D+0 ) ) DOUBLE PRECISION RZERO, RONE, CONST PARAMETER ( RZERO = 0.0D+0, RONE = 1.0D+0, $ CONST = 1.5D+0 ) INTEGER NSMAX, LDS PARAMETER ( NSMAX = 15, LDS = NSMAX )* ..* .. Local Scalars .. LOGICAL INITZ, LQUERY, WANTT, WANTZ INTEGER I, I1, I2, IERR, II, ITEMP, ITN, ITS, J, K, L, $ MAXB, NH, NR, NS, NV DOUBLE PRECISION OPST, OVFL, RTEMP, SMLNUM, TST1, ULP, UNFL COMPLEX*16 CDUM, TAU, TEMP* ..* .. Local Arrays .. DOUBLE PRECISION RWORK( 1 ) COMPLEX*16 S( LDS, NSMAX ), V( NSMAX+1 ), VV( NSMAX+1 )* ..* .. External Functions .. LOGICAL LSAME INTEGER ILAENV, IZAMAX DOUBLE PRECISION DLAMCH, DLAPY2, ZLANHS EXTERNAL LSAME, ILAENV, IZAMAX, DLAMCH, DLAPY2, ZLANHS* ..* .. External Subroutines .. EXTERNAL DLABAD, XERBLA, ZCOPY, ZDSCAL, ZGEMV, ZLACPY, $ ZLAHQR, ZLARFG, ZLARFX, ZLASET, ZSCAL* ..* .. Intrinsic Functions .. INTRINSIC ABS, DBLE, DCONJG, DIMAG, MAX, MIN* ..* .. Statement Functions .. DOUBLE PRECISION CABS1* ..* .. Statement Function definitions .. CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )* ..* .. Executable Statements ..** Decode and test the input parameters* WANTT = LSAME( JOB, 'S' ) INITZ = LSAME( COMPZ, 'I' ) WANTZ = INITZ .OR. LSAME( COMPZ, 'V' )* INFO = 0 WORK( 1 ) = MAX( 1, N ) LQUERY = ( LWORK.EQ.-1 ) IF( .NOT.LSAME( JOB, 'E' ) .AND. .NOT.WANTT ) THEN INFO = -1 ELSE IF( .NOT.LSAME( COMPZ, 'N' ) .AND. .NOT.WANTZ ) THEN INFO = -2 ELSE IF( N.LT.0 ) THEN INFO = -3 ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THEN INFO = -4 ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THEN INFO = -5 ELSE IF( LDH.LT.MAX( 1, N ) ) THEN INFO = -7 ELSE IF( LDZ.LT.1 .OR. WANTZ .AND. LDZ.LT.MAX( 1, N ) ) THEN INFO = -10 ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN INFO = -12 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'ZHSEQR', -INFO ) RETURN ELSE IF( LQUERY ) THEN RETURN END IF**** Initialize OPST = 0***** Initialize Z, if necessary* IF( INITZ ) $ CALL ZLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Store the eigenvalues isolated by ZGEBAL.* DO 10 I = 1, ILO - 1 W( I ) = H( I, I ) 10 CONTINUE DO 20 I = IHI + 1, N W( I ) = H( I, I ) 20 CONTINUE** Quick return if possible.* IF( N.EQ.0 ) $ RETURN IF( ILO.EQ.IHI ) THEN W( ILO ) = H( ILO, ILO ) RETURN END IF** Set rows and columns ILO to IHI to zero below the first* subdiagonal.* DO 40 J = ILO, IHI - 2 DO 30 I = J + 2, N H( I, J ) = ZERO 30 CONTINUE 40 CONTINUE NH = IHI - ILO + 1** I1 and I2 are the indices of the first row and last column of H* to which transformations must be applied. If eigenvalues only are* being computed, I1 and I2 are re-set inside the main loop.* IF( WANTT ) THEN I1 = 1 I2 = N ELSE I1 = ILO I2 = IHI END IF** Ensure that the subdiagonal elements are real.* DO 50 I = ILO + 1, IHI TEMP = H( I, I-1 ) IF( DIMAG( TEMP ).NE.RZERO ) THEN RTEMP = DLAPY2( DBLE( TEMP ), DIMAG( TEMP ) ) H( I, I-1 ) = RTEMP TEMP = TEMP / RTEMP IF( I2.GT.I ) $ CALL ZSCAL( I2-I, DCONJG( TEMP ), H( I, I+1 ), LDH ) CALL ZSCAL( I-I1, TEMP, H( I1, I ), 1 ) IF( I.LT.IHI ) $ H( I+1, I ) = TEMP*H( I+1, I )**** Increment op count OPST = OPST + 6*( I2-I1+2 )*** IF( WANTZ ) THEN CALL ZSCAL( NH, TEMP, Z( ILO, I ), 1 )**** Increment op count OPST = OPST + 6*NH*** END IF END IF 50 CONTINUE** Determine the order of the multi-shift QR algorithm to be used.* NS = ILAENV( 4, 'ZHSEQR', JOB // COMPZ, N, ILO, IHI, -1 ) MAXB = ILAENV( 8, 'ZHSEQR', JOB // COMPZ, N, ILO, IHI, -1 ) IF( NS.LE.1 .OR. NS.GT.NH .OR. MAXB.GE.NH ) THEN** Use the standard double-shift algorithm* CALL ZLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, W, ILO, IHI, Z,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -