File:  [local] / rpl / lapack / lapack / dlasd4.f
Revision 1.12: download - view: text, annotated - select for diffs - revision graph
Wed Aug 22 09:48:20 2012 UTC (11 years, 8 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_9, rpl-4_1_10, HEAD
Cohérence

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

CVSweb interface <joel.bertrand@systella.fr>