Annotation of rpl/lapack/lapack/dlasq3.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,
! 2: $ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,
! 3: $ DN2, G, TAU )
! 4: *
! 5: * -- LAPACK routine (version 3.2) --
! 6: *
! 7: * -- Contributed by Osni Marques of the Lawrence Berkeley National --
! 8: * -- Laboratory and Beresford Parlett of the Univ. of California at --
! 9: * -- Berkeley --
! 10: * -- November 2008 --
! 11: *
! 12: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 13: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 14: *
! 15: * .. Scalar Arguments ..
! 16: LOGICAL IEEE
! 17: INTEGER I0, ITER, N0, NDIV, NFAIL, PP
! 18: DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,
! 19: $ QMAX, SIGMA, TAU
! 20: * ..
! 21: * .. Array Arguments ..
! 22: DOUBLE PRECISION Z( * )
! 23: * ..
! 24: *
! 25: * Purpose
! 26: * =======
! 27: *
! 28: * DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds.
! 29: * In case of failure it changes shifts, and tries again until output
! 30: * is positive.
! 31: *
! 32: * Arguments
! 33: * =========
! 34: *
! 35: * I0 (input) INTEGER
! 36: * First index.
! 37: *
! 38: * N0 (input) INTEGER
! 39: * Last index.
! 40: *
! 41: * Z (input) DOUBLE PRECISION array, dimension ( 4*N )
! 42: * Z holds the qd array.
! 43: *
! 44: * PP (input/output) INTEGER
! 45: * PP=0 for ping, PP=1 for pong.
! 46: * PP=2 indicates that flipping was applied to the Z array
! 47: * and that the initial tests for deflation should not be
! 48: * performed.
! 49: *
! 50: * DMIN (output) DOUBLE PRECISION
! 51: * Minimum value of d.
! 52: *
! 53: * SIGMA (output) DOUBLE PRECISION
! 54: * Sum of shifts used in current segment.
! 55: *
! 56: * DESIG (input/output) DOUBLE PRECISION
! 57: * Lower order part of SIGMA
! 58: *
! 59: * QMAX (input) DOUBLE PRECISION
! 60: * Maximum value of q.
! 61: *
! 62: * NFAIL (output) INTEGER
! 63: * Number of times shift was too big.
! 64: *
! 65: * ITER (output) INTEGER
! 66: * Number of iterations.
! 67: *
! 68: * NDIV (output) INTEGER
! 69: * Number of divisions.
! 70: *
! 71: * IEEE (input) LOGICAL
! 72: * Flag for IEEE or non IEEE arithmetic (passed to DLASQ5).
! 73: *
! 74: * TTYPE (input/output) INTEGER
! 75: * Shift type.
! 76: *
! 77: * DMIN1, DMIN2, DN, DN1, DN2, G, TAU (input/output) DOUBLE PRECISION
! 78: * These are passed as arguments in order to save their values
! 79: * between calls to DLASQ3.
! 80: *
! 81: * =====================================================================
! 82: *
! 83: * .. Parameters ..
! 84: DOUBLE PRECISION CBIAS
! 85: PARAMETER ( CBIAS = 1.50D0 )
! 86: DOUBLE PRECISION ZERO, QURTR, HALF, ONE, TWO, HUNDRD
! 87: PARAMETER ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,
! 88: $ ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )
! 89: * ..
! 90: * .. Local Scalars ..
! 91: INTEGER IPN4, J4, N0IN, NN, TTYPE
! 92: DOUBLE PRECISION EPS, S, T, TEMP, TOL, TOL2
! 93: * ..
! 94: * .. External Subroutines ..
! 95: EXTERNAL DLASQ4, DLASQ5, DLASQ6
! 96: * ..
! 97: * .. External Function ..
! 98: DOUBLE PRECISION DLAMCH
! 99: LOGICAL DISNAN
! 100: EXTERNAL DISNAN, DLAMCH
! 101: * ..
! 102: * .. Intrinsic Functions ..
! 103: INTRINSIC ABS, MAX, MIN, SQRT
! 104: * ..
! 105: * .. Executable Statements ..
! 106: *
! 107: N0IN = N0
! 108: EPS = DLAMCH( 'Precision' )
! 109: TOL = EPS*HUNDRD
! 110: TOL2 = TOL**2
! 111: *
! 112: * Check for deflation.
! 113: *
! 114: 10 CONTINUE
! 115: *
! 116: IF( N0.LT.I0 )
! 117: $ RETURN
! 118: IF( N0.EQ.I0 )
! 119: $ GO TO 20
! 120: NN = 4*N0 + PP
! 121: IF( N0.EQ.( I0+1 ) )
! 122: $ GO TO 40
! 123: *
! 124: * Check whether E(N0-1) is negligible, 1 eigenvalue.
! 125: *
! 126: IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.
! 127: $ Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )
! 128: $ GO TO 30
! 129: *
! 130: 20 CONTINUE
! 131: *
! 132: Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA
! 133: N0 = N0 - 1
! 134: GO TO 10
! 135: *
! 136: * Check whether E(N0-2) is negligible, 2 eigenvalues.
! 137: *
! 138: 30 CONTINUE
! 139: *
! 140: IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.
! 141: $ Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )
! 142: $ GO TO 50
! 143: *
! 144: 40 CONTINUE
! 145: *
! 146: IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN
! 147: S = Z( NN-3 )
! 148: Z( NN-3 ) = Z( NN-7 )
! 149: Z( NN-7 ) = S
! 150: END IF
! 151: IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN
! 152: T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )
! 153: S = Z( NN-3 )*( Z( NN-5 ) / T )
! 154: IF( S.LE.T ) THEN
! 155: S = Z( NN-3 )*( Z( NN-5 ) /
! 156: $ ( T*( ONE+SQRT( ONE+S / T ) ) ) )
! 157: ELSE
! 158: S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )
! 159: END IF
! 160: T = Z( NN-7 ) + ( S+Z( NN-5 ) )
! 161: Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )
! 162: Z( NN-7 ) = T
! 163: END IF
! 164: Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA
! 165: Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA
! 166: N0 = N0 - 2
! 167: GO TO 10
! 168: *
! 169: 50 CONTINUE
! 170: IF( PP.EQ.2 )
! 171: $ PP = 0
! 172: *
! 173: * Reverse the qd-array, if warranted.
! 174: *
! 175: IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN
! 176: IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN
! 177: IPN4 = 4*( I0+N0 )
! 178: DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4
! 179: TEMP = Z( J4-3 )
! 180: Z( J4-3 ) = Z( IPN4-J4-3 )
! 181: Z( IPN4-J4-3 ) = TEMP
! 182: TEMP = Z( J4-2 )
! 183: Z( J4-2 ) = Z( IPN4-J4-2 )
! 184: Z( IPN4-J4-2 ) = TEMP
! 185: TEMP = Z( J4-1 )
! 186: Z( J4-1 ) = Z( IPN4-J4-5 )
! 187: Z( IPN4-J4-5 ) = TEMP
! 188: TEMP = Z( J4 )
! 189: Z( J4 ) = Z( IPN4-J4-4 )
! 190: Z( IPN4-J4-4 ) = TEMP
! 191: 60 CONTINUE
! 192: IF( N0-I0.LE.4 ) THEN
! 193: Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )
! 194: Z( 4*N0-PP ) = Z( 4*I0-PP )
! 195: END IF
! 196: DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )
! 197: Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),
! 198: $ Z( 4*I0+PP+3 ) )
! 199: Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),
! 200: $ Z( 4*I0-PP+4 ) )
! 201: QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )
! 202: DMIN = -ZERO
! 203: END IF
! 204: END IF
! 205: *
! 206: * Choose a shift.
! 207: *
! 208: CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,
! 209: $ DN2, TAU, TTYPE, G )
! 210: *
! 211: * Call dqds until DMIN > 0.
! 212: *
! 213: 70 CONTINUE
! 214: *
! 215: CALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN,
! 216: $ DN1, DN2, IEEE )
! 217: *
! 218: NDIV = NDIV + ( N0-I0+2 )
! 219: ITER = ITER + 1
! 220: *
! 221: * Check status.
! 222: *
! 223: IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN
! 224: *
! 225: * Success.
! 226: *
! 227: GO TO 90
! 228: *
! 229: ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.
! 230: $ Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.
! 231: $ ABS( DN ).LT.TOL*SIGMA ) THEN
! 232: *
! 233: * Convergence hidden by negative DN.
! 234: *
! 235: Z( 4*( N0-1 )-PP+2 ) = ZERO
! 236: DMIN = ZERO
! 237: GO TO 90
! 238: ELSE IF( DMIN.LT.ZERO ) THEN
! 239: *
! 240: * TAU too big. Select new TAU and try again.
! 241: *
! 242: NFAIL = NFAIL + 1
! 243: IF( TTYPE.LT.-22 ) THEN
! 244: *
! 245: * Failed twice. Play it safe.
! 246: *
! 247: TAU = ZERO
! 248: ELSE IF( DMIN1.GT.ZERO ) THEN
! 249: *
! 250: * Late failure. Gives excellent shift.
! 251: *
! 252: TAU = ( TAU+DMIN )*( ONE-TWO*EPS )
! 253: TTYPE = TTYPE - 11
! 254: ELSE
! 255: *
! 256: * Early failure. Divide by 4.
! 257: *
! 258: TAU = QURTR*TAU
! 259: TTYPE = TTYPE - 12
! 260: END IF
! 261: GO TO 70
! 262: ELSE IF( DISNAN( DMIN ) ) THEN
! 263: *
! 264: * NaN.
! 265: *
! 266: IF( TAU.EQ.ZERO ) THEN
! 267: GO TO 80
! 268: ELSE
! 269: TAU = ZERO
! 270: GO TO 70
! 271: END IF
! 272: ELSE
! 273: *
! 274: * Possible underflow. Play it safe.
! 275: *
! 276: GO TO 80
! 277: END IF
! 278: *
! 279: * Risk of underflow.
! 280: *
! 281: 80 CONTINUE
! 282: CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )
! 283: NDIV = NDIV + ( N0-I0+2 )
! 284: ITER = ITER + 1
! 285: TAU = ZERO
! 286: *
! 287: 90 CONTINUE
! 288: IF( TAU.LT.SIGMA ) THEN
! 289: DESIG = DESIG + TAU
! 290: T = SIGMA + DESIG
! 291: DESIG = DESIG - ( T-SIGMA )
! 292: ELSE
! 293: T = SIGMA + TAU
! 294: DESIG = SIGMA - ( T-TAU ) + DESIG
! 295: END IF
! 296: SIGMA = T
! 297: *
! 298: RETURN
! 299: *
! 300: * End of DLASQ3
! 301: *
! 302: END
CVSweb interface <joel.bertrand@systella.fr>