LAPACK  3.4.2
LAPACK: Linear Algebra PACKage
 All Files Functions Groups
dlasq2.f
Go to the documentation of this file.
1 *> \brief \b DLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated with the qd Array Z to high relative accuracy. Used by sbdsqr and sstegr.
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download DLASQ2 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq2.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq2.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq2.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE DLASQ2( N, Z, INFO )
22 *
23 * .. Scalar Arguments ..
24 * INTEGER INFO, N
25 * ..
26 * .. Array Arguments ..
27 * DOUBLE PRECISION Z( * )
28 * ..
29 *
30 *
31 *> \par Purpose:
32 * =============
33 *>
34 *> \verbatim
35 *>
36 *> DLASQ2 computes all the eigenvalues of the symmetric positive
37 *> definite tridiagonal matrix associated with the qd array Z to high
38 *> relative accuracy are computed to high relative accuracy, in the
39 *> absence of denormalization, underflow and overflow.
40 *>
41 *> To see the relation of Z to the tridiagonal matrix, let L be a
42 *> unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and
43 *> let U be an upper bidiagonal matrix with 1's above and diagonal
44 *> Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the
45 *> symmetric tridiagonal to which it is similar.
46 *>
47 *> Note : DLASQ2 defines a logical variable, IEEE, which is true
48 *> on machines which follow ieee-754 floating-point standard in their
49 *> handling of infinities and NaNs, and false otherwise. This variable
50 *> is passed to DLASQ3.
51 *> \endverbatim
52 *
53 * Arguments:
54 * ==========
55 *
56 *> \param[in] N
57 *> \verbatim
58 *> N is INTEGER
59 *> The number of rows and columns in the matrix. N >= 0.
60 *> \endverbatim
61 *>
62 *> \param[in,out] Z
63 *> \verbatim
64 *> Z is DOUBLE PRECISION array, dimension ( 4*N )
65 *> On entry Z holds the qd array. On exit, entries 1 to N hold
66 *> the eigenvalues in decreasing order, Z( 2*N+1 ) holds the
67 *> trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If
68 *> N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 )
69 *> holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of
70 *> shifts that failed.
71 *> \endverbatim
72 *>
73 *> \param[out] INFO
74 *> \verbatim
75 *> INFO is INTEGER
76 *> = 0: successful exit
77 *> < 0: if the i-th argument is a scalar and had an illegal
78 *> value, then INFO = -i, if the i-th argument is an
79 *> array and the j-entry had an illegal value, then
80 *> INFO = -(i*100+j)
81 *> > 0: the algorithm failed
82 *> = 1, a split was marked by a positive value in E
83 *> = 2, current block of Z not diagonalized after 100*N
84 *> iterations (in inner while loop). On exit Z holds
85 *> a qd array with the same eigenvalues as the given Z.
86 *> = 3, termination criterion of outer while loop not met
87 *> (program created more than N unreduced blocks)
88 *> \endverbatim
89 *
90 * Authors:
91 * ========
92 *
93 *> \author Univ. of Tennessee
94 *> \author Univ. of California Berkeley
95 *> \author Univ. of Colorado Denver
96 *> \author NAG Ltd.
97 *
98 *> \date September 2012
99 *
100 *> \ingroup auxOTHERcomputational
101 *
102 *> \par Further Details:
103 * =====================
104 *>
105 *> \verbatim
106 *>
107 *> Local Variables: I0:N0 defines a current unreduced segment of Z.
108 *> The shifts are accumulated in SIGMA. Iteration count is in ITER.
109 *> Ping-pong is controlled by PP (alternates between 0 and 1).
110 *> \endverbatim
111 *>
112 * =====================================================================
113  SUBROUTINE dlasq2( N, Z, INFO )
114 *
115 * -- LAPACK computational routine (version 3.4.2) --
116 * -- LAPACK is a software package provided by Univ. of Tennessee, --
117 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
118 * September 2012
119 *
120 * .. Scalar Arguments ..
121  INTEGER info, n
122 * ..
123 * .. Array Arguments ..
124  DOUBLE PRECISION z( * )
125 * ..
126 *
127 * =====================================================================
128 *
129 * .. Parameters ..
130  DOUBLE PRECISION cbias
131  parameter( cbias = 1.50d0 )
132  DOUBLE PRECISION zero, half, one, two, four, hundrd
133  parameter( zero = 0.0d0, half = 0.5d0, one = 1.0d0,
134  $ two = 2.0d0, four = 4.0d0, hundrd = 100.0d0 )
135 * ..
136 * .. Local Scalars ..
137  LOGICAL ieee
138  INTEGER i0, i1, i4, iinfo, ipn4, iter, iwhila, iwhilb,
139  $ k, kmin, n0, n1, nbig, ndiv, nfail, pp, splt,
140  $ ttype
141  DOUBLE PRECISION d, dee, deemin, desig, dmin, dmin1, dmin2, dn,
142  $ dn1, dn2, e, emax, emin, eps, g, oldemn, qmax,
143  $ qmin, s, safmin, sigma, t, tau, temp, tol,
144  $ tol2, trace, zmax, tempe, tempq
145 * ..
146 * .. External Subroutines ..
147  EXTERNAL dlasq3, dlasrt, xerbla
148 * ..
149 * .. External Functions ..
150  INTEGER ilaenv
151  DOUBLE PRECISION dlamch
152  EXTERNAL dlamch, ilaenv
153 * ..
154 * .. Intrinsic Functions ..
155  INTRINSIC abs, dble, max, min, sqrt
156 * ..
157 * .. Executable Statements ..
158 *
159 * Test the input arguments.
160 * (in case DLASQ2 is not called by DLASQ1)
161 *
162  info = 0
163  eps = dlamch( 'Precision' )
164  safmin = dlamch( 'Safe minimum' )
165  tol = eps*hundrd
166  tol2 = tol**2
167 *
168  IF( n.LT.0 ) THEN
169  info = -1
170  CALL xerbla( 'DLASQ2', 1 )
171  return
172  ELSE IF( n.EQ.0 ) THEN
173  return
174  ELSE IF( n.EQ.1 ) THEN
175 *
176 * 1-by-1 case.
177 *
178  IF( z( 1 ).LT.zero ) THEN
179  info = -201
180  CALL xerbla( 'DLASQ2', 2 )
181  END IF
182  return
183  ELSE IF( n.EQ.2 ) THEN
184 *
185 * 2-by-2 case.
186 *
187  IF( z( 2 ).LT.zero .OR. z( 3 ).LT.zero ) THEN
188  info = -2
189  CALL xerbla( 'DLASQ2', 2 )
190  return
191  ELSE IF( z( 3 ).GT.z( 1 ) ) THEN
192  d = z( 3 )
193  z( 3 ) = z( 1 )
194  z( 1 ) = d
195  END IF
196  z( 5 ) = z( 1 ) + z( 2 ) + z( 3 )
197  IF( z( 2 ).GT.z( 3 )*tol2 ) THEN
198  t = half*( ( z( 1 )-z( 3 ) )+z( 2 ) )
199  s = z( 3 )*( z( 2 ) / t )
200  IF( s.LE.t ) THEN
201  s = z( 3 )*( z( 2 ) / ( t*( one+sqrt( one+s / t ) ) ) )
202  ELSE
203  s = z( 3 )*( z( 2 ) / ( t+sqrt( t )*sqrt( t+s ) ) )
204  END IF
205  t = z( 1 ) + ( s+z( 2 ) )
206  z( 3 ) = z( 3 )*( z( 1 ) / t )
207  z( 1 ) = t
208  END IF
209  z( 2 ) = z( 3 )
210  z( 6 ) = z( 2 ) + z( 1 )
211  return
212  END IF
213 *
214 * Check for negative data and compute sums of q's and e's.
215 *
216  z( 2*n ) = zero
217  emin = z( 2 )
218  qmax = zero
219  zmax = zero
220  d = zero
221  e = zero
222 *
223  DO 10 k = 1, 2*( n-1 ), 2
224  IF( z( k ).LT.zero ) THEN
225  info = -( 200+k )
226  CALL xerbla( 'DLASQ2', 2 )
227  return
228  ELSE IF( z( k+1 ).LT.zero ) THEN
229  info = -( 200+k+1 )
230  CALL xerbla( 'DLASQ2', 2 )
231  return
232  END IF
233  d = d + z( k )
234  e = e + z( k+1 )
235  qmax = max( qmax, z( k ) )
236  emin = min( emin, z( k+1 ) )
237  zmax = max( qmax, zmax, z( k+1 ) )
238  10 continue
239  IF( z( 2*n-1 ).LT.zero ) THEN
240  info = -( 200+2*n-1 )
241  CALL xerbla( 'DLASQ2', 2 )
242  return
243  END IF
244  d = d + z( 2*n-1 )
245  qmax = max( qmax, z( 2*n-1 ) )
246  zmax = max( qmax, zmax )
247 *
248 * Check for diagonality.
249 *
250  IF( e.EQ.zero ) THEN
251  DO 20 k = 2, n
252  z( k ) = z( 2*k-1 )
253  20 continue
254  CALL dlasrt( 'D', n, z, iinfo )
255  z( 2*n-1 ) = d
256  return
257  END IF
258 *
259  trace = d + e
260 *
261 * Check for zero data.
262 *
263  IF( trace.EQ.zero ) THEN
264  z( 2*n-1 ) = zero
265  return
266  END IF
267 *
268 * Check whether the machine is IEEE conformable.
269 *
270  ieee = ilaenv( 10, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 .AND.
271  $ ilaenv( 11, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1
272 *
273 * Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...).
274 *
275  DO 30 k = 2*n, 2, -2
276  z( 2*k ) = zero
277  z( 2*k-1 ) = z( k )
278  z( 2*k-2 ) = zero
279  z( 2*k-3 ) = z( k-1 )
280  30 continue
281 *
282  i0 = 1
283  n0 = n
284 *
285 * Reverse the qd-array, if warranted.
286 *
287  IF( cbias*z( 4*i0-3 ).LT.z( 4*n0-3 ) ) THEN
288  ipn4 = 4*( i0+n0 )
289  DO 40 i4 = 4*i0, 2*( i0+n0-1 ), 4
290  temp = z( i4-3 )
291  z( i4-3 ) = z( ipn4-i4-3 )
292  z( ipn4-i4-3 ) = temp
293  temp = z( i4-1 )
294  z( i4-1 ) = z( ipn4-i4-5 )
295  z( ipn4-i4-5 ) = temp
296  40 continue
297  END IF
298 *
299 * Initial split checking via dqd and Li's test.
300 *
301  pp = 0
302 *
303  DO 80 k = 1, 2
304 *
305  d = z( 4*n0+pp-3 )
306  DO 50 i4 = 4*( n0-1 ) + pp, 4*i0 + pp, -4
307  IF( z( i4-1 ).LE.tol2*d ) THEN
308  z( i4-1 ) = -zero
309  d = z( i4-3 )
310  ELSE
311  d = z( i4-3 )*( d / ( d+z( i4-1 ) ) )
312  END IF
313  50 continue
314 *
315 * dqd maps Z to ZZ plus Li's test.
316 *
317  emin = z( 4*i0+pp+1 )
318  d = z( 4*i0+pp-3 )
319  DO 60 i4 = 4*i0 + pp, 4*( n0-1 ) + pp, 4
320  z( i4-2*pp-2 ) = d + z( i4-1 )
321  IF( z( i4-1 ).LE.tol2*d ) THEN
322  z( i4-1 ) = -zero
323  z( i4-2*pp-2 ) = d
324  z( i4-2*pp ) = zero
325  d = z( i4+1 )
326  ELSE IF( safmin*z( i4+1 ).LT.z( i4-2*pp-2 ) .AND.
327  $ safmin*z( i4-2*pp-2 ).LT.z( i4+1 ) ) THEN
328  temp = z( i4+1 ) / z( i4-2*pp-2 )
329  z( i4-2*pp ) = z( i4-1 )*temp
330  d = d*temp
331  ELSE
332  z( i4-2*pp ) = z( i4+1 )*( z( i4-1 ) / z( i4-2*pp-2 ) )
333  d = z( i4+1 )*( d / z( i4-2*pp-2 ) )
334  END IF
335  emin = min( emin, z( i4-2*pp ) )
336  60 continue
337  z( 4*n0-pp-2 ) = d
338 *
339 * Now find qmax.
340 *
341  qmax = z( 4*i0-pp-2 )
342  DO 70 i4 = 4*i0 - pp + 2, 4*n0 - pp - 2, 4
343  qmax = max( qmax, z( i4 ) )
344  70 continue
345 *
346 * Prepare for the next iteration on K.
347 *
348  pp = 1 - pp
349  80 continue
350 *
351 * Initialise variables to pass to DLASQ3.
352 *
353  ttype = 0
354  dmin1 = zero
355  dmin2 = zero
356  dn = zero
357  dn1 = zero
358  dn2 = zero
359  g = zero
360  tau = zero
361 *
362  iter = 2
363  nfail = 0
364  ndiv = 2*( n0-i0 )
365 *
366  DO 160 iwhila = 1, n + 1
367  IF( n0.LT.1 )
368  $ go to 170
369 *
370 * While array unfinished do
371 *
372 * E(N0) holds the value of SIGMA when submatrix in I0:N0
373 * splits from the rest of the array, but is negated.
374 *
375  desig = zero
376  IF( n0.EQ.n ) THEN
377  sigma = zero
378  ELSE
379  sigma = -z( 4*n0-1 )
380  END IF
381  IF( sigma.LT.zero ) THEN
382  info = 1
383  return
384  END IF
385 *
386 * Find last unreduced submatrix's top index I0, find QMAX and
387 * EMIN. Find Gershgorin-type bound if Q's much greater than E's.
388 *
389  emax = zero
390  IF( n0.GT.i0 ) THEN
391  emin = abs( z( 4*n0-5 ) )
392  ELSE
393  emin = zero
394  END IF
395  qmin = z( 4*n0-3 )
396  qmax = qmin
397  DO 90 i4 = 4*n0, 8, -4
398  IF( z( i4-5 ).LE.zero )
399  $ go to 100
400  IF( qmin.GE.four*emax ) THEN
401  qmin = min( qmin, z( i4-3 ) )
402  emax = max( emax, z( i4-5 ) )
403  END IF
404  qmax = max( qmax, z( i4-7 )+z( i4-5 ) )
405  emin = min( emin, z( i4-5 ) )
406  90 continue
407  i4 = 4
408 *
409  100 continue
410  i0 = i4 / 4
411  pp = 0
412 *
413  IF( n0-i0.GT.1 ) THEN
414  dee = z( 4*i0-3 )
415  deemin = dee
416  kmin = i0
417  DO 110 i4 = 4*i0+1, 4*n0-3, 4
418  dee = z( i4 )*( dee /( dee+z( i4-2 ) ) )
419  IF( dee.LE.deemin ) THEN
420  deemin = dee
421  kmin = ( i4+3 )/4
422  END IF
423  110 continue
424  IF( (kmin-i0)*2.LT.n0-kmin .AND.
425  $ deemin.LE.half*z(4*n0-3) ) THEN
426  ipn4 = 4*( i0+n0 )
427  pp = 2
428  DO 120 i4 = 4*i0, 2*( i0+n0-1 ), 4
429  temp = z( i4-3 )
430  z( i4-3 ) = z( ipn4-i4-3 )
431  z( ipn4-i4-3 ) = temp
432  temp = z( i4-2 )
433  z( i4-2 ) = z( ipn4-i4-2 )
434  z( ipn4-i4-2 ) = temp
435  temp = z( i4-1 )
436  z( i4-1 ) = z( ipn4-i4-5 )
437  z( ipn4-i4-5 ) = temp
438  temp = z( i4 )
439  z( i4 ) = z( ipn4-i4-4 )
440  z( ipn4-i4-4 ) = temp
441  120 continue
442  END IF
443  END IF
444 *
445 * Put -(initial shift) into DMIN.
446 *
447  dmin = -max( zero, qmin-two*sqrt( qmin )*sqrt( emax ) )
448 *
449 * Now I0:N0 is unreduced.
450 * PP = 0 for ping, PP = 1 for pong.
451 * PP = 2 indicates that flipping was applied to the Z array and
452 * and that the tests for deflation upon entry in DLASQ3
453 * should not be performed.
454 *
455  nbig = 100*( n0-i0+1 )
456  DO 140 iwhilb = 1, nbig
457  IF( i0.GT.n0 )
458  $ go to 150
459 *
460 * While submatrix unfinished take a good dqds step.
461 *
462  CALL dlasq3( i0, n0, z, pp, dmin, sigma, desig, qmax, nfail,
463  $ iter, ndiv, ieee, ttype, dmin1, dmin2, dn, dn1,
464  $ dn2, g, tau )
465 *
466  pp = 1 - pp
467 *
468 * When EMIN is very small check for splits.
469 *
470  IF( pp.EQ.0 .AND. n0-i0.GE.3 ) THEN
471  IF( z( 4*n0 ).LE.tol2*qmax .OR.
472  $ z( 4*n0-1 ).LE.tol2*sigma ) THEN
473  splt = i0 - 1
474  qmax = z( 4*i0-3 )
475  emin = z( 4*i0-1 )
476  oldemn = z( 4*i0 )
477  DO 130 i4 = 4*i0, 4*( n0-3 ), 4
478  IF( z( i4 ).LE.tol2*z( i4-3 ) .OR.
479  $ z( i4-1 ).LE.tol2*sigma ) THEN
480  z( i4-1 ) = -sigma
481  splt = i4 / 4
482  qmax = zero
483  emin = z( i4+3 )
484  oldemn = z( i4+4 )
485  ELSE
486  qmax = max( qmax, z( i4+1 ) )
487  emin = min( emin, z( i4-1 ) )
488  oldemn = min( oldemn, z( i4 ) )
489  END IF
490  130 continue
491  z( 4*n0-1 ) = emin
492  z( 4*n0 ) = oldemn
493  i0 = splt + 1
494  END IF
495  END IF
496 *
497  140 continue
498 *
499  info = 2
500 *
501 * Maximum number of iterations exceeded, restore the shift
502 * SIGMA and place the new d's and e's in a qd array.
503 * This might need to be done for several blocks
504 *
505  i1 = i0
506  n1 = n0
507  145 continue
508  tempq = z( 4*i0-3 )
509  z( 4*i0-3 ) = z( 4*i0-3 ) + sigma
510  DO k = i0+1, n0
511  tempe = z( 4*k-5 )
512  z( 4*k-5 ) = z( 4*k-5 ) * (tempq / z( 4*k-7 ))
513  tempq = z( 4*k-3 )
514  z( 4*k-3 ) = z( 4*k-3 ) + sigma + tempe - z( 4*k-5 )
515  END DO
516 *
517 * Prepare to do this on the previous block if there is one
518 *
519  IF( i1.GT.1 ) THEN
520  n1 = i1-1
521  DO WHILE( ( i1.GE.2 ) .AND. ( z(4*i1-5).GE.zero ) )
522  i1 = i1 - 1
523  END DO
524  sigma = -z(4*n1-1)
525  go to 145
526  END IF
527 
528  DO k = 1, n
529  z( 2*k-1 ) = z( 4*k-3 )
530 *
531 * Only the block 1..N0 is unfinished. The rest of the e's
532 * must be essentially zero, although sometimes other data
533 * has been stored in them.
534 *
535  IF( k.LT.n0 ) THEN
536  z( 2*k ) = z( 4*k-1 )
537  ELSE
538  z( 2*k ) = 0
539  END IF
540  END DO
541  return
542 *
543 * end IWHILB
544 *
545  150 continue
546 *
547  160 continue
548 *
549  info = 3
550  return
551 *
552 * end IWHILA
553 *
554  170 continue
555 *
556 * Move q's to the front.
557 *
558  DO 180 k = 2, n
559  z( k ) = z( 4*k-3 )
560  180 continue
561 *
562 * Sort and compute sum of eigenvalues.
563 *
564  CALL dlasrt( 'D', n, z, iinfo )
565 *
566  e = zero
567  DO 190 k = n, 1, -1
568  e = e + z( k )
569  190 continue
570 *
571 * Store trace, sum(eigenvalues) and information on performance.
572 *
573  z( 2*n+1 ) = trace
574  z( 2*n+2 ) = e
575  z( 2*n+3 ) = dble( iter )
576  z( 2*n+4 ) = dble( ndiv ) / dble( n**2 )
577  z( 2*n+5 ) = hundrd*nfail / dble( iter )
578  return
579 *
580 * End of DLASQ2
581 *
582  END