1 *> \brief \b SLANEG computes the Sturm count.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download SLANEG + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slaneg.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slaneg.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slaneg.f">
21 * INTEGER FUNCTION SLANEG( N, D, LLD, SIGMA, PIVMIN, R )
23 * .. Scalar Arguments ..
27 * .. Array Arguments ..
28 * REAL D( * ), LLD( * )
37 *> SLANEG computes the Sturm count, the number of negative pivots
38 *> encountered while factoring tridiagonal T - sigma I = L D L^T.
39 *> This implementation works directly on the factors without forming
40 *> the tridiagonal matrix T. The Sturm count is also the number of
41 *> eigenvalues of T less than sigma.
43 *> This routine is called from SLARRB.
45 *> The current routine does not use the PIVMIN parameter but rather
46 *> requires IEEE-754 propagation of Infinities and NaNs. This
47 *> routine also has no input range restrictions but does require
48 *> default exception handling such that x/0 produces Inf when x is
49 *> non-zero, and Inf/Inf produces NaN. For more information, see:
51 *> Marques, Riedy, and Voemel, "Benefits of IEEE-754 Features in
52 *> Modern Symmetric Tridiagonal Eigensolvers," SIAM Journal on
53 *> Scientific Computing, v28, n5, 2006. DOI 10.1137/050641624
54 *> (Tech report version in LAWN 172 with the same title.)
63 *> The order of the matrix.
68 *> D is REAL array, dimension (N)
69 *> The N diagonal elements of the diagonal matrix D.
74 *> LLD is REAL array, dimension (N-1)
75 *> The (N-1) elements L(i)*L(i)*D(i).
81 *> Shift amount in T - sigma I = L D L^T.
87 *> The minimum pivot in the Sturm sequence. May be used
88 *> when zero pivots are encountered on non-IEEE-754
95 *> The twist index for the twisted factorization that is used
102 *> \author Univ. of Tennessee
103 *> \author Univ. of California Berkeley
104 *> \author Univ. of Colorado Denver
107 *> \date September 2012
109 *> \ingroup OTHERauxiliary
111 *> \par Contributors:
114 *> Osni Marques, LBNL/NERSC, USA \n
115 *> Christof Voemel, University of California, Berkeley, USA \n
116 *> Jason Riedy, University of California, Berkeley, USA \n
118 * =====================================================================
119 INTEGER FUNCTION SLANEG( N, D, LLD, SIGMA, PIVMIN, R )
121 * -- LAPACK auxiliary routine (version 3.4.2) --
122 * -- LAPACK is a software package provided by Univ. of Tennessee, --
123 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
126 * .. Scalar Arguments ..
130 * .. Array Arguments ..
131 REAL D( * ), LLD( * )
134 * =====================================================================
138 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
139 * Some architectures propagate Infinities and NaNs very slowly, so
140 * the code computes counts in BLKLEN chunks. Then a NaN can
141 * propagate at most BLKLEN columns before being detected. This is
142 * not a general tuning parameter; it needs only to be just large
143 * enough that the overhead is tiny in common cases.
145 PARAMETER ( BLKLEN = 128 )
147 * .. Local Scalars ..
148 INTEGER BJ, J, NEG1, NEG2, NEGCNT
149 REAL BSAV, DMINUS, DPLUS, GAMMA, P, T, TMP
152 * .. Intrinsic Functions ..
155 * .. External Functions ..
159 * .. Executable Statements ..
163 * I) upper part: L D L^T - SIGMA I = L+ D+ L+^T
165 DO 210 BJ = 1, R-1, BLKLEN
168 DO 21 J = BJ, MIN(BJ+BLKLEN-1, R-1)
170 IF( DPLUS.LT.ZERO ) NEG1 = NEG1 + 1
172 T = TMP * LLD( J ) - SIGMA
175 * Run a slower version of the above loop if a NaN is detected.
176 * A NaN should occur only with a zero pivot after an infinite
177 * pivot. In that case, substituting 1 for T/DPLUS is the
182 DO 22 J = BJ, MIN(BJ+BLKLEN-1, R-1)
184 IF( DPLUS.LT.ZERO ) NEG1 = NEG1 + 1
186 IF (SISNAN(TMP)) TMP = ONE
187 T = TMP * LLD(J) - SIGMA
190 NEGCNT = NEGCNT + NEG1
193 * II) lower part: L D L^T - SIGMA I = U- D- U-^T
195 DO 230 BJ = N-1, R, -BLKLEN
198 DO 23 J = BJ, MAX(BJ-BLKLEN+1, R), -1
199 DMINUS = LLD( J ) + P
200 IF( DMINUS.LT.ZERO ) NEG2 = NEG2 + 1
202 P = TMP * D( J ) - SIGMA
205 * As above, run a slower version that substitutes 1 for Inf/Inf.
210 DO 24 J = BJ, MAX(BJ-BLKLEN+1, R), -1
211 DMINUS = LLD( J ) + P
212 IF( DMINUS.LT.ZERO ) NEG2 = NEG2 + 1
214 IF (SISNAN(TMP)) TMP = ONE
215 P = TMP * D(J) - SIGMA
218 NEGCNT = NEGCNT + NEG2
222 * T was shifted by SIGMA initially.
223 GAMMA = (T + SIGMA) + P
224 IF( GAMMA.LT.ZERO ) NEGCNT = NEGCNT+1