1*> \brief \b DLAIC1 applies one step of incremental condition estimation. 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8*> \htmlonly 9*> Download DLAIC1 + dependencies 10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaic1.f"> 11*> [TGZ]</a> 12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaic1.f"> 13*> [ZIP]</a> 14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaic1.f"> 15*> [TXT]</a> 16*> \endhtmlonly 17* 18* Definition: 19* =========== 20* 21* SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C ) 22* 23* .. Scalar Arguments .. 24* INTEGER J, JOB 25* DOUBLE PRECISION C, GAMMA, S, SEST, SESTPR 26* .. 27* .. Array Arguments .. 28* DOUBLE PRECISION W( J ), X( J ) 29* .. 30* 31* 32*> \par Purpose: 33* ============= 34*> 35*> \verbatim 36*> 37*> DLAIC1 applies one step of incremental condition estimation in 38*> its simplest version: 39*> 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 44*> the vector 45*> [ s*x ] 46*> xhat = [ c ] 47*> is an approximate singular vector of 48*> [ L 0 ] 49*> Lhat = [ w**T gamma ] 50*> in the sense that 51*> twonorm(Lhat*xhat) = sestpr. 52*> 53*> Depending on JOB, an estimate for the largest or smallest singular 54*> value is computed. 55*> 56*> Note that [s c]**T and sestpr**2 is an eigenpair of the system 57*> 58*> diag(sest*sest, 0) + [alpha gamma] * [ alpha ] 59*> [ gamma ] 60*> 61*> where alpha = x**T*w. 62*> \endverbatim 63* 64* Arguments: 65* ========== 66* 67*> \param[in] JOB 68*> \verbatim 69*> JOB is INTEGER 70*> = 1: an estimate for the largest singular value is computed. 71*> = 2: an estimate for the smallest singular value is computed. 72*> \endverbatim 73*> 74*> \param[in] J 75*> \verbatim 76*> J is INTEGER 77*> Length of X and W 78*> \endverbatim 79*> 80*> \param[in] X 81*> \verbatim 82*> X is DOUBLE PRECISION array, dimension (J) 83*> The j-vector x. 84*> \endverbatim 85*> 86*> \param[in] SEST 87*> \verbatim 88*> SEST is DOUBLE PRECISION 89*> Estimated singular value of j by j matrix L 90*> \endverbatim 91*> 92*> \param[in] W 93*> \verbatim 94*> W is DOUBLE PRECISION array, dimension (J) 95*> The j-vector w. 96*> \endverbatim 97*> 98*> \param[in] GAMMA 99*> \verbatim 100*> GAMMA is DOUBLE PRECISION 101*> The diagonal element gamma. 102*> \endverbatim 103*> 104*> \param[out] SESTPR 105*> \verbatim 106*> SESTPR is DOUBLE PRECISION 107*> Estimated singular value of (j+1) by (j+1) matrix Lhat. 108*> \endverbatim 109*> 110*> \param[out] S 111*> \verbatim 112*> S is DOUBLE PRECISION 113*> Sine needed in forming xhat. 114*> \endverbatim 115*> 116*> \param[out] C 117*> \verbatim 118*> C is DOUBLE PRECISION 119*> Cosine needed in forming xhat. 120*> \endverbatim 121* 122* Authors: 123* ======== 124* 125*> \author Univ. of Tennessee 126*> \author Univ. of California Berkeley 127*> \author Univ. of Colorado Denver 128*> \author NAG Ltd. 129* 130*> \date September 2012 131* 132*> \ingroup doubleOTHERauxiliary 133* 134* ===================================================================== 135 SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C ) 136* 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..-- 140* September 2012 141* 142* .. Scalar Arguments .. 143 INTEGER J, JOB 144 DOUBLE PRECISION C, GAMMA, S, SEST, SESTPR 145* .. 146* .. Array Arguments .. 147 DOUBLE PRECISION W( J ), X( J ) 148* .. 149* 150* ===================================================================== 151* 152* .. Parameters .. 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 ) 157* .. 158* .. Local Scalars .. 159 DOUBLE PRECISION ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS, 160 $ NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2 161* .. 162* .. Intrinsic Functions .. 163 INTRINSIC ABS, MAX, SIGN, SQRT 164* .. 165* .. External Functions .. 166 DOUBLE PRECISION DDOT, DLAMCH 167 EXTERNAL DDOT, DLAMCH 168* .. 169* .. Executable Statements .. 170* 171 EPS = DLAMCH( 'Epsilon' ) 172 ALPHA = DDOT( J, X, 1, W, 1 ) 173* 174 ABSALP = ABS( ALPHA ) 175 ABSGAM = ABS( GAMMA ) 176 ABSEST = ABS( SEST ) 177* 178 IF( JOB.EQ.1 ) THEN 179* 180* Estimating largest singular value 181* 182* special cases 183* 184 IF( SEST.EQ.ZERO ) THEN 185 S1 = MAX( ABSGAM, ABSALP ) 186 IF( S1.EQ.ZERO ) THEN 187 S = ZERO 188 C = ONE 189 SESTPR = ZERO 190 ELSE 191 S = ALPHA / S1 192 C = GAMMA / S1 193 TMP = SQRT( S*S+C*C ) 194 S = S / TMP 195 C = C / TMP 196 SESTPR = S1*TMP 197 END IF 198 RETURN 199 ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN 200 S = ONE 201 C = ZERO 202 TMP = MAX( ABSEST, ABSALP ) 203 S1 = ABSEST / TMP 204 S2 = ABSALP / TMP 205 SESTPR = TMP*SQRT( S1*S1+S2*S2 ) 206 RETURN 207 ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN 208 S1 = ABSGAM 209 S2 = ABSEST 210 IF( S1.LE.S2 ) THEN 211 S = ONE 212 C = ZERO 213 SESTPR = S2 214 ELSE 215 S = ZERO 216 C = ONE 217 SESTPR = S1 218 END IF 219 RETURN 220 ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN 221 S1 = ABSGAM 222 S2 = ABSALP 223 IF( S1.LE.S2 ) THEN 224 TMP = S1 / S2 225 S = SQRT( ONE+TMP*TMP ) 226 SESTPR = S2*S 227 C = ( GAMMA / S2 ) / S 228 S = SIGN( ONE, ALPHA ) / S 229 ELSE 230 TMP = S2 / S1 231 C = SQRT( ONE+TMP*TMP ) 232 SESTPR = S1*C 233 S = ( ALPHA / S1 ) / C 234 C = SIGN( ONE, GAMMA ) / C 235 END IF 236 RETURN 237 ELSE 238* 239* normal case 240* 241 ZETA1 = ALPHA / ABSEST 242 ZETA2 = GAMMA / ABSEST 243* 244 B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF 245 C = ZETA1*ZETA1 246 IF( B.GT.ZERO ) THEN 247 T = C / ( B+SQRT( B*B+C ) ) 248 ELSE 249 T = SQRT( B*B+C ) - B 250 END IF 251* 252 SINE = -ZETA1 / T 253 COSINE = -ZETA2 / ( ONE+T ) 254 TMP = SQRT( SINE*SINE+COSINE*COSINE ) 255 S = SINE / TMP 256 C = COSINE / TMP 257 SESTPR = SQRT( T+ONE )*ABSEST 258 RETURN 259 END IF 260* 261 ELSE IF( JOB.EQ.2 ) THEN 262* 263* Estimating smallest singular value 264* 265* special cases 266* 267 IF( SEST.EQ.ZERO ) THEN 268 SESTPR = ZERO 269 IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN 270 SINE = ONE 271 COSINE = ZERO 272 ELSE 273 SINE = -GAMMA 274 COSINE = ALPHA 275 END IF 276 S1 = MAX( ABS( SINE ), ABS( COSINE ) ) 277 S = SINE / S1 278 C = COSINE / S1 279 TMP = SQRT( S*S+C*C ) 280 S = S / TMP 281 C = C / TMP 282 RETURN 283 ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN 284 S = ZERO 285 C = ONE 286 SESTPR = ABSGAM 287 RETURN 288 ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN 289 S1 = ABSGAM 290 S2 = ABSEST 291 IF( S1.LE.S2 ) THEN 292 S = ZERO 293 C = ONE 294 SESTPR = S1 295 ELSE 296 S = ONE 297 C = ZERO 298 SESTPR = S2 299 END IF 300 RETURN 301 ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN 302 S1 = ABSGAM 303 S2 = ABSALP 304 IF( S1.LE.S2 ) THEN 305 TMP = S1 / S2 306 C = SQRT( ONE+TMP*TMP ) 307 SESTPR = ABSEST*( TMP / C ) 308 S = -( GAMMA / S2 ) / C 309 C = SIGN( ONE, ALPHA ) / C 310 ELSE 311 TMP = S2 / S1 312 S = SQRT( ONE+TMP*TMP ) 313 SESTPR = ABSEST / S 314 C = ( ALPHA / S1 ) / S 315 S = -SIGN( ONE, GAMMA ) / S 316 END IF 317 RETURN 318 ELSE 319* 320* normal case 321* 322 ZETA1 = ALPHA / ABSEST 323 ZETA2 = GAMMA / ABSEST 324* 325 NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ), 326 $ ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 ) 327* 328* See if root is closer to zero or to ONE 329* 330 TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 ) 331 IF( TEST.GE.ZERO ) THEN 332* 333* root is close to zero, compute directly 334* 335 B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF 336 C = ZETA2*ZETA2 337 T = C / ( B+SQRT( ABS( B*B-C ) ) ) 338 SINE = ZETA1 / ( ONE-T ) 339 COSINE = -ZETA2 / T 340 SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST 341 ELSE 342* 343* root is closer to ONE, shift by that amount 344* 345 B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF 346 C = ZETA1*ZETA1 347 IF( B.GE.ZERO ) THEN 348 T = -C / ( B+SQRT( B*B+C ) ) 349 ELSE 350 T = B - SQRT( B*B+C ) 351 END IF 352 SINE = -ZETA1 / T 353 COSINE = -ZETA2 / ( ONE+T ) 354 SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST 355 END IF 356 TMP = SQRT( SINE*SINE+COSINE*COSINE ) 357 S = SINE / TMP 358 C = COSINE / TMP 359 RETURN 360* 361 END IF 362 END IF 363 RETURN 364* 365* End of DLAIC1 366* 367 END 368