303 SUBROUTINE slarre( RANGE, N, VL, VU, IL, IU, D, E, E2,
304 $ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,
305 $ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
306 $ WORK, IWORK, INFO )
315 INTEGER IL, INFO, IU, M, N, NSPLIT
316 REAL PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
319 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
321 REAL D( * ), E( * ), E2( * ), GERS( * ),
322 $ w( * ),werr( * ), wgap( * ), work( * )
328 REAL FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
329 $ maxgrowth, one, pert, two, zero
330 parameter( zero = 0.0e0, one = 1.0e0,
331 $ two = 2.0e0, four=4.0e0,
334 $ half = one/two, fourth = one/four, fac= half,
335 $ maxgrowth = 64.0e0, fudge = 2.0e0 )
336 INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG
337 parameter( maxtry = 6, allrng = 1, indrng = 2,
341 LOGICAL FORCEB, NOREP, USEDQD
342 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
343 $ in, indl, indu, irange, j, jblk, mb, mm,
345 REAL AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
346 $ emax, eold, eps, gl, gu, isleft, isrght, rtl,
347 $ rtol, s1, s2, safmin, sgndef, sigma, spdiam,
358 EXTERNAL slamch, lsame
366 INTRINSIC abs, max, min
382 IF( lsame( range,
'A' ) )
THEN 384 ELSE IF( lsame( range,
'V' ) )
THEN 386 ELSE IF( lsame( range,
'I' ) )
THEN 393 safmin = slamch(
'S' )
402 bsrtol = sqrt(eps)*(0.5e-3)
406 IF( (irange.EQ.allrng).OR.
407 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
408 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) )
THEN 437 IF( eabs .GE. emax )
THEN 441 gers( 2*i-1) = d(i) - tmp1
442 gl = min( gl, gers( 2*i - 1))
443 gers( 2*i ) = d(i) + tmp1
444 gu = max( gu, gers(2*i) )
448 pivmin = safmin * max( one, emax**2 )
454 CALL slarra( n, d, e, e2, spltol, spdiam,
455 $ nsplit, isplit, iinfo )
463 usedqd = (( irange.EQ.allrng ) .AND. (.NOT.forceb))
465 IF( (irange.EQ.allrng) .AND. (.NOT. forceb) )
THEN 476 CALL slarrd( range,
'B', n, vl, vu, il, iu, gers,
477 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
478 $ mm, w, werr, vl, vu, iblock, indexw,
479 $ work, iwork, iinfo )
480 IF( iinfo.NE.0 )
THEN 498 DO 170 jblk = 1, nsplit
499 iend = isplit( jblk )
500 in = iend - ibegin + 1
504 IF( (irange.EQ.allrng).OR.( (irange.EQ.valrng).AND.
505 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
506 $ .OR. ( (irange.EQ.indrng).AND.(iblock(wbegin).EQ.jblk))
532 DO 15 i = ibegin , iend
533 gl = min( gers( 2*i-1 ), gl )
534 gu = max( gers( 2*i ), gu )
538 IF(.NOT. ((irange.EQ.allrng).AND.(.NOT.forceb)) )
THEN 542 IF( iblock(i).EQ.jblk )
THEN 559 usedqd = ( (mb .GT. fac*in) .AND. (.NOT.forceb) )
560 wend = wbegin + mb - 1
565 DO 30 i = wbegin, wend - 1
566 wgap( i ) = max( zero,
567 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
569 wgap( wend ) = max( zero,
570 $ vu - sigma - (w( wend )+werr( wend )))
572 indl = indexw(wbegin)
573 indu = indexw( wend )
576 IF(( (irange.EQ.allrng) .AND. (.NOT. forceb) ).OR.usedqd)
THEN 579 CALL slarrk( in, 1, gl, gu, d(ibegin),
580 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
581 IF( iinfo.NE.0 )
THEN 585 isleft = max(gl, tmp - tmp1
586 $ - hndrd * eps* abs(tmp - tmp1))
588 CALL slarrk( in, in, gl, gu, d(ibegin),
589 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
590 IF( iinfo.NE.0 )
THEN 594 isrght = min(gu, tmp + tmp1
595 $ + hndrd * eps * abs(tmp + tmp1))
597 spdiam = isrght - isleft
601 isleft = max(gl, w(wbegin) - werr(wbegin)
602 $ - hndrd * eps*abs(w(wbegin)- werr(wbegin) ))
603 isrght = min(gu,w(wend) + werr(wend)
604 $ + hndrd * eps * abs(w(wend)+ werr(wend)))
616 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN 624 wend = wbegin + mb - 1
626 s1 = isleft + fourth * spdiam
627 s2 = isrght - fourth * spdiam
633 s1 = isleft + fourth * spdiam
634 s2 = isrght - fourth * spdiam
636 tmp = min(isrght,vu) - max(isleft,vl)
637 s1 = max(isleft,vl) + fourth * tmp
638 s2 = min(isrght,vu) - fourth * tmp
644 CALL slarrc(
'T', in, s1, s2, d(ibegin),
645 $ e(ibegin), pivmin, cnt, cnt1, cnt2, iinfo)
651 ELSEIF( cnt1 - indl .GE. indu - cnt2 )
THEN 652 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN 653 sigma = max(isleft,gl)
654 ELSEIF( usedqd )
THEN 661 sigma = max(isleft,vl)
665 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) )
THEN 666 sigma = min(isrght,gu)
667 ELSEIF( usedqd )
THEN 674 sigma = min(isrght,vu)
688 tau = spdiam*eps*n + two*pivmin
689 tau = max( tau,two*eps*abs(sigma) )
692 clwdth = w(wend) + werr(wend) - w(wbegin) - werr(wbegin)
693 avgap = abs(clwdth /
REAL(wend-wbegin))
694 IF( sgndef.EQ.one )
THEN 695 tau = half*max(wgap(wbegin),avgap)
696 tau = max(tau,werr(wbegin))
698 tau = half*max(wgap(wend-1),avgap)
699 tau = max(tau,werr(wend))
706 DO 80 idum = 1, maxtry
710 dpivot = d( ibegin ) - sigma
712 dmax = abs( work(1) )
715 work( 2*in+i ) = one / work( i )
716 tmp = e( j )*work( 2*in+i )
718 dpivot = ( d( j+1 )-sigma ) - tmp*e( j )
720 dmax = max( dmax, abs(dpivot) )
724 IF( dmax .GT. maxgrowth*spdiam )
THEN 729 IF( usedqd .AND. .NOT.norep )
THEN 733 tmp = sgndef*work( i )
734 IF( tmp.LT.zero ) norep = .true.
741 IF( idum.EQ.maxtry-1 )
THEN 742 IF( sgndef.EQ.one )
THEN 745 $ gl - fudge*spdiam*eps*n - fudge*two*pivmin
748 $ gu + fudge*spdiam*eps*n + fudge*two*pivmin
751 sigma = sigma - sgndef * tau
770 CALL scopy( in, work, 1, d( ibegin ), 1 )
771 CALL scopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
784 CALL slarnv(2, iseed, 2*in-1, work(1))
786 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
787 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
789 d(iend) = d(iend)*(one+eps*four*work(in))
799 IF ( .NOT.usedqd )
THEN 807 werr(j) = werr(j) + abs(w(j)) * eps
811 DO 135 i = ibegin, iend-1
812 work( i ) = d( i ) * e( i )**2
815 CALL slarrb(in, d(ibegin), work(ibegin),
816 $ indl, indu, rtol1, rtol2, indl-1,
817 $ w(wbegin), wgap(wbegin), werr(wbegin),
818 $ work( 2*n+1 ), iwork, pivmin, spdiam,
820 IF( iinfo .NE. 0 )
THEN 826 wgap( wend ) = max( zero,
827 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
828 DO 138 i = indl, indu
845 rtol = log(
REAL(in)) * four * eps
848 work( 2*i-1 ) = abs( d( j ) )
849 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
852 work( 2*in-1 ) = abs( d( iend ) )
854 CALL slasq2( in, work, iinfo )
855 IF( iinfo .NE. 0 )
THEN 864 IF( work( i ).LT.zero )
THEN 870 IF( sgndef.GT.zero )
THEN 871 DO 150 i = indl, indu
873 w( m ) = work( in-i+1 )
878 DO 160 i = indl, indu
886 DO 165 i = m - mb + 1, m
888 werr( i ) = rtol * abs( w(i) )
890 DO 166 i = m - mb + 1, m - 1
892 wgap( i ) = max( zero,
893 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
895 wgap( m ) = max( zero,
896 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )
subroutine slarrd(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)
SLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.
subroutine slarrb(N, D, LLD, IFIRST, ILAST, RTOL1, RTOL2, OFFSET, W, WGAP, WERR, WORK, IWORK, PIVMIN, SPDIAM, TWIST, INFO)
SLARRB provides limited bisection to locate eigenvalues for more accuracy.
subroutine slarrk(N, IW, GL, GU, D, E2, PIVMIN, RELTOL, W, WERR, INFO)
SLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.
subroutine slarnv(IDIST, ISEED, N, X)
SLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine slasq2(N, Z, INFO)
SLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated ...
subroutine slarra(N, D, E, E2, SPLTOL, TNRM, NSPLIT, ISPLIT, INFO)
SLARRA computes the splitting points with the specified threshold.
subroutine slarre(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)
SLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduce...
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY
subroutine slarrc(JOBT, N, VL, VU, D, E, PIVMIN, EIGCNT, LCNT, RCNT, INFO)
SLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.