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 scopy(n, sx, incx, sy, incy)
SCOPY
subroutine slarnv(idist, iseed, n, x)
SLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine slarra(n, d, e, e2, spltol, tnrm, nsplit, isplit, info)
SLARRA computes the splitting points with the specified threshold.
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 slarrc(jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
SLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
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 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 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 slasq2(n, z, info)
SLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated ...