root / src / lapack / double / dlasq2.f @ 7
Historique | Voir | Annoter | Télécharger (14,15 ko)
1 |
SUBROUTINE DLASQ2( N, Z, INFO ) |
---|---|
2 |
* |
3 |
* -- LAPACK routine (version 3.2) -- |
4 |
* |
5 |
* -- Contributed by Osni Marques of the Lawrence Berkeley National -- |
6 |
* -- Laboratory and Beresford Parlett of the Univ. of California at -- |
7 |
* -- Berkeley -- |
8 |
* -- November 2008 -- |
9 |
* |
10 |
* -- LAPACK is a software package provided by Univ. of Tennessee, -- |
11 |
* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- |
12 |
* |
13 |
* .. Scalar Arguments .. |
14 |
INTEGER INFO, N |
15 |
* .. |
16 |
* .. Array Arguments .. |
17 |
DOUBLE PRECISION Z( * ) |
18 |
* .. |
19 |
* |
20 |
* Purpose |
21 |
* ======= |
22 |
* |
23 |
* DLASQ2 computes all the eigenvalues of the symmetric positive |
24 |
* definite tridiagonal matrix associated with the qd array Z to high |
25 |
* relative accuracy are computed to high relative accuracy, in the |
26 |
* absence of denormalization, underflow and overflow. |
27 |
* |
28 |
* To see the relation of Z to the tridiagonal matrix, let L be a |
29 |
* unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and |
30 |
* let U be an upper bidiagonal matrix with 1's above and diagonal |
31 |
* Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the |
32 |
* symmetric tridiagonal to which it is similar. |
33 |
* |
34 |
* Note : DLASQ2 defines a logical variable, IEEE, which is true |
35 |
* on machines which follow ieee-754 floating-point standard in their |
36 |
* handling of infinities and NaNs, and false otherwise. This variable |
37 |
* is passed to DLASQ3. |
38 |
* |
39 |
* Arguments |
40 |
* ========= |
41 |
* |
42 |
* N (input) INTEGER |
43 |
* The number of rows and columns in the matrix. N >= 0. |
44 |
* |
45 |
* Z (input/output) DOUBLE PRECISION array, dimension ( 4*N ) |
46 |
* On entry Z holds the qd array. On exit, entries 1 to N hold |
47 |
* the eigenvalues in decreasing order, Z( 2*N+1 ) holds the |
48 |
* trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If |
49 |
* N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 ) |
50 |
* holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of |
51 |
* shifts that failed. |
52 |
* |
53 |
* INFO (output) INTEGER |
54 |
* = 0: successful exit |
55 |
* < 0: if the i-th argument is a scalar and had an illegal |
56 |
* value, then INFO = -i, if the i-th argument is an |
57 |
* array and the j-entry had an illegal value, then |
58 |
* INFO = -(i*100+j) |
59 |
* > 0: the algorithm failed |
60 |
* = 1, a split was marked by a positive value in E |
61 |
* = 2, current block of Z not diagonalized after 30*N |
62 |
* iterations (in inner while loop) |
63 |
* = 3, termination criterion of outer while loop not met |
64 |
* (program created more than N unreduced blocks) |
65 |
* |
66 |
* Further Details |
67 |
* =============== |
68 |
* Local Variables: I0:N0 defines a current unreduced segment of Z. |
69 |
* The shifts are accumulated in SIGMA. Iteration count is in ITER. |
70 |
* Ping-pong is controlled by PP (alternates between 0 and 1). |
71 |
* |
72 |
* ===================================================================== |
73 |
* |
74 |
* .. Parameters .. |
75 |
DOUBLE PRECISION CBIAS |
76 |
PARAMETER ( CBIAS = 1.50D0 ) |
77 |
DOUBLE PRECISION ZERO, HALF, ONE, TWO, FOUR, HUNDRD |
78 |
PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0, |
79 |
$ TWO = 2.0D0, FOUR = 4.0D0, HUNDRD = 100.0D0 ) |
80 |
* .. |
81 |
* .. Local Scalars .. |
82 |
LOGICAL IEEE |
83 |
INTEGER I0, I4, IINFO, IPN4, ITER, IWHILA, IWHILB, K, |
84 |
$ KMIN, N0, NBIG, NDIV, NFAIL, PP, SPLT, TTYPE |
85 |
DOUBLE PRECISION D, DEE, DEEMIN, DESIG, DMIN, DMIN1, DMIN2, DN, |
86 |
$ DN1, DN2, E, EMAX, EMIN, EPS, G, OLDEMN, QMAX, |
87 |
$ QMIN, S, SAFMIN, SIGMA, T, TAU, TEMP, TOL, |
88 |
$ TOL2, TRACE, ZMAX |
89 |
* .. |
90 |
* .. External Subroutines .. |
91 |
EXTERNAL DLASQ3, DLASRT, XERBLA |
92 |
* .. |
93 |
* .. External Functions .. |
94 |
INTEGER ILAENV |
95 |
DOUBLE PRECISION DLAMCH |
96 |
EXTERNAL DLAMCH, ILAENV |
97 |
* .. |
98 |
* .. Intrinsic Functions .. |
99 |
INTRINSIC ABS, DBLE, MAX, MIN, SQRT |
100 |
* .. |
101 |
* .. Executable Statements .. |
102 |
* |
103 |
* Test the input arguments. |
104 |
* (in case DLASQ2 is not called by DLASQ1) |
105 |
* |
106 |
INFO = 0 |
107 |
EPS = DLAMCH( 'Precision' ) |
108 |
SAFMIN = DLAMCH( 'Safe minimum' ) |
109 |
TOL = EPS*HUNDRD |
110 |
TOL2 = TOL**2 |
111 |
* |
112 |
IF( N.LT.0 ) THEN |
113 |
INFO = -1 |
114 |
CALL XERBLA( 'DLASQ2', 1 ) |
115 |
RETURN |
116 |
ELSE IF( N.EQ.0 ) THEN |
117 |
RETURN |
118 |
ELSE IF( N.EQ.1 ) THEN |
119 |
* |
120 |
* 1-by-1 case. |
121 |
* |
122 |
IF( Z( 1 ).LT.ZERO ) THEN |
123 |
INFO = -201 |
124 |
CALL XERBLA( 'DLASQ2', 2 ) |
125 |
END IF |
126 |
RETURN |
127 |
ELSE IF( N.EQ.2 ) THEN |
128 |
* |
129 |
* 2-by-2 case. |
130 |
* |
131 |
IF( Z( 2 ).LT.ZERO .OR. Z( 3 ).LT.ZERO ) THEN |
132 |
INFO = -2 |
133 |
CALL XERBLA( 'DLASQ2', 2 ) |
134 |
RETURN |
135 |
ELSE IF( Z( 3 ).GT.Z( 1 ) ) THEN |
136 |
D = Z( 3 ) |
137 |
Z( 3 ) = Z( 1 ) |
138 |
Z( 1 ) = D |
139 |
END IF |
140 |
Z( 5 ) = Z( 1 ) + Z( 2 ) + Z( 3 ) |
141 |
IF( Z( 2 ).GT.Z( 3 )*TOL2 ) THEN |
142 |
T = HALF*( ( Z( 1 )-Z( 3 ) )+Z( 2 ) ) |
143 |
S = Z( 3 )*( Z( 2 ) / T ) |
144 |
IF( S.LE.T ) THEN |
145 |
S = Z( 3 )*( Z( 2 ) / ( T*( ONE+SQRT( ONE+S / T ) ) ) ) |
146 |
ELSE |
147 |
S = Z( 3 )*( Z( 2 ) / ( T+SQRT( T )*SQRT( T+S ) ) ) |
148 |
END IF |
149 |
T = Z( 1 ) + ( S+Z( 2 ) ) |
150 |
Z( 3 ) = Z( 3 )*( Z( 1 ) / T ) |
151 |
Z( 1 ) = T |
152 |
END IF |
153 |
Z( 2 ) = Z( 3 ) |
154 |
Z( 6 ) = Z( 2 ) + Z( 1 ) |
155 |
RETURN |
156 |
END IF |
157 |
* |
158 |
* Check for negative data and compute sums of q's and e's. |
159 |
* |
160 |
Z( 2*N ) = ZERO |
161 |
EMIN = Z( 2 ) |
162 |
QMAX = ZERO |
163 |
ZMAX = ZERO |
164 |
D = ZERO |
165 |
E = ZERO |
166 |
* |
167 |
DO 10 K = 1, 2*( N-1 ), 2 |
168 |
IF( Z( K ).LT.ZERO ) THEN |
169 |
INFO = -( 200+K ) |
170 |
CALL XERBLA( 'DLASQ2', 2 ) |
171 |
RETURN |
172 |
ELSE IF( Z( K+1 ).LT.ZERO ) THEN |
173 |
INFO = -( 200+K+1 ) |
174 |
CALL XERBLA( 'DLASQ2', 2 ) |
175 |
RETURN |
176 |
END IF |
177 |
D = D + Z( K ) |
178 |
E = E + Z( K+1 ) |
179 |
QMAX = MAX( QMAX, Z( K ) ) |
180 |
EMIN = MIN( EMIN, Z( K+1 ) ) |
181 |
ZMAX = MAX( QMAX, ZMAX, Z( K+1 ) ) |
182 |
10 CONTINUE |
183 |
IF( Z( 2*N-1 ).LT.ZERO ) THEN |
184 |
INFO = -( 200+2*N-1 ) |
185 |
CALL XERBLA( 'DLASQ2', 2 ) |
186 |
RETURN |
187 |
END IF |
188 |
D = D + Z( 2*N-1 ) |
189 |
QMAX = MAX( QMAX, Z( 2*N-1 ) ) |
190 |
ZMAX = MAX( QMAX, ZMAX ) |
191 |
* |
192 |
* Check for diagonality. |
193 |
* |
194 |
IF( E.EQ.ZERO ) THEN |
195 |
DO 20 K = 2, N |
196 |
Z( K ) = Z( 2*K-1 ) |
197 |
20 CONTINUE |
198 |
CALL DLASRT( 'D', N, Z, IINFO ) |
199 |
Z( 2*N-1 ) = D |
200 |
RETURN |
201 |
END IF |
202 |
* |
203 |
TRACE = D + E |
204 |
* |
205 |
* Check for zero data. |
206 |
* |
207 |
IF( TRACE.EQ.ZERO ) THEN |
208 |
Z( 2*N-1 ) = ZERO |
209 |
RETURN |
210 |
END IF |
211 |
* |
212 |
* Check whether the machine is IEEE conformable. |
213 |
* |
214 |
IEEE = ILAENV( 10, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 .AND. |
215 |
$ ILAENV( 11, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 |
216 |
* |
217 |
* Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...). |
218 |
* |
219 |
DO 30 K = 2*N, 2, -2 |
220 |
Z( 2*K ) = ZERO |
221 |
Z( 2*K-1 ) = Z( K ) |
222 |
Z( 2*K-2 ) = ZERO |
223 |
Z( 2*K-3 ) = Z( K-1 ) |
224 |
30 CONTINUE |
225 |
* |
226 |
I0 = 1 |
227 |
N0 = N |
228 |
* |
229 |
* Reverse the qd-array, if warranted. |
230 |
* |
231 |
IF( CBIAS*Z( 4*I0-3 ).LT.Z( 4*N0-3 ) ) THEN |
232 |
IPN4 = 4*( I0+N0 ) |
233 |
DO 40 I4 = 4*I0, 2*( I0+N0-1 ), 4 |
234 |
TEMP = Z( I4-3 ) |
235 |
Z( I4-3 ) = Z( IPN4-I4-3 ) |
236 |
Z( IPN4-I4-3 ) = TEMP |
237 |
TEMP = Z( I4-1 ) |
238 |
Z( I4-1 ) = Z( IPN4-I4-5 ) |
239 |
Z( IPN4-I4-5 ) = TEMP |
240 |
40 CONTINUE |
241 |
END IF |
242 |
* |
243 |
* Initial split checking via dqd and Li's test. |
244 |
* |
245 |
PP = 0 |
246 |
* |
247 |
DO 80 K = 1, 2 |
248 |
* |
249 |
D = Z( 4*N0+PP-3 ) |
250 |
DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4 |
251 |
IF( Z( I4-1 ).LE.TOL2*D ) THEN |
252 |
Z( I4-1 ) = -ZERO |
253 |
D = Z( I4-3 ) |
254 |
ELSE |
255 |
D = Z( I4-3 )*( D / ( D+Z( I4-1 ) ) ) |
256 |
END IF |
257 |
50 CONTINUE |
258 |
* |
259 |
* dqd maps Z to ZZ plus Li's test. |
260 |
* |
261 |
EMIN = Z( 4*I0+PP+1 ) |
262 |
D = Z( 4*I0+PP-3 ) |
263 |
DO 60 I4 = 4*I0 + PP, 4*( N0-1 ) + PP, 4 |
264 |
Z( I4-2*PP-2 ) = D + Z( I4-1 ) |
265 |
IF( Z( I4-1 ).LE.TOL2*D ) THEN |
266 |
Z( I4-1 ) = -ZERO |
267 |
Z( I4-2*PP-2 ) = D |
268 |
Z( I4-2*PP ) = ZERO |
269 |
D = Z( I4+1 ) |
270 |
ELSE IF( SAFMIN*Z( I4+1 ).LT.Z( I4-2*PP-2 ) .AND. |
271 |
$ SAFMIN*Z( I4-2*PP-2 ).LT.Z( I4+1 ) ) THEN |
272 |
TEMP = Z( I4+1 ) / Z( I4-2*PP-2 ) |
273 |
Z( I4-2*PP ) = Z( I4-1 )*TEMP |
274 |
D = D*TEMP |
275 |
ELSE |
276 |
Z( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) / Z( I4-2*PP-2 ) ) |
277 |
D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) ) |
278 |
END IF |
279 |
EMIN = MIN( EMIN, Z( I4-2*PP ) ) |
280 |
60 CONTINUE |
281 |
Z( 4*N0-PP-2 ) = D |
282 |
* |
283 |
* Now find qmax. |
284 |
* |
285 |
QMAX = Z( 4*I0-PP-2 ) |
286 |
DO 70 I4 = 4*I0 - PP + 2, 4*N0 - PP - 2, 4 |
287 |
QMAX = MAX( QMAX, Z( I4 ) ) |
288 |
70 CONTINUE |
289 |
* |
290 |
* Prepare for the next iteration on K. |
291 |
* |
292 |
PP = 1 - PP |
293 |
80 CONTINUE |
294 |
* |
295 |
* Initialise variables to pass to DLASQ3. |
296 |
* |
297 |
TTYPE = 0 |
298 |
DMIN1 = ZERO |
299 |
DMIN2 = ZERO |
300 |
DN = ZERO |
301 |
DN1 = ZERO |
302 |
DN2 = ZERO |
303 |
G = ZERO |
304 |
TAU = ZERO |
305 |
* |
306 |
ITER = 2 |
307 |
NFAIL = 0 |
308 |
NDIV = 2*( N0-I0 ) |
309 |
* |
310 |
DO 160 IWHILA = 1, N + 1 |
311 |
IF( N0.LT.1 ) |
312 |
$ GO TO 170 |
313 |
* |
314 |
* While array unfinished do |
315 |
* |
316 |
* E(N0) holds the value of SIGMA when submatrix in I0:N0 |
317 |
* splits from the rest of the array, but is negated. |
318 |
* |
319 |
DESIG = ZERO |
320 |
IF( N0.EQ.N ) THEN |
321 |
SIGMA = ZERO |
322 |
ELSE |
323 |
SIGMA = -Z( 4*N0-1 ) |
324 |
END IF |
325 |
IF( SIGMA.LT.ZERO ) THEN |
326 |
INFO = 1 |
327 |
RETURN |
328 |
END IF |
329 |
* |
330 |
* Find last unreduced submatrix's top index I0, find QMAX and |
331 |
* EMIN. Find Gershgorin-type bound if Q's much greater than E's. |
332 |
* |
333 |
EMAX = ZERO |
334 |
IF( N0.GT.I0 ) THEN |
335 |
EMIN = ABS( Z( 4*N0-5 ) ) |
336 |
ELSE |
337 |
EMIN = ZERO |
338 |
END IF |
339 |
QMIN = Z( 4*N0-3 ) |
340 |
QMAX = QMIN |
341 |
DO 90 I4 = 4*N0, 8, -4 |
342 |
IF( Z( I4-5 ).LE.ZERO ) |
343 |
$ GO TO 100 |
344 |
IF( QMIN.GE.FOUR*EMAX ) THEN |
345 |
QMIN = MIN( QMIN, Z( I4-3 ) ) |
346 |
EMAX = MAX( EMAX, Z( I4-5 ) ) |
347 |
END IF |
348 |
QMAX = MAX( QMAX, Z( I4-7 )+Z( I4-5 ) ) |
349 |
EMIN = MIN( EMIN, Z( I4-5 ) ) |
350 |
90 CONTINUE |
351 |
I4 = 4 |
352 |
* |
353 |
100 CONTINUE |
354 |
I0 = I4 / 4 |
355 |
PP = 0 |
356 |
* |
357 |
IF( N0-I0.GT.1 ) THEN |
358 |
DEE = Z( 4*I0-3 ) |
359 |
DEEMIN = DEE |
360 |
KMIN = I0 |
361 |
DO 110 I4 = 4*I0+1, 4*N0-3, 4 |
362 |
DEE = Z( I4 )*( DEE /( DEE+Z( I4-2 ) ) ) |
363 |
IF( DEE.LE.DEEMIN ) THEN |
364 |
DEEMIN = DEE |
365 |
KMIN = ( I4+3 )/4 |
366 |
END IF |
367 |
110 CONTINUE |
368 |
IF( (KMIN-I0)*2.LT.N0-KMIN .AND. |
369 |
$ DEEMIN.LE.HALF*Z(4*N0-3) ) THEN |
370 |
IPN4 = 4*( I0+N0 ) |
371 |
PP = 2 |
372 |
DO 120 I4 = 4*I0, 2*( I0+N0-1 ), 4 |
373 |
TEMP = Z( I4-3 ) |
374 |
Z( I4-3 ) = Z( IPN4-I4-3 ) |
375 |
Z( IPN4-I4-3 ) = TEMP |
376 |
TEMP = Z( I4-2 ) |
377 |
Z( I4-2 ) = Z( IPN4-I4-2 ) |
378 |
Z( IPN4-I4-2 ) = TEMP |
379 |
TEMP = Z( I4-1 ) |
380 |
Z( I4-1 ) = Z( IPN4-I4-5 ) |
381 |
Z( IPN4-I4-5 ) = TEMP |
382 |
TEMP = Z( I4 ) |
383 |
Z( I4 ) = Z( IPN4-I4-4 ) |
384 |
Z( IPN4-I4-4 ) = TEMP |
385 |
120 CONTINUE |
386 |
END IF |
387 |
END IF |
388 |
* |
389 |
* Put -(initial shift) into DMIN. |
390 |
* |
391 |
DMIN = -MAX( ZERO, QMIN-TWO*SQRT( QMIN )*SQRT( EMAX ) ) |
392 |
* |
393 |
* Now I0:N0 is unreduced. |
394 |
* PP = 0 for ping, PP = 1 for pong. |
395 |
* PP = 2 indicates that flipping was applied to the Z array and |
396 |
* and that the tests for deflation upon entry in DLASQ3 |
397 |
* should not be performed. |
398 |
* |
399 |
NBIG = 30*( N0-I0+1 ) |
400 |
DO 140 IWHILB = 1, NBIG |
401 |
IF( I0.GT.N0 ) |
402 |
$ GO TO 150 |
403 |
* |
404 |
* While submatrix unfinished take a good dqds step. |
405 |
* |
406 |
CALL DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL, |
407 |
$ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1, |
408 |
$ DN2, G, TAU ) |
409 |
* |
410 |
PP = 1 - PP |
411 |
* |
412 |
* When EMIN is very small check for splits. |
413 |
* |
414 |
IF( PP.EQ.0 .AND. N0-I0.GE.3 ) THEN |
415 |
IF( Z( 4*N0 ).LE.TOL2*QMAX .OR. |
416 |
$ Z( 4*N0-1 ).LE.TOL2*SIGMA ) THEN |
417 |
SPLT = I0 - 1 |
418 |
QMAX = Z( 4*I0-3 ) |
419 |
EMIN = Z( 4*I0-1 ) |
420 |
OLDEMN = Z( 4*I0 ) |
421 |
DO 130 I4 = 4*I0, 4*( N0-3 ), 4 |
422 |
IF( Z( I4 ).LE.TOL2*Z( I4-3 ) .OR. |
423 |
$ Z( I4-1 ).LE.TOL2*SIGMA ) THEN |
424 |
Z( I4-1 ) = -SIGMA |
425 |
SPLT = I4 / 4 |
426 |
QMAX = ZERO |
427 |
EMIN = Z( I4+3 ) |
428 |
OLDEMN = Z( I4+4 ) |
429 |
ELSE |
430 |
QMAX = MAX( QMAX, Z( I4+1 ) ) |
431 |
EMIN = MIN( EMIN, Z( I4-1 ) ) |
432 |
OLDEMN = MIN( OLDEMN, Z( I4 ) ) |
433 |
END IF |
434 |
130 CONTINUE |
435 |
Z( 4*N0-1 ) = EMIN |
436 |
Z( 4*N0 ) = OLDEMN |
437 |
I0 = SPLT + 1 |
438 |
END IF |
439 |
END IF |
440 |
* |
441 |
140 CONTINUE |
442 |
* |
443 |
INFO = 2 |
444 |
RETURN |
445 |
* |
446 |
* end IWHILB |
447 |
* |
448 |
150 CONTINUE |
449 |
* |
450 |
160 CONTINUE |
451 |
* |
452 |
INFO = 3 |
453 |
RETURN |
454 |
* |
455 |
* end IWHILA |
456 |
* |
457 |
170 CONTINUE |
458 |
* |
459 |
* Move q's to the front. |
460 |
* |
461 |
DO 180 K = 2, N |
462 |
Z( K ) = Z( 4*K-3 ) |
463 |
180 CONTINUE |
464 |
* |
465 |
* Sort and compute sum of eigenvalues. |
466 |
* |
467 |
CALL DLASRT( 'D', N, Z, IINFO ) |
468 |
* |
469 |
E = ZERO |
470 |
DO 190 K = N, 1, -1 |
471 |
E = E + Z( K ) |
472 |
190 CONTINUE |
473 |
* |
474 |
* Store trace, sum(eigenvalues) and information on performance. |
475 |
* |
476 |
Z( 2*N+1 ) = TRACE |
477 |
Z( 2*N+2 ) = E |
478 |
Z( 2*N+3 ) = DBLE( ITER ) |
479 |
Z( 2*N+4 ) = DBLE( NDIV ) / DBLE( N**2 ) |
480 |
Z( 2*N+5 ) = HUNDRD*NFAIL / DBLE( ITER ) |
481 |
RETURN |
482 |
* |
483 |
* End of DLASQ2 |
484 |
* |
485 |
END |