8 
    9
   10
   11
   12
   13      IMPLICIT NONE
   14
   15
   16      INTEGER            DOL, DOU, INFO, LDZ, M, N, MAXCLS,
   17     $                   NDEPTH, NEEDIL, NEEDIU, PARITY, ZOFFSET
   18      DOUBLE PRECISION   MINRGP, PIVMIN, RTOL1, RTOL2, VL, VU
   19      LOGICAL VSTART, FINISH 
   20
   21
   22      INTEGER            IBLOCK( * ), INDEXW( * ), ISPLIT( * ),
   23     $                   ISUPPZ( * ), IWORK( * )
   24      DOUBLE PRECISION   D( * ), GERS( * ), L( * ), SDIAM( * ), 
   25     $                   W( * ), WERR( * ),
   26     $                   WGAP( * ), WORK( * )
   27      DOUBLE PRECISION  Z( LDZ, * )
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247      INTEGER            MAXITR, USE30, USE31, USE32A, USE32B
  248      parameter( maxitr = 10, use30=30, use31=31, 
  249     $                     use32a=3210, use32b = 3211 )
  250      DOUBLE PRECISION   ZERO, ONE, TWO, THREE, FOUR, HALF
  251      parameter( zero = 0.0d0, one = 1.0d0, 
  252     $                     two = 2.0d0, three = 3.0d0,
  253     $                     four = 4.0d0, half = 0.5d0)
  254
  255
  256      INTEGER            SPLACE( 4 )
  257
  258
  259      LOGICAL            DELREF, ESKIP, NEEDBS, ONLYLC, STP2II, TRYMID,
  260     $                   TRYRQC, USEDBS, USEDRQ
  261      INTEGER            I, IBEGIN, IEND, II, IINCLS, IINDC1, IINDC2,
  262     $                   IINDWK, IINFO, IM, IN, INDEIG, INDLD, INDLLD,
  263     $                   INDWRK, ISUPMN, ISUPMX, ITER, ITMP1, ITWIST, J,
  264     $                   JBLK, K, KK, MINIWSIZE, MINWSIZE, MYWFST,
  265     $                   MYWLST, NCLUS, NEGCNT, NEWCLS, NEWFST, NEWFTT,
  266     $                   NEWLST, NEWSIZ, OFFSET, OLDCLS, OLDFST, OLDIEN,
  267     $                   OLDLST, OLDNCL, P, Q, VRTREE, WBEGIN, WEND,
  268     $                   WINDEX, WINDMN, WINDPL, ZFROM, ZINDEX, ZTO,
  269     $                   ZUSEDL, ZUSEDU, ZUSEDW
  270      DOUBLE PRECISION   AVGAP, BSTRES, BSTW, ENUFGP, EPS, FUDGE, GAP,
  271     $                   GAPTOL, LAMBDA, LEFT, LGAP, LGPVMN, LGSPDM,
  272     $                   LOG_IN, MGAP, MINGMA, MYERR, NRMINV, NXTERR,
  273     $                   ORTOL, RESID, RGAP, RIGHT, RLTL30, RQCORR,
  274     $                   RQTOL, SAVEGP, SGNDEF, SIGMA, SPDIAM, SSIGMA,
  275     $                   TAU, TMP, TOL, ZTZ
  276
  277
  278      DOUBLE PRECISION  DLAMCH
  279      DOUBLE PRECISION   DDOT, DNRM2
  280      EXTERNAL           ddot, 
dlamch, dnrm2
 
  281
  282
  285
  286
  287      INTRINSIC abs, dble, 
max, 
min, sqrt
 
  288
  289
  290
  291 
  292 
  293      info = 0
  294
  295      indld = n+1
  296      indlld= 2*n+1
  297      indwrk= 3*n+1
  298      minwsize = 12 * n
  299 
  300
  301
  302      iincls = 0
  303
  304
  305      iindc1 = n
  306      iindc2 = 2*n
  307      iindwk = 3*n + 1
  308      miniwsize = 7 * n
  309 
  310      eps = 
dlamch( 
'Precision' )
 
  311      rqtol = two * eps
  312 
  313      tryrqc = .true.
  314
  315
  316
  317
  318
  319      vrtree = use32a
  320
  321      lgpvmn = log( pivmin )
  322 
  323 
  324      IF(vstart) THEN
  325
  326
  327
  328         vstart = .false.   
  329
  330         maxcls = 1
  331 
  332
  333
  334
  335
  336         delref = .false.
  337 
  338         DO 1 i= 1,minwsize
  339            work( i ) = zero 
  340 1       CONTINUE
  341 
  342         DO 2 i= 1,miniwsize
  343            iwork( i ) = 0
  344 2       CONTINUE
  345 
  346         zusedl = 1
  347         IF(dol.GT.1) THEN
  348
  349            zusedl = dol-1
  350         ENDIF
  351         zusedu = m
  352         IF(dou.LT.m) THEN
  353
  354            zusedu = dou+1
  355         ENDIF
  356
  357         zusedw = zusedu - zusedl + 1
  358
  359         CALL dlaset( 'Full', n, zusedw, zero, zero, 
  360     $                    z(1,(zusedl-zoffset)), ldz )
  361 
  362
  363         ndepth = 0
  364
  365         parity = 1
  366 
  367
  368         ibegin = 1
  369         wbegin = 1
  370         DO 10 jblk = 1, iblock( m )
  371            iend = isplit( jblk )
  372            sigma = l( iend )
  373            wend = wbegin - 1
  374 3          CONTINUE
  375            IF( wend.LT.m ) THEN
  376               IF( iblock( wend+1 ).EQ.jblk ) THEN
  377                  wend = wend + 1
  378                  GO TO 3
  379               END IF
  380            END IF
  381            IF( wend.LT.wbegin ) THEN
  382               iwork( iincls + jblk ) = 0
  383               ibegin = iend + 1
  384               GO TO 10
  385            ELSEIF( (wend.LT.dol).OR.(wbegin.GT.dou) ) THEN
  386               iwork( iincls + jblk ) = 0
  387               ibegin = iend + 1
  388               wbegin = wend + 1
  389               GO TO 10
  390            END IF
  391
  392            im = wend - wbegin + 1
  393
  394            IF( ibegin.EQ.iend ) THEN
  395               iwork( iincls + jblk ) = 0
  396               z( ibegin, (wbegin-zoffset) ) = one
  397               isuppz( 2*wbegin-1 ) = ibegin
  398               isuppz( 2*wbegin ) = ibegin
  399               w( wbegin ) = w( wbegin ) + sigma
  400               work( wbegin ) = w( wbegin )
  401               ibegin = iend + 1
  402               wbegin = wbegin + 1
  403               GO TO 10
  404            END IF
  405            CALL dcopy( im, w( wbegin ), 1, 
  406     &                work( wbegin ), 1 )        
  407
  408
  409            DO 5 i=1,im
  410               w(wbegin+i-1) = w(wbegin+i-1)+sigma
  411 5          CONTINUE
  412 
  413
  414            iwork( iincls + jblk ) = 1
  415            iwork( iindc1+ibegin ) = 1
  416            iwork( iindc1+ibegin+1 ) = im
  417
  418            ibegin = iend + 1
  419            wbegin = wend + 1
  42010       CONTINUE
  421
  422      ENDIF 
  423 
  424
  425      needil = dou
  426      neediu = dol      
  427 
  428
  429
  430
  431 40   CONTINUE
  432 
  433      parity = 1 - parity
  434 
  435
  436
  437      ibegin = 1
  438      wbegin = 1
  439      DO 170 jblk = 1, iblock( m )
  440         iend = isplit( jblk )
  441         sigma = l( iend )
  442
  443
  444         IF(m.EQ.n) THEN
  445
  446            wend = iend
  447         ELSE
  448
  449            wend = wbegin - 1
  450 15         CONTINUE
  451            IF( wend.LT.m ) THEN
  452               IF( iblock( wend+1 ).EQ.jblk ) THEN
  453                  wend = wend + 1
  454                  GO TO 15
  455               END IF
  456            END IF
  457         ENDIF
  458 
  459         oldncl = iwork( iincls + jblk )
  460         IF( oldncl.EQ.0 ) THEN
  461            ibegin = iend + 1
  462            wbegin = wend + 1
  463            GO TO 170
  464         END IF
  465
  466         oldien = ibegin - 1
  467
  468         in = iend - ibegin + 1
  469
  470         im = wend - wbegin + 1
  471 
  472
  473         spdiam = sdiam(jblk)
  474         lgspdm = log( spdiam + pivmin )
  475
  476         ortol = spdiam*1.0d-3
  477
  478         avgap = spdiam/dble(in-1)
  479
  480
  481
  482         enufgp = 
min(ortol,avgap)
 
  483 
  484
  485 
  486
  487
  488         IF( oldncl.GT.0 ) THEN
  489
  490            IF( ndepth.GT.m ) THEN
  491               info = -2
  492               RETURN
  493            ENDIF
  494
  495
  496
  497
  498            nclus = 0
  499
  500            log_in = log(dble(in))
  501
  502            rltl30 = 
min( 1.0d-2, one / dble( in ) )
 
  503
  504            IF( parity.EQ.0 ) THEN
  505               oldcls = iindc1+ibegin-1
  506               newcls = iindc2+ibegin-1
  507            ELSE
  508               oldcls = iindc2+ibegin-1
  509               newcls = iindc1+ibegin-1
  510            END IF
  511
  512            DO 150 i = 1, oldncl
  513               j = oldcls + 2*i
  514
  515
  516
  517               oldfst = iwork( j-1 )
  518               oldlst = iwork( j )
  519               IF( ndepth.GT.0 ) THEN
  520
  521
  522
  523
  524 
  525                  IF((dol.EQ.1).AND.(dou.EQ.m)) THEN
  526
  527
  528                     j = wbegin + oldfst - 1
  529                  ELSE
  530                     IF(wbegin+oldfst-1.LT.dol) THEN
  531
  532                        j = dol - 1
  533                     ELSEIF(wbegin+oldfst-1.GT.dou) THEN
  534
  535                        j = dou
  536                     ELSE
  537                        j = wbegin + oldfst - 1
  538                     ENDIF
  539                  ENDIF
  540                  CALL dcopy( in, z( ibegin, (j-zoffset) ), 
  541     $               1, d( ibegin ), 1 )
  542                  CALL dcopy( in-1, z( ibegin, (j+1-zoffset) ), 
  543     $               1, l( ibegin ),1 )
  544                  sigma = z( iend, (j+1-zoffset) )
  545
  546                  CALL dlaset( 'Full', in, 2, zero, zero,
  547     $                         z( ibegin, (j-zoffset) ), ldz )
  548               END IF
  549 
  550
  551               DO 50 j = ibegin, iend-1
  552                  tmp = d( j )*l( j )
  553                  work( indld-1+j ) = tmp
  554                  work( indlld-1+j ) = tmp*l( j )
  555   50          CONTINUE
  556 
  557               IF( ndepth.GT.0 .AND. delref ) THEN
  558
  559
  560                  p = indexw( wbegin-1+oldfst )
  561                  q = indexw( wbegin-1+oldlst )
  562
  563
  564
  565                  offset = indexw( wbegin ) - 1
  566
  567
  569     $                         work(indlld+ibegin-1),
  570     $                         p, q, rtol1, rtol2, offset, 
  571     $                         work(wbegin),wgap(wbegin),werr(wbegin),
  572     $                         work( indwrk ), iwork( iindwk ),
  573     $                         pivmin, lgpvmn, lgspdm, in, iinfo )
  574                  IF( iinfo.NE.0 ) THEN
  575                     info = -1
  576                     RETURN
  577                  ENDIF       
  578
  579
  580
  581
  582
  583
  584
  585                  IF( oldfst.GT.1) THEN
  586                     wgap( wbegin+oldfst-2 ) = 
  587     $             
max(wgap(wbegin+oldfst-2),
 
  588     $                 w(wbegin+oldfst-1)-werr(wbegin+oldfst-1) 
  589     $                 - w(wbegin+oldfst-2)-werr(wbegin+oldfst-2) )
  590                  ENDIF
  591                  IF( wbegin + oldlst -1 .LT. wend ) THEN
  592                     wgap( wbegin+oldlst-1 ) = 
  593     $               
max(wgap(wbegin+oldlst-1), 
 
  594     $                   w(wbegin+oldlst)-werr(wbegin+oldlst) 
  595     $                   - w(wbegin+oldlst-1)-werr(wbegin+oldlst-1) )
  596                  ENDIF
  597
  598
  599                  DO 53 j=oldfst,oldlst
  600                     w(wbegin+j-1) = work(wbegin+j-1)+sigma
  601 53               CONTINUE
  602               ELSEIF( (ndepth.EQ.0) .OR. (.NOT.delref) ) THEN 
  603
  604
  605
  606
  607
  608                  DO 54 j = oldfst, oldlst-1
  609                     myerr = werr(wbegin + j - 1) 
  610                     nxterr = werr(wbegin + j )
  611                     wgap(wbegin+j-1) = 
max(wgap(wbegin+j-1),
 
  612     $                    (   work(wbegin+j) - nxterr ) 
  613     $                  - ( work(wbegin+j-1) + myerr )
  614     $                                     )
  615 54               CONTINUE
  616               END IF
  617
  618
  619
  620               newfst = oldfst
  621               DO 140 j = oldfst, oldlst
  622                  IF( j.EQ.oldlst ) THEN
  623
  624
  625                     newlst = j
  626                  ELSE 
  627                     IF (vrtree.EQ.use30) THEN
  628                        IF(wgap( wbegin + j -1).GE.
  629     $                     rltl30 * abs(work(wbegin + j -1)) ) THEN
  630
  631                           newlst = j
  632                        ELSE
  633
  634
  635                           GOTO 140
  636                        ENDIF
  637                     ELSE IF (vrtree.EQ.use31) THEN
  638                        IF ( wgap( wbegin + j -1).GE.
  639     $                      minrgp* abs( work(wbegin + j -1) ) ) THEN
  640
  641
  642                           newlst = j
  643                        ELSE
  644
  645
  646                           GOTO 140
  647                        ENDIF
  648                     ELSE IF (vrtree.EQ.use32a) THEN
  649                        IF( (j.EQ.oldfst).AND.( wgap(wbegin+j-1).GE.
  650     $                      minrgp* abs(work(wbegin+j-1)) ) ) THEN
  651
  652
  653                           newlst = j
  654                        ELSE IF( (j.GT.oldfst).AND.(j.EQ.newfst).AND.
  655     $                           ( wgap(wbegin+j-2).GE.
  656     $                             minrgp* abs(work(wbegin+j-1)) ).AND. 
  657     $                           ( wgap(wbegin+j-1).GE.
  658     $                             minrgp* abs(work(wbegin+j-1)) ) 
  659     $                     ) THEN
  660
  661                           newlst = j
  662                        ELSE IF( (j.GT.newfst).AND.wgap(wbegin+j-1).GE.
  663     $                     (minrgp*abs(work(wbegin+j-1)) ) ) 
  664     $                     THEN
  665
  666                           newlst = j
  667                        ELSE IF((j.GT.newfst).AND.(j+1.LT.oldlst).AND.
  668     $                     (wgap(wbegin+j-1).GE.enufgp))
  669     $                     THEN
  670
  671
  672
  673                           newlst = j
  674                        ELSE
  675
  676
  677                           GOTO 140
  678                        ENDIF
  679                     ELSE IF (vrtree.EQ.use32b) THEN
  680                        IF( (j.EQ.oldfst).AND.( wgap(wbegin+j-1).GE.
  681     $                      minrgp* abs(work(wbegin+j-1)) ) ) THEN
  682
  683
  684                           newlst = j
  685                        ELSE IF( (j.GT.oldfst).AND.(j.EQ.newfst).AND.
  686     $                           ( wgap(wbegin+j-2).GE.
  687     $                             minrgp* abs(work(wbegin+j-1)) ).AND. 
  688     $                           ( wgap(wbegin+j-1).GE.
  689     $                             minrgp* abs(work(wbegin+j-1)) ) 
  690     $                     ) THEN
  691
  692                           newlst = j
  693                        ELSE IF( (j.GT.newfst).AND.wgap(wbegin+j-1).GE.
  694     $                     (minrgp*abs(work(wbegin+j-1)) ) ) 
  695     $                     THEN
  696
  697                           newlst = j
  698                        ELSE IF((j.GT.newfst).AND.(j+1.LT.oldlst).AND.
  699     $                     (wgap( wbegin + j -1).GE.
  700     $                     rltl30 * abs(work(wbegin + j -1)) ))
  701     $                     THEN
  702
  703
  704
  705                           newlst = j
  706                        ELSE
  707
  708
  709                           GOTO 140
  710                        ENDIF
  711                     END IF
  712                  END IF
  713 
  714
  715                  newsiz = newlst - newfst + 1
  716                  maxcls = 
max( newsiz, maxcls )
 
  717 
  718
  719
  720                  IF((dol.EQ.1).AND.(dou.EQ.m)) THEN
  721
  722
  723                     newftt = wbegin + newfst - 1
  724                  ELSE
  725                     IF(wbegin+newfst-1.LT.dol) THEN
  726
  727                        newftt = dol - 1
  728                     ELSEIF(wbegin+newfst-1.GT.dou) THEN
  729
  730                        newftt = dou
  731                     ELSE
  732                        newftt = wbegin + newfst - 1
  733                     ENDIF
  734                  ENDIF
  735
  736                  newftt = newftt - zoffset
  737 
  738                  IF( newsiz.GT.1) THEN
  739
  740
  741
  742
  743                     IF((wbegin+newlst-1.LT.dol).OR.
  744     $                  (wbegin+newfst-1.GT.dou)) THEN
  745
  746
  747                        GOTO 139
  748                     ENDIF
  749 
  750
  751
  752                     IF( newfst.EQ.1 ) THEN
  754     $                       w(wbegin)-werr(wbegin) - vl )
  755                     ELSE
  756                        lgap = wgap( wbegin+newfst-2 )
  757                     ENDIF
  758                     rgap = wgap( wbegin+newlst-1 )
  759
  760
  761
  762
  763
  764                     mgap = zero
  765                     IF(newsiz.GE.50) THEN
  766                        kk = newfst
  767                        DO 545 k =newfst+newsiz/3,newlst-newsiz/3
  768                           IF(mgap.LT.wgap( wbegin+k-1 )) THEN
  769                              kk = k
  770                              mgap = wgap( wbegin+k-1 )
  771                           ENDIF
  772 545                    CONTINUE
  773                     ENDIF
  774                     
  775
  776
  777
  778                     needil = 
min(needil,wbegin+newfst-1)
 
  779                     neediu = 
max(neediu,wbegin+newlst-1)
 
  780 
  781
  782
  783
  785                     trymid = (mgap.GT.gap)
  786 
  787                     splace(1) = newfst
  788                     splace(2) = newlst
  789                     IF(trymid) THEN
  790                        splace(3) = kk
  791                        splace(4) = kk+1
  792                     ELSE
  793                        splace(3) = newfst
  794                        splace(4) = newlst
  795                     ENDIF
  796
  797
  798
  799
  800
  801
  802 
  803                     DO 55 k =1,4
  804                        p = indexw( wbegin-1+splace(k) )
  805                        offset = indexw( wbegin ) - 1
  807     $                       work( indlld+ibegin-1 ),p,p,
  808     $                       rqtol, rqtol, offset, 
  809     $                       work(wbegin),wgap(wbegin),
  810     $                       werr(wbegin),work( indwrk ), 
  811     $                       iwork( iindwk ), 
  812     $                       pivmin, lgpvmn, lgspdm, in, iinfo )
  813 55                  CONTINUE
  814
  815
  816
  817
  818
  819                     CALL dlarrf2( in, d( ibegin ), l( ibegin ),
 
  820     $                         work(indld+ibegin-1), 
  821     $                         splace(1), splace(2), 
  822     $                         splace(3), splace(4), work(wbegin),
  823     $                         wgap(wbegin), werr(wbegin), trymid,
  824     $                         spdiam, lgap, rgap, pivmin, tau, 
  825     $                         z( ibegin, newftt ),
  826     $                         z( ibegin, newftt+1 ),
  827     $                         work( indwrk ), iinfo )
  828                     IF( iinfo.EQ.0 ) THEN
  829
  830
  831                        ssigma = sigma + tau
  832                        z( iend, newftt+1 ) = ssigma
  833
  834
  835                        DO 116 k = newfst, newlst
  836                           fudge = 
  837     $                          three*eps*abs(work(wbegin+k-1))
  838                           work( wbegin + k - 1 ) = 
  839     $                          work( wbegin + k - 1) - tau
  840                           fudge = fudge + 
  841     $                          four*eps*abs(work(wbegin+k-1))
  842
  843                           werr( wbegin + k - 1 ) =
  844     $                          werr( wbegin + k - 1 ) + fudge
  845 116                    CONTINUE
  846 
  847                        nclus = nclus + 1
  848                        k = newcls + 2*nclus
  849                        iwork( k-1 ) = newfst
  850                        iwork( k ) = newlst
  851
  852                        IF(.NOT.delref) THEN
  853                           onlylc = .true.
  854
  855                           IF(onlylc) THEN
  856                              mywfst = 
max(wbegin-1+newfst,dol-1)
 
  857                              mywlst = 
min(wbegin-1+newlst,dou+1)
 
  858                           ELSE
  859                              mywfst = wbegin-1+newfst
  860                              mywlst = wbegin-1+newlst 
  861                           ENDIF
  862 
  863
  864                           DO 5000 k = ibegin, iend-1
  865                              work( indwrk-1+k ) = 
  866     $                        z(k,newftt)*
  867     $                       (z(k,newftt+1)**2)
  868 5000                      CONTINUE
  869
  870
  871                           p = indexw( mywfst )
  872                           q = indexw( mywlst )
  873
  874                           offset = indexw( wbegin ) - 1
  875
  876
  878     $                         z(ibegin, newftt ),
  879     $                         work(indwrk+ibegin-1),
  880     $                         p, q, rtol1, rtol2, offset, 
  881     $                         work(wbegin),wgap(wbegin),werr(wbegin),
  882     $                         work( indwrk+n ), iwork( iindwk ),
  883     $                         pivmin, lgpvmn, lgspdm, in, iinfo )
  884                           IF( iinfo.NE.0 ) THEN
  885                              info = -1
  886                              RETURN
  887                           ENDIF       
  888
  889
  890                           DO 5003 k=newfst,newlst
  891                              w(wbegin+k-1) = work(wbegin+k-1)+ssigma
  892 5003                      CONTINUE
  893                        ENDIF
  894
  895                     ELSE    
  896                        info = -2
  897                        RETURN
  898                     ENDIF      
  899                  ELSE
  900
  901
  902
  903                     iter = 0
  904
  905                     tol = four * log_in * eps
  906
  907                     k = newfst
  908                     windex = wbegin + k - 1
  909                     zindex = windex - zoffset
  910                     windmn = 
max(windex - 1,1)
 
  911                     windpl = 
min(windex + 1,m)
 
  912                     lambda = work( windex )
  913
  914                     IF((windex.LT.dol).OR.
  915     $                  (windex.GT.dou)) THEN
  916                        eskip = .true.
  917                        GOTO 125
  918                     ELSE
  919                        eskip = .false.
  920                     ENDIF
  921                     left = work( windex ) - werr( windex )
  922                     right = work( windex ) + werr( windex )
  923                     indeig = indexw( windex )
  924                     IF( k .EQ. 1) THEN
  925                        lgap = eps*
max(abs(left),abs(right))
 
  926                     ELSE
  927                        lgap = wgap(windmn)
  928                     ENDIF
  929                     IF( k .EQ. im) THEN
  930                        rgap = eps*
max(abs(left),abs(right))
 
  931                     ELSE
  932                        rgap = wgap(windex)
  933                     ENDIF
  934                     gap = 
