zstemr.f.html
来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 689 行 · 第 1/4 页
HTML
689 行
</span><span class="comment">*</span><span class="comment"> Get machine constants.
</span><span class="comment">*</span><span class="comment">
</span> SAFMIN = <a name="DLAMCH.330"></a><a href="dlamch.f.html#DLAMCH.1">DLAMCH</a>( <span class="string">'Safe minimum'</span> )
EPS = <a name="DLAMCH.331"></a><a href="dlamch.f.html#DLAMCH.1">DLAMCH</a>( <span class="string">'Precision'</span> )
SMLNUM = SAFMIN / EPS
BIGNUM = ONE / SMLNUM
RMIN = SQRT( SMLNUM )
RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )
<span class="comment">*</span><span class="comment">
</span> IF( INFO.EQ.0 ) THEN
WORK( 1 ) = LWMIN
IWORK( 1 ) = LIWMIN
<span class="comment">*</span><span class="comment">
</span> IF( WANTZ .AND. ALLEIG ) THEN
NZCMIN = N
ELSE IF( WANTZ .AND. VALEIG ) THEN
CALL <a name="DLARRC.344"></a><a href="dlarrc.f.html#DLARRC.1">DLARRC</a>( <span class="string">'T'</span>, N, VL, VU, D, E, SAFMIN,
$ NZCMIN, ITMP, ITMP2, INFO )
ELSE IF( WANTZ .AND. INDEIG ) THEN
NZCMIN = IIU-IIL+1
ELSE
<span class="comment">*</span><span class="comment"> WANTZ .EQ. FALSE.
</span> NZCMIN = 0
ENDIF
IF( ZQUERY .AND. INFO.EQ.0 ) THEN
Z( 1,1 ) = NZCMIN
ELSE IF( NZC.LT.NZCMIN .AND. .NOT.ZQUERY ) THEN
INFO = -14
END IF
END IF
IF( INFO.NE.0 ) THEN
<span class="comment">*</span><span class="comment">
</span> CALL <a name="XERBLA.361"></a><a href="xerbla.f.html#XERBLA.1">XERBLA</a>( <span class="string">'<a name="ZSTEMR.361"></a><a href="zstemr.f.html#ZSTEMR.1">ZSTEMR</a>'</span>, -INFO )
<span class="comment">*</span><span class="comment">
</span> RETURN
ELSE IF( LQUERY .OR. ZQUERY ) THEN
RETURN
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Handle N = 0, 1, and 2 cases immediately
</span><span class="comment">*</span><span class="comment">
</span> M = 0
IF( N.EQ.0 )
$ RETURN
<span class="comment">*</span><span class="comment">
</span> IF( N.EQ.1 ) THEN
IF( ALLEIG .OR. INDEIG ) THEN
M = 1
W( 1 ) = D( 1 )
ELSE
IF( WL.LT.D( 1 ) .AND. WU.GE.D( 1 ) ) THEN
M = 1
W( 1 ) = D( 1 )
END IF
END IF
IF( WANTZ.AND.(.NOT.ZQUERY) ) THEN
Z( 1, 1 ) = ONE
ISUPPZ(1) = 1
ISUPPZ(2) = 1
END IF
RETURN
END IF
<span class="comment">*</span><span class="comment">
</span> IF( N.EQ.2 ) THEN
IF( .NOT.WANTZ ) THEN
CALL <a name="DLAE2.394"></a><a href="dlae2.f.html#DLAE2.1">DLAE2</a>( D(1), E(1), D(2), R1, R2 )
ELSE IF( WANTZ.AND.(.NOT.ZQUERY) ) THEN
CALL <a name="DLAEV2.396"></a><a href="dlaev2.f.html#DLAEV2.1">DLAEV2</a>( D(1), E(1), D(2), R1, R2, CS, SN )
END IF
IF( ALLEIG.OR.
$ (VALEIG.AND.(R2.GT.WL).AND.
$ (R2.LE.WU)).OR.
$ (INDEIG.AND.(IIL.EQ.1)) ) THEN
M = M+1
W( M ) = R2
IF( WANTZ.AND.(.NOT.ZQUERY) ) THEN
Z( 1, M ) = -SN
Z( 2, M ) = CS
<span class="comment">*</span><span class="comment"> Note: At most one of SN and CS can be zero.
</span> IF (SN.NE.ZERO) THEN
IF (CS.NE.ZERO) THEN
ISUPPZ(2*M-1) = 1
ISUPPZ(2*M-1) = 2
ELSE
ISUPPZ(2*M-1) = 1
ISUPPZ(2*M-1) = 1
END IF
ELSE
ISUPPZ(2*M-1) = 2
ISUPPZ(2*M) = 2
END IF
ENDIF
ENDIF
IF( ALLEIG.OR.
$ (VALEIG.AND.(R1.GT.WL).AND.
$ (R1.LE.WU)).OR.
$ (INDEIG.AND.(IIU.EQ.2)) ) THEN
M = M+1
W( M ) = R1
IF( WANTZ.AND.(.NOT.ZQUERY) ) THEN
Z( 1, M ) = CS
Z( 2, M ) = SN
<span class="comment">*</span><span class="comment"> Note: At most one of SN and CS can be zero.
</span> IF (SN.NE.ZERO) THEN
IF (CS.NE.ZERO) THEN
ISUPPZ(2*M-1) = 1
ISUPPZ(2*M-1) = 2
ELSE
ISUPPZ(2*M-1) = 1
ISUPPZ(2*M-1) = 1
END IF
ELSE
ISUPPZ(2*M-1) = 2
ISUPPZ(2*M) = 2
END IF
ENDIF
ENDIF
RETURN
END IF
<span class="comment">*</span><span class="comment"> Continue with general N
</span>
INDGRS = 1
INDERR = 2*N + 1
INDGP = 3*N + 1
INDD = 4*N + 1
INDE2 = 5*N + 1
INDWRK = 6*N + 1
<span class="comment">*</span><span class="comment">
</span> IINSPL = 1
IINDBL = N + 1
IINDW = 2*N + 1
IINDWK = 3*N + 1
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Scale matrix to allowable range, if necessary.
</span><span class="comment">*</span><span class="comment"> The allowable range is related to the PIVMIN parameter; see the
</span><span class="comment">*</span><span class="comment"> comments in <a name="DLARRD.465"></a><a href="dlarrd.f.html#DLARRD.1">DLARRD</a>. The preference for scaling small values
</span><span class="comment">*</span><span class="comment"> up is heuristic; we expect users' matrices not to be close to the
</span><span class="comment">*</span><span class="comment"> RMAX threshold.
</span><span class="comment">*</span><span class="comment">
</span> SCALE = ONE
TNRM = <a name="DLANST.470"></a><a href="dlanst.f.html#DLANST.1">DLANST</a>( <span class="string">'M'</span>, N, D, E )
IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THEN
SCALE = RMIN / TNRM
ELSE IF( TNRM.GT.RMAX ) THEN
SCALE = RMAX / TNRM
END IF
IF( SCALE.NE.ONE ) THEN
CALL DSCAL( N, SCALE, D, 1 )
CALL DSCAL( N-1, SCALE, E, 1 )
TNRM = TNRM*SCALE
IF( VALEIG ) THEN
<span class="comment">*</span><span class="comment"> If eigenvalues in interval have to be found,
</span><span class="comment">*</span><span class="comment"> scale (WL, WU] accordingly
</span> WL = WL*SCALE
WU = WU*SCALE
ENDIF
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Compute the desired eigenvalues of the tridiagonal after splitting
</span><span class="comment">*</span><span class="comment"> into smaller subblocks if the corresponding off-diagonal elements
</span><span class="comment">*</span><span class="comment"> are small
</span><span class="comment">*</span><span class="comment"> THRESH is the splitting parameter for <a name="DLARRE.491"></a><a href="dlarre.f.html#DLARRE.1">DLARRE</a>
</span><span class="comment">*</span><span class="comment"> A negative THRESH forces the old splitting criterion based on the
</span><span class="comment">*</span><span class="comment"> size of the off-diagonal. A positive THRESH switches to splitting
</span><span class="comment">*</span><span class="comment"> which preserves relative accuracy.
</span><span class="comment">*</span><span class="comment">
</span> IF( TRYRAC ) THEN
<span class="comment">*</span><span class="comment"> Test whether the matrix warrants the more expensive relative approach.
</span> CALL <a name="DLARRR.498"></a><a href="dlarrr.f.html#DLARRR.1">DLARRR</a>( N, D, E, IINFO )
ELSE
<span class="comment">*</span><span class="comment"> The user does not care about relative accurately eigenvalues
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?