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