min( lgap, rgap )
 
  935                     IF(( k .EQ. 1).OR.(k .EQ. im)) THEN
  936                        gaptol = zero
  937                     ELSE
  938                        gaptol = gap * eps
  939                     ENDIF
  940                     isupmn = in
  941                     isupmx = 1
  942
  943
  944
  945
  946
  947                     savegp = wgap(windex)
  948                     wgap(windex) = gap
  949
  950
  951
  952
  953
  954
  955                     usedbs = .false.
  956                     usedrq = .false.
  957
  958                     needbs =  .NOT.tryrqc 
  959
  960                     itwist = 0
  961 120                 CONTINUE
  962
  963                     IF(needbs) THEN
  964
  965                        usedbs = .true.
  966
  967                        itmp1 = itwist
  968                        offset = indexw( wbegin ) - 1
  970     $                       work(indlld+ibegin-1),indeig,indeig,
  971     $                       zero, two*eps, offset, 
  972     $                       work(wbegin),wgap(wbegin),
  973     $                       werr(wbegin),work( indwrk ), 
  974     $                       iwork( iindwk ), 
  975     $                       pivmin, lgpvmn, lgspdm, itmp1, iinfo )
  976                        IF( iinfo.NE.0 ) THEN
  977                           info = -3
  978                           RETURN
  979                        ENDIF       
  980                        lambda = work( windex )
  981
  982
  983                        itwist = 0
  984                     ENDIF
  985
  986                     CALL dlar1va( in, 1, in, lambda, d(ibegin),
 
  987     $                    l( ibegin ), work(indld+ibegin-1), 
  988     $                    work(indlld+ibegin-1),
  989     $                    pivmin, gaptol, z( ibegin, zindex),
  990     $                    .NOT.usedbs, negcnt, ztz, mingma,
  991     $                    itwist, isuppz( 2*windex-1 ),
  992     $                    nrminv, resid, rqcorr, work( indwrk ) )
  993                     IF(iter .EQ. 0) THEN
  994                        bstres = resid
  995                        bstw = lambda
  996                     ELSEIF(resid.LT.bstres) THEN
  997                        bstres = resid
  998                        bstw = lambda
  999                     ENDIF
 1000                     isupmn = 
min(isupmn,isuppz( 2*windex-1 ))
 
 1001                     isupmx = 
max(isupmx,isuppz( 2*windex ))
 
 1002                     iter = iter + 1
 1003
 1004
 1005
 1006
 1007                     IF( resid.GT.tol*gap .AND. abs( rqcorr ).GT.
 1008     $                    rqtol*abs( lambda ) .AND. .NOT. usedbs) 
 1009     $                    THEN
 1010
 1011
 1012
 1013                        IF(indeig.LE.negcnt) THEN
 1014
 1015                           sgndef = -one
 1016                        ELSE
 1017
 1018                           sgndef = one
 1019                        ENDIF
 1020
 1021
 1022                        IF( ( rqcorr*sgndef.GE.zero )
 1023     $                       .AND.( lambda + rqcorr.LE. right)
 1024     $                       .AND.( lambda + rqcorr.GE. left)
 1025     $                       ) THEN
 1026                           usedrq = .true.
 1027
 1028                           IF(sgndef.EQ.one) THEN
 1029
 1030
 1031                              left = lambda
 1032                           ELSE   
 1033
 1034
 1035                              right = lambda
 1036                           ENDIF  
 1037                           work( windex ) = 
 1038     $                       half * (right + left)
 1039
 1040
 1041                           lambda = lambda + rqcorr
 1042
 1043                           werr( windex ) =                
 1044     $                             half * (right-left)
 1045                        ELSE
 1046                           needbs = .true.
 1047                        ENDIF
 1048                        IF(right-left.LT.rqtol*abs(lambda)) THEN
 1049
 1050
 1051                           usedbs = .true.
 1052                           GOTO 120
 1053                        ELSEIF( iter.LT.maxitr ) THEN
 1054                           GOTO 120
 1055                        ELSEIF( iter.EQ.maxitr ) THEN
 1056                           needbs = .true.
 1057                           GOTO 120
 1058                        ELSE
 1059                           info = 5
 1060                           RETURN
 1061                        END IF
 1062                     ELSE 
 1063                        stp2ii = .false.
 1064                        IF(usedrq .AND. usedbs .AND. 
 1065     $                     bstres.LE.resid) THEN
 1066                           lambda = bstw
 1067                           stp2ii = .true.
 1068                        ENDIF
 1069                        IF (stp2ii) THEN
 1070                           CALL dlar1va( in, 1, in, lambda,
 
 1071     $                          d( ibegin ), l( ibegin ), 
 1072     $                          work(indld+ibegin-1), 
 1073     $                          work(indlld+ibegin-1),
 1074     $                          pivmin, gaptol, 
 1075     $                          z( ibegin, zindex ),
 1076     $                          .NOT.usedbs, negcnt, ztz, mingma,
 1077     $                          itwist, 
 1078     $                          isuppz( 2*windex-1 ),
 1079     $                          nrminv, resid, rqcorr, work( indwrk ) )
 1080                        ENDIF
 1081                        work( windex ) = lambda
 1082                     END IF
 1083
 1084
 1085
 1086                     isuppz( 2*windex-1 ) = isuppz( 2*windex-1 )+oldien
 1087                     isuppz( 2*windex ) = isuppz( 2*windex )+oldien
 1088                     zfrom = isuppz( 2*windex-1 )
 1089                     zto = isuppz( 2*windex )
 1090                     isupmn = isupmn + oldien
 1091                     isupmx = isupmx + oldien
 1092
 1093                     IF(isupmn.LT.zfrom) THEN
 1094                        DO 122 ii = isupmn,zfrom-1
 1095                           z( ii, zindex ) = zero
 1096 122                    CONTINUE
 1097                     ENDIF   
 1098                     IF(isupmx.GT.zto) THEN
 1099                        DO 123 ii = zto+1,isupmx
 1100                           z( ii, zindex ) = zero
 1101 123                    CONTINUE
 1102                     ENDIF   
 1103                     CALL dscal( zto-zfrom+1, nrminv,
 1104     $                       z( zfrom, zindex ), 1 )
 1105 125                 CONTINUE
 1106
 1107                     w( windex ) = lambda+sigma
 1108
 1109
 1110
 1111
 1112
 1113
 1114                     IF(.NOT.eskip) THEN
 1115                        IF( k.GT.1) THEN
 1116                           wgap( windmn ) = 
