OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
slaqz0.f
Go to the documentation of this file.
1*> \brief \b SLAQZ0
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download SLAQZ0 + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slaqz0.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slaqz0.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slaqz0.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE SLAQZ0( WANTS, WANTQ, WANTZ, N, ILO, IHI, A, LDA, B,
22* $ LDB, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, REC,
23* $ INFO )
24* IMPLICIT NONE
25*
26* Arguments
27* CHARACTER, INTENT( IN ) :: WANTS, WANTQ, WANTZ
28* INTEGER, INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
29* $ REC
30*
31* INTEGER, INTENT( OUT ) :: INFO
32*
33* REAL, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
34* $ Z( LDZ, * ), ALPHAR( * ), ALPHAI( * ), BETA( * ), WORK( * )
35* ..
36*
37*
38*> \par Purpose:
39* =============
40*>
41*> \verbatim
42*>
43*> SLAQZ0 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 SGGHRD.
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 SGGHRD 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 agressive 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 REAL 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 REAL 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 REAL 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 REAL 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 REAL 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 REAL 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 REAL 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 REAL 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 doubleGEcomputational
298*>
299* =====================================================================
300 RECURSIVE SUBROUTINE slaqz0( WANTS, WANTQ, WANTZ, N, ILO, IHI, A,
301 $ LDA, B, LDB, ALPHAR, ALPHAI, BETA,
302 $ Q, LDQ, Z, LDZ, WORK, LWORK, REC,
303 $ INFO )
304 IMPLICIT NONE
305
306* Arguments
307 CHARACTER, INTENT( IN ) :: wants, wantq, wantz
308 INTEGER, INTENT( IN ) :: n, ilo, ihi, lda, ldb, ldq, ldz, lwork,
309 $ rec
310
311 INTEGER, INTENT( OUT ) :: info
312
313 REAL, INTENT( INOUT ) :: a( lda, * ), b( ldb, * ), q( ldq, * ),
314 $ z( ldz, * ), alphar( * ), alphai( * ), beta( * ), work( * )
315
316* Parameters
317 REAL :: zero, one, HALF
318 PARAMETER( zero = 0.0, one = 1.0, half = 0.5 )
319
320* Local scalars
321 REAL :: smlnum, ulp, eshift, safmin, safmax, c1, s1, temp, swap
322 INTEGER :: istart, istop, iiter, maxit, istart2, k, ld, nshifts,
323 $ nblock, nw, nmin, nibble, n_undeflated, n_deflated,
324 $ ns, sweep_info, shiftpos, lworkreq, k2, istartm,
325 $ istopm, iwants, iwantq, iwantz, norm_info, aed_info,
326 $ nwr, nbr, nsr, itemp1, itemp2, rcost, i
327 LOGICAL :: ilschur, ILQ, ilz
328 CHARACTER :: jbcmpz*3
329
330* External Functions
331 EXTERNAL :: xerbla, shgeqz, slaqz3, slaqz4, slaset, slabad,
332 $ slartg, srot
333 REAL, EXTERNAL :: slamch
334 LOGICAL, EXTERNAL :: lsame
335 INTEGER, EXTERNAL :: ilaenv
336
337*
338* Decode wantS,wantQ,wantZ
339*
340 IF( lsame( wants, 'E' ) ) THEN
341 ilschur = .false.
342 iwants = 1
343 ELSE IF( lsame( wants, 'S' ) ) THEN
344 ilschur = .true.
345 iwants = 2
346 ELSE
347 iwants = 0
348 END IF
349
350 IF( lsame( wantq, 'N' ) ) THEN
351 ilq = .false.
352 iwantq = 1
353 ELSE IF( lsame( wantq, 'V' ) ) THEN
354 ilq = .true.
355 iwantq = 2
356 ELSE IF( lsame( wantq, 'I' ) ) THEN
357 ilq = .true.
358 iwantq = 3
359 ELSE
360 iwantq = 0
361 END IF
362
363 IF( lsame( wantz, 'N' ) ) THEN
364 ilz = .false.
365 iwantz = 1
366 ELSE IF( lsame( wantz, 'V' ) ) THEN
367 ilz = .true.
368 iwantz = 2
369 ELSE IF( lsame( wantz, 'I' ) ) THEN
370 ilz = .true.
371 iwantz = 3
372 ELSE
373 iwantz = 0
374 END IF
375*
376* Check Argument Values
377*
378 info = 0
379 IF( iwants.EQ.0 ) THEN
380 info = -1
381 ELSE IF( iwantq.EQ.0 ) THEN
382 info = -2
383 ELSE IF( iwantz.EQ.0 ) THEN
384 info = -3
385 ELSE IF( n.LT.0 ) THEN
386 info = -4
387 ELSE IF( ilo.LT.1 ) THEN
388 info = -5
389 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 ) THEN
390 info = -6
391 ELSE IF( lda.LT.n ) THEN
392 info = -8
393 ELSE IF( ldb.LT.n ) THEN
394 info = -10
395 ELSE IF( ldq.LT.1 .OR. ( ilq .AND. ldq.LT.n ) ) THEN
396 info = -15
397 ELSE IF( ldz.LT.1 .OR. ( ilz .AND. ldz.LT.n ) ) THEN
398 info = -17
399 END IF
400 IF( info.NE.0 ) THEN
401 CALL xerbla( 'SLAQZ0', -info )
402 RETURN
403 END IF
404
405*
406* Quick return if possible
407*
408 IF( n.LE.0 ) THEN
409 work( 1 ) = real( 1 )
410 RETURN
411 END IF
412
413*
414* Get the parameters
415*
416 jbcmpz( 1:1 ) = wants
417 jbcmpz( 2:2 ) = wantq
418 jbcmpz( 3:3 ) = wantz
419
420 nmin = ilaenv( 12, 'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
421
422 nwr = ilaenv( 13, 'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
423 nwr = max( 2, nwr )
424 nwr = min( ihi-ilo+1, ( n-1 ) / 3, nwr )
425
426 nibble = ilaenv( 14, 'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
427
428 nsr = ilaenv( 15, 'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
429 nsr = min( nsr, ( n+6 ) / 9, ihi-ilo )
430 nsr = max( 2, nsr-mod( nsr, 2 ) )
431
432 rcost = ilaenv( 17, 'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
433 itemp1 = int( nsr/sqrt( 1+2*nsr/( real( rcost )/100*n ) ) )
434 itemp1 = ( ( itemp1-1 )/4 )*4+4
435 nbr = nsr+itemp1
436
437 IF( n .LT. nmin .OR. rec .GE. 2 ) THEN
438 CALL shgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
439 $ alphar, alphai, beta, q, ldq, z, ldz, work,
440 $ lwork, info )
441 RETURN
442 END IF
443
444*
445* Find out required workspace
446*
447
448* Workspace query to slaqz3
449 nw = max( nwr, nmin )
450 CALL slaqz3( ilschur, ilq, ilz, n, ilo, ihi, nw, a, lda, b, ldb,
451 $ q, ldq, z, ldz, n_undeflated, n_deflated, alphar,
452 $ alphai, beta, work, nw, work, nw, work, -1, rec,
453 $ aed_info )
454 itemp1 = int( work( 1 ) )
455* Workspace query to slaqz4
456 CALL slaqz4( ilschur, ilq, ilz, n, ilo, ihi, nsr, nbr, alphar,
457 $ alphai, beta, a, lda, b, ldb, q, ldq, z, ldz, work,
458 $ nbr, work, nbr, work, -1, sweep_info )
459 itemp2 = int( work( 1 ) )
460
461 lworkreq = max( itemp1+2*nw**2, itemp2+2*nbr**2 )
462 IF ( lwork .EQ.-1 ) THEN
463 work( 1 ) = real( lworkreq )
464 RETURN
465 ELSE IF ( lwork .LT. lworkreq ) THEN
466 info = -19
467 END IF
468 IF( info.NE.0 ) THEN
469 CALL xerbla( 'SLAQZ0', info )
470 RETURN
471 END IF
472*
473* Initialize Q and Z
474*
475 IF( iwantq.EQ.3 ) CALL slaset( 'FULL', n, n, zero, one, q, ldq )
476 IF( iwantz.EQ.3 ) CALL slaset( 'FULL', n, n, zero, one, z, ldz )
477
478* Get machine constants
479 safmin = slamch( 'safe minimum' )
480 SAFMAX = ONE/SAFMIN
481 CALL SLABAD( SAFMIN, SAFMAX )
482 ULP = SLAMCH( 'precision' )
483 SMLNUM = SAFMIN*( REAL( N )/ULP )
484
485 ISTART = ILO
486 ISTOP = IHI
487 MAXIT = 3*( IHI-ILO+1 )
488 LD = 0
489
490 DO IITER = 1, MAXIT
491.GE. IF( IITER MAXIT ) THEN
492 INFO = ISTOP+1
493 GOTO 80
494 END IF
495.GE. IF ( ISTART+1 ISTOP ) THEN
496 ISTOP = ISTART
497 EXIT
498 END IF
499
500* Check deflations at the end
501.LE. IF ( ABS( A( ISTOP-1, ISTOP-2 ) ) MAX( SMLNUM,
502 $ ULP*( ABS( A( ISTOP-1, ISTOP-1 ) )+ABS( A( ISTOP-2,
503 $ ISTOP-2 ) ) ) ) ) THEN
504 A( ISTOP-1, ISTOP-2 ) = ZERO
505 ISTOP = ISTOP-2
506 LD = 0
507 ESHIFT = ZERO
508.LE. ELSE IF ( ABS( A( ISTOP, ISTOP-1 ) ) MAX( SMLNUM,
509 $ ULP*( ABS( A( ISTOP, ISTOP ) )+ABS( A( ISTOP-1,
510 $ ISTOP-1 ) ) ) ) ) THEN
511 A( ISTOP, ISTOP-1 ) = ZERO
512 ISTOP = ISTOP-1
513 LD = 0
514 ESHIFT = ZERO
515 END IF
516* Check deflations at the start
517.LE. IF ( ABS( A( ISTART+2, ISTART+1 ) ) MAX( SMLNUM,
518 $ ULP*( ABS( A( ISTART+1, ISTART+1 ) )+ABS( A( ISTART+2,
519 $ ISTART+2 ) ) ) ) ) THEN
520 A( ISTART+2, ISTART+1 ) = ZERO
521 ISTART = ISTART+2
522 LD = 0
523 ESHIFT = ZERO
524.LE. ELSE IF ( ABS( A( ISTART+1, ISTART ) ) MAX( SMLNUM,
525 $ ULP*( ABS( A( ISTART, ISTART ) )+ABS( A( ISTART+1,
526 $ ISTART+1 ) ) ) ) ) THEN
527 A( ISTART+1, ISTART ) = ZERO
528 ISTART = ISTART+1
529 LD = 0
530 ESHIFT = ZERO
531 END IF
532
533.GE. IF ( ISTART+1 ISTOP ) THEN
534 EXIT
535 END IF
536
537* Check interior deflations
538 ISTART2 = ISTART
539 DO K = ISTOP, ISTART+1, -1
540.LE. IF ( ABS( A( K, K-1 ) ) MAX( SMLNUM, ULP*( ABS( A( K,
541 $ K ) )+ABS( A( K-1, K-1 ) ) ) ) ) THEN
542 A( K, K-1 ) = ZERO
543 ISTART2 = K
544 EXIT
545 END IF
546 END DO
547
548* Get range to apply rotations to
549 IF ( ILSCHUR ) THEN
550 ISTARTM = 1
551 ISTOPM = N
552 ELSE
553 ISTARTM = ISTART2
554 ISTOPM = ISTOP
555 END IF
556
557* Check infinite eigenvalues, this is done without blocking so might
558* slow down the method when many infinite eigenvalues are present
559 K = ISTOP
560.GE. DO WHILE ( KISTART2 )
561 TEMP = ZERO
562.LT. IF( K ISTOP ) THEN
563 TEMP = TEMP+ABS( B( K, K+1 ) )
564 END IF
565.GT. IF( K ISTART2 ) THEN
566 TEMP = TEMP+ABS( B( K-1, K ) )
567 END IF
568
569.LT. IF( ABS( B( K, K ) ) MAX( SMLNUM, ULP*TEMP ) ) THEN
570* A diagonal element of B is negligable, move it
571* to the top and deflate it
572
573 DO K2 = K, ISTART2+1, -1
574 CALL SLARTG( B( K2-1, K2 ), B( K2-1, K2-1 ), C1, S1,
575 $ TEMP )
576 B( K2-1, K2 ) = TEMP
577 B( K2-1, K2-1 ) = ZERO
578
579 CALL SROT( K2-2-ISTARTM+1, B( ISTARTM, K2 ), 1,
580 $ B( ISTARTM, K2-1 ), 1, C1, S1 )
581 CALL SROT( MIN( K2+1, ISTOP )-ISTARTM+1, A( ISTARTM,
582 $ K2 ), 1, A( ISTARTM, K2-1 ), 1, C1, S1 )
583 IF ( ILZ ) THEN
584 CALL SROT( N, Z( 1, K2 ), 1, Z( 1, K2-1 ), 1, C1,
585 $ S1 )
586 END IF
587
588.LT. IF( K2ISTOP ) THEN
589 CALL SLARTG( A( K2, K2-1 ), A( K2+1, K2-1 ), C1,
590 $ S1, TEMP )
591 A( K2, K2-1 ) = TEMP
592 A( K2+1, K2-1 ) = ZERO
593
594 CALL SROT( ISTOPM-K2+1, A( K2, K2 ), LDA, A( K2+1,
595 $ K2 ), LDA, C1, S1 )
596 CALL SROT( ISTOPM-K2+1, B( K2, K2 ), LDB, B( K2+1,
597 $ K2 ), LDB, C1, S1 )
598 IF( ILQ ) THEN
599 CALL SROT( N, Q( 1, K2 ), 1, Q( 1, K2+1 ), 1,
600 $ C1, S1 )
601 END IF
602 END IF
603
604 END DO
605
606.LT. IF( ISTART2ISTOP )THEN
607 CALL SLARTG( A( ISTART2, ISTART2 ), A( ISTART2+1,
608 $ ISTART2 ), C1, S1, TEMP )
609 A( ISTART2, ISTART2 ) = TEMP
610 A( ISTART2+1, ISTART2 ) = ZERO
611
612 CALL SROT( ISTOPM-( ISTART2+1 )+1, A( ISTART2,
613 $ ISTART2+1 ), LDA, A( ISTART2+1,
614 $ ISTART2+1 ), LDA, C1, S1 )
615 CALL SROT( ISTOPM-( ISTART2+1 )+1, B( ISTART2,
616 $ ISTART2+1 ), LDB, B( ISTART2+1,
617 $ ISTART2+1 ), LDB, C1, S1 )
618 IF( ILQ ) THEN
619 CALL SROT( N, Q( 1, ISTART2 ), 1, Q( 1,
620 $ ISTART2+1 ), 1, C1, S1 )
621 END IF
622 END IF
623
624 ISTART2 = ISTART2+1
625
626 END IF
627 K = K-1
628 END DO
629
630* istart2 now points to the top of the bottom right
631* unreduced Hessenberg block
632.GE. IF ( ISTART2 ISTOP ) THEN
633 ISTOP = ISTART2-1
634 LD = 0
635 ESHIFT = ZERO
636 CYCLE
637 END IF
638
639 NW = NWR
640 NSHIFTS = NSR
641 NBLOCK = NBR
642
643.LT. IF ( ISTOP-ISTART2+1 NMIN ) THEN
644* Setting nw to the size of the subblock will make AED deflate
645* all the eigenvalues. This is slightly more efficient than just
646* using qz_small because the off diagonal part gets updated via BLAS.
647.LT. IF ( ISTOP-ISTART+1 NMIN ) THEN
648 NW = ISTOP-ISTART+1
649 ISTART2 = ISTART
650 ELSE
651 NW = ISTOP-ISTART2+1
652 END IF
653 END IF
654
655*
656* Time for AED
657*
658 CALL SLAQZ3( ILSCHUR, ILQ, ILZ, N, ISTART2, ISTOP, NW, A, LDA,
659 $ B, LDB, Q, LDQ, Z, LDZ, N_UNDEFLATED, N_DEFLATED,
660 $ ALPHAR, ALPHAI, BETA, WORK, NW, WORK( NW**2+1 ),
661 $ NW, WORK( 2*NW**2+1 ), LWORK-2*NW**2, REC,
662 $ AED_INFO )
663
664 IF ( N_DEFLATED > 0 ) THEN
665 ISTOP = ISTOP-N_DEFLATED
666 LD = 0
667 ESHIFT = ZERO
668 END IF
669
670.OR. IF ( 100*N_DEFLATED > NIBBLE*( N_DEFLATED+N_UNDEFLATED )
671.LT. $ ISTOP-ISTART2+1 NMIN ) THEN
672* AED has uncovered many eigenvalues. Skip a QZ sweep and run
673* AED again.
674 CYCLE
675 END IF
676
677 LD = LD+1
678
679 NS = MIN( NSHIFTS, ISTOP-ISTART2 )
680 NS = MIN( NS, N_UNDEFLATED )
681 SHIFTPOS = ISTOP-N_DEFLATED-N_UNDEFLATED+1
682*
683* Shuffle shifts to put double shifts in front
684* This ensures that we don't split up a double shift
685*
686 DO I = SHIFTPOS, SHIFTPOS+N_UNDEFLATED-1, 2
687.NE. IF( ALPHAI( I )-ALPHAI( I+1 ) ) THEN
688*
689 SWAP = ALPHAR( I )
690 ALPHAR( I ) = ALPHAR( I+1 )
691 ALPHAR( I+1 ) = ALPHAR( I+2 )
692 ALPHAR( I+2 ) = SWAP
693
694 SWAP = ALPHAI( I )
695 ALPHAI( I ) = ALPHAI( I+1 )
696 ALPHAI( I+1 ) = ALPHAI( I+2 )
697 ALPHAI( I+2 ) = SWAP
698
699 SWAP = BETA( I )
700 BETA( I ) = BETA( I+1 )
701 BETA( I+1 ) = BETA( I+2 )
702 BETA( I+2 ) = SWAP
703 END IF
704 END DO
705
706.EQ. IF ( MOD( LD, 6 ) 0 ) THEN
707*
708* Exceptional shift. Chosen for no particularly good reason.
709*
710 IF( ( REAL( MAXIT )*SAFMIN )*ABS( A( ISTOP,
711.LT. $ ISTOP-1 ) )ABS( A( ISTOP-1, ISTOP-1 ) ) ) THEN
712 ESHIFT = A( ISTOP, ISTOP-1 )/B( ISTOP-1, ISTOP-1 )
713 ELSE
714 ESHIFT = ESHIFT+ONE/( SAFMIN*REAL( MAXIT ) )
715 END IF
716 ALPHAR( SHIFTPOS ) = ONE
717 ALPHAR( SHIFTPOS+1 ) = ZERO
718 ALPHAI( SHIFTPOS ) = ZERO
719 ALPHAI( SHIFTPOS+1 ) = ZERO
720 BETA( SHIFTPOS ) = ESHIFT
721 BETA( SHIFTPOS+1 ) = ESHIFT
722 NS = 2
723 END IF
724
725*
726* Time for a QZ sweep
727*
728 CALL SLAQZ4( ILSCHUR, ILQ, ILZ, N, ISTART2, ISTOP, NS, NBLOCK,
729 $ ALPHAR( SHIFTPOS ), ALPHAI( SHIFTPOS ),
730 $ BETA( SHIFTPOS ), A, LDA, B, LDB, Q, LDQ, Z, LDZ,
731 $ WORK, NBLOCK, WORK( NBLOCK**2+1 ), NBLOCK,
732 $ WORK( 2*NBLOCK**2+1 ), LWORK-2*NBLOCK**2,
733 $ SWEEP_INFO )
734
735 END DO
736
737*
738* Call SHGEQZ to normalize the eigenvalue blocks and set the eigenvalues
739* If all the eigenvalues have been found, SHGEQZ will not do any iterations
740* and only normalize the blocks. In case of a rare convergence failure,
741* the single shift might perform better.
742*
743 80 CALL SHGEQZ( WANTS, WANTQ, WANTZ, N, ILO, IHI, A, LDA, B, LDB,
744 $ ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK,
745 $ NORM_INFO )
746
747 INFO = NORM_INFO
748
749 END SUBROUTINE
subroutine slabad(small, large)
SLABAD
Definition slabad.f:74
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition slaset.f:110
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
Definition slartg.f90:113
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:162
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
logical function lsame(ca, cb)
LSAME
Definition lsame.f:53
subroutine slaqz4(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)
SLAQZ4
Definition slaqz4.f:214
recursive subroutine slaqz3(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)
SLAQZ3
Definition slaqz3.f:238
recursive subroutine slaqz0(wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, rec, info)
SLAQZ0
Definition slaqz0.f:304
subroutine shgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
SHGEQZ
Definition shgeqz.f:304
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT
Definition srot.f:92
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
#define swap(a, b, tmp)
Definition macros.h:40
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21