1       SUBROUTINE ZLAED8( K, N, QSIZ, Q, LDQ, D, RHO, CUTPNT, Z, DLAMDA,
  2      $                   Q2, LDQ2, W, INDXP, INDX, INDXQ, PERM, GIVPTR,
  3      $                   GIVCOL, GIVNUM, INFO )
  4 *
  5 *  -- LAPACK routine (version 3.2.2) --
  6 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  7 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  8 *     June 2010
  9 *
 10 *     .. Scalar Arguments ..
 11       INTEGER            CUTPNT, GIVPTR, INFO, K, LDQ, LDQ2, N, QSIZ
 12       DOUBLE PRECISION   RHO
 13 *     ..
 14 *     .. Array Arguments ..
 15       INTEGER            GIVCOL( 2* ), INDX( * ), INDXP( * ),
 16      $                   INDXQ( * ), PERM( * )
 17       DOUBLE PRECISION   D( * ), DLAMDA( * ), GIVNUM( 2* ), W( * ),
 18      $                   Z( * )
 19       COMPLEX*16         Q( LDQ, * ), Q2( LDQ2, * )
 20 *     ..
 21 *
 22 *  Purpose
 23 *  =======
 24 *
 25 *  ZLAED8 merges the two sets of eigenvalues together into a single
 26 *  sorted set.  Then it tries to deflate the size of the problem.
 27 *  There are two ways in which deflation can occur:  when two or more
 28 *  eigenvalues are close together or if there is a tiny element in the
 29 *  Z vector.  For each such occurrence the order of the related secular
 30 *  equation problem is reduced by one.
 31 *
 32 *  Arguments
 33 *  =========
 34 *
 35 *  K      (output) INTEGER
 36 *         Contains the number of non-deflated eigenvalues.
 37 *         This is the order of the related secular equation.
 38 *
 39 *  N      (input) INTEGER
 40 *         The dimension of the symmetric tridiagonal matrix.  N >= 0.
 41 *
 42 *  QSIZ   (input) INTEGER
 43 *         The dimension of the unitary matrix used to reduce
 44 *         the dense or band matrix to tridiagonal form.
 45 *         QSIZ >= N if ICOMPQ = 1.
 46 *
 47 *  Q      (input/output) COMPLEX*16 array, dimension (LDQ,N)
 48 *         On entry, Q contains the eigenvectors of the partially solved
 49 *         system which has been previously updated in matrix
 50 *         multiplies with other partially solved eigensystems.
 51 *         On exit, Q contains the trailing (N-K) updated eigenvectors
 52 *         (those which were deflated) in its last N-K columns.
 53 *
 54 *  LDQ    (input) INTEGER
 55 *         The leading dimension of the array Q.  LDQ >= max( 1, N ).
 56 *
 57 *  D      (input/output) DOUBLE PRECISION array, dimension (N)
 58 *         On entry, D contains the eigenvalues of the two submatrices to
 59 *         be combined.  On exit, D contains the trailing (N-K) updated
 60 *         eigenvalues (those which were deflated) sorted into increasing
 61 *         order.
 62 *
 63 *  RHO    (input/output) DOUBLE PRECISION
 64 *         Contains the off diagonal element associated with the rank-1
 65 *         cut which originally split the two submatrices which are now
 66 *         being recombined. RHO is modified during the computation to
 67 *         the value required by DLAED3.
 68 *
 69 *  CUTPNT (input) INTEGER
 70 *         Contains the location of the last eigenvalue in the leading
 71 *         sub-matrix.  MIN(1,N) <= CUTPNT <= N.
 72 *
 73 *  Z      (input) DOUBLE PRECISION array, dimension (N)
 74 *         On input this vector contains the updating vector (the last
 75 *         row of the first sub-eigenvector matrix and the first row of
 76 *         the second sub-eigenvector matrix).  The contents of Z are
 77 *         destroyed during the updating process.
 78 *
 79 *  DLAMDA (output) DOUBLE PRECISION array, dimension (N)
 80 *         Contains a copy of the first K eigenvalues which will be used
 81 *         by DLAED3 to form the secular equation.
 82 *
 83 *  Q2     (output) COMPLEX*16 array, dimension (LDQ2,N)
 84 *         If ICOMPQ = 0, Q2 is not referenced.  Otherwise,
 85 *         Contains a copy of the first K eigenvectors which will be used
 86 *         by DLAED7 in a matrix multiply (DGEMM) to update the new
 87 *         eigenvectors.
 88 *
 89 *  LDQ2   (input) INTEGER
 90 *         The leading dimension of the array Q2.  LDQ2 >= max( 1, N ).
 91 *
 92 *  W      (output) DOUBLE PRECISION array, dimension (N)
 93 *         This will hold the first k values of the final
 94 *         deflation-altered z-vector and will be passed to DLAED3.
 95 *
 96 *  INDXP  (workspace) INTEGER array, dimension (N)
 97 *         This will contain the permutation used to place deflated
 98 *         values of D at the end of the array. On output INDXP(1:K)
 99 *         points to the nondeflated D-values and INDXP(K+1:N)
