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