max( wgap(windmn),
 
 1117     $                          w(windex)-werr(windex) 
 1118     $                          - w(windmn)-werr(windmn) )
 1119                        ENDIF
 1120                        IF( windex.LT.wend ) THEN
 1121                           wgap( windex ) = 
max( savegp, 
 
 1122     $                          w( windpl )-werr( windpl ) 
 1123     $                          - w( windex )-werr( windex) )
 1124                        ENDIF
 1125                     ENDIF
 1126                  ENDIF
 1127
 1128
 1129 139              CONTINUE
 1130
 1131                  newfst = j + 1
 1132 140           CONTINUE
 1133 150        CONTINUE
 1134
 1135            iwork( iincls + jblk ) = nclus
 1136
 1137         END IF
 1138         ibegin = iend + 1
 1139         wbegin = wend + 1
 1140 170  CONTINUE
 1141
 1142
 1143
 1144
 1145      finish = .true.
 1146      DO 180 jblk = 1, iblock( m )      
 1147         finish = finish .AND. (iwork(iincls + jblk).EQ.0)
 1148 180  CONTINUE
 1149 
 1150      IF(.NOT.finish) THEN
 1151         ndepth = ndepth + 1
 1152         IF((needil.GE.dol).AND.(neediu.LE.dou)) THEN
 1153
 1154
 1155
 1156
 1157            GOTO 40
 1158         ENDIF
 1159      ENDIF
 1160
 1161 
 1162      RETURN
 1163
 1164
 1165
subroutine dlar1va(n, b1, bn, lambda, d, l, ld, lld, pivmin, gaptol, z, wantnc, negcnt, ztz, mingma, r, isuppz, nrminv, resid, rqcorr, work)
 
subroutine dlarrb2(n, d, lld, ifirst, ilast, rtol1, rtol2, offset, w, wgap, werr, work, iwork, pivmin, lgpvmn, lgspdm, twist, info)
 
subroutine dlarrf2(n, d, l, ld, clstrt, clend, clmid1, clmid2, w, wgap, werr, trymid, spdiam, clgapl, clgapr, pivmin, sigma, dplus, lplus, work, info)