slahqr.f

来自「计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.」· F 代码 · 共 513 行 · 第 1/2 页

F
513
字号
            DISC = DISC*DISC + H43H34****           Increment op count            OPST = OPST + 6***            IF( DISC.GT.ZERO ) THEN**              Real roots: use Wilkinson's shift twice*               DISC = SQRT( DISC )               AVE = HALF*( H33+H44 )****              Increment op count               OPST = OPST + 2***               IF( ABS( H33 )-ABS( H44 ).GT.ZERO ) THEN                  H33 = H33*H44 - H43H34                  H44 = H33 / ( SIGN( DISC, AVE )+AVE )****                 Increment op count                  OPST = OPST + 4***               ELSE                  H44 = SIGN( DISC, AVE ) + AVE****                 Increment op count                  OPST = OPST + 1***               END IF               H33 = H44               H43H34 = ZERO            END IF         END IF**        Look for two consecutive small subdiagonal elements.*         DO 40 M = I - 2, L, -1**           Determine the effect of starting the double-shift QR*           iteration at row M, and see if this would make H(M,M-1)*           negligible.*            H11 = H( M, M )            H22 = H( M+1, M+1 )            H21 = H( M+1, M )            H12 = H( M, M+1 )            H44S = H44 - H11            H33S = H33 - H11            V1 = ( H33S*H44S-H43H34 ) / H21 + H12            V2 = H22 - H11 - H33S - H44S            V3 = H( M+2, M+1 )            S = ABS( V1 ) + ABS( V2 ) + ABS( V3 )            V1 = V1 / S            V2 = V2 / S            V3 = V3 / S            V( 1 ) = V1            V( 2 ) = V2            V( 3 ) = V3            IF( M.EQ.L )     $         GO TO 50            H00 = H( M-1, M-1 )            H10 = H( M, M-1 )            TST1 = ABS( V1 )*( ABS( H00 )+ABS( H11 )+ABS( H22 ) )            IF( ABS( H10 )*( ABS( V2 )+ABS( V3 ) ).LE.ULP*TST1 )     $         GO TO 50   40    CONTINUE   50    CONTINUE****        Increment op count         OPST = OPST + 20*( I-M-1 )*****        Double-shift QR step*         DO 120 K = M, 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( 3, I-K+1 )            IF( K.GT.M )     $         CALL SCOPY( NR, H( K, K-1 ), 1, V, 1 )            CALL SLARFG( NR, V( 1 ), V( 2 ), 1, T1 )****           Increment op count            OPST = OPST + 3*NR + 9***            IF( K.GT.M ) THEN               H( K, K-1 ) = V( 1 )               H( K+1, K-1 ) = ZERO               IF( K.LT.I-1 )     $            H( K+2, K-1 ) = ZERO            ELSE IF( M.GT.L ) THEN               H( K, K-1 ) = -H( K, K-1 )            END IF            V2 = V( 2 )            T2 = T1*V2            IF( NR.EQ.3 ) THEN               V3 = V( 3 )               T3 = T1*V3**              Apply G from the left to transform the rows of the matrix*              in columns K to I2.*               DO 60 J = K, I2                  SUM = H( K, J ) + V2*H( K+1, J ) + V3*H( K+2, J )                  H( K, J ) = H( K, J ) - SUM*T1                  H( K+1, J ) = H( K+1, J ) - SUM*T2                  H( K+2, J ) = H( K+2, J ) - SUM*T3   60          CONTINUE**              Apply G from the right to transform the columns of the*              matrix in rows I1 to min(K+3,I).*               DO 70 J = I1, MIN( K+3, I )                  SUM = H( J, K ) + V2*H( J, K+1 ) + V3*H( J, K+2 )                  H( J, K ) = H( J, K ) - SUM*T1                  H( J, K+1 ) = H( J, K+1 ) - SUM*T2                  H( J, K+2 ) = H( J, K+2 ) - SUM*T3   70          CONTINUE****              Increment op count               OPS = OPS + 10*( I2-I1+2+MIN( 3, I-K ) )****               IF( WANTZ ) THEN**                 Accumulate transformations in the matrix Z*                  DO 80 J = ILOZ, IHIZ                     SUM = Z( J, K ) + V2*Z( J, K+1 ) + V3*Z( J, K+2 )                     Z( J, K ) = Z( J, K ) - SUM*T1                     Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2                     Z( J, K+2 ) = Z( J, K+2 ) - SUM*T3   80             CONTINUE****                 Increment op count                  OPS = OPS + 10*NZ***               END IF            ELSE IF( NR.EQ.2 ) THEN**              Apply G from the left to transform the rows of the matrix*              in columns K to I2.*               DO 90 J = K, I2                  SUM = H( K, J ) + V2*H( K+1, J )                  H( K, J ) = H( K, J ) - SUM*T1                  H( K+1, J ) = H( K+1, J ) - SUM*T2   90          CONTINUE**              Apply G from the right to transform the columns of the*              matrix in rows I1 to min(K+3,I).*               DO 100 J = I1, I                  SUM = H( J, K ) + V2*H( J, K+1 )                  H( J, K ) = H( J, K ) - SUM*T1                  H( J, K+1 ) = H( J, K+1 ) - SUM*T2  100          CONTINUE****              Increment op count               OPS = OPS + 6*( I2-I1+3 )****               IF( WANTZ ) THEN**                 Accumulate transformations in the matrix Z*                  DO 110 J = ILOZ, IHIZ                     SUM = Z( J, K ) + V2*Z( J, K+1 )                     Z( J, K ) = Z( J, K ) - SUM*T1                     Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2  110             CONTINUE****                 Increment op count                  OPS = OPS + 6*NZ***               END IF            END IF  120    CONTINUE*  130 CONTINUE**     Failure to converge in remaining number of iterations*      INFO = I      RETURN*  140 CONTINUE*      IF( L.EQ.I ) THEN**        H(I,I-1) is negligible: one eigenvalue has converged.*         WR( I ) = H( I, I )         WI( I ) = ZERO      ELSE IF( L.EQ.I-1 ) THEN**        H(I-1,I-2) is negligible: a pair of eigenvalues have converged.**        Transform the 2-by-2 submatrix to standard Schur form,*        and compute and store the eigenvalues.*         CALL SLANV2( H( I-1, I-1 ), H( I-1, I ), H( I, I-1 ),     $                H( I, I ), WR( I-1 ), WI( I-1 ), WR( I ), WI( I ),     $                CS, SN )*         IF( WANTT ) THEN**           Apply the transformation to the rest of H.*            IF( I2.GT.I )     $         CALL SROT( I2-I, H( I-1, I+1 ), LDH, H( I, I+1 ), LDH,     $                    CS, SN )            CALL SROT( I-I1-1, H( I1, I-1 ), 1, H( I1, I ), 1, CS, SN )****           Increment op count            OPS = OPS + 6*( I2-I1-1 )***         END IF         IF( WANTZ ) THEN**           Apply the transformation to Z.*            CALL SROT( NZ, Z( ILOZ, I-1 ), 1, Z( ILOZ, I ), 1, CS, SN )****           Increment op count            OPS = OPS + 6*NZ***         END IF      END IF**     Decrement number of remaining iterations, and return to start of*     the main loop with new value of I.*      ITN = ITN - ITS      I = L - 1      GO TO 10*  150 CONTINUE****     Compute final op count      OPS = OPS + OPST***      RETURN**     End of SLAHQR*      END

⌨️ 快捷键说明

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