LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zlaqr2.f
Go to the documentation of this file.
1*> \brief \b ZLAQR2 performs the unitary similarity transformation of a Hessenberg matrix to detect and deflate fully converged eigenvalues from a trailing principal submatrix (aggressive early deflation).
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZLAQR2 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlaqr2.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlaqr2.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlaqr2.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,
20* IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
21* NV, WV, LDWV, WORK, LWORK )
22*
23* .. Scalar Arguments ..
24* INTEGER IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
25* $ LDZ, LWORK, N, ND, NH, NS, NV, NW
26* LOGICAL WANTT, WANTZ
27* ..
28* .. Array Arguments ..
29* COMPLEX*16 H( LDH, * ), SH( * ), T( LDT, * ), V( LDV, * ),
30* $ WORK( * ), WV( LDWV, * ), Z( LDZ, * )
31* ..
32*
33*
34*> \par Purpose:
35* =============
36*>
37*> \verbatim
38*>
39*> ZLAQR2 is identical to ZLAQR3 except that it avoids
40*> recursion by calling ZLAHQR instead of ZLAQR4.
41*>
42*> Aggressive early deflation:
43*>
44*> ZLAQR2 accepts as input an upper Hessenberg matrix
45*> H and performs an unitary similarity transformation
46*> designed to detect and deflate fully converged eigenvalues from
47*> a trailing principal submatrix. On output H has been over-
48*> written by a new Hessenberg matrix that is a perturbation of
49*> an unitary similarity transformation of H. It is to be
50*> hoped that the final version of H has many zero subdiagonal
51*> entries.
52*>
53*> \endverbatim
54*
55* Arguments:
56* ==========
57*
58*> \param[in] WANTT
59*> \verbatim
60*> WANTT is LOGICAL
61*> If .TRUE., then the Hessenberg matrix H is fully updated
62*> so that the triangular Schur factor may be
63*> computed (in cooperation with the calling subroutine).
64*> If .FALSE., then only enough of H is updated to preserve
65*> the eigenvalues.
66*> \endverbatim
67*>
68*> \param[in] WANTZ
69*> \verbatim
70*> WANTZ is LOGICAL
71*> If .TRUE., then the unitary matrix Z is updated so
72*> so that the unitary Schur factor may be computed
73*> (in cooperation with the calling subroutine).
74*> If .FALSE., then Z is not referenced.
75*> \endverbatim
76*>
77*> \param[in] N
78*> \verbatim
79*> N is INTEGER
80*> The order of the matrix H and (if WANTZ is .TRUE.) the
81*> order of the unitary matrix Z.
82*> \endverbatim
83*>
84*> \param[in] KTOP
85*> \verbatim
86*> KTOP is INTEGER
87*> It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
88*> KBOT and KTOP together determine an isolated block
89*> along the diagonal of the Hessenberg matrix.
90*> \endverbatim
91*>
92*> \param[in] KBOT
93*> \verbatim
94*> KBOT is INTEGER
95*> It is assumed without a check that either
96*> KBOT = N or H(KBOT+1,KBOT)=0. KBOT and KTOP together
97*> determine an isolated block along the diagonal of the
98*> Hessenberg matrix.
99*> \endverbatim
100*>
101*> \param[in] NW
102*> \verbatim
103*> NW is INTEGER
104*> Deflation window size. 1 <= NW <= (KBOT-KTOP+1).
105*> \endverbatim
106*>
107*> \param[in,out] H
108*> \verbatim
109*> H is COMPLEX*16 array, dimension (LDH,N)
110*> On input the initial N-by-N section of H stores the
111*> Hessenberg matrix undergoing aggressive early deflation.
112*> On output H has been transformed by a unitary
113*> similarity transformation, perturbed, and the returned
114*> to Hessenberg form that (it is to be hoped) has some
115*> zero subdiagonal entries.
116*> \endverbatim
117*>
118*> \param[in] LDH
119*> \verbatim
120*> LDH is INTEGER
121*> Leading dimension of H just as declared in the calling
122*> subroutine. N <= LDH
123*> \endverbatim
124*>
125*> \param[in] ILOZ
126*> \verbatim
127*> ILOZ is INTEGER
128*> \endverbatim
129*>
130*> \param[in] IHIZ
131*> \verbatim
132*> IHIZ is INTEGER
133*> Specify the rows of Z to which transformations must be
134*> applied if WANTZ is .TRUE.. 1 <= ILOZ <= IHIZ <= N.
135*> \endverbatim
136*>
137*> \param[in,out] Z
138*> \verbatim
139*> Z is COMPLEX*16 array, dimension (LDZ,N)
140*> IF WANTZ is .TRUE., then on output, the unitary
141*> similarity transformation mentioned above has been
142*> accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
143*> If WANTZ is .FALSE., then Z is unreferenced.
144*> \endverbatim
145*>
146*> \param[in] LDZ
147*> \verbatim
148*> LDZ is INTEGER
149*> The leading dimension of Z just as declared in the
150*> calling subroutine. 1 <= LDZ.
151*> \endverbatim
152*>
153*> \param[out] NS
154*> \verbatim
155*> NS is INTEGER
156*> The number of unconverged (ie approximate) eigenvalues
157*> returned in SR and SI that may be used as shifts by the
158*> calling subroutine.
159*> \endverbatim
160*>
161*> \param[out] ND
162*> \verbatim
163*> ND is INTEGER
164*> The number of converged eigenvalues uncovered by this
165*> subroutine.
166*> \endverbatim
167*>
168*> \param[out] SH
169*> \verbatim
170*> SH is COMPLEX*16 array, dimension (KBOT)
171*> On output, approximate eigenvalues that may
172*> be used for shifts are stored in SH(KBOT-ND-NS+1)
173*> through SR(KBOT-ND). Converged eigenvalues are
174*> stored in SH(KBOT-ND+1) through SH(KBOT).
175*> \endverbatim
176*>
177*> \param[out] V
178*> \verbatim
179*> V is COMPLEX*16 array, dimension (LDV,NW)
180*> An NW-by-NW work array.
181*> \endverbatim
182*>
183*> \param[in] LDV
184*> \verbatim
185*> LDV is INTEGER
186*> The leading dimension of V just as declared in the
187*> calling subroutine. NW <= LDV
188*> \endverbatim
189*>
190*> \param[in] NH
191*> \verbatim
192*> NH is INTEGER
193*> The number of columns of T. NH >= NW.
194*> \endverbatim
195*>
196*> \param[out] T
197*> \verbatim
198*> T is COMPLEX*16 array, dimension (LDT,NW)
199*> \endverbatim
200*>
201*> \param[in] LDT
202*> \verbatim
203*> LDT is INTEGER
204*> The leading dimension of T just as declared in the
205*> calling subroutine. NW <= LDT
206*> \endverbatim
207*>
208*> \param[in] NV
209*> \verbatim
210*> NV is INTEGER
211*> The number of rows of work array WV available for
212*> workspace. NV >= NW.
213*> \endverbatim
214*>
215*> \param[out] WV
216*> \verbatim
217*> WV is COMPLEX*16 array, dimension (LDWV,NW)
218*> \endverbatim
219*>
220*> \param[in] LDWV
221*> \verbatim
222*> LDWV is INTEGER
223*> The leading dimension of W just as declared in the
224*> calling subroutine. NW <= LDV
225*> \endverbatim
226*>
227*> \param[out] WORK
228*> \verbatim
229*> WORK is COMPLEX*16 array, dimension (LWORK)
230*> On exit, WORK(1) is set to an estimate of the optimal value
231*> of LWORK for the given values of N, NW, KTOP and KBOT.
232*> \endverbatim
233*>
234*> \param[in] LWORK
235*> \verbatim
236*> LWORK is INTEGER
237*> The dimension of the work array WORK. LWORK = 2*NW
238*> suffices, but greater efficiency may result from larger
239*> values of LWORK.
240*>
241*> If LWORK = -1, then a workspace query is assumed; ZLAQR2
242*> only estimates the optimal workspace size for the given
243*> values of N, NW, KTOP and KBOT. The estimate is returned
244*> in WORK(1). No error message related to LWORK is issued
245*> by XERBLA. Neither H nor Z are accessed.
246*> \endverbatim
247*
248* Authors:
249* ========
250*
251*> \author Univ. of Tennessee
252*> \author Univ. of California Berkeley
253*> \author Univ. of Colorado Denver
254*> \author NAG Ltd.
255*
256*> \ingroup laqr2
257*
258*> \par Contributors:
259* ==================
260*>
261*> Karen Braman and Ralph Byers, Department of Mathematics,
262*> University of Kansas, USA
263*>
264* =====================================================================
265 SUBROUTINE zlaqr2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH,
266 $ ILOZ,
267 $ IHIZ, Z, LDZ, NS, ND, SH, V, LDV, NH, T, LDT,
268 $ NV, WV, LDWV, WORK, LWORK )
269*
270* -- LAPACK auxiliary routine --
271* -- LAPACK is a software package provided by Univ. of Tennessee, --
272* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
273*
274* .. Scalar Arguments ..
275 INTEGER IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
276 $ LDZ, LWORK, N, ND, NH, NS, NV, NW
277 LOGICAL WANTT, WANTZ
278* ..
279* .. Array Arguments ..
280 COMPLEX*16 H( LDH, * ), SH( * ), T( LDT, * ), V( LDV, * ),
281 $ WORK( * ), WV( LDWV, * ), Z( LDZ, * )
282* ..
283*
284* ================================================================
285*
286* .. Parameters ..
287 COMPLEX*16 ZERO, ONE
288 PARAMETER ( ZERO = ( 0.0d0, 0.0d0 ),
289 $ one = ( 1.0d0, 0.0d0 ) )
290 DOUBLE PRECISION RZERO, RONE
291 parameter( rzero = 0.0d0, rone = 1.0d0 )
292* ..
293* .. Local Scalars ..
294 COMPLEX*16 CDUM, S, TAU
295 DOUBLE PRECISION FOO, SAFMAX, SAFMIN, SMLNUM, ULP
296 INTEGER I, IFST, ILST, INFO, INFQR, J, JW, KCOL, KLN,
297 $ knt, krow, kwtop, ltop, lwk1, lwk2, lwkopt
298* ..
299* .. External Functions ..
300 DOUBLE PRECISION DLAMCH
301 EXTERNAL DLAMCH
302* ..
303* .. External Subroutines ..
304 EXTERNAL zcopy, zgehrd, zgemm, zlacpy,
305 $ zlahqr,
307* ..
308* .. Intrinsic Functions ..
309 INTRINSIC abs, dble, dcmplx, dconjg, dimag, int, max, min
310* ..
311* .. Statement Functions ..
312 DOUBLE PRECISION CABS1
313* ..
314* .. Statement Function definitions ..
315 cabs1( cdum ) = abs( dble( cdum ) ) + abs( dimag( cdum ) )
316* ..
317* .. Executable Statements ..
318*
319* ==== Estimate optimal workspace. ====
320*
321 jw = min( nw, kbot-ktop+1 )
322 IF( jw.LE.2 ) THEN
323 lwkopt = 1
324 ELSE
325*
326* ==== Workspace query call to ZGEHRD ====
327*
328 CALL zgehrd( jw, 1, jw-1, t, ldt, work, work, -1, info )
329 lwk1 = int( work( 1 ) )
330*
331* ==== Workspace query call to ZUNMHR ====
332*
333 CALL zunmhr( 'R', 'N', jw, jw, 1, jw-1, t, ldt, work, v,
334 $ ldv,
335 $ work, -1, info )
336 lwk2 = int( work( 1 ) )
337*
338* ==== Optimal workspace ====
339*
340 lwkopt = jw + max( lwk1, lwk2 )
341 END IF
342*
343* ==== Quick return in case of workspace query. ====
344*
345 IF( lwork.EQ.-1 ) THEN
346 work( 1 ) = dcmplx( lwkopt, 0 )
347 RETURN
348 END IF
349*
350* ==== Nothing to do ...
351* ... for an empty active block ... ====
352 ns = 0
353 nd = 0
354 work( 1 ) = one
355 IF( ktop.GT.kbot )
356 $ RETURN
357* ... nor for an empty deflation window. ====
358 IF( nw.LT.1 )
359 $ RETURN
360*
361* ==== Machine constants ====
362*
363 safmin = dlamch( 'SAFE MINIMUM' )
364 safmax = rone / safmin
365 ulp = dlamch( 'PRECISION' )
366 smlnum = safmin*( dble( n ) / ulp )
367*
368* ==== Setup deflation window ====
369*
370 jw = min( nw, kbot-ktop+1 )
371 kwtop = kbot - jw + 1
372 IF( kwtop.EQ.ktop ) THEN
373 s = zero
374 ELSE
375 s = h( kwtop, kwtop-1 )
376 END IF
377*
378 IF( kbot.EQ.kwtop ) THEN
379*
380* ==== 1-by-1 deflation window: not much to do ====
381*
382 sh( kwtop ) = h( kwtop, kwtop )
383 ns = 1
384 nd = 0
385 IF( cabs1( s ).LE.max( smlnum, ulp*cabs1( h( kwtop,
386 $ kwtop ) ) ) ) THEN
387 ns = 0
388 nd = 1
389 IF( kwtop.GT.ktop )
390 $ h( kwtop, kwtop-1 ) = zero
391 END IF
392 work( 1 ) = one
393 RETURN
394 END IF
395*
396* ==== Convert to spike-triangular form. (In case of a
397* . rare QR failure, this routine continues to do
398* . aggressive early deflation using that part of
399* . the deflation window that converged using INFQR
400* . here and there to keep track.) ====
401*
402 CALL zlacpy( 'U', jw, jw, h( kwtop, kwtop ), ldh, t, ldt )
403 CALL zcopy( jw-1, h( kwtop+1, kwtop ), ldh+1, t( 2, 1 ),
404 $ ldt+1 )
405*
406 CALL zlaset( 'A', jw, jw, zero, one, v, ldv )
407 CALL zlahqr( .true., .true., jw, 1, jw, t, ldt, sh( kwtop ), 1,
408 $ jw, v, ldv, infqr )
409*
410* ==== Deflation detection loop ====
411*
412 ns = jw
413 ilst = infqr + 1
414 DO 10 knt = infqr + 1, jw
415*
416* ==== Small spike tip deflation test ====
417*
418 foo = cabs1( t( ns, ns ) )
419 IF( foo.EQ.rzero )
420 $ foo = cabs1( s )
421 IF( cabs1( s )*cabs1( v( 1, ns ) ).LE.max( smlnum, ulp*foo ) )
422 $ THEN
423*
424* ==== One more converged eigenvalue ====
425*
426 ns = ns - 1
427 ELSE
428*
429* ==== One undeflatable eigenvalue. Move it up out of the
430* . way. (ZTREXC can not fail in this case.) ====
431*
432 ifst = ns
433 CALL ztrexc( 'V', jw, t, ldt, v, ldv, ifst, ilst, info )
434 ilst = ilst + 1
435 END IF
436 10 CONTINUE
437*
438* ==== Return to Hessenberg form ====
439*
440 IF( ns.EQ.0 )
441 $ s = zero
442*
443 IF( ns.LT.jw ) THEN
444*
445* ==== sorting the diagonal of T improves accuracy for
446* . graded matrices. ====
447*
448 DO 30 i = infqr + 1, ns
449 ifst = i
450 DO 20 j = i + 1, ns
451 IF( cabs1( t( j, j ) ).GT.cabs1( t( ifst, ifst ) ) )
452 $ ifst = j
453 20 CONTINUE
454 ilst = i
455 IF( ifst.NE.ilst )
456 $ CALL ztrexc( 'V', jw, t, ldt, v, ldv, ifst, ilst,
457 $ info )
458 30 CONTINUE
459 END IF
460*
461* ==== Restore shift/eigenvalue array from T ====
462*
463 DO 40 i = infqr + 1, jw
464 sh( kwtop+i-1 ) = t( i, i )
465 40 CONTINUE
466*
467*
468 IF( ns.LT.jw .OR. s.EQ.zero ) THEN
469 IF( ns.GT.1 .AND. s.NE.zero ) THEN
470*
471* ==== Reflect spike back into lower triangle ====
472*
473 CALL zcopy( ns, v, ldv, work, 1 )
474 DO 50 i = 1, ns
475 work( i ) = dconjg( work( i ) )
476 50 CONTINUE
477 CALL zlarfg( ns, work( 1 ), work( 2 ), 1, tau )
478*
479 CALL zlaset( 'L', jw-2, jw-2, zero, zero, t( 3, 1 ),
480 $ ldt )
481*
482 CALL zlarf1f( 'L', ns, jw, work, 1, conjg( tau ), t, ldt,
483 $ work( jw+1 ) )
484 CALL zlarf1f( 'R', ns, ns, work, 1, tau, t, ldt,
485 $ work( jw+1 ) )
486 CALL zlarf1f( 'R', jw, ns, work, 1, tau, v, ldv,
487 $ work( jw+1 ) )
488*
489 CALL zgehrd( jw, 1, ns, t, ldt, work, work( jw+1 ),
490 $ lwork-jw, info )
491 END IF
492*
493* ==== Copy updated reduced window into place ====
494*
495 IF( kwtop.GT.1 )
496 $ h( kwtop, kwtop-1 ) = s*dconjg( v( 1, 1 ) )
497 CALL zlacpy( 'U', jw, jw, t, ldt, h( kwtop, kwtop ), ldh )
498 CALL zcopy( jw-1, t( 2, 1 ), ldt+1, h( kwtop+1, kwtop ),
499 $ ldh+1 )
500*
501* ==== Accumulate orthogonal matrix in order update
502* . H and Z, if requested. ====
503*
504 IF( ns.GT.1 .AND. s.NE.zero )
505 $ CALL zunmhr( 'R', 'N', jw, ns, 1, ns, t, ldt, work, v,
506 $ ldv,
507 $ work( jw+1 ), lwork-jw, info )
508*
509* ==== Update vertical slab in H ====
510*
511 IF( wantt ) THEN
512 ltop = 1
513 ELSE
514 ltop = ktop
515 END IF
516 DO 60 krow = ltop, kwtop - 1, nv
517 kln = min( nv, kwtop-krow )
518 CALL zgemm( 'N', 'N', kln, jw, jw, one, h( krow, kwtop ),
519 $ ldh, v, ldv, zero, wv, ldwv )
520 CALL zlacpy( 'A', kln, jw, wv, ldwv, h( krow, kwtop ),
521 $ ldh )
522 60 CONTINUE
523*
524* ==== Update horizontal slab in H ====
525*
526 IF( wantt ) THEN
527 DO 70 kcol = kbot + 1, n, nh
528 kln = min( nh, n-kcol+1 )
529 CALL zgemm( 'C', 'N', jw, kln, jw, one, v, ldv,
530 $ h( kwtop, kcol ), ldh, zero, t, ldt )
531 CALL zlacpy( 'A', jw, kln, t, ldt, h( kwtop, kcol ),
532 $ ldh )
533 70 CONTINUE
534 END IF
535*
536* ==== Update vertical slab in Z ====
537*
538 IF( wantz ) THEN
539 DO 80 krow = iloz, ihiz, nv
540 kln = min( nv, ihiz-krow+1 )
541 CALL zgemm( 'N', 'N', kln, jw, jw, one, z( krow,
542 $ kwtop ),
543 $ ldz, v, ldv, zero, wv, ldwv )
544 CALL zlacpy( 'A', kln, jw, wv, ldwv, z( krow, kwtop ),
545 $ ldz )
546 80 CONTINUE
547 END IF
548 END IF
549*
550* ==== Return the number of deflations ... ====
551*
552 nd = jw - ns
553*
554* ==== ... and the number of shifts. (Subtracting
555* . INFQR from the spike length takes care
556* . of the case of a rare QR failure while
557* . calculating eigenvalues of the deflation
558* . window.) ====
559*
560 ns = ns - infqr
561*
562* ==== Return optimal workspace. ====
563*
564 work( 1 ) = dcmplx( lwkopt, 0 )
565*
566* ==== End of ZLAQR2 ====
567*
568 END
subroutine zcopy(n, zx, incx, zy, incy)
ZCOPY
Definition zcopy.f:81
subroutine zgehrd(n, ilo, ihi, a, lda, tau, work, lwork, info)
ZGEHRD
Definition zgehrd.f:166
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
Definition zgemm.f:188
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 zlahqr(wantt, wantz, n, ilo, ihi, h, ldh, w, iloz, ihiz, z, ldz, info)
ZLAHQR computes the eigenvalues and Schur factorization of an upper Hessenberg matrix,...
Definition zlahqr.f:193
subroutine zlaqr2(wantt, wantz, n, ktop, kbot, nw, h, ldh, iloz, ihiz, z, ldz, ns, nd, sh, v, ldv, nh, t, ldt, nv, wv, ldwv, work, lwork)
ZLAQR2 performs the unitary similarity transformation of a Hessenberg matrix to detect and deflate fu...
Definition zlaqr2.f:269
subroutine zlarf1f(side, m, n, v, incv, tau, c, ldc, work)
ZLARF1F applies an elementary reflector to a general rectangular
Definition zlarf1f.f:157
subroutine zlarfg(n, alpha, x, incx, tau)
ZLARFG generates an elementary reflector (Householder matrix).
Definition zlarfg.f:104
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition zlaset.f:104
subroutine ztrexc(compq, n, t, ldt, q, ldq, ifst, ilst, info)
ZTREXC
Definition ztrexc.f:124
subroutine zunmhr(side, trans, m, n, ilo, ihi, a, lda, tau, c, ldc, work, lwork, info)
ZUNMHR
Definition zunmhr.f:176