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