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