Annotation of rpl/lapack/lapack/dlaic1.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
! 2: *
! 3: * -- LAPACK auxiliary 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: * November 2006
! 7: *
! 8: * .. Scalar Arguments ..
! 9: INTEGER J, JOB
! 10: DOUBLE PRECISION C, GAMMA, S, SEST, SESTPR
! 11: * ..
! 12: * .. Array Arguments ..
! 13: DOUBLE PRECISION W( J ), X( J )
! 14: * ..
! 15: *
! 16: * Purpose
! 17: * =======
! 18: *
! 19: * DLAIC1 applies one step of incremental condition estimation in
! 20: * its simplest version:
! 21: *
! 22: * Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
! 23: * lower triangular matrix L, such that
! 24: * twonorm(L*x) = sest
! 25: * Then DLAIC1 computes sestpr, s, c such that
! 26: * the vector
! 27: * [ s*x ]
! 28: * xhat = [ c ]
! 29: * is an approximate singular vector of
! 30: * [ L 0 ]
! 31: * Lhat = [ w' gamma ]
! 32: * in the sense that
! 33: * twonorm(Lhat*xhat) = sestpr.
! 34: *
! 35: * Depending on JOB, an estimate for the largest or smallest singular
! 36: * value is computed.
! 37: *
! 38: * Note that [s c]' and sestpr**2 is an eigenpair of the system
! 39: *
! 40: * diag(sest*sest, 0) + [alpha gamma] * [ alpha ]
! 41: * [ gamma ]
! 42: *
! 43: * where alpha = x'*w.
! 44: *
! 45: * Arguments
! 46: * =========
! 47: *
! 48: * JOB (input) INTEGER
! 49: * = 1: an estimate for the largest singular value is computed.
! 50: * = 2: an estimate for the smallest singular value is computed.
! 51: *
! 52: * J (input) INTEGER
! 53: * Length of X and W
! 54: *
! 55: * X (input) DOUBLE PRECISION array, dimension (J)
! 56: * The j-vector x.
! 57: *
! 58: * SEST (input) DOUBLE PRECISION
! 59: * Estimated singular value of j by j matrix L
! 60: *
! 61: * W (input) DOUBLE PRECISION array, dimension (J)
! 62: * The j-vector w.
! 63: *
! 64: * GAMMA (input) DOUBLE PRECISION
! 65: * The diagonal element gamma.
! 66: *
! 67: * SESTPR (output) DOUBLE PRECISION
! 68: * Estimated singular value of (j+1) by (j+1) matrix Lhat.
! 69: *
! 70: * S (output) DOUBLE PRECISION
! 71: * Sine needed in forming xhat.
! 72: *
! 73: * C (output) DOUBLE PRECISION
! 74: * Cosine needed in forming xhat.
! 75: *
! 76: * =====================================================================
! 77: *
! 78: * .. Parameters ..
! 79: DOUBLE PRECISION ZERO, ONE, TWO
! 80: PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
! 81: DOUBLE PRECISION HALF, FOUR
! 82: PARAMETER ( HALF = 0.5D0, FOUR = 4.0D0 )
! 83: * ..
! 84: * .. Local Scalars ..
! 85: DOUBLE PRECISION ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS,
! 86: $ NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2
! 87: * ..
! 88: * .. Intrinsic Functions ..
! 89: INTRINSIC ABS, MAX, SIGN, SQRT
! 90: * ..
! 91: * .. External Functions ..
! 92: DOUBLE PRECISION DDOT, DLAMCH
! 93: EXTERNAL DDOT, DLAMCH
! 94: * ..
! 95: * .. Executable Statements ..
! 96: *
! 97: EPS = DLAMCH( 'Epsilon' )
! 98: ALPHA = DDOT( J, X, 1, W, 1 )
! 99: *
! 100: ABSALP = ABS( ALPHA )
! 101: ABSGAM = ABS( GAMMA )
! 102: ABSEST = ABS( SEST )
! 103: *
! 104: IF( JOB.EQ.1 ) THEN
! 105: *
! 106: * Estimating largest singular value
! 107: *
! 108: * special cases
! 109: *
! 110: IF( SEST.EQ.ZERO ) THEN
! 111: S1 = MAX( ABSGAM, ABSALP )
! 112: IF( S1.EQ.ZERO ) THEN
! 113: S = ZERO
! 114: C = ONE
! 115: SESTPR = ZERO
! 116: ELSE
! 117: S = ALPHA / S1
! 118: C = GAMMA / S1
! 119: TMP = SQRT( S*S+C*C )
! 120: S = S / TMP
! 121: C = C / TMP
! 122: SESTPR = S1*TMP
! 123: END IF
! 124: RETURN
! 125: ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
! 126: S = ONE
! 127: C = ZERO
! 128: TMP = MAX( ABSEST, ABSALP )
! 129: S1 = ABSEST / TMP
! 130: S2 = ABSALP / TMP
! 131: SESTPR = TMP*SQRT( S1*S1+S2*S2 )
! 132: RETURN
! 133: ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
! 134: S1 = ABSGAM
! 135: S2 = ABSEST
! 136: IF( S1.LE.S2 ) THEN
! 137: S = ONE
! 138: C = ZERO
! 139: SESTPR = S2
! 140: ELSE
! 141: S = ZERO
! 142: C = ONE
! 143: SESTPR = S1
! 144: END IF
! 145: RETURN
! 146: ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
! 147: S1 = ABSGAM
! 148: S2 = ABSALP
! 149: IF( S1.LE.S2 ) THEN
! 150: TMP = S1 / S2
! 151: S = SQRT( ONE+TMP*TMP )
! 152: SESTPR = S2*S
! 153: C = ( GAMMA / S2 ) / S
! 154: S = SIGN( ONE, ALPHA ) / S
! 155: ELSE
! 156: TMP = S2 / S1
! 157: C = SQRT( ONE+TMP*TMP )
! 158: SESTPR = S1*C
! 159: S = ( ALPHA / S1 ) / C
! 160: C = SIGN( ONE, GAMMA ) / C
! 161: END IF
! 162: RETURN
! 163: ELSE
! 164: *
! 165: * normal case
! 166: *
! 167: ZETA1 = ALPHA / ABSEST
! 168: ZETA2 = GAMMA / ABSEST
! 169: *
! 170: B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
! 171: C = ZETA1*ZETA1
! 172: IF( B.GT.ZERO ) THEN
! 173: T = C / ( B+SQRT( B*B+C ) )
! 174: ELSE
! 175: T = SQRT( B*B+C ) - B
! 176: END IF
! 177: *
! 178: SINE = -ZETA1 / T
! 179: COSINE = -ZETA2 / ( ONE+T )
! 180: TMP = SQRT( SINE*SINE+COSINE*COSINE )
! 181: S = SINE / TMP
! 182: C = COSINE / TMP
! 183: SESTPR = SQRT( T+ONE )*ABSEST
! 184: RETURN
! 185: END IF
! 186: *
! 187: ELSE IF( JOB.EQ.2 ) THEN
! 188: *
! 189: * Estimating smallest singular value
! 190: *
! 191: * special cases
! 192: *
! 193: IF( SEST.EQ.ZERO ) THEN
! 194: SESTPR = ZERO
! 195: IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
! 196: SINE = ONE
! 197: COSINE = ZERO
! 198: ELSE
! 199: SINE = -GAMMA
! 200: COSINE = ALPHA
! 201: END IF
! 202: S1 = MAX( ABS( SINE ), ABS( COSINE ) )
! 203: S = SINE / S1
! 204: C = COSINE / S1
! 205: TMP = SQRT( S*S+C*C )
! 206: S = S / TMP
! 207: C = C / TMP
! 208: RETURN
! 209: ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
! 210: S = ZERO
! 211: C = ONE
! 212: SESTPR = ABSGAM
! 213: RETURN
! 214: ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
! 215: S1 = ABSGAM
! 216: S2 = ABSEST
! 217: IF( S1.LE.S2 ) THEN
! 218: S = ZERO
! 219: C = ONE
! 220: SESTPR = S1
! 221: ELSE
! 222: S = ONE
! 223: C = ZERO
! 224: SESTPR = S2
! 225: END IF
! 226: RETURN
! 227: ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
! 228: S1 = ABSGAM
! 229: S2 = ABSALP
! 230: IF( S1.LE.S2 ) THEN
! 231: TMP = S1 / S2
! 232: C = SQRT( ONE+TMP*TMP )
! 233: SESTPR = ABSEST*( TMP / C )
! 234: S = -( GAMMA / S2 ) / C
! 235: C = SIGN( ONE, ALPHA ) / C
! 236: ELSE
! 237: TMP = S2 / S1
! 238: S = SQRT( ONE+TMP*TMP )
! 239: SESTPR = ABSEST / S
! 240: C = ( ALPHA / S1 ) / S
! 241: S = -SIGN( ONE, GAMMA ) / S
! 242: END IF
! 243: RETURN
! 244: ELSE
! 245: *
! 246: * normal case
! 247: *
! 248: ZETA1 = ALPHA / ABSEST
! 249: ZETA2 = GAMMA / ABSEST
! 250: *
! 251: NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ),
! 252: $ ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 )
! 253: *
! 254: * See if root is closer to zero or to ONE
! 255: *
! 256: TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
! 257: IF( TEST.GE.ZERO ) THEN
! 258: *
! 259: * root is close to zero, compute directly
! 260: *
! 261: B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
! 262: C = ZETA2*ZETA2
! 263: T = C / ( B+SQRT( ABS( B*B-C ) ) )
! 264: SINE = ZETA1 / ( ONE-T )
! 265: COSINE = -ZETA2 / T
! 266: SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
! 267: ELSE
! 268: *
! 269: * root is closer to ONE, shift by that amount
! 270: *
! 271: B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
! 272: C = ZETA1*ZETA1
! 273: IF( B.GE.ZERO ) THEN
! 274: T = -C / ( B+SQRT( B*B+C ) )
! 275: ELSE
! 276: T = B - SQRT( B*B+C )
! 277: END IF
! 278: SINE = -ZETA1 / T
! 279: COSINE = -ZETA2 / ( ONE+T )
! 280: SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
! 281: END IF
! 282: TMP = SQRT( SINE*SINE+COSINE*COSINE )
! 283: S = SINE / TMP
! 284: C = COSINE / TMP
! 285: RETURN
! 286: *
! 287: END IF
! 288: END IF
! 289: RETURN
! 290: *
! 291: * End of DLAIC1
! 292: *
! 293: END
CVSweb interface <joel.bertrand@systella.fr>