File:  [local] / rpl / lapack / lapack / dlaed4.f
Revision 1.19: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:38:53 2023 UTC (8 months, 3 weeks ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_35, rpl-4_1_34, HEAD
Première mise à jour de lapack et blas.

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

CVSweb interface <joel.bertrand@systella.fr>