1 SUBROUTINE slarre2( RANGE, N, VL, VU, IL, IU, D, E, E2,
2 $ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT,
4 $ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
13 INTEGER DOL, DOU, IL, INFO, IU, M, N, NSPLIT
14 REAL PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
17 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
19 REAL D( * ), E( * ), E2( * ), GERS( * ),
20 $ W( * ),WERR( * ), WGAP( * ), WORK( * )
192 REAL FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
193 $ MAXGROWTH, ONE, PERT, TWO, ZERO
194 PARAMETER ( ZERO = 0.0e0, one = 1.0e0,
195 $ two = 2.0e0, four=4.0e0,
198 $ half = one/two, fourth = one/four, fac= half,
199 $ maxgrowth = 64.0e0, fudge = 2.0e0 )
201 PARAMETER ( MAXTRY = 6 )
204 LOGICAL FORCEB, NOREP, RNDPRT, USEDQD
205 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
206 $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,
208 REAL AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
209 $ emax, eold, eps, gl, gu, isleft, isrght, rtl,
210 $ rtol, s1, s2, safmin, sgndef, sigma, spdiam,
221 EXTERNAL SLAMCH, LSAME
225 EXTERNAL scopy, slarnv, slarra, slarrb, slarrc,
242 IF( lsame( range,
'A' ) )
THEN
244 ELSE IF( lsame( range,
'V' ) )
THEN
246 ELSE IF( lsame( range,
'I' ) )
THEN
253 safmin = slamch(
'S' )
262 IF( (irange.EQ.1).OR.
263 $ ((irange.EQ.2).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
264 $ ((irange.EQ.3).AND.(il.EQ.1).AND.(iu.EQ.1)) )
THEN
293 IF( eabs .GE. emax )
THEN
297 gers( 2*i-1) = d(i) - tmp1
298 gl =
min( gl, gers( 2*i - 1))
299 gers( 2*i ) = d(i) + tmp1
300 gu =
max( gu, gers(2*i) )
304 pivmin = safmin *
max( one, emax**2 )
310 CALL slarra( n, d, e, e2, spltol, spdiam,
311 $ nsplit, isplit, iinfo )
316 IF( (irange.EQ.1) .AND. (.NOT. forceb) )
THEN
327 CALL slarrd( range,
'B', n, vl, vu, il, iu, gers,
328 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
329 $ mm, w, werr, vl, vu, iblock, indexw,
330 $ work, iwork, iinfo )
331 IF( iinfo.NE.0 )
THEN
349 DO 170 jblk = 1, nsplit
350 iend = isplit( jblk )
351 in = iend - ibegin + 1
355 IF( (irange.EQ.1).OR.( (irange.EQ.2).AND.
356 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
357 $ .OR. ( (irange.EQ.3).AND.(iblock(wbegin).EQ.jblk))
383 DO 15 i = ibegin , iend
384 gl =
min( gers( 2*i-1 ), gl )
385 gu =
max( gers( 2*i ), gu )
389 IF(.NOT. ((irange.EQ.1).AND.(.NOT.forceb)) )
THEN
393 IF( iblock(i).EQ.jblk )
THEN
410 usedqd = ( (mb .GT. fac*in) .AND. (.NOT.forceb) )
411 wend = wbegin + mb - 1
416 DO 30 i = wbegin, wend - 1
417 wgap( i ) =
max( zero,
418 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
420 wgap( wend ) =
max( zero,
421 $ vu - sigma - (w( wend )+werr( wend )))
423 indl = indexw(wbegin)
424 indu = indexw( wend )
429 wend = wbegin + mb - 1
434 IF( (wend.LT.dol).OR.(wbegin.GT.dou) )
THEN
439 m = m + indu - indl + 1
444 CALL slarrk( in, 1, gl, gu, d(ibegin),
445 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
446 IF( iinfo.NE.0 )
THEN
450 isleft =
max(gl, tmp - tmp1
451 $ - hndrd * eps* abs(tmp - tmp1))
452 CALL slarrk( in, in, gl, gu, d(ibegin),
453 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
454 IF( iinfo.NE.0 )
THEN
458 isrght =
min(gu, tmp + tmp1
459 $ + hndrd * eps * abs(tmp + tmp1))
460 IF(( (irange.EQ.1) .AND. (.NOT. forceb) ).OR.usedqd)
THEN
463 spdiam = isrght - isleft
467 isleft =
max(gl, w(wbegin) - werr(wbegin)
468 $ - hndrd * eps*abs(w(wbegin)- werr(wbegin) ))
469 isrght =
min(gu,w(wend) + werr(wend)
470 $ + hndrd * eps * abs(w(wend)+ werr(wend)))
482 IF( ( irange.EQ.1 ) .AND. (.NOT.forceb) )
THEN
490 wend = wbegin + mb - 1
492 s1 = isleft + fourth * spdiam
493 s2 = isrght - fourth * spdiam
499 s1 = isleft + fourth * spdiam
500 s2 = isrght - fourth * spdiam
502 tmp =
min(isrght,vu) -
max(isleft,vl)
503 s1 =
max(isleft,vl) + fourth * tmp
504 s2 =
min(isrght,vu) - fourth * tmp
510 CALL slarrc(
'T', in, s1, s2, d(ibegin),
511 $ e(ibegin), pivmin, cnt, cnt1, cnt2, iinfo)
517 ELSEIF( cnt1 - indl .GE. indu - cnt2 )
THEN
518 IF( ( irange.EQ.1 ) .AND. (.NOT.forceb) )
THEN
519 sigma =
max(isleft,gl)
520 ELSEIF( usedqd )
THEN
527 sigma =
max(isleft,vl)
531 IF( ( irange.EQ.1 ) .AND. (.NOT.forceb) )
THEN
532 sigma =
min(isrght,gu)
533 ELSEIF( usedqd )
THEN
540 sigma =
min(isrght,vu)
552 tau = spdiam*eps*n + two*pivmin
553 tau =
max(tau,eps*abs(sigma))
556 clwdth = w(wend) + werr(wend) - w(wbegin) - werr(wbegin)
557 avgap = abs(clwdth / real(wend-wbegin))
558 IF( sgndef.EQ.one )
THEN
559 tau = half*
max(wgap(wbegin),avgap)
560 tau =
max(tau,werr(wbegin))
562 tau = half*
max(wgap(wend-1),avgap)
563 tau =
max(tau,werr(wend))
570 DO 80 idum = 1, maxtry
574 dpivot = d( ibegin ) - sigma
576 dmax = abs( work(1) )
579 work( 2*in+i ) = one / work( i )
580 tmp = e( j )*work( 2*in+i )
582 dpivot = ( d( j+1 )-sigma ) - tmp*e( j )
584 dmax =
max( dmax, abs(dpivot) )
588 IF( dmax .GT. maxgrowth*spdiam )
THEN
597 IF( idum.EQ.maxtry-1 )
THEN
598 IF( sgndef.EQ.one )
THEN
601 $ gl - fudge*spdiam*eps*n - fudge*two*pivmin
604 $ gu + fudge*spdiam*eps*n + fudge*two*pivmin
607 sigma = sigma - sgndef * tau
626 CALL scopy( in, work, 1, d( ibegin ), 1 )
627 CALL scopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
630 IF(rndprt .AND. mb.GT.1 )
THEN
640 CALL slarnv(2, iseed, 2*in-1, work(1))
642 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
643 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
645 d(iend) = d(iend)*(one+eps*four*work(in))
655 IF ( .NOT.usedqd )
THEN
663 werr(j) = werr(j) + abs(w(j)) * eps
667 DO 135 i = ibegin, iend-1
668 work( i ) = d( i ) * e( i )**2
671 CALL slarrb(in, d(ibegin), work(ibegin),
672 $ indl, indu, rtol1, rtol2, indl-1,
673 $ w(wbegin), wgap(wbegin), werr(wbegin),
674 $ work( 2*n+1 ), iwork, pivmin, spdiam,
676 IF( iinfo .NE. 0 )
THEN
682 wgap( wend ) =
max( zero,
683 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
684 DO 138 i = indl, indu
701 rtol = log(real(in)) * four * eps
704 work( 2*i-1 ) = abs( d( j ) )
705 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
708 work( 2*in-1 ) = abs( d( iend ) )
710 CALL slasq2( in, work, iinfo )
711 IF( iinfo .NE. 0 )
THEN
720 IF( work( i ).LT.zero )
THEN
726 IF( sgndef.GT.zero )
THEN
727 DO 150 i = indl, indu
729 w( m ) = work( in-i+1 )
734 DO 160 i = indl, indu
742 DO 165 i = m - mb + 1, m
744 werr( i ) = rtol * abs( w(i) )
746 DO 166 i = m - mb + 1, m - 1
748 wgap( i ) =
max( zero,
749 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
751 wgap( m ) =
max( zero,
752 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )