281 SUBROUTINE zlarrv( N, VL, VU, D, L, PIVMIN,
282 $ ISPLIT, M, DOL, DOU, MINRGP,
283 $ RTOL1, RTOL2, W, WERR, WGAP,
284 $ IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,
285 $ WORK, IWORK, INFO )
292 INTEGER DOL, DOU, INFO, LDZ, M, N
293 DOUBLE PRECISION MINRGP, PIVMIN, RTOL1, RTOL2, VL, VU
296 INTEGER IBLOCK( * ), INDEXW( * ), ISPLIT( * ),
297 $ isuppz( * ), iwork( * )
298 DOUBLE PRECISION D( * ), GERS( * ), L( * ), W( * ), WERR( * ),
299 $ wgap( * ), work( * )
300 COMPLEX*16 Z( ldz, * )
307 parameter( maxitr = 10 )
309 parameter( czero = ( 0.0d0, 0.0d0 ) )
310 DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, HALF
311 parameter( zero = 0.0d0, one = 1.0d0,
312 $ two = 2.0d0, three = 3.0d0,
313 $ four = 4.0d0, half = 0.5d0)
316 LOGICAL ESKIP, NEEDBS, STP2II, TRYRQC, USEDBS, USEDRQ
317 INTEGER DONE, I, IBEGIN, IDONE, IEND, II, IINDC1,
318 $ iindc2, iindr, iindwk, iinfo, im, in, indeig,
319 $ indld, indlld, indwrk, isupmn, isupmx, iter,
320 $ itmp1, j, jblk, k, miniwsize, minwsize, nclus,
321 $ ndepth, negcnt, newcls, newfst, newftt, newlst,
322 $ newsiz, offset, oldcls, oldfst, oldien, oldlst,
323 $ oldncl, p, parity, q, wbegin, wend, windex,
324 $ windmn, windpl, zfrom, zto, zusedl, zusedu,
326 INTEGER INDIN1, INDIN2
327 DOUBLE PRECISION BSTRES, BSTW, EPS, FUDGE, GAP, GAPTOL, GL, GU,
328 $ lambda, left, lgap, mingma, nrminv, resid,
329 $ rgap, right, rqcorr, rqtol, savgap, sgndef,
330 $ sigma, spdiam, ssigma, tau, tmp, tol, ztz
333 DOUBLE PRECISION DLAMCH
341 INTRINSIC abs, dble, max, min
351 IF( (n.LE.0).OR.(m.LE.0) )
THEN 392 zusedw = zusedu - zusedl + 1
395 CALL zlaset(
'Full', n, zusedw, czero, czero,
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 ) = dcmplx( one, zero )
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
557 d( ibegin+k-1 ) = dble( z( ibegin+k-1,
559 l( ibegin+k-1 ) = dble( z( ibegin+k-1,
562 d( iend ) = dble( z( iend, j ) )
563 sigma = dble( z( iend, j+1 ) )
566 CALL zlaset(
'Full', in, 2, czero, czero,
567 $ z( ibegin, j), ldz )
571 DO 50 j = ibegin, iend-1
573 work( indld-1+j ) = tmp
574 work( indlld-1+j ) = tmp*l( j )
577 IF( ndepth.GT.0 )
THEN 580 p = indexw( wbegin-1+oldfst )
581 q = indexw( wbegin-1+oldlst )
585 offset = indexw( wbegin ) - 1
588 CALL dlarrb( in, d( ibegin ),
589 $ work(indlld+ibegin-1),
590 $ p, q, rtol1, rtol2, offset,
591 $ work(wbegin),wgap(wbegin),werr(wbegin),
592 $ work( indwrk ), iwork( iindwk ),
593 $ pivmin, spdiam, in, iinfo )
594 IF( iinfo.NE.0 )
THEN 605 IF( oldfst.GT.1)
THEN 606 wgap( wbegin+oldfst-2 ) =
607 $ max(wgap(wbegin+oldfst-2),
608 $ w(wbegin+oldfst-1)-werr(wbegin+oldfst-1)
609 $ - w(wbegin+oldfst-2)-werr(wbegin+oldfst-2) )
611 IF( wbegin + oldlst -1 .LT. wend )
THEN 612 wgap( wbegin+oldlst-1 ) =
613 $ max(wgap(wbegin+oldlst-1),
614 $ w(wbegin+oldlst)-werr(wbegin+oldlst)
615 $ - w(wbegin+oldlst-1)-werr(wbegin+oldlst-1) )
619 DO 53 j=oldfst,oldlst
620 w(wbegin+j-1) = work(wbegin+j-1)+sigma
626 DO 140 j = oldfst, oldlst
627 IF( j.EQ.oldlst )
THEN 631 ELSE IF ( wgap( wbegin + j -1).GE.
632 $ minrgp* abs( work(wbegin + j -1) ) )
THEN 643 newsiz = newlst - newfst + 1
647 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN 650 newftt = wbegin + newfst - 1
652 IF(wbegin+newfst-1.LT.dol)
THEN 655 ELSEIF(wbegin+newfst-1.GT.dou)
THEN 659 newftt = wbegin + newfst - 1
663 IF( newsiz.GT.1)
THEN 678 IF( newfst.EQ.1 )
THEN 680 $ w(wbegin)-werr(wbegin) - vl )
682 lgap = wgap( wbegin+newfst-2 )
684 rgap = wgap( wbegin+newlst-1 )
693 p = indexw( wbegin-1+newfst )
695 p = indexw( wbegin-1+newlst )
697 offset = indexw( wbegin ) - 1
698 CALL dlarrb( in, d(ibegin),
699 $ work( indlld+ibegin-1 ),p,p,
700 $ rqtol, rqtol, offset,
701 $ work(wbegin),wgap(wbegin),
702 $ werr(wbegin),work( indwrk ),
703 $ iwork( iindwk ), pivmin, spdiam,
707 IF((wbegin+newlst-1.LT.dol).OR.
708 $ (wbegin+newfst-1.GT.dou))
THEN 716 idone = idone + newlst - newfst + 1
724 CALL dlarrf( in, d( ibegin ), l( ibegin ),
725 $ work(indld+ibegin-1),
726 $ newfst, newlst, work(wbegin),
727 $ wgap(wbegin), werr(wbegin),
728 $ spdiam, lgap, rgap, pivmin, tau,
729 $ work( indin1 ), work( indin2 ),
730 $ work( indwrk ), iinfo )
735 z( ibegin+k-1, newftt ) =
736 $ dcmplx( work( indin1+k-1 ), zero )
737 z( ibegin+k-1, newftt+1 ) =
738 $ dcmplx( work( indin2+k-1 ), zero )
741 $ dcmplx( work( indin1+in-1 ), zero )
742 IF( iinfo.EQ.0 )
THEN 746 z( iend, newftt+1 ) = dcmplx( ssigma, zero )
749 DO 116 k = newfst, newlst
751 $ three*eps*abs(work(wbegin+k-1))
752 work( wbegin + k - 1 ) =
753 $ work( wbegin + k - 1) - tau
755 $ four*eps*abs(work(wbegin+k-1))
757 werr( wbegin + k - 1 ) =
758 $ werr( wbegin + k - 1 ) + fudge
770 iwork( k-1 ) = newfst
782 tol = four * log(dble(in)) * eps
785 windex = wbegin + k - 1
786 windmn = max(windex - 1,1)
787 windpl = min(windex + 1,m)
788 lambda = work( windex )
791 IF((windex.LT.dol).OR.
792 $ (windex.GT.dou))
THEN 798 left = work( windex ) - werr( windex )
799 right = work( windex ) + werr( windex )
800 indeig = indexw( windex )
815 lgap = eps*max(abs(left),abs(right))
825 rgap = eps*max(abs(left),abs(right))
829 gap = min( lgap, rgap )
830 IF(( k .EQ. 1).OR.(k .EQ. im))
THEN 845 savgap = wgap(windex)
862 itmp1 = iwork( iindr+windex )
863 offset = indexw( wbegin ) - 1
864 CALL dlarrb( in, d(ibegin),
865 $ work(indlld+ibegin-1),indeig,indeig,
866 $ zero, two*eps, offset,
867 $ work(wbegin),wgap(wbegin),
868 $ werr(wbegin),work( indwrk ),
869 $ iwork( iindwk ), pivmin, spdiam,
871 IF( iinfo.NE.0 )
THEN 875 lambda = work( windex )
878 iwork( iindr+windex ) = 0
881 CALL zlar1v( in, 1, in, lambda, d( ibegin ),
882 $ l( ibegin ), work(indld+ibegin-1),
883 $ work(indlld+ibegin-1),
884 $ pivmin, gaptol, z( ibegin, windex ),
885 $ .NOT.usedbs, negcnt, ztz, mingma,
886 $ iwork( iindr+windex ), isuppz( 2*windex-1 ),
887 $ nrminv, resid, rqcorr, work( indwrk ) )
891 ELSEIF(resid.LT.bstres)
THEN 895 isupmn = min(isupmn,isuppz( 2*windex-1 ))
896 isupmx = max(isupmx,isuppz( 2*windex ))
908 IF( resid.GT.tol*gap .AND. abs( rqcorr ).GT.
909 $ rqtol*abs( lambda ) .AND. .NOT. usedbs)
914 IF(indeig.LE.negcnt)
THEN 923 IF( ( rqcorr*sgndef.GE.zero )
924 $ .AND.( lambda + rqcorr.LE. right)
925 $ .AND.( lambda + rqcorr.GE. left)
929 IF(sgndef.EQ.one)
THEN 948 $ half * (right + left)
951 lambda = lambda + rqcorr
954 $ half * (right-left)
958 IF(right-left.LT.rqtol*abs(lambda))
THEN 963 ELSEIF( iter.LT.maxitr )
THEN 965 ELSEIF( iter.EQ.maxitr )
THEN 974 IF(usedrq .AND. usedbs .AND.
975 $ bstres.LE.resid)
THEN 981 CALL zlar1v( in, 1, in, lambda,
982 $ d( ibegin ), l( ibegin ),
983 $ work(indld+ibegin-1),
984 $ work(indlld+ibegin-1),
985 $ pivmin, gaptol, z( ibegin, windex ),
986 $ .NOT.usedbs, negcnt, ztz, mingma,
987 $ iwork( iindr+windex ),
988 $ isuppz( 2*windex-1 ),
989 $ nrminv, resid, rqcorr, work( indwrk ) )
991 work( windex ) = lambda
996 isuppz( 2*windex-1 ) = isuppz( 2*windex-1 )+oldien
997 isuppz( 2*windex ) = isuppz( 2*windex )+oldien
998 zfrom = isuppz( 2*windex-1 )
999 zto = isuppz( 2*windex )
1000 isupmn = isupmn + oldien
1001 isupmx = isupmx + oldien
1003 IF(isupmn.LT.zfrom)
THEN 1004 DO 122 ii = isupmn,zfrom-1
1005 z( ii, windex ) = zero
1008 IF(isupmx.GT.zto)
THEN 1009 DO 123 ii = zto+1,isupmx
1010 z( ii, windex ) = zero
1013 CALL zdscal( zto-zfrom+1, nrminv,
1014 $ z( zfrom, windex ), 1 )
1017 w( windex ) = lambda+sigma
1026 wgap( windmn ) = max( wgap(windmn),
1027 $ w(windex)-werr(windex)
1028 $ - w(windmn)-werr(windmn) )
1030 IF( windex.LT.wend )
THEN 1031 wgap( windex ) = max( savgap,
1032 $ w( windpl )-werr( windpl )
1033 $ - w( windex )-werr( windex) )
subroutine zdscal(N, DA, ZX, INCX)
ZDSCAL
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 zlar1v(N, B1, BN, LAMBDA, D, L, LD, LLD, PIVMIN, GAPTOL, Z, WANTNC, NEGCNT, ZTZ, MINGMA, R, ISUPPZ, NRMINV, RESID, RQCORR, WORK)
ZLAR1V computes the (scaled) r-th column of the inverse of the submatrix in rows b1 through bn of the...
subroutine zlarrv(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)
ZLARRV computes the eigenvectors of the tridiagonal matrix T = L D LT given L, D and the eigenvalues ...
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
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 dcopy(N, DX, INCX, DY, INCY)
DCOPY