OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
slarrd2.f
Go to the documentation of this file.
1 SUBROUTINE slarrd2( RANGE, ORDER, N, VL, VU, IL, IU, GERS,
2 $ RELTOL, D, E, E2, PIVMIN, NSPLIT, ISPLIT,
3 $ M, W, WERR, WL, WU, IBLOCK, INDEXW,
4 $ WORK, IWORK, DOL, DOU, INFO )
5*
6* -- ScaLAPACK auxiliary routine (version 2.0) --
7* Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver
8* July 4, 2010
9*
10* .. Scalar Arguments ..
11 CHARACTER ORDER, RANGE
12 INTEGER DOL, DOU, IL, INFO, IU, M, N, NSPLIT
13 REAL PIVMIN, RELTOL, VL, VU, WL, WU
14* ..
15* .. Array Arguments ..
16 INTEGER IBLOCK( * ), INDEXW( * ),
17 $ ISPLIT( * ), IWORK( * )
18 REAL D( * ), E( * ), E2( * ),
19 $ gers( * ), w( * ), werr( * ), work( * )
20* ..
21*
22* Purpose
23* =======
24*
25* SLARRD2 computes the eigenvalues of a symmetric tridiagonal
26* matrix T to limited initial accuracy. This is an auxiliary code to be
27* called from SLARRE2A.
28*
29* SLARRD2 has been created using the LAPACK code SLARRD
30* which itself stems from SSTEBZ. The motivation for creating
31* SLARRD2 is efficiency: When computing eigenvalues in parallel
32* and the input tridiagonal matrix splits into blocks, SLARRD2
33* can skip over blocks which contain none of the eigenvalues from
34* DOL to DOU for which the processor responsible. In extreme cases (such
35* as large matrices consisting of many blocks of small size, e.g. 2x2,
36* the gain can be substantial.
37*
38* Arguments
39* =========
40*
41* RANGE (input) CHARACTER
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
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) REAL
62* VU (input) REAL
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* GERS (input) REAL array, dimension (2*N)
76* The N Gerschgorin intervals (the i-th Gerschgorin interval
77* is (GERS(2*i-1), GERS(2*i)).
78*
79* RELTOL (input) REAL
80* The minimum relative width of an interval. When an interval
81* is narrower than RELTOL times the larger (in
82* magnitude) endpoint, then it is considered to be
83* sufficiently small, i.e., converged. Note: this should
84* always be at least radix*machine epsilon.
85*
86* D (input) REAL array, dimension (N)
87* The n diagonal elements of the tridiagonal matrix T.
88*
89* E (input) REAL array, dimension (N-1)
90* The (n-1) off-diagonal elements of the tridiagonal matrix T.
91*
92* E2 (input) REAL array, dimension (N-1)
93* The (n-1) squared off-diagonal elements of the tridiagonal matrix T.
94*
95* PIVMIN (input) REAL
96* The minimum pivot allowed in the sturm sequence for T.
97*
98* NSPLIT (input) INTEGER
99* The number of diagonal blocks in the matrix T.
100* 1 <= NSPLIT <= N.
101*
102* ISPLIT (input) INTEGER array, dimension (N)
103* The splitting points, at which T breaks up into submatrices.
104* The first submatrix consists of rows/columns 1 to ISPLIT(1),
105* the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
106* etc., and the NSPLIT-th consists of rows/columns
107* ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
108* (Only the first NSPLIT elements will actually be used, but
109* since the user cannot know a priori what value NSPLIT will
110* have, N words must be reserved for ISPLIT.)
111*
112* M (output) INTEGER
113* The actual number of eigenvalues found. 0 <= M <= N.
114* (See also the description of INFO=2,3.)
115*
116* W (output) REAL array, dimension (N)
117* On exit, the first M elements of W will contain the
118* eigenvalue approximations. SLARRD2 computes an interval
119* I_j = (a_j, b_j] that includes eigenvalue j. The eigenvalue
120* approximation is given as the interval midpoint
121* W(j)= ( a_j + b_j)/2. The corresponding error is bounded by
122* WERR(j) = abs( a_j - b_j)/2
123*
124* WERR (output) REAL array, dimension (N)
125* The error bound on the corresponding eigenvalue approximation
126* in W.
127*
128* WL (output) REAL
129* WU (output) REAL
130* The interval (WL, WU] contains all the wanted eigenvalues.
131* If RANGE='V', then WL=VL and WU=VU.
132* If RANGE='A', then WL and WU are the global Gerschgorin bounds
133* on the spectrum.
134* If RANGE='I', then WL and WU are computed by SLAEBZ from the
135* index range specified.
136*
137* IBLOCK (output) INTEGER array, dimension (N)
138* At each row/column j where E(j) is zero or small, the
139* matrix T is considered to split into a block diagonal
140* matrix. On exit, if INFO = 0, IBLOCK(i) specifies to which
141* block (from 1 to the number of blocks) the eigenvalue W(i)
142* belongs. (SLARRD2 may use the remaining N-M elements as
143* workspace.)
144*
145* INDEXW (output) INTEGER array, dimension (N)
146* The indices of the eigenvalues within each block (submatrix);
147* for example, INDEXW(i)= j and IBLOCK(i)=k imply that the
148* i-th eigenvalue W(i) is the j-th eigenvalue in block k.
149*
150* WORK (workspace) REAL array, dimension (4*N)
151*
152* IWORK (workspace) INTEGER array, dimension (3*N)
153*
154* DOL (input) INTEGER
155* DOU (input) INTEGER
156* If the user wants to work on only a selected part of the
157* representation tree, he can specify an index range DOL:DOU.
158* Otherwise, the setting DOL=1, DOU=N should be applied.
159* Note that DOL and DOU refer to the order in which the eigenvalues
160* are stored in W.
161*
162* INFO (output) INTEGER
163* = 0: successful exit
164* < 0: if INFO = -i, the i-th argument had an illegal value
165* > 0: some or all of the eigenvalues failed to converge or
166* were not computed:
167* =1 or 3: Bisection failed to converge for some
168* eigenvalues; these eigenvalues are flagged by a
169* negative block number. The effect is that the
170* eigenvalues may not be as accurate as the
171* absolute and relative tolerances. This is
172* generally caused by unexpectedly inaccurate
173* arithmetic.
174* =2 or 3: RANGE='I' only: Not all of the eigenvalues
175* IL:IU were found.
176* Effect: M < IU+1-IL
177* Cause: non-monotonic arithmetic, causing the
178* Sturm sequence to be non-monotonic.
179* Cure: recalculate, using RANGE='A', and pick
180* out eigenvalues IL:IU. In some cases,
181* increasing the PARAMETER "FUDGE" may
182* make things work.
183* = 4: RANGE='I', and the Gershgorin interval
184* initially used was too small. No eigenvalues
185* were computed.
186* Probable cause: your machine has sloppy
187* floating-point arithmetic.
188* Cure: Increase the PARAMETER "FUDGE",
189* recompile, and try again.
190*
191* Internal Parameters
192* ===================
193*
194* FUDGE REAL , default = 2 originally, increased to 10.
195* A "fudge factor" to widen the Gershgorin intervals. Ideally,
196* a value of 1 should work, but on machines with sloppy
197* arithmetic, this needs to be larger. The default for
198* publicly released versions should be large enough to handle
199* the worst machine around. Note that this has no effect
200* on accuracy of the solution.
201*
202* =====================================================================
203*
204* .. Parameters ..
205 REAL ZERO, ONE, TWO, HALF, FUDGE
206 PARAMETER ( ZERO = 0.0e0, one = 1.0e0,
207 $ two = 2.0e0, half = one/two,
208 $ fudge = 10.0e0 )
209
210* ..
211* .. Local Scalars ..
212 LOGICAL NCNVRG, TOOFEW
213 INTEGER I, IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,
214 $ IM, IN, IOFF, IORDER, IOUT, IRANGE, ITMAX,
215 $ itmp1, itmp2, iw, iwoff, j, jblk, jdisc, je,
216 $ jee, nb, nwl, nwu
217 REAL ATOLI, EPS, GL, GU, RTOLI, SPDIAM, TMP1, TMP2,
218 $ TNORM, UFLOW, WKILL, WLU, WUL
219
220* ..
221* .. Local Arrays ..
222 INTEGER IDUMMA( 1 )
223* ..
224* .. External Functions ..
225 LOGICAL LSAME
226 INTEGER ILAENV
227 REAL SLAMCH
228 EXTERNAL lsame, ilaenv, slamch
229* ..
230* .. External Subroutines ..
231 EXTERNAL slaebz
232* ..
233* .. Intrinsic Functions ..
234 INTRINSIC abs, int, log, max, min, sqrt
235* ..
236* .. Executable Statements ..
237*
238 info = 0
239*
240* Decode RANGE
241*
242 IF( lsame( range, 'A' ) ) THEN
243 irange = 1
244 ELSE IF( lsame( range, 'V' ) ) THEN
245 irange = 2
246 ELSE IF( lsame( range, 'i' ) ) THEN
247 IRANGE = 3
248 ELSE
249 IRANGE = 0
250 END IF
251*
252* Decode ORDER
253*
254 IF( LSAME( ORDER, 'b' ) ) THEN
255 IORDER = 2
256 ELSE IF( LSAME( ORDER, 'e' ) ) THEN
257 IORDER = 1
258 ELSE
259 IORDER = 0
260 END IF
261*
262* Check for Errors
263*
264.LE. IF( IRANGE0 ) THEN
265 INFO = -1
266.LE. ELSE IF( IORDER0 ) THEN
267 INFO = -2
268.LT. ELSE IF( N0 ) THEN
269 INFO = -3
270.EQ. ELSE IF( IRANGE2 ) THEN
271.GE. IF( VLVU )
272 $ INFO = -5
273.EQ..AND..LT..OR..GT. ELSE IF( IRANGE3 ( IL1 ILMAX( 1, N ) ) )
274 $ THEN
275 INFO = -6
276.EQ..AND..LT..OR..GT. ELSE IF( IRANGE3 ( IUMIN( N, IL ) IUN ) )
277 $ THEN
278 INFO = -7
279 END IF
280*
281.NE. IF( INFO0 ) THEN
282 RETURN
283 END IF
284
285* Initialize error flags
286 INFO = 0
287 NCNVRG = .FALSE.
288 TOOFEW = .FALSE.
289
290* Quick return if possible
291 M = 0
292.EQ. IF( N0 ) RETURN
293
294* Simplification:
295.EQ..AND..EQ..AND..EQ. IF( IRANGE3 IL1 IUN ) IRANGE = 1
296
297* Get machine constants
298 EPS = SLAMCH( 'p' )
299 UFLOW = SLAMCH( 'u' )
300
301
302* Special Case when N=1
303* Treat case of 1x1 matrix for quick return
304.EQ. IF( N1 ) THEN
305.EQ..OR. IF( (IRANGE1)
306.EQ..AND..GT..AND..LE..OR. $ ((IRANGE2)(D(1)VL)(D(1)VU))
307.EQ..AND..EQ..AND..EQ. $ ((IRANGE3)(IL1)(IU1)) ) THEN
308 M = 1
309 W(1) = D(1)
310* The computation error of the eigenvalue is zero
311 WERR(1) = ZERO
312 IBLOCK( 1 ) = 1
313 INDEXW( 1 ) = 1
314 ENDIF
315 RETURN
316 END IF
317
318* NB is the minimum vector length for vector bisection, or 0
319* if only scalar is to be done.
320 NB = ILAENV( 1, 'sstebz', ' ', N, -1, -1, -1 )
321.LE. IF( NB1 ) NB = 0
322
323* Find global spectral radius
324 GL = D(1)
325 GU = D(1)
326 DO 5 I = 1,N
327 GL = MIN( GL, GERS( 2*I - 1))
328 GU = MAX( GU, GERS(2*I) )
329 5 CONTINUE
330* Compute global Gerschgorin bounds and spectral diameter
331 TNORM = MAX( ABS( GL ), ABS( GU ) )
332 GL = GL - FUDGE*TNORM*EPS*N - FUDGE*TWO*PIVMIN
333 GU = GU + FUDGE*TNORM*EPS*N + FUDGE*TWO*PIVMIN
334 SPDIAM = GU - GL
335* Input arguments for SLAEBZ:
336* The relative tolerance. An interval (a,b] lies within
337* "relative tolerance" if b-a < RELTOL*max(|a|,|b|),
338 RTOLI = RELTOL
339 ATOLI = FUDGE*TWO*UFLOW + FUDGE*TWO*PIVMIN
340
341.EQ. IF( IRANGE3 ) THEN
342
343* RANGE='I': Compute an interval containing eigenvalues
344* IL through IU. The initial interval [GL,GU] from the global
345* Gerschgorin bounds GL and GU is refined by SLAEBZ.
346 ITMAX = INT( ( LOG( TNORM+PIVMIN )-LOG( PIVMIN ) ) /
347 $ LOG( TWO ) ) + 2
348 WORK( N+1 ) = GL
349 WORK( N+2 ) = GL
350 WORK( N+3 ) = GU
351 WORK( N+4 ) = GU
352 WORK( N+5 ) = GL
353 WORK( N+6 ) = GU
354 IWORK( 1 ) = -1
355 IWORK( 2 ) = -1
356 IWORK( 3 ) = N + 1
357 IWORK( 4 ) = N + 1
358 IWORK( 5 ) = IL - 1
359 IWORK( 6 ) = IU
360*
361 CALL SLAEBZ( 3, ITMAX, N, 2, 2, NB, ATOLI, RTOLI, PIVMIN,
362 $ D, E, E2, IWORK( 5 ), WORK( N+1 ), WORK( N+5 ), IOUT,
363 $ IWORK, W, IBLOCK, IINFO )
364.NE. IF( IINFO 0 ) THEN
365 INFO = IINFO
366 RETURN
367 END IF
368* On exit, output intervals may not be ordered by ascending negcount
369.EQ. IF( IWORK( 6 )IU ) THEN
370 WL = WORK( N+1 )
371 WLU = WORK( N+3 )
372 NWL = IWORK( 1 )
373 WU = WORK( N+4 )
374 WUL = WORK( N+2 )
375 NWU = IWORK( 4 )
376 ELSE
377 WL = WORK( N+2 )
378 WLU = WORK( N+4 )
379 NWL = IWORK( 2 )
380 WU = WORK( N+3 )
381 WUL = WORK( N+1 )
382 NWU = IWORK( 3 )
383 END IF
384* On exit, the interval [WL, WLU] contains a value with negcount NWL,
385* and [WUL, WU] contains a value with negcount NWU.
386.LT..OR..GE..OR..LT..OR..GT. IF( NWL0 NWLN NWU1 NWUN ) THEN
387 INFO = 4
388 RETURN
389 END IF
390
391.EQ. ELSEIF( IRANGE2 ) THEN
392 WL = VL
393 WU = VU
394
395.EQ. ELSEIF( IRANGE1 ) THEN
396 WL = GL
397 WU = GU
398 ENDIF
399
400
401
402* Find Eigenvalues -- Loop Over blocks and recompute NWL and NWU.
403* NWL accumulates the number of eigenvalues .le. WL,
404* NWU accumulates the number of eigenvalues .le. WU
405 M = 0
406 IEND = 0
407 INFO = 0
408 NWL = 0
409 NWU = 0
410*
411 DO 70 JBLK = 1, NSPLIT
412 IOFF = IEND
413 IBEGIN = IOFF + 1
414 IEND = ISPLIT( JBLK )
415 IN = IEND - IOFF
416*
417.EQ. IF( IRANGE1 ) THEN
418.LT..OR..GT. IF( (IENDDOL)(IBEGINDOU) ) THEN
419* the local block contains none of eigenvalues that matter
420* to this processor
421 NWU = NWU + IN
422 DO 30 J = 1, IN
423 M = M + 1
424 IBLOCK( M ) = JBLK
425 30 CONTINUE
426 GO TO 70
427 END IF
428 END IF
429
430.EQ. IF( IN1 ) THEN
431* 1x1 block
432.GE. IF( WLD( IBEGIN )-PIVMIN )
433 $ NWL = NWL + 1
434.GE. IF( WUD( IBEGIN )-PIVMIN )
435 $ NWU = NWU + 1
436.EQ..OR..LT..AND..GE. IF( IRANGE1 ( WLD( IBEGIN )-PIVMIN WU
437 $ D( IBEGIN )-PIVMIN ) ) THEN
438 M = M + 1
439 W( M ) = D( IBEGIN )
440 WERR(M) = ZERO
441* The gap for a single block doesn't matter for the later
442* algorithm and is assigned an arbitrary large value
443 IBLOCK( M ) = JBLK
444 INDEXW( M ) = 1
445 END IF
446 ELSE
447* General Case - block of size IN > 2
448* Compute local Gerschgorin interval and use it as the initial
449* interval for SLAEBZ
450 GU = D( IBEGIN )
451 GL = D( IBEGIN )
452 TMP1 = ZERO
453
454 DO 40 J = IBEGIN, IEND
455 GL = MIN( GL, GERS( 2*J - 1))
456 GU = MAX( GU, GERS(2*J) )
457 40 CONTINUE
458 SPDIAM = GU - GL
459 GL = GL - FUDGE*TNORM*EPS*IN - FUDGE*PIVMIN
460 GU = GU + FUDGE*TNORM*EPS*IN + FUDGE*PIVMIN
461*
462.GT. IF( IRANGE1 ) THEN
463.LT. IF( GUWL ) THEN
464* the local block contains none of the wanted eigenvalues
465 NWL = NWL + IN
466 NWU = NWU + IN
467 GO TO 70
468 END IF
469* refine search interval if possible, only range (WL,WU] matters
470 GL = MAX( GL, WL )
471 GU = MIN( GU, WU )
472.GE. IF( GLGU )
473 $ GO TO 70
474 END IF
475
476* Find negcount of initial interval boundaries GL and GU
477 WORK( N+1 ) = GL
478 WORK( N+IN+1 ) = GU
479 CALL SLAEBZ( 1, 0, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
480 $ D( IBEGIN ), E( IBEGIN ), E2( IBEGIN ),
481 $ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IM,
482 $ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
483.NE. IF( IINFO 0 ) THEN
484 INFO = IINFO
485 RETURN
486 END IF
487*
488 NWL = NWL + IWORK( 1 )
489 NWU = NWU + IWORK( IN+1 )
490 IWOFF = M - IWORK( 1 )
491
492* Compute Eigenvalues
493 ITMAX = INT( ( LOG( GU-GL+PIVMIN )-LOG( PIVMIN ) ) /
494 $ LOG( TWO ) ) + 2
495 CALL SLAEBZ( 2, ITMAX, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
496 $ D( IBEGIN ), E( IBEGIN ), E2( IBEGIN ),
497 $ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IOUT,
498 $ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
499.NE. IF( IINFO 0 ) THEN
500 INFO = IINFO
501 RETURN
502 END IF
503*
504* Copy eigenvalues into W and IBLOCK
505* Use -JBLK for block number for unconverged eigenvalues.
506* Loop over the number of output intervals from SLAEBZ
507 DO 60 J = 1, IOUT
508* eigenvalue approximation is middle point of interval
509 TMP1 = HALF*( WORK( J+N )+WORK( J+IN+N ) )
510* semi length of error interval
511 TMP2 = HALF*ABS( WORK( J+N )-WORK( J+IN+N ) )
512.GT. IF( JIOUT-IINFO ) THEN
513* Flag non-convergence.
514 NCNVRG = .TRUE.
515 IB = -JBLK
516 ELSE
517 IB = JBLK
518 END IF
519 DO 50 JE = IWORK( J ) + 1 + IWOFF,
520 $ IWORK( J+IN ) + IWOFF
521 W( JE ) = TMP1
522 WERR( JE ) = TMP2
523 INDEXW( JE ) = JE - IWOFF
524 IBLOCK( JE ) = IB
525 50 CONTINUE
526 60 CONTINUE
527*
528 M = M + IM
529 END IF
530 70 CONTINUE
531
532* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU
533* If NWL+1 < IL or NWU > IU, discard extra eigenvalues.
534.EQ. IF( IRANGE3 ) THEN
535 IDISCL = IL - 1 - NWL
536 IDISCU = NWU - IU
537*
538.GT. IF( IDISCL0 ) THEN
539 IM = 0
540 DO 80 JE = 1, M
541* Remove some of the smallest eigenvalues from the left so that
542* at the end IDISCL =0. Move all eigenvalues up to the left.
543.LE..AND..GT. IF( W( JE )WLU IDISCL0 ) THEN
544 IDISCL = IDISCL - 1
545 ELSE
546 IM = IM + 1
547 W( IM ) = W( JE )
548 WERR( IM ) = WERR( JE )
549 INDEXW( IM ) = INDEXW( JE )
550 IBLOCK( IM ) = IBLOCK( JE )
551 END IF
552 80 CONTINUE
553 M = IM
554 END IF
555.GT. IF( IDISCU0 ) THEN
556* Remove some of the largest eigenvalues from the right so that
557* at the end IDISCU =0. Move all eigenvalues up to the left.
558 IM=M+1
559 DO 81 JE = M, 1, -1
560.GE..AND..GT. IF( W( JE )WUL IDISCU0 ) THEN
561 IDISCU = IDISCU - 1
562 ELSE
563 IM = IM - 1
564 W( IM ) = W( JE )
565 WERR( IM ) = WERR( JE )
566 INDEXW( IM ) = INDEXW( JE )
567 IBLOCK( IM ) = IBLOCK( JE )
568 END IF
569 81 CONTINUE
570 JEE = 0
571 DO 82 JE = IM, M
572 JEE = JEE + 1
573 W( JEE ) = W( JE )
574 WERR( JEE ) = WERR( JE )
575 INDEXW( JEE ) = INDEXW( JE )
576 IBLOCK( JEE ) = IBLOCK( JE )
577 82 CONTINUE
578 M = M-IM+1
579 END IF
580
581.GT..OR..GT. IF( IDISCL0 IDISCU0 ) THEN
582* Code to deal with effects of bad arithmetic. (If N(w) is
583* monotone non-decreasing, this should never happen.)
584* Some low eigenvalues to be discarded are not in (WL,WLU],
585* or high eigenvalues to be discarded are not in (WUL,WU]
586* so just kill off the smallest IDISCL/largest IDISCU
587* eigenvalues, by marking the corresponding IBLOCK = 0
588.GT. IF( IDISCL0 ) THEN
589 WKILL = WU
590 DO 100 JDISC = 1, IDISCL
591 IW = 0
592 DO 90 JE = 1, M
593.NE..AND. IF( IBLOCK( JE )0
594.LT..OR..EQ. $ ( W( JE )WKILL IW0 ) ) THEN
595 IW = JE
596 WKILL = W( JE )
597 END IF
598 90 CONTINUE
599 IBLOCK( IW ) = 0
600 100 CONTINUE
601 END IF
602.GT. IF( IDISCU0 ) THEN
603 WKILL = WL
604 DO 120 JDISC = 1, IDISCU
605 IW = 0
606 DO 110 JE = 1, M
607.NE..AND. IF( IBLOCK( JE )0
608.GE..OR..EQ. $ ( W( JE )WKILL IW0 ) ) THEN
609 IW = JE
610 WKILL = W( JE )
611 END IF
612 110 CONTINUE
613 IBLOCK( IW ) = 0
614 120 CONTINUE
615 END IF
616* Now erase all eigenvalues with IBLOCK set to zero
617 IM = 0
618 DO 130 JE = 1, M
619.NE. IF( IBLOCK( JE )0 ) THEN
620 IM = IM + 1
621 W( IM ) = W( JE )
622 WERR( IM ) = WERR( JE )
623 INDEXW( IM ) = INDEXW( JE )
624 IBLOCK( IM ) = IBLOCK( JE )
625 END IF
626 130 CONTINUE
627 M = IM
628 END IF
629.LT..OR..LT. IF( IDISCL0 IDISCU0 ) THEN
630 TOOFEW = .TRUE.
631 END IF
632 END IF
633*
634.EQ..AND..NE..OR. IF(( IRANGE1 MN )
635.EQ..AND..NE. $ ( IRANGE3 MIU-IL+1 ) ) THEN
636 TOOFEW = .TRUE.
637 END IF
638
639* If ORDER='B',(IBLOCK = 2), do nothing the eigenvalues are already sorted
640* by block.
641* If ORDER='E',(IBLOCK = 1), sort the eigenvalues from smallest to largest
642
643.EQ..AND..GT. IF( IORDER1 NSPLIT1 ) THEN
644 DO 150 JE = 1, M - 1
645 IE = 0
646 TMP1 = W( JE )
647 DO 140 J = JE + 1, M
648.LT. IF( W( J )TMP1 ) THEN
649 IE = J
650 TMP1 = W( J )
651 END IF
652 140 CONTINUE
653.NE. IF( IE0 ) THEN
654 TMP2 = WERR( IE )
655 ITMP1 = IBLOCK( IE )
656 ITMP2 = INDEXW( IE )
657 W( IE ) = W( JE )
658 WERR( IE ) = WERR( JE )
659 IBLOCK( IE ) = IBLOCK( JE )
660 INDEXW( IE ) = INDEXW( JE )
661 W( JE ) = TMP1
662 WERR( JE ) = TMP2
663 IBLOCK( JE ) = ITMP1
664 INDEXW( JE ) = ITMP2
665 END IF
666 150 CONTINUE
667 END IF
668*
669 INFO = 0
670 IF( NCNVRG )
671 $ INFO = INFO + 1
672 IF( TOOFEW )
673 $ INFO = INFO + 2
674 RETURN
675*
676* End of SLARRD2
677*
678 END
subroutine slaebz(ijob, nitmax, n, mmax, minp, nbmin, abstol, reltol, pivmin, d, e, e2, nval, ab, c, mout, nab, work, iwork, info)
SLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than ...
Definition slaebz.f:319
subroutine sstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
SSTEBZ
Definition sstebz.f:273
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21
subroutine slarrd2(range, order, n, vl, vu, il, iu, gers, reltol, d, e, e2, pivmin, nsplit, isplit, m, w, werr, wl, wu, iblock, indexw, work, iwork, dol, dou, info)
Definition slarrd2.f:5