283 SUBROUTINE zlarrv( N, VL, VU, D, L, PIVMIN,
284 $ isplit, m, dol, dou, minrgp,
285 $ rtol1, rtol2, w, werr, wgap,
286 $ iblock, indexw, gers, z, ldz, isuppz,
287 $ work, iwork, info )
295 INTEGER DOL, DOU, INFO, LDZ, M, N
296 DOUBLE PRECISION MINRGP, PIVMIN, RTOL1, RTOL2, VL, VU
299 INTEGER IBLOCK( * ), INDEXW( * ), ISPLIT( * ),
300 $ isuppz( * ), iwork( * )
301 DOUBLE PRECISION D( * ), GERS( * ), L( * ), W( * ), WERR( * ),
302 $ wgap( * ), work( * )
303 COMPLEX*16 Z( ldz, * )
310 parameter ( maxitr = 10 )
312 parameter ( czero = ( 0.0d0, 0.0d0 ) )
313 DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, HALF
314 parameter ( zero = 0.0d0, one = 1.0d0,
315 $ two = 2.0d0, three = 3.0d0,
316 $ four = 4.0d0, half = 0.5d0)
319 LOGICAL ESKIP, NEEDBS, STP2II, TRYRQC, USEDBS, USEDRQ
320 INTEGER DONE, I, IBEGIN, IDONE, IEND, II, IINDC1,
321 $ iindc2, iindr, iindwk, iinfo, im, in, indeig,
322 $ indld, indlld, indwrk, isupmn, isupmx, iter,
323 $ itmp1, j, jblk, k, miniwsize, minwsize, nclus,
324 $ ndepth, negcnt, newcls, newfst, newftt, newlst,
325 $ newsiz, offset, oldcls, oldfst, oldien, oldlst,
326 $ oldncl, p, parity, q, wbegin, wend, windex,
327 $ windmn, windpl, zfrom, zto, zusedl, zusedu,
329 INTEGER INDIN1, INDIN2
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
388 zusedw = zusedu - zusedl + 1
391 CALL zlaset(
'Full', n, zusedw, czero, czero,
394 eps = dlamch(
'Precision' )
400 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN
419 DO 170 jblk = 1, iblock( m )
420 iend = isplit( jblk )
427 IF( iblock( wend+1 ).EQ.jblk )
THEN
432 IF( wend.LT.wbegin )
THEN
435 ELSEIF( (wend.LT.dol).OR.(wbegin.GT.dou) )
THEN
442 gl = gers( 2*ibegin-1 )
443 gu = gers( 2*ibegin )
444 DO 20 i = ibegin+1 , iend
445 gl = min( gers( 2*i-1 ), gl )
446 gu = max( gers( 2*i ), gu )
453 in = iend - ibegin + 1
455 im = wend - wbegin + 1
458 IF( ibegin.EQ.iend )
THEN
460 z( ibegin, wbegin ) = dcmplx( one, zero )
461 isuppz( 2*wbegin-1 ) = ibegin
462 isuppz( 2*wbegin ) = ibegin
463 w( wbegin ) = w( wbegin ) + sigma
464 work( wbegin ) = w( wbegin )
476 CALL dcopy( im, w( wbegin ), 1,
477 $ work( wbegin ), 1 )
482 w(wbegin+i-1) = w(wbegin+i-1)+sigma
493 iwork( iindc1+1 ) = 1
494 iwork( iindc1+2 ) = im
503 IF( idone.LT.im )
THEN
505 IF( ndepth.GT.m )
THEN
516 IF( parity.EQ.0 )
THEN
529 oldfst = iwork( j-1 )
531 IF( ndepth.GT.0 )
THEN
537 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN
540 j = wbegin + oldfst - 1
542 IF(wbegin+oldfst-1.LT.dol)
THEN
545 ELSEIF(wbegin+oldfst-1.GT.dou)
THEN
549 j = wbegin + oldfst - 1
553 d( ibegin+k-1 ) = dble( z( ibegin+k-1,
555 l( ibegin+k-1 ) = dble( z( ibegin+k-1,
558 d( iend ) = dble( z( iend, j ) )
559 sigma = dble( z( iend, j+1 ) )
562 CALL zlaset(
'Full', in, 2, czero, czero,
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 $ work( indin1 ), work( indin2 ),
726 $ work( indwrk ), iinfo )
731 z( ibegin+k-1, newftt ) =
732 $ dcmplx( work( indin1+k-1 ), zero )
733 z( ibegin+k-1, newftt+1 ) =
734 $ dcmplx( work( indin2+k-1 ), zero )
737 $ dcmplx( work( indin1+in-1 ), zero )
738 IF( iinfo.EQ.0 )
THEN
742 z( iend, newftt+1 ) = dcmplx( ssigma, zero )
745 DO 116 k = newfst, newlst
747 $ three*eps*abs(work(wbegin+k-1))
748 work( wbegin + k - 1 ) =
749 $ work( wbegin + k - 1) - tau
751 $ four*eps*abs(work(wbegin+k-1))
753 werr( wbegin + k - 1 ) =
754 $ werr( wbegin + k - 1 ) + fudge
766 iwork( k-1 ) = newfst
778 tol = four * log(dble(in)) * eps
781 windex = wbegin + k - 1
782 windmn = max(windex - 1,1)
783 windpl = min(windex + 1,m)
784 lambda = work( windex )
787 IF((windex.LT.dol).OR.
788 $ (windex.GT.dou))
THEN
794 left = work( windex ) - werr( windex )
795 right = work( windex ) + werr( windex )
796 indeig = indexw( windex )
811 lgap = eps*max(abs(left),abs(right))
821 rgap = eps*max(abs(left),abs(right))
825 gap = min( lgap, rgap )
826 IF(( k .EQ. 1).OR.(k .EQ. im))
THEN
841 savgap = wgap(windex)
858 itmp1 = iwork( iindr+windex )
859 offset = indexw( wbegin ) - 1
860 CALL dlarrb( in, d(ibegin),
861 $ work(indlld+ibegin-1),indeig,indeig,
862 $ zero, two*eps, offset,
863 $ work(wbegin),wgap(wbegin),
864 $ werr(wbegin),work( indwrk ),
865 $ iwork( iindwk ), pivmin, spdiam,
867 IF( iinfo.NE.0 )
THEN
871 lambda = work( windex )
874 iwork( iindr+windex ) = 0
877 CALL zlar1v( in, 1, in, lambda, d( ibegin ),
878 $ l( ibegin ), work(indld+ibegin-1),
879 $ work(indlld+ibegin-1),
880 $ pivmin, gaptol, z( ibegin, windex ),
881 $ .NOT.usedbs, negcnt, ztz, mingma,
882 $ iwork( iindr+windex ), isuppz( 2*windex-1 ),
883 $ nrminv, resid, rqcorr, work( indwrk ) )
887 ELSEIF(resid.LT.bstres)
THEN
891 isupmn = min(isupmn,isuppz( 2*windex-1 ))
892 isupmx = max(isupmx,isuppz( 2*windex ))
904 IF( resid.GT.tol*gap .AND. abs( rqcorr ).GT.
905 $ rqtol*abs( lambda ) .AND. .NOT. usedbs)
910 IF(indeig.LE.negcnt)
THEN
919 IF( ( rqcorr*sgndef.GE.zero )
920 $ .AND.( lambda + rqcorr.LE. right)
921 $ .AND.( lambda + rqcorr.GE. left)
925 IF(sgndef.EQ.one)
THEN
944 $ half * (right + left)
947 lambda = lambda + rqcorr
950 $ half * (right-left)
954 IF(right-left.LT.rqtol*abs(lambda))
THEN
959 ELSEIF( iter.LT.maxitr )
THEN
961 ELSEIF( iter.EQ.maxitr )
THEN
970 IF(usedrq .AND. usedbs .AND.
971 $ bstres.LE.resid)
THEN
977 CALL zlar1v( in, 1, in, lambda,
978 $ d( ibegin ), l( ibegin ),
979 $ work(indld+ibegin-1),
980 $ work(indlld+ibegin-1),
981 $ pivmin, gaptol, z( ibegin, windex ),
982 $ .NOT.usedbs, negcnt, ztz, mingma,
983 $ iwork( iindr+windex ),
984 $ isuppz( 2*windex-1 ),
985 $ nrminv, resid, rqcorr, work( indwrk ) )
987 work( windex ) = lambda
992 isuppz( 2*windex-1 ) = isuppz( 2*windex-1 )+oldien
993 isuppz( 2*windex ) = isuppz( 2*windex )+oldien
994 zfrom = isuppz( 2*windex-1 )
995 zto = isuppz( 2*windex )
996 isupmn = isupmn + oldien
997 isupmx = isupmx + oldien
999 IF(isupmn.LT.zfrom)
THEN
1000 DO 122 ii = isupmn,zfrom-1
1001 z( ii, windex ) = zero
1004 IF(isupmx.GT.zto)
THEN
1005 DO 123 ii = zto+1,isupmx
1006 z( ii, windex ) = zero
1009 CALL zdscal( zto-zfrom+1, nrminv,
1010 $ z( zfrom, windex ), 1 )
1013 w( windex ) = lambda+sigma
1022 wgap( windmn ) = max( wgap(windmn),
1023 $ w(windex)-werr(windex)
1024 $ - w(windmn)-werr(windmn) )
1026 IF( windex.LT.wend )
THEN
1027 wgap( windex ) = max( savgap,
1028 $ w( windpl )-werr( windpl )
1029 $ - w( windex )-werr( windex) )
subroutine dcopy(N, DX, INCX, DY, INCY)
DCOPY
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 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 zdscal(N, DA, ZX, INCX)
ZDSCAL