root / src / lapack / double / dlaic1.f @ 2
Historique | Voir | Annoter | Télécharger (8,17 ko)
1 | 1 | equemene | SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C ) |
---|---|---|---|
2 | 1 | equemene | * |
3 | 1 | equemene | * -- LAPACK auxiliary routine (version 3.2) -- |
4 | 1 | equemene | * -- LAPACK is a software package provided by Univ. of Tennessee, -- |
5 | 1 | equemene | * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- |
6 | 1 | equemene | * November 2006 |
7 | 1 | equemene | * |
8 | 1 | equemene | * .. Scalar Arguments .. |
9 | 1 | equemene | INTEGER J, JOB |
10 | 1 | equemene | DOUBLE PRECISION C, GAMMA, S, SEST, SESTPR |
11 | 1 | equemene | * .. |
12 | 1 | equemene | * .. Array Arguments .. |
13 | 1 | equemene | DOUBLE PRECISION W( J ), X( J ) |
14 | 1 | equemene | * .. |
15 | 1 | equemene | * |
16 | 1 | equemene | * Purpose |
17 | 1 | equemene | * ======= |
18 | 1 | equemene | * |
19 | 1 | equemene | * DLAIC1 applies one step of incremental condition estimation in |
20 | 1 | equemene | * its simplest version: |
21 | 1 | equemene | * |
22 | 1 | equemene | * Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j |
23 | 1 | equemene | * lower triangular matrix L, such that |
24 | 1 | equemene | * twonorm(L*x) = sest |
25 | 1 | equemene | * Then DLAIC1 computes sestpr, s, c such that |
26 | 1 | equemene | * the vector |
27 | 1 | equemene | * [ s*x ] |
28 | 1 | equemene | * xhat = [ c ] |
29 | 1 | equemene | * is an approximate singular vector of |
30 | 1 | equemene | * [ L 0 ] |
31 | 1 | equemene | * Lhat = [ w' gamma ] |
32 | 1 | equemene | * in the sense that |
33 | 1 | equemene | * twonorm(Lhat*xhat) = sestpr. |
34 | 1 | equemene | * |
35 | 1 | equemene | * Depending on JOB, an estimate for the largest or smallest singular |
36 | 1 | equemene | * value is computed. |
37 | 1 | equemene | * |
38 | 1 | equemene | * Note that [s c]' and sestpr**2 is an eigenpair of the system |
39 | 1 | equemene | * |
40 | 1 | equemene | * diag(sest*sest, 0) + [alpha gamma] * [ alpha ] |
41 | 1 | equemene | * [ gamma ] |
42 | 1 | equemene | * |
43 | 1 | equemene | * where alpha = x'*w. |
44 | 1 | equemene | * |
45 | 1 | equemene | * Arguments |
46 | 1 | equemene | * ========= |
47 | 1 | equemene | * |
48 | 1 | equemene | * JOB (input) INTEGER |
49 | 1 | equemene | * = 1: an estimate for the largest singular value is computed. |
50 | 1 | equemene | * = 2: an estimate for the smallest singular value is computed. |
51 | 1 | equemene | * |
52 | 1 | equemene | * J (input) INTEGER |
53 | 1 | equemene | * Length of X and W |
54 | 1 | equemene | * |
55 | 1 | equemene | * X (input) DOUBLE PRECISION array, dimension (J) |
56 | 1 | equemene | * The j-vector x. |
57 | 1 | equemene | * |
58 | 1 | equemene | * SEST (input) DOUBLE PRECISION |
59 | 1 | equemene | * Estimated singular value of j by j matrix L |
60 | 1 | equemene | * |
61 | 1 | equemene | * W (input) DOUBLE PRECISION array, dimension (J) |
62 | 1 | equemene | * The j-vector w. |
63 | 1 | equemene | * |
64 | 1 | equemene | * GAMMA (input) DOUBLE PRECISION |
65 | 1 | equemene | * The diagonal element gamma. |
66 | 1 | equemene | * |
67 | 1 | equemene | * SESTPR (output) DOUBLE PRECISION |
68 | 1 | equemene | * Estimated singular value of (j+1) by (j+1) matrix Lhat. |
69 | 1 | equemene | * |
70 | 1 | equemene | * S (output) DOUBLE PRECISION |
71 | 1 | equemene | * Sine needed in forming xhat. |
72 | 1 | equemene | * |
73 | 1 | equemene | * C (output) DOUBLE PRECISION |
74 | 1 | equemene | * Cosine needed in forming xhat. |
75 | 1 | equemene | * |
76 | 1 | equemene | * ===================================================================== |
77 | 1 | equemene | * |
78 | 1 | equemene | * .. Parameters .. |
79 | 1 | equemene | DOUBLE PRECISION ZERO, ONE, TWO |
80 | 1 | equemene | PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 ) |
81 | 1 | equemene | DOUBLE PRECISION HALF, FOUR |
82 | 1 | equemene | PARAMETER ( HALF = 0.5D0, FOUR = 4.0D0 ) |
83 | 1 | equemene | * .. |
84 | 1 | equemene | * .. Local Scalars .. |
85 | 1 | equemene | DOUBLE PRECISION ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS, |
86 | 1 | equemene | $ NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2 |
87 | 1 | equemene | * .. |
88 | 1 | equemene | * .. Intrinsic Functions .. |
89 | 1 | equemene | INTRINSIC ABS, MAX, SIGN, SQRT |
90 | 1 | equemene | * .. |
91 | 1 | equemene | * .. External Functions .. |
92 | 1 | equemene | DOUBLE PRECISION DDOT, DLAMCH |
93 | 1 | equemene | EXTERNAL DDOT, DLAMCH |
94 | 1 | equemene | * .. |
95 | 1 | equemene | * .. Executable Statements .. |
96 | 1 | equemene | * |
97 | 1 | equemene | EPS = DLAMCH( 'Epsilon' ) |
98 | 1 | equemene | ALPHA = DDOT( J, X, 1, W, 1 ) |
99 | 1 | equemene | * |
100 | 1 | equemene | ABSALP = ABS( ALPHA ) |
101 | 1 | equemene | ABSGAM = ABS( GAMMA ) |
102 | 1 | equemene | ABSEST = ABS( SEST ) |
103 | 1 | equemene | * |
104 | 1 | equemene | IF( JOB.EQ.1 ) THEN |
105 | 1 | equemene | * |
106 | 1 | equemene | * Estimating largest singular value |
107 | 1 | equemene | * |
108 | 1 | equemene | * special cases |
109 | 1 | equemene | * |
110 | 1 | equemene | IF( SEST.EQ.ZERO ) THEN |
111 | 1 | equemene | S1 = MAX( ABSGAM, ABSALP ) |
112 | 1 | equemene | IF( S1.EQ.ZERO ) THEN |
113 | 1 | equemene | S = ZERO |
114 | 1 | equemene | C = ONE |
115 | 1 | equemene | SESTPR = ZERO |
116 | 1 | equemene | ELSE |
117 | 1 | equemene | S = ALPHA / S1 |
118 | 1 | equemene | C = GAMMA / S1 |
119 | 1 | equemene | TMP = SQRT( S*S+C*C ) |
120 | 1 | equemene | S = S / TMP |
121 | 1 | equemene | C = C / TMP |
122 | 1 | equemene | SESTPR = S1*TMP |
123 | 1 | equemene | END IF |
124 | 1 | equemene | RETURN |
125 | 1 | equemene | ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN |
126 | 1 | equemene | S = ONE |
127 | 1 | equemene | C = ZERO |
128 | 1 | equemene | TMP = MAX( ABSEST, ABSALP ) |
129 | 1 | equemene | S1 = ABSEST / TMP |
130 | 1 | equemene | S2 = ABSALP / TMP |
131 | 1 | equemene | SESTPR = TMP*SQRT( S1*S1+S2*S2 ) |
132 | 1 | equemene | RETURN |
133 | 1 | equemene | ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN |
134 | 1 | equemene | S1 = ABSGAM |
135 | 1 | equemene | S2 = ABSEST |
136 | 1 | equemene | IF( S1.LE.S2 ) THEN |
137 | 1 | equemene | S = ONE |
138 | 1 | equemene | C = ZERO |
139 | 1 | equemene | SESTPR = S2 |
140 | 1 | equemene | ELSE |
141 | 1 | equemene | S = ZERO |
142 | 1 | equemene | C = ONE |
143 | 1 | equemene | SESTPR = S1 |
144 | 1 | equemene | END IF |
145 | 1 | equemene | RETURN |
146 | 1 | equemene | ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN |
147 | 1 | equemene | S1 = ABSGAM |
148 | 1 | equemene | S2 = ABSALP |
149 | 1 | equemene | IF( S1.LE.S2 ) THEN |
150 | 1 | equemene | TMP = S1 / S2 |
151 | 1 | equemene | S = SQRT( ONE+TMP*TMP ) |
152 | 1 | equemene | SESTPR = S2*S |
153 | 1 | equemene | C = ( GAMMA / S2 ) / S |
154 | 1 | equemene | S = SIGN( ONE, ALPHA ) / S |
155 | 1 | equemene | ELSE |
156 | 1 | equemene | TMP = S2 / S1 |
157 | 1 | equemene | C = SQRT( ONE+TMP*TMP ) |
158 | 1 | equemene | SESTPR = S1*C |
159 | 1 | equemene | S = ( ALPHA / S1 ) / C |
160 | 1 | equemene | C = SIGN( ONE, GAMMA ) / C |
161 | 1 | equemene | END IF |
162 | 1 | equemene | RETURN |
163 | 1 | equemene | ELSE |
164 | 1 | equemene | * |
165 | 1 | equemene | * normal case |
166 | 1 | equemene | * |
167 | 1 | equemene | ZETA1 = ALPHA / ABSEST |
168 | 1 | equemene | ZETA2 = GAMMA / ABSEST |
169 | 1 | equemene | * |
170 | 1 | equemene | B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF |
171 | 1 | equemene | C = ZETA1*ZETA1 |
172 | 1 | equemene | IF( B.GT.ZERO ) THEN |
173 | 1 | equemene | T = C / ( B+SQRT( B*B+C ) ) |
174 | 1 | equemene | ELSE |
175 | 1 | equemene | T = SQRT( B*B+C ) - B |
176 | 1 | equemene | END IF |
177 | 1 | equemene | * |
178 | 1 | equemene | SINE = -ZETA1 / T |
179 | 1 | equemene | COSINE = -ZETA2 / ( ONE+T ) |
180 | 1 | equemene | TMP = SQRT( SINE*SINE+COSINE*COSINE ) |
181 | 1 | equemene | S = SINE / TMP |
182 | 1 | equemene | C = COSINE / TMP |
183 | 1 | equemene | SESTPR = SQRT( T+ONE )*ABSEST |
184 | 1 | equemene | RETURN |
185 | 1 | equemene | END IF |
186 | 1 | equemene | * |
187 | 1 | equemene | ELSE IF( JOB.EQ.2 ) THEN |
188 | 1 | equemene | * |
189 | 1 | equemene | * Estimating smallest singular value |
190 | 1 | equemene | * |
191 | 1 | equemene | * special cases |
192 | 1 | equemene | * |
193 | 1 | equemene | IF( SEST.EQ.ZERO ) THEN |
194 | 1 | equemene | SESTPR = ZERO |
195 | 1 | equemene | IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN |
196 | 1 | equemene | SINE = ONE |
197 | 1 | equemene | COSINE = ZERO |
198 | 1 | equemene | ELSE |
199 | 1 | equemene | SINE = -GAMMA |
200 | 1 | equemene | COSINE = ALPHA |
201 | 1 | equemene | END IF |
202 | 1 | equemene | S1 = MAX( ABS( SINE ), ABS( COSINE ) ) |
203 | 1 | equemene | S = SINE / S1 |
204 | 1 | equemene | C = COSINE / S1 |
205 | 1 | equemene | TMP = SQRT( S*S+C*C ) |
206 | 1 | equemene | S = S / TMP |
207 | 1 | equemene | C = C / TMP |
208 | 1 | equemene | RETURN |
209 | 1 | equemene | ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN |
210 | 1 | equemene | S = ZERO |
211 | 1 | equemene | C = ONE |
212 | 1 | equemene | SESTPR = ABSGAM |
213 | 1 | equemene | RETURN |
214 | 1 | equemene | ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN |
215 | 1 | equemene | S1 = ABSGAM |
216 | 1 | equemene | S2 = ABSEST |
217 | 1 | equemene | IF( S1.LE.S2 ) THEN |
218 | 1 | equemene | S = ZERO |
219 | 1 | equemene | C = ONE |
220 | 1 | equemene | SESTPR = S1 |
221 | 1 | equemene | ELSE |
222 | 1 | equemene | S = ONE |
223 | 1 | equemene | C = ZERO |
224 | 1 | equemene | SESTPR = S2 |
225 | 1 | equemene | END IF |
226 | 1 | equemene | RETURN |
227 | 1 | equemene | ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN |
228 | 1 | equemene | S1 = ABSGAM |
229 | 1 | equemene | S2 = ABSALP |
230 | 1 | equemene | IF( S1.LE.S2 ) THEN |
231 | 1 | equemene | TMP = S1 / S2 |
232 | 1 | equemene | C = SQRT( ONE+TMP*TMP ) |
233 | 1 | equemene | SESTPR = ABSEST*( TMP / C ) |
234 | 1 | equemene | S = -( GAMMA / S2 ) / C |
235 | 1 | equemene | C = SIGN( ONE, ALPHA ) / C |
236 | 1 | equemene | ELSE |
237 | 1 | equemene | TMP = S2 / S1 |
238 | 1 | equemene | S = SQRT( ONE+TMP*TMP ) |
239 | 1 | equemene | SESTPR = ABSEST / S |
240 | 1 | equemene | C = ( ALPHA / S1 ) / S |
241 | 1 | equemene | S = -SIGN( ONE, GAMMA ) / S |
242 | 1 | equemene | END IF |
243 | 1 | equemene | RETURN |
244 | 1 | equemene | ELSE |
245 | 1 | equemene | * |
246 | 1 | equemene | * normal case |
247 | 1 | equemene | * |
248 | 1 | equemene | ZETA1 = ALPHA / ABSEST |
249 | 1 | equemene | ZETA2 = GAMMA / ABSEST |
250 | 1 | equemene | * |
251 | 1 | equemene | NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ), |
252 | 1 | equemene | $ ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 ) |
253 | 1 | equemene | * |
254 | 1 | equemene | * See if root is closer to zero or to ONE |
255 | 1 | equemene | * |
256 | 1 | equemene | TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 ) |
257 | 1 | equemene | IF( TEST.GE.ZERO ) THEN |
258 | 1 | equemene | * |
259 | 1 | equemene | * root is close to zero, compute directly |
260 | 1 | equemene | * |
261 | 1 | equemene | B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF |
262 | 1 | equemene | C = ZETA2*ZETA2 |
263 | 1 | equemene | T = C / ( B+SQRT( ABS( B*B-C ) ) ) |
264 | 1 | equemene | SINE = ZETA1 / ( ONE-T ) |
265 | 1 | equemene | COSINE = -ZETA2 / T |
266 | 1 | equemene | SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST |
267 | 1 | equemene | ELSE |
268 | 1 | equemene | * |
269 | 1 | equemene | * root is closer to ONE, shift by that amount |
270 | 1 | equemene | * |
271 | 1 | equemene | B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF |
272 | 1 | equemene | C = ZETA1*ZETA1 |
273 | 1 | equemene | IF( B.GE.ZERO ) THEN |
274 | 1 | equemene | T = -C / ( B+SQRT( B*B+C ) ) |
275 | 1 | equemene | ELSE |
276 | 1 | equemene | T = B - SQRT( B*B+C ) |
277 | 1 | equemene | END IF |
278 | 1 | equemene | SINE = -ZETA1 / T |
279 | 1 | equemene | COSINE = -ZETA2 / ( ONE+T ) |
280 | 1 | equemene | SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST |
281 | 1 | equemene | END IF |
282 | 1 | equemene | TMP = SQRT( SINE*SINE+COSINE*COSINE ) |
283 | 1 | equemene | S = SINE / TMP |
284 | 1 | equemene | C = COSINE / TMP |
285 | 1 | equemene | RETURN |
286 | 1 | equemene | * |
287 | 1 | equemene | END IF |
288 | 1 | equemene | END IF |
289 | 1 | equemene | RETURN |
290 | 1 | equemene | * |
291 | 1 | equemene | * End of DLAIC1 |
292 | 1 | equemene | * |
293 | 1 | equemene | END |