📄 dhseqr.f
字号:
SUBROUTINE DHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, 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 .. DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ), $ Z( LDZ, * )* ..* Common block to return operation count.* .. Common blocks .. COMMON / LATIME / OPS, ITCNT* ..* .. Scalars in Common .. DOUBLE PRECISION ITCNT, OPS* ..** Purpose* =======** DHSEQR computes the eigenvalues of a real upper Hessenberg matrix H* and, optionally, the matrices T and Z from the Schur decomposition* H = Z T Z**T, where T is an upper quasi-triangular matrix (the Schur* form), and Z is the orthogonal matrix of Schur vectors.** Optionally Z may be postmultiplied into an input orthogonal 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 orthogonal* matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T.** 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 orthogonal 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 DGEBAL, and then passed to SGEHRD* when the matrix output by DGEBAL 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) DOUBLE PRECISION array, dimension (LDH,N)* On entry, the upper Hessenberg matrix H.* On exit, if JOB = 'S', H contains the upper quasi-triangular* matrix T from the Schur decomposition (the Schur form);* 2-by-2 diagonal blocks (corresponding to complex conjugate* pairs of eigenvalues) are returned in standard form, with* H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0. 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).** WR (output) DOUBLE PRECISION array, dimension (N)* WI (output) DOUBLE PRECISION array, dimension (N)* The real and imaginary parts, respectively, of the computed* eigenvalues. If two eigenvalues are computed as a complex* conjugate pair, they are stored in consecutive elements of* WR and WI, say the i-th and (i+1)th, with WI(i) > 0 and* WI(i+1) < 0. If JOB = 'S', the eigenvalues are stored in the* same order as on the diagonal of the Schur form returned in* H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2* diagonal block, WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and* WI(i+1) = -WI(i).** Z (input/output) DOUBLE PRECISION 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 orthogonal 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 orthogonal matrix generated by DORGHR after* the call to DGEHRD 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) DOUBLE PRECISION 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, DHSEQR failed to compute all of the* eigenvalues in a total of 30*(IHI-ILO+1) iterations;* elements 1:ilo-1 and i+1:n of WR and WI contain those* eigenvalues which have been successfully computed.** =====================================================================** .. Parameters .. DOUBLE PRECISION ZERO, ONE, TWO PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 ) DOUBLE PRECISION CONST PARAMETER ( 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 ABSW, OPST, OVFL, SMLNUM, TAU, TEMP, TST1, ULP, $ UNFL* ..* .. Local Arrays .. DOUBLE PRECISION S( LDS, NSMAX ), V( NSMAX+1 ), VV( NSMAX+1 )* ..* .. External Functions .. LOGICAL LSAME INTEGER IDAMAX, ILAENV DOUBLE PRECISION DLAMCH, DLANHS, DLAPY2 EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANHS, DLAPY2* ..* .. External Subroutines .. EXTERNAL DCOPY, DGEMV, DLABAD, DLACPY, DLAHQR, DLARFG, $ DLARFX, DLASET, DSCAL, XERBLA* ..* .. Intrinsic Functions .. INTRINSIC ABS, MAX, MIN* ..* .. 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 = -11 ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN INFO = -13 END IF IF( INFO.NE.0 ) THEN CALL XERBLA( 'DHSEQR', -INFO ) RETURN ELSE IF( LQUERY ) THEN RETURN END IF**** Initialize OPST = 0***** Initialize Z, if necessary* IF( INITZ ) $ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Store the eigenvalues isolated by DGEBAL.* DO 10 I = 1, ILO - 1 WR( I ) = H( I, I ) WI( I ) = ZERO 10 CONTINUE DO 20 I = IHI + 1, N WR( I ) = H( I, I ) WI( I ) = ZERO 20 CONTINUE** Quick return if possible.* IF( N.EQ.0 ) $ RETURN IF( ILO.EQ.IHI ) THEN WR( ILO ) = H( ILO, ILO ) WI( ILO ) = ZERO 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** Determine the order of the multi-shift QR algorithm to be used.* NS = ILAENV( 4, 'DHSEQR', JOB // COMPZ, N, ILO, IHI, -1 ) MAXB = ILAENV( 8, 'DHSEQR', JOB // COMPZ, N, ILO, IHI, -1 ) IF( NS.LE.2 .OR. NS.GT.NH .OR. MAXB.GE.NH ) THEN** Use the standard double-shift algorithm* CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO, $ IHI, Z, LDZ, INFO ) RETURN END IF MAXB = MAX( 3, MAXB ) NS = MIN( NS, MAXB, NSMAX )** Now 2 < NS <= MAXB < NH.** Set machine-dependent constants for the stopping criterion.* If norm(H) <= sqrt(OVFL), overflow should not occur.* UNFL = DLAMCH( 'Safe minimum' ) OVFL = ONE / UNFL CALL DLABAD( UNFL, OVFL ) ULP = DLAMCH( 'Precision' ) SMLNUM = UNFL*( NH / ULP )** 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 set inside the main loop.* IF( WANTT ) THEN I1 = 1 I2 = N END IF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -