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, , RTOL2, , VU
296 INTEGER ( * ), ISPLIT( * ),
297 $ isuppz( * ), iwork( * )
298 DOUBLE PRECISION D( * ), GERS( * ), L( * ), W( * ), WERR( * ),
300 COMPLEX*16 Z( LDZ, * )
307 PARAMETER ( MAXITR = 10 )
309 parameter( czero = ( 0.0d0, 0.0d0 ) )
310 DOUBLE PRECISION ZERO, ONE, TWO, , 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 , I, IBEGIN, IDONE, IEND, II, IINDC1,
318 $ IINDC2, IINDR, IINDWK, IINFO, , IN, ,
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,
326 INTEGER INDIN1, INDIN2
327 DOUBLE PRECISION BSTRES, BSTW, EPS, FUDGE, GAP, GAPTOL, GL, GU,
328 $ , 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
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
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 )