Annotation of rpl/lapack/lapack/dlarrf.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DLARRF( N, D, L, LD, CLSTRT, CLEND,
! 2: $ W, WGAP, WERR,
! 3: $ SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,
! 4: $ DPLUS, LPLUS, WORK, INFO )
! 5: *
! 6: * -- LAPACK auxiliary routine (version 3.2) --
! 7: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 8: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 9: * November 2006
! 10: **
! 11: * .. Scalar Arguments ..
! 12: INTEGER CLSTRT, CLEND, INFO, N
! 13: DOUBLE PRECISION CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM
! 14: * ..
! 15: * .. Array Arguments ..
! 16: DOUBLE PRECISION D( * ), DPLUS( * ), L( * ), LD( * ),
! 17: $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )
! 18: * ..
! 19: *
! 20: * Purpose
! 21: * =======
! 22: *
! 23: * Given the initial representation L D L^T and its cluster of close
! 24: * eigenvalues (in a relative measure), W( CLSTRT ), W( CLSTRT+1 ), ...
! 25: * W( CLEND ), DLARRF finds a new relatively robust representation
! 26: * L D L^T - SIGMA I = L(+) D(+) L(+)^T such that at least one of the
! 27: * eigenvalues of L(+) D(+) L(+)^T is relatively isolated.
! 28: *
! 29: * Arguments
! 30: * =========
! 31: *
! 32: * N (input) INTEGER
! 33: * The order of the matrix (subblock, if the matrix splitted).
! 34: *
! 35: * D (input) DOUBLE PRECISION array, dimension (N)
! 36: * The N diagonal elements of the diagonal matrix D.
! 37: *
! 38: * L (input) DOUBLE PRECISION array, dimension (N-1)
! 39: * The (N-1) subdiagonal elements of the unit bidiagonal
! 40: * matrix L.
! 41: *
! 42: * LD (input) DOUBLE PRECISION array, dimension (N-1)
! 43: * The (N-1) elements L(i)*D(i).
! 44: *
! 45: * CLSTRT (input) INTEGER
! 46: * The index of the first eigenvalue in the cluster.
! 47: *
! 48: * CLEND (input) INTEGER
! 49: * The index of the last eigenvalue in the cluster.
! 50: *
! 51: * W (input) DOUBLE PRECISION array, dimension >= (CLEND-CLSTRT+1)
! 52: * The eigenvalue APPROXIMATIONS of L D L^T in ascending order.
! 53: * W( CLSTRT ) through W( CLEND ) form the cluster of relatively
! 54: * close eigenalues.
! 55: *
! 56: * WGAP (input/output) DOUBLE PRECISION array, dimension >= (CLEND-CLSTRT+1)
! 57: * The separation from the right neighbor eigenvalue in W.
! 58: *
! 59: * WERR (input) DOUBLE PRECISION array, dimension >= (CLEND-CLSTRT+1)
! 60: * WERR contain the semiwidth of the uncertainty
! 61: * interval of the corresponding eigenvalue APPROXIMATION in W
! 62: *
! 63: * SPDIAM (input) estimate of the spectral diameter obtained from the
! 64: * Gerschgorin intervals
! 65: *
! 66: * CLGAPL, CLGAPR (input) absolute gap on each end of the cluster.
! 67: * Set by the calling routine to protect against shifts too close
! 68: * to eigenvalues outside the cluster.
! 69: *
! 70: * PIVMIN (input) DOUBLE PRECISION
! 71: * The minimum pivot allowed in the Sturm sequence.
! 72: *
! 73: * SIGMA (output) DOUBLE PRECISION
! 74: * The shift used to form L(+) D(+) L(+)^T.
! 75: *
! 76: * DPLUS (output) DOUBLE PRECISION array, dimension (N)
! 77: * The N diagonal elements of the diagonal matrix D(+).
! 78: *
! 79: * LPLUS (output) DOUBLE PRECISION array, dimension (N-1)
! 80: * The first (N-1) elements of LPLUS contain the subdiagonal
! 81: * elements of the unit bidiagonal matrix L(+).
! 82: *
! 83: * WORK (workspace) DOUBLE PRECISION array, dimension (2*N)
! 84: * Workspace.
! 85: *
! 86: * Further Details
! 87: * ===============
! 88: *
! 89: * Based on contributions by
! 90: * Beresford Parlett, University of California, Berkeley, USA
! 91: * Jim Demmel, University of California, Berkeley, USA
! 92: * Inderjit Dhillon, University of Texas, Austin, USA
! 93: * Osni Marques, LBNL/NERSC, USA
! 94: * Christof Voemel, University of California, Berkeley, USA
! 95: *
! 96: * =====================================================================
! 97: *
! 98: * .. Parameters ..
! 99: DOUBLE PRECISION FOUR, MAXGROWTH1, MAXGROWTH2, ONE, QUART, TWO,
! 100: $ ZERO
! 101: PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
! 102: $ FOUR = 4.0D0, QUART = 0.25D0,
! 103: $ MAXGROWTH1 = 8.D0,
! 104: $ MAXGROWTH2 = 8.D0 )
! 105: * ..
! 106: * .. Local Scalars ..
! 107: LOGICAL DORRR1, FORCER, NOFAIL, SAWNAN1, SAWNAN2, TRYRRR1
! 108: INTEGER I, INDX, KTRY, KTRYMAX, SLEFT, SRIGHT, SHIFT
! 109: PARAMETER ( KTRYMAX = 1, SLEFT = 1, SRIGHT = 2 )
! 110: DOUBLE PRECISION AVGAP, BESTSHIFT, CLWDTH, EPS, FACT, FAIL,
! 111: $ FAIL2, GROWTHBOUND, LDELTA, LDMAX, LSIGMA,
! 112: $ MAX1, MAX2, MINGAP, OLDP, PROD, RDELTA, RDMAX,
! 113: $ RRR1, RRR2, RSIGMA, S, SMLGROWTH, TMP, ZNM2
! 114: * ..
! 115: * .. External Functions ..
! 116: LOGICAL DISNAN
! 117: DOUBLE PRECISION DLAMCH
! 118: EXTERNAL DISNAN, DLAMCH
! 119: * ..
! 120: * .. External Subroutines ..
! 121: EXTERNAL DCOPY
! 122: * ..
! 123: * .. Intrinsic Functions ..
! 124: INTRINSIC ABS
! 125: * ..
! 126: * .. Executable Statements ..
! 127: *
! 128: INFO = 0
! 129: FACT = DBLE(2**KTRYMAX)
! 130: EPS = DLAMCH( 'Precision' )
! 131: SHIFT = 0
! 132: FORCER = .FALSE.
! 133:
! 134:
! 135: * Note that we cannot guarantee that for any of the shifts tried,
! 136: * the factorization has a small or even moderate element growth.
! 137: * There could be Ritz values at both ends of the cluster and despite
! 138: * backing off, there are examples where all factorizations tried
! 139: * (in IEEE mode, allowing zero pivots & infinities) have INFINITE
! 140: * element growth.
! 141: * For this reason, we should use PIVMIN in this subroutine so that at
! 142: * least the L D L^T factorization exists. It can be checked afterwards
! 143: * whether the element growth caused bad residuals/orthogonality.
! 144:
! 145: * Decide whether the code should accept the best among all
! 146: * representations despite large element growth or signal INFO=1
! 147: NOFAIL = .TRUE.
! 148: *
! 149:
! 150: * Compute the average gap length of the cluster
! 151: CLWDTH = ABS(W(CLEND)-W(CLSTRT)) + WERR(CLEND) + WERR(CLSTRT)
! 152: AVGAP = CLWDTH / DBLE(CLEND-CLSTRT)
! 153: MINGAP = MIN(CLGAPL, CLGAPR)
! 154: * Initial values for shifts to both ends of cluster
! 155: LSIGMA = MIN(W( CLSTRT ),W( CLEND )) - WERR( CLSTRT )
! 156: RSIGMA = MAX(W( CLSTRT ),W( CLEND )) + WERR( CLEND )
! 157:
! 158: * Use a small fudge to make sure that we really shift to the outside
! 159: LSIGMA = LSIGMA - ABS(LSIGMA)* FOUR * EPS
! 160: RSIGMA = RSIGMA + ABS(RSIGMA)* FOUR * EPS
! 161:
! 162: * Compute upper bounds for how much to back off the initial shifts
! 163: LDMAX = QUART * MINGAP + TWO * PIVMIN
! 164: RDMAX = QUART * MINGAP + TWO * PIVMIN
! 165:
! 166: LDELTA = MAX(AVGAP,WGAP( CLSTRT ))/FACT
! 167: RDELTA = MAX(AVGAP,WGAP( CLEND-1 ))/FACT
! 168: *
! 169: * Initialize the record of the best representation found
! 170: *
! 171: S = DLAMCH( 'S' )
! 172: SMLGROWTH = ONE / S
! 173: FAIL = DBLE(N-1)*MINGAP/(SPDIAM*EPS)
! 174: FAIL2 = DBLE(N-1)*MINGAP/(SPDIAM*SQRT(EPS))
! 175: BESTSHIFT = LSIGMA
! 176: *
! 177: * while (KTRY <= KTRYMAX)
! 178: KTRY = 0
! 179: GROWTHBOUND = MAXGROWTH1*SPDIAM
! 180:
! 181: 5 CONTINUE
! 182: SAWNAN1 = .FALSE.
! 183: SAWNAN2 = .FALSE.
! 184: * Ensure that we do not back off too much of the initial shifts
! 185: LDELTA = MIN(LDMAX,LDELTA)
! 186: RDELTA = MIN(RDMAX,RDELTA)
! 187:
! 188: * Compute the element growth when shifting to both ends of the cluster
! 189: * accept the shift if there is no element growth at one of the two ends
! 190:
! 191: * Left end
! 192: S = -LSIGMA
! 193: DPLUS( 1 ) = D( 1 ) + S
! 194: IF(ABS(DPLUS(1)).LT.PIVMIN) THEN
! 195: DPLUS(1) = -PIVMIN
! 196: * Need to set SAWNAN1 because refined RRR test should not be used
! 197: * in this case
! 198: SAWNAN1 = .TRUE.
! 199: ENDIF
! 200: MAX1 = ABS( DPLUS( 1 ) )
! 201: DO 6 I = 1, N - 1
! 202: LPLUS( I ) = LD( I ) / DPLUS( I )
! 203: S = S*LPLUS( I )*L( I ) - LSIGMA
! 204: DPLUS( I+1 ) = D( I+1 ) + S
! 205: IF(ABS(DPLUS(I+1)).LT.PIVMIN) THEN
! 206: DPLUS(I+1) = -PIVMIN
! 207: * Need to set SAWNAN1 because refined RRR test should not be used
! 208: * in this case
! 209: SAWNAN1 = .TRUE.
! 210: ENDIF
! 211: MAX1 = MAX( MAX1,ABS(DPLUS(I+1)) )
! 212: 6 CONTINUE
! 213: SAWNAN1 = SAWNAN1 .OR. DISNAN( MAX1 )
! 214:
! 215: IF( FORCER .OR.
! 216: $ (MAX1.LE.GROWTHBOUND .AND. .NOT.SAWNAN1 ) ) THEN
! 217: SIGMA = LSIGMA
! 218: SHIFT = SLEFT
! 219: GOTO 100
! 220: ENDIF
! 221:
! 222: * Right end
! 223: S = -RSIGMA
! 224: WORK( 1 ) = D( 1 ) + S
! 225: IF(ABS(WORK(1)).LT.PIVMIN) THEN
! 226: WORK(1) = -PIVMIN
! 227: * Need to set SAWNAN2 because refined RRR test should not be used
! 228: * in this case
! 229: SAWNAN2 = .TRUE.
! 230: ENDIF
! 231: MAX2 = ABS( WORK( 1 ) )
! 232: DO 7 I = 1, N - 1
! 233: WORK( N+I ) = LD( I ) / WORK( I )
! 234: S = S*WORK( N+I )*L( I ) - RSIGMA
! 235: WORK( I+1 ) = D( I+1 ) + S
! 236: IF(ABS(WORK(I+1)).LT.PIVMIN) THEN
! 237: WORK(I+1) = -PIVMIN
! 238: * Need to set SAWNAN2 because refined RRR test should not be used
! 239: * in this case
! 240: SAWNAN2 = .TRUE.
! 241: ENDIF
! 242: MAX2 = MAX( MAX2,ABS(WORK(I+1)) )
! 243: 7 CONTINUE
! 244: SAWNAN2 = SAWNAN2 .OR. DISNAN( MAX2 )
! 245:
! 246: IF( FORCER .OR.
! 247: $ (MAX2.LE.GROWTHBOUND .AND. .NOT.SAWNAN2 ) ) THEN
! 248: SIGMA = RSIGMA
! 249: SHIFT = SRIGHT
! 250: GOTO 100
! 251: ENDIF
! 252: * If we are at this point, both shifts led to too much element growth
! 253:
! 254: * Record the better of the two shifts (provided it didn't lead to NaN)
! 255: IF(SAWNAN1.AND.SAWNAN2) THEN
! 256: * both MAX1 and MAX2 are NaN
! 257: GOTO 50
! 258: ELSE
! 259: IF( .NOT.SAWNAN1 ) THEN
! 260: INDX = 1
! 261: IF(MAX1.LE.SMLGROWTH) THEN
! 262: SMLGROWTH = MAX1
! 263: BESTSHIFT = LSIGMA
! 264: ENDIF
! 265: ENDIF
! 266: IF( .NOT.SAWNAN2 ) THEN
! 267: IF(SAWNAN1 .OR. MAX2.LE.MAX1) INDX = 2
! 268: IF(MAX2.LE.SMLGROWTH) THEN
! 269: SMLGROWTH = MAX2
! 270: BESTSHIFT = RSIGMA
! 271: ENDIF
! 272: ENDIF
! 273: ENDIF
! 274:
! 275: * If we are here, both the left and the right shift led to
! 276: * element growth. If the element growth is moderate, then
! 277: * we may still accept the representation, if it passes a
! 278: * refined test for RRR. This test supposes that no NaN occurred.
! 279: * Moreover, we use the refined RRR test only for isolated clusters.
! 280: IF((CLWDTH.LT.MINGAP/DBLE(128)) .AND.
! 281: $ (MIN(MAX1,MAX2).LT.FAIL2)
! 282: $ .AND.(.NOT.SAWNAN1).AND.(.NOT.SAWNAN2)) THEN
! 283: DORRR1 = .TRUE.
! 284: ELSE
! 285: DORRR1 = .FALSE.
! 286: ENDIF
! 287: TRYRRR1 = .TRUE.
! 288: IF( TRYRRR1 .AND. DORRR1 ) THEN
! 289: IF(INDX.EQ.1) THEN
! 290: TMP = ABS( DPLUS( N ) )
! 291: ZNM2 = ONE
! 292: PROD = ONE
! 293: OLDP = ONE
! 294: DO 15 I = N-1, 1, -1
! 295: IF( PROD .LE. EPS ) THEN
! 296: PROD =
! 297: $ ((DPLUS(I+1)*WORK(N+I+1))/(DPLUS(I)*WORK(N+I)))*OLDP
! 298: ELSE
! 299: PROD = PROD*ABS(WORK(N+I))
! 300: END IF
! 301: OLDP = PROD
! 302: ZNM2 = ZNM2 + PROD**2
! 303: TMP = MAX( TMP, ABS( DPLUS( I ) * PROD ))
! 304: 15 CONTINUE
! 305: RRR1 = TMP/( SPDIAM * SQRT( ZNM2 ) )
! 306: IF (RRR1.LE.MAXGROWTH2) THEN
! 307: SIGMA = LSIGMA
! 308: SHIFT = SLEFT
! 309: GOTO 100
! 310: ENDIF
! 311: ELSE IF(INDX.EQ.2) THEN
! 312: TMP = ABS( WORK( N ) )
! 313: ZNM2 = ONE
! 314: PROD = ONE
! 315: OLDP = ONE
! 316: DO 16 I = N-1, 1, -1
! 317: IF( PROD .LE. EPS ) THEN
! 318: PROD = ((WORK(I+1)*LPLUS(I+1))/(WORK(I)*LPLUS(I)))*OLDP
! 319: ELSE
! 320: PROD = PROD*ABS(LPLUS(I))
! 321: END IF
! 322: OLDP = PROD
! 323: ZNM2 = ZNM2 + PROD**2
! 324: TMP = MAX( TMP, ABS( WORK( I ) * PROD ))
! 325: 16 CONTINUE
! 326: RRR2 = TMP/( SPDIAM * SQRT( ZNM2 ) )
! 327: IF (RRR2.LE.MAXGROWTH2) THEN
! 328: SIGMA = RSIGMA
! 329: SHIFT = SRIGHT
! 330: GOTO 100
! 331: ENDIF
! 332: END IF
! 333: ENDIF
! 334:
! 335: 50 CONTINUE
! 336:
! 337: IF (KTRY.LT.KTRYMAX) THEN
! 338: * If we are here, both shifts failed also the RRR test.
! 339: * Back off to the outside
! 340: LSIGMA = MAX( LSIGMA - LDELTA,
! 341: $ LSIGMA - LDMAX)
! 342: RSIGMA = MIN( RSIGMA + RDELTA,
! 343: $ RSIGMA + RDMAX )
! 344: LDELTA = TWO * LDELTA
! 345: RDELTA = TWO * RDELTA
! 346: KTRY = KTRY + 1
! 347: GOTO 5
! 348: ELSE
! 349: * None of the representations investigated satisfied our
! 350: * criteria. Take the best one we found.
! 351: IF((SMLGROWTH.LT.FAIL).OR.NOFAIL) THEN
! 352: LSIGMA = BESTSHIFT
! 353: RSIGMA = BESTSHIFT
! 354: FORCER = .TRUE.
! 355: GOTO 5
! 356: ELSE
! 357: INFO = 1
! 358: RETURN
! 359: ENDIF
! 360: END IF
! 361:
! 362: 100 CONTINUE
! 363: IF (SHIFT.EQ.SLEFT) THEN
! 364: ELSEIF (SHIFT.EQ.SRIGHT) THEN
! 365: * store new L and D back into DPLUS, LPLUS
! 366: CALL DCOPY( N, WORK, 1, DPLUS, 1 )
! 367: CALL DCOPY( N-1, WORK(N+1), 1, LPLUS, 1 )
! 368: ENDIF
! 369:
! 370: RETURN
! 371: *
! 372: * End of DLARRF
! 373: *
! 374: END
CVSweb interface <joel.bertrand@systella.fr>