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>