📄 claic1.f
字号:
SUBROUTINE CLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )** -- LAPACK auxiliary routine (instrumented to count ops, version 3.0) --* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,* Courant Institute, Argonne National Lab, and Rice University* June 30, 1999** .. Scalar Arguments .. INTEGER J, JOB REAL SEST, SESTPR COMPLEX C, GAMMA, S* ..* .. Array Arguments .. COMPLEX W( J ), X( J )* ..* .. Common block to return operation count .. COMMON / LATIME / OPS, ITCNT* ..* .. Scalars in Common .. REAL ITCNT, OPS* ..* .. Common block to return operation counts and timings .. COMMON / LSTIME / OPCNT, TIMNG* ..* .. Arrays in Common .. REAL OPCNT( 6 ), TIMNG( 6 )* ..** Purpose* =======** CLAIC1 applies one step of incremental condition estimation in* its simplest version:** Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j* lower triangular matrix L, such that* twonorm(L*x) = sest* Then CLAIC1 computes sestpr, s, c such that* the vector* [ s*x ]* xhat = [ c ]* is an approximate singular vector of* [ L 0 ]* Lhat = [ w' gamma ]* in the sense that* twonorm(Lhat*xhat) = sestpr.** Depending on JOB, an estimate for the largest or smallest singular* value is computed.** Note that [s c]' and sestpr**2 is an eigenpair of the system** diag(sest*sest, 0) + [alpha gamma] * [ conjg(alpha) ]* [ conjg(gamma) ]** where alpha = conjg(x)'*w.** Arguments* =========** JOB (input) INTEGER* = 1: an estimate for the largest singular value is computed.* = 2: an estimate for the smallest singular value is computed.** J (input) INTEGER* Length of X and W** X (input) COMPLEX array, dimension (J)* The j-vector x.** SEST (input) REAL* Estimated singular value of j by j matrix L** W (input) COMPLEX array, dimension (J)* The j-vector w.** GAMMA (input) COMPLEX* The diagonal element gamma.** SESTPR (output) REAL* Estimated singular value of (j+1) by (j+1) matrix Lhat.** S (output) COMPLEX* Sine needed in forming xhat.** C (output) COMPLEX* Cosine needed in forming xhat.** =====================================================================** .. Parameters .. REAL ZERO, ONE, TWO PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 ) REAL HALF, FOUR PARAMETER ( HALF = 0.5E0, FOUR = 4.0E0 )* ..* .. Local Scalars .. REAL ABSALP, ABSEST, ABSGAM, B, EPS, NORMA, S1, S2, $ SCL, T, TEST, TMP, ZETA1, ZETA2 COMPLEX ALPHA, COSINE, SINE* ..* .. Intrinsic Functions .. INTRINSIC ABS, CONJG, MAX, SQRT* ..* .. External Functions .. REAL SLAMCH COMPLEX CDOTC EXTERNAL CDOTC, SLAMCH* ..* .. Executable Statements ..* EPS = SLAMCH( 'Epsilon' ) ALPHA = CDOTC( J, X, 1, W, 1 )* ABSALP = ABS( ALPHA ) ABSGAM = ABS( GAMMA ) ABSEST = ABS( SEST )* IF( JOB.EQ.1 ) THEN** Estimating largest singular value** special cases* IF( SEST.EQ.ZERO ) THEN S1 = MAX( ABSGAM, ABSALP ) IF( S1.EQ.ZERO ) THEN S = ZERO C = ONE SESTPR = ZERO ELSE OPS = OPS + 67 S = ALPHA / S1 C = GAMMA / S1 TMP = SQRT( S*CONJG( S )+C*CONJG( C ) ) S = S / TMP C = C / TMP SESTPR = S1*TMP END IF RETURN ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN OPS = OPS + 7 S = ONE C = ZERO TMP = MAX( ABSEST, ABSALP ) S1 = ABSEST / TMP S2 = ABSALP / TMP SESTPR = TMP*SQRT( S1*S1+S2*S2 ) RETURN ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN S1 = ABSGAM S2 = ABSEST IF( S1.LE.S2 ) THEN S = ONE C = ZERO SESTPR = S2 ELSE S = ZERO C = ONE SESTPR = S1 END IF RETURN ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN S1 = ABSGAM S2 = ABSALP IF( S1.LE.S2 ) THEN OPS = OPS + 57 TMP = S1 / S2 SCL = SQRT( ONE+TMP*TMP ) SESTPR = S2*SCL S = ( ALPHA / S2 ) / SCL C = ( GAMMA / S2 ) / SCL ELSE OPS = OPS + 57 TMP = S2 / S1 SCL = SQRT( ONE+TMP*TMP ) SESTPR = S1*SCL S = ( ALPHA / S1 ) / SCL C = ( GAMMA / S1 ) / SCL END IF RETURN ELSE** normal case* OPS = OPS + 8 ZETA1 = ABSALP / ABSEST ZETA2 = ABSGAM / ABSEST* B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF C = ZETA1*ZETA1 IF( B.GT.ZERO ) THEN OPS = OPS + 17 T = C / ( B+SQRT( B*B+C ) ) ELSE OPS = OPS + 5 T = SQRT( B*B+C ) - B END IF* OPS = OPS + 96 SINE = -( ALPHA / ABSEST ) / T COSINE = -( GAMMA / ABSEST ) / ( ONE+T ) TMP = SQRT( SINE*CONJG( SINE )+COSINE*CONJG( COSINE ) ) S = SINE / TMP C = COSINE / TMP SESTPR = SQRT( T+ONE )*ABSEST RETURN END IF* ELSE IF( JOB.EQ.2 ) THEN** Estimating smallest singular value** special cases* IF( SEST.EQ.ZERO ) THEN SESTPR = ZERO IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN SINE = ONE COSINE = ZERO ELSE SINE = -CONJG( GAMMA ) COSINE = CONJG( ALPHA ) END IF OPS = OPS + 66 S1 = MAX( ABS( SINE ), ABS( COSINE ) ) S = SINE / S1 C = COSINE / S1 TMP = SQRT( S*CONJG( S )+C*CONJG( C ) ) S = S / TMP C = C / TMP RETURN ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN S = ZERO C = ONE SESTPR = ABSGAM RETURN ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN S1 = ABSGAM S2 = ABSEST IF( S1.LE.S2 ) THEN S = ZERO C = ONE SESTPR = S1 ELSE S = ONE C = ZERO SESTPR = S2 END IF RETURN ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN S1 = ABSGAM S2 = ABSALP IF( S1.LE.S2 ) THEN OPS = OPS + 57 TMP = S1 / S2 SCL = SQRT( ONE+TMP*TMP ) SESTPR = ABSEST*( TMP / SCL ) S = -( CONJG( GAMMA ) / S2 ) / SCL C = ( CONJG( ALPHA ) / S2 ) / SCL ELSE OPS = OPS + 56 TMP = S2 / S1 SCL = SQRT( ONE+TMP*TMP ) SESTPR = ABSEST / SCL S = -( CONJG( GAMMA ) / S1 ) / SCL C = ( CONJG( ALPHA ) / S1 ) / SCL END IF RETURN ELSE** normal case* OPS = OPS + 14 ZETA1 = ABSALP / ABSEST ZETA2 = ABSGAM / ABSEST* NORMA = MAX( ONE+ZETA1*ZETA1+ZETA1*ZETA2, $ ZETA1*ZETA2+ZETA2*ZETA2 )** See if root is closer to zero or to ONE* TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 ) IF( TEST.GE.ZERO ) THEN** root is close to zero, compute directly* OPS = OPS + 62 B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF C = ZETA2*ZETA2 T = C / ( B+SQRT( ABS( B*B-C ) ) ) SINE = ( ALPHA / ABSEST ) / ( ONE-T ) COSINE = -( GAMMA / ABSEST ) / T SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST ELSE** root is closer to ONE, shift by that amount* OPS = OPS + 6 B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF C = ZETA1*ZETA1 IF( B.GE.ZERO ) THEN OPS = OPS + 5 T = -C / ( B+SQRT( B*B+C ) ) ELSE OPS = OPS + 5 T = B - SQRT( B*B+C ) END IF OPS = OPS + 5 SINE = -( ALPHA / ABSEST ) / T COSINE = -( GAMMA / ABSEST ) / ( ONE+T ) SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST END IF OPS = OPS + 40 TMP = SQRT( SINE*CONJG( SINE )+COSINE*CONJG( COSINE ) ) S = SINE / TMP C = COSINE / TMP RETURN* END IF END IF RETURN** End of CLAIC1* END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -