File:  [local] / rpl / lapack / lapack / dlaed4.f
Revision 1.3: download - view: text, annotated - select for diffs - revision graph
Fri Aug 6 15:28:39 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Cohérence

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

CVSweb interface <joel.bertrand@systella.fr>