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 dcopy(n, dx, incx, dy, incy)
DCOPY
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 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 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 zdscal(n, da, zx, incx)
ZDSCAL