LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
sstebz.f
Go to the documentation of this file.
1*> \brief \b SSTEBZ
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download SSTEBZ + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sstebz.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sstebz.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sstebz.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE SSTEBZ( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D, E,
20* M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,
21* INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER ORDER, RANGE
25* INTEGER IL, INFO, IU, M, N, NSPLIT
26* REAL ABSTOL, VL, VU
27* ..
28* .. Array Arguments ..
29* INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * )
30* REAL D( * ), E( * ), W( * ), WORK( * )
31* ..
32*
33*
34*> \par Purpose:
35* =============
36*>
37*> \verbatim
38*>
39*> SSTEBZ computes the eigenvalues of a symmetric tridiagonal
40*> matrix T. The user may ask for all eigenvalues, all eigenvalues
41*> in the half-open interval (VL, VU], or the IL-th through IU-th
42*> eigenvalues.
43*>
44*> To avoid overflow, the matrix must be scaled so that its
45*> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest
46*> accuracy, it should not be much smaller than that.
47*>
48*> See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal
49*> Matrix", Report CS41, Computer Science Dept., Stanford
50*> University, July 21, 1966.
51*> \endverbatim
52*
53* Arguments:
54* ==========
55*
56*> \param[in] RANGE
57*> \verbatim
58*> RANGE is CHARACTER*1
59*> = 'A': ("All") all eigenvalues will be found.
60*> = 'V': ("Value") all eigenvalues in the half-open interval
61*> (VL, VU] will be found.
62*> = 'I': ("Index") the IL-th through IU-th eigenvalues (of the
63*> entire matrix) will be found.
64*> \endverbatim
65*>
66*> \param[in] ORDER
67*> \verbatim
68*> ORDER is CHARACTER*1
69*> = 'B': ("By Block") the eigenvalues will be grouped by
70*> split-off block (see IBLOCK, ISPLIT) and
71*> ordered from smallest to largest within
72*> the block.
73*> = 'E': ("Entire matrix")
74*> the eigenvalues for the entire matrix
75*> will be ordered from smallest to
76*> largest.
77*> \endverbatim
78*>
79*> \param[in] N
80*> \verbatim
81*> N is INTEGER
82*> The order of the tridiagonal matrix T. N >= 0.
83*> \endverbatim
84*>
85*> \param[in] VL
86*> \verbatim
87*> VL is REAL
88*>
89*> If RANGE='V', the lower bound of the interval to
90*> be searched for eigenvalues. Eigenvalues less than or equal
91*> to VL, or greater than VU, will not be returned. VL < VU.
92*> Not referenced if RANGE = 'A' or 'I'.
93*> \endverbatim
94*>
95*> \param[in] VU
96*> \verbatim
97*> VU is REAL
98*>
99*> If RANGE='V', the upper bound of the interval to
100*> be searched for eigenvalues. Eigenvalues less than or equal
101*> to VL, or greater than VU, will not be returned. VL < VU.
102*> Not referenced if RANGE = 'A' or 'I'.
103*> \endverbatim
104*>
105*> \param[in] IL
106*> \verbatim
107*> IL is INTEGER
108*>
109*> If RANGE='I', the index of the
110*> smallest eigenvalue to be returned.
111*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
112*> Not referenced if RANGE = 'A' or 'V'.
113*> \endverbatim
114*>
115*> \param[in] IU
116*> \verbatim
117*> IU is INTEGER
118*>
119*> If RANGE='I', the index of the
120*> largest eigenvalue to be returned.
121*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
122*> Not referenced if RANGE = 'A' or 'V'.
123*> \endverbatim
124*>
125*> \param[in] ABSTOL
126*> \verbatim
127*> ABSTOL is REAL
128*> The absolute tolerance for the eigenvalues. An eigenvalue
129*> (or cluster) is considered to be located if it has been
130*> determined to lie in an interval whose width is ABSTOL or
131*> less. If ABSTOL is less than or equal to zero, then ULP*|T|
132*> will be used, where |T| means the 1-norm of T.
133*>
134*> Eigenvalues will be computed most accurately when ABSTOL is
135*> set to twice the underflow threshold 2*SLAMCH('S'), not zero.
136*> \endverbatim
137*>
138*> \param[in] D
139*> \verbatim
140*> D is REAL array, dimension (N)
141*> The n diagonal elements of the tridiagonal matrix T.
142*> \endverbatim
143*>
144*> \param[in] E
145*> \verbatim
146*> E is REAL array, dimension (N-1)
147*> The (n-1) off-diagonal elements of the tridiagonal matrix T.
148*> \endverbatim
149*>
150*> \param[out] M
151*> \verbatim
152*> M is INTEGER
153*> The actual number of eigenvalues found. 0 <= M <= N.
154*> (See also the description of INFO=2,3.)
155*> \endverbatim
156*>
157*> \param[out] NSPLIT
158*> \verbatim
159*> NSPLIT is INTEGER
160*> The number of diagonal blocks in the matrix T.
161*> 1 <= NSPLIT <= N.
162*> \endverbatim
163*>
164*> \param[out] W
165*> \verbatim
166*> W is REAL array, dimension (N)
167*> On exit, the first M elements of W will contain the
168*> eigenvalues. (SSTEBZ may use the remaining N-M elements as
169*> workspace.)
170*> \endverbatim
171*>
172*> \param[out] IBLOCK
173*> \verbatim
174*> IBLOCK is INTEGER array, dimension (N)
175*> At each row/column j where E(j) is zero or small, the
176*> matrix T is considered to split into a block diagonal
177*> matrix. On exit, if INFO = 0, IBLOCK(i) specifies to which
178*> block (from 1 to the number of blocks) the eigenvalue W(i)
179*> belongs. (SSTEBZ may use the remaining N-M elements as
180*> workspace.)
181*> \endverbatim
182*>
183*> \param[out] ISPLIT
184*> \verbatim
185*> ISPLIT is INTEGER array, dimension (N)
186*> The splitting points, at which T breaks up into submatrices.
187*> The first submatrix consists of rows/columns 1 to ISPLIT(1),
188*> the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
189*> etc., and the NSPLIT-th consists of rows/columns
190*> ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
191*> (Only the first NSPLIT elements will actually be used, but
192*> since the user cannot know a priori what value NSPLIT will
193*> have, N words must be reserved for ISPLIT.)
194*> \endverbatim
195*>
196*> \param[out] WORK
197*> \verbatim
198*> WORK is REAL array, dimension (4*N)
199*> \endverbatim
200*>
201*> \param[out] IWORK
202*> \verbatim
203*> IWORK is INTEGER array, dimension (3*N)
204*> \endverbatim
205*>
206*> \param[out] INFO
207*> \verbatim
208*> INFO is INTEGER
209*> = 0: successful exit
210*> < 0: if INFO = -i, the i-th argument had an illegal value
211*> > 0: some or all of the eigenvalues failed to converge or
212*> were not computed:
213*> =1 or 3: Bisection failed to converge for some
214*> eigenvalues; these eigenvalues are flagged by a
215*> negative block number. The effect is that the
216*> eigenvalues may not be as accurate as the
217*> absolute and relative tolerances. This is
218*> generally caused by unexpectedly inaccurate
219*> arithmetic.
220*> =2 or 3: RANGE='I' only: Not all of the eigenvalues
221*> IL:IU were found.
222*> Effect: M < IU+1-IL
223*> Cause: non-monotonic arithmetic, causing the
224*> Sturm sequence to be non-monotonic.
225*> Cure: recalculate, using RANGE='A', and pick
226*> out eigenvalues IL:IU. In some cases,
227*> increasing the PARAMETER "FUDGE" may
228*> make things work.
229*> = 4: RANGE='I', and the Gershgorin interval
230*> initially used was too small. No eigenvalues
231*> were computed.
232*> Probable cause: your machine has sloppy
233*> floating-point arithmetic.
234*> Cure: Increase the PARAMETER "FUDGE",
235*> recompile, and try again.
236*> \endverbatim
237*
238*> \par Internal Parameters:
239* =========================
240*>
241*> \verbatim
242*> RELFAC REAL, default = 2.0e0
243*> The relative tolerance. An interval (a,b] lies within
244*> "relative tolerance" if b-a < RELFAC*ulp*max(|a|,|b|),
245*> where "ulp" is the machine precision (distance from 1 to
246*> the next larger floating point number.)
247*>
248*> FUDGE REAL, default = 2
249*> A "fudge factor" to widen the Gershgorin intervals. Ideally,
250*> a value of 1 should work, but on machines with sloppy
251*> arithmetic, this needs to be larger. The default for
252*> publicly released versions should be large enough to handle
253*> the worst machine around. Note that this has no effect
254*> on accuracy of the solution.
255*> \endverbatim
256*
257* Authors:
258* ========
259*
260*> \author Univ. of Tennessee
261*> \author Univ. of California Berkeley
262*> \author Univ. of Colorado Denver
263*> \author NAG Ltd.
264*
265*> \ingroup stebz
266*
267* =====================================================================
268 SUBROUTINE sstebz( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D,
269 $ E,
270 $ M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,
271 $ INFO )
272*
273* -- LAPACK computational routine --
274* -- LAPACK is a software package provided by Univ. of Tennessee, --
275* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
276*
277* .. Scalar Arguments ..
278 CHARACTER ORDER, RANGE
279 INTEGER IL, INFO, IU, M, N, NSPLIT
280 REAL ABSTOL, VL, VU
281* ..
282* .. Array Arguments ..
283 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * )
284 REAL D( * ), E( * ), W( * ), WORK( * )
285* ..
286*
287* =====================================================================
288*
289* .. Parameters ..
290 REAL ZERO, ONE, TWO, HALF
291 PARAMETER ( ZERO = 0.0e0, one = 1.0e0, two = 2.0e0,
292 $ half = 1.0e0 / two )
293 REAL FUDGE, RELFAC
294 parameter( fudge = 2.1e0, relfac = 2.0e0 )
295* ..
296* .. Local Scalars ..
297 LOGICAL NCNVRG, TOOFEW
298 INTEGER IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,
299 $ IM, IN, IOFF, IORDER, IOUT, IRANGE, ITMAX,
300 $ itmp1, iw, iwoff, j, jb, jdisc, je, nb, nwl,
301 $ nwu
302 REAL ATOLI, BNORM, GL, GU, PIVMIN, RTOLI, SAFEMN,
303 $ TMP1, TMP2, TNORM, ULP, WKILL, WL, WLU, WU, WUL
304* ..
305* .. Local Arrays ..
306 INTEGER IDUMMA( 1 )
307* ..
308* .. External Functions ..
309 LOGICAL LSAME
310 INTEGER ILAENV
311 REAL SLAMCH
312 EXTERNAL lsame, ilaenv, slamch
313* ..
314* .. External Subroutines ..
315 EXTERNAL slaebz, xerbla
316* ..
317* .. Intrinsic Functions ..
318 INTRINSIC abs, int, log, max, min, sqrt
319* ..
320* .. Executable Statements ..
321*
322 info = 0
323*
324* Decode RANGE
325*
326 IF( lsame( range, 'A' ) ) THEN
327 irange = 1
328 ELSE IF( lsame( range, 'V' ) ) THEN
329 irange = 2
330 ELSE IF( lsame( range, 'I' ) ) THEN
331 irange = 3
332 ELSE
333 irange = 0
334 END IF
335*
336* Decode ORDER
337*
338 IF( lsame( order, 'B' ) ) THEN
339 iorder = 2
340 ELSE IF( lsame( order, 'E' ) ) THEN
341 iorder = 1
342 ELSE
343 iorder = 0
344 END IF
345*
346* Check for Errors
347*
348 IF( irange.LE.0 ) THEN
349 info = -1
350 ELSE IF( iorder.LE.0 ) THEN
351 info = -2
352 ELSE IF( n.LT.0 ) THEN
353 info = -3
354 ELSE IF( irange.EQ.2 ) THEN
355 IF( vl.GE.vu ) info = -5
356 ELSE IF( irange.EQ.3 .AND. ( il.LT.1 .OR. il.GT.max( 1, n ) ) )
357 $ THEN
358 info = -6
359 ELSE IF( irange.EQ.3 .AND. ( iu.LT.min( n, il ) .OR. iu.GT.n ) )
360 $ THEN
361 info = -7
362 END IF
363*
364 IF( info.NE.0 ) THEN
365 CALL xerbla( 'SSTEBZ', -info )
366 RETURN
367 END IF
368*
369* Initialize error flags
370*
371 info = 0
372 ncnvrg = .false.
373 toofew = .false.
374*
375* Quick return if possible
376*
377 m = 0
378 IF( n.EQ.0 )
379 $ RETURN
380*
381* Simplifications:
382*
383 IF( irange.EQ.3 .AND. il.EQ.1 .AND. iu.EQ.n )
384 $ irange = 1
385*
386* Get machine constants
387* NB is the minimum vector length for vector bisection, or 0
388* if only scalar is to be done.
389*
390 safemn = slamch( 'S' )
391 ulp = slamch( 'P' )
392 rtoli = ulp*relfac
393 nb = ilaenv( 1, 'SSTEBZ', ' ', n, -1, -1, -1 )
394 IF( nb.LE.1 )
395 $ nb = 0
396*
397* Special Case when N=1
398*
399 IF( n.EQ.1 ) THEN
400 nsplit = 1
401 isplit( 1 ) = 1
402 IF( irange.EQ.2 .AND. ( vl.GE.d( 1 ) .OR. vu.LT.d( 1 ) ) ) THEN
403 m = 0
404 ELSE
405 w( 1 ) = d( 1 )
406 iblock( 1 ) = 1
407 m = 1
408 END IF
409 RETURN
410 END IF
411*
412* Compute Splitting Points
413*
414 nsplit = 1
415 work( n ) = zero
416 pivmin = one
417*
418 DO 10 j = 2, n
419 tmp1 = e( j-1 )**2
420 IF( abs( d( j )*d( j-1 ) )*ulp**2+safemn.GT.tmp1 ) THEN
421 isplit( nsplit ) = j - 1
422 nsplit = nsplit + 1
423 work( j-1 ) = zero
424 ELSE
425 work( j-1 ) = tmp1
426 pivmin = max( pivmin, tmp1 )
427 END IF
428 10 CONTINUE
429 isplit( nsplit ) = n
430 pivmin = pivmin*safemn
431*
432* Compute Interval and ATOLI
433*
434 IF( irange.EQ.3 ) THEN
435*
436* RANGE='I': Compute the interval containing eigenvalues
437* IL through IU.
438*
439* Compute Gershgorin interval for entire (split) matrix
440* and use it as the initial interval
441*
442 gu = d( 1 )
443 gl = d( 1 )
444 tmp1 = zero
445*
446 DO 20 j = 1, n - 1
447 tmp2 = sqrt( work( j ) )
448 gu = max( gu, d( j )+tmp1+tmp2 )
449 gl = min( gl, d( j )-tmp1-tmp2 )
450 tmp1 = tmp2
451 20 CONTINUE
452*
453 gu = max( gu, d( n )+tmp1 )
454 gl = min( gl, d( n )-tmp1 )
455 tnorm = max( abs( gl ), abs( gu ) )
456 gl = gl - fudge*tnorm*ulp*real( n ) - fudge*two*pivmin
457 gu = gu + fudge*tnorm*ulp*real( n ) + fudge*pivmin
458*
459* Compute Iteration parameters
460*
461 itmax = int( ( log( tnorm+pivmin )-log( pivmin ) ) /
462 $ log( two ) ) + 2
463 IF( abstol.LE.zero ) THEN
464 atoli = ulp*tnorm
465 ELSE
466 atoli = abstol
467 END IF
468*
469 work( n+1 ) = gl
470 work( n+2 ) = gl
471 work( n+3 ) = gu
472 work( n+4 ) = gu
473 work( n+5 ) = gl
474 work( n+6 ) = gu
475 iwork( 1 ) = -1
476 iwork( 2 ) = -1
477 iwork( 3 ) = n + 1
478 iwork( 4 ) = n + 1
479 iwork( 5 ) = il - 1
480 iwork( 6 ) = iu
481*
482 CALL slaebz( 3, itmax, n, 2, 2, nb, atoli, rtoli, pivmin, d,
483 $ e,
484 $ work, iwork( 5 ), work( n+1 ), work( n+5 ), iout,
485 $ iwork, w, iblock, iinfo )
486*
487 IF( iwork( 6 ).EQ.iu ) THEN
488 wl = work( n+1 )
489 wlu = work( n+3 )
490 nwl = iwork( 1 )
491 wu = work( n+4 )
492 wul = work( n+2 )
493 nwu = iwork( 4 )
494 ELSE
495 wl = work( n+2 )
496 wlu = work( n+4 )
497 nwl = iwork( 2 )
498 wu = work( n+3 )
499 wul = work( n+1 )
500 nwu = iwork( 3 )
501 END IF
502*
503 IF( nwl.LT.0 .OR. nwl.GE.n .OR. nwu.LT.1 .OR. nwu.GT.n ) THEN
504 info = 4
505 RETURN
506 END IF
507 ELSE
508*
509* RANGE='A' or 'V' -- Set ATOLI
510*
511 tnorm = max( abs( d( 1 ) )+abs( e( 1 ) ),
512 $ abs( d( n ) )+abs( e( n-1 ) ) )
513*
514 DO 30 j = 2, n - 1
515 tnorm = max( tnorm, abs( d( j ) )+abs( e( j-1 ) )+
516 $ abs( e( j ) ) )
517 30 CONTINUE
518*
519 IF( abstol.LE.zero ) THEN
520 atoli = ulp*tnorm
521 ELSE
522 atoli = abstol
523 END IF
524*
525 IF( irange.EQ.2 ) THEN
526 wl = vl
527 wu = vu
528 ELSE
529 wl = zero
530 wu = zero
531 END IF
532 END IF
533*
534* Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU.
535* NWL accumulates the number of eigenvalues .le. WL,
536* NWU accumulates the number of eigenvalues .le. WU
537*
538 m = 0
539 iend = 0
540 info = 0
541 nwl = 0
542 nwu = 0
543*
544 DO 70 jb = 1, nsplit
545 ioff = iend
546 ibegin = ioff + 1
547 iend = isplit( jb )
548 in = iend - ioff
549*
550 IF( in.EQ.1 ) THEN
551*
552* Special Case -- IN=1
553*
554 IF( irange.EQ.1 .OR. wl.GE.d( ibegin )-pivmin )
555 $ nwl = nwl + 1
556 IF( irange.EQ.1 .OR. wu.GE.d( ibegin )-pivmin )
557 $ nwu = nwu + 1
558 IF( irange.EQ.1 .OR. ( wl.LT.d( ibegin )-pivmin .AND. wu.GE.
559 $ d( ibegin )-pivmin ) ) THEN
560 m = m + 1
561 w( m ) = d( ibegin )
562 iblock( m ) = jb
563 END IF
564 ELSE
565*
566* General Case -- IN > 1
567*
568* Compute Gershgorin Interval
569* and use it as the initial interval
570*
571 gu = d( ibegin )
572 gl = d( ibegin )
573 tmp1 = zero
574*
575 DO 40 j = ibegin, iend - 1
576 tmp2 = abs( e( j ) )
577 gu = max( gu, d( j )+tmp1+tmp2 )
578 gl = min( gl, d( j )-tmp1-tmp2 )
579 tmp1 = tmp2
580 40 CONTINUE
581*
582 gu = max( gu, d( iend )+tmp1 )
583 gl = min( gl, d( iend )-tmp1 )
584 bnorm = max( abs( gl ), abs( gu ) )
585 gl = gl - fudge*bnorm*ulp*real( in ) - fudge*pivmin
586 gu = gu + fudge*bnorm*ulp*real( in ) + fudge*pivmin
587*
588* Compute ATOLI for the current submatrix
589*
590 IF( abstol.LE.zero ) THEN
591 atoli = ulp*max( abs( gl ), abs( gu ) )
592 ELSE
593 atoli = abstol
594 END IF
595*
596 IF( irange.GT.1 ) THEN
597 IF( gu.LT.wl ) THEN
598 nwl = nwl + in
599 nwu = nwu + in
600 GO TO 70
601 END IF
602 gl = max( gl, wl )
603 gu = min( gu, wu )
604 IF( gl.GE.gu )
605 $ GO TO 70
606 END IF
607*
608* Set Up Initial Interval
609*
610 work( n+1 ) = gl
611 work( n+in+1 ) = gu
612 CALL slaebz( 1, 0, in, in, 1, nb, atoli, rtoli, pivmin,
613 $ d( ibegin ), e( ibegin ), work( ibegin ),
614 $ idumma, work( n+1 ), work( n+2*in+1 ), im,
615 $ iwork, w( m+1 ), iblock( m+1 ), iinfo )
616*
617 nwl = nwl + iwork( 1 )
618 nwu = nwu + iwork( in+1 )
619 iwoff = m - iwork( 1 )
620*
621* Compute Eigenvalues
622*
623 itmax = int( ( log( gu-gl+pivmin )-log( pivmin ) ) /
624 $ log( two ) ) + 2
625 CALL slaebz( 2, itmax, in, in, 1, nb, atoli, rtoli,
626 $ pivmin,
627 $ d( ibegin ), e( ibegin ), work( ibegin ),
628 $ idumma, work( n+1 ), work( n+2*in+1 ), iout,
629 $ iwork, w( m+1 ), iblock( m+1 ), iinfo )
630*
631* Copy Eigenvalues Into W and IBLOCK
632* Use -JB for block number for unconverged eigenvalues.
633*
634 DO 60 j = 1, iout
635 tmp1 = half*( work( j+n )+work( j+in+n ) )
636*
637* Flag non-convergence.
638*
639 IF( j.GT.iout-iinfo ) THEN
640 ncnvrg = .true.
641 ib = -jb
642 ELSE
643 ib = jb
644 END IF
645 DO 50 je = iwork( j ) + 1 + iwoff,
646 $ iwork( j+in ) + iwoff
647 w( je ) = tmp1
648 iblock( je ) = ib
649 50 CONTINUE
650 60 CONTINUE
651*
652 m = m + im
653 END IF
654 70 CONTINUE
655*
656* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU
657* If NWL+1 < IL or NWU > IU, discard extra eigenvalues.
658*
659 IF( irange.EQ.3 ) THEN
660 im = 0
661 idiscl = il - 1 - nwl
662 idiscu = nwu - iu
663*
664 IF( idiscl.GT.0 .OR. idiscu.GT.0 ) THEN
665 DO 80 je = 1, m
666 IF( w( je ).LE.wlu .AND. idiscl.GT.0 ) THEN
667 idiscl = idiscl - 1
668 ELSE IF( w( je ).GE.wul .AND. idiscu.GT.0 ) THEN
669 idiscu = idiscu - 1
670 ELSE
671 im = im + 1
672 w( im ) = w( je )
673 iblock( im ) = iblock( je )
674 END IF
675 80 CONTINUE
676 m = im
677 END IF
678 IF( idiscl.GT.0 .OR. idiscu.GT.0 ) THEN
679*
680* Code to deal with effects of bad arithmetic:
681* Some low eigenvalues to be discarded are not in (WL,WLU],
682* or high eigenvalues to be discarded are not in (WUL,WU]
683* so just kill off the smallest IDISCL/largest IDISCU
684* eigenvalues, by simply finding the smallest/largest
685* eigenvalue(s).
686*
687* (If N(w) is monotone non-decreasing, this should never
688* happen.)
689*
690 IF( idiscl.GT.0 ) THEN
691 wkill = wu
692 DO 100 jdisc = 1, idiscl
693 iw = 0
694 DO 90 je = 1, m
695 IF( iblock( je ).NE.0 .AND.
696 $ ( w( je ).LT.wkill .OR. iw.EQ.0 ) ) THEN
697 iw = je
698 wkill = w( je )
699 END IF
700 90 CONTINUE
701 iblock( iw ) = 0
702 100 CONTINUE
703 END IF
704 IF( idiscu.GT.0 ) THEN
705*
706 wkill = wl
707 DO 120 jdisc = 1, idiscu
708 iw = 0
709 DO 110 je = 1, m
710 IF( iblock( je ).NE.0 .AND.
711 $ ( w( je ).GT.wkill .OR. iw.EQ.0 ) ) THEN
712 iw = je
713 wkill = w( je )
714 END IF
715 110 CONTINUE
716 iblock( iw ) = 0
717 120 CONTINUE
718 END IF
719 im = 0
720 DO 130 je = 1, m
721 IF( iblock( je ).NE.0 ) THEN
722 im = im + 1
723 w( im ) = w( je )
724 iblock( im ) = iblock( je )
725 END IF
726 130 CONTINUE
727 m = im
728 END IF
729 IF( idiscl.LT.0 .OR. idiscu.LT.0 ) THEN
730 toofew = .true.
731 END IF
732 END IF
733*
734* If ORDER='B', do nothing -- the eigenvalues are already sorted
735* by block.
736* If ORDER='E', sort the eigenvalues from smallest to largest
737*
738 IF( iorder.EQ.1 .AND. nsplit.GT.1 ) THEN
739 DO 150 je = 1, m - 1
740 ie = 0
741 tmp1 = w( je )
742 DO 140 j = je + 1, m
743 IF( w( j ).LT.tmp1 ) THEN
744 ie = j
745 tmp1 = w( j )
746 END IF
747 140 CONTINUE
748*
749 IF( ie.NE.0 ) THEN
750 itmp1 = iblock( ie )
751 w( ie ) = w( je )
752 iblock( ie ) = iblock( je )
753 w( je ) = tmp1
754 iblock( je ) = itmp1
755 END IF
756 150 CONTINUE
757 END IF
758*
759 info = 0
760 IF( ncnvrg )
761 $ info = info + 1
762 IF( toofew )
763 $ info = info + 2
764 RETURN
765*
766* End of SSTEBZ
767*
768 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
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:317
subroutine sstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
SSTEBZ
Definition sstebz.f:272