1 *> \brief \b DLAIC1 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 DLAIC1 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaic1.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaic1.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaic1.f">
21 * SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
23 * .. Scalar Arguments ..
25 * DOUBLE PRECISION C, GAMMA, S, SEST, SESTPR
27 * .. Array Arguments ..
28 * DOUBLE PRECISION W( J ), X( J )
37 *> DLAIC1 applies one step of incremental condition estimation in
38 *> its simplest version:
40 *> Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
41 *> lower triangular matrix L, such that
42 *> twonorm(L*x) = sest
43 *> Then DLAIC1 computes sestpr, s, c such that
47 *> is an approximate singular vector of
49 *> Lhat = [ w**T gamma ]
51 *> twonorm(Lhat*xhat) = sestpr.
53 *> Depending on JOB, an estimate for the largest or smallest singular
56 *> Note that [s c]**T and sestpr**2 is an eigenpair of the system
58 *> diag(sest*sest, 0) + [alpha gamma] * [ alpha ]
61 *> where alpha = x**T*w.
70 *> = 1: an estimate for the largest singular value is computed.
71 *> = 2: an estimate for the smallest singular value is computed.
82 *> X is DOUBLE PRECISION array, dimension (J)
88 *> SEST is DOUBLE PRECISION
89 *> Estimated singular value of j by j matrix L
94 *> W is DOUBLE PRECISION array, dimension (J)
100 *> GAMMA is DOUBLE PRECISION
101 *> The diagonal element gamma.
104 *> \param[out] SESTPR
106 *> SESTPR is DOUBLE PRECISION
107 *> Estimated singular value of (j+1) by (j+1) matrix Lhat.
112 *> S is DOUBLE PRECISION
113 *> Sine needed in forming xhat.
118 *> C is DOUBLE PRECISION
119 *> Cosine needed in forming xhat.
125 *> \author Univ. of Tennessee
126 *> \author Univ. of California Berkeley
127 *> \author Univ. of Colorado Denver
130 *> \date September 2012
132 *> \ingroup doubleOTHERauxiliary
134 * =====================================================================
135 SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
137 * -- LAPACK auxiliary routine (version 3.4.2) --
138 * -- LAPACK is a software package provided by Univ. of Tennessee, --
139 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
142 * .. Scalar Arguments ..
144 DOUBLE PRECISION C, GAMMA, S, SEST, SESTPR
146 * .. Array Arguments ..
147 DOUBLE PRECISION W( J ), X( J )
150 * =====================================================================
153 DOUBLE PRECISION ZERO, ONE, TWO
154 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
155 DOUBLE PRECISION HALF, FOUR
156 PARAMETER ( HALF = 0.5D0, FOUR = 4.0D0 )
158 * .. Local Scalars ..
159 DOUBLE PRECISION ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS,
160 $ NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2
162 * .. Intrinsic Functions ..
163 INTRINSIC ABS, MAX, SIGN, SQRT
165 * .. External Functions ..
166 DOUBLE PRECISION DDOT, DLAMCH
167 EXTERNAL DDOT, DLAMCH
169 * .. Executable Statements ..
171 EPS = DLAMCH( 'Epsilon' )
172 ALPHA = DDOT( J, X, 1, W, 1 )
174 ABSALP = ABS( ALPHA )
175 ABSGAM = ABS( GAMMA )
180 * Estimating largest singular value
184 IF( SEST.EQ.ZERO ) THEN
185 S1 = MAX( ABSGAM, ABSALP )
186 IF( S1.EQ.ZERO ) THEN
193 TMP = SQRT( S*S+C*C )
199 ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
202 TMP = MAX( ABSEST, ABSALP )
205 SESTPR = TMP*SQRT( S1*S1+S2*S2 )
207 ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
220 ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
225 S = SQRT( ONE+TMP*TMP )
227 C = ( GAMMA / S2 ) / S
228 S = SIGN( ONE, ALPHA ) / S
231 C = SQRT( ONE+TMP*TMP )
233 S = ( ALPHA / S1 ) / C
234 C = SIGN( ONE, GAMMA ) / C
241 ZETA1 = ALPHA / ABSEST
242 ZETA2 = GAMMA / ABSEST
244 B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
247 T = C / ( B+SQRT( B*B+C ) )
249 T = SQRT( B*B+C ) - B
253 COSINE = -ZETA2 / ( ONE+T )
254 TMP = SQRT( SINE*SINE+COSINE*COSINE )
257 SESTPR = SQRT( T+ONE )*ABSEST
261 ELSE IF( JOB.EQ.2 ) THEN
263 * Estimating smallest singular value
267 IF( SEST.EQ.ZERO ) THEN
269 IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
276 S1 = MAX( ABS( SINE ), ABS( COSINE ) )
279 TMP = SQRT( S*S+C*C )
283 ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
288 ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
301 ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
306 C = SQRT( ONE+TMP*TMP )
307 SESTPR = ABSEST*( TMP / C )
308 S = -( GAMMA / S2 ) / C
309 C = SIGN( ONE, ALPHA ) / C
312 S = SQRT( ONE+TMP*TMP )
314 C = ( ALPHA / S1 ) / S
315 S = -SIGN( ONE, GAMMA ) / S
322 ZETA1 = ALPHA / ABSEST
323 ZETA2 = GAMMA / ABSEST
325 NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ),
326 $ ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 )
328 * See if root is closer to zero or to ONE
330 TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
331 IF( TEST.GE.ZERO ) THEN
333 * root is close to zero, compute directly
335 B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
337 T = C / ( B+SQRT( ABS( B*B-C ) ) )
338 SINE = ZETA1 / ( ONE-T )
340 SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
343 * root is closer to ONE, shift by that amount
345 B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
348 T = -C / ( B+SQRT( B*B+C ) )
350 T = B - SQRT( B*B+C )
353 COSINE = -ZETA2 / ( ONE+T )
354 SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
356 TMP = SQRT( SINE*SINE+COSINE*COSINE )