001:       SUBROUTINE DLARRC( JOBT, N, VL, VU, D, E, PIVMIN,
002:      $                            EIGCNT, LCNT, RCNT, INFO )
003: *
004: *  -- LAPACK auxiliary routine (version 3.2) --
005: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
006: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
007: *     November 2006
008: *
009: *     .. Scalar Arguments ..
010:       CHARACTER          JOBT
011:       INTEGER            EIGCNT, INFO, LCNT, N, RCNT
012:       DOUBLE PRECISION   PIVMIN, VL, VU
013: *     ..
014: *     .. Array Arguments ..
015:       DOUBLE PRECISION   D( * ), E( * )
016: *     ..
017: *
018: *  Purpose
019: *  =======
020: *
021: *  Find the number of eigenvalues of the symmetric tridiagonal matrix T
022: *  that are in the interval (VL,VU] if JOBT = 'T', and of L D L^T
023: *  if JOBT = 'L'.
024: *
025: *  Arguments
026: *  =========
027: *
028: *  JOBT    (input) CHARACTER*1
029: *          = 'T':  Compute Sturm count for matrix T.
030: *          = 'L':  Compute Sturm count for matrix L D L^T.
031: *
032: *  N       (input) INTEGER
033: *          The order of the matrix. N > 0.
034: *
035: *  VL      (input) DOUBLE PRECISION
036: *  VU      (input) DOUBLE PRECISION
037: *          The lower and upper bounds for the eigenvalues.
038: *
039: *  D       (input) DOUBLE PRECISION array, dimension (N)
040: *          JOBT = 'T': The N diagonal elements of the tridiagonal matrix T.
041: *          JOBT = 'L': The N diagonal elements of the diagonal matrix D.
042: *
043: *  E       (input) DOUBLE PRECISION array, dimension (N)
044: *          JOBT = 'T': The N-1 offdiagonal elements of the matrix T.
045: *          JOBT = 'L': The N-1 offdiagonal elements of the matrix L.
046: *
047: *  PIVMIN  (input) DOUBLE PRECISION
048: *          The minimum pivot in the Sturm sequence for T.
049: *
050: *  EIGCNT  (output) INTEGER
051: *          The number of eigenvalues of the symmetric tridiagonal matrix T
052: *          that are in the interval (VL,VU]
053: *
054: *  LCNT    (output) INTEGER
055: *  RCNT    (output) INTEGER
056: *          The left and right negcounts of the interval.
057: *
058: *  INFO    (output) INTEGER
059: *
060: *  Further Details
061: *  ===============
062: *
063: *  Based on contributions by
064: *     Beresford Parlett, University of California, Berkeley, USA
065: *     Jim Demmel, University of California, Berkeley, USA
066: *     Inderjit Dhillon, University of Texas, Austin, USA
067: *     Osni Marques, LBNL/NERSC, USA
068: *     Christof Voemel, University of California, Berkeley, USA
069: *
070: *  =====================================================================
071: *
072: *     .. Parameters ..
073:       DOUBLE PRECISION   ZERO
074:       PARAMETER          ( ZERO = 0.0D0 )
075: *     ..
076: *     .. Local Scalars ..
077:       INTEGER            I
078:       LOGICAL            MATT
079:       DOUBLE PRECISION   LPIVOT, RPIVOT, SL, SU, TMP, TMP2
080: 
081: *     ..
082: *     .. External Functions ..
083:       LOGICAL            LSAME
084:       EXTERNAL           LSAME
085: *     ..
086: *     .. Executable Statements ..
087: *
088:       INFO = 0
089:       LCNT = 0
090:       RCNT = 0
091:       EIGCNT = 0
092:       MATT = LSAME( JOBT, 'T' )
093: 
094: 
095:       IF (MATT) THEN
096: *        Sturm sequence count on T
097:          LPIVOT = D( 1 ) - VL
098:          RPIVOT = D( 1 ) - VU
099:          IF( LPIVOT.LE.ZERO ) THEN
100:             LCNT = LCNT + 1
101:          ENDIF
102:          IF( RPIVOT.LE.ZERO ) THEN
103:             RCNT = RCNT + 1
104:          ENDIF
105:          DO 10 I = 1, N-1
106:             TMP = E(I)**2
107:             LPIVOT = ( D( I+1 )-VL ) - TMP/LPIVOT
108:             RPIVOT = ( D( I+1 )-VU ) - TMP/RPIVOT
109:             IF( LPIVOT.LE.ZERO ) THEN
110:                LCNT = LCNT + 1
111:             ENDIF
112:             IF( RPIVOT.LE.ZERO ) THEN
113:                RCNT = RCNT + 1
114:             ENDIF
115:  10      CONTINUE
116:       ELSE
117: *        Sturm sequence count on L D L^T
118:          SL = -VL
119:          SU = -VU
120:          DO 20 I = 1, N - 1
121:             LPIVOT = D( I ) + SL
122:             RPIVOT = D( I ) + SU
123:             IF( LPIVOT.LE.ZERO ) THEN
124:                LCNT = LCNT + 1
125:             ENDIF
126:             IF( RPIVOT.LE.ZERO ) THEN
127:                RCNT = RCNT + 1
128:             ENDIF
129:             TMP = E(I) * D(I) * E(I)
130: *
131:             TMP2 = TMP / LPIVOT
132:             IF( TMP2.EQ.ZERO ) THEN
133:                SL =  TMP - VL
134:             ELSE
135:                SL = SL*TMP2 - VL
136:             END IF
137: *
138:             TMP2 = TMP / RPIVOT
139:             IF( TMP2.EQ.ZERO ) THEN
140:                SU =  TMP - VU
141:             ELSE
142:                SU = SU*TMP2 - VU
143:             END IF
144:  20      CONTINUE
145:          LPIVOT = D( N ) + SL
146:          RPIVOT = D( N ) + SU
147:          IF( LPIVOT.LE.ZERO ) THEN
148:             LCNT = LCNT + 1
149:          ENDIF
150:          IF( RPIVOT.LE.ZERO ) THEN
151:             RCNT = RCNT + 1
152:          ENDIF
153:       ENDIF
154:       EIGCNT = RCNT - LCNT
155: 
156:       RETURN
157: *
158: *     end of DLARRC
159: *
160:       END
161: