299 SUBROUTINE slarre( RANGE, N, VL, VU, IL, IU, D, E, E2,
300 $ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,
301 $ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
302 $ WORK, IWORK, INFO )
310 INTEGER IL, INFO, IU, M, N, NSPLIT
311 REAL PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
314 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
316 REAL D( * ), E( * ), E2( * ), GERS( * ),
317 $ w( * ),werr( * ), wgap( * ), work( * )
323 REAL FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
324 $ MAXGROWTH, ONE, PERT, TWO, ZERO
325 PARAMETER ( ZERO = 0.0e0, one = 1.0e0,
326 $ two = 2.0e0, four=4.0e0,
329 $ half = one/two, fourth = one/four, fac= half,
330 $ maxgrowth = 64.0e0, fudge = 2.0e0 )
331 INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG
332 PARAMETER ( MAXTRY = 6, allrng = 1, indrng = 2,
336 LOGICAL FORCEB, NOREP, USEDQD
337 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
338 $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,
340 REAL AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
341 $ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,
342 $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,
353 EXTERNAL SLAMCH, LSAME
362 INTRINSIC abs, max, min
380 IF( lsame( range,
'A' ) )
THEN
382 ELSE IF( lsame( range,
'V' ) )
THEN
384 ELSE IF( lsame( range,
'I' ) )
THEN
389 safmin = slamch(
'S' )
398 bsrtol = sqrt(eps)*(0.5e-3)
402 IF( (irange.EQ.allrng).OR.
403 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
404 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) )
THEN
433 IF( eabs .GE. emax )
THEN
437 gers( 2*i-1) = d(i) - tmp1
438 gl = min( gl, gers( 2*i - 1))
439 gers( 2*i ) = d(i) + tmp1
440 gu = max( gu, gers(2*i) )
444 pivmin = safmin * max( one, emax**2 )
450 CALL slarra( n, d, e, e2, spltol, spdiam,
451 $ nsplit, isplit, iinfo )
459 usedqd = (( irange.EQ.allrng ) .AND. (.NOT.forceb))
461 IF( (irange.EQ.allrng) .AND. (.NOT. forceb) )
THEN
472 CALL slarrd( range,
'B', n, vl, vu, il, iu, gers,
473 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
474 $ mm, w, werr, vl, vu, iblock, indexw,
475 $ work, iwork, iinfo )
476 IF( iinfo.NE.0 )
THEN
494 DO 170 jblk = 1, nsplit
495 iend = isplit( jblk )
496 in = iend - ibegin + 1
500 IF( (irange.EQ.allrng).OR.( (irange.EQ.valrng).AND.
501 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
502 $ .OR. ( (irange.EQ.indrng).AND.(iblock(wbegin).EQ.jblk))
528 DO 15 i = ibegin , iend
529 gl = min( gers( 2*i-1 ), gl )
530 gu = max( gers( 2*i ), gu )
534 IF(.NOT. ((irange.EQ.allrng).AND.(.NOT.forceb)) )
THEN
538 IF( iblock(i).EQ.jblk )
THEN
555 usedqd = ( (real( mb ) .GT. fac*real( in )) .AND.
557 wend = wbegin + mb - 1
562 DO 30 i = wbegin, wend - 1
563 wgap( i ) = max( zero,
564 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
566 wgap( wend ) = max( zero,
567 $ vu - sigma - (w( wend )+werr( wend )))
569 indl = indexw(wbegin)
570 indu = indexw( wend )
573 IF(( (irange.EQ.allrng) .AND. (.NOT. forceb) ).OR.usedqd)
THEN
576 CALL slarrk( in, 1, gl, gu, d(ibegin),
577 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
578 IF( iinfo.NE.0 )
THEN
582 isleft = max(gl, tmp - tmp1
583 $ - hndrd * eps* abs(tmp - tmp1))
585 CALL slarrk( in, in, gl, gu, d(ibegin),
586 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
587 IF( iinfo.NE.0 )
THEN
591 isrght = min(gu, tmp + tmp1
592 $ + hndrd * eps * abs(tmp + tmp1))
594 spdiam = isrght - isleft
598 isleft = max(gl, w(wbegin) - werr(wbegin)
599 $ - hndrd * eps*abs(w(wbegin)- werr(wbegin) ))
600 isrght = min(gu,w(wend) + werr(wend)
601 $ + hndrd * eps * abs(w(wend)+ werr(wend)))
613 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN
621 wend = wbegin + mb - 1
623 s1 = isleft + fourth * spdiam
624 s2 = isrght - fourth * spdiam
630 s1 = isleft + fourth * spdiam
631 s2 = isrght - fourth * spdiam
633 tmp = min(isrght,vu) - max(isleft,vl)
634 s1 = max(isleft,vl) + fourth * tmp
635 s2 = min(isrght,vu) - fourth * tmp
641 CALL slarrc(
'T', in, s1, s2, d(ibegin),
642 $ e(ibegin), pivmin, cnt, cnt1, cnt2, iinfo)
648 ELSEIF( cnt1 - indl .GE. indu - cnt2 )
THEN
649 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN
650 sigma = max(isleft,gl)
651 ELSEIF( usedqd )
THEN
658 sigma = max(isleft,vl)
662 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN
663 sigma = min(isrght,gu)
664 ELSEIF( usedqd )
THEN
671 sigma = min(isrght,vu)
685 tau = spdiam*eps*real( n ) + two*pivmin
686 tau = max( tau,two*eps*abs(sigma) )
689 clwdth = w(wend) + werr(wend) - w(wbegin) - werr(wbegin)
690 avgap = abs(clwdth / real(wend-wbegin))
691 IF( sgndef.EQ.one )
THEN
692 tau = half*max(wgap(wbegin),avgap)
693 tau = max(tau,werr(wbegin))
695 tau = half*max(wgap(wend-1),avgap)
696 tau = max(tau,werr(wend))
703 DO 80 idum = 1, maxtry
707 dpivot = d( ibegin ) - sigma
709 dmax = abs( work(1) )
712 work( 2*in+i ) = one / work( i )
713 tmp = e( j )*work( 2*in+i )
715 dpivot = ( d( j+1 )-sigma ) - tmp*e( j )
717 dmax = max( dmax, abs(dpivot) )
721 IF( dmax .GT. maxgrowth*spdiam )
THEN
726 IF( usedqd .AND. .NOT.norep )
THEN
730 tmp = sgndef*work( i )
731 IF( tmp.LT.zero ) norep = .true.
738 IF( idum.EQ.maxtry-1 )
THEN
739 IF( sgndef.EQ.one )
THEN
742 $ gl - fudge*spdiam*eps*real( n ) -
746 $ gu + fudge*spdiam*eps*real( n ) +
750 sigma = sigma - sgndef * tau
769 CALL scopy( in, work, 1, d( ibegin ), 1 )
770 CALL scopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
783 CALL slarnv(2, iseed, 2*in-1, work(1))
785 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
786 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
788 d(iend) = d(iend)*(one+eps*four*work(in))
798 IF ( .NOT.usedqd )
THEN
806 werr(j) = werr(j) + abs(w(j)) * eps
810 DO 135 i = ibegin, iend-1
811 work( i ) = d( i ) * e( i )**2
814 CALL slarrb(in, d(ibegin), work(ibegin),
815 $ indl, indu, rtol1, rtol2, indl-1,
816 $ w(wbegin), wgap(wbegin), werr(wbegin),
817 $ work( 2*n+1 ), iwork, pivmin, spdiam,
819 IF( iinfo .NE. 0 )
THEN
825 wgap( wend ) = max( zero,
826 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
827 DO 138 i = indl, indu
844 rtol = log(real(in)) * four * eps
847 work( 2*i-1 ) = abs( d( j ) )
848 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
851 work( 2*in-1 ) = abs( d( iend ) )
853 CALL slasq2( in, work, iinfo )
854 IF( iinfo .NE. 0 )
THEN
863 IF( work( i ).LT.zero )
THEN
869 IF( sgndef.GT.zero )
THEN
870 DO 150 i = indl, indu
872 w( m ) = work( in-i+1 )
877 DO 160 i = indl, indu
885 DO 165 i = m - mb + 1, m
887 werr( i ) = rtol * abs( w(i) )
889 DO 166 i = m - mb + 1, m - 1
891 wgap( i ) = max( zero,
892 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
894 wgap( m ) = max( zero,
895 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )