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 + -
显示快捷键?