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( * ), IWORK( * ),
318 DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),
319 $ w( * ),werr( * ), wgap( * ), work( * )
325 DOUBLE PRECISION FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
326 $ MAXGROWTH, ONE, 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, USEDQD
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, DMAX, DPIVOT, EABS,
343 $ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,
344 $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,
354 DOUBLE PRECISION DLAMCH
355 EXTERNAL DLAMCH, LSAME
363 INTRINSIC abs, max, min
381 IF( lsame( range,
'A' ) )
THEN
383 ELSE IF( lsame( range,
'V' ) )
THEN
385 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 )
527 gu = max( gers( 2*i ), gu )
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)) )
562 wgap( wend ) = max( zero,
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
804 DO 135 i = ibegin, iend-1
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,
820 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
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 ) ) )
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine dlarra(n, d, e, e2, spltol, tnrm, nsplit, isplit, info)
DLARRA computes the splitting points with the specified threshold.
subroutine dlarrb(n, d, lld, ifirst, ilast, rtol1, rtol2, offset, w, wgap, werr, work, iwork, pivmin, spdiam, twist, info)
DLARRB provides limited bisection to locate eigenvalues for more accuracy.
subroutine dlarrc(jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
DLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
subroutine dlarrd(range, order, n, vl, vu, il, iu, gers, reltol, d, e, e2, pivmin, nsplit, isplit, m, w, werr, wl, wu, iblock, indexw, work, iwork, info)
DLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.
subroutine dlarre(range, n, vl, vu, il, iu, d, e, e2, rtol1, rtol2, spltol, nsplit, isplit, m, w, werr, wgap, iblock, indexw, gers, pivmin, work, iwork, info)
DLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduce...
subroutine dlarrk(n, iw, gl, gu, d, e2, pivmin, reltol, w, werr, info)
DLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.
subroutine dlasq2(n, z, info)
DLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated ...