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