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