238      IMPLICIT NONE
  239 
  240
  241      LOGICAL, INTENT( IN ) :: ILSCHUR, ILQ, ILZ
  242      INTEGER, INTENT( IN ) :: N, ILO, IHI, NW, LDA, LDB, LDQ, LDZ,
  243     $         LDQC, LDZC, LWORK, REC
  244 
  245      DOUBLE PRECISION, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ),
  246     $                  Q( LDQ, * ), Z( LDZ, * ), ALPHAR( * ),
  247     $                  ALPHAI( * ), BETA( * )
  248      INTEGER, INTENT( OUT ) :: NS, ND, INFO
  249      DOUBLE PRECISION :: QC( LDQC, * ), ZC( LDZC, * ), WORK( * )
  250 
  251
  252      DOUBLE PRECISION :: ZERO, ONE, HALF
  253      parameter( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
  254 
  255
  256      LOGICAL :: BULGE
  257      INTEGER :: JW, KWTOP, KWBOT, ISTOPM, ISTARTM, K, K2, DTGEXC_INFO,
  258     $           IFST, ILST, LWORKREQ, QZ_SMALL_INFO
  259      DOUBLE PRECISION :: S, SMLNUM, ULP, SAFMIN, SAFMAX, C1, S1, TEMP
  260 
  261
  264      DOUBLE PRECISION, EXTERNAL :: DLAMCH
  265 
  266      info = 0
  267 
  268
  269      jw = min( nw, ihi-ilo+1 )
  270      kwtop = ihi-jw+1
  271      IF ( kwtop .EQ. ilo ) THEN
  272         s = zero
  273      ELSE
  274         s = a( kwtop, kwtop-1 )
  275      END IF
  276 
  277
  278      ifst = 1
  279      ilst = jw
  280      CALL dtgexc( .true., .true., jw, a, lda, b, ldb, qc, ldqc, zc,
 
  281     $             ldzc, ifst, ilst, work, -1, dtgexc_info )
  282      lworkreq = int( work( 1 ) )
  283      CALL dlaqz0( 
'S', 
'V', 
'V', jw, 1, jw, a( kwtop, kwtop ), lda,
 
  284     $             b( kwtop, kwtop ), ldb, alphar, alphai, beta, qc,
  285     $             ldqc, zc, ldzc, work, -1, rec+1, qz_small_info )
  286      lworkreq = max( lworkreq, int( work( 1 ) )+2*jw**2 )
  287      lworkreq = max( lworkreq, n*nw, 2*nw**2+n )
  288      IF ( lwork .EQ.-1 ) THEN
  289
  290         work( 1 ) = lworkreq
  291         RETURN
  292      ELSE IF ( lwork .LT. lworkreq ) THEN
  293         info = -26
  294      END IF
  295 
  296      IF( info.NE.0 ) THEN
  297         CALL xerbla( 
'DLAQZ3', -info )
 
  298         RETURN
  299      END IF
  300 
  301
  302      safmin = 
dlamch( 
'SAFE MINIMUM' )
 
  303      safmax = one/safmin
  304      ulp = 
dlamch( 
'PRECISION' )
 
  305      smlnum = safmin*( dble( n )/ulp )
  306 
  307      IF ( ihi .EQ. kwtop ) THEN
  308
  309         alphar( kwtop ) = a( kwtop, kwtop )
  310         alphai( kwtop ) = zero
  311         beta( kwtop ) = b( kwtop, kwtop )
  312         ns = 1
  313         nd = 0
  314         IF ( abs( s ) .LE. max( smlnum, ulp*abs( a( kwtop,
  315     $      kwtop ) ) ) ) THEN
  316            ns = 0
  317            nd = 1
  318            IF ( kwtop .GT. ilo ) THEN
  319               a( kwtop, kwtop-1 ) = zero
  320            END IF
  321         END IF
  322      END IF
  323 
  324 
  325
  326      CALL dlacpy( 
'ALL', jw, jw, a( kwtop, kwtop ), lda, work, jw )
 
  327      CALL dlacpy( 
'ALL', jw, jw, b( kwtop, kwtop ), ldb,
 
  328     $             work( jw**2+
  329     $             1 ), jw )
  330 
  331
  332      CALL dlaset( 
'FULL', jw, jw, zero, one, qc, ldqc )
 
  333      CALL dlaset( 
'FULL', jw, jw, zero, one, zc, ldzc )
 
  334      CALL dlaqz0( 
'S', 
'V', 
'V', jw, 1, jw, a( kwtop, kwtop ), lda,
 
  335     $             b( kwtop, kwtop ), ldb, alphar, alphai, beta, qc,
  336     $             ldqc, zc, ldzc, work( 2*jw**2+1 ), lwork-2*jw**2,
  337     $             rec+1, qz_small_info )
  338 
  339      IF( qz_small_info .NE. 0 ) THEN
  340
  341         nd = 0
  342         ns = jw-qz_small_info
  343         CALL dlacpy( 
'ALL', jw, jw, work, jw, a( kwtop, kwtop ),
 
  344     $                lda )
  345         CALL dlacpy( 
'ALL', jw, jw, work( jw**2+1 ), jw, b( kwtop,
 
  346     $                kwtop ), ldb )
  347         RETURN
  348      END IF
  349 
  350
  351      IF ( kwtop .EQ. ilo .OR. s .EQ. zero ) THEN
  352         kwbot = kwtop-1
  353      ELSE
  354         kwbot = ihi
  355         k = 1
  356         k2 = 1
  357         DO WHILE ( k .LE. jw )
  358            bulge = .false.
  359            IF ( kwbot-kwtop+1 .GE. 2 ) THEN
  360               bulge = a( kwbot, kwbot-1 ) .NE. zero
  361            END IF
  362            IF ( bulge ) THEN
  363 
  364
  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
  368                  temp = abs( s )
  369               END IF
  370               IF ( max( abs( s*qc( 1, kwbot-kwtop ) ), abs( s*qc( 1,
  371     $            kwbot-kwtop+1 ) ) ) .LE. max( smlnum,
  372     $            ulp*temp ) ) THEN
  373
  374                  kwbot = kwbot-2
  375               ELSE
  376
  377                  ifst = kwbot-kwtop+1
  378                  ilst = k2
  379                  CALL dtgexc( .true., .true., jw, a( kwtop, kwtop ),
 
  380     $                         lda, b( kwtop, kwtop ), ldb, qc, ldqc,
  381     $                         zc, ldzc, ifst, ilst, work, lwork,
  382     $                         dtgexc_info )
  383                  k2 = k2+2
  384               END IF
  385               k = k+2
  386            ELSE
  387 
  388
  389               temp = abs( a( kwbot, kwbot ) )
  390               IF( temp .EQ. zero ) THEN
  391                  temp = abs( s )
  392               END IF
  393               IF ( ( abs( s*qc( 1, kwbot-kwtop+1 ) ) ) .LE. max( ulp*
  394     $            temp, smlnum ) ) THEN
  395
  396                  kwbot = kwbot-1
  397               ELSE
  398
  399                  ifst = kwbot-kwtop+1
  400                  ilst = k2
  401                  CALL dtgexc( .true., .true., jw, a( kwtop, kwtop ),
 
  402     $                         lda, b( kwtop, kwtop ), ldb, qc, ldqc,
  403     $                         zc, ldzc, ifst, ilst, work, lwork,
  404     $                         dtgexc_info )
  405                  k2 = k2+1
  406               END IF
  407 
  408               k = k+1
  409 
  410            END IF
  411         END DO
  412      END IF
  413 
  414
  415      nd = ihi-kwbot
  416      ns = jw-nd
  417      k = kwtop
  418      DO WHILE ( k .LE. ihi )
  419         bulge = .false.
  420         IF ( k .LT. ihi ) THEN
  421            IF ( a( k+1, k ) .NE. zero ) THEN
  422               bulge = .true.
  423            END IF
  424         END IF
  425         IF ( bulge ) THEN
  426
  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 )
  431            k = k+2
  432         ELSE
  433
  434            alphar( k ) = a( k, k )
  435            alphai( k ) = zero
  436            beta( k ) = b( k, k )
  437            k = k+1
  438         END IF
  439      END DO
  440 
  441      IF ( kwtop .NE. ilo .AND. s .NE. zero ) THEN
  442
  443         a( kwtop:kwbot, kwtop-1 ) = a( kwtop, kwtop-1 )*qc( 1,
  444     $      1:jw-nd )
  445         DO k = kwbot-1, kwtop, -1
  446            CALL dlartg( a( k, kwtop-1 ), a( k+1, kwtop-1 ), c1, s1,
 
  447     $                   temp )
  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,
 
  452     $                 c1,
  453     $                 s1 )
  454            CALL drot( ihi-( k-1 )+1, b( k, k-1 ), ldb, b( k+1,
 
  455     $                 k-1 ),
  456     $                 ldb, c1, s1 )
  457            CALL drot( jw, qc( 1, k-kwtop+1 ), 1, qc( 1,
 
  458     $                 k+1-kwtop+1 ),
  459     $                 1, c1, s1 )
  460         END DO
  461 
  462
  463         istartm = kwtop
  464         istopm = ihi
  465         k = kwbot-1
  466         DO WHILE ( k .GE. kwtop )
  467            IF ( ( k .GE. kwtop+1 ) .AND. a( k+1, k-1 ) .NE. zero ) THEN
  468 
  469
  470               DO k2 = k-1, kwbot-2
  471                  CALL dlaqz2( .true., .true., k2, kwtop, kwtop+jw-1,
 
  472     $                         kwbot, a, lda, b, ldb, jw, kwtop, qc,
  473     $                         ldqc, jw, kwtop, zc, ldzc )
  474               END DO
  475 
  476               k = k-2
  477            ELSE
  478 
  479
  480               DO k2 = k, kwbot-2
  481 
  482
  483                  CALL dlartg( b( k2+1, k2+1 ), b( k2+1, k2 ), c1,
 
  484     $                         s1,
  485     $                         temp )
  486                  b( k2+1, k2+1 ) = temp
  487                  b( k2+1, k2 ) = zero
  488                  CALL drot( k2+2-istartm+1, a( istartm, k2+1 ), 1,
 
  489     $                       a( istartm, k2 ), 1, c1, s1 )
  490                  CALL drot( k2-istartm+1, b( istartm, k2+1 ), 1,
 
  491     $                       b( istartm, k2 ), 1, c1, s1 )
  492                  CALL drot( jw, zc( 1, k2+1-kwtop+1 ), 1, zc( 1,
 
  493     $                       k2-kwtop+1 ), 1, c1, s1 )
  494            
  495                  CALL dlartg( a( k2+1, k2 ), a( k2+2, k2 ), c1, s1,
 
  496     $                         temp )
  497                  a( k2+1, k2 ) = temp
  498                  a( k2+2, k2 ) = zero
  499                  CALL drot( istopm-k2, a( k2+1, k2+1 ), lda,
 
  500     $                       a( k2+2,
  501     $                       k2+1 ), lda, c1, s1 )
  502                  CALL drot( istopm-k2, b( k2+1, k2+1 ), ldb,
 
  503     $                       b( k2+2,
  504     $                       k2+1 ), ldb, c1, s1 )
  505                  CALL drot( jw, qc( 1, k2+1-kwtop+1 ), 1, qc( 1,
 
  506     $                       k2+2-kwtop+1 ), 1, c1, s1 )
  507 
  508               END DO
  509 
  510
  511               CALL dlartg( b( kwbot, kwbot ), b( kwbot, kwbot-1 ),
 
  512     $                      c1,
  513     $                      s1, temp )
  514               b( kwbot, kwbot ) = temp
  515               b( kwbot, kwbot-1 ) = zero
  516               CALL drot( kwbot-istartm, b( istartm, kwbot ), 1,
 
  517     $                    b( istartm, kwbot-1 ), 1, c1, s1 )
  518               CALL drot( kwbot-istartm+1, a( istartm, kwbot ), 1,
 
  519     $                    a( istartm, kwbot-1 ), 1, c1, s1 )
  520               CALL drot( jw, zc( 1, kwbot-kwtop+1 ), 1, zc( 1,
 
  521     $                    kwbot-1-kwtop+1 ), 1, c1, s1 )
  522 
  523               k = k-1
  524            END IF
  525         END DO
  526 
  527      END IF
  528 
  529
  530      IF ( ilschur ) THEN
  531         istartm = 1
  532         istopm = n
  533      ELSE
  534         istartm = ilo
  535         istopm = ihi
  536      END IF
  537 
  538      IF ( istopm-ihi > 0 ) THEN
  539         CALL dgemm( 
'T', 
'N', jw, istopm-ihi, jw, one, qc, ldqc,
 
  540     $               a( kwtop, ihi+1 ), lda, zero, work, jw )
  541         CALL dlacpy( 
'ALL', jw, istopm-ihi, work, jw, a( kwtop,
 
  542     $                ihi+1 ), lda )
  543         CALL dgemm( 
'T', 
'N', jw, istopm-ihi, jw, one, qc, ldqc,
 
  544     $               b( kwtop, ihi+1 ), ldb, zero, work, jw )
  545         CALL dlacpy( 
'ALL', jw, istopm-ihi, work, jw, b( kwtop,
 
  546     $                ihi+1 ), ldb )
  547      END IF
  548      IF ( ilq ) THEN
  549         CALL dgemm( 
'N', 
'N', n, jw, jw, one, q( 1, kwtop ), ldq,
 
  550     $               qc,
  551     $               ldqc, zero, work, n )
  552         CALL dlacpy( 
'ALL', n, jw, work, n, q( 1, kwtop ), ldq )
 
  553      END IF
  554 
  555      IF ( kwtop-1-istartm+1 > 0 ) THEN
  556         CALL dgemm( 
'N', 
'N', kwtop-istartm, jw, jw, one,
 
  557     $               a( istartm,
  558     $               kwtop ), lda, zc, ldzc, zero, work,
  559     $               kwtop-istartm )
  560         CALL dlacpy( 
'ALL', kwtop-istartm, jw, work, kwtop-istartm,
 
  561     $                a( istartm, kwtop ), lda )
  562         CALL dgemm( 
'N', 
'N', kwtop-istartm, jw, jw, one,
 
  563     $               b( istartm,
  564     $               kwtop ), ldb, zc, ldzc, zero, work,
  565     $               kwtop-istartm )
  566         CALL dlacpy( 
'ALL', kwtop-istartm, jw, work, kwtop-istartm,
 
  567     $                b( istartm, kwtop ), ldb )
  568      END IF
  569      IF ( ilz ) THEN
  570         CALL dgemm( 
'N', 
'N', n, jw, jw, one, z( 1, kwtop ), ldz,
 
  571     $               zc,
  572     $               ldzc, zero, work, n )
  573         CALL dlacpy( 
'ALL', n, jw, work, n, z( 1, kwtop ), ldz )
 
  574      END IF
  575 
subroutine xerbla(srname, info)
 
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
 
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
 
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 ...
 
double precision function dlamch(cmach)
DLAMCH
 
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
 
subroutine dlaqz2(ilq, ilz, k, istartm, istopm, ihi, a, lda, b, ldb, nq, qstart, q, ldq, nz, zstart, z, ldz)
DLAQZ2
 
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 drot(n, dx, incx, dy, incy, c, s)
DROT
 
subroutine dtgexc(wantq, wantz, n, a, lda, b, ldb, q, ldq, z, ldz, ifst, ilst, work, lwork, info)
DTGEXC