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 $ , ilst, lworkreq, qz_small_info
260 DOUBLE PRECISION :: s, smlnum, ulp, safmin, safmax, c1, s1, temp
265 DOUBLE PRECISION,
EXTERNAL ::
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
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,
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
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 )