1 *> \brief \b ZLAIC1 applies one step of incremental condition estimation.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download ZLAIC1 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlaic1.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlaic1.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlaic1.f">
21 * SUBROUTINE ZLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
23 * .. Scalar Arguments ..
25 * DOUBLE PRECISION SEST, SESTPR
26 * COMPLEX*16 C, GAMMA, S
28 * .. Array Arguments ..
29 * COMPLEX*16 W( J ), X( J )
38 *> ZLAIC1 applies one step of incremental condition estimation in
39 *> its simplest version:
41 *> Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
42 *> lower triangular matrix L, such that
43 *> twonorm(L*x) = sest
44 *> Then ZLAIC1 computes sestpr, s, c such that
48 *> is an approximate singular vector of
50 *> Lhat = [ w**H gamma ]
52 *> twonorm(Lhat*xhat) = sestpr.
54 *> Depending on JOB, an estimate for the largest or smallest singular
57 *> Note that [s c]**H and sestpr**2 is an eigenpair of the system
59 *> diag(sest*sest, 0) + [alpha gamma] * [ conjg(alpha) ]
62 *> where alpha = x**H * w.
71 *> = 1: an estimate for the largest singular value is computed.
72 *> = 2: an estimate for the smallest singular value is computed.
83 *> X is COMPLEX*16 array, dimension (J)
89 *> SEST is DOUBLE PRECISION
90 *> Estimated singular value of j by j matrix L
95 *> W is COMPLEX*16 array, dimension (J)
101 *> GAMMA is COMPLEX*16
102 *> The diagonal element gamma.
105 *> \param[out] SESTPR
107 *> SESTPR is DOUBLE PRECISION
108 *> Estimated singular value of (j+1) by (j+1) matrix Lhat.
114 *> Sine needed in forming xhat.
120 *> Cosine needed in forming xhat.
126 *> \author Univ. of Tennessee
127 *> \author Univ. of California Berkeley
128 *> \author Univ. of Colorado Denver
131 *> \date September 2012
133 *> \ingroup complex16OTHERauxiliary
135 * =====================================================================
136 SUBROUTINE ZLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
138 * -- LAPACK auxiliary routine (version 3.4.2) --
139 * -- LAPACK is a software package provided by Univ. of Tennessee, --
140 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
143 * .. Scalar Arguments ..
145 DOUBLE PRECISION SEST, SESTPR
146 COMPLEX*16 C, GAMMA, S
148 * .. Array Arguments ..
149 COMPLEX*16 W( J ), X( J )
152 * =====================================================================
155 DOUBLE PRECISION ZERO, ONE, TWO
156 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
157 DOUBLE PRECISION HALF, FOUR
158 PARAMETER ( HALF = 0.5D0, FOUR = 4.0D0 )
160 * .. Local Scalars ..
161 DOUBLE PRECISION ABSALP, ABSEST, ABSGAM, B, EPS, NORMA, S1, S2,
162 $ SCL, T, TEST, TMP, ZETA1, ZETA2
163 COMPLEX*16 ALPHA, COSINE, SINE
165 * .. Intrinsic Functions ..
166 INTRINSIC ABS, DCONJG, MAX, SQRT
168 * .. External Functions ..
169 DOUBLE PRECISION DLAMCH
171 EXTERNAL DLAMCH, ZDOTC
173 * .. Executable Statements ..
175 EPS = DLAMCH( 'Epsilon' )
176 ALPHA = ZDOTC( J, X, 1, W, 1 )
178 ABSALP = ABS( ALPHA )
179 ABSGAM = ABS( GAMMA )
184 * Estimating largest singular value
188 IF( SEST.EQ.ZERO ) THEN
189 S1 = MAX( ABSGAM, ABSALP )
190 IF( S1.EQ.ZERO ) THEN
197 TMP = SQRT( S*DCONJG( S )+C*DCONJG( C ) )
203 ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
206 TMP = MAX( ABSEST, ABSALP )
209 SESTPR = TMP*SQRT( S1*S1+S2*S2 )
211 ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
224 ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
229 SCL = SQRT( ONE+TMP*TMP )
231 S = ( ALPHA / S2 ) / SCL
232 C = ( GAMMA / S2 ) / SCL
235 SCL = SQRT( ONE+TMP*TMP )
237 S = ( ALPHA / S1 ) / SCL
238 C = ( GAMMA / S1 ) / SCL
245 ZETA1 = ABSALP / ABSEST
246 ZETA2 = ABSGAM / ABSEST
248 B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
251 T = C / ( B+SQRT( B*B+C ) )
253 T = SQRT( B*B+C ) - B
256 SINE = -( ALPHA / ABSEST ) / T
257 COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
258 TMP = SQRT( SINE*DCONJG( SINE )+COSINE*DCONJG( COSINE ) )
261 SESTPR = SQRT( T+ONE )*ABSEST
265 ELSE IF( JOB.EQ.2 ) THEN
267 * Estimating smallest singular value
271 IF( SEST.EQ.ZERO ) THEN
273 IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
277 SINE = -DCONJG( GAMMA )
278 COSINE = DCONJG( ALPHA )
280 S1 = MAX( ABS( SINE ), ABS( COSINE ) )
283 TMP = SQRT( S*DCONJG( S )+C*DCONJG( C ) )
287 ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
292 ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
305 ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
310 SCL = SQRT( ONE+TMP*TMP )
311 SESTPR = ABSEST*( TMP / SCL )
312 S = -( DCONJG( GAMMA ) / S2 ) / SCL
313 C = ( DCONJG( ALPHA ) / S2 ) / SCL
316 SCL = SQRT( ONE+TMP*TMP )
317 SESTPR = ABSEST / SCL
318 S = -( DCONJG( GAMMA ) / S1 ) / SCL
319 C = ( DCONJG( ALPHA ) / S1 ) / SCL
326 ZETA1 = ABSALP / ABSEST
327 ZETA2 = ABSGAM / ABSEST
329 NORMA = MAX( ONE+ZETA1*ZETA1+ZETA1*ZETA2,
330 $ ZETA1*ZETA2+ZETA2*ZETA2 )
332 * See if root is closer to zero or to ONE
334 TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
335 IF( TEST.GE.ZERO ) THEN
337 * root is close to zero, compute directly
339 B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
341 T = C / ( B+SQRT( ABS( B*B-C ) ) )
342 SINE = ( ALPHA / ABSEST ) / ( ONE-T )
343 COSINE = -( GAMMA / ABSEST ) / T
344 SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
347 * root is closer to ONE, shift by that amount
349 B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
352 T = -C / ( B+SQRT( B*B+C ) )
354 T = B - SQRT( B*B+C )
356 SINE = -( ALPHA / ABSEST ) / T
357 COSINE = -( GAMMA / ABSEST ) / ( ONE+T )
358 SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
360 TMP = SQRT( SINE*DCONJG( SINE )+COSINE*DCONJG( COSINE ) )