LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zlaqz0.f
Go to the documentation of this file.
1*> \brief \b ZLAQZ0
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZLAQZ0 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlaqz0.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlaqz0.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlaqz0.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZLAQZ0( WANTS, WANTQ, WANTZ, N, ILO, IHI, A, LDA, B,
20* $ LDB, ALPHA, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, RWORK, REC,
21* $ INFO )
22* IMPLICIT NONE
23*
24* Arguments
25* CHARACTER, INTENT( IN ) :: WANTS, WANTQ, WANTZ
26* INTEGER, INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
27* $ REC
28* INTEGER, INTENT( OUT ) :: INFO
29* COMPLEX*16, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ,
30* $ * ), Z( LDZ, * ), ALPHA( * ), BETA( * ), WORK( * )
31* DOUBLE PRECISION, INTENT( OUT ) :: RWORK( * )
32* ..
33*
34*
35*> \par Purpose:
36* =============
37*>
38*> \verbatim
39*>
40*> ZLAQZ0 computes the eigenvalues of a real matrix pair (H,T),
41*> where H is an upper Hessenberg matrix and T is upper triangular,
42*> using the double-shift QZ method.
43*> Matrix pairs of this type are produced by the reduction to
44*> generalized upper Hessenberg form of a real matrix pair (A,B):
45*>
46*> A = Q1*H*Z1**H, B = Q1*T*Z1**H,
47*>
48*> as computed by ZGGHRD.
49*>
50*> If JOB='S', then the Hessenberg-triangular pair (H,T) is
51*> also reduced to generalized Schur form,
52*>
53*> H = Q*S*Z**H, T = Q*P*Z**H,
54*>
55*> where Q and Z are unitary matrices, P and S are an upper triangular
56*> matrices.
57*>
58*> Optionally, the unitary matrix Q from the generalized Schur
59*> factorization may be postmultiplied into an input matrix Q1, and the
60*> unitary matrix Z may be postmultiplied into an input matrix Z1.
61*> If Q1 and Z1 are the unitary matrices from ZGGHRD that reduced
62*> the matrix pair (A,B) to generalized upper Hessenberg form, then the
63*> output matrices Q1*Q and Z1*Z are the unitary factors from the
64*> generalized Schur factorization of (A,B):
65*>
66*> A = (Q1*Q)*S*(Z1*Z)**H, B = (Q1*Q)*P*(Z1*Z)**H.
67*>
68*> To avoid overflow, eigenvalues of the matrix pair (H,T) (equivalently,
69*> of (A,B)) are computed as a pair of values (alpha,beta), where alpha is
70*> complex and beta real.
71*> If beta is nonzero, lambda = alpha / beta is an eigenvalue of the
72*> generalized nonsymmetric eigenvalue problem (GNEP)
73*> A*x = lambda*B*x
74*> and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the
75*> alternate form of the GNEP
76*> mu*A*y = B*y.
77*> Eigenvalues can be read directly from the generalized Schur
78*> form:
79*> alpha = S(i,i), beta = P(i,i).
80*>
81*> Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix
82*> Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973),
83*> pp. 241--256.
84*>
85*> Ref: B. Kagstrom, D. Kressner, "Multishift Variants of the QZ
86*> Algorithm with Aggressive Early Deflation", SIAM J. Numer.
87*> Anal., 29(2006), pp. 199--227.
88*>
89*> Ref: T. Steel, D. Camps, K. Meerbergen, R. Vandebril "A multishift,
90*> multipole rational QZ method with aggressive early deflation"
91*> \endverbatim
92*
93* Arguments:
94* ==========
95*
96*> \param[in] WANTS
97*> \verbatim
98*> WANTS is CHARACTER*1
99*> = 'E': Compute eigenvalues only;
100*> = 'S': Compute eigenvalues and the Schur form.
101*> \endverbatim
102*>
103*> \param[in] WANTQ
104*> \verbatim
105*> WANTQ is CHARACTER*1
106*> = 'N': Left Schur vectors (Q) are not computed;
107*> = 'I': Q is initialized to the unit matrix and the matrix Q
108*> of left Schur vectors of (A,B) is returned;
109*> = 'V': Q must contain an unitary matrix Q1 on entry and
110*> the product Q1*Q is returned.
111*> \endverbatim
112*>
113*> \param[in] WANTZ
114*> \verbatim
115*> WANTZ is CHARACTER*1
116*> = 'N': Right Schur vectors (Z) are not computed;
117*> = 'I': Z is initialized to the unit matrix and the matrix Z
118*> of right Schur vectors of (A,B) is returned;
119*> = 'V': Z must contain an unitary matrix Z1 on entry and
120*> the product Z1*Z is returned.
121*> \endverbatim
122*>
123*> \param[in] N
124*> \verbatim
125*> N is INTEGER
126*> The order of the matrices A, B, Q, and Z. N >= 0.
127*> \endverbatim
128*>
129*> \param[in] ILO
130*> \verbatim
131*> ILO is INTEGER
132*> \endverbatim
133*>
134*> \param[in] IHI
135*> \verbatim
136*> IHI is INTEGER
137*> ILO and IHI mark the rows and columns of A which are in
138*> Hessenberg form. It is assumed that A is already upper
139*> triangular in rows and columns 1:ILO-1 and IHI+1:N.
140*> If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0.
141*> \endverbatim
142*>
143*> \param[in,out] A
144*> \verbatim
145*> A is COMPLEX*16 array, dimension (LDA, N)
146*> On entry, the N-by-N upper Hessenberg matrix A.
147*> On exit, if JOB = 'S', A contains the upper triangular
148*> matrix S from the generalized Schur factorization.
149*> If JOB = 'E', the diagonal blocks of A match those of S, but
150*> the rest of A is unspecified.
151*> \endverbatim
152*>
153*> \param[in] LDA
154*> \verbatim
155*> LDA is INTEGER
156*> The leading dimension of the array A. LDA >= max( 1, N ).
157*> \endverbatim
158*>
159*> \param[in,out] B
160*> \verbatim
161*> B is COMPLEX*16 array, dimension (LDB, N)
162*> On entry, the N-by-N upper triangular matrix B.
163*> On exit, if JOB = 'S', B contains the upper triangular
164*> matrix P from the generalized Schur factorization;
165*> If JOB = 'E', the diagonal blocks of B match those of P, but
166*> the rest of B is unspecified.
167*> \endverbatim
168*>
169*> \param[in] LDB
170*> \verbatim
171*> LDB is INTEGER
172*> The leading dimension of the array B. LDB >= max( 1, N ).
173*> \endverbatim
174*>
175*> \param[out] ALPHA
176*> \verbatim
177*> ALPHA is COMPLEX*16 array, dimension (N)
178*> Each scalar alpha defining an eigenvalue
179*> of GNEP.
180*> \endverbatim
181*>
182*> \param[out] BETA
183*> \verbatim
184*> BETA is COMPLEX*16 array, dimension (N)
185*> The scalars beta that define the eigenvalues of GNEP.
186*> Together, the quantities alpha = ALPHA(j) and
187*> beta = BETA(j) represent the j-th eigenvalue of the matrix
188*> pair (A,B), in one of the forms lambda = alpha/beta or
189*> mu = beta/alpha. Since either lambda or mu may overflow,
190*> they should not, in general, be computed.
191*> \endverbatim
192*>
193*> \param[in,out] Q
194*> \verbatim
195*> Q is COMPLEX*16 array, dimension (LDQ, N)
196*> On entry, if COMPQ = 'V', the unitary matrix Q1 used in
197*> the reduction of (A,B) to generalized Hessenberg form.
198*> On exit, if COMPQ = 'I', the unitary matrix of left Schur
199*> vectors of (A,B), and if COMPQ = 'V', the unitary matrix
200*> of left Schur vectors of (A,B).
201*> Not referenced if COMPQ = 'N'.
202*> \endverbatim
203*>
204*> \param[in] LDQ
205*> \verbatim
206*> LDQ is INTEGER
207*> The leading dimension of the array Q. LDQ >= 1.
208*> If COMPQ='V' or 'I', then LDQ >= N.
209*> \endverbatim
210*>
211*> \param[in,out] Z
212*> \verbatim
213*> Z is COMPLEX*16 array, dimension (LDZ, N)
214*> On entry, if COMPZ = 'V', the unitary matrix Z1 used in
215*> the reduction of (A,B) to generalized Hessenberg form.
216*> On exit, if COMPZ = 'I', the unitary matrix of
217*> right Schur vectors of (H,T), and if COMPZ = 'V', the
218*> unitary matrix of right Schur vectors of (A,B).
219*> Not referenced if COMPZ = 'N'.
220*> \endverbatim
221*>
222*> \param[in] LDZ
223*> \verbatim
224*> LDZ is INTEGER
225*> The leading dimension of the array Z. LDZ >= 1.
226*> If COMPZ='V' or 'I', then LDZ >= N.
227*> \endverbatim
228*>
229*> \param[out] WORK
230*> \verbatim
231*> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
232*> On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.
233*> \endverbatim
234*>
235*> \param[out] RWORK
236*> \verbatim
237*> RWORK is DOUBLE PRECISION array, dimension (N)
238*> \endverbatim
239*>
240*> \param[in] LWORK
241*> \verbatim
242*> LWORK is INTEGER
243*> The dimension of the array WORK. LWORK >= max(1,N).
244*>
245*> If LWORK = -1, then a workspace query is assumed; the routine
246*> only calculates the optimal size of the WORK array, returns
247*> this value as the first entry of the WORK array, and no error
248*> message related to LWORK is issued by XERBLA.
249*> \endverbatim
250*>
251*> \param[in] REC
252*> \verbatim
253*> REC is INTEGER
254*> REC indicates the current recursion level. Should be set
255*> to 0 on first call.
256*> \endverbatim
257*>
258*> \param[out] INFO
259*> \verbatim
260*> INFO is INTEGER
261*> = 0: successful exit
262*> < 0: if INFO = -i, the i-th argument had an illegal value
263*> = 1,...,N: the QZ iteration did not converge. (A,B) is not
264*> in Schur form, but ALPHA(i) and
265*> BETA(i), i=INFO+1,...,N should be correct.
266*> \endverbatim
267*
268* Authors:
269* ========
270*
271*> \author Thijs Steel, KU Leuven
272*
273*> \date May 2020
274*
275*> \ingroup laqz0
276*>
277* =====================================================================
278 RECURSIVE SUBROUTINE zlaqz0( WANTS, WANTQ, WANTZ, N, ILO, IHI,
279 $ A,
280 $ LDA, B, LDB, ALPHA, BETA, Q, LDQ, Z,
281 $ LDZ, WORK, LWORK, RWORK, REC,
282 $ INFO )
283 IMPLICIT NONE
284
285* Arguments
286 CHARACTER, INTENT( IN ) :: wants, wantq, wantz
287 INTEGER, INTENT( IN ) :: n, ilo, ihi, lda, ldb, ldq, ldz, lwork,
288 $ rec
289 INTEGER, INTENT( OUT ) :: info
290 COMPLEX*16, INTENT( INOUT ) :: a( lda, * ), b( ldb, * ), q( ldq,
291 $ * ), z( ldz, * ), alpha( * ), beta( * ), work( * )
292 DOUBLE PRECISION, INTENT( OUT ) :: rwork( * )
293
294* Parameters
295 COMPLEX*16 czero, cone
296 parameter( czero = ( 0.0d+0, 0.0d+0 ), cone = ( 1.0d+0,
297 $ 0.0d+0 ) )
298 DOUBLE PRECISION :: zero, one, half
299 parameter( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
300
301* Local scalars
302 DOUBLE PRECISION :: smlnum, ulp, safmin, safmax, c1, tempr,
303 $ bnorm, btol
304 COMPLEX*16 :: eshift, s1, temp
305 INTEGER :: istart, istop, iiter, maxit, istart2, k, ld, nshifts,
306 $ nblock, nw, nmin, nibble, n_undeflated, n_deflated,
307 $ ns, sweep_info, shiftpos, lworkreq, k2, istartm,
308 $ istopm, iwants, iwantq, iwantz, norm_info, aed_info,
309 $ nwr, nbr, nsr, itemp1, itemp2, rcost
310 LOGICAL :: ilschur, ilq, ilz
311 CHARACTER :: jbcmpz*3
312
313* External Functions
314 EXTERNAL :: xerbla, zhgeqz, zlaqz2, zlaqz3, zlaset,
315 $ zlartg, zrot
316 DOUBLE PRECISION, EXTERNAL :: dlamch, zlanhs
317 LOGICAL, EXTERNAL :: lsame
318 INTEGER, EXTERNAL :: ilaenv
319
320*
321* Decode wantS,wantQ,wantZ
322*
323 IF( lsame( wants, 'E' ) ) THEN
324 ilschur = .false.
325 iwants = 1
326 ELSE IF( lsame( wants, 'S' ) ) THEN
327 ilschur = .true.
328 iwants = 2
329 ELSE
330 iwants = 0
331 END IF
332
333 IF( lsame( wantq, 'N' ) ) THEN
334 ilq = .false.
335 iwantq = 1
336 ELSE IF( lsame( wantq, 'V' ) ) THEN
337 ilq = .true.
338 iwantq = 2
339 ELSE IF( lsame( wantq, 'I' ) ) THEN
340 ilq = .true.
341 iwantq = 3
342 ELSE
343 iwantq = 0
344 END IF
345
346 IF( lsame( wantz, 'N' ) ) THEN
347 ilz = .false.
348 iwantz = 1
349 ELSE IF( lsame( wantz, 'V' ) ) THEN
350 ilz = .true.
351 iwantz = 2
352 ELSE IF( lsame( wantz, 'I' ) ) THEN
353 ilz = .true.
354 iwantz = 3
355 ELSE
356 iwantz = 0
357 END IF
358*
359* Check Argument Values
360*
361 info = 0
362 IF( iwants.EQ.0 ) THEN
363 info = -1
364 ELSE IF( iwantq.EQ.0 ) THEN
365 info = -2
366 ELSE IF( iwantz.EQ.0 ) THEN
367 info = -3
368 ELSE IF( n.LT.0 ) THEN
369 info = -4
370 ELSE IF( ilo.LT.1 ) THEN
371 info = -5
372 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 ) THEN
373 info = -6
374 ELSE IF( lda.LT.n ) THEN
375 info = -8
376 ELSE IF( ldb.LT.n ) THEN
377 info = -10
378 ELSE IF( ldq.LT.1 .OR. ( ilq .AND. ldq.LT.n ) ) THEN
379 info = -15
380 ELSE IF( ldz.LT.1 .OR. ( ilz .AND. ldz.LT.n ) ) THEN
381 info = -17
382 END IF
383 IF( info.NE.0 ) THEN
384 CALL xerbla( 'ZLAQZ0', -info )
385 RETURN
386 END IF
387
388*
389* Quick return if possible
390*
391 IF( n.LE.0 ) THEN
392 work( 1 ) = dble( 1 )
393 RETURN
394 END IF
395
396*
397* Get the parameters
398*
399 jbcmpz( 1:1 ) = wants
400 jbcmpz( 2:2 ) = wantq
401 jbcmpz( 3:3 ) = wantz
402
403 nmin = ilaenv( 12, 'ZLAQZ0', jbcmpz, n, ilo, ihi, lwork )
404
405 nwr = ilaenv( 13, 'ZLAQZ0', jbcmpz, n, ilo, ihi, lwork )
406 nwr = max( 2, nwr )
407 nwr = min( ihi-ilo+1, ( n-1 ) / 3, nwr )
408
409 nibble = ilaenv( 14, 'ZLAQZ0', jbcmpz, n, ilo, ihi, lwork )
410
411 nsr = ilaenv( 15, 'ZLAQZ0', jbcmpz, n, ilo, ihi, lwork )
412 nsr = min( nsr, ( n+6 ) / 9, ihi-ilo )
413 nsr = max( 2, nsr-mod( nsr, 2 ) )
414
415 rcost = ilaenv( 17, 'ZLAQZ0', jbcmpz, n, ilo, ihi, lwork )
416 itemp1 = int( nsr/sqrt( 1+2*nsr/( dble( rcost )/100*n ) ) )
417 itemp1 = ( ( itemp1-1 )/4 )*4+4
418 nbr = nsr+itemp1
419
420 IF( n .LT. nmin .OR. rec .GE. 2 ) THEN
421 CALL zhgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b,
422 $ ldb,
423 $ alpha, beta, q, ldq, z, ldz, work, lwork, rwork,
424 $ info )
425 RETURN
426 END IF
427
428*
429* Find out required workspace
430*
431
432* Workspace query to ZLAQZ2
433 nw = max( nwr, nmin )
434 CALL zlaqz2( ilschur, ilq, ilz, n, ilo, ihi, nw, a, lda, b,
435 $ ldb,
436 $ q, ldq, z, ldz, n_undeflated, n_deflated, alpha,
437 $ beta, work, nw, work, nw, work, -1, rwork, rec,
438 $ aed_info )
439 itemp1 = int( work( 1 ) )
440* Workspace query to ZLAQZ3
441 CALL zlaqz3( ilschur, ilq, ilz, n, ilo, ihi, nsr, nbr, alpha,
442 $ beta, a, lda, b, ldb, q, ldq, z, ldz, work, nbr,
443 $ work, nbr, work, -1, sweep_info )
444 itemp2 = int( work( 1 ) )
445
446 lworkreq = max( itemp1+2*nw**2, itemp2+2*nbr**2 )
447 IF ( lwork .EQ.-1 ) THEN
448 work( 1 ) = dble( lworkreq )
449 RETURN
450 ELSE IF ( lwork .LT. lworkreq ) THEN
451 info = -19
452 END IF
453 IF( info.NE.0 ) THEN
454 CALL xerbla( 'ZLAQZ0', info )
455 RETURN
456 END IF
457*
458* Initialize Q and Z
459*
460 IF( iwantq.EQ.3 ) CALL zlaset( 'FULL', n, n, czero, cone, q,
461 $ ldq )
462 IF( iwantz.EQ.3 ) CALL zlaset( 'FULL', n, n, czero, cone, z,
463 $ ldz )
464
465* Get machine constants
466 safmin = dlamch( 'SAFE MINIMUM' )
467 safmax = one/safmin
468 ulp = dlamch( 'PRECISION' )
469 smlnum = safmin*( dble( n )/ulp )
470
471 bnorm = zlanhs( 'F', ihi-ilo+1, b( ilo, ilo ), ldb, rwork )
472 btol = max( safmin, ulp*bnorm )
473
474 istart = ilo
475 istop = ihi
476 maxit = 30*( ihi-ilo+1 )
477 ld = 0
478
479 DO iiter = 1, maxit
480 IF( iiter .GE. maxit ) THEN
481 info = istop+1
482 GOTO 80
483 END IF
484 IF ( istart+1 .GE. istop ) THEN
485 istop = istart
486 EXIT
487 END IF
488
489* Check deflations at the end
490 IF ( abs( a( istop, istop-1 ) ) .LE. max( smlnum,
491 $ ulp*( abs( a( istop, istop ) )+abs( a( istop-1,
492 $ istop-1 ) ) ) ) ) THEN
493 a( istop, istop-1 ) = czero
494 istop = istop-1
495 ld = 0
496 eshift = czero
497 END IF
498* Check deflations at the start
499 IF ( abs( a( istart+1, istart ) ) .LE. max( smlnum,
500 $ ulp*( abs( a( istart, istart ) )+abs( a( istart+1,
501 $ istart+1 ) ) ) ) ) THEN
502 a( istart+1, istart ) = czero
503 istart = istart+1
504 ld = 0
505 eshift = czero
506 END IF
507
508 IF ( istart+1 .GE. istop ) THEN
509 EXIT
510 END IF
511
512* Check interior deflations
513 istart2 = istart
514 DO k = istop, istart+1, -1
515 IF ( abs( a( k, k-1 ) ) .LE. max( smlnum, ulp*( abs( a( k,
516 $ k ) )+abs( a( k-1, k-1 ) ) ) ) ) THEN
517 a( k, k-1 ) = czero
518 istart2 = k
519 EXIT
520 END IF
521 END DO
522
523* Get range to apply rotations to
524 IF ( ilschur ) THEN
525 istartm = 1
526 istopm = n
527 ELSE
528 istartm = istart2
529 istopm = istop
530 END IF
531
532* Check infinite eigenvalues, this is done without blocking so might
533* slow down the method when many infinite eigenvalues are present
534 k = istop
535 DO WHILE ( k.GE.istart2 )
536
537 IF( abs( b( k, k ) ) .LT. btol ) THEN
538* A diagonal element of B is negligible, move it
539* to the top and deflate it
540
541 DO k2 = k, istart2+1, -1
542 CALL zlartg( b( k2-1, k2 ), b( k2-1, k2-1 ), c1,
543 $ s1,
544 $ temp )
545 b( k2-1, k2 ) = temp
546 b( k2-1, k2-1 ) = czero
547
548 CALL zrot( k2-2-istartm+1, b( istartm, k2 ), 1,
549 $ b( istartm, k2-1 ), 1, c1, s1 )
550 CALL zrot( min( k2+1, istop )-istartm+1,
551 $ a( istartm,
552 $ k2 ), 1, a( istartm, k2-1 ), 1, c1, s1 )
553 IF ( ilz ) THEN
554 CALL zrot( n, z( 1, k2 ), 1, z( 1, k2-1 ), 1,
555 $ c1,
556 $ s1 )
557 END IF
558
559 IF( k2.LT.istop ) THEN
560 CALL zlartg( a( k2, k2-1 ), a( k2+1, k2-1 ), c1,
561 $ s1, temp )
562 a( k2, k2-1 ) = temp
563 a( k2+1, k2-1 ) = czero
564
565 CALL zrot( istopm-k2+1, a( k2, k2 ), lda,
566 $ a( k2+1,
567 $ k2 ), lda, c1, s1 )
568 CALL zrot( istopm-k2+1, b( k2, k2 ), ldb,
569 $ b( k2+1,
570 $ k2 ), ldb, c1, s1 )
571 IF( ilq ) THEN
572 CALL zrot( n, q( 1, k2 ), 1, q( 1, k2+1 ), 1,
573 $ c1, dconjg( s1 ) )
574 END IF
575 END IF
576
577 END DO
578
579 IF( istart2.LT.istop )THEN
580 CALL zlartg( a( istart2, istart2 ), a( istart2+1,
581 $ istart2 ), c1, s1, temp )
582 a( istart2, istart2 ) = temp
583 a( istart2+1, istart2 ) = czero
584
585 CALL zrot( istopm-( istart2+1 )+1, a( istart2,
586 $ istart2+1 ), lda, a( istart2+1,
587 $ istart2+1 ), lda, c1, s1 )
588 CALL zrot( istopm-( istart2+1 )+1, b( istart2,
589 $ istart2+1 ), ldb, b( istart2+1,
590 $ istart2+1 ), ldb, c1, s1 )
591 IF( ilq ) THEN
592 CALL zrot( n, q( 1, istart2 ), 1, q( 1,
593 $ istart2+1 ), 1, c1, dconjg( s1 ) )
594 END IF
595 END IF
596
597 istart2 = istart2+1
598
599 END IF
600 k = k-1
601 END DO
602
603* istart2 now points to the top of the bottom right
604* unreduced Hessenberg block
605 IF ( istart2 .GE. istop ) THEN
606 istop = istart2-1
607 ld = 0
608 eshift = czero
609 cycle
610 END IF
611
612 nw = nwr
613 nshifts = nsr
614 nblock = nbr
615
616 IF ( istop-istart2+1 .LT. nmin ) THEN
617* Setting nw to the size of the subblock will make AED deflate
618* all the eigenvalues. This is slightly more efficient than just
619* using qz_small because the off diagonal part gets updated via BLAS.
620 IF ( istop-istart+1 .LT. nmin ) THEN
621 nw = istop-istart+1
622 istart2 = istart
623 ELSE
624 nw = istop-istart2+1
625 END IF
626 END IF
627
628*
629* Time for AED
630*
631 CALL zlaqz2( ilschur, ilq, ilz, n, istart2, istop, nw, a,
632 $ lda,
633 $ b, ldb, q, ldq, z, ldz, n_undeflated, n_deflated,
634 $ alpha, beta, work, nw, work( nw**2+1 ), nw,
635 $ work( 2*nw**2+1 ), lwork-2*nw**2, rwork, rec,
636 $ aed_info )
637
638 IF ( n_deflated > 0 ) THEN
639 istop = istop-n_deflated
640 ld = 0
641 eshift = czero
642 END IF
643
644 IF ( 100*n_deflated > nibble*( n_deflated+n_undeflated ) .OR.
645 $ istop-istart2+1 .LT. nmin ) THEN
646* AED has uncovered many eigenvalues. Skip a QZ sweep and run
647* AED again.
648 cycle
649 END IF
650
651 ld = ld+1
652
653 ns = min( nshifts, istop-istart2 )
654 ns = min( ns, n_undeflated )
655 shiftpos = istop-n_undeflated+1
656
657 IF ( mod( ld, 6 ) .EQ. 0 ) THEN
658*
659* Exceptional shift. Chosen for no particularly good reason.
660*
661 IF( ( dble( maxit )*safmin )*abs( a( istop,
662 $ istop-1 ) ).LT.abs( a( istop-1, istop-1 ) ) ) THEN
663 eshift = a( istop, istop-1 )/b( istop-1, istop-1 )
664 ELSE
665 eshift = eshift+cone/( safmin*dble( maxit ) )
666 END IF
667 alpha( shiftpos ) = cone
668 beta( shiftpos ) = eshift
669 ns = 1
670 END IF
671
672*
673* Time for a QZ sweep
674*
675 CALL zlaqz3( ilschur, ilq, ilz, n, istart2, istop, ns,
676 $ nblock,
677 $ alpha( shiftpos ), beta( shiftpos ), a, lda, b,
678 $ ldb, q, ldq, z, ldz, work, nblock, work( nblock**
679 $ 2+1 ), nblock, work( 2*nblock**2+1 ),
680 $ lwork-2*nblock**2, sweep_info )
681
682 END DO
683
684*
685* Call ZHGEQZ to normalize the eigenvalue blocks and set the eigenvalues
686* If all the eigenvalues have been found, ZHGEQZ will not do any iterations
687* and only normalize the blocks. In case of a rare convergence failure,
688* the single shift might perform better.
689*
690 80 CALL zhgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
691 $ alpha, beta, q, ldq, z, ldz, work, lwork, rwork,
692 $ norm_info )
693
694 info = norm_info
695
696 END SUBROUTINE
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zhgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alpha, beta, q, ldq, z, ldz, work, lwork, rwork, info)
ZHGEQZ
Definition zhgeqz.f:283
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
double precision function zlanhs(norm, n, a, lda, work)
ZLANHS returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
Definition zlanhs.f:107
recursive subroutine zlaqz0(wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb, alpha, beta, q, ldq, z, ldz, work, lwork, rwork, rec, info)
ZLAQZ0
Definition zlaqz0.f:283
recursive subroutine zlaqz2(ilschur, ilq, ilz, n, ilo, ihi, nw, a, lda, b, ldb, q, ldq, z, ldz, ns, nd, alpha, beta, qc, ldqc, zc, ldzc, work, lwork, rwork, rec, info)
ZLAQZ2
Definition zlaqz2.f:233
subroutine zlaqz3(ilschur, ilq, ilz, n, ilo, ihi, nshifts, nblock_desired, alpha, beta, a, lda, b, ldb, q, ldq, z, ldz, qc, ldqc, zc, ldzc, work, lwork, info)
ZLAQZ3
Definition zlaqz3.f:206
subroutine zlartg(f, g, c, s, r)
ZLARTG generates a plane rotation with real cosine and complex sine.
Definition zlartg.f90:116
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
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine zrot(n, cx, incx, cy, incy, c, s)
ZROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
Definition zrot.f:101