dtgevc.f.html
来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 1,038 行 · 第 1/5 页
HTML
1,038 行
TEMP = TEMP + ABS( S( I, J ) )
TEMP2 = TEMP2 + ABS( P( I, J ) )
40 CONTINUE
ANORM = MAX( ANORM, TEMP )
BNORM = MAX( BNORM, TEMP2 )
50 CONTINUE
<span class="comment">*</span><span class="comment">
</span> ASCALE = ONE / MAX( ANORM, SAFMIN )
BSCALE = ONE / MAX( BNORM, SAFMIN )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Left eigenvectors
</span><span class="comment">*</span><span class="comment">
</span> IF( COMPL ) THEN
IEIG = 0
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Main loop over eigenvalues
</span><span class="comment">*</span><span class="comment">
</span> ILCPLX = .FALSE.
DO 220 JE = 1, N
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
</span><span class="comment">*</span><span class="comment"> (b) this would be the second of a complex pair.
</span><span class="comment">*</span><span class="comment"> Check for complex eigenvalue, so as to be sure of which
</span><span class="comment">*</span><span class="comment"> entry(-ies) of SELECT to look at.
</span><span class="comment">*</span><span class="comment">
</span> IF( ILCPLX ) THEN
ILCPLX = .FALSE.
GO TO 220
END IF
NW = 1
IF( JE.LT.N ) THEN
IF( S( JE+1, JE ).NE.ZERO ) THEN
ILCPLX = .TRUE.
NW = 2
END IF
END IF
IF( ILALL ) THEN
ILCOMP = .TRUE.
ELSE IF( ILCPLX ) THEN
ILCOMP = SELECT( JE ) .OR. SELECT( JE+1 )
ELSE
ILCOMP = SELECT( JE )
END IF
IF( .NOT.ILCOMP )
$ GO TO 220
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Decide if (a) singular pencil, (b) real eigenvalue, or
</span><span class="comment">*</span><span class="comment"> (c) complex eigenvalue.
</span><span class="comment">*</span><span class="comment">
</span> IF( .NOT.ILCPLX ) THEN
IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
$ ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Singular matrix pencil -- return unit eigenvector
</span><span class="comment">*</span><span class="comment">
</span> IEIG = IEIG + 1
DO 60 JR = 1, N
VL( JR, IEIG ) = ZERO
60 CONTINUE
VL( IEIG, IEIG ) = ONE
GO TO 220
END IF
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Clear vector
</span><span class="comment">*</span><span class="comment">
</span> DO 70 JR = 1, NW*N
WORK( 2*N+JR ) = ZERO
70 CONTINUE
<span class="comment">*</span><span class="comment"> T
</span><span class="comment">*</span><span class="comment"> Compute coefficients in ( a A - b B ) y = 0
</span><span class="comment">*</span><span class="comment"> a is ACOEF
</span><span class="comment">*</span><span class="comment"> b is BCOEFR + i*BCOEFI
</span><span class="comment">*</span><span class="comment">
</span> IF( .NOT.ILCPLX ) THEN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Real eigenvalue
</span><span class="comment">*</span><span class="comment">
</span> TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
$ ABS( P( JE, JE ) )*BSCALE, SAFMIN )
SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
SBETA = ( TEMP*P( JE, JE ) )*BSCALE
ACOEF = SBETA*ASCALE
BCOEFR = SALFAR*BSCALE
BCOEFI = ZERO
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Scale to avoid underflow
</span><span class="comment">*</span><span class="comment">
</span> SCALE = ONE
LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
$ SMALL
IF( LSA )
$ SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
IF( LSB )
$ SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
$ MIN( BNORM, BIG ) )
IF( LSA .OR. LSB ) THEN
SCALE = MIN( SCALE, ONE /
$ ( SAFMIN*MAX( ONE, ABS( ACOEF ),
$ ABS( BCOEFR ) ) ) )
IF( LSA ) THEN
ACOEF = ASCALE*( SCALE*SBETA )
ELSE
ACOEF = SCALE*ACOEF
END IF
IF( LSB ) THEN
BCOEFR = BSCALE*( SCALE*SALFAR )
ELSE
BCOEFR = SCALE*BCOEFR
END IF
END IF
ACOEFA = ABS( ACOEF )
BCOEFA = ABS( BCOEFR )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> First component is 1
</span><span class="comment">*</span><span class="comment">
</span> WORK( 2*N+JE ) = ONE
XMAX = ONE
ELSE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Complex eigenvalue
</span><span class="comment">*</span><span class="comment">
</span> CALL <a name="DLAG2.521"></a><a href="dlag2.f.html#DLAG2.1">DLAG2</a>( S( JE, JE ), LDS, P( JE, JE ), LDP,
$ SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
$ BCOEFI )
BCOEFI = -BCOEFI
IF( BCOEFI.EQ.ZERO ) THEN
INFO = JE
RETURN
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Scale to avoid over/underflow
</span><span class="comment">*</span><span class="comment">
</span> ACOEFA = ABS( ACOEF )
BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
SCALE = ONE
IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
$ SCALE = ( SAFMIN / ULP ) / ACOEFA
IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
$ SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
IF( SAFMIN*ACOEFA.GT.ASCALE )
$ SCALE = ASCALE / ( SAFMIN*ACOEFA )
IF( SAFMIN*BCOEFA.GT.BSCALE )
$ SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
IF( SCALE.NE.ONE ) THEN
ACOEF = SCALE*ACOEF
ACOEFA = ABS( ACOEF )
BCOEFR = SCALE*BCOEFR
BCOEFI = SCALE*BCOEFI
BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Compute first two components of eigenvector
</span><span class="comment">*</span><span class="comment">
</span> TEMP = ACOEF*S( JE+1, JE )
TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
TEMP2I = -BCOEFI*P( JE, JE )
IF( ABS( TEMP ).GT.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
WORK( 2*N+JE ) = ONE
WORK( 3*N+JE ) = ZERO
WORK( 2*N+JE+1 ) = -TEMP2R / TEMP
WORK( 3*N+JE+1 ) = -TEMP2I / TEMP
ELSE
WORK( 2*N+JE+1 ) = ONE
WORK( 3*N+JE+1 ) = ZERO
TEMP = ACOEF*S( JE, JE+1 )
WORK( 2*N+JE ) = ( BCOEFR*P( JE+1, JE+1 )-ACOEF*
$ S( JE+1, JE+1 ) ) / TEMP
WORK( 3*N+JE ) = BCOEFI*P( JE+1, JE+1 ) / TEMP
END IF
XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
$ ABS( WORK( 2*N+JE+1 ) )+ABS( WORK( 3*N+JE+1 ) ) )
END IF
<span class="comment">*</span><span class="comment">
</span> DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> T
</span><span class="comment">*</span><span class="comment"> Triangular solve of (a A - b B) y = 0
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> T
</span><span class="comment">*</span><span class="comment"> (rowwise in (a A - b B) , or columnwise in (a A - b B) )
</span><span class="comment">*</span><span class="comment">
</span> IL2BY2 = .FALSE.
<span class="comment">*</span><span class="comment">
</span> DO 160 J = JE + NW, N
IF( IL2BY2 ) THEN
IL2BY2 = .FALSE.
GO TO 160
END IF
<span class="comment">*</span><span class="comment">
</span> NA = 1
BDIAG( 1 ) = P( J, J )
IF( J.LT.N ) THEN
IF( S( J+1, J ).NE.ZERO ) THEN
IL2BY2 = .TRUE.
BDIAG( 2 ) = P( J+1, J+1 )
NA = 2
END IF
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Check whether scaling is necessary for dot products
</span><span class="comment">*</span><span class="comment">
</span> XSCALE = ONE / MAX( ONE, XMAX )
TEMP = MAX( WORK( J ), WORK( N+J ),
$ ACOEFA*WORK( J )+BCOEFA*WORK( N+J ) )
IF( IL2BY2 )
$ TEMP = MAX( TEMP, WORK( J+1 ), WORK( N+J+1 ),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?