Statistiques
| Révision :

root / src / lapack / double / dlasq2.f @ 1

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