Annotation of rpl/lapack/lapack/dlaed6.f, revision 1.1

1.1     ! bertrand    1:       SUBROUTINE DLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, 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: *     February 2007
        !             7: *
        !             8: *     .. Scalar Arguments ..
        !             9:       LOGICAL            ORGATI
        !            10:       INTEGER            INFO, KNITER
        !            11:       DOUBLE PRECISION   FINIT, RHO, TAU
        !            12: *     ..
        !            13: *     .. Array Arguments ..
        !            14:       DOUBLE PRECISION   D( 3 ), Z( 3 )
        !            15: *     ..
        !            16: *
        !            17: *  Purpose
        !            18: *  =======
        !            19: *
        !            20: *  DLAED6 computes the positive or negative root (closest to the origin)
        !            21: *  of
        !            22: *                   z(1)        z(2)        z(3)
        !            23: *  f(x) =   rho + --------- + ---------- + ---------
        !            24: *                  d(1)-x      d(2)-x      d(3)-x
        !            25: *
        !            26: *  It is assumed that
        !            27: *
        !            28: *        if ORGATI = .true. the root is between d(2) and d(3);
        !            29: *        otherwise it is between d(1) and d(2)
        !            30: *
        !            31: *  This routine will be called by DLAED4 when necessary. In most cases,
        !            32: *  the root sought is the smallest in magnitude, though it might not be
        !            33: *  in some extremely rare situations.
        !            34: *
        !            35: *  Arguments
        !            36: *  =========
        !            37: *
        !            38: *  KNITER       (input) INTEGER
        !            39: *               Refer to DLAED4 for its significance.
        !            40: *
        !            41: *  ORGATI       (input) LOGICAL
        !            42: *               If ORGATI is true, the needed root is between d(2) and
        !            43: *               d(3); otherwise it is between d(1) and d(2).  See
        !            44: *               DLAED4 for further details.
        !            45: *
        !            46: *  RHO          (input) DOUBLE PRECISION
        !            47: *               Refer to the equation f(x) above.
        !            48: *
        !            49: *  D            (input) DOUBLE PRECISION array, dimension (3)
        !            50: *               D satisfies d(1) < d(2) < d(3).
        !            51: *
        !            52: *  Z            (input) DOUBLE PRECISION array, dimension (3)
        !            53: *               Each of the elements in z must be positive.
        !            54: *
        !            55: *  FINIT        (input) DOUBLE PRECISION
        !            56: *               The value of f at 0. It is more accurate than the one
        !            57: *               evaluated inside this routine (if someone wants to do
        !            58: *               so).
        !            59: *
        !            60: *  TAU          (output) DOUBLE PRECISION
        !            61: *               The root of the equation f(x).
        !            62: *
        !            63: *  INFO         (output) INTEGER
        !            64: *               = 0: successful exit
        !            65: *               > 0: if INFO = 1, failure to converge
        !            66: *
        !            67: *  Further Details
        !            68: *  ===============
        !            69: *
        !            70: *  30/06/99: Based on contributions by
        !            71: *     Ren-Cang Li, Computer Science Division, University of California
        !            72: *     at Berkeley, USA
        !            73: *
        !            74: *  10/02/03: This version has a few statements commented out for thread
        !            75: *  safety (machine parameters are computed on each entry). SJH.
        !            76: *
        !            77: *  05/10/06: Modified from a new version of Ren-Cang Li, use
        !            78: *     Gragg-Thornton-Warner cubic convergent scheme for better stability.
        !            79: *
        !            80: *  =====================================================================
        !            81: *
        !            82: *     .. Parameters ..
        !            83:       INTEGER            MAXIT
        !            84:       PARAMETER          ( MAXIT = 40 )
        !            85:       DOUBLE PRECISION   ZERO, ONE, TWO, THREE, FOUR, EIGHT
        !            86:       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
        !            87:      $                   THREE = 3.0D0, FOUR = 4.0D0, EIGHT = 8.0D0 )
        !            88: *     ..
        !            89: *     .. External Functions ..
        !            90:       DOUBLE PRECISION   DLAMCH
        !            91:       EXTERNAL           DLAMCH
        !            92: *     ..
        !            93: *     .. Local Arrays ..
        !            94:       DOUBLE PRECISION   DSCALE( 3 ), ZSCALE( 3 )
        !            95: *     ..
        !            96: *     .. Local Scalars ..
        !            97:       LOGICAL            SCALE
        !            98:       INTEGER            I, ITER, NITER
        !            99:       DOUBLE PRECISION   A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,
        !           100:      $                   FC, SCLFAC, SCLINV, SMALL1, SMALL2, SMINV1,
        !           101:      $                   SMINV2, TEMP, TEMP1, TEMP2, TEMP3, TEMP4, 
        !           102:      $                   LBD, UBD
        !           103: *     ..
        !           104: *     .. Intrinsic Functions ..
        !           105:       INTRINSIC          ABS, INT, LOG, MAX, MIN, SQRT
        !           106: *     ..
        !           107: *     .. Executable Statements ..
        !           108: *
        !           109:       INFO = 0
        !           110: *
        !           111:       IF( ORGATI ) THEN
        !           112:          LBD = D(2)
        !           113:          UBD = D(3)
        !           114:       ELSE
        !           115:          LBD = D(1)
        !           116:          UBD = D(2)
        !           117:       END IF
        !           118:       IF( FINIT .LT. ZERO )THEN
        !           119:          LBD = ZERO
        !           120:       ELSE
        !           121:          UBD = ZERO 
        !           122:       END IF
        !           123: *
        !           124:       NITER = 1
        !           125:       TAU = ZERO
        !           126:       IF( KNITER.EQ.2 ) THEN
        !           127:          IF( ORGATI ) THEN
        !           128:             TEMP = ( D( 3 )-D( 2 ) ) / TWO
        !           129:             C = RHO + Z( 1 ) / ( ( D( 1 )-D( 2 ) )-TEMP )
        !           130:             A = C*( D( 2 )+D( 3 ) ) + Z( 2 ) + Z( 3 )
        !           131:             B = C*D( 2 )*D( 3 ) + Z( 2 )*D( 3 ) + Z( 3 )*D( 2 )
        !           132:          ELSE
        !           133:             TEMP = ( D( 1 )-D( 2 ) ) / TWO
        !           134:             C = RHO + Z( 3 ) / ( ( D( 3 )-D( 2 ) )-TEMP )
        !           135:             A = C*( D( 1 )+D( 2 ) ) + Z( 1 ) + Z( 2 )
        !           136:             B = C*D( 1 )*D( 2 ) + Z( 1 )*D( 2 ) + Z( 2 )*D( 1 )
        !           137:          END IF
        !           138:          TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
        !           139:          A = A / TEMP
        !           140:          B = B / TEMP
        !           141:          C = C / TEMP
        !           142:          IF( C.EQ.ZERO ) THEN
        !           143:             TAU = B / A
        !           144:          ELSE IF( A.LE.ZERO ) THEN
        !           145:             TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
        !           146:          ELSE
        !           147:             TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
        !           148:          END IF
        !           149:          IF( TAU .LT. LBD .OR. TAU .GT. UBD )
        !           150:      $      TAU = ( LBD+UBD )/TWO
        !           151:          IF( D(1).EQ.TAU .OR. D(2).EQ.TAU .OR. D(3).EQ.TAU ) THEN
        !           152:             TAU = ZERO
        !           153:          ELSE
        !           154:             TEMP = FINIT + TAU*Z(1)/( D(1)*( D( 1 )-TAU ) ) +
        !           155:      $                     TAU*Z(2)/( D(2)*( D( 2 )-TAU ) ) +
        !           156:      $                     TAU*Z(3)/( D(3)*( D( 3 )-TAU ) )
        !           157:             IF( TEMP .LE. ZERO )THEN
        !           158:                LBD = TAU
        !           159:             ELSE
        !           160:                UBD = TAU
        !           161:             END IF
        !           162:             IF( ABS( FINIT ).LE.ABS( TEMP ) )
        !           163:      $         TAU = ZERO
        !           164:          END IF
        !           165:       END IF
        !           166: *
        !           167: *     get machine parameters for possible scaling to avoid overflow
        !           168: *
        !           169: *     modified by Sven: parameters SMALL1, SMINV1, SMALL2,
        !           170: *     SMINV2, EPS are not SAVEd anymore between one call to the
        !           171: *     others but recomputed at each call
        !           172: *
        !           173:       EPS = DLAMCH( 'Epsilon' )
        !           174:       BASE = DLAMCH( 'Base' )
        !           175:       SMALL1 = BASE**( INT( LOG( DLAMCH( 'SafMin' ) ) / LOG( BASE ) /
        !           176:      $         THREE ) )
        !           177:       SMINV1 = ONE / SMALL1
        !           178:       SMALL2 = SMALL1*SMALL1
        !           179:       SMINV2 = SMINV1*SMINV1
        !           180: *
        !           181: *     Determine if scaling of inputs necessary to avoid overflow
        !           182: *     when computing 1/TEMP**3
        !           183: *
        !           184:       IF( ORGATI ) THEN
        !           185:          TEMP = MIN( ABS( D( 2 )-TAU ), ABS( D( 3 )-TAU ) )
        !           186:       ELSE
        !           187:          TEMP = MIN( ABS( D( 1 )-TAU ), ABS( D( 2 )-TAU ) )
        !           188:       END IF
        !           189:       SCALE = .FALSE.
        !           190:       IF( TEMP.LE.SMALL1 ) THEN
        !           191:          SCALE = .TRUE.
        !           192:          IF( TEMP.LE.SMALL2 ) THEN
        !           193: *
        !           194: *        Scale up by power of radix nearest 1/SAFMIN**(2/3)
        !           195: *
        !           196:             SCLFAC = SMINV2
        !           197:             SCLINV = SMALL2
        !           198:          ELSE
        !           199: *
        !           200: *        Scale up by power of radix nearest 1/SAFMIN**(1/3)
        !           201: *
        !           202:             SCLFAC = SMINV1
        !           203:             SCLINV = SMALL1
        !           204:          END IF
        !           205: *
        !           206: *        Scaling up safe because D, Z, TAU scaled elsewhere to be O(1)
        !           207: *
        !           208:          DO 10 I = 1, 3
        !           209:             DSCALE( I ) = D( I )*SCLFAC
        !           210:             ZSCALE( I ) = Z( I )*SCLFAC
        !           211:    10    CONTINUE
        !           212:          TAU = TAU*SCLFAC
        !           213:          LBD = LBD*SCLFAC
        !           214:          UBD = UBD*SCLFAC
        !           215:       ELSE
        !           216: *
        !           217: *        Copy D and Z to DSCALE and ZSCALE
        !           218: *
        !           219:          DO 20 I = 1, 3
        !           220:             DSCALE( I ) = D( I )
        !           221:             ZSCALE( I ) = Z( I )
        !           222:    20    CONTINUE
        !           223:       END IF
        !           224: *
        !           225:       FC = ZERO
        !           226:       DF = ZERO
        !           227:       DDF = ZERO
        !           228:       DO 30 I = 1, 3
        !           229:          TEMP = ONE / ( DSCALE( I )-TAU )
        !           230:          TEMP1 = ZSCALE( I )*TEMP
        !           231:          TEMP2 = TEMP1*TEMP
        !           232:          TEMP3 = TEMP2*TEMP
        !           233:          FC = FC + TEMP1 / DSCALE( I )
        !           234:          DF = DF + TEMP2
        !           235:          DDF = DDF + TEMP3
        !           236:    30 CONTINUE
        !           237:       F = FINIT + TAU*FC
        !           238: *
        !           239:       IF( ABS( F ).LE.ZERO )
        !           240:      $   GO TO 60
        !           241:       IF( F .LE. ZERO )THEN
        !           242:          LBD = TAU
        !           243:       ELSE
        !           244:          UBD = TAU
        !           245:       END IF
        !           246: *
        !           247: *        Iteration begins -- Use Gragg-Thornton-Warner cubic convergent
        !           248: *                            scheme
        !           249: *
        !           250: *     It is not hard to see that
        !           251: *
        !           252: *           1) Iterations will go up monotonically
        !           253: *              if FINIT < 0;
        !           254: *
        !           255: *           2) Iterations will go down monotonically
        !           256: *              if FINIT > 0.
        !           257: *
        !           258:       ITER = NITER + 1
        !           259: *
        !           260:       DO 50 NITER = ITER, MAXIT
        !           261: *
        !           262:          IF( ORGATI ) THEN
        !           263:             TEMP1 = DSCALE( 2 ) - TAU
        !           264:             TEMP2 = DSCALE( 3 ) - TAU
        !           265:          ELSE
        !           266:             TEMP1 = DSCALE( 1 ) - TAU
        !           267:             TEMP2 = DSCALE( 2 ) - TAU
        !           268:          END IF
        !           269:          A = ( TEMP1+TEMP2 )*F - TEMP1*TEMP2*DF
        !           270:          B = TEMP1*TEMP2*F
        !           271:          C = F - ( TEMP1+TEMP2 )*DF + TEMP1*TEMP2*DDF
        !           272:          TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
        !           273:          A = A / TEMP
        !           274:          B = B / TEMP
        !           275:          C = C / TEMP
        !           276:          IF( C.EQ.ZERO ) THEN
        !           277:             ETA = B / A
        !           278:          ELSE IF( A.LE.ZERO ) THEN
        !           279:             ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
        !           280:          ELSE
        !           281:             ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
        !           282:          END IF
        !           283:          IF( F*ETA.GE.ZERO ) THEN
        !           284:             ETA = -F / DF
        !           285:          END IF
        !           286: *
        !           287:          TAU = TAU + ETA
        !           288:          IF( TAU .LT. LBD .OR. TAU .GT. UBD )
        !           289:      $      TAU = ( LBD + UBD )/TWO 
        !           290: *
        !           291:          FC = ZERO
        !           292:          ERRETM = ZERO
        !           293:          DF = ZERO
        !           294:          DDF = ZERO
        !           295:          DO 40 I = 1, 3
        !           296:             TEMP = ONE / ( DSCALE( I )-TAU )
        !           297:             TEMP1 = ZSCALE( I )*TEMP
        !           298:             TEMP2 = TEMP1*TEMP
        !           299:             TEMP3 = TEMP2*TEMP
        !           300:             TEMP4 = TEMP1 / DSCALE( I )
        !           301:             FC = FC + TEMP4
        !           302:             ERRETM = ERRETM + ABS( TEMP4 )
        !           303:             DF = DF + TEMP2
        !           304:             DDF = DDF + TEMP3
        !           305:    40    CONTINUE
        !           306:          F = FINIT + TAU*FC
        !           307:          ERRETM = EIGHT*( ABS( FINIT )+ABS( TAU )*ERRETM ) +
        !           308:      $            ABS( TAU )*DF
        !           309:          IF( ABS( F ).LE.EPS*ERRETM )
        !           310:      $      GO TO 60
        !           311:          IF( F .LE. ZERO )THEN
        !           312:             LBD = TAU
        !           313:          ELSE
        !           314:             UBD = TAU
        !           315:          END IF
        !           316:    50 CONTINUE
        !           317:       INFO = 1
        !           318:    60 CONTINUE
        !           319: *
        !           320: *     Undo scaling
        !           321: *
        !           322:       IF( SCALE )
        !           323:      $   TAU = TAU*SCLINV
        !           324:       RETURN
        !           325: *
        !           326: *     End of DLAED6
        !           327: *
        !           328:       END

CVSweb interface <joel.bertrand@systella.fr>