zhpevx.f.html
来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 413 行 · 第 1/2 页
HTML
413 行
IF( VALEIG ) THEN
IF( N.GT.0 .AND. VU.LE.VL )
$ INFO = -7
ELSE IF( INDEIG ) THEN
IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
INFO = -8
ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
INFO = -9
END IF
END IF
END IF
IF( INFO.EQ.0 ) THEN
IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) )
$ INFO = -14
END IF
<span class="comment">*</span><span class="comment">
</span> IF( INFO.NE.0 ) THEN
CALL <a name="XERBLA.206"></a><a href="xerbla.f.html#XERBLA.1">XERBLA</a>( <span class="string">'<a name="ZHPEVX.206"></a><a href="zhpevx.f.html#ZHPEVX.1">ZHPEVX</a>'</span>, -INFO )
RETURN
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Quick return if possible
</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 ) = AP( 1 )
ELSE
IF( VL.LT.DBLE( AP( 1 ) ) .AND. VU.GE.DBLE( AP( 1 ) ) ) THEN
M = 1
W( 1 ) = AP( 1 )
END IF
END IF
IF( WANTZ )
$ Z( 1, 1 ) = CONE
RETURN
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Get machine constants.
</span><span class="comment">*</span><span class="comment">
</span> SAFMIN = <a name="DLAMCH.233"></a><a href="dlamch.f.html#DLAMCH.1">DLAMCH</a>( <span class="string">'Safe minimum'</span> )
EPS = <a name="DLAMCH.234"></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><span class="comment">*</span><span class="comment"> Scale matrix to allowable range, if necessary.
</span><span class="comment">*</span><span class="comment">
</span> ISCALE = 0
ABSTLL = ABSTOL
IF( VALEIG ) THEN
VLL = VL
VUU = VU
ELSE
VLL = ZERO
VUU = ZERO
END IF
ANRM = <a name="ZLANHP.251"></a><a href="zlanhp.f.html#ZLANHP.1">ZLANHP</a>( <span class="string">'M'</span>, UPLO, N, AP, RWORK )
IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
ISCALE = 1
SIGMA = RMIN / ANRM
ELSE IF( ANRM.GT.RMAX ) THEN
ISCALE = 1
SIGMA = RMAX / ANRM
END IF
IF( ISCALE.EQ.1 ) THEN
CALL ZDSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )
IF( ABSTOL.GT.0 )
$ ABSTLL = ABSTOL*SIGMA
IF( VALEIG ) THEN
VLL = VL*SIGMA
VUU = VU*SIGMA
END IF
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Call <a name="ZHPTRD.269"></a><a href="zhptrd.f.html#ZHPTRD.1">ZHPTRD</a> to reduce Hermitian packed matrix to tridiagonal form.
</span><span class="comment">*</span><span class="comment">
</span> INDD = 1
INDE = INDD + N
INDRWK = INDE + N
INDTAU = 1
INDWRK = INDTAU + N
CALL <a name="ZHPTRD.276"></a><a href="zhptrd.f.html#ZHPTRD.1">ZHPTRD</a>( UPLO, N, AP, RWORK( INDD ), RWORK( INDE ),
$ WORK( INDTAU ), IINFO )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> If all eigenvalues are desired and ABSTOL is less than or equal
</span><span class="comment">*</span><span class="comment"> to zero, then call <a name="DSTERF.280"></a><a href="dsterf.f.html#DSTERF.1">DSTERF</a> or <a name="ZUPGTR.280"></a><a href="zupgtr.f.html#ZUPGTR.1">ZUPGTR</a> and <a name="ZSTEQR.280"></a><a href="zsteqr.f.html#ZSTEQR.1">ZSTEQR</a>. If this fails
</span><span class="comment">*</span><span class="comment"> for some eigenvalue, then try <a name="DSTEBZ.281"></a><a href="dstebz.f.html#DSTEBZ.1">DSTEBZ</a>.
</span><span class="comment">*</span><span class="comment">
</span> TEST = .FALSE.
IF (INDEIG) THEN
IF (IL.EQ.1 .AND. IU.EQ.N) THEN
TEST = .TRUE.
END IF
END IF
IF ((ALLEIG .OR. TEST) .AND. (ABSTOL.LE.ZERO)) THEN
CALL DCOPY( N, RWORK( INDD ), 1, W, 1 )
INDEE = INDRWK + 2*N
IF( .NOT.WANTZ ) THEN
CALL DCOPY( N-1, RWORK( INDE ), 1, RWORK( INDEE ), 1 )
CALL <a name="DSTERF.294"></a><a href="dsterf.f.html#DSTERF.1">DSTERF</a>( N, W, RWORK( INDEE ), INFO )
ELSE
CALL <a name="ZUPGTR.296"></a><a href="zupgtr.f.html#ZUPGTR.1">ZUPGTR</a>( UPLO, N, AP, WORK( INDTAU ), Z, LDZ,
$ WORK( INDWRK ), IINFO )
CALL DCOPY( N-1, RWORK( INDE ), 1, RWORK( INDEE ), 1 )
CALL <a name="ZSTEQR.299"></a><a href="zsteqr.f.html#ZSTEQR.1">ZSTEQR</a>( JOBZ, N, W, RWORK( INDEE ), Z, LDZ,
$ RWORK( INDRWK ), INFO )
IF( INFO.EQ.0 ) THEN
DO 10 I = 1, N
IFAIL( I ) = 0
10 CONTINUE
END IF
END IF
IF( INFO.EQ.0 ) THEN
M = N
GO TO 20
END IF
INFO = 0
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Otherwise, call <a name="DSTEBZ.314"></a><a href="dstebz.f.html#DSTEBZ.1">DSTEBZ</a> and, if eigenvectors are desired, <a name="ZSTEIN.314"></a><a href="zstein.f.html#ZSTEIN.1">ZSTEIN</a>.
</span><span class="comment">*</span><span class="comment">
</span> IF( WANTZ ) THEN
ORDER = <span class="string">'B'</span>
ELSE
ORDER = <span class="string">'E'</span>
END IF
INDIBL = 1
INDISP = INDIBL + N
INDIWK = INDISP + N
CALL <a name="DSTEBZ.324"></a><a href="dstebz.f.html#DSTEBZ.1">DSTEBZ</a>( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,
$ RWORK( INDD ), RWORK( INDE ), M, NSPLIT, W,
$ IWORK( INDIBL ), IWORK( INDISP ), RWORK( INDRWK ),
$ IWORK( INDIWK ), INFO )
<span class="comment">*</span><span class="comment">
</span> IF( WANTZ ) THEN
CALL <a name="ZSTEIN.330"></a><a href="zstein.f.html#ZSTEIN.1">ZSTEIN</a>( N, RWORK( INDD ), RWORK( INDE ), M, W,
$ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,
$ RWORK( INDRWK ), IWORK( INDIWK ), IFAIL, INFO )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> Apply unitary matrix used in reduction to tridiagonal
</span><span class="comment">*</span><span class="comment"> form to eigenvectors returned by <a name="ZSTEIN.335"></a><a href="zstein.f.html#ZSTEIN.1">ZSTEIN</a>.
</span><span class="comment">*</span><span class="comment">
</span> INDWRK = INDTAU + N
CALL <a name="ZUPMTR.338"></a><a href="zupmtr.f.html#ZUPMTR.1">ZUPMTR</a>( <span class="string">'L'</span>, UPLO, <span class="string">'N'</span>, N, M, AP, WORK( INDTAU ), Z, LDZ,
$ WORK( INDWRK ), INFO )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> If matrix was scaled, then rescale eigenvalues appropriately.
</span><span class="comment">*</span><span class="comment">
</span> 20 CONTINUE
IF( ISCALE.EQ.1 ) THEN
IF( INFO.EQ.0 ) THEN
IMAX = M
ELSE
IMAX = INFO - 1
END IF
CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> If eigenvalues are not in order, then sort them, along with
</span><span class="comment">*</span><span class="comment"> eigenvectors.
</span><span class="comment">*</span><span class="comment">
</span> IF( WANTZ ) THEN
DO 40 J = 1, M - 1
I = 0
TMP1 = W( J )
DO 30 JJ = J + 1, M
IF( W( JJ ).LT.TMP1 ) THEN
I = JJ
TMP1 = W( JJ )
END IF
30 CONTINUE
<span class="comment">*</span><span class="comment">
</span> IF( I.NE.0 ) THEN
ITMP1 = IWORK( INDIBL+I-1 )
W( I ) = W( J )
IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )
W( J ) = TMP1
IWORK( INDIBL+J-1 ) = ITMP1
CALL ZSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
IF( INFO.NE.0 ) THEN
ITMP1 = IFAIL( I )
IFAIL( I ) = IFAIL( J )
IFAIL( J ) = ITMP1
END IF
END IF
40 CONTINUE
END IF
<span class="comment">*</span><span class="comment">
</span> RETURN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment"> End of <a name="ZHPEVX.386"></a><a href="zhpevx.f.html#ZHPEVX.1">ZHPEVX</a>
</span><span class="comment">*</span><span class="comment">
</span> END
</pre>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?