Cloned library LAPACK-3.11.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

233 lines
5.9 KiB

*> \brief \b DSTECH
*
* =========== DOCUMENTATION ===========
*
* Online html documentation available at
* http://www.netlib.org/lapack/explore-html/
*
* Definition:
* ===========
*
* SUBROUTINE DSTECH( N, A, B, EIG, TOL, WORK, INFO )
*
* .. Scalar Arguments ..
* INTEGER INFO, N
* DOUBLE PRECISION TOL
* ..
* .. Array Arguments ..
* DOUBLE PRECISION A( * ), B( * ), EIG( * ), WORK( * )
* ..
*
*
*> \par Purpose:
* =============
*>
*> \verbatim
*>
*> Let T be the tridiagonal matrix with diagonal entries A(1) ,...,
*> A(N) and offdiagonal entries B(1) ,..., B(N-1)). DSTECH checks to
*> see if EIG(1) ,..., EIG(N) are indeed accurate eigenvalues of T.
*> It does this by expanding each EIG(I) into an interval
*> [SVD(I) - EPS, SVD(I) + EPS], merging overlapping intervals if
*> any, and using Sturm sequences to count and verify whether each
*> resulting interval has the correct number of eigenvalues (using
*> DSTECT). Here EPS = TOL*MAZHEPS*MAXEIG, where MACHEPS is the
*> machine precision and MAXEIG is the absolute value of the largest
*> eigenvalue. If each interval contains the correct number of
*> eigenvalues, INFO = 0 is returned, otherwise INFO is the index of
*> the first eigenvalue in the first bad interval.
*> \endverbatim
*
* Arguments:
* ==========
*
*> \param[in] N
*> \verbatim
*> N is INTEGER
*> The dimension of the tridiagonal matrix T.
*> \endverbatim
*>
*> \param[in] A
*> \verbatim
*> A is DOUBLE PRECISION array, dimension (N)
*> The diagonal entries of the tridiagonal matrix T.
*> \endverbatim
*>
*> \param[in] B
*> \verbatim
*> B is DOUBLE PRECISION array, dimension (N-1)
*> The offdiagonal entries of the tridiagonal matrix T.
*> \endverbatim
*>
*> \param[in] EIG
*> \verbatim
*> EIG is DOUBLE PRECISION array, dimension (N)
*> The purported eigenvalues to be checked.
*> \endverbatim
*>
*> \param[in] TOL
*> \verbatim
*> TOL is DOUBLE PRECISION
*> Error tolerance for checking, a multiple of the
*> machine precision.
*> \endverbatim
*>
*> \param[out] WORK
*> \verbatim
*> WORK is DOUBLE PRECISION array, dimension (N)
*> \endverbatim
*>
*> \param[out] INFO
*> \verbatim
*> INFO is INTEGER
*> 0 if the eigenvalues are all correct (to within
*> 1 +- TOL*MAZHEPS*MAXEIG)
*> >0 if the interval containing the INFO-th eigenvalue
*> contains the incorrect number of eigenvalues.
*> \endverbatim
*
* Authors:
* ========
*
*> \author Univ. of Tennessee
*> \author Univ. of California Berkeley
*> \author Univ. of Colorado Denver
*> \author NAG Ltd.
*
*> \ingroup double_eig
*
* =====================================================================
SUBROUTINE DSTECH( N, A, B, EIG, TOL, WORK, INFO )
*
* -- LAPACK test routine --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
*
* .. Scalar Arguments ..
INTEGER INFO, N
DOUBLE PRECISION TOL
* ..
* .. Array Arguments ..
DOUBLE PRECISION A( * ), B( * ), EIG( * ), WORK( * )
* ..
*
* =====================================================================
*
* .. Parameters ..
DOUBLE PRECISION ZERO
PARAMETER ( ZERO = 0.0D0 )
* ..
* .. Local Scalars ..
INTEGER BPNT, COUNT, I, ISUB, J, NUML, NUMU, TPNT
DOUBLE PRECISION EMIN, EPS, LOWER, MX, TUPPR, UNFLEP, UPPER
* ..
* .. External Functions ..
DOUBLE PRECISION DLAMCH
EXTERNAL DLAMCH
* ..
* .. External Subroutines ..
EXTERNAL DSTECT
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, MAX
* ..
* .. Executable Statements ..
*
* Check input parameters
*
INFO = 0
IF( N.EQ.0 )
$ RETURN
IF( N.LT.0 ) THEN
INFO = -1
RETURN
END IF
IF( TOL.LT.ZERO ) THEN
INFO = -5
RETURN
END IF
*
* Get machine constants
*
EPS = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
UNFLEP = DLAMCH( 'Safe minimum' ) / EPS
EPS = TOL*EPS
*
* Compute maximum absolute eigenvalue, error tolerance
*
MX = ABS( EIG( 1 ) )
DO 10 I = 2, N
MX = MAX( MX, ABS( EIG( I ) ) )
10 CONTINUE
EPS = MAX( EPS*MX, UNFLEP )
*
* Sort eigenvalues from EIG into WORK
*
DO 20 I = 1, N
WORK( I ) = EIG( I )
20 CONTINUE
DO 40 I = 1, N - 1
ISUB = 1
EMIN = WORK( 1 )
DO 30 J = 2, N + 1 - I
IF( WORK( J ).LT.EMIN ) THEN
ISUB = J
EMIN = WORK( J )
END IF
30 CONTINUE
IF( ISUB.NE.N+1-I ) THEN
WORK( ISUB ) = WORK( N+1-I )
WORK( N+1-I ) = EMIN
END IF
40 CONTINUE
*
* TPNT points to singular value at right endpoint of interval
* BPNT points to singular value at left endpoint of interval
*
TPNT = 1
BPNT = 1
*
* Begin loop over all intervals
*
50 CONTINUE
UPPER = WORK( TPNT ) + EPS
LOWER = WORK( BPNT ) - EPS
*
* Begin loop merging overlapping intervals
*
60 CONTINUE
IF( BPNT.EQ.N )
$ GO TO 70
TUPPR = WORK( BPNT+1 ) + EPS
IF( TUPPR.LT.LOWER )
$ GO TO 70
*
* Merge
*
BPNT = BPNT + 1
LOWER = WORK( BPNT ) - EPS
GO TO 60
70 CONTINUE
*
* Count singular values in interval [ LOWER, UPPER ]
*
CALL DSTECT( N, A, B, LOWER, NUML )
CALL DSTECT( N, A, B, UPPER, NUMU )
COUNT = NUMU - NUML
IF( COUNT.NE.BPNT-TPNT+1 ) THEN
*
* Wrong number of singular values in interval
*
INFO = TPNT
GO TO 80
END IF
TPNT = BPNT + 1
BPNT = TPNT
IF( TPNT.LE.N )
$ GO TO 50
80 CONTINUE
RETURN
*
* End of DSTECH
*
END