Statistiques
| Révision :

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