slahqr.f
来自「计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.」· F 代码 · 共 513 行 · 第 1/2 页
F
513 行
SUBROUTINE SLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, $ ILOZ, IHIZ, Z, LDZ, INFO )** -- LAPACK auxiliary routine (instrum. to count ops. 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 .. LOGICAL WANTT, WANTZ INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N* ..* .. Array Arguments .. REAL H( LDH, * ), WI( * ), WR( * ), Z( LDZ, * )* ..* Common block to return operation count.* .. Common blocks .. COMMON / LATIME / OPS, ITCNT* ..* .. Scalars in Common .. REAL ITCNT, OPS* ..** Purpose* =======** SLAHQR is an auxiliary routine called by SHSEQR to update the* eigenvalues and Schur decomposition already computed by SHSEQR, by* dealing with the Hessenberg submatrix in rows and columns ILO to IHI.** Arguments* =========** WANTT (input) LOGICAL* = .TRUE. : the full Schur form T is required;* = .FALSE.: only eigenvalues are required.** WANTZ (input) LOGICAL* = .TRUE. : the matrix of Schur vectors Z is required;* = .FALSE.: Schur vectors are not required.** 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 quasi-triangular in* rows and columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless* ILO = 1). SLAHQR works primarily with the Hessenberg* submatrix in rows and columns ILO to IHI, but applies* transformations to all of H if WANTT is .TRUE..* 1 <= ILO <= max(1,IHI); IHI <= N.** H (input/output) REAL array, dimension (LDH,N)* On entry, the upper Hessenberg matrix H.* On exit, if WANTT is .TRUE., H is upper quasi-triangular in* rows and columns ILO:IHI, with any 2-by-2 diagonal blocks in* standard form. If WANTT is .FALSE., the contents of H are* unspecified on exit.** LDH (input) INTEGER* The leading dimension of the array H. LDH >= max(1,N).** WR (output) REAL array, dimension (N)* WI (output) REAL array, dimension (N)* The real and imaginary parts, respectively, of the computed* eigenvalues ILO to IHI are stored in the corresponding* elements of WR and WI. 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 WANTT is .TRUE., 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).** ILOZ (input) INTEGER* IHIZ (input) INTEGER* Specify the rows of Z to which transformations must be* applied if WANTZ is .TRUE..* 1 <= ILOZ <= ILO; IHI <= IHIZ <= N.** Z (input/output) REAL array, dimension (LDZ,N)* If WANTZ is .TRUE., on entry Z must contain the current* matrix Z of transformations accumulated by SHSEQR, and on* exit Z has been updated; transformations are applied only to* the submatrix Z(ILOZ:IHIZ,ILO:IHI).* If WANTZ is .FALSE., Z is not referenced.** LDZ (input) INTEGER* The leading dimension of the array Z. LDZ >= max(1,N).** INFO (output) INTEGER* = 0: successful exit* > 0: SLAHQR failed to compute all the eigenvalues ILO to IHI* in a total of 30*(IHI-ILO+1) iterations; if INFO = i,* elements i+1:ihi of WR and WI contain those eigenvalues* which have been successfully computed.** Further Details* ===============** 2-96 Based on modifications by* David Day, Sandia National Laboratory, USA** =====================================================================** .. Parameters .. REAL ZERO, ONE, HALF PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0, HALF = 0.5E0 ) REAL DAT1, DAT2 PARAMETER ( DAT1 = 0.75E+0, DAT2 = -0.4375E+0 )* ..* .. Local Scalars .. INTEGER I, I1, I2, ITN, ITS, J, K, L, M, NH, NR, NZ REAL AVE, CS, DISC, H00, H10, H11, H12, H21, H22, $ H33, H33S, H43H34, H44, H44S, OPST, OVFL, S, $ SMLNUM, SN, SUM, T1, T2, T3, TST1, ULP, UNFL, $ V1, V2, V3* ..* .. Local Arrays .. REAL V( 3 ), WORK( 1 )* ..* .. External Functions .. REAL SLAMCH, SLANHS EXTERNAL SLAMCH, SLANHS* ..* .. External Subroutines .. EXTERNAL SCOPY, SLABAD, SLANV2, SLARFG, SROT* ..* .. Intrinsic Functions .. INTRINSIC ABS, MAX, MIN, SIGN, SQRT* ..* .. Executable Statements ..* INFO = 0**** Initialize OPST = 0***** 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* NH = IHI - ILO + 1 NZ = IHIZ - ILOZ + 1** Set machine-dependent constants for the stopping criterion.* If norm(H) <= sqrt(OVFL), overflow should not occur.* UNFL = SLAMCH( 'Safe minimum' ) OVFL = ONE / UNFL CALL SLABAD( UNFL, OVFL ) ULP = SLAMCH( '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** ITN is the total number of QR iterations allowed.* ITN = 30*NH** The main loop begins here. I is the loop index and decreases from* IHI to ILO in steps of 1 or 2. Each iteration of the loop works* with the active submatrix in rows and columns L to I.* Eigenvalues I+1 to IHI have already converged. Either L = ILO or* H(L,L-1) is negligible so that the matrix splits.* I = IHI 10 CONTINUE L = ILO IF( I.LT.ILO ) $ GO TO 150** Perform QR iterations on rows and columns ILO to I until a* submatrix of order 1 or 2 splits off at the bottom because a* subdiagonal element has become negligible.* DO 130 ITS = 0, ITN** Look for a single small subdiagonal element.* DO 20 K = I, L + 1, -1 TST1 = ABS( H( K-1, K-1 ) ) + ABS( H( K, K ) ) IF( TST1.EQ.ZERO ) THEN TST1 = SLANHS( '1', I-L+1, H( L, L ), LDH, WORK )**** Increment op count OPS = OPS + ( I-L+1 )*( I-L+2 ) / 2*** END IF IF( ABS( H( K, K-1 ) ).LE.MAX( ULP*TST1, SMLNUM ) ) $ GO TO 30 20 CONTINUE 30 CONTINUE L = K**** Increment op count OPST = OPST + 3*( I-L+1 )*** IF( L.GT.ILO ) THEN** H(L,L-1) is negligible* H( L, L-1 ) = ZERO END IF** Exit from loop if a submatrix of order 1 or 2 has split off.* IF( L.GE.I-1 ) $ GO TO 140** Now the active submatrix is in rows and columns L to I. If* eigenvalues only are being computed, only the active submatrix* need be transformed.* IF( .NOT.WANTT ) THEN I1 = L I2 = I END IF* IF( ITS.EQ.10 .OR. ITS.EQ.20 ) THEN** Exceptional shift.* S = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) ) H44 = DAT1*S + H( I, I ) H33 = H44 H43H34 = DAT2*S*S**** Increment op count OPST = OPST + 5*** ELSE** Prepare to use Francis' double shift* (i.e. 2nd degree generalized Rayleigh quotient)* H44 = H( I, I ) H33 = H( I-1, I-1 ) H43H34 = H( I, I-1 )*H( I-1, I ) S = H( I-1, I-2 )*H( I-1, I-2 ) DISC = ( H33-H44 )*HALF
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?