283 SUBROUTINE clarrv( 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 REAL MINRGP, PIVMIN, RTOL1, RTOL2, VL, VU
299 INTEGER IBLOCK( * ), INDEXW( * ), ISPLIT( * ),
300 $ isuppz( * ), iwork( * )
301 REAL D( * ), GERS( * ), L( * ), W( * ), WERR( * ),
302 $ WGAP( * ), WORK( * )
310 PARAMETER ( MAXITR = 10 )
312 parameter( czero = ( 0.0e0, 0.0e0 ) )
313 REAL ZERO, ONE, TWO, THREE, FOUR, HALF
314 parameter( zero = 0.0e0, one = 1.0e0,
315 $ two = 2.0e0, three = 3.0e0,
316 $ four = 4.0e0, half = 0.5e0)
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 REAL 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
344 INTRINSIC abs, real, max, min
395 zusedw = zusedu - zusedl + 1
398 CALL claset(
'Full', n, zusedw, czero, czero,
401 eps = slamch(
'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 ) = cmplx( 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 scopy( 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 ) = real( z( ibegin+k-1,
562 l( ibegin+k-1 ) = real( z( ibegin+k-1,
565 d( iend ) = real( z( iend, j ) )
566 sigma = real( z( iend, j+1 ) )
569 CALL claset(
'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 slarrb( 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 slarrb( 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 slarrf( 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 $ cmplx( work( indin1+k-1 ), zero )
740 z( ibegin+k-1, newftt+1 ) =
741 $ cmplx( work( indin2+k-1 ), zero )
744 $ cmplx( work( indin1+in-1 ), zero )
745 IF( iinfo.EQ.0 )
THEN
749 z( iend, newftt+1 ) = cmplx( 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(real(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 slarrb( 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 clar1v( 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 clar1v( 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 csscal( 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) )