LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zlaed8.f
Go to the documentation of this file.
1*> \brief \b ZLAED8 used by ZSTEDC. Merges eigenvalues and deflates secular equation. Used when the original matrix is dense.
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZLAED8 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlaed8.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlaed8.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlaed8.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZLAED8( K, N, QSIZ, Q, LDQ, D, RHO, CUTPNT, Z, DLAMBDA,
20* Q2, LDQ2, W, INDXP, INDX, INDXQ, PERM, GIVPTR,
21* GIVCOL, GIVNUM, INFO )
22*
23* .. Scalar Arguments ..
24* INTEGER CUTPNT, GIVPTR, INFO, K, LDQ, LDQ2, N, QSIZ
25* DOUBLE PRECISION RHO
26* ..
27* .. Array Arguments ..
28* INTEGER GIVCOL( 2, * ), INDX( * ), INDXP( * ),
29* $ INDXQ( * ), PERM( * )
30* DOUBLE PRECISION D( * ), DLAMBDA( * ), GIVNUM( 2, * ), W( * ),
31* $ Z( * )
32* COMPLEX*16 Q( LDQ, * ), Q2( LDQ2, * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> ZLAED8 merges the two sets of eigenvalues together into a single
42*> sorted set. Then it tries to deflate the size of the problem.
43*> There are two ways in which deflation can occur: when two or more
44*> eigenvalues are close together or if there is a tiny element in the
45*> Z vector. For each such occurrence the order of the related secular
46*> equation problem is reduced by one.
47*> \endverbatim
48*
49* Arguments:
50* ==========
51*
52*> \param[out] K
53*> \verbatim
54*> K is INTEGER
55*> Contains the number of non-deflated eigenvalues.
56*> This is the order of the related secular equation.
57*> \endverbatim
58*>
59*> \param[in] N
60*> \verbatim
61*> N is INTEGER
62*> The dimension of the symmetric tridiagonal matrix. N >= 0.
63*> \endverbatim
64*>
65*> \param[in] QSIZ
66*> \verbatim
67*> QSIZ is INTEGER
68*> The dimension of the unitary matrix used to reduce
69*> the dense or band matrix to tridiagonal form.
70*> QSIZ >= N if ICOMPQ = 1.
71*> \endverbatim
72*>
73*> \param[in,out] Q
74*> \verbatim
75*> Q is COMPLEX*16 array, dimension (LDQ,N)
76*> On entry, Q contains the eigenvectors of the partially solved
77*> system which has been previously updated in matrix
78*> multiplies with other partially solved eigensystems.
79*> On exit, Q contains the trailing (N-K) updated eigenvectors
80*> (those which were deflated) in its last N-K columns.
81*> \endverbatim
82*>
83*> \param[in] LDQ
84*> \verbatim
85*> LDQ is INTEGER
86*> The leading dimension of the array Q. LDQ >= max( 1, N ).
87*> \endverbatim
88*>
89*> \param[in,out] D
90*> \verbatim
91*> D is DOUBLE PRECISION array, dimension (N)
92*> On entry, D contains the eigenvalues of the two submatrices to
93*> be combined. On exit, D contains the trailing (N-K) updated
94*> eigenvalues (those which were deflated) sorted into increasing
95*> order.
96*> \endverbatim
97*>
98*> \param[in,out] RHO
99*> \verbatim
100*> RHO is DOUBLE PRECISION
101*> Contains the off diagonal element associated with the rank-1
102*> cut which originally split the two submatrices which are now
103*> being recombined. RHO is modified during the computation to
104*> the value required by DLAED3.
105*> \endverbatim
106*>
107*> \param[in] CUTPNT
108*> \verbatim
109*> CUTPNT is INTEGER
110*> Contains the location of the last eigenvalue in the leading
111*> sub-matrix. MIN(1,N) <= CUTPNT <= N.
112*> \endverbatim
113*>
114*> \param[in] Z
115*> \verbatim
116*> Z is DOUBLE PRECISION array, dimension (N)
117*> On input this vector contains the updating vector (the last
118*> row of the first sub-eigenvector matrix and the first row of
119*> the second sub-eigenvector matrix). The contents of Z are
120*> destroyed during the updating process.
121*> \endverbatim
122*>
123*> \param[out] DLAMBDA
124*> \verbatim
125*> DLAMBDA is DOUBLE PRECISION array, dimension (N)
126*> Contains a copy of the first K eigenvalues which will be used
127*> by DLAED3 to form the secular equation.
128*> \endverbatim
129*>
130*> \param[out] Q2
131*> \verbatim
132*> Q2 is COMPLEX*16 array, dimension (LDQ2,N)
133*> If ICOMPQ = 0, Q2 is not referenced. Otherwise,
134*> Contains a copy of the first K eigenvectors which will be used
135*> by DLAED7 in a matrix multiply (DGEMM) to update the new
136*> eigenvectors.
137*> \endverbatim
138*>
139*> \param[in] LDQ2
140*> \verbatim
141*> LDQ2 is INTEGER
142*> The leading dimension of the array Q2. LDQ2 >= max( 1, N ).
143*> \endverbatim
144*>
145*> \param[out] W
146*> \verbatim
147*> W is DOUBLE PRECISION array, dimension (N)
148*> This will hold the first k values of the final
149*> deflation-altered z-vector and will be passed to DLAED3.
150*> \endverbatim
151*>
152*> \param[out] INDXP
153*> \verbatim
154*> INDXP is INTEGER array, dimension (N)
155*> This will contain the permutation used to place deflated
156*> values of D at the end of the array. On output INDXP(1:K)
157*> points to the nondeflated D-values and INDXP(K+1:N)
158*> points to the deflated eigenvalues.
159*> \endverbatim
160*>
161*> \param[out] INDX
162*> \verbatim
163*> INDX is INTEGER array, dimension (N)
164*> This will contain the permutation used to sort the contents of
165*> D into ascending order.
166*> \endverbatim
167*>
168*> \param[in] INDXQ
169*> \verbatim
170*> INDXQ is INTEGER array, dimension (N)
171*> This contains the permutation which separately sorts the two
172*> sub-problems in D into ascending order. Note that elements in
173*> the second half of this permutation must first have CUTPNT
174*> added to their values in order to be accurate.
175*> \endverbatim
176*>
177*> \param[out] PERM
178*> \verbatim
179*> PERM is INTEGER array, dimension (N)
180*> Contains the permutations (from deflation and sorting) to be
181*> applied to each eigenblock.
182*> \endverbatim
183*>
184*> \param[out] GIVPTR
185*> \verbatim
186*> GIVPTR is INTEGER
187*> Contains the number of Givens rotations which took place in
188*> this subproblem.
189*> \endverbatim
190*>
191*> \param[out] GIVCOL
192*> \verbatim
193*> GIVCOL is INTEGER array, dimension (2, N)
194*> Each pair of numbers indicates a pair of columns to take place
195*> in a Givens rotation.
196*> \endverbatim
197*>
198*> \param[out] GIVNUM
199*> \verbatim
200*> GIVNUM is DOUBLE PRECISION array, dimension (2, N)
201*> Each number indicates the S value to be used in the
202*> corresponding Givens rotation.
203*> \endverbatim
204*>
205*> \param[out] INFO
206*> \verbatim
207*> INFO is INTEGER
208*> = 0: successful exit.
209*> < 0: if INFO = -i, the i-th argument had an illegal value.
210*> \endverbatim
211*
212* Authors:
213* ========
214*
215*> \author Univ. of Tennessee
216*> \author Univ. of California Berkeley
217*> \author Univ. of Colorado Denver
218*> \author NAG Ltd.
219*
220*> \ingroup laed8
221*
222* =====================================================================
223 SUBROUTINE zlaed8( K, N, QSIZ, Q, LDQ, D, RHO, CUTPNT, Z,
224 $ DLAMBDA,
225 $ Q2, LDQ2, W, INDXP, INDX, INDXQ, PERM, GIVPTR,
226 $ GIVCOL, GIVNUM, INFO )
227*
228* -- LAPACK computational routine --
229* -- LAPACK is a software package provided by Univ. of Tennessee, --
230* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
231*
232* .. Scalar Arguments ..
233 INTEGER CUTPNT, GIVPTR, INFO, K, LDQ, LDQ2, N, QSIZ
234 DOUBLE PRECISION RHO
235* ..
236* .. Array Arguments ..
237 INTEGER GIVCOL( 2, * ), INDX( * ), INDXP( * ),
238 $ INDXQ( * ), PERM( * )
239 DOUBLE PRECISION D( * ), DLAMBDA( * ), GIVNUM( 2, * ), W( * ),
240 $ z( * )
241 COMPLEX*16 Q( LDQ, * ), Q2( LDQ2, * )
242* ..
243*
244* =====================================================================
245*
246* .. Parameters ..
247 DOUBLE PRECISION MONE, ZERO, ONE, TWO, EIGHT
248 PARAMETER ( MONE = -1.0d0, zero = 0.0d0, one = 1.0d0,
249 $ two = 2.0d0, eight = 8.0d0 )
250* ..
251* .. Local Scalars ..
252 INTEGER I, IMAX, J, JLAM, JMAX, JP, K2, N1, N1P1, N2
253 DOUBLE PRECISION C, EPS, S, T, TAU, TOL
254* ..
255* .. External Functions ..
256 INTEGER IDAMAX
257 DOUBLE PRECISION DLAMCH, DLAPY2
258 EXTERNAL IDAMAX, DLAMCH, DLAPY2
259* ..
260* .. External Subroutines ..
261 EXTERNAL dcopy, dlamrg, dscal, xerbla, zcopy,
262 $ zdrot,
263 $ zlacpy
264* ..
265* .. Intrinsic Functions ..
266 INTRINSIC abs, max, min, sqrt
267* ..
268* .. Executable Statements ..
269*
270* Test the input parameters.
271*
272 info = 0
273*
274 IF( n.LT.0 ) THEN
275 info = -2
276 ELSE IF( qsiz.LT.n ) THEN
277 info = -3
278 ELSE IF( ldq.LT.max( 1, n ) ) THEN
279 info = -5
280 ELSE IF( cutpnt.LT.min( 1, n ) .OR. cutpnt.GT.n ) THEN
281 info = -8
282 ELSE IF( ldq2.LT.max( 1, n ) ) THEN
283 info = -12
284 END IF
285 IF( info.NE.0 ) THEN
286 CALL xerbla( 'ZLAED8', -info )
287 RETURN
288 END IF
289*
290* Need to initialize GIVPTR to O here in case of quick exit
291* to prevent an unspecified code behavior (usually sigfault)
292* when IWORK array on entry to *stedc is not zeroed
293* (or at least some IWORK entries which used in *laed7 for GIVPTR).
294*
295 givptr = 0
296*
297* Quick return if possible
298*
299 IF( n.EQ.0 )
300 $ RETURN
301*
302 n1 = cutpnt
303 n2 = n - n1
304 n1p1 = n1 + 1
305*
306 IF( rho.LT.zero ) THEN
307 CALL dscal( n2, mone, z( n1p1 ), 1 )
308 END IF
309*
310* Normalize z so that norm(z) = 1
311*
312 t = one / sqrt( two )
313 DO 10 j = 1, n
314 indx( j ) = j
315 10 CONTINUE
316 CALL dscal( n, t, z, 1 )
317 rho = abs( two*rho )
318*
319* Sort the eigenvalues into increasing order
320*
321 DO 20 i = cutpnt + 1, n
322 indxq( i ) = indxq( i ) + cutpnt
323 20 CONTINUE
324 DO 30 i = 1, n
325 dlambda( i ) = d( indxq( i ) )
326 w( i ) = z( indxq( i ) )
327 30 CONTINUE
328 i = 1
329 j = cutpnt + 1
330 CALL dlamrg( n1, n2, dlambda, 1, 1, indx )
331 DO 40 i = 1, n
332 d( i ) = dlambda( indx( i ) )
333 z( i ) = w( indx( i ) )
334 40 CONTINUE
335*
336* Calculate the allowable deflation tolerance
337*
338 imax = idamax( n, z, 1 )
339 jmax = idamax( n, d, 1 )
340 eps = dlamch( 'Epsilon' )
341 tol = eight*eps*abs( d( jmax ) )
342*
343* If the rank-1 modifier is small enough, no more needs to be done
344* -- except to reorganize Q so that its columns correspond with the
345* elements in D.
346*
347 IF( rho*abs( z( imax ) ).LE.tol ) THEN
348 k = 0
349 DO 50 j = 1, n
350 perm( j ) = indxq( indx( j ) )
351 CALL zcopy( qsiz, q( 1, perm( j ) ), 1, q2( 1, j ), 1 )
352 50 CONTINUE
353 CALL zlacpy( 'A', qsiz, n, q2( 1, 1 ), ldq2, q( 1, 1 ),
354 $ ldq )
355 RETURN
356 END IF
357*
358* If there are multiple eigenvalues then the problem deflates. Here
359* the number of equal eigenvalues are found. As each equal
360* eigenvalue is found, an elementary reflector is computed to rotate
361* the corresponding eigensubspace so that the corresponding
362* components of Z are zero in this new basis.
363*
364 k = 0
365 k2 = n + 1
366 DO 60 j = 1, n
367 IF( rho*abs( z( j ) ).LE.tol ) THEN
368*
369* Deflate due to small z component.
370*
371 k2 = k2 - 1
372 indxp( k2 ) = j
373 IF( j.EQ.n )
374 $ GO TO 100
375 ELSE
376 jlam = j
377 GO TO 70
378 END IF
379 60 CONTINUE
380 70 CONTINUE
381 j = j + 1
382 IF( j.GT.n )
383 $ GO TO 90
384 IF( rho*abs( z( j ) ).LE.tol ) THEN
385*
386* Deflate due to small z component.
387*
388 k2 = k2 - 1
389 indxp( k2 ) = j
390 ELSE
391*
392* Check if eigenvalues are close enough to allow deflation.
393*
394 s = z( jlam )
395 c = z( j )
396*
397* Find sqrt(a**2+b**2) without overflow or
398* destructive underflow.
399*
400 tau = dlapy2( c, s )
401 t = d( j ) - d( jlam )
402 c = c / tau
403 s = -s / tau
404 IF( abs( t*c*s ).LE.tol ) THEN
405*
406* Deflation is possible.
407*
408 z( j ) = tau
409 z( jlam ) = zero
410*
411* Record the appropriate Givens rotation
412*
413 givptr = givptr + 1
414 givcol( 1, givptr ) = indxq( indx( jlam ) )
415 givcol( 2, givptr ) = indxq( indx( j ) )
416 givnum( 1, givptr ) = c
417 givnum( 2, givptr ) = s
418 CALL zdrot( qsiz, q( 1, indxq( indx( jlam ) ) ), 1,
419 $ q( 1, indxq( indx( j ) ) ), 1, c, s )
420 t = d( jlam )*c*c + d( j )*s*s
421 d( j ) = d( jlam )*s*s + d( j )*c*c
422 d( jlam ) = t
423 k2 = k2 - 1
424 i = 1
425 80 CONTINUE
426 IF( k2+i.LE.n ) THEN
427 IF( d( jlam ).LT.d( indxp( k2+i ) ) ) THEN
428 indxp( k2+i-1 ) = indxp( k2+i )
429 indxp( k2+i ) = jlam
430 i = i + 1
431 GO TO 80
432 ELSE
433 indxp( k2+i-1 ) = jlam
434 END IF
435 ELSE
436 indxp( k2+i-1 ) = jlam
437 END IF
438 jlam = j
439 ELSE
440 k = k + 1
441 w( k ) = z( jlam )
442 dlambda( k ) = d( jlam )
443 indxp( k ) = jlam
444 jlam = j
445 END IF
446 END IF
447 GO TO 70
448 90 CONTINUE
449*
450* Record the last eigenvalue.
451*
452 k = k + 1
453 w( k ) = z( jlam )
454 dlambda( k ) = d( jlam )
455 indxp( k ) = jlam
456*
457 100 CONTINUE
458*
459* Sort the eigenvalues and corresponding eigenvectors into DLAMBDA
460* and Q2 respectively. The eigenvalues/vectors which were not
461* deflated go into the first K slots of DLAMBDA and Q2 respectively,
462* while those which were deflated go into the last N - K slots.
463*
464 DO 110 j = 1, n
465 jp = indxp( j )
466 dlambda( j ) = d( jp )
467 perm( j ) = indxq( indx( jp ) )
468 CALL zcopy( qsiz, q( 1, perm( j ) ), 1, q2( 1, j ), 1 )
469 110 CONTINUE
470*
471* The deflated eigenvalues and their corresponding vectors go back
472* into the last N - K slots of D and Q respectively.
473*
474 IF( k.LT.n ) THEN
475 CALL dcopy( n-k, dlambda( k+1 ), 1, d( k+1 ), 1 )
476 CALL zlacpy( 'A', qsiz, n-k, q2( 1, k+1 ), ldq2, q( 1,
477 $ k+1 ),
478 $ ldq )
479 END IF
480*
481 RETURN
482*
483* End of ZLAED8
484*
485 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zcopy(n, zx, incx, zy, incy)
ZCOPY
Definition zcopy.f:81
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
Definition zlacpy.f:101
subroutine zlaed8(k, n, qsiz, q, ldq, d, rho, cutpnt, z, dlambda, q2, ldq2, w, indxp, indx, indxq, perm, givptr, givcol, givnum, info)
ZLAED8 used by ZSTEDC. Merges eigenvalues and deflates secular equation. Used when the original matri...
Definition zlaed8.f:227
subroutine dlamrg(n1, n2, a, dtrd1, dtrd2, index)
DLAMRG creates a permutation list to merge the entries of two independently sorted sets into a single...
Definition dlamrg.f:97
subroutine zdrot(n, zx, incx, zy, incy, c, s)
ZDROT
Definition zdrot.f:98
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79