235 RECURSIVE SUBROUTINE dlaqz3( ILSCHUR, ILQ, ILZ, N, ILO, IHI, NW,
236 $ A, LDA, B, LDB, Q, LDQ, Z, LDZ, NS,
237 $ ND, ALPHAR, ALPHAI, BETA, QC, LDQC,
238 $ ZC, LDZC, WORK, LWORK, REC, INFO )
242 LOGICAL,
INTENT( IN ) :: ilschur, ilq, ilz
243 INTEGER,
INTENT( IN ) :: n, ilo, ihi, nw, lda, ldb, ldq, ldz,
244 $ ldqc, ldzc, lwork, rec
246 DOUBLE PRECISION,
INTENT( INOUT ) :: a( lda, * ), b( ldb, * ),
247 $ q( ldq, * ), z( ldz, * ), alphar( * ),
248 $ alphai( * ), beta( * )
249 INTEGER,
INTENT( OUT ) :: ns, nd, info
250 DOUBLE PRECISION :: qc( ldqc, * ), zc( ldzc, * ), work( * )
253 DOUBLE PRECISION :: zero, one, half
254 PARAMETER( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
258 INTEGER :: jw, kwtop, kwbot, istopm, istartm, k, k2, dtgexc_info,
259 $ ifst, ilst, lworkreq, qz_small_info
260 DOUBLE PRECISION :: s, smlnum, ulp, safmin, safmax, c1, s1, temp
265 DOUBLE PRECISION,
EXTERNAL ::
dlamch
270 jw = min( nw, ihi-ilo+1 )
272 IF ( kwtop .EQ. ilo )
THEN
275 s = a( kwtop, kwtop-1 )
281 CALL dtgexc( .true., .true., jw, a, lda, b, ldb, qc, ldqc, zc,
282 $ ldzc, ifst, ilst, work, -1, dtgexc_info )
283 lworkreq = int( work( 1 ) )
284 CALL dlaqz0(
'S',
'V',
'V', jw, 1, jw, a( kwtop, kwtop ), lda,
285 $ b( kwtop, kwtop ), ldb, alphar, alphai, beta, qc,
286 $ ldqc, zc, ldzc, work, -1, rec+1, qz_small_info )
287 lworkreq = max( lworkreq, int( work( 1 ) )+2*jw**2 )
288 lworkreq = max( lworkreq, n*nw, 2*nw**2+n )
289 IF ( lwork .EQ.-1 )
THEN
293 ELSE IF ( lwork .LT. lworkreq )
THEN
298 CALL xerbla(
'DLAQZ3', -info )
303 safmin =
dlamch(
'SAFE MINIMUM' )
305 CALL dlabad( safmin, safmax )
306 ulp =
dlamch(
'PRECISION' )
307 smlnum = safmin*( dble( n )/ulp )
309 IF ( ihi .EQ. kwtop )
THEN
311 alphar( kwtop ) = a( kwtop, kwtop )
312 alphai( kwtop ) = zero
313 beta( kwtop ) = b( kwtop, kwtop )
316 IF ( abs( s ) .LE. max( smlnum, ulp*abs( a( kwtop,
320 IF ( kwtop .GT. ilo )
THEN
321 a( kwtop, kwtop-1 ) = zero
328 CALL dlacpy(
'ALL', jw, jw, a( kwtop, kwtop ), lda, work, jw )
329 CALL dlacpy(
'ALL', jw, jw, b( kwtop, kwtop ), ldb, work( jw**2+
333 CALL dlaset(
'FULL', jw, jw, zero, one, qc, ldqc )
334 CALL dlaset(
'FULL', jw, jw, zero, one, zc, ldzc )
335 CALL dlaqz0(
'S',
'V',
'V', jw, 1, jw, a( kwtop, kwtop ), lda,
336 $ b( kwtop, kwtop ), ldb, alphar, alphai, beta, qc,
337 $ ldqc, zc, ldzc, work( 2*jw**2+1 ), lwork-2*jw**2,
338 $ rec+1, qz_small_info )
340 IF( qz_small_info .NE. 0 )
THEN
343 ns = jw-qz_small_info
344 CALL dlacpy(
'ALL', jw, jw, work, jw, a( kwtop, kwtop ), lda )
345 CALL dlacpy(
'ALL', jw, jw, work( jw**2+1 ), jw, b( kwtop,
351 IF ( kwtop .EQ. ilo .OR. s .EQ. zero )
THEN
357 DO WHILE ( k .LE. jw )
359 IF ( kwbot-kwtop+1 .GE. 2 )
THEN
360 bulge = a( kwbot, kwbot-1 ) .NE. zero
365 temp = abs( a( kwbot, kwbot ) )+sqrt( abs( a( kwbot,
366 $ kwbot-1 ) ) )*sqrt( abs( a( kwbot-1, kwbot ) ) )
367 IF( temp .EQ. zero )
THEN
370 IF ( max( abs( s*qc( 1, kwbot-kwtop ) ), abs( s*qc( 1,
371 $ kwbot-kwtop+1 ) ) ) .LE. max( smlnum,
379 CALL dtgexc( .true., .true., jw, a( kwtop, kwtop ),
380 $ lda, b( kwtop, kwtop ), ldb, qc, ldqc,
381 $ zc, ldzc, ifst, ilst, work, lwork,
389 temp = abs( a( kwbot, kwbot ) )
390 IF( temp .EQ. zero )
THEN
393 IF ( ( abs( s*qc( 1, kwbot-kwtop+1 ) ) ) .LE. max( ulp*
394 $ temp, smlnum ) )
THEN
401 CALL dtgexc( .true., .true., jw, a( kwtop, kwtop ),
402 $ lda, b( kwtop, kwtop ), ldb, qc, ldqc,
403 $ zc, ldzc, ifst, ilst, work, lwork,
418 DO WHILE ( k .LE. ihi )
420 IF ( k .LT. ihi )
THEN
421 IF ( a( k+1, k ) .NE. zero )
THEN
427 CALL dlag2( a( k, k ), lda, b( k, k ), ldb, safmin,
428 $ beta( k ), beta( k+1 ), alphar( k ),
429 $ alphar( k+1 ), alphai( k ) )
430 alphai( k+1 ) = -alphai( k )
434 alphar( k ) = a( k, k )
436 beta( k ) = b( k, k )
441 IF ( kwtop .NE. ilo .AND. s .NE. zero )
THEN
443 a( kwtop:kwbot, kwtop-1 ) = a( kwtop, kwtop-1 )*qc( 1,
445 DO k = kwbot-1, kwtop, -1
446 CALL dlartg( a( k, kwtop-1 ), a( k+1, kwtop-1 ), c1, s1,
448 a( k, kwtop-1 ) = temp
449 a( k+1, kwtop-1 ) = zero
450 k2 = max( kwtop, k-1 )
451 CALL drot( ihi-k2+1, a( k, k2 ), lda, a( k+1, k2 ), lda, c1,
453 CALL drot( ihi-( k-1 )+1, b( k, k-1 ), ldb, b( k+1, k-1 ),
455 CALL drot( jw, qc( 1, k-kwtop+1 ), 1, qc( 1, k+1-kwtop+1 ),
463 DO WHILE ( k .GE. kwtop )
464 IF ( ( k .GE. kwtop+1 ) .AND. a( k+1, k-1 ) .NE. zero )
THEN
468 CALL dlaqz2( .true., .true., k2, kwtop, kwtop+jw-1,
469 $ kwbot, a, lda, b, ldb, jw, kwtop, qc,
470 $ ldqc, jw, kwtop, zc, ldzc )
480 CALL dlartg( b( k2+1, k2+1 ), b( k2+1, k2 ), c1, s1,
482 b( k2+1, k2+1 ) = temp
484 CALL drot( k2+2-istartm+1, a( istartm, k2+1 ), 1,
485 $ a( istartm, k2 ), 1, c1, s1 )
486 CALL drot( k2-istartm+1, b( istartm, k2+1 ), 1,
487 $ b( istartm, k2 ), 1, c1, s1 )
488 CALL drot( jw, zc( 1, k2+1-kwtop+1 ), 1, zc( 1,
489 $ k2-kwtop+1 ), 1, c1, s1 )
491 CALL dlartg( a( k2+1, k2 ), a( k2+2, k2 ), c1, s1,
495 CALL drot( istopm-k2, a( k2+1, k2+1 ), lda, a( k2+2,
496 $ k2+1 ), lda, c1, s1 )
497 CALL drot( istopm-k2, b( k2+1, k2+1 ), ldb, b( k2+2,
498 $ k2+1 ), ldb, c1, s1 )
499 CALL drot( jw, qc( 1, k2+1-kwtop+1 ), 1, qc( 1,
500 $ k2+2-kwtop+1 ), 1, c1, s1 )
505 CALL dlartg( b( kwbot, kwbot ), b( kwbot, kwbot-1 ), c1,
507 b( kwbot, kwbot ) = temp
508 b( kwbot, kwbot-1 ) = zero
509 CALL drot( kwbot-istartm, b( istartm, kwbot ), 1,
510 $ b( istartm, kwbot-1 ), 1, c1, s1 )
511 CALL drot( kwbot-istartm+1, a( istartm, kwbot ), 1,
512 $ a( istartm, kwbot-1 ), 1, c1, s1 )
513 CALL drot( jw, zc( 1, kwbot-kwtop+1 ), 1, zc( 1,
514 $ kwbot-1-kwtop+1 ), 1, c1, s1 )
531 IF ( istopm-ihi > 0 )
THEN
532 CALL dgemm(
'T',
'N', jw, istopm-ihi, jw, one, qc, ldqc,
533 $ a( kwtop, ihi+1 ), lda, zero, work, jw )
534 CALL dlacpy(
'ALL', jw, istopm-ihi, work, jw, a( kwtop,
536 CALL dgemm(
'T',
'N', jw, istopm-ihi, jw, one, qc, ldqc,
537 $ b( kwtop, ihi+1 ), ldb, zero, work, jw )
538 CALL dlacpy(
'ALL', jw, istopm-ihi, work, jw, b( kwtop,
542 CALL dgemm(
'N',
'N', n, jw, jw, one, q( 1, kwtop ), ldq, qc,
543 $ ldqc, zero, work, n )
544 CALL dlacpy(
'ALL', n, jw, work, n, q( 1, kwtop ), ldq )
547 IF ( kwtop-1-istartm+1 > 0 )
THEN
548 CALL dgemm(
'N',
'N', kwtop-istartm, jw, jw, one, a( istartm,
549 $ kwtop ), lda, zc, ldzc, zero, work,
551 CALL dlacpy(
'ALL', kwtop-istartm, jw, work, kwtop-istartm,
552 $ a( istartm, kwtop ), lda )
553 CALL dgemm(
'N',
'N', kwtop-istartm, jw, jw, one, b( istartm,
554 $ kwtop ), ldb, zc, ldzc, zero, work,
556 CALL dlacpy(
'ALL', kwtop-istartm, jw, work, kwtop-istartm,
557 $ b( istartm, kwtop ), ldb )
560 CALL dgemm(
'N',
'N', n, jw, jw, one, z( 1, kwtop ), ldz, zc,
561 $ ldzc, zero, work, n )
562 CALL dlacpy(
'ALL', n, jw, work, n, z( 1, kwtop ), ldz )
double precision function dlamch(CMACH)
DLAMCH
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
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.
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine drot(N, DX, INCX, DY, INCY, C, S)
DROT
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dtgexc(WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z, LDZ, IFST, ILST, WORK, LWORK, INFO)
DTGEXC
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
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
subroutine dlaqz2(ILQ, ILZ, K, ISTARTM, ISTOPM, IHI, A, LDA, B, LDB, NQ, QSTART, Q, LDQ, NZ, ZSTART, Z, LDZ)
DLAQZ2
subroutine dlag2(A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1, WR2, WI)
DLAG2 computes the eigenvalues of a 2-by-2 generalized eigenvalue problem, with scaling as necessary ...