File:  [local] / rpl / lapack / lapack / dlasd4.f
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Wed Apr 21 13:45:19 2010 UTC (14 years ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_0_17, rpl-4_0_16, rpl-4_0_15, HEAD
En route pour la 4.0.15 !

    1:       SUBROUTINE DLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO )
    2: *
    3: *  -- LAPACK auxiliary routine (version 3.2) --
    4: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
    5: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
    6: *     November 2006
    7: *
    8: *     .. Scalar Arguments ..
    9:       INTEGER            I, INFO, N
   10:       DOUBLE PRECISION   RHO, SIGMA
   11: *     ..
   12: *     .. Array Arguments ..
   13:       DOUBLE PRECISION   D( * ), DELTA( * ), WORK( * ), Z( * )
   14: *     ..
   15: *
   16: *  Purpose
   17: *  =======
   18: *
   19: *  This subroutine computes the square root of the I-th updated
   20: *  eigenvalue of a positive symmetric rank-one modification to
   21: *  a positive diagonal matrix whose entries are given as the squares
   22: *  of the corresponding entries in the array d, and that
   23: *
   24: *         0 <= D(i) < D(j)  for  i < j
   25: *
   26: *  and that RHO > 0. This is arranged by the calling routine, and is
   27: *  no loss in generality.  The rank-one modified system is thus
   28: *
   29: *         diag( D ) * diag( D ) +  RHO *  Z * Z_transpose.
   30: *
   31: *  where we assume the Euclidean norm of Z is 1.
   32: *
   33: *  The method consists of approximating the rational functions in the
   34: *  secular equation by simpler interpolating rational functions.
   35: *
   36: *  Arguments
   37: *  =========
   38: *
   39: *  N      (input) INTEGER
   40: *         The length of all arrays.
   41: *
   42: *  I      (input) INTEGER
   43: *         The index of the eigenvalue to be computed.  1 <= I <= N.
   44: *
   45: *  D      (input) DOUBLE PRECISION array, dimension ( N )
   46: *         The original eigenvalues.  It is assumed that they are in
   47: *         order, 0 <= D(I) < D(J)  for I < J.
   48: *
   49: *  Z      (input) DOUBLE PRECISION array, dimension ( N )
   50: *         The components of the updating vector.
   51: *
   52: *  DELTA  (output) DOUBLE PRECISION array, dimension ( N )
   53: *         If N .ne. 1, DELTA contains (D(j) - sigma_I) in its  j-th
   54: *         component.  If N = 1, then DELTA(1) = 1.  The vector DELTA
   55: *         contains the information necessary to construct the
   56: *         (singular) eigenvectors.
   57: *
   58: *  RHO    (input) DOUBLE PRECISION
   59: *         The scalar in the symmetric updating formula.
   60: *
   61: *  SIGMA  (output) DOUBLE PRECISION
   62: *         The computed sigma_I, the I-th updated eigenvalue.
   63: *
   64: *  WORK   (workspace) DOUBLE PRECISION array, dimension ( N )
   65: *         If N .ne. 1, WORK contains (D(j) + sigma_I) in its  j-th
   66: *         component.  If N = 1, then WORK( 1 ) = 1.
   67: *
   68: *  INFO   (output) INTEGER
   69: *         = 0:  successful exit
   70: *         > 0:  if INFO = 1, the updating process failed.
   71: *
   72: *  Internal Parameters
   73: *  ===================
   74: *
   75: *  Logical variable ORGATI (origin-at-i?) is used for distinguishing
   76: *  whether D(i) or D(i+1) is treated as the origin.
   77: *
   78: *            ORGATI = .true.    origin at i
   79: *            ORGATI = .false.   origin at i+1
   80: *
   81: *  Logical variable SWTCH3 (switch-for-3-poles?) is for noting
   82: *  if we are working with THREE poles!
   83: *
   84: *  MAXIT is the maximum number of iterations allowed for each
   85: *  eigenvalue.
   86: *
   87: *  Further Details
   88: *  ===============
   89: *
   90: *  Based on contributions by
   91: *     Ren-Cang Li, Computer Science Division, University of California
   92: *     at Berkeley, USA
   93: *
   94: *  =====================================================================
   95: *
   96: *     .. Parameters ..
   97:       INTEGER            MAXIT
   98:       PARAMETER          ( MAXIT = 20 )
   99:       DOUBLE PRECISION   ZERO, ONE, TWO, THREE, FOUR, EIGHT, TEN
  100:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
  101:      $                   THREE = 3.0D+0, FOUR = 4.0D+0, EIGHT = 8.0D+0,
  102:      $                   TEN = 10.0D+0 )
  103: *     ..
  104: *     .. Local Scalars ..
  105:       LOGICAL            ORGATI, SWTCH, SWTCH3
  106:       INTEGER            II, IIM1, IIP1, IP1, ITER, J, NITER
  107:       DOUBLE PRECISION   A, B, C, DELSQ, DELSQ2, DPHI, DPSI, DTIIM,
  108:      $                   DTIIP, DTIPSQ, DTISQ, DTNSQ, DTNSQ1, DW, EPS,
  109:      $                   ERRETM, ETA, PHI, PREW, PSI, RHOINV, SG2LB,
  110:      $                   SG2UB, TAU, TEMP, TEMP1, TEMP2, W
  111: *     ..
  112: *     .. Local Arrays ..
  113:       DOUBLE PRECISION   DD( 3 ), ZZ( 3 )
  114: *     ..
  115: *     .. External Subroutines ..
  116:       EXTERNAL           DLAED6, DLASD5
  117: *     ..
  118: *     .. External Functions ..
  119:       DOUBLE PRECISION   DLAMCH
  120:       EXTERNAL           DLAMCH
  121: *     ..
  122: *     .. Intrinsic Functions ..
  123:       INTRINSIC          ABS, MAX, MIN, SQRT
  124: *     ..
  125: *     .. Executable Statements ..
  126: *
  127: *     Since this routine is called in an inner loop, we do no argument
  128: *     checking.
  129: *
  130: *     Quick return for N=1 and 2.
  131: *
  132:       INFO = 0
  133:       IF( N.EQ.1 ) THEN
  134: *
  135: *        Presumably, I=1 upon entry
  136: *
  137:          SIGMA = SQRT( D( 1 )*D( 1 )+RHO*Z( 1 )*Z( 1 ) )
  138:          DELTA( 1 ) = ONE
  139:          WORK( 1 ) = ONE
  140:          RETURN
  141:       END IF
  142:       IF( N.EQ.2 ) THEN
  143:          CALL DLASD5( I, D, Z, DELTA, RHO, SIGMA, WORK )
  144:          RETURN
  145:       END IF
  146: *
  147: *     Compute machine epsilon
  148: *
  149:       EPS = DLAMCH( 'Epsilon' )
  150:       RHOINV = ONE / RHO
  151: *
  152: *     The case I = N
  153: *
  154:       IF( I.EQ.N ) THEN
  155: *
  156: *        Initialize some basic variables
  157: *
  158:          II = N - 1
  159:          NITER = 1
  160: *
  161: *        Calculate initial guess
  162: *
  163:          TEMP = RHO / TWO
  164: *
  165: *        If ||Z||_2 is not one, then TEMP should be set to
  166: *        RHO * ||Z||_2^2 / TWO
  167: *
  168:          TEMP1 = TEMP / ( D( N )+SQRT( D( N )*D( N )+TEMP ) )
  169:          DO 10 J = 1, N
  170:             WORK( J ) = D( J ) + D( N ) + TEMP1
  171:             DELTA( J ) = ( D( J )-D( N ) ) - TEMP1
  172:    10    CONTINUE
  173: *
  174:          PSI = ZERO
  175:          DO 20 J = 1, N - 2
  176:             PSI = PSI + Z( J )*Z( J ) / ( DELTA( J )*WORK( J ) )
  177:    20    CONTINUE
  178: *
  179:          C = RHOINV + PSI
  180:          W = C + Z( II )*Z( II ) / ( DELTA( II )*WORK( II ) ) +
  181:      $       Z( N )*Z( N ) / ( DELTA( N )*WORK( N ) )
  182: *
  183:          IF( W.LE.ZERO ) THEN
  184:             TEMP1 = SQRT( D( N )*D( N )+RHO )
  185:             TEMP = Z( N-1 )*Z( N-1 ) / ( ( D( N-1 )+TEMP1 )*
  186:      $             ( D( N )-D( N-1 )+RHO / ( D( N )+TEMP1 ) ) ) +
  187:      $             Z( N )*Z( N ) / RHO
  188: *
  189: *           The following TAU is to approximate
  190: *           SIGMA_n^2 - D( N )*D( N )
  191: *
  192:             IF( C.LE.TEMP ) THEN
  193:                TAU = RHO
  194:             ELSE
  195:                DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
  196:                A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
  197:                B = Z( N )*Z( N )*DELSQ
  198:                IF( A.LT.ZERO ) THEN
  199:                   TAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
  200:                ELSE
  201:                   TAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
  202:                END IF
  203:             END IF
  204: *
  205: *           It can be proved that
  206: *               D(N)^2+RHO/2 <= SIGMA_n^2 < D(N)^2+TAU <= D(N)^2+RHO
  207: *
  208:          ELSE
  209:             DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
  210:             A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
  211:             B = Z( N )*Z( N )*DELSQ
  212: *
  213: *           The following TAU is to approximate
  214: *           SIGMA_n^2 - D( N )*D( N )
  215: *
  216:             IF( A.LT.ZERO ) THEN
  217:                TAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
  218:             ELSE
  219:                TAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
  220:             END IF
  221: *
  222: *           It can be proved that
  223: *           D(N)^2 < D(N)^2+TAU < SIGMA(N)^2 < D(N)^2+RHO/2
  224: *
  225:          END IF
  226: *
  227: *        The following ETA is to approximate SIGMA_n - D( N )
  228: *
  229:          ETA = TAU / ( D( N )+SQRT( D( N )*D( N )+TAU ) )
  230: *
  231:          SIGMA = D( N ) + ETA
  232:          DO 30 J = 1, N
  233:             DELTA( J ) = ( D( J )-D( I ) ) - ETA
  234:             WORK( J ) = D( J ) + D( I ) + ETA
  235:    30    CONTINUE
  236: *
  237: *        Evaluate PSI and the derivative DPSI
  238: *
  239:          DPSI = ZERO
  240:          PSI = ZERO
  241:          ERRETM = ZERO
  242:          DO 40 J = 1, II
  243:             TEMP = Z( J ) / ( DELTA( J )*WORK( J ) )
  244:             PSI = PSI + Z( J )*TEMP
  245:             DPSI = DPSI + TEMP*TEMP
  246:             ERRETM = ERRETM + PSI
  247:    40    CONTINUE
  248:          ERRETM = ABS( ERRETM )
  249: *
  250: *        Evaluate PHI and the derivative DPHI
  251: *
  252:          TEMP = Z( N ) / ( DELTA( N )*WORK( N ) )
  253:          PHI = Z( N )*TEMP
  254:          DPHI = TEMP*TEMP
  255:          ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
  256:      $            ABS( TAU )*( DPSI+DPHI )
  257: *
  258:          W = RHOINV + PHI + PSI
  259: *
  260: *        Test for convergence
  261: *
  262:          IF( ABS( W ).LE.EPS*ERRETM ) THEN
  263:             GO TO 240
  264:          END IF
  265: *
  266: *        Calculate the new step
  267: *
  268:          NITER = NITER + 1
  269:          DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
  270:          DTNSQ = WORK( N )*DELTA( N )
  271:          C = W - DTNSQ1*DPSI - DTNSQ*DPHI
  272:          A = ( DTNSQ+DTNSQ1 )*W - DTNSQ*DTNSQ1*( DPSI+DPHI )
  273:          B = DTNSQ*DTNSQ1*W
  274:          IF( C.LT.ZERO )
  275:      $      C = ABS( C )
  276:          IF( C.EQ.ZERO ) THEN
  277:             ETA = RHO - SIGMA*SIGMA
  278:          ELSE IF( A.GE.ZERO ) THEN
  279:             ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
  280:          ELSE
  281:             ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
  282:          END IF
  283: *
  284: *        Note, eta should be positive if w is negative, and
  285: *        eta should be negative otherwise. However,
  286: *        if for some reason caused by roundoff, eta*w > 0,
  287: *        we simply use one Newton step instead. This way
  288: *        will guarantee eta*w < 0.
  289: *
  290:          IF( W*ETA.GT.ZERO )
  291:      $      ETA = -W / ( DPSI+DPHI )
  292:          TEMP = ETA - DTNSQ
  293:          IF( TEMP.GT.RHO )
  294:      $      ETA = RHO + DTNSQ
  295: *
  296:          TAU = TAU + ETA
  297:          ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
  298:          DO 50 J = 1, N
  299:             DELTA( J ) = DELTA( J ) - ETA
  300:             WORK( J ) = WORK( J ) + ETA
  301:    50    CONTINUE
  302: *
  303:          SIGMA = SIGMA + ETA
  304: *
  305: *        Evaluate PSI and the derivative DPSI
  306: *
  307:          DPSI = ZERO
  308:          PSI = ZERO
  309:          ERRETM = ZERO
  310:          DO 60 J = 1, II
  311:             TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  312:             PSI = PSI + Z( J )*TEMP
  313:             DPSI = DPSI + TEMP*TEMP
  314:             ERRETM = ERRETM + PSI
  315:    60    CONTINUE
  316:          ERRETM = ABS( ERRETM )
  317: *
  318: *        Evaluate PHI and the derivative DPHI
  319: *
  320:          TEMP = Z( N ) / ( WORK( N )*DELTA( N ) )
  321:          PHI = Z( N )*TEMP
  322:          DPHI = TEMP*TEMP
  323:          ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
  324:      $            ABS( TAU )*( DPSI+DPHI )
  325: *
  326:          W = RHOINV + PHI + PSI
  327: *
  328: *        Main loop to update the values of the array   DELTA
  329: *
  330:          ITER = NITER + 1
  331: *
  332:          DO 90 NITER = ITER, MAXIT
  333: *
  334: *           Test for convergence
  335: *
  336:             IF( ABS( W ).LE.EPS*ERRETM ) THEN
  337:                GO TO 240
  338:             END IF
  339: *
  340: *           Calculate the new step
  341: *
  342:             DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
  343:             DTNSQ = WORK( N )*DELTA( N )
  344:             C = W - DTNSQ1*DPSI - DTNSQ*DPHI
  345:             A = ( DTNSQ+DTNSQ1 )*W - DTNSQ1*DTNSQ*( DPSI+DPHI )
  346:             B = DTNSQ1*DTNSQ*W
  347:             IF( A.GE.ZERO ) THEN
  348:                ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
  349:             ELSE
  350:                ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
  351:             END IF
  352: *
  353: *           Note, eta should be positive if w is negative, and
  354: *           eta should be negative otherwise. However,
  355: *           if for some reason caused by roundoff, eta*w > 0,
  356: *           we simply use one Newton step instead. This way
  357: *           will guarantee eta*w < 0.
  358: *
  359:             IF( W*ETA.GT.ZERO )
  360:      $         ETA = -W / ( DPSI+DPHI )
  361:             TEMP = ETA - DTNSQ
  362:             IF( TEMP.LE.ZERO )
  363:      $         ETA = ETA / TWO
  364: *
  365:             TAU = TAU + ETA
  366:             ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
  367:             DO 70 J = 1, N
  368:                DELTA( J ) = DELTA( J ) - ETA
  369:                WORK( J ) = WORK( J ) + ETA
  370:    70       CONTINUE
  371: *
  372:             SIGMA = SIGMA + ETA
  373: *
  374: *           Evaluate PSI and the derivative DPSI
  375: *
  376:             DPSI = ZERO
  377:             PSI = ZERO
  378:             ERRETM = ZERO
  379:             DO 80 J = 1, II
  380:                TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  381:                PSI = PSI + Z( J )*TEMP
  382:                DPSI = DPSI + TEMP*TEMP
  383:                ERRETM = ERRETM + PSI
  384:    80       CONTINUE
  385:             ERRETM = ABS( ERRETM )
  386: *
  387: *           Evaluate PHI and the derivative DPHI
  388: *
  389:             TEMP = Z( N ) / ( WORK( N )*DELTA( N ) )
  390:             PHI = Z( N )*TEMP
  391:             DPHI = TEMP*TEMP
  392:             ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +
  393:      $               ABS( TAU )*( DPSI+DPHI )
  394: *
  395:             W = RHOINV + PHI + PSI
  396:    90    CONTINUE
  397: *
  398: *        Return with INFO = 1, NITER = MAXIT and not converged
  399: *
  400:          INFO = 1
  401:          GO TO 240
  402: *
  403: *        End for the case I = N
  404: *
  405:       ELSE
  406: *
  407: *        The case for I < N
  408: *
  409:          NITER = 1
  410:          IP1 = I + 1
  411: *
  412: *        Calculate initial guess
  413: *
  414:          DELSQ = ( D( IP1 )-D( I ) )*( D( IP1 )+D( I ) )
  415:          DELSQ2 = DELSQ / TWO
  416:          TEMP = DELSQ2 / ( D( I )+SQRT( D( I )*D( I )+DELSQ2 ) )
  417:          DO 100 J = 1, N
  418:             WORK( J ) = D( J ) + D( I ) + TEMP
  419:             DELTA( J ) = ( D( J )-D( I ) ) - TEMP
  420:   100    CONTINUE
  421: *
  422:          PSI = ZERO
  423:          DO 110 J = 1, I - 1
  424:             PSI = PSI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
  425:   110    CONTINUE
  426: *
  427:          PHI = ZERO
  428:          DO 120 J = N, I + 2, -1
  429:             PHI = PHI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
  430:   120    CONTINUE
  431:          C = RHOINV + PSI + PHI
  432:          W = C + Z( I )*Z( I ) / ( WORK( I )*DELTA( I ) ) +
  433:      $       Z( IP1 )*Z( IP1 ) / ( WORK( IP1 )*DELTA( IP1 ) )
  434: *
  435:          IF( W.GT.ZERO ) THEN
  436: *
  437: *           d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2
  438: *
  439: *           We choose d(i) as origin.
  440: *
  441:             ORGATI = .TRUE.
  442:             SG2LB = ZERO
  443:             SG2UB = DELSQ2
  444:             A = C*DELSQ + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )
  445:             B = Z( I )*Z( I )*DELSQ
  446:             IF( A.GT.ZERO ) THEN
  447:                TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
  448:             ELSE
  449:                TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
  450:             END IF
  451: *
  452: *           TAU now is an estimation of SIGMA^2 - D( I )^2. The
  453: *           following, however, is the corresponding estimation of
  454: *           SIGMA - D( I ).
  455: *
  456:             ETA = TAU / ( D( I )+SQRT( D( I )*D( I )+TAU ) )
  457:          ELSE
  458: *
  459: *           (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2
  460: *
  461: *           We choose d(i+1) as origin.
  462: *
  463:             ORGATI = .FALSE.
  464:             SG2LB = -DELSQ2
  465:             SG2UB = ZERO
  466:             A = C*DELSQ - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )
  467:             B = Z( IP1 )*Z( IP1 )*DELSQ
  468:             IF( A.LT.ZERO ) THEN
  469:                TAU = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )
  470:             ELSE
  471:                TAU = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )
  472:             END IF
  473: *
  474: *           TAU now is an estimation of SIGMA^2 - D( IP1 )^2. The
  475: *           following, however, is the corresponding estimation of
  476: *           SIGMA - D( IP1 ).
  477: *
  478:             ETA = TAU / ( D( IP1 )+SQRT( ABS( D( IP1 )*D( IP1 )+
  479:      $            TAU ) ) )
  480:          END IF
  481: *
  482:          IF( ORGATI ) THEN
  483:             II = I
  484:             SIGMA = D( I ) + ETA
  485:             DO 130 J = 1, N
  486:                WORK( J ) = D( J ) + D( I ) + ETA
  487:                DELTA( J ) = ( D( J )-D( I ) ) - ETA
  488:   130       CONTINUE
  489:          ELSE
  490:             II = I + 1
  491:             SIGMA = D( IP1 ) + ETA
  492:             DO 140 J = 1, N
  493:                WORK( J ) = D( J ) + D( IP1 ) + ETA
  494:                DELTA( J ) = ( D( J )-D( IP1 ) ) - ETA
  495:   140       CONTINUE
  496:          END IF
  497:          IIM1 = II - 1
  498:          IIP1 = II + 1
  499: *
  500: *        Evaluate PSI and the derivative DPSI
  501: *
  502:          DPSI = ZERO
  503:          PSI = ZERO
  504:          ERRETM = ZERO
  505:          DO 150 J = 1, IIM1
  506:             TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  507:             PSI = PSI + Z( J )*TEMP
  508:             DPSI = DPSI + TEMP*TEMP
  509:             ERRETM = ERRETM + PSI
  510:   150    CONTINUE
  511:          ERRETM = ABS( ERRETM )
  512: *
  513: *        Evaluate PHI and the derivative DPHI
  514: *
  515:          DPHI = ZERO
  516:          PHI = ZERO
  517:          DO 160 J = N, IIP1, -1
  518:             TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  519:             PHI = PHI + Z( J )*TEMP
  520:             DPHI = DPHI + TEMP*TEMP
  521:             ERRETM = ERRETM + PHI
  522:   160    CONTINUE
  523: *
  524:          W = RHOINV + PHI + PSI
  525: *
  526: *        W is the value of the secular function with
  527: *        its ii-th element removed.
  528: *
  529:          SWTCH3 = .FALSE.
  530:          IF( ORGATI ) THEN
  531:             IF( W.LT.ZERO )
  532:      $         SWTCH3 = .TRUE.
  533:          ELSE
  534:             IF( W.GT.ZERO )
  535:      $         SWTCH3 = .TRUE.
  536:          END IF
  537:          IF( II.EQ.1 .OR. II.EQ.N )
  538:      $      SWTCH3 = .FALSE.
  539: *
  540:          TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
  541:          DW = DPSI + DPHI + TEMP*TEMP
  542:          TEMP = Z( II )*TEMP
  543:          W = W + TEMP
  544:          ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
  545:      $            THREE*ABS( TEMP ) + ABS( TAU )*DW
  546: *
  547: *        Test for convergence
  548: *
  549:          IF( ABS( W ).LE.EPS*ERRETM ) THEN
  550:             GO TO 240
  551:          END IF
  552: *
  553:          IF( W.LE.ZERO ) THEN
  554:             SG2LB = MAX( SG2LB, TAU )
  555:          ELSE
  556:             SG2UB = MIN( SG2UB, TAU )
  557:          END IF
  558: *
  559: *        Calculate the new step
  560: *
  561:          NITER = NITER + 1
  562:          IF( .NOT.SWTCH3 ) THEN
  563:             DTIPSQ = WORK( IP1 )*DELTA( IP1 )
  564:             DTISQ = WORK( I )*DELTA( I )
  565:             IF( ORGATI ) THEN
  566:                C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
  567:             ELSE
  568:                C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
  569:             END IF
  570:             A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
  571:             B = DTIPSQ*DTISQ*W
  572:             IF( C.EQ.ZERO ) THEN
  573:                IF( A.EQ.ZERO ) THEN
  574:                   IF( ORGATI ) THEN
  575:                      A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )
  576:                   ELSE
  577:                      A = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI )
  578:                   END IF
  579:                END IF
  580:                ETA = B / A
  581:             ELSE IF( A.LE.ZERO ) THEN
  582:                ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
  583:             ELSE
  584:                ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
  585:             END IF
  586:          ELSE
  587: *
  588: *           Interpolation using THREE most relevant poles
  589: *
  590:             DTIIM = WORK( IIM1 )*DELTA( IIM1 )
  591:             DTIIP = WORK( IIP1 )*DELTA( IIP1 )
  592:             TEMP = RHOINV + PSI + PHI
  593:             IF( ORGATI ) THEN
  594:                TEMP1 = Z( IIM1 ) / DTIIM
  595:                TEMP1 = TEMP1*TEMP1
  596:                C = ( TEMP - DTIIP*( DPSI+DPHI ) ) -
  597:      $             ( D( IIM1 )-D( IIP1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
  598:                ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
  599:                IF( DPSI.LT.TEMP1 ) THEN
  600:                   ZZ( 3 ) = DTIIP*DTIIP*DPHI
  601:                ELSE
  602:                   ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
  603:                END IF
  604:             ELSE
  605:                TEMP1 = Z( IIP1 ) / DTIIP
  606:                TEMP1 = TEMP1*TEMP1
  607:                C = ( TEMP - DTIIM*( DPSI+DPHI ) ) -
  608:      $             ( D( IIP1 )-D( IIM1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
  609:                IF( DPHI.LT.TEMP1 ) THEN
  610:                   ZZ( 1 ) = DTIIM*DTIIM*DPSI
  611:                ELSE
  612:                   ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
  613:                END IF
  614:                ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
  615:             END IF
  616:             ZZ( 2 ) = Z( II )*Z( II )
  617:             DD( 1 ) = DTIIM
  618:             DD( 2 ) = DELTA( II )*WORK( II )
  619:             DD( 3 ) = DTIIP
  620:             CALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
  621:             IF( INFO.NE.0 )
  622:      $         GO TO 240
  623:          END IF
  624: *
  625: *        Note, eta should be positive if w is negative, and
  626: *        eta should be negative otherwise. However,
  627: *        if for some reason caused by roundoff, eta*w > 0,
  628: *        we simply use one Newton step instead. This way
  629: *        will guarantee eta*w < 0.
  630: *
  631:          IF( W*ETA.GE.ZERO )
  632:      $      ETA = -W / DW
  633:          IF( ORGATI ) THEN
  634:             TEMP1 = WORK( I )*DELTA( I )
  635:             TEMP = ETA - TEMP1
  636:          ELSE
  637:             TEMP1 = WORK( IP1 )*DELTA( IP1 )
  638:             TEMP = ETA - TEMP1
  639:          END IF
  640:          IF( TEMP.GT.SG2UB .OR. TEMP.LT.SG2LB ) THEN
  641:             IF( W.LT.ZERO ) THEN
  642:                ETA = ( SG2UB-TAU ) / TWO
  643:             ELSE
  644:                ETA = ( SG2LB-TAU ) / TWO
  645:             END IF
  646:          END IF
  647: *
  648:          TAU = TAU + ETA
  649:          ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
  650: *
  651:          PREW = W
  652: *
  653:          SIGMA = SIGMA + ETA
  654:          DO 170 J = 1, N
  655:             WORK( J ) = WORK( J ) + ETA
  656:             DELTA( J ) = DELTA( J ) - ETA
  657:   170    CONTINUE
  658: *
  659: *        Evaluate PSI and the derivative DPSI
  660: *
  661:          DPSI = ZERO
  662:          PSI = ZERO
  663:          ERRETM = ZERO
  664:          DO 180 J = 1, IIM1
  665:             TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  666:             PSI = PSI + Z( J )*TEMP
  667:             DPSI = DPSI + TEMP*TEMP
  668:             ERRETM = ERRETM + PSI
  669:   180    CONTINUE
  670:          ERRETM = ABS( ERRETM )
  671: *
  672: *        Evaluate PHI and the derivative DPHI
  673: *
  674:          DPHI = ZERO
  675:          PHI = ZERO
  676:          DO 190 J = N, IIP1, -1
  677:             TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  678:             PHI = PHI + Z( J )*TEMP
  679:             DPHI = DPHI + TEMP*TEMP
  680:             ERRETM = ERRETM + PHI
  681:   190    CONTINUE
  682: *
  683:          TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
  684:          DW = DPSI + DPHI + TEMP*TEMP
  685:          TEMP = Z( II )*TEMP
  686:          W = RHOINV + PHI + PSI + TEMP
  687:          ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
  688:      $            THREE*ABS( TEMP ) + ABS( TAU )*DW
  689: *
  690:          IF( W.LE.ZERO ) THEN
  691:             SG2LB = MAX( SG2LB, TAU )
  692:          ELSE
  693:             SG2UB = MIN( SG2UB, TAU )
  694:          END IF
  695: *
  696:          SWTCH = .FALSE.
  697:          IF( ORGATI ) THEN
  698:             IF( -W.GT.ABS( PREW ) / TEN )
  699:      $         SWTCH = .TRUE.
  700:          ELSE
  701:             IF( W.GT.ABS( PREW ) / TEN )
  702:      $         SWTCH = .TRUE.
  703:          END IF
  704: *
  705: *        Main loop to update the values of the array   DELTA and WORK
  706: *
  707:          ITER = NITER + 1
  708: *
  709:          DO 230 NITER = ITER, MAXIT
  710: *
  711: *           Test for convergence
  712: *
  713:             IF( ABS( W ).LE.EPS*ERRETM ) THEN
  714:                GO TO 240
  715:             END IF
  716: *
  717: *           Calculate the new step
  718: *
  719:             IF( .NOT.SWTCH3 ) THEN
  720:                DTIPSQ = WORK( IP1 )*DELTA( IP1 )
  721:                DTISQ = WORK( I )*DELTA( I )
  722:                IF( .NOT.SWTCH ) THEN
  723:                   IF( ORGATI ) THEN
  724:                      C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
  725:                   ELSE
  726:                      C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
  727:                   END IF
  728:                ELSE
  729:                   TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
  730:                   IF( ORGATI ) THEN
  731:                      DPSI = DPSI + TEMP*TEMP
  732:                   ELSE
  733:                      DPHI = DPHI + TEMP*TEMP
  734:                   END IF
  735:                   C = W - DTISQ*DPSI - DTIPSQ*DPHI
  736:                END IF
  737:                A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
  738:                B = DTIPSQ*DTISQ*W
  739:                IF( C.EQ.ZERO ) THEN
  740:                   IF( A.EQ.ZERO ) THEN
  741:                      IF( .NOT.SWTCH ) THEN
  742:                         IF( ORGATI ) THEN
  743:                            A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*
  744:      $                         ( DPSI+DPHI )
  745:                         ELSE
  746:                            A = Z( IP1 )*Z( IP1 ) +
  747:      $                         DTISQ*DTISQ*( DPSI+DPHI )
  748:                         END IF
  749:                      ELSE
  750:                         A = DTISQ*DTISQ*DPSI + DTIPSQ*DTIPSQ*DPHI
  751:                      END IF
  752:                   END IF
  753:                   ETA = B / A
  754:                ELSE IF( A.LE.ZERO ) THEN
  755:                   ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
  756:                ELSE
  757:                   ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
  758:                END IF
  759:             ELSE
  760: *
  761: *              Interpolation using THREE most relevant poles
  762: *
  763:                DTIIM = WORK( IIM1 )*DELTA( IIM1 )
  764:                DTIIP = WORK( IIP1 )*DELTA( IIP1 )
  765:                TEMP = RHOINV + PSI + PHI
  766:                IF( SWTCH ) THEN
  767:                   C = TEMP - DTIIM*DPSI - DTIIP*DPHI
  768:                   ZZ( 1 ) = DTIIM*DTIIM*DPSI
  769:                   ZZ( 3 ) = DTIIP*DTIIP*DPHI
  770:                ELSE
  771:                   IF( ORGATI ) THEN
  772:                      TEMP1 = Z( IIM1 ) / DTIIM
  773:                      TEMP1 = TEMP1*TEMP1
  774:                      TEMP2 = ( D( IIM1 )-D( IIP1 ) )*
  775:      $                       ( D( IIM1 )+D( IIP1 ) )*TEMP1
  776:                      C = TEMP - DTIIP*( DPSI+DPHI ) - TEMP2
  777:                      ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
  778:                      IF( DPSI.LT.TEMP1 ) THEN
  779:                         ZZ( 3 ) = DTIIP*DTIIP*DPHI
  780:                      ELSE
  781:                         ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
  782:                      END IF
  783:                   ELSE
  784:                      TEMP1 = Z( IIP1 ) / DTIIP
  785:                      TEMP1 = TEMP1*TEMP1
  786:                      TEMP2 = ( D( IIP1 )-D( IIM1 ) )*
  787:      $                       ( D( IIM1 )+D( IIP1 ) )*TEMP1
  788:                      C = TEMP - DTIIM*( DPSI+DPHI ) - TEMP2
  789:                      IF( DPHI.LT.TEMP1 ) THEN
  790:                         ZZ( 1 ) = DTIIM*DTIIM*DPSI
  791:                      ELSE
  792:                         ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
  793:                      END IF
  794:                      ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
  795:                   END IF
  796:                END IF
  797:                DD( 1 ) = DTIIM
  798:                DD( 2 ) = DELTA( II )*WORK( II )
  799:                DD( 3 ) = DTIIP
  800:                CALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
  801:                IF( INFO.NE.0 )
  802:      $            GO TO 240
  803:             END IF
  804: *
  805: *           Note, eta should be positive if w is negative, and
  806: *           eta should be negative otherwise. However,
  807: *           if for some reason caused by roundoff, eta*w > 0,
  808: *           we simply use one Newton step instead. This way
  809: *           will guarantee eta*w < 0.
  810: *
  811:             IF( W*ETA.GE.ZERO )
  812:      $         ETA = -W / DW
  813:             IF( ORGATI ) THEN
  814:                TEMP1 = WORK( I )*DELTA( I )
  815:                TEMP = ETA - TEMP1
  816:             ELSE
  817:                TEMP1 = WORK( IP1 )*DELTA( IP1 )
  818:                TEMP = ETA - TEMP1
  819:             END IF
  820:             IF( TEMP.GT.SG2UB .OR. TEMP.LT.SG2LB ) THEN
  821:                IF( W.LT.ZERO ) THEN
  822:                   ETA = ( SG2UB-TAU ) / TWO
  823:                ELSE
  824:                   ETA = ( SG2LB-TAU ) / TWO
  825:                END IF
  826:             END IF
  827: *
  828:             TAU = TAU + ETA
  829:             ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
  830: *
  831:             SIGMA = SIGMA + ETA
  832:             DO 200 J = 1, N
  833:                WORK( J ) = WORK( J ) + ETA
  834:                DELTA( J ) = DELTA( J ) - ETA
  835:   200       CONTINUE
  836: *
  837:             PREW = W
  838: *
  839: *           Evaluate PSI and the derivative DPSI
  840: *
  841:             DPSI = ZERO
  842:             PSI = ZERO
  843:             ERRETM = ZERO
  844:             DO 210 J = 1, IIM1
  845:                TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  846:                PSI = PSI + Z( J )*TEMP
  847:                DPSI = DPSI + TEMP*TEMP
  848:                ERRETM = ERRETM + PSI
  849:   210       CONTINUE
  850:             ERRETM = ABS( ERRETM )
  851: *
  852: *           Evaluate PHI and the derivative DPHI
  853: *
  854:             DPHI = ZERO
  855:             PHI = ZERO
  856:             DO 220 J = N, IIP1, -1
  857:                TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
  858:                PHI = PHI + Z( J )*TEMP
  859:                DPHI = DPHI + TEMP*TEMP
  860:                ERRETM = ERRETM + PHI
  861:   220       CONTINUE
  862: *
  863:             TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
  864:             DW = DPSI + DPHI + TEMP*TEMP
  865:             TEMP = Z( II )*TEMP
  866:             W = RHOINV + PHI + PSI + TEMP
  867:             ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +
  868:      $               THREE*ABS( TEMP ) + ABS( TAU )*DW
  869:             IF( W*PREW.GT.ZERO .AND. ABS( W ).GT.ABS( PREW ) / TEN )
  870:      $         SWTCH = .NOT.SWTCH
  871: *
  872:             IF( W.LE.ZERO ) THEN
  873:                SG2LB = MAX( SG2LB, TAU )
  874:             ELSE
  875:                SG2UB = MIN( SG2UB, TAU )
  876:             END IF
  877: *
  878:   230    CONTINUE
  879: *
  880: *        Return with INFO = 1, NITER = MAXIT and not converged
  881: *
  882:          INFO = 1
  883: *
  884:       END IF
  885: *
  886:   240 CONTINUE
  887:       RETURN
  888: *
  889: *     End of DLASD4
  890: *
  891:       END

CVSweb interface <joel.bertrand@systella.fr>