301 SUBROUTINE dlarre( RANGE, N, VL, VU, IL, IU, D, E, E2,
302 $ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,
303 $ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
304 $ WORK, IWORK, INFO )
312 INTEGER IL, INFO, IU, M, N, NSPLIT
313 DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
316 INTEGER IBLOCK( * ), ISPLIT( * ), ( * ),
318 DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),
319 $ w( * ),werr( * ), wgap( * ), work( * )
325 DOUBLE PRECISION FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
326 $ MAXGROWTH, , PERT, TWO, ZERO
327 PARAMETER ( ZERO = 0.0d0, one = 1.0d0,
328 $ two = 2.0d0, four=4.0d0,
331 $ half = one/two, fourth = one/four, fac= half,
332 $ maxgrowth = 64.0d0, fudge = 2.0d0 )
333 INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG
334 PARAMETER ( MAXTRY = 6, allrng = 1, indrng = 2,
338 LOGICAL FORCEB, NOREP,
339 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
340 $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,
342 DOUBLE PRECISION AVGAP, BSRTOL, CLWDTH, , DPIVOT, EABS,
343 $ , EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,
344 $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,
354 DOUBLE PRECISION DLAMCH
355 EXTERNAL DLAMCH, LSAME
379 IF( lsame( range,
'A' ) )
THEN
381 ELSE IF( lsame( range,
'V' ) )
THEN
383 ELSE IF( lsame( range,
'I' ) )
THEN
390 safmin = dlamch(
'S' )
399 IF( (irange.EQ.allrng).OR.
400 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
401 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) )
THEN
430 IF( eabs .GE. emax )
THEN
434 gers( 2*i-1) = d(i) - tmp1
435 gl =
min( gl, gers( 2*i - 1))
436 gers( 2*i ) = d(i) + tmp1
437 gu =
max( gu, gers(2*i) )
441 pivmin = safmin *
max( one, emax**2 )
447 CALL dlarra( n, d, e, e2, spltol, spdiam,
448 $ nsplit, isplit, iinfo )
456 usedqd = (( irange.EQ.allrng ) .AND. (.NOT.forceb))
458 IF( (irange.EQ.allrng) .AND. (.NOT. forceb) )
THEN
469 CALL dlarrd( range,
'B', n, vl, vu, il, iu, gers,
470 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
471 $ mm, w, werr, vl, vu, iblock, indexw,
472 $ work, iwork, iinfo )
473 IF( iinfo.NE.0 )
THEN
491 DO 170 jblk = 1, nsplit
492 iend = isplit( jblk )
493 in = iend - ibegin + 1
497 IF( (irange.EQ.allrng).OR.( (irange.EQ.valrng).AND.
498 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
499 $ .OR. ( (irange.EQ.indrng).AND.(iblock(wbegin).EQ.jblk))
525 DO 15 i = ibegin , iend
526 gl =
min( gers( 2*i-1 ), gl )
531 IF(.NOT. ((irange.EQ.allrng).AND.(.NOT.forceb)) )
THEN
535 IF( iblock(i).EQ.jblk )
THEN
552 usedqd = ( (mb .GT. fac*in) .AND. (.NOT.forceb) )
553 wend = wbegin + mb - 1
558 DO 30 i = wbegin, wend - 1
559 wgap( i ) =
max( zero,
560 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
563 $ vu - sigma - (w( wend )+werr( wend )))
565 indl = indexw(wbegin)
566 indu = indexw( wend )
569 IF(( (irange.EQ.allrng) .AND. (.NOT. forceb) ).OR.usedqd)
THEN
572 CALL dlarrk( in, 1, gl, gu, d(ibegin),
573 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
574 IF( iinfo.NE.0 )
THEN
578 isleft =
max(gl, tmp - tmp1
579 $ - hndrd * eps* abs(tmp - tmp1))
581 CALL dlarrk( in, in, gl, gu, d(ibegin),
582 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
583 IF( iinfo.NE.0 )
THEN
587 isrght =
min(gu, tmp + tmp1
588 $ + hndrd * eps * abs(tmp + tmp1))
590 spdiam = isrght - isleft
594 isleft =
max(gl, w(wbegin) - werr(wbegin)
595 $ - hndrd * eps*abs(w(wbegin)- werr(wbegin) ))
596 isrght =
min(gu,w(wend) + werr(wend)
597 $ + hndrd * eps * abs(w(wend)+ werr(wend)))
609 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN
617 wend = wbegin + mb - 1
619 s1 = isleft + fourth * spdiam
620 s2 = isrght - fourth * spdiam
626 s1 = isleft + fourth * spdiam
627 s2 = isrght - fourth * spdiam
629 tmp =
min(isrght,vu) -
max(isleft,vl)
630 s1 =
max(isleft,vl) + fourth * tmp
631 s2 =
min(isrght,vu) - fourth * tmp
637 CALL dlarrc(
'T', in, s1, s2, d(ibegin),
638 $ e(ibegin), pivmin, cnt, cnt1, cnt2, iinfo)
644 ELSEIF( cnt1 - indl .GE. indu - cnt2 )
THEN
645 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN
646 sigma =
max(isleft,gl)
647 ELSEIF( usedqd )
THEN
654 sigma =
max(isleft,vl)
658 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN
659 sigma =
min(isrght,gu)
660 ELSEIF( usedqd )
THEN
667 sigma =
min(isrght,vu)
681 tau = spdiam*eps*n + two*pivmin
682 tau =
max( tau,two*eps*abs(sigma) )
685 clwdth = w(wend) + werr(wend) - w(wbegin) - werr(wbegin)
686 avgap = abs(clwdth / dble(wend-wbegin))
687 IF( sgndef.EQ.one )
THEN
688 tau = half*
max(wgap(wbegin),avgap)
689 tau =
max(tau,werr(wbegin))
691 tau = half*
max(wgap(wend-1),avgap)
692 tau =
max(tau,werr(wend))
699 DO 80 idum = 1, maxtry
703 dpivot = d( ibegin ) - sigma
705 dmax = abs( work(1) )
708 work( 2*in+i ) = one / work( i )
709 tmp = e( j )*work( 2*in+i )
711 dpivot = ( d( j+1 )-sigma ) - tmp*e( j )
713 dmax =
max( dmax, abs(dpivot) )
717 IF( dmax .GT. maxgrowth*spdiam )
THEN
722 IF( usedqd .AND. .NOT.norep )
THEN
726 tmp = sgndef*work( i )
727 IF( tmp.LT.zero ) norep = .true.
734 IF( idum.EQ.maxtry-1 )
THEN
735 IF( sgndef.EQ.one )
THEN
738 $ gl - fudge*spdiam*eps*n - fudge*two*pivmin
741 $ gu + fudge*spdiam*eps*n + fudge*two*pivmin
744 sigma = sigma - sgndef * tau
763 CALL dcopy( in, work, 1, d( ibegin ), 1 )
764 CALL dcopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
777 CALL dlarnv(2, iseed, 2*in-1, work(1))
779 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
780 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
782 d(iend) = d(iend)*(one+eps*four*work(in))
792 IF ( .NOT.usedqd )
THEN
800 werr(j) = werr(j) + abs(w(j)) * eps
805 work( i ) = d( i ) * e( i )**2
808 CALL dlarrb(in, d(ibegin), work(ibegin),
809 $ indl, indu, rtol1, rtol2, indl-1,
810 $ w(wbegin), wgap(wbegin), werr(wbegin),
811 $ work( 2*n+1 ), iwork, pivmin, spdiam,
813 IF( iinfo .NE. 0 )
THEN
819 wgap( wend ) =
max( zero,
821 DO 138 i = indl, indu
838 rtol = log(dble(in)) * four * eps
841 work( 2*i-1 ) = abs( d( j ) )
842 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
845 work( 2*in-1 ) = abs( d( iend ) )
847 CALL dlasq2( in, work, iinfo )
848 IF( iinfo .NE. 0 )
THEN
857 IF( work( i ).LT.zero )
THEN
863 IF( sgndef.GT.zero )
THEN
864 DO 150 i = indl, indu
866 w( m ) = work( in-i+1 )
871 DO 160 i = indl, indu
879 DO 165 i = m - mb + 1, m
881 werr( i ) = rtol * abs( w(i) )
883 DO 166 i = m - mb + 1, m - 1
885 wgap( i ) =
max( zero,
886 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
888 wgap( m ) =
max( zero,
889 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )