Annotation of rpl/lapack/lapack/dstebz.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DSTEBZ( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D, E,
! 2: $ M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,
! 3: $ INFO )
! 4: *
! 5: * -- LAPACK routine (version 3.2) --
! 6: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 7: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 8: * November 2006
! 9: * 8-18-00: Increase FUDGE factor for T3E (eca)
! 10: *
! 11: * .. Scalar Arguments ..
! 12: CHARACTER ORDER, RANGE
! 13: INTEGER IL, INFO, IU, M, N, NSPLIT
! 14: DOUBLE PRECISION ABSTOL, VL, VU
! 15: * ..
! 16: * .. Array Arguments ..
! 17: INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * )
! 18: DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )
! 19: * ..
! 20: *
! 21: * Purpose
! 22: * =======
! 23: *
! 24: * DSTEBZ computes the eigenvalues of a symmetric tridiagonal
! 25: * matrix T. The user may ask for all eigenvalues, all eigenvalues
! 26: * in the half-open interval (VL, VU], or the IL-th through IU-th
! 27: * eigenvalues.
! 28: *
! 29: * To avoid overflow, the matrix must be scaled so that its
! 30: * largest element is no greater than overflow**(1/2) *
! 31: * underflow**(1/4) in absolute value, and for greatest
! 32: * accuracy, it should not be much smaller than that.
! 33: *
! 34: * See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal
! 35: * Matrix", Report CS41, Computer Science Dept., Stanford
! 36: * University, July 21, 1966.
! 37: *
! 38: * Arguments
! 39: * =========
! 40: *
! 41: * RANGE (input) CHARACTER*1
! 42: * = 'A': ("All") all eigenvalues will be found.
! 43: * = 'V': ("Value") all eigenvalues in the half-open interval
! 44: * (VL, VU] will be found.
! 45: * = 'I': ("Index") the IL-th through IU-th eigenvalues (of the
! 46: * entire matrix) will be found.
! 47: *
! 48: * ORDER (input) CHARACTER*1
! 49: * = 'B': ("By Block") the eigenvalues will be grouped by
! 50: * split-off block (see IBLOCK, ISPLIT) and
! 51: * ordered from smallest to largest within
! 52: * the block.
! 53: * = 'E': ("Entire matrix")
! 54: * the eigenvalues for the entire matrix
! 55: * will be ordered from smallest to
! 56: * largest.
! 57: *
! 58: * N (input) INTEGER
! 59: * The order of the tridiagonal matrix T. N >= 0.
! 60: *
! 61: * VL (input) DOUBLE PRECISION
! 62: * VU (input) DOUBLE PRECISION
! 63: * If RANGE='V', the lower and upper bounds of the interval to
! 64: * be searched for eigenvalues. Eigenvalues less than or equal
! 65: * to VL, or greater than VU, will not be returned. VL < VU.
! 66: * Not referenced if RANGE = 'A' or 'I'.
! 67: *
! 68: * IL (input) INTEGER
! 69: * IU (input) INTEGER
! 70: * If RANGE='I', the indices (in ascending order) of the
! 71: * smallest and largest eigenvalues to be returned.
! 72: * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
! 73: * Not referenced if RANGE = 'A' or 'V'.
! 74: *
! 75: * ABSTOL (input) DOUBLE PRECISION
! 76: * The absolute tolerance for the eigenvalues. An eigenvalue
! 77: * (or cluster) is considered to be located if it has been
! 78: * determined to lie in an interval whose width is ABSTOL or
! 79: * less. If ABSTOL is less than or equal to zero, then ULP*|T|
! 80: * will be used, where |T| means the 1-norm of T.
! 81: *
! 82: * Eigenvalues will be computed most accurately when ABSTOL is
! 83: * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
! 84: *
! 85: * D (input) DOUBLE PRECISION array, dimension (N)
! 86: * The n diagonal elements of the tridiagonal matrix T.
! 87: *
! 88: * E (input) DOUBLE PRECISION array, dimension (N-1)
! 89: * The (n-1) off-diagonal elements of the tridiagonal matrix T.
! 90: *
! 91: * M (output) INTEGER
! 92: * The actual number of eigenvalues found. 0 <= M <= N.
! 93: * (See also the description of INFO=2,3.)
! 94: *
! 95: * NSPLIT (output) INTEGER
! 96: * The number of diagonal blocks in the matrix T.
! 97: * 1 <= NSPLIT <= N.
! 98: *
! 99: * W (output) DOUBLE PRECISION array, dimension (N)
! 100: * On exit, the first M elements of W will contain the
! 101: * eigenvalues. (DSTEBZ may use the remaining N-M elements as
! 102: * workspace.)
! 103: *
! 104: * IBLOCK (output) INTEGER array, dimension (N)
! 105: * At each row/column j where E(j) is zero or small, the
! 106: * matrix T is considered to split into a block diagonal
! 107: * matrix. On exit, if INFO = 0, IBLOCK(i) specifies to which
! 108: * block (from 1 to the number of blocks) the eigenvalue W(i)
! 109: * belongs. (DSTEBZ may use the remaining N-M elements as
! 110: * workspace.)
! 111: *
! 112: * ISPLIT (output) INTEGER array, dimension (N)
! 113: * The splitting points, at which T breaks up into submatrices.
! 114: * The first submatrix consists of rows/columns 1 to ISPLIT(1),
! 115: * the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
! 116: * etc., and the NSPLIT-th consists of rows/columns
! 117: * ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
! 118: * (Only the first NSPLIT elements will actually be used, but
! 119: * since the user cannot know a priori what value NSPLIT will
! 120: * have, N words must be reserved for ISPLIT.)
! 121: *
! 122: * WORK (workspace) DOUBLE PRECISION array, dimension (4*N)
! 123: *
! 124: * IWORK (workspace) INTEGER array, dimension (3*N)
! 125: *
! 126: * INFO (output) INTEGER
! 127: * = 0: successful exit
! 128: * < 0: if INFO = -i, the i-th argument had an illegal value
! 129: * > 0: some or all of the eigenvalues failed to converge or
! 130: * were not computed:
! 131: * =1 or 3: Bisection failed to converge for some
! 132: * eigenvalues; these eigenvalues are flagged by a
! 133: * negative block number. The effect is that the
! 134: * eigenvalues may not be as accurate as the
! 135: * absolute and relative tolerances. This is
! 136: * generally caused by unexpectedly inaccurate
! 137: * arithmetic.
! 138: * =2 or 3: RANGE='I' only: Not all of the eigenvalues
! 139: * IL:IU were found.
! 140: * Effect: M < IU+1-IL
! 141: * Cause: non-monotonic arithmetic, causing the
! 142: * Sturm sequence to be non-monotonic.
! 143: * Cure: recalculate, using RANGE='A', and pick
! 144: * out eigenvalues IL:IU. In some cases,
! 145: * increasing the PARAMETER "FUDGE" may
! 146: * make things work.
! 147: * = 4: RANGE='I', and the Gershgorin interval
! 148: * initially used was too small. No eigenvalues
! 149: * were computed.
! 150: * Probable cause: your machine has sloppy
! 151: * floating-point arithmetic.
! 152: * Cure: Increase the PARAMETER "FUDGE",
! 153: * recompile, and try again.
! 154: *
! 155: * Internal Parameters
! 156: * ===================
! 157: *
! 158: * RELFAC DOUBLE PRECISION, default = 2.0e0
! 159: * The relative tolerance. An interval (a,b] lies within
! 160: * "relative tolerance" if b-a < RELFAC*ulp*max(|a|,|b|),
! 161: * where "ulp" is the machine precision (distance from 1 to
! 162: * the next larger floating point number.)
! 163: *
! 164: * FUDGE DOUBLE PRECISION, default = 2
! 165: * A "fudge factor" to widen the Gershgorin intervals. Ideally,
! 166: * a value of 1 should work, but on machines with sloppy
! 167: * arithmetic, this needs to be larger. The default for
! 168: * publicly released versions should be large enough to handle
! 169: * the worst machine around. Note that this has no effect
! 170: * on accuracy of the solution.
! 171: *
! 172: * =====================================================================
! 173: *
! 174: * .. Parameters ..
! 175: DOUBLE PRECISION ZERO, ONE, TWO, HALF
! 176: PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
! 177: $ HALF = 1.0D0 / TWO )
! 178: DOUBLE PRECISION FUDGE, RELFAC
! 179: PARAMETER ( FUDGE = 2.1D0, RELFAC = 2.0D0 )
! 180: * ..
! 181: * .. Local Scalars ..
! 182: LOGICAL NCNVRG, TOOFEW
! 183: INTEGER IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,
! 184: $ IM, IN, IOFF, IORDER, IOUT, IRANGE, ITMAX,
! 185: $ ITMP1, IW, IWOFF, J, JB, JDISC, JE, NB, NWL,
! 186: $ NWU
! 187: DOUBLE PRECISION ATOLI, BNORM, GL, GU, PIVMIN, RTOLI, SAFEMN,
! 188: $ TMP1, TMP2, TNORM, ULP, WKILL, WL, WLU, WU, WUL
! 189: * ..
! 190: * .. Local Arrays ..
! 191: INTEGER IDUMMA( 1 )
! 192: * ..
! 193: * .. External Functions ..
! 194: LOGICAL LSAME
! 195: INTEGER ILAENV
! 196: DOUBLE PRECISION DLAMCH
! 197: EXTERNAL LSAME, ILAENV, DLAMCH
! 198: * ..
! 199: * .. External Subroutines ..
! 200: EXTERNAL DLAEBZ, XERBLA
! 201: * ..
! 202: * .. Intrinsic Functions ..
! 203: INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT
! 204: * ..
! 205: * .. Executable Statements ..
! 206: *
! 207: INFO = 0
! 208: *
! 209: * Decode RANGE
! 210: *
! 211: IF( LSAME( RANGE, 'A' ) ) THEN
! 212: IRANGE = 1
! 213: ELSE IF( LSAME( RANGE, 'V' ) ) THEN
! 214: IRANGE = 2
! 215: ELSE IF( LSAME( RANGE, 'I' ) ) THEN
! 216: IRANGE = 3
! 217: ELSE
! 218: IRANGE = 0
! 219: END IF
! 220: *
! 221: * Decode ORDER
! 222: *
! 223: IF( LSAME( ORDER, 'B' ) ) THEN
! 224: IORDER = 2
! 225: ELSE IF( LSAME( ORDER, 'E' ) ) THEN
! 226: IORDER = 1
! 227: ELSE
! 228: IORDER = 0
! 229: END IF
! 230: *
! 231: * Check for Errors
! 232: *
! 233: IF( IRANGE.LE.0 ) THEN
! 234: INFO = -1
! 235: ELSE IF( IORDER.LE.0 ) THEN
! 236: INFO = -2
! 237: ELSE IF( N.LT.0 ) THEN
! 238: INFO = -3
! 239: ELSE IF( IRANGE.EQ.2 ) THEN
! 240: IF( VL.GE.VU )
! 241: $ INFO = -5
! 242: ELSE IF( IRANGE.EQ.3 .AND. ( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) )
! 243: $ THEN
! 244: INFO = -6
! 245: ELSE IF( IRANGE.EQ.3 .AND. ( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) )
! 246: $ THEN
! 247: INFO = -7
! 248: END IF
! 249: *
! 250: IF( INFO.NE.0 ) THEN
! 251: CALL XERBLA( 'DSTEBZ', -INFO )
! 252: RETURN
! 253: END IF
! 254: *
! 255: * Initialize error flags
! 256: *
! 257: INFO = 0
! 258: NCNVRG = .FALSE.
! 259: TOOFEW = .FALSE.
! 260: *
! 261: * Quick return if possible
! 262: *
! 263: M = 0
! 264: IF( N.EQ.0 )
! 265: $ RETURN
! 266: *
! 267: * Simplifications:
! 268: *
! 269: IF( IRANGE.EQ.3 .AND. IL.EQ.1 .AND. IU.EQ.N )
! 270: $ IRANGE = 1
! 271: *
! 272: * Get machine constants
! 273: * NB is the minimum vector length for vector bisection, or 0
! 274: * if only scalar is to be done.
! 275: *
! 276: SAFEMN = DLAMCH( 'S' )
! 277: ULP = DLAMCH( 'P' )
! 278: RTOLI = ULP*RELFAC
! 279: NB = ILAENV( 1, 'DSTEBZ', ' ', N, -1, -1, -1 )
! 280: IF( NB.LE.1 )
! 281: $ NB = 0
! 282: *
! 283: * Special Case when N=1
! 284: *
! 285: IF( N.EQ.1 ) THEN
! 286: NSPLIT = 1
! 287: ISPLIT( 1 ) = 1
! 288: IF( IRANGE.EQ.2 .AND. ( VL.GE.D( 1 ) .OR. VU.LT.D( 1 ) ) ) THEN
! 289: M = 0
! 290: ELSE
! 291: W( 1 ) = D( 1 )
! 292: IBLOCK( 1 ) = 1
! 293: M = 1
! 294: END IF
! 295: RETURN
! 296: END IF
! 297: *
! 298: * Compute Splitting Points
! 299: *
! 300: NSPLIT = 1
! 301: WORK( N ) = ZERO
! 302: PIVMIN = ONE
! 303: *
! 304: *DIR$ NOVECTOR
! 305: DO 10 J = 2, N
! 306: TMP1 = E( J-1 )**2
! 307: IF( ABS( D( J )*D( J-1 ) )*ULP**2+SAFEMN.GT.TMP1 ) THEN
! 308: ISPLIT( NSPLIT ) = J - 1
! 309: NSPLIT = NSPLIT + 1
! 310: WORK( J-1 ) = ZERO
! 311: ELSE
! 312: WORK( J-1 ) = TMP1
! 313: PIVMIN = MAX( PIVMIN, TMP1 )
! 314: END IF
! 315: 10 CONTINUE
! 316: ISPLIT( NSPLIT ) = N
! 317: PIVMIN = PIVMIN*SAFEMN
! 318: *
! 319: * Compute Interval and ATOLI
! 320: *
! 321: IF( IRANGE.EQ.3 ) THEN
! 322: *
! 323: * RANGE='I': Compute the interval containing eigenvalues
! 324: * IL through IU.
! 325: *
! 326: * Compute Gershgorin interval for entire (split) matrix
! 327: * and use it as the initial interval
! 328: *
! 329: GU = D( 1 )
! 330: GL = D( 1 )
! 331: TMP1 = ZERO
! 332: *
! 333: DO 20 J = 1, N - 1
! 334: TMP2 = SQRT( WORK( J ) )
! 335: GU = MAX( GU, D( J )+TMP1+TMP2 )
! 336: GL = MIN( GL, D( J )-TMP1-TMP2 )
! 337: TMP1 = TMP2
! 338: 20 CONTINUE
! 339: *
! 340: GU = MAX( GU, D( N )+TMP1 )
! 341: GL = MIN( GL, D( N )-TMP1 )
! 342: TNORM = MAX( ABS( GL ), ABS( GU ) )
! 343: GL = GL - FUDGE*TNORM*ULP*N - FUDGE*TWO*PIVMIN
! 344: GU = GU + FUDGE*TNORM*ULP*N + FUDGE*PIVMIN
! 345: *
! 346: * Compute Iteration parameters
! 347: *
! 348: ITMAX = INT( ( LOG( TNORM+PIVMIN )-LOG( PIVMIN ) ) /
! 349: $ LOG( TWO ) ) + 2
! 350: IF( ABSTOL.LE.ZERO ) THEN
! 351: ATOLI = ULP*TNORM
! 352: ELSE
! 353: ATOLI = ABSTOL
! 354: END IF
! 355: *
! 356: WORK( N+1 ) = GL
! 357: WORK( N+2 ) = GL
! 358: WORK( N+3 ) = GU
! 359: WORK( N+4 ) = GU
! 360: WORK( N+5 ) = GL
! 361: WORK( N+6 ) = GU
! 362: IWORK( 1 ) = -1
! 363: IWORK( 2 ) = -1
! 364: IWORK( 3 ) = N + 1
! 365: IWORK( 4 ) = N + 1
! 366: IWORK( 5 ) = IL - 1
! 367: IWORK( 6 ) = IU
! 368: *
! 369: CALL DLAEBZ( 3, ITMAX, N, 2, 2, NB, ATOLI, RTOLI, PIVMIN, D, E,
! 370: $ WORK, IWORK( 5 ), WORK( N+1 ), WORK( N+5 ), IOUT,
! 371: $ IWORK, W, IBLOCK, IINFO )
! 372: *
! 373: IF( IWORK( 6 ).EQ.IU ) THEN
! 374: WL = WORK( N+1 )
! 375: WLU = WORK( N+3 )
! 376: NWL = IWORK( 1 )
! 377: WU = WORK( N+4 )
! 378: WUL = WORK( N+2 )
! 379: NWU = IWORK( 4 )
! 380: ELSE
! 381: WL = WORK( N+2 )
! 382: WLU = WORK( N+4 )
! 383: NWL = IWORK( 2 )
! 384: WU = WORK( N+3 )
! 385: WUL = WORK( N+1 )
! 386: NWU = IWORK( 3 )
! 387: END IF
! 388: *
! 389: IF( NWL.LT.0 .OR. NWL.GE.N .OR. NWU.LT.1 .OR. NWU.GT.N ) THEN
! 390: INFO = 4
! 391: RETURN
! 392: END IF
! 393: ELSE
! 394: *
! 395: * RANGE='A' or 'V' -- Set ATOLI
! 396: *
! 397: TNORM = MAX( ABS( D( 1 ) )+ABS( E( 1 ) ),
! 398: $ ABS( D( N ) )+ABS( E( N-1 ) ) )
! 399: *
! 400: DO 30 J = 2, N - 1
! 401: TNORM = MAX( TNORM, ABS( D( J ) )+ABS( E( J-1 ) )+
! 402: $ ABS( E( J ) ) )
! 403: 30 CONTINUE
! 404: *
! 405: IF( ABSTOL.LE.ZERO ) THEN
! 406: ATOLI = ULP*TNORM
! 407: ELSE
! 408: ATOLI = ABSTOL
! 409: END IF
! 410: *
! 411: IF( IRANGE.EQ.2 ) THEN
! 412: WL = VL
! 413: WU = VU
! 414: ELSE
! 415: WL = ZERO
! 416: WU = ZERO
! 417: END IF
! 418: END IF
! 419: *
! 420: * Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU.
! 421: * NWL accumulates the number of eigenvalues .le. WL,
! 422: * NWU accumulates the number of eigenvalues .le. WU
! 423: *
! 424: M = 0
! 425: IEND = 0
! 426: INFO = 0
! 427: NWL = 0
! 428: NWU = 0
! 429: *
! 430: DO 70 JB = 1, NSPLIT
! 431: IOFF = IEND
! 432: IBEGIN = IOFF + 1
! 433: IEND = ISPLIT( JB )
! 434: IN = IEND - IOFF
! 435: *
! 436: IF( IN.EQ.1 ) THEN
! 437: *
! 438: * Special Case -- IN=1
! 439: *
! 440: IF( IRANGE.EQ.1 .OR. WL.GE.D( IBEGIN )-PIVMIN )
! 441: $ NWL = NWL + 1
! 442: IF( IRANGE.EQ.1 .OR. WU.GE.D( IBEGIN )-PIVMIN )
! 443: $ NWU = NWU + 1
! 444: IF( IRANGE.EQ.1 .OR. ( WL.LT.D( IBEGIN )-PIVMIN .AND. WU.GE.
! 445: $ D( IBEGIN )-PIVMIN ) ) THEN
! 446: M = M + 1
! 447: W( M ) = D( IBEGIN )
! 448: IBLOCK( M ) = JB
! 449: END IF
! 450: ELSE
! 451: *
! 452: * General Case -- IN > 1
! 453: *
! 454: * Compute Gershgorin Interval
! 455: * and use it as the initial interval
! 456: *
! 457: GU = D( IBEGIN )
! 458: GL = D( IBEGIN )
! 459: TMP1 = ZERO
! 460: *
! 461: DO 40 J = IBEGIN, IEND - 1
! 462: TMP2 = ABS( E( J ) )
! 463: GU = MAX( GU, D( J )+TMP1+TMP2 )
! 464: GL = MIN( GL, D( J )-TMP1-TMP2 )
! 465: TMP1 = TMP2
! 466: 40 CONTINUE
! 467: *
! 468: GU = MAX( GU, D( IEND )+TMP1 )
! 469: GL = MIN( GL, D( IEND )-TMP1 )
! 470: BNORM = MAX( ABS( GL ), ABS( GU ) )
! 471: GL = GL - FUDGE*BNORM*ULP*IN - FUDGE*PIVMIN
! 472: GU = GU + FUDGE*BNORM*ULP*IN + FUDGE*PIVMIN
! 473: *
! 474: * Compute ATOLI for the current submatrix
! 475: *
! 476: IF( ABSTOL.LE.ZERO ) THEN
! 477: ATOLI = ULP*MAX( ABS( GL ), ABS( GU ) )
! 478: ELSE
! 479: ATOLI = ABSTOL
! 480: END IF
! 481: *
! 482: IF( IRANGE.GT.1 ) THEN
! 483: IF( GU.LT.WL ) THEN
! 484: NWL = NWL + IN
! 485: NWU = NWU + IN
! 486: GO TO 70
! 487: END IF
! 488: GL = MAX( GL, WL )
! 489: GU = MIN( GU, WU )
! 490: IF( GL.GE.GU )
! 491: $ GO TO 70
! 492: END IF
! 493: *
! 494: * Set Up Initial Interval
! 495: *
! 496: WORK( N+1 ) = GL
! 497: WORK( N+IN+1 ) = GU
! 498: CALL DLAEBZ( 1, 0, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
! 499: $ D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),
! 500: $ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IM,
! 501: $ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
! 502: *
! 503: NWL = NWL + IWORK( 1 )
! 504: NWU = NWU + IWORK( IN+1 )
! 505: IWOFF = M - IWORK( 1 )
! 506: *
! 507: * Compute Eigenvalues
! 508: *
! 509: ITMAX = INT( ( LOG( GU-GL+PIVMIN )-LOG( PIVMIN ) ) /
! 510: $ LOG( TWO ) ) + 2
! 511: CALL DLAEBZ( 2, ITMAX, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
! 512: $ D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),
! 513: $ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IOUT,
! 514: $ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
! 515: *
! 516: * Copy Eigenvalues Into W and IBLOCK
! 517: * Use -JB for block number for unconverged eigenvalues.
! 518: *
! 519: DO 60 J = 1, IOUT
! 520: TMP1 = HALF*( WORK( J+N )+WORK( J+IN+N ) )
! 521: *
! 522: * Flag non-convergence.
! 523: *
! 524: IF( J.GT.IOUT-IINFO ) THEN
! 525: NCNVRG = .TRUE.
! 526: IB = -JB
! 527: ELSE
! 528: IB = JB
! 529: END IF
! 530: DO 50 JE = IWORK( J ) + 1 + IWOFF,
! 531: $ IWORK( J+IN ) + IWOFF
! 532: W( JE ) = TMP1
! 533: IBLOCK( JE ) = IB
! 534: 50 CONTINUE
! 535: 60 CONTINUE
! 536: *
! 537: M = M + IM
! 538: END IF
! 539: 70 CONTINUE
! 540: *
! 541: * If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU
! 542: * If NWL+1 < IL or NWU > IU, discard extra eigenvalues.
! 543: *
! 544: IF( IRANGE.EQ.3 ) THEN
! 545: IM = 0
! 546: IDISCL = IL - 1 - NWL
! 547: IDISCU = NWU - IU
! 548: *
! 549: IF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN
! 550: DO 80 JE = 1, M
! 551: IF( W( JE ).LE.WLU .AND. IDISCL.GT.0 ) THEN
! 552: IDISCL = IDISCL - 1
! 553: ELSE IF( W( JE ).GE.WUL .AND. IDISCU.GT.0 ) THEN
! 554: IDISCU = IDISCU - 1
! 555: ELSE
! 556: IM = IM + 1
! 557: W( IM ) = W( JE )
! 558: IBLOCK( IM ) = IBLOCK( JE )
! 559: END IF
! 560: 80 CONTINUE
! 561: M = IM
! 562: END IF
! 563: IF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN
! 564: *
! 565: * Code to deal with effects of bad arithmetic:
! 566: * Some low eigenvalues to be discarded are not in (WL,WLU],
! 567: * or high eigenvalues to be discarded are not in (WUL,WU]
! 568: * so just kill off the smallest IDISCL/largest IDISCU
! 569: * eigenvalues, by simply finding the smallest/largest
! 570: * eigenvalue(s).
! 571: *
! 572: * (If N(w) is monotone non-decreasing, this should never
! 573: * happen.)
! 574: *
! 575: IF( IDISCL.GT.0 ) THEN
! 576: WKILL = WU
! 577: DO 100 JDISC = 1, IDISCL
! 578: IW = 0
! 579: DO 90 JE = 1, M
! 580: IF( IBLOCK( JE ).NE.0 .AND.
! 581: $ ( W( JE ).LT.WKILL .OR. IW.EQ.0 ) ) THEN
! 582: IW = JE
! 583: WKILL = W( JE )
! 584: END IF
! 585: 90 CONTINUE
! 586: IBLOCK( IW ) = 0
! 587: 100 CONTINUE
! 588: END IF
! 589: IF( IDISCU.GT.0 ) THEN
! 590: *
! 591: WKILL = WL
! 592: DO 120 JDISC = 1, IDISCU
! 593: IW = 0
! 594: DO 110 JE = 1, M
! 595: IF( IBLOCK( JE ).NE.0 .AND.
! 596: $ ( W( JE ).GT.WKILL .OR. IW.EQ.0 ) ) THEN
! 597: IW = JE
! 598: WKILL = W( JE )
! 599: END IF
! 600: 110 CONTINUE
! 601: IBLOCK( IW ) = 0
! 602: 120 CONTINUE
! 603: END IF
! 604: IM = 0
! 605: DO 130 JE = 1, M
! 606: IF( IBLOCK( JE ).NE.0 ) THEN
! 607: IM = IM + 1
! 608: W( IM ) = W( JE )
! 609: IBLOCK( IM ) = IBLOCK( JE )
! 610: END IF
! 611: 130 CONTINUE
! 612: M = IM
! 613: END IF
! 614: IF( IDISCL.LT.0 .OR. IDISCU.LT.0 ) THEN
! 615: TOOFEW = .TRUE.
! 616: END IF
! 617: END IF
! 618: *
! 619: * If ORDER='B', do nothing -- the eigenvalues are already sorted
! 620: * by block.
! 621: * If ORDER='E', sort the eigenvalues from smallest to largest
! 622: *
! 623: IF( IORDER.EQ.1 .AND. NSPLIT.GT.1 ) THEN
! 624: DO 150 JE = 1, M - 1
! 625: IE = 0
! 626: TMP1 = W( JE )
! 627: DO 140 J = JE + 1, M
! 628: IF( W( J ).LT.TMP1 ) THEN
! 629: IE = J
! 630: TMP1 = W( J )
! 631: END IF
! 632: 140 CONTINUE
! 633: *
! 634: IF( IE.NE.0 ) THEN
! 635: ITMP1 = IBLOCK( IE )
! 636: W( IE ) = W( JE )
! 637: IBLOCK( IE ) = IBLOCK( JE )
! 638: W( JE ) = TMP1
! 639: IBLOCK( JE ) = ITMP1
! 640: END IF
! 641: 150 CONTINUE
! 642: END IF
! 643: *
! 644: INFO = 0
! 645: IF( NCNVRG )
! 646: $ INFO = INFO + 1
! 647: IF( TOOFEW )
! 648: $ INFO = INFO + 2
! 649: RETURN
! 650: *
! 651: * End of DSTEBZ
! 652: *
! 653: END
CVSweb interface <joel.bertrand@systella.fr>