100 *         points to the deflated eigenvalues.
101 *
102 *  INDX   (workspace) INTEGER array, dimension (N)
103 *         This will contain the permutation used to sort the contents of
104 *         D into ascending order.
105 *
106 *  INDXQ  (input) INTEGER array, dimension (N)
107 *         This contains the permutation which separately sorts the two
108 *         sub-problems in D into ascending order.  Note that elements in
109 *         the second half of this permutation must first have CUTPNT
110 *         added to their values in order to be accurate.
111 *
112 *  PERM   (output) INTEGER array, dimension (N)
113 *         Contains the permutations (from deflation and sorting) to be
114 *         applied to each eigenblock.
115 *
116 *  GIVPTR (output) INTEGER
117 *         Contains the number of Givens rotations which took place in
118 *         this subproblem.
119 *
120 *  GIVCOL (output) INTEGER array, dimension (2, N)
121 *         Each pair of numbers indicates a pair of columns to take place
122 *         in a Givens rotation.
123 *
124 *  GIVNUM (output) DOUBLE PRECISION array, dimension (2, N)
125 *         Each number indicates the S value to be used in the
126 *         corresponding Givens rotation.
127 *
128 *  INFO   (output) INTEGER
129 *          = 0:  successful exit.
130 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
131 *
132 *  =====================================================================
133 *
134 *     .. Parameters ..
135       DOUBLE PRECISION   MONE, ZERO, ONE, TWO, EIGHT
136       PARAMETER          ( MONE = -1.0D0, ZERO = 0.0D0, ONE = 1.0D0,
137      $                   TWO = 2.0D0, EIGHT = 8.0D0 )
138 *     ..
139 *     .. Local Scalars ..
140       INTEGER            I, IMAX, J, JLAM, JMAX, JP, K2, N1, N1P1, N2
141       DOUBLE PRECISION   C, EPS, S, T, TAU, TOL
142 *     ..
143 *     .. External Functions ..
144       INTEGER            IDAMAX
145       DOUBLE PRECISION   DLAMCH, DLAPY2
146       EXTERNAL           IDAMAX, DLAMCH, DLAPY2
147 *     ..
148 *     .. External Subroutines ..
149       EXTERNAL           DCOPY, DLAMRG, DSCAL, XERBLA, ZCOPY, ZDROT,
150      $                   ZLACPY
151 *     ..
152 *     .. Intrinsic Functions ..
153       INTRINSIC          ABSMAXMINSQRT
154 *     ..
155 *     .. Executable Statements ..
156 *
157 *     Test the input parameters.
158 *
159       INFO = 0
160 *
161       IF( N.LT.0 ) THEN
162          INFO = -2
163       ELSE IF( QSIZ.LT.N ) THEN
164          INFO = -3
165       ELSE IF( LDQ.LT.MAX1, N ) ) THEN
166          INFO = -5
167       ELSE IF( CUTPNT.LT.MIN1, N ) .OR. CUTPNT.GT.N ) THEN
168          INFO = -8
169       ELSE IF( LDQ2.LT.MAX1, N ) ) THEN
170          INFO = -12
171       END IF
172       IF( INFO.NE.0 ) THEN
173          CALL XERBLA( 'ZLAED8'-INFO )
174          RETURN
175       END IF
176 *
177 *     Need to initialize GIVPTR to O here in case of quick exit
178 *     to prevent an unspecified code behavior (usually sigfault) 
179 *     when IWORK array on entry to *stedc is not zeroed 
180 *     (or at least some IWORK entries which used in *laed7 for GIVPTR).
181 *
182       GIVPTR = 0
183 *
184 *     Quick return if possible
185 *
186       IF( N.EQ.0 )
187      $   RETURN
188 *
189       N1 = CUTPNT
190       N2 = N - N1
191       N1P1 = N1 + 1
192 *
193       IF( RHO.LT.ZERO ) THEN
194          CALL DSCAL( N2, MONE, Z( N1P1 ), 1 )
195       END IF
196 *
197 *     Normalize z so that norm(z) = 1
198 *
199       T = ONE / SQRT( TWO )
200       DO 10 J = 1, N
201          INDX( J ) = J
202    10 CONTINUE
203       CALL DSCAL( N, T, Z, 1 )
204       RHO = ABS( TWO*RHO )
205 *
206 *     Sort the eigenvalues into increasing order
207 *
208       DO 20 I = CUTPNT + 1, N
209          INDXQ( I ) = INDXQ( I ) + CUTPNT
210    20 CONTINUE
211       DO 30 I = 1, N
212          DLAMDA( I ) = D( INDXQ( I ) )
213          W( I ) = Z( INDXQ( I ) )
214    30 CONTINUE
215       I = 1
216       J = CUTPNT + 1
217       CALL DLAMRG( N1, N2, DLAMDA, 11, INDX )
218       DO 40 I = 1, N
219          D( I ) = DLAMDA( INDX( I ) )
220          Z( I ) = W( INDX( I ) )
221    40 CONTINUE
222 *
223 *     Calculate the allowable deflation tolerance
224 *
225       IMAX = IDAMAX( N, Z, 1 )
226       JMAX = IDAMAX( N, D, 1 )
227       EPS = DLAMCH( 'Epsilon' )
228       TOL = EIGHT*EPS*ABS( D( JMAX ) )
229 *
230 *     If the rank-1 modifier is small enough, no more needs to be done
231 *     -- except to reorganize Q so that its columns correspond with the
232 *     elements in D.
233 *
234       IF( RHO*ABS( Z( IMAX ) ).LE.TOL ) THEN
235          K = 0
236          DO 50 J = 1, N
237             PERM( J ) = INDXQ( INDX( J ) )
238             CALL ZCOPY( QSIZ, Q( 1, PERM( J ) ), 1, Q2( 1, J ), 1 )
239    50    CONTINUE
240          CALL ZLACPY( 'A', QSIZ, N, Q2( 11 ), LDQ2, Q( 11 ), LDQ )
241          RETURN
242       END IF
243 *
244 *     If there are multiple eigenvalues then the problem deflates.  Here
245 *     the number of equal eigenvalues are found.  As each equal
246 *     eigenvalue is found, an elementary reflector is computed to rotate
247 *     the corresponding eigensubspace so that the corresponding
248 *     components of Z are zero in this new basis.
249 *
250       K = 0
251       K2 = N + 1
252       DO 60 J = 1, N
253          IF( RHO*ABS( Z( J ) ).LE.TOL ) THEN
254 *
255 *           Deflate due to small z component.
256 *
257             K2 = K2 - 1
258             INDXP( K2 ) = J
259             IF( J.EQ.N )
260      $         GO TO 100
261          ELSE
262             JLAM = J
263             GO TO 70
264          END IF
265    60 CONTINUE
266    70 CONTINUE
267       J = J + 1
268       IF( J.GT.N )
269      $   GO TO 90
270       IF( RHO*ABS( Z( J ) ).LE.TOL ) THEN
271 *
272 *        Deflate due to small z component.
273 *
274          K2 = K2 - 1
275          INDXP( K2 ) = J
276       ELSE
277 *
278 *        Check if eigenvalues are close enough to allow deflation.
279 *
280          S = Z( JLAM )
281          C = Z( J )
282 *
283 *        Find sqrt(a**2+b**2) without overflow or
284 *        destructive underflow.
285 *
286          TAU = DLAPY2( C, S )
287          T = D( J ) - D( JLAM )
288          C = C / TAU
289          S = -/ TAU
290          IFABS( T*C*S ).LE.TOL ) THEN
291 *
292 *           Deflation is possible.
293 *
294             Z( J ) = TAU
295             Z( JLAM ) = ZERO
296 *
297 *           Record the appropriate Givens rotation
298 *
299             GIVPTR = GIVPTR + 1
300             GIVCOL( 1, GIVPTR ) = INDXQ( INDX( JLAM ) )
301             GIVCOL( 2, GIVPTR ) = INDXQ( INDX( J ) )
302             GIVNUM( 1, GIVPTR ) = C
303             GIVNUM( 2, GIVPTR ) = S
304             CALL ZDROT( QSIZ, Q( 1, INDXQ( INDX( JLAM ) ) ), 1,
305      $                  Q( 1, INDXQ( INDX( J ) ) ), 1, C, S )
306             T = D( JLAM )*C*+ D( J )*S*S
307             D( J ) = D( JLAM )*S*+ D( J )*C*C
308             D( JLAM ) = T
309             K2 = K2 - 1
310             I = 1
311    80       CONTINUE
312             IF( K2+I.LE.N ) THEN
313                IF( D( JLAM ).LT.D( INDXP( K2+I ) ) ) THEN
314                   INDXP( K2+I-1 ) = INDXP( K2+I )
315                   INDXP( K2+I ) = JLAM
316                   I = I + 1
317                   GO TO 80
318                ELSE
319                   INDXP( K2+I-1 ) = JLAM
320                END IF
321             ELSE
322                INDXP( K2+I-1 ) = JLAM
323             END IF
324             JLAM = J
325          ELSE
326             K = K + 1
327             W( K ) = Z( JLAM )
328             DLAMDA( K ) = D( JLAM )
329             INDXP( K ) = JLAM
330             JLAM = J
331          END IF
332       END IF
333       GO TO 70
334    90 CONTINUE
335 *
336 *     Record the last eigenvalue.
337 *
338       K = K + 1
339       W( K ) = Z( JLAM )
340       DLAMDA( K ) = D( JLAM )
341       INDXP( K ) = JLAM
342 *
343   100 CONTINUE
344 *
345 *     Sort the eigenvalues and corresponding eigenvectors into DLAMDA
346 *     and Q2 respectively.  The eigenvalues/vectors which were not
347 *     deflated go into the first K slots of DLAMDA and Q2 respectively,
348 *     while those which were deflated go into the last N - K slots.
349 *
350       DO 110 J = 1, N
351          JP = INDXP( J )
352          DLAMDA( J ) = D( JP )
353          PERM( J ) = INDXQ( INDX( JP ) )
354          CALL ZCOPY( QSIZ, Q( 1, PERM( J ) ), 1, Q2( 1, J ), 1 )
355   110 CONTINUE
356 *
357 *     The deflated eigenvalues and their corresponding vectors go back
358 *     into the last N - K slots of D and Q respectively.
359 *
360       IF( K.LT.N ) THEN
361          CALL DCOPY( N-K, DLAMDA( K+1 ), 1, D( K+1 ), 1 )
362          CALL ZLACPY( 'A', QSIZ, N-K, Q2( 1, K+1 ), LDQ2, Q( 1, K+1 ),
363      $                LDQ )
364       END IF
365 *
366       RETURN
367 *
368 *     End of ZLAED8
369 *
370       END