1 *> \brief \b DLARRF finds a new relatively robust representation such that at least one of the eigenvalues is relatively isolated.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DLARRF + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrf.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrf.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrf.f">
21 * SUBROUTINE DLARRF( N, D, L, LD, CLSTRT, CLEND,
23 * SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,
24 * DPLUS, LPLUS, WORK, INFO )
26 * .. Scalar Arguments ..
27 * INTEGER CLSTRT, CLEND, INFO, N
28 * DOUBLE PRECISION CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM
30 * .. Array Arguments ..
31 * DOUBLE PRECISION D( * ), DPLUS( * ), L( * ), LD( * ),
32 * $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )
41 *> Given the initial representation L D L^T and its cluster of close
42 *> eigenvalues (in a relative measure), W( CLSTRT ), W( CLSTRT+1 ), ...
43 *> W( CLEND ), DLARRF finds a new relatively robust representation
44 *> L D L^T - SIGMA I = L(+) D(+) L(+)^T such that at least one of the
45 *> eigenvalues of L(+) D(+) L(+)^T is relatively isolated.
54 *> The order of the matrix (subblock, if the matrix split).
59 *> D is DOUBLE PRECISION array, dimension (N)
60 *> The N diagonal elements of the diagonal matrix D.
65 *> L is DOUBLE PRECISION array, dimension (N-1)
66 *> The (N-1) subdiagonal elements of the unit bidiagonal
72 *> LD is DOUBLE PRECISION array, dimension (N-1)
73 *> The (N-1) elements L(i)*D(i).
79 *> The index of the first eigenvalue in the cluster.
85 *> The index of the last eigenvalue in the cluster.
90 *> W is DOUBLE PRECISION array, dimension
91 *> dimension is >= (CLEND-CLSTRT+1)
92 *> The eigenvalue APPROXIMATIONS of L D L^T in ascending order.
93 *> W( CLSTRT ) through W( CLEND ) form the cluster of relatively
97 *> \param[in,out] WGAP
99 *> WGAP is DOUBLE PRECISION array, dimension
100 *> dimension is >= (CLEND-CLSTRT+1)
101 *> The separation from the right neighbor eigenvalue in W.
106 *> WERR is DOUBLE PRECISION array, dimension
107 *> dimension is >= (CLEND-CLSTRT+1)
108 *> WERR contain the semiwidth of the uncertainty
109 *> interval of the corresponding eigenvalue APPROXIMATION in W
114 *> SPDIAM is DOUBLE PRECISION
115 *> estimate of the spectral diameter obtained from the
116 *> Gerschgorin intervals
121 *> CLGAPL is DOUBLE PRECISION
126 *> CLGAPR is DOUBLE PRECISION
127 *> absolute gap on each end of the cluster.
128 *> Set by the calling routine to protect against shifts too close
129 *> to eigenvalues outside the cluster.
134 *> PIVMIN is DOUBLE PRECISION
135 *> The minimum pivot allowed in the Sturm sequence.
140 *> SIGMA is DOUBLE PRECISION
141 *> The shift used to form L(+) D(+) L(+)^T.
146 *> DPLUS is DOUBLE PRECISION array, dimension (N)
147 *> The N diagonal elements of the diagonal matrix D(+).
152 *> LPLUS is DOUBLE PRECISION array, dimension (N-1)
153 *> The first (N-1) elements of LPLUS contain the subdiagonal
154 *> elements of the unit bidiagonal matrix L(+).
159 *> WORK is DOUBLE PRECISION array, dimension (2*N)
166 *> Signals processing OK (=0) or failure (=1)
172 *> \author Univ. of Tennessee
173 *> \author Univ. of California Berkeley
174 *> \author Univ. of Colorado Denver
179 *> \ingroup OTHERauxiliary
181 *> \par Contributors:
184 *> Beresford Parlett, University of California, Berkeley, USA \n
185 *> Jim Demmel, University of California, Berkeley, USA \n
186 *> Inderjit Dhillon, University of Texas, Austin, USA \n
187 *> Osni Marques, LBNL/NERSC, USA \n
188 *> Christof Voemel, University of California, Berkeley, USA
190 * =====================================================================
191 SUBROUTINE DLARRF( N, D, L, LD, CLSTRT, CLEND,
193 $ SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,
194 $ DPLUS, LPLUS, WORK, INFO )
196 * -- LAPACK auxiliary routine (version 3.6.1) --
197 * -- LAPACK is a software package provided by Univ. of Tennessee, --
198 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
201 * .. Scalar Arguments ..
202 INTEGER CLSTRT, CLEND, INFO, N
203 DOUBLE PRECISION CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM
205 * .. Array Arguments ..
206 DOUBLE PRECISION D( * ), DPLUS( * ), L( * ), LD( * ),
207 $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )
210 * =====================================================================
213 DOUBLE PRECISION FOUR, MAXGROWTH1, MAXGROWTH2, ONE, QUART, TWO
214 PARAMETER ( ONE = 1.0D0, TWO = 2.0D0, FOUR = 4.0D0,
217 $ MAXGROWTH2 = 8.D0 )
219 * .. Local Scalars ..
220 LOGICAL DORRR1, FORCER, NOFAIL, SAWNAN1, SAWNAN2, TRYRRR1
221 INTEGER I, INDX, KTRY, KTRYMAX, SLEFT, SRIGHT, SHIFT
222 PARAMETER ( KTRYMAX = 1, SLEFT = 1, SRIGHT = 2 )
223 DOUBLE PRECISION AVGAP, BESTSHIFT, CLWDTH, EPS, FACT, FAIL,
224 $ FAIL2, GROWTHBOUND, LDELTA, LDMAX, LSIGMA,
225 $ MAX1, MAX2, MINGAP, OLDP, PROD, RDELTA, RDMAX,
226 $ RRR1, RRR2, RSIGMA, S, SMLGROWTH, TMP, ZNM2
228 * .. External Functions ..
230 DOUBLE PRECISION DLAMCH
231 EXTERNAL DISNAN, DLAMCH
233 * .. External Subroutines ..
236 * .. Intrinsic Functions ..
239 * .. Executable Statements ..
242 FACT = DBLE(2**KTRYMAX)
243 EPS = DLAMCH( 'Precision' )
248 * Note that we cannot guarantee that for any of the shifts tried,
249 * the factorization has a small or even moderate element growth.
250 * There could be Ritz values at both ends of the cluster and despite
251 * backing off, there are examples where all factorizations tried
252 * (in IEEE mode, allowing zero pivots & infinities) have INFINITE
254 * For this reason, we should use PIVMIN in this subroutine so that at
255 * least the L D L^T factorization exists. It can be checked afterwards
256 * whether the element growth caused bad residuals/orthogonality.
258 * Decide whether the code should accept the best among all
259 * representations despite large element growth or signal INFO=1
260 * Setting NOFAIL to .FALSE. for quick fix for bug 113
264 * Compute the average gap length of the cluster
265 CLWDTH = ABS(W(CLEND)-W(CLSTRT)) + WERR(CLEND) + WERR(CLSTRT)
266 AVGAP = CLWDTH / DBLE(CLEND-CLSTRT)
267 MINGAP = MIN(CLGAPL, CLGAPR)
268 * Initial values for shifts to both ends of cluster
269 LSIGMA = MIN(W( CLSTRT ),W( CLEND )) - WERR( CLSTRT )
270 RSIGMA = MAX(W( CLSTRT ),W( CLEND )) + WERR( CLEND )
272 * Use a small fudge to make sure that we really shift to the outside
273 LSIGMA = LSIGMA - ABS(LSIGMA)* FOUR * EPS
274 RSIGMA = RSIGMA + ABS(RSIGMA)* FOUR * EPS
276 * Compute upper bounds for how much to back off the initial shifts
277 LDMAX = QUART * MINGAP + TWO * PIVMIN
278 RDMAX = QUART * MINGAP + TWO * PIVMIN
280 LDELTA = MAX(AVGAP,WGAP( CLSTRT ))/FACT
281 RDELTA = MAX(AVGAP,WGAP( CLEND-1 ))/FACT
283 * Initialize the record of the best representation found
287 FAIL = DBLE(N-1)*MINGAP/(SPDIAM*EPS)
288 FAIL2 = DBLE(N-1)*MINGAP/(SPDIAM*SQRT(EPS))
291 * while (KTRY <= KTRYMAX)
293 GROWTHBOUND = MAXGROWTH1*SPDIAM
298 * Ensure that we do not back off too much of the initial shifts
299 LDELTA = MIN(LDMAX,LDELTA)
300 RDELTA = MIN(RDMAX,RDELTA)
302 * Compute the element growth when shifting to both ends of the cluster
303 * accept the shift if there is no element growth at one of the two ends
307 DPLUS( 1 ) = D( 1 ) + S
308 IF(ABS(DPLUS(1)).LT.PIVMIN) THEN
310 * Need to set SAWNAN1 because refined RRR test should not be used
314 MAX1 = ABS( DPLUS( 1 ) )
316 LPLUS( I ) = LD( I ) / DPLUS( I )
317 S = S*LPLUS( I )*L( I ) - LSIGMA
318 DPLUS( I+1 ) = D( I+1 ) + S
319 IF(ABS(DPLUS(I+1)).LT.PIVMIN) THEN
321 * Need to set SAWNAN1 because refined RRR test should not be used
325 MAX1 = MAX( MAX1,ABS(DPLUS(I+1)) )
327 SAWNAN1 = SAWNAN1 .OR. DISNAN( MAX1 )
330 $ (MAX1.LE.GROWTHBOUND .AND. .NOT.SAWNAN1 ) ) THEN
338 WORK( 1 ) = D( 1 ) + S
339 IF(ABS(WORK(1)).LT.PIVMIN) THEN
341 * Need to set SAWNAN2 because refined RRR test should not be used
345 MAX2 = ABS( WORK( 1 ) )
347 WORK( N+I ) = LD( I ) / WORK( I )
348 S = S*WORK( N+I )*L( I ) - RSIGMA
349 WORK( I+1 ) = D( I+1 ) + S
350 IF(ABS(WORK(I+1)).LT.PIVMIN) THEN
352 * Need to set SAWNAN2 because refined RRR test should not be used
356 MAX2 = MAX( MAX2,ABS(WORK(I+1)) )
358 SAWNAN2 = SAWNAN2 .OR. DISNAN( MAX2 )
361 $ (MAX2.LE.GROWTHBOUND .AND. .NOT.SAWNAN2 ) ) THEN
366 * If we are at this point, both shifts led to too much element growth
368 * Record the better of the two shifts (provided it didn't lead to NaN)
369 IF(SAWNAN1.AND.SAWNAN2) THEN
370 * both MAX1 and MAX2 are NaN
373 IF( .NOT.SAWNAN1 ) THEN
375 IF(MAX1.LE.SMLGROWTH) THEN
380 IF( .NOT.SAWNAN2 ) THEN
381 IF(SAWNAN1 .OR. MAX2.LE.MAX1) INDX = 2
382 IF(MAX2.LE.SMLGROWTH) THEN
389 * If we are here, both the left and the right shift led to
390 * element growth. If the element growth is moderate, then
391 * we may still accept the representation, if it passes a
392 * refined test for RRR. This test supposes that no NaN occurred.
393 * Moreover, we use the refined RRR test only for isolated clusters.
394 IF((CLWDTH.LT.MINGAP/DBLE(128)) .AND.
395 $ (MIN(MAX1,MAX2).LT.FAIL2)
396 $ .AND.(.NOT.SAWNAN1).AND.(.NOT.SAWNAN2)) THEN
402 IF( TRYRRR1 .AND. DORRR1 ) THEN
404 TMP = ABS( DPLUS( N ) )
409 IF( PROD .LE. EPS ) THEN
411 $ ((DPLUS(I+1)*WORK(N+I+1))/(DPLUS(I)*WORK(N+I)))*OLDP
413 PROD = PROD*ABS(WORK(N+I))
416 ZNM2 = ZNM2 + PROD**2
417 TMP = MAX( TMP, ABS( DPLUS( I ) * PROD ))
419 RRR1 = TMP/( SPDIAM * SQRT( ZNM2 ) )
420 IF (RRR1.LE.MAXGROWTH2) THEN
425 ELSE IF(INDX.EQ.2) THEN
426 TMP = ABS( WORK( N ) )
431 IF( PROD .LE. EPS ) THEN
432 PROD = ((WORK(I+1)*LPLUS(I+1))/(WORK(I)*LPLUS(I)))*OLDP
434 PROD = PROD*ABS(LPLUS(I))
437 ZNM2 = ZNM2 + PROD**2
438 TMP = MAX( TMP, ABS( WORK( I ) * PROD ))
440 RRR2 = TMP/( SPDIAM * SQRT( ZNM2 ) )
441 IF (RRR2.LE.MAXGROWTH2) THEN
451 IF (KTRY.LT.KTRYMAX) THEN
452 * If we are here, both shifts failed also the RRR test.
453 * Back off to the outside
454 LSIGMA = MAX( LSIGMA - LDELTA,
456 RSIGMA = MIN( RSIGMA + RDELTA,
458 LDELTA = TWO * LDELTA
459 RDELTA = TWO * RDELTA
463 * None of the representations investigated satisfied our
464 * criteria. Take the best one we found.
465 IF((SMLGROWTH.LT.FAIL).OR.NOFAIL) THEN
477 IF (SHIFT.EQ.SLEFT) THEN
478 ELSEIF (SHIFT.EQ.SRIGHT) THEN
479 * store new L and D back into DPLUS, LPLUS
480 CALL DCOPY( N, WORK, 1, DPLUS, 1 )
481 CALL DCOPY( N-1, WORK(N+1), 1, LPLUS, 1 )