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>