287 SUBROUTINE dlarrv( N, VL, VU, D, L, PIVMIN,
288 $ ISPLIT, M, DOL, DOU, MINRGP,
289 $ RTOL1, RTOL2, W, WERR, WGAP,
290 $ IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,
291 $ WORK, IWORK, INFO )
298 INTEGER DOL, DOU, INFO, LDZ, M, N
299 DOUBLE PRECISION MINRGP, PIVMIN, RTOL1, RTOL2, VL, VU
302 INTEGER IBLOCK( * ), INDEXW( * ), ISPLIT( * ),
303 $ isuppz( * ), iwork( * )
304 DOUBLE PRECISION D( * ), GERS( * ), L( * ), W( * ), WERR( * ),
305 $ WGAP( * ), WORK( * )
306 DOUBLE PRECISION Z( LDZ, * )
313 PARAMETER ( MAXITR = 10 )
314 double precision zero, one, two, three, four, half
315 parameter( zero = 0.0d0, one = 1.0d0,
316 $ two = 2.0d0, three = 3.0d0,
317 $ four = 4.0d0, half = 0.5d0)
320 LOGICAL ESKIP, NEEDBS, STP2II, TRYRQC, USEDBS, USEDRQ
321 INTEGER DONE, I, IBEGIN, IDONE, IEND, II, IINDC1,
322 $ IINDC2, IINDR, IINDWK, IINFO, IM, IN, INDEIG,
323 $ INDLD, INDLLD, INDWRK, ISUPMN, ISUPMX, ITER,
324 $ itmp1, j, jblk, k, miniwsize, minwsize, nclus,
325 $ ndepth, negcnt, newcls, newfst, newftt, newlst,
326 $ newsiz, offset, oldcls, oldfst, oldien, oldlst,
327 $ oldncl, p, parity, q, wbegin, wend, windex,
328 $ windmn, windpl, zfrom, zto, zusedl, zusedu,
330 DOUBLE PRECISION BSTRES, BSTW, EPS, FUDGE, GAP, GAPTOL, GL, GU,
331 $ LAMBDA, LEFT, LGAP, MINGMA, NRMINV, RESID,
332 $ RGAP, RIGHT, RQCORR, RQTOL, SAVGAP, SGNDEF,
333 $ SIGMA, SPDIAM, SSIGMA, TAU, TMP, TOL, ZTZ
336 DOUBLE PRECISION DLAMCH
344 INTRINSIC abs, dble, max, min
353 IF( (n.LE.0).OR.(m.LE.0) )
THEN
392 zusedw = zusedu - zusedl + 1
395 CALL dlaset(
'Full', n, zusedw, zero, zero,
398 eps = dlamch(
'Precision' )
404 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN
423 DO 170 jblk = 1, iblock( m )
424 iend = isplit( jblk )
431 IF( iblock( wend+1 ).EQ.jblk )
THEN
436 IF( wend.LT.wbegin )
THEN
439 ELSEIF( (wend.LT.dol).OR.(wbegin.GT.dou) )
THEN
446 gl = gers( 2*ibegin-1 )
447 gu = gers( 2*ibegin )
448 DO 20 i = ibegin+1 , iend
449 gl = min( gers( 2*i-1 ), gl )
450 gu = max( gers( 2*i ), gu )
457 in = iend - ibegin + 1
459 im = wend - wbegin + 1
462 IF( ibegin.EQ.iend )
THEN
464 z( ibegin, wbegin ) = one
465 isuppz( 2*wbegin-1 ) = ibegin
466 isuppz( 2*wbegin ) = ibegin
467 w( wbegin ) = w( wbegin ) + sigma
468 work( wbegin ) = w( wbegin )
480 CALL dcopy( im, w( wbegin ), 1,
481 $ work( wbegin ), 1 )
486 w(wbegin+i-1) = w(wbegin+i-1)+sigma
497 iwork( iindc1+1 ) = 1
498 iwork( iindc1+2 ) = im
507 IF( idone.LT.im )
THEN
509 IF( ndepth.GT.m )
THEN
520 IF( parity.EQ.0 )
THEN
533 oldfst = iwork( j-1 )
535 IF( ndepth.GT.0 )
THEN
541 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN
544 j = wbegin + oldfst - 1
546 IF(wbegin+oldfst-1.LT.dol)
THEN
549 ELSEIF(wbegin+oldfst-1.GT.dou)
THEN
553 j = wbegin + oldfst - 1
556 CALL dcopy( in, z( ibegin, j ), 1, d( ibegin ), 1 )
557 CALL dcopy( in-1, z( ibegin, j+1 ), 1, l( ibegin ),
559 sigma = z( iend, j+1 )
562 CALL dlaset(
'Full', in, 2, zero, zero,
563 $ z( ibegin, j), ldz )
567 DO 50 j = ibegin, iend-1
569 work( indld-1+j ) = tmp
570 work( indlld-1+j ) = tmp*l( j )
573 IF( ndepth.GT.0 )
THEN
576 p = indexw( wbegin-1+oldfst )
577 q = indexw( wbegin-1+oldlst )
581 offset = indexw( wbegin ) - 1
584 CALL dlarrb( in, d( ibegin ),
585 $ work(indlld+ibegin-1),
586 $ p, q, rtol1, rtol2, offset,
587 $ work(wbegin),wgap(wbegin),werr(wbegin),
588 $ work( indwrk ), iwork( iindwk ),
589 $ pivmin, spdiam, in, iinfo )
590 IF( iinfo.NE.0 )
THEN
601 IF( oldfst.GT.1)
THEN
602 wgap( wbegin+oldfst-2 ) =
603 $ max(wgap(wbegin+oldfst-2),
604 $ w(wbegin+oldfst-1)-werr(wbegin+oldfst-1)
605 $ - w(wbegin+oldfst-2)-werr(wbegin+oldfst-2) )
607 IF( wbegin + oldlst -1 .LT. wend )
THEN
608 wgap( wbegin+oldlst-1 ) =
609 $ max(wgap(wbegin+oldlst-1),
610 $ w(wbegin+oldlst)-werr(wbegin+oldlst)
611 $ - w(wbegin+oldlst-1)-werr(wbegin+oldlst-1) )
615 DO 53 j=oldfst,oldlst
616 w(wbegin+j-1) = work(wbegin+j-1)+sigma
622 DO 140 j = oldfst, oldlst
623 IF( j.EQ.oldlst )
THEN
627 ELSE IF ( wgap( wbegin + j -1).GE.
628 $ minrgp* abs( work(wbegin + j -1) ) )
THEN
639 newsiz = newlst - newfst + 1
643 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN
646 newftt = wbegin + newfst - 1
648 IF(wbegin+newfst-1.LT.dol)
THEN
651 ELSEIF(wbegin+newfst-1.GT.dou)
THEN
655 newftt = wbegin + newfst - 1
659 IF( newsiz.GT.1)
THEN
674 IF( newfst.EQ.1 )
THEN
676 $ w(wbegin)-werr(wbegin) - vl )
678 lgap = wgap( wbegin+newfst-2 )
680 rgap = wgap( wbegin+newlst-1 )
689 p = indexw( wbegin-1+newfst )
691 p = indexw( wbegin-1+newlst )
693 offset = indexw( wbegin ) - 1
694 CALL dlarrb( in, d(ibegin),
695 $ work( indlld+ibegin-1 ),p,p,
696 $ rqtol, rqtol, offset,
697 $ work(wbegin),wgap(wbegin),
698 $ werr(wbegin),work( indwrk ),
699 $ iwork( iindwk ), pivmin, spdiam,
703 IF((wbegin+newlst-1.LT.dol).OR.
704 $ (wbegin+newfst-1.GT.dou))
THEN
712 idone = idone + newlst - newfst + 1
720 CALL dlarrf( in, d( ibegin ), l( ibegin ),
721 $ work(indld+ibegin-1),
722 $ newfst, newlst, work(wbegin),
723 $ wgap(wbegin), werr(wbegin),
724 $ spdiam, lgap, rgap, pivmin, tau,
725 $ z(ibegin, newftt),z(ibegin, newftt+1),
726 $ work( indwrk ), iinfo )
727 IF( iinfo.EQ.0 )
THEN
731 z( iend, newftt+1 ) = ssigma
734 DO 116 k = newfst, newlst
736 $ three*eps*abs(work(wbegin+k-1))
737 work( wbegin + k - 1 ) =
738 $ work( wbegin + k - 1) - tau
740 $ four*eps*abs(work(wbegin+k-1))
742 werr( wbegin + k - 1 ) =
743 $ werr( wbegin + k - 1 ) + fudge
755 iwork( k-1 ) = newfst
767 tol = four * log(dble(in)) * eps
770 windex = wbegin + k - 1
771 windmn = max(windex - 1,1)
772 windpl = min(windex + 1,m)
773 lambda = work( windex )
776 IF((windex.LT.dol).OR.
777 $ (windex.GT.dou))
THEN
783 left = work( windex ) - werr( windex )
784 right = work( windex ) + werr( windex )
785 indeig = indexw( windex )
800 lgap = eps*max(abs(left),abs(right))
810 rgap = eps*max(abs(left),abs(right))
814 gap = min( lgap, rgap )
815 IF(( k .EQ. 1).OR.(k .EQ. im))
THEN
830 savgap = wgap(windex)
847 itmp1 = iwork( iindr+windex )
848 offset = indexw( wbegin ) - 1
849 CALL dlarrb( in, d(ibegin),
850 $ work(indlld+ibegin-1),indeig,indeig,
851 $ zero, two*eps, offset,
852 $ work(wbegin),wgap(wbegin),
853 $ werr(wbegin),work( indwrk ),
854 $ iwork( iindwk ), pivmin, spdiam,
856 IF( iinfo.NE.0 )
THEN
860 lambda = work( windex )
863 iwork( iindr+windex ) = 0
866 CALL dlar1v( in, 1, in, lambda, d( ibegin ),
867 $ l( ibegin ), work(indld+ibegin-1),
868 $ work(indlld+ibegin-1),
869 $ pivmin, gaptol, z( ibegin, windex ),
870 $ .NOT.usedbs, negcnt, ztz, mingma,
871 $ iwork( iindr+windex ), isuppz( 2*windex-1 ),
872 $ nrminv, resid, rqcorr, work( indwrk ) )
876 ELSEIF(resid.LT.bstres)
THEN
880 isupmn = min(isupmn,isuppz( 2*windex-1 ))
881 isupmx = max(isupmx,isuppz( 2*windex ))
893 IF( resid.GT.tol*gap .AND. abs( rqcorr ).GT.
894 $ rqtol*abs( lambda ) .AND. .NOT. usedbs)
899 IF(indeig.LE.negcnt)
THEN
908 IF( ( rqcorr*sgndef.GE.zero )
909 $ .AND.( lambda + rqcorr.LE. right)
910 $ .AND.( lambda + rqcorr.GE. left)
914 IF(sgndef.EQ.one)
THEN
933 $ half * (right + left)
936 lambda = lambda + rqcorr
939 $ half * (right-left)
943 IF(right-left.LT.rqtol*abs(lambda))
THEN
948 ELSEIF( iter.LT.maxitr )
THEN
950 ELSEIF( iter.EQ.maxitr )
THEN
959 IF(usedrq .AND. usedbs .AND.
960 $ bstres.LE.resid)
THEN
966 CALL dlar1v( in, 1, in, lambda,
967 $ d( ibegin ), l( ibegin ),
968 $ work(indld+ibegin-1),
969 $ work(indlld+ibegin-1),
970 $ pivmin, gaptol, z( ibegin, windex ),
971 $ .NOT.usedbs, negcnt, ztz, mingma,
972 $ iwork( iindr+windex ),
973 $ isuppz( 2*windex-1 ),
974 $ nrminv, resid, rqcorr, work( indwrk ) )
976 work( windex ) = lambda
981 isuppz( 2*windex-1 ) = isuppz( 2*windex-1 )+oldien
982 isuppz( 2*windex ) = isuppz( 2*windex )+oldien
983 zfrom = isuppz( 2*windex-1 )
984 zto = isuppz( 2*windex )
985 isupmn = isupmn + oldien
986 isupmx = isupmx + oldien
988 IF(isupmn.LT.zfrom)
THEN
989 DO 122 ii = isupmn,zfrom-1
990 z( ii, windex ) = zero
993 IF(isupmx.GT.zto)
THEN
994 DO 123 ii = zto+1,isupmx
995 z( ii, windex ) = zero
998 CALL dscal( zto-zfrom+1, nrminv,
999 $ z( zfrom, windex ), 1 )
1002 w( windex ) = lambda+sigma
1011 wgap( windmn ) = max( wgap(windmn),
1012 $ w(windex)-werr(windex)
1013 $ - w(windmn)-werr(windmn) )
1015 IF( windex.LT.wend )
THEN
1016 wgap( windex ) = max( savgap,
1017 $ w( windpl )-werr( windpl )
1018 $ - w( windex )-werr( windex) )
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dlar1v(n, b1, bn, lambda, d, l, ld, lld, pivmin, gaptol, z, wantnc, negcnt, ztz, mingma, r, isuppz, nrminv, resid, rqcorr, work)
DLAR1V computes the (scaled) r-th column of the inverse of the submatrix in rows b1 through bn of the...
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 dlarrf(n, d, l, ld, clstrt, clend, w, wgap, werr, spdiam, clgapl, clgapr, pivmin, sigma, dplus, lplus, work, info)
DLARRF finds a new relatively robust representation such that at least one of the eigenvalues is rela...
subroutine dlarrv(n, vl, vu, d, l, pivmin, isplit, m, dol, dou, minrgp, rtol1, rtol2, w, werr, wgap, iblock, indexw, gers, z, ldz, isuppz, work, iwork, info)
DLARRV computes the eigenvectors of the tridiagonal matrix T = L D LT given L, D and the eigenvalues ...
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dscal(n, da, dx, incx)
DSCAL