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
395 zusedw = zusedu - zusedl + 1
398 CALL zlaset(
'Full', n, zusedw, czero, czero,
401 eps = dlamch(
'Precision' )
407 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN 426 DO 170 jblk = 1, iblock( m )
427 iend = isplit( jblk )
434 IF( iblock( wend+1 ).EQ.jblk )
THEN 439 IF( wend.LT.wbegin )
THEN 442 ELSEIF( (wend.LT.dol).OR.(wbegin.GT.dou) )
THEN 449 gl = gers( 2*ibegin-1 )
450 gu = gers( 2*ibegin )
451 DO 20 i = ibegin+1 , iend
452 gl = min( gers( 2*i-1 ), gl )
453 gu = max( gers( 2*i ), gu )
460 in = iend - ibegin + 1
462 im = wend - wbegin + 1
465 IF( ibegin.EQ.iend )
THEN 467 z( ibegin, wbegin ) = dcmplx( one, zero )
468 isuppz( 2*wbegin-1 ) = ibegin
469 isuppz( 2*wbegin ) = ibegin
470 w( wbegin ) = w( wbegin ) + sigma
471 work( wbegin ) = w( wbegin )
483 CALL dcopy( im, w( wbegin ), 1,
484 $ work( wbegin ), 1 )
489 w(wbegin+i-1) = w(wbegin+i-1)+sigma
500 iwork( iindc1+1 ) = 1
501 iwork( iindc1+2 ) = im
510 IF( idone.LT.im )
THEN 512 IF( ndepth.GT.m )
THEN 523 IF( parity.EQ.0 )
THEN 536 oldfst = iwork( j-1 )
538 IF( ndepth.GT.0 )
THEN 544 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN 547 j = wbegin + oldfst - 1
549 IF(wbegin+oldfst-1.LT.dol)
THEN 552 ELSEIF(wbegin+oldfst-1.GT.dou)
THEN 556 j = wbegin + oldfst - 1
560 d( ibegin+k-1 ) = dble( z( ibegin+k-1,
562 l( ibegin+k-1 ) = dble( z( ibegin+k-1,
565 d( iend ) = dble( z( iend, j ) )
566 sigma = dble( z( iend, j+1 ) )
569 CALL zlaset(
'Full', in, 2, czero, czero,
570 $ z( ibegin, j), ldz )
574 DO 50 j = ibegin, iend-1
576 work( indld-1+j ) = tmp
577 work( indlld-1+j ) = tmp*l( j )
580 IF( ndepth.GT.0 )
THEN 583 p = indexw( wbegin-1+oldfst )
584 q = indexw( wbegin-1+oldlst )
588 offset = indexw( wbegin ) - 1
591 CALL dlarrb( in, d( ibegin ),
592 $ work(indlld+ibegin-1),
593 $ p, q, rtol1, rtol2, offset,
594 $ work(wbegin),wgap(wbegin),werr(wbegin),
595 $ work( indwrk ), iwork( iindwk ),
596 $ pivmin, spdiam, in, iinfo )
597 IF( iinfo.NE.0 )
THEN 608 IF( oldfst.GT.1)
THEN 609 wgap( wbegin+oldfst-2 ) =
610 $ max(wgap(wbegin+oldfst-2),
611 $ w(wbegin+oldfst-1)-werr(wbegin+oldfst-1)
612 $ - w(wbegin+oldfst-2)-werr(wbegin+oldfst-2) )
614 IF( wbegin + oldlst -1 .LT. wend )
THEN 615 wgap( wbegin+oldlst-1 ) =
616 $ max(wgap(wbegin+oldlst-1),
617 $ w(wbegin+oldlst)-werr(wbegin+oldlst)
618 $ - w(wbegin+oldlst-1)-werr(wbegin+oldlst-1) )
622 DO 53 j=oldfst,oldlst
623 w(wbegin+j-1) = work(wbegin+j-1)+sigma
629 DO 140 j = oldfst, oldlst
630 IF( j.EQ.oldlst )
THEN 634 ELSE IF ( wgap( wbegin + j -1).GE.
635 $ minrgp* abs( work(wbegin + j -1) ) )
THEN 646 newsiz = newlst - newfst + 1
650 IF((dol.EQ.1).AND.(dou.EQ.m))
THEN 653 newftt = wbegin + newfst - 1
655 IF(wbegin+newfst-1.LT.dol)
THEN 658 ELSEIF(wbegin+newfst-1.GT.dou)
THEN 662 newftt = wbegin + newfst - 1
666 IF( newsiz.GT.1)
THEN 681 IF( newfst.EQ.1 )
THEN 683 $ w(wbegin)-werr(wbegin) - vl )
685 lgap = wgap( wbegin+newfst-2 )
687 rgap = wgap( wbegin+newlst-1 )
696 p = indexw( wbegin-1+newfst )
698 p = indexw( wbegin-1+newlst )
700 offset = indexw( wbegin ) - 1
701 CALL dlarrb( in, d(ibegin),
702 $ work( indlld+ibegin-1 ),p,p,
703 $ rqtol, rqtol, offset,
704 $ work(wbegin),wgap(wbegin),
705 $ werr(wbegin),work( indwrk ),
706 $ iwork( iindwk ), pivmin, spdiam,
710 IF((wbegin+newlst-1.LT.dol).OR.
711 $ (wbegin+newfst-1.GT.dou))
THEN 719 idone = idone + newlst - newfst + 1
727 CALL dlarrf( in, d( ibegin ), l( ibegin ),
728 $ work(indld+ibegin-1),
729 $ newfst, newlst, work(wbegin),
730 $ wgap(wbegin), werr(wbegin),
731 $ spdiam, lgap, rgap, pivmin, tau,
732 $ work( indin1 ), work( indin2 ),
733 $ work( indwrk ), iinfo )
738 z( ibegin+k-1, newftt ) =
739 $ dcmplx( work( indin1+k-1 ), zero )
740 z( ibegin+k-1, newftt+1 ) =
741 $ dcmplx( work( indin2+k-1 ), zero )
744 $ dcmplx( work( indin1+in-1 ), zero )
745 IF( iinfo.EQ.0 )
THEN 749 z( iend, newftt+1 ) = dcmplx( ssigma, zero )
752 DO 116 k = newfst, newlst
754 $ three*eps*abs(work(wbegin+k-1))
755 work( wbegin + k - 1 ) =
756 $ work( wbegin + k - 1) - tau
758 $ four*eps*abs(work(wbegin+k-1))
760 werr( wbegin + k - 1 ) =
761 $ werr( wbegin + k - 1 ) + fudge
773 iwork( k-1 ) = newfst
785 tol = four * log(dble(in)) * eps
788 windex = wbegin + k - 1
789 windmn = max(windex - 1,1)
790 windpl = min(windex + 1,m)
791 lambda = work( windex )
794 IF((windex.LT.dol).OR.
795 $ (windex.GT.dou))
THEN 801 left = work( windex ) - werr( windex )
802 right = work( windex ) + werr( windex )
803 indeig = indexw( windex )
818 lgap = eps*max(abs(left),abs(right))
828 rgap = eps*max(abs(left),abs(right))
832 gap = min( lgap, rgap )
833 IF(( k .EQ. 1).OR.(k .EQ. im))
THEN 848 savgap = wgap(windex)
865 itmp1 = iwork( iindr+windex )
866 offset = indexw( wbegin ) - 1
867 CALL dlarrb( in, d(ibegin),
868 $ work(indlld+ibegin-1),indeig,indeig,
869 $ zero, two*eps, offset,
870 $ work(wbegin),wgap(wbegin),
871 $ werr(wbegin),work( indwrk ),
872 $ iwork( iindwk ), pivmin, spdiam,
874 IF( iinfo.NE.0 )
THEN 878 lambda = work( windex )
881 iwork( iindr+windex ) = 0
884 CALL zlar1v( in, 1, in, lambda, d( ibegin ),
885 $ l( ibegin ), work(indld+ibegin-1),
886 $ work(indlld+ibegin-1),
887 $ pivmin, gaptol, z( ibegin, windex ),
888 $ .NOT.usedbs, negcnt, ztz, mingma,
889 $ iwork( iindr+windex ), isuppz( 2*windex-1 ),
890 $ nrminv, resid, rqcorr, work( indwrk ) )
894 ELSEIF(resid.LT.bstres)
THEN 898 isupmn = min(isupmn,isuppz( 2*windex-1 ))
899 isupmx = max(isupmx,isuppz( 2*windex ))
911 IF( resid.GT.tol*gap .AND. abs( rqcorr ).GT.
912 $ rqtol*abs( lambda ) .AND. .NOT. usedbs)
917 IF(indeig.LE.negcnt)
THEN 926 IF( ( rqcorr*sgndef.GE.zero )
927 $ .AND.( lambda + rqcorr.LE. right)
928 $ .AND.( lambda + rqcorr.GE. left)
932 IF(sgndef.EQ.one)
THEN 951 $ half * (right + left)
954 lambda = lambda + rqcorr
957 $ half * (right-left)
961 IF(right-left.LT.rqtol*abs(lambda))
THEN 966 ELSEIF( iter.LT.maxitr )
THEN 968 ELSEIF( iter.EQ.maxitr )
THEN 977 IF(usedrq .AND. usedbs .AND.
978 $ bstres.LE.resid)
THEN 984 CALL zlar1v( in, 1, in, lambda,
985 $ d( ibegin ), l( ibegin ),
986 $ work(indld+ibegin-1),
987 $ work(indlld+ibegin-1),
988 $ pivmin, gaptol, z( ibegin, windex ),
989 $ .NOT.usedbs, negcnt, ztz, mingma,
990 $ iwork( iindr+windex ),
991 $ isuppz( 2*windex-1 ),
992 $ nrminv, resid, rqcorr, work( indwrk ) )
994 work( windex ) = lambda
999 isuppz( 2*windex-1 ) = isuppz( 2*windex-1 )+oldien
1000 isuppz( 2*windex ) = isuppz( 2*windex )+oldien
1001 zfrom = isuppz( 2*windex-1 )
1002 zto = isuppz( 2*windex )
1003 isupmn = isupmn + oldien
1004 isupmx = isupmx + oldien
1006 IF(isupmn.LT.zfrom)
THEN 1007 DO 122 ii = isupmn,zfrom-1
1008 z( ii, windex ) = zero
1011 IF(isupmx.GT.zto)
THEN 1012 DO 123 ii = zto+1,isupmx
1013 z( ii, windex ) = zero
1016 CALL zdscal( zto-zfrom+1, nrminv,
1017 $ z( zfrom, windex ), 1 )
1020 w( windex ) = lambda+sigma
1029 wgap( windmn ) = max( wgap(windmn),
1030 $ w(windex)-werr(windex)
1031 $ - w(windmn)-werr(windmn) )
1033 IF( windex.LT.wend )
THEN 1034 wgap( windex ) = max( savgap,
1035 $ w( windpl )-werr( windpl )
1036 $ - 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 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 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 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 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 zdscal(N, DA, ZX, INCX)
ZDSCAL