301 SUBROUTINE slarre( 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 REAL PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
316 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
318 REAL D( * ), E( * ), E2( * ), GERS( * ),
319 $ w( * ),werr( * ), wgap( * ), work( * )
325 REAL FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
326 $ maxgrowth, one, pert, two, zero
327 parameter( zero = 0.0e0, one = 1.0e0,
328 $ two = 2.0e0, four=4.0e0,
331 $ half = one/two, fourth = one/four, fac= half,
332 $ maxgrowth = 64.0e0, fudge = 2.0e0 )
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 REAL AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
343 $ emax, eold, eps, gl, gu, isleft, isrght, rtl,
344 $ rtol, s1, s2, safmin, sgndef, sigma, spdiam,
355 EXTERNAL slamch, 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 = slamch(
'S' )
399 bsrtol = sqrt(eps)*(0.5e-3)
403 IF( (irange.EQ.allrng).OR.
404 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
405 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) )
THEN 434 IF( eabs .GE. emax )
THEN 438 gers( 2*i-1) = d(i) - tmp1
439 gl = min( gl, gers( 2*i - 1))
440 gers( 2*i ) = d(i) + tmp1
441 gu = max( gu, gers(2*i) )
445 pivmin = safmin * max( one, emax**2 )
451 CALL slarra( n, d, e, e2, spltol, spdiam,
452 $ nsplit, isplit, iinfo )
460 usedqd = (( irange.EQ.allrng ) .AND. (.NOT.forceb))
462 IF( (irange.EQ.allrng) .AND. (.NOT. forceb) )
THEN 473 CALL slarrd( range,
'B', n, vl, vu, il, iu, gers,
474 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
475 $ mm, w, werr, vl, vu, iblock, indexw,
476 $ work, iwork, iinfo )
477 IF( iinfo.NE.0 )
THEN 495 DO 170 jblk = 1, nsplit
496 iend = isplit( jblk )
497 in = iend - ibegin + 1
501 IF( (irange.EQ.allrng).OR.( (irange.EQ.valrng).AND.
502 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
503 $ .OR. ( (irange.EQ.indrng).AND.(iblock(wbegin).EQ.jblk))
529 DO 15 i = ibegin , iend
530 gl = min( gers( 2*i-1 ), gl )
531 gu = max( gers( 2*i ), gu )
535 IF(.NOT. ((irange.EQ.allrng).AND.(.NOT.forceb)) )
THEN 539 IF( iblock(i).EQ.jblk )
THEN 556 usedqd = ( (mb .GT. fac*in) .AND. (.NOT.forceb) )
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*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*n - fudge*two*pivmin
745 $ gu + fudge*spdiam*eps*n + fudge*two*pivmin
748 sigma = sigma - sgndef * tau
767 CALL scopy( in, work, 1, d( ibegin ), 1 )
768 CALL scopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
781 CALL slarnv(2, iseed, 2*in-1, work(1))
783 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
784 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
786 d(iend) = d(iend)*(one+eps*four*work(in))
796 IF ( .NOT.usedqd )
THEN 804 werr(j) = werr(j) + abs(w(j)) * eps
808 DO 135 i = ibegin, iend-1
809 work( i ) = d( i ) * e( i )**2
812 CALL slarrb(in, d(ibegin), work(ibegin),
813 $ indl, indu, rtol1, rtol2, indl-1,
814 $ w(wbegin), wgap(wbegin), werr(wbegin),
815 $ work( 2*n+1 ), iwork, pivmin, spdiam,
817 IF( iinfo .NE. 0 )
THEN 823 wgap( wend ) = max( zero,
824 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
825 DO 138 i = indl, indu
842 rtol = log(
REAL(in)) * four * eps
845 work( 2*i-1 ) = abs( d( j ) )
846 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
849 work( 2*in-1 ) = abs( d( iend ) )
851 CALL slasq2( in, work, iinfo )
852 IF( iinfo .NE. 0 )
THEN 861 IF( work( i ).LT.zero )
THEN 867 IF( sgndef.GT.zero )
THEN 868 DO 150 i = indl, indu
870 w( m ) = work( in-i+1 )
875 DO 160 i = indl, indu
883 DO 165 i = m - mb + 1, m
885 werr( i ) = rtol * abs( w(i) )
887 DO 166 i = m - mb + 1, m - 1
889 wgap( i ) = max( zero,
890 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
892 wgap( m ) = max( zero,
893 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )
subroutine slarrc(JOBT, N, VL, VU, D, E, PIVMIN, EIGCNT, LCNT, RCNT, INFO)
SLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
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 scopy(N, SX, INCX, SY, INCY)
SCOPY
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 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 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 slarra(N, D, E, E2, SPLTOL, TNRM, NSPLIT, ISPLIT, INFO)
SLARRA computes the splitting points with the specified threshold.
subroutine slasq2(N, Z, INFO)
SLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated ...
subroutine slarnv(IDIST, ISEED, N, X)
SLARNV returns a vector of random numbers from a uniform or normal distribution.