LAPACK 3.3.0
|
00001 SUBROUTINE SLARRF( N, D, L, LD, CLSTRT, CLEND, 00002 $ W, WGAP, WERR, 00003 $ SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA, 00004 $ DPLUS, LPLUS, WORK, INFO ) 00005 * 00006 * -- LAPACK auxiliary routine (version 3.2.2) -- 00007 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00008 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00009 * June 2010 00010 ** 00011 * .. Scalar Arguments .. 00012 INTEGER CLSTRT, CLEND, INFO, N 00013 REAL CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM 00014 * .. 00015 * .. Array Arguments .. 00016 REAL D( * ), DPLUS( * ), L( * ), LD( * ), 00017 $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * ) 00018 * .. 00019 * 00020 * Purpose 00021 * ======= 00022 * 00023 * Given the initial representation L D L^T and its cluster of close 00024 * eigenvalues (in a relative measure), W( CLSTRT ), W( CLSTRT+1 ), ... 00025 * W( CLEND ), SLARRF finds a new relatively robust representation 00026 * L D L^T - SIGMA I = L(+) D(+) L(+)^T such that at least one of the 00027 * eigenvalues of L(+) D(+) L(+)^T is relatively isolated. 00028 * 00029 * Arguments 00030 * ========= 00031 * 00032 * N (input) INTEGER 00033 * The order of the matrix (subblock, if the matrix splitted). 00034 * 00035 * D (input) REAL array, dimension (N) 00036 * The N diagonal elements of the diagonal matrix D. 00037 * 00038 * L (input) REAL array, dimension (N-1) 00039 * The (N-1) subdiagonal elements of the unit bidiagonal 00040 * matrix L. 00041 * 00042 * LD (input) REAL array, dimension (N-1) 00043 * The (N-1) elements L(i)*D(i). 00044 * 00045 * CLSTRT (input) INTEGER 00046 * The index of the first eigenvalue in the cluster. 00047 * 00048 * CLEND (input) INTEGER 00049 * The index of the last eigenvalue in the cluster. 00050 * 00051 * W (input) REAL array, dimension 00052 * dimension is >= (CLEND-CLSTRT+1) 00053 * The eigenvalue APPROXIMATIONS of L D L^T in ascending order. 00054 * W( CLSTRT ) through W( CLEND ) form the cluster of relatively 00055 * close eigenalues. 00056 * 00057 * WGAP (input/output) REAL array, dimension 00058 * dimension is >= (CLEND-CLSTRT+1) 00059 * The separation from the right neighbor eigenvalue in W. 00060 * 00061 * WERR (input) REAL array, dimension 00062 * dimension is >= (CLEND-CLSTRT+1) 00063 * WERR contain the semiwidth of the uncertainty 00064 * interval of the corresponding eigenvalue APPROXIMATION in W 00065 * 00066 * SPDIAM (input) REAL 00067 * estimate of the spectral diameter obtained from the 00068 * Gerschgorin intervals 00069 * 00070 * CLGAPL (input) REAL 00071 * 00072 * CLGAPR (input) REAL 00073 * absolute gap on each end of the cluster. 00074 * Set by the calling routine to protect against shifts too close 00075 * to eigenvalues outside the cluster. 00076 * 00077 * PIVMIN (input) REAL 00078 * The minimum pivot allowed in the Sturm sequence. 00079 * 00080 * SIGMA (output) REAL 00081 * The shift used to form L(+) D(+) L(+)^T. 00082 * 00083 * DPLUS (output) REAL array, dimension (N) 00084 * The N diagonal elements of the diagonal matrix D(+). 00085 * 00086 * LPLUS (output) REAL array, dimension (N-1) 00087 * The first (N-1) elements of LPLUS contain the subdiagonal 00088 * elements of the unit bidiagonal matrix L(+). 00089 * 00090 * WORK (workspace) REAL array, dimension (2*N) 00091 * Workspace. 00092 * 00093 * Further Details 00094 * =============== 00095 * 00096 * Based on contributions by 00097 * Beresford Parlett, University of California, Berkeley, USA 00098 * Jim Demmel, University of California, Berkeley, USA 00099 * Inderjit Dhillon, University of Texas, Austin, USA 00100 * Osni Marques, LBNL/NERSC, USA 00101 * Christof Voemel, University of California, Berkeley, USA 00102 * 00103 * ===================================================================== 00104 * 00105 * .. Parameters .. 00106 REAL FOUR, MAXGROWTH1, MAXGROWTH2, ONE, QUART, TWO, 00107 $ ZERO 00108 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0, 00109 $ FOUR = 4.0E0, QUART = 0.25E0, 00110 $ MAXGROWTH1 = 8.E0, 00111 $ MAXGROWTH2 = 8.E0 ) 00112 * .. 00113 * .. Local Scalars .. 00114 LOGICAL DORRR1, FORCER, NOFAIL, SAWNAN1, SAWNAN2, TRYRRR1 00115 INTEGER I, INDX, KTRY, KTRYMAX, SLEFT, SRIGHT, SHIFT 00116 PARAMETER ( KTRYMAX = 1, SLEFT = 1, SRIGHT = 2 ) 00117 REAL AVGAP, BESTSHIFT, CLWDTH, EPS, FACT, FAIL, 00118 $ FAIL2, GROWTHBOUND, LDELTA, LDMAX, LSIGMA, 00119 $ MAX1, MAX2, MINGAP, OLDP, PROD, RDELTA, RDMAX, 00120 $ RRR1, RRR2, RSIGMA, S, SMLGROWTH, TMP, ZNM2 00121 * .. 00122 * .. External Functions .. 00123 LOGICAL SISNAN 00124 REAL SLAMCH 00125 EXTERNAL SISNAN, SLAMCH 00126 * .. 00127 * .. External Subroutines .. 00128 EXTERNAL SCOPY 00129 * .. 00130 * .. Intrinsic Functions .. 00131 INTRINSIC ABS 00132 * .. 00133 * .. Executable Statements .. 00134 * 00135 INFO = 0 00136 FACT = REAL(2**KTRYMAX) 00137 EPS = SLAMCH( 'Precision' ) 00138 SHIFT = 0 00139 FORCER = .FALSE. 00140 00141 00142 * Note that we cannot guarantee that for any of the shifts tried, 00143 * the factorization has a small or even moderate element growth. 00144 * There could be Ritz values at both ends of the cluster and despite 00145 * backing off, there are examples where all factorizations tried 00146 * (in IEEE mode, allowing zero pivots & infinities) have INFINITE 00147 * element growth. 00148 * For this reason, we should use PIVMIN in this subroutine so that at 00149 * least the L D L^T factorization exists. It can be checked afterwards 00150 * whether the element growth caused bad residuals/orthogonality. 00151 00152 * Decide whether the code should accept the best among all 00153 * representations despite large element growth or signal INFO=1 00154 NOFAIL = .TRUE. 00155 * 00156 00157 * Compute the average gap length of the cluster 00158 CLWDTH = ABS(W(CLEND)-W(CLSTRT)) + WERR(CLEND) + WERR(CLSTRT) 00159 AVGAP = CLWDTH / REAL(CLEND-CLSTRT) 00160 MINGAP = MIN(CLGAPL, CLGAPR) 00161 * Initial values for shifts to both ends of cluster 00162 LSIGMA = MIN(W( CLSTRT ),W( CLEND )) - WERR( CLSTRT ) 00163 RSIGMA = MAX(W( CLSTRT ),W( CLEND )) + WERR( CLEND ) 00164 00165 * Use a small fudge to make sure that we really shift to the outside 00166 LSIGMA = LSIGMA - ABS(LSIGMA)* TWO * EPS 00167 RSIGMA = RSIGMA + ABS(RSIGMA)* TWO * EPS 00168 00169 * Compute upper bounds for how much to back off the initial shifts 00170 LDMAX = QUART * MINGAP + TWO * PIVMIN 00171 RDMAX = QUART * MINGAP + TWO * PIVMIN 00172 00173 LDELTA = MAX(AVGAP,WGAP( CLSTRT ))/FACT 00174 RDELTA = MAX(AVGAP,WGAP( CLEND-1 ))/FACT 00175 * 00176 * Initialize the record of the best representation found 00177 * 00178 S = SLAMCH( 'S' ) 00179 SMLGROWTH = ONE / S 00180 FAIL = REAL(N-1)*MINGAP/(SPDIAM*EPS) 00181 FAIL2 = REAL(N-1)*MINGAP/(SPDIAM*SQRT(EPS)) 00182 BESTSHIFT = LSIGMA 00183 * 00184 * while (KTRY <= KTRYMAX) 00185 KTRY = 0 00186 GROWTHBOUND = MAXGROWTH1*SPDIAM 00187 00188 5 CONTINUE 00189 SAWNAN1 = .FALSE. 00190 SAWNAN2 = .FALSE. 00191 * Ensure that we do not back off too much of the initial shifts 00192 LDELTA = MIN(LDMAX,LDELTA) 00193 RDELTA = MIN(RDMAX,RDELTA) 00194 00195 * Compute the element growth when shifting to both ends of the cluster 00196 * accept the shift if there is no element growth at one of the two ends 00197 00198 * Left end 00199 S = -LSIGMA 00200 DPLUS( 1 ) = D( 1 ) + S 00201 IF(ABS(DPLUS(1)).LT.PIVMIN) THEN 00202 DPLUS(1) = -PIVMIN 00203 * Need to set SAWNAN1 because refined RRR test should not be used 00204 * in this case 00205 SAWNAN1 = .TRUE. 00206 ENDIF 00207 MAX1 = ABS( DPLUS( 1 ) ) 00208 DO 6 I = 1, N - 1 00209 LPLUS( I ) = LD( I ) / DPLUS( I ) 00210 S = S*LPLUS( I )*L( I ) - LSIGMA 00211 DPLUS( I+1 ) = D( I+1 ) + S 00212 IF(ABS(DPLUS(I+1)).LT.PIVMIN) THEN 00213 DPLUS(I+1) = -PIVMIN 00214 * Need to set SAWNAN1 because refined RRR test should not be used 00215 * in this case 00216 SAWNAN1 = .TRUE. 00217 ENDIF 00218 MAX1 = MAX( MAX1,ABS(DPLUS(I+1)) ) 00219 6 CONTINUE 00220 SAWNAN1 = SAWNAN1 .OR. SISNAN( MAX1 ) 00221 00222 IF( FORCER .OR. 00223 $ (MAX1.LE.GROWTHBOUND .AND. .NOT.SAWNAN1 ) ) THEN 00224 SIGMA = LSIGMA 00225 SHIFT = SLEFT 00226 GOTO 100 00227 ENDIF 00228 00229 * Right end 00230 S = -RSIGMA 00231 WORK( 1 ) = D( 1 ) + S 00232 IF(ABS(WORK(1)).LT.PIVMIN) THEN 00233 WORK(1) = -PIVMIN 00234 * Need to set SAWNAN2 because refined RRR test should not be used 00235 * in this case 00236 SAWNAN2 = .TRUE. 00237 ENDIF 00238 MAX2 = ABS( WORK( 1 ) ) 00239 DO 7 I = 1, N - 1 00240 WORK( N+I ) = LD( I ) / WORK( I ) 00241 S = S*WORK( N+I )*L( I ) - RSIGMA 00242 WORK( I+1 ) = D( I+1 ) + S 00243 IF(ABS(WORK(I+1)).LT.PIVMIN) THEN 00244 WORK(I+1) = -PIVMIN 00245 * Need to set SAWNAN2 because refined RRR test should not be used 00246 * in this case 00247 SAWNAN2 = .TRUE. 00248 ENDIF 00249 MAX2 = MAX( MAX2,ABS(WORK(I+1)) ) 00250 7 CONTINUE 00251 SAWNAN2 = SAWNAN2 .OR. SISNAN( MAX2 ) 00252 00253 IF( FORCER .OR. 00254 $ (MAX2.LE.GROWTHBOUND .AND. .NOT.SAWNAN2 ) ) THEN 00255 SIGMA = RSIGMA 00256 SHIFT = SRIGHT 00257 GOTO 100 00258 ENDIF 00259 * If we are at this point, both shifts led to too much element growth 00260 00261 * Record the better of the two shifts (provided it didn't lead to NaN) 00262 IF(SAWNAN1.AND.SAWNAN2) THEN 00263 * both MAX1 and MAX2 are NaN 00264 GOTO 50 00265 ELSE 00266 IF( .NOT.SAWNAN1 ) THEN 00267 INDX = 1 00268 IF(MAX1.LE.SMLGROWTH) THEN 00269 SMLGROWTH = MAX1 00270 BESTSHIFT = LSIGMA 00271 ENDIF 00272 ENDIF 00273 IF( .NOT.SAWNAN2 ) THEN 00274 IF(SAWNAN1 .OR. MAX2.LE.MAX1) INDX = 2 00275 IF(MAX2.LE.SMLGROWTH) THEN 00276 SMLGROWTH = MAX2 00277 BESTSHIFT = RSIGMA 00278 ENDIF 00279 ENDIF 00280 ENDIF 00281 00282 * If we are here, both the left and the right shift led to 00283 * element growth. If the element growth is moderate, then 00284 * we may still accept the representation, if it passes a 00285 * refined test for RRR. This test supposes that no NaN occurred. 00286 * Moreover, we use the refined RRR test only for isolated clusters. 00287 IF((CLWDTH.LT.MINGAP/REAL(128)) .AND. 00288 $ (MIN(MAX1,MAX2).LT.FAIL2) 00289 $ .AND.(.NOT.SAWNAN1).AND.(.NOT.SAWNAN2)) THEN 00290 DORRR1 = .TRUE. 00291 ELSE 00292 DORRR1 = .FALSE. 00293 ENDIF 00294 TRYRRR1 = .TRUE. 00295 IF( TRYRRR1 .AND. DORRR1 ) THEN 00296 IF(INDX.EQ.1) THEN 00297 TMP = ABS( DPLUS( N ) ) 00298 ZNM2 = ONE 00299 PROD = ONE 00300 OLDP = ONE 00301 DO 15 I = N-1, 1, -1 00302 IF( PROD .LE. EPS ) THEN 00303 PROD = 00304 $ ((DPLUS(I+1)*WORK(N+I+1))/(DPLUS(I)*WORK(N+I)))*OLDP 00305 ELSE 00306 PROD = PROD*ABS(WORK(N+I)) 00307 END IF 00308 OLDP = PROD 00309 ZNM2 = ZNM2 + PROD**2 00310 TMP = MAX( TMP, ABS( DPLUS( I ) * PROD )) 00311 15 CONTINUE 00312 RRR1 = TMP/( SPDIAM * SQRT( ZNM2 ) ) 00313 IF (RRR1.LE.MAXGROWTH2) THEN 00314 SIGMA = LSIGMA 00315 SHIFT = SLEFT 00316 GOTO 100 00317 ENDIF 00318 ELSE IF(INDX.EQ.2) THEN 00319 TMP = ABS( WORK( N ) ) 00320 ZNM2 = ONE 00321 PROD = ONE 00322 OLDP = ONE 00323 DO 16 I = N-1, 1, -1 00324 IF( PROD .LE. EPS ) THEN 00325 PROD = ((WORK(I+1)*LPLUS(I+1))/(WORK(I)*LPLUS(I)))*OLDP 00326 ELSE 00327 PROD = PROD*ABS(LPLUS(I)) 00328 END IF 00329 OLDP = PROD 00330 ZNM2 = ZNM2 + PROD**2 00331 TMP = MAX( TMP, ABS( WORK( I ) * PROD )) 00332 16 CONTINUE 00333 RRR2 = TMP/( SPDIAM * SQRT( ZNM2 ) ) 00334 IF (RRR2.LE.MAXGROWTH2) THEN 00335 SIGMA = RSIGMA 00336 SHIFT = SRIGHT 00337 GOTO 100 00338 ENDIF 00339 END IF 00340 ENDIF 00341 00342 50 CONTINUE 00343 00344 IF (KTRY.LT.KTRYMAX) THEN 00345 * If we are here, both shifts failed also the RRR test. 00346 * Back off to the outside 00347 LSIGMA = MAX( LSIGMA - LDELTA, 00348 $ LSIGMA - LDMAX) 00349 RSIGMA = MIN( RSIGMA + RDELTA, 00350 $ RSIGMA + RDMAX ) 00351 LDELTA = TWO * LDELTA 00352 RDELTA = TWO * RDELTA 00353 KTRY = KTRY + 1 00354 GOTO 5 00355 ELSE 00356 * None of the representations investigated satisfied our 00357 * criteria. Take the best one we found. 00358 IF((SMLGROWTH.LT.FAIL).OR.NOFAIL) THEN 00359 LSIGMA = BESTSHIFT 00360 RSIGMA = BESTSHIFT 00361 FORCER = .TRUE. 00362 GOTO 5 00363 ELSE 00364 INFO = 1 00365 RETURN 00366 ENDIF 00367 END IF 00368 00369 100 CONTINUE 00370 IF (SHIFT.EQ.SLEFT) THEN 00371 ELSEIF (SHIFT.EQ.SRIGHT) THEN 00372 * store new L and D back into DPLUS, LPLUS 00373 CALL SCOPY( N, WORK, 1, DPLUS, 1 ) 00374 CALL SCOPY( N-1, WORK(N+1), 1, LPLUS, 1 ) 00375 ENDIF 00376 00377 RETURN 00378 * 00379 * End of SLARRF 00380 * 00381 END