⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhseqr.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 2 页
字号:
**     ITN is the total number of multiple-shift 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 at most MAXB. 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   50 CONTINUE      L = ILO      IF( I.LT.ILO )     $   GO TO 170**     Perform multiple-shift QR iterations on rows and columns ILO to I*     until a submatrix of order at most MAXB splits off at the bottom*     because a subdiagonal element has become negligible.*      DO 150 ITS = 0, ITN**        Look for a single small subdiagonal element.*         DO 60 K = I, L + 1, -1            TST1 = ABS( H( K-1, K-1 ) ) + ABS( H( K, K ) )            IF( TST1.EQ.ZERO ) THEN               TST1 = DLANHS( '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 70   60    CONTINUE   70    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 <= MAXB has split off.*         IF( L.GE.I-MAXB+1 )     $      GO TO 160**        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.20 .OR. ITS.EQ.30 ) THEN**           Exceptional shifts.*            DO 80 II = I - NS + 1, I               WR( II ) = CONST*( ABS( H( II, II-1 ) )+     $                    ABS( H( II, II ) ) )               WI( II ) = ZERO   80       CONTINUE****           Increment op count            OPST = OPST + 2*NS***         ELSE**           Use eigenvalues of trailing submatrix of order NS as shifts.*            CALL DLACPY( 'Full', NS, NS, H( I-NS+1, I-NS+1 ), LDH, S,     $                   LDS )            CALL DLAHQR( .FALSE., .FALSE., NS, 1, NS, S, LDS,     $                   WR( I-NS+1 ), WI( I-NS+1 ), 1, NS, Z, LDZ,     $                   IERR )            IF( IERR.GT.0 ) THEN**              If DLAHQR failed to compute all NS eigenvalues, use the*              unconverged diagonal elements as the remaining shifts.*               DO 90 II = 1, IERR                  WR( I-NS+II ) = S( II, II )                  WI( I-NS+II ) = ZERO   90          CONTINUE            END IF         END IF**        Form the first column of (G-w(1)) (G-w(2)) . . . (G-w(ns))*        where G is the Hessenberg submatrix H(L:I,L:I) and w is*        the vector of shifts (stored in WR and WI). The result is*        stored in the local array V.*         V( 1 ) = ONE         DO 100 II = 2, NS + 1            V( II ) = ZERO  100    CONTINUE         NV = 1         DO 120 J = I - NS + 1, I            IF( WI( J ).GE.ZERO ) THEN               IF( WI( J ).EQ.ZERO ) THEN**                 real shift*                  CALL DCOPY( NV+1, V, 1, VV, 1 )                  CALL DGEMV( 'No transpose', NV+1, NV, ONE, H( L, L ),     $                        LDH, VV, 1, -WR( J ), V, 1 )                  NV = NV + 1****                 Increment op count                  OPST = OPST + 2*NV*( NV+1 ) + NV + 1***               ELSE IF( WI( J ).GT.ZERO ) THEN**                 complex conjugate pair of shifts*                  CALL DCOPY( NV+1, V, 1, VV, 1 )                  CALL DGEMV( 'No transpose', NV+1, NV, ONE, H( L, L ),     $                        LDH, V, 1, -TWO*WR( J ), VV, 1 )                  ITEMP = IDAMAX( NV+1, VV, 1 )                  TEMP = ONE / MAX( ABS( VV( ITEMP ) ), SMLNUM )                  CALL DSCAL( NV+1, TEMP, VV, 1 )                  ABSW = DLAPY2( WR( J ), WI( J ) )                  TEMP = ( TEMP*ABSW )*ABSW                  CALL DGEMV( 'No transpose', NV+2, NV+1, ONE,     $                        H( L, L ), LDH, VV, 1, TEMP, V, 1 )                  NV = NV + 2****                 Increment op count                  OPST = OPST + 4*( NV+1 )**2 + 4*NV + 9***               END IF**              Scale V(1:NV) so that max(abs(V(i))) = 1. If V is zero,*              reset it to the unit vector.*               ITEMP = IDAMAX( NV, V, 1 )****              Increment op count               OPST = OPST + NV***               TEMP = ABS( V( ITEMP ) )               IF( TEMP.EQ.ZERO ) THEN                  V( 1 ) = ONE                  DO 110 II = 2, NV                     V( II ) = ZERO  110             CONTINUE               ELSE                  TEMP = MAX( TEMP, SMLNUM )                  CALL DSCAL( NV, ONE / TEMP, V, 1 )****                 Increment op count                  OPST = OPST + NV***               END IF            END IF  120    CONTINUE**        Multiple-shift QR step*         DO 140 K = L, I - 1**           The first iteration of this loop determines a reflection G*           from the vector V and applies it from left and right to H,*           thus creating a nonzero bulge below the subdiagonal.**           Each subsequent iteration determines a reflection G to*           restore the Hessenberg form in the (K-1)th column, and thus*           chases the bulge one step toward the bottom of the active*           submatrix. NR is the order of G.*            NR = MIN( NS+1, I-K+1 )            IF( K.GT.L )     $         CALL DCOPY( NR, H( K, K-1 ), 1, V, 1 )            CALL DLARFG( NR, V( 1 ), V( 2 ), 1, TAU )****           Increment op count            OPST = OPST + 3*NR + 9***            IF( K.GT.L ) THEN               H( K, K-1 ) = V( 1 )               DO 130 II = K + 1, I                  H( II, K-1 ) = ZERO  130          CONTINUE            END IF            V( 1 ) = ONE**           Apply G from the left to transform the rows of the matrix in*           columns K to I2.*            CALL DLARFX( 'Left', NR, I2-K+1, V, TAU, H( K, K ), LDH,     $                   WORK )**           Apply G from the right to transform the columns of the*           matrix in rows I1 to min(K+NR,I).*            CALL DLARFX( 'Right', MIN( K+NR, I )-I1+1, NR, V, TAU,     $                   H( I1, K ), LDH, WORK )****           Increment op count            OPS = OPS + ( 4*NR-2 )*( I2-I1+2+MIN( NR, I-K ) )****            IF( WANTZ ) THEN**              Accumulate transformations in the matrix Z*               CALL DLARFX( 'Right', NH, NR, V, TAU, Z( ILO, K ), LDZ,     $                      WORK )****              Increment op count               OPS = OPS + ( 4*NR-2 )*NH***            END IF  140    CONTINUE*  150 CONTINUE**     Failure to converge in remaining number of iterations*      INFO = I      RETURN*  160 CONTINUE**     A submatrix of order <= MAXB in rows and columns L to I has split*     off. Use the double-shift QR algorithm to handle it.*      CALL DLAHQR( WANTT, WANTZ, N, L, I, H, LDH, WR, WI, ILO, IHI, Z,     $             LDZ, INFO )      IF( INFO.GT.0 )     $   RETURN**     Decrement number of remaining iterations, and return to start of*     the main loop with a new value of I.*      ITN = ITN - ITS      I = L - 1      GO TO 50*  170 CONTINUE****     Compute final op count      OPS = OPS + OPST***      WORK( 1 ) = MAX( 1, N )      RETURN**     End of DHSEQR*      END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -