📄 dlaein.f
字号:
SUBROUTINE DLAEIN( RIGHTV, NOINIT, N, H, LDH, WR, WI, VR, VI, B, $ LDB, WORK, EPS3, SMLNUM, BIGNUM, INFO )** -- LAPACK auxiliary routine (instrumented to count operations) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* September 30, 1994** .. Scalar Arguments .. LOGICAL NOINIT, RIGHTV INTEGER INFO, LDB, LDH, N DOUBLE PRECISION BIGNUM, EPS3, SMLNUM, WI, WR* ..* .. Array Arguments .. DOUBLE PRECISION B( LDB, * ), H( LDH, * ), VI( * ), VR( * ), $ WORK( * )* ..* Common block to return operation count.* .. Common blocks .. COMMON / LATIME / OPS, ITCNT* ..* .. Scalars in Common .. DOUBLE PRECISION ITCNT, OPS* ..** Purpose* =======** DLAEIN uses inverse iteration to find a right or left eigenvector* corresponding to the eigenvalue (WR,WI) of a real upper Hessenberg* matrix H.** Arguments* =========** RIGHTV (input) LOGICAL* = .TRUE. : compute right eigenvector;* = .FALSE.: compute left eigenvector.** NOINIT (input) LOGICAL* = .TRUE. : no initial vector supplied in (VR,VI).* = .FALSE.: initial vector supplied in (VR,VI).** N (input) INTEGER* The order of the matrix H. N >= 0.** H (input) DOUBLE PRECISION array, dimension (LDH,N)* The upper Hessenberg matrix H.** LDH (input) INTEGER* The leading dimension of the array H. LDH >= max(1,N).** WR (input) DOUBLE PRECISION* WI (input) DOUBLE PRECISION* The real and imaginary parts of the eigenvalue of H whose* corresponding right or left eigenvector is to be computed.** VR (input/output) DOUBLE PRECISION array, dimension (N)* VI (input/output) DOUBLE PRECISION array, dimension (N)* On entry, if NOINIT = .FALSE. and WI = 0.0, VR must contain* a real starting vector for inverse iteration using the real* eigenvalue WR; if NOINIT = .FALSE. and WI.ne.0.0, VR and VI* must contain the real and imaginary parts of a complex* starting vector for inverse iteration using the complex* eigenvalue (WR,WI); otherwise VR and VI need not be set.* On exit, if WI = 0.0 (real eigenvalue), VR contains the* computed real eigenvector; if WI.ne.0.0 (complex eigenvalue),* VR and VI contain the real and imaginary parts of the* computed complex eigenvector. The eigenvector is normalized* so that the component of largest magnitude has magnitude 1;* here the magnitude of a complex number (x,y) is taken to be* |x| + |y|.* VI is not referenced if WI = 0.0.** B (workspace) DOUBLE PRECISION array, dimension (LDB,N)** LDB (input) INTEGER* The leading dimension of the array B. LDB >= N+1.** WORK (workspace) DOUBLE PRECISION array, dimension (N)** EPS3 (input) DOUBLE PRECISION* A small machine-dependent value which is used to perturb* close eigenvalues, and to replace zero pivots.** SMLNUM (input) DOUBLE PRECISION* A machine-dependent value close to the underflow threshold.** BIGNUM (input) DOUBLE PRECISION* A machine-dependent value close to the overflow threshold.** INFO (output) INTEGER* = 0: successful exit* = 1: inverse iteration did not converge; VR is set to the* last iterate, and so is VI if WI.ne.0.0.** =====================================================================** .. Parameters .. DOUBLE PRECISION ZERO, ONE, TENTH PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TENTH = 1.0D-1 )* ..* .. Local Scalars .. CHARACTER NORMIN, TRANS INTEGER I, I1, I2, I3, IERR, ITS, J DOUBLE PRECISION ABSBII, ABSBJJ, EI, EJ, GROWTO, NORM, NRMSML, $ OPST, REC, ROOTN, SCALE, TEMP, VCRIT, VMAX, $ VNORM, W, W1, X, XI, XR, Y* ..* .. External Functions .. INTEGER IDAMAX DOUBLE PRECISION DASUM, DLAPY2, DNRM2 EXTERNAL IDAMAX, DASUM, DLAPY2, DNRM2* ..* .. External Subroutines .. EXTERNAL DLADIV, DLATRS, DSCAL* ..* .. Intrinsic Functions .. INTRINSIC ABS, DBLE, MAX, SQRT* ..* .. Executable Statements ..* INFO = 0**** Initialize OPST = 0***** GROWTO is the threshold used in the acceptance test for an* eigenvector.* ROOTN = SQRT( DBLE( N ) ) GROWTO = TENTH / ROOTN NRMSML = MAX( ONE, EPS3*ROOTN )*SMLNUM**** Increment op count for computing ROOTN, GROWTO and NRMSML OPST = OPST + 4***** Form B = H - (WR,WI)*I (except that the subdiagonal elements and* the imaginary parts of the diagonal elements are not stored).* DO 20 J = 1, N DO 10 I = 1, J - 1 B( I, J ) = H( I, J ) 10 CONTINUE B( J, J ) = H( J, J ) - WR 20 CONTINUE*** OPST = OPST + N**** IF( WI.EQ.ZERO ) THEN** Real eigenvalue.* IF( NOINIT ) THEN** Set initial vector.* DO 30 I = 1, N VR( I ) = EPS3 30 CONTINUE ELSE** Scale supplied initial vector.* VNORM = DNRM2( N, VR, 1 ) CALL DSCAL( N, ( EPS3*ROOTN ) / MAX( VNORM, NRMSML ), VR, $ 1 )*** OPST = OPST + ( 3*N+2 )*** END IF* IF( RIGHTV ) THEN** LU decomposition with partial pivoting of B, replacing zero* pivots by EPS3.* DO 60 I = 1, N - 1 EI = H( I+1, I ) IF( ABS( B( I, I ) ).LT.ABS( EI ) ) THEN** Interchange rows and eliminate.* X = B( I, I ) / EI B( I, I ) = EI DO 40 J = I + 1, N TEMP = B( I+1, J ) B( I+1, J ) = B( I, J ) - X*TEMP B( I, J ) = TEMP 40 CONTINUE ELSE** Eliminate without interchange.* IF( B( I, I ).EQ.ZERO ) $ B( I, I ) = EPS3 X = EI / B( I, I ) IF( X.NE.ZERO ) THEN DO 50 J = I + 1, N B( I+1, J ) = B( I+1, J ) - X*B( I, J ) 50 CONTINUE END IF END IF 60 CONTINUE IF( B( N, N ).EQ.ZERO ) $ B( N, N ) = EPS3**** Increment op count for LU decomposition OPS = OPS + ( N-1 )*( N+1 )**** TRANS = 'N'* ELSE** UL decomposition with partial pivoting of B, replacing zero* pivots by EPS3.* DO 90 J = N, 2, -1 EJ = H( J, J-1 ) IF( ABS( B( J, J ) ).LT.ABS( EJ ) ) THEN** Interchange columns and eliminate.* X = B( J, J ) / EJ B( J, J ) = EJ DO 70 I = 1, J - 1 TEMP = B( I, J-1 ) B( I, J-1 ) = B( I, J ) - X*TEMP B( I, J ) = TEMP 70 CONTINUE ELSE** Eliminate without interchange.* IF( B( J, J ).EQ.ZERO ) $ B( J, J ) = EPS3 X = EJ / B( J, J ) IF( X.NE.ZERO ) THEN DO 80 I = 1, J - 1 B( I, J-1 ) = B( I, J-1 ) - X*B( I, J ) 80 CONTINUE END IF END IF 90 CONTINUE IF( B( 1, 1 ).EQ.ZERO ) $ B( 1, 1 ) = EPS3**** Increment op count for UL decomposition OPS = OPS + ( N-1 )*( N+1 )**** TRANS = 'T'* END IF* NORMIN = 'N' DO 110 ITS = 1, N** Solve U*x = scale*v for a right eigenvector* or U'*x = scale*v for a left eigenvector,* overwriting x on v.* CALL DLATRS( 'Upper', TRANS, 'Nonunit', NORMIN, N, B, LDB, $ VR, SCALE, WORK, IERR )**** Increment opcount for triangular solver, assuming that* ops DLATRS = ops DTRSV, with no scaling in DLATRS. OPS = OPS + N*N*** NORMIN = 'Y'** Test for sufficient growth in the norm of v.* VNORM = DASUM( N, VR, 1 )*** OPST = OPST + N*** IF( VNORM.GE.GROWTO*SCALE ) $ GO TO 120** Choose new orthogonal starting vector and try again.* TEMP = EPS3 / ( ROOTN+ONE ) VR( 1 ) = EPS3 DO 100 I = 2, N VR( I ) = TEMP 100 CONTINUE VR( N-ITS+1 ) = VR( N-ITS+1 ) - EPS3*ROOTN*** OPST = OPST + 4*** 110 CONTINUE** Failure to find eigenvector in N iterations.* INFO = 1* 120 CONTINUE** Normalize eigenvector.* I = IDAMAX( N, VR, 1 ) CALL DSCAL( N, ONE / ABS( VR( I ) ), VR, 1 )*** OPST = OPST + ( 2*N+1 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -