206      IMPLICIT NONE
  207 
  208
  209      LOGICAL, INTENT( IN ) :: ILSCHUR, ILQ, ILZ
  210      INTEGER, INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
  211     $         NSHIFTS, NBLOCK_DESIRED, LDQC, LDZC
  212 
  213      COMPLEX*16, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ,
  214     $   * ), Z( LDZ, * ), QC( LDQC, * ), ZC( LDZC, * ), WORK( * ),
  215     $   ALPHA( * ), BETA( * )
  216 
  217      INTEGER, INTENT( OUT ) :: INFO
  218 
  219
  220      COMPLEX*16         CZERO, CONE
  221      parameter( czero = ( 0.0d+0, 0.0d+0 ), cone = ( 1.0d+0,
  222     $                     0.0d+0 ) )
  223      DOUBLE PRECISION :: ZERO, ONE, HALF
  224      parameter( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
  225 
  226
  227      INTEGER :: I, J, NS, ISTARTM, ISTOPM, SHEIGHT, SWIDTH, K, NP,
  228     $           ISTARTB, ISTOPB, ISHIFT, NBLOCK, NPOS
  229      DOUBLE PRECISION :: SAFMIN, SAFMAX, C, SCALE
  230      COMPLEX*16 :: TEMP, TEMP2, TEMP3, S
  231 
  232
  235      DOUBLE PRECISION, EXTERNAL :: DLAMCH
  236 
  237      info = 0
  238      IF ( nblock_desired .LT. nshifts+1 ) THEN
  239         info = -8
  240      END IF
  241      IF ( lwork .EQ.-1 ) THEN
  242
  243         work( 1 ) = n*nblock_desired
  244         RETURN
  245      ELSE IF ( lwork .LT. n*nblock_desired ) THEN
  246         info = -25
  247      END IF
  248 
  249      IF( info.NE.0 ) THEN
  250         CALL xerbla( 
'ZLAQZ3', -info )
 
  251         RETURN
  252      END IF
  253 
  254
  255
  256
  257 
  258
  259      safmin = 
dlamch( 
'SAFE MINIMUM' )
 
  260      safmax = one/safmin
  261 
  262      IF ( ilo .GE. ihi ) THEN
  263         RETURN
  264      END IF
  265 
  266      IF ( ilschur ) THEN
  267         istartm = 1
  268         istopm = n
  269      ELSE
  270         istartm = ilo
  271         istopm = ihi
  272      END IF
  273 
  274      ns = nshifts
  275      npos = max( nblock_desired-ns, 1 )
  276 
  277 
  278
  279
  280
  281
  282 
  283      CALL zlaset( 
'FULL', ns+1, ns+1, czero, cone, qc, ldqc )
 
  284      CALL zlaset( 
'FULL', ns, ns, czero, cone, zc, ldzc )
 
  285 
  286      DO i = 1, ns
  287
  288         scale = sqrt( abs( alpha( i ) ) ) * sqrt( abs( beta( i ) ) )
  289         IF( scale .GE. safmin .AND. scale .LE. safmax ) THEN
  290            alpha( i ) = alpha( i )/scale
  291            beta( i ) = beta( i )/scale
  292         END IF
  293 
  294         temp2 = beta( i )*a( ilo, ilo )-alpha( i )*b( ilo, ilo )
  295         temp3 = beta( i )*a( ilo+1, ilo )
  296 
  297         IF ( abs( temp2 ) .GT. safmax .OR.
  298     $      abs( temp3 ) .GT. safmax ) THEN
  299            temp2 = cone
  300            temp3 = czero
  301         END IF
  302 
  303         CALL zlartg( temp2, temp3, c, s, temp )
 
  304         CALL zrot( ns, a( ilo, ilo ), lda, a( ilo+1, ilo ), lda, c,
 
  305     $              s )
  306         CALL zrot( ns, b( ilo, ilo ), ldb, b( ilo+1, ilo ), ldb, c,
 
  307     $              s )
  308         CALL zrot( ns+1, qc( 1, 1 ), 1, qc( 1, 2 ), 1, c,
 
  309     $              dconjg( s ) )
  310        
  311
  312         DO j = 1, ns-i
  313 
  314            CALL zlaqz1( .true., .true., j, 1, ns, ihi-ilo+1, a( ilo,
 
  315     $                   ilo ), lda, b( ilo, ilo ), ldb, ns+1, 1, qc,
  316     $                   ldqc, ns, 1, zc, ldzc )
  317 
  318         END DO
  319 
  320      END DO
  321 
  322
  323 
  324
  325
  326      sheight = ns+1
  327      swidth = istopm-( ilo+ns )+1
  328      IF ( swidth > 0 ) THEN
  329         CALL zgemm( 
'C', 
'N', sheight, swidth, sheight, cone, qc,
 
  330     $               ldqc,
  331     $               a( ilo, ilo+ns ), lda, czero, work, sheight )
  332         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight, a( ilo,
 
  333     $                ilo+ns ), lda )
  334         CALL zgemm( 
'C', 
'N', sheight, swidth, sheight, cone, qc,
 
  335     $               ldqc,
  336     $               b( ilo, ilo+ns ), ldb, czero, work, sheight )
  337         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight, b( ilo,
 
  338     $                ilo+ns ), ldb )
  339      END IF
  340      IF ( ilq ) THEN
  341         CALL zgemm( 
'N', 
'N', n, sheight, sheight, cone, q( 1,
 
  342     $               ilo ),
  343     $               ldq, qc, ldqc, czero, work, n )
  344         CALL zlacpy( 
'ALL', n, sheight, work, n, q( 1, ilo ), ldq )
 
  345      END IF
  346 
  347
  348
  349      sheight = ilo-1-istartm+1
  350      swidth = ns
  351      IF ( sheight > 0 ) THEN
  352         CALL zgemm( 
'N', 
'N', sheight, swidth, swidth, cone,
 
  353     $               a( istartm, ilo ), lda, zc, ldzc, czero, work,
  354     $               sheight )
  355         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  356     $                a( istartm,
  357     $                ilo ), lda )
  358         CALL zgemm( 
'N', 
'N', sheight, swidth, swidth, cone,
 
  359     $               b( istartm, ilo ), ldb, zc, ldzc, czero, work,
  360     $               sheight )
  361         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  362     $                b( istartm,
  363     $                ilo ), ldb )
  364      END IF
  365      IF ( ilz ) THEN
  366         CALL zgemm( 
'N', 
'N', n, swidth, swidth, cone, z( 1, ilo ),
 
  367     $               ldz, zc, ldzc, czero, work, n )
  368         CALL zlacpy( 
'ALL', n, swidth, work, n, z( 1, ilo ), ldz )
 
  369      END IF
  370 
  371
  372
  373
  374 
  375      k = ilo
  376      DO WHILE ( k < ihi-ns )
  377         np = min( ihi-ns-k, npos )
  378
  379         nblock = ns+np
  380
  381         istartb = k+1
  382
  383         istopb = k+nblock-1
  384 
  385         CALL zlaset( 
'FULL', ns+np, ns+np, czero, cone, qc, ldqc )
 
  386         CALL zlaset( 
'FULL', ns+np, ns+np, czero, cone, zc, ldzc )
 
  387 
  388
  389         DO i = ns-1, 0, -1
  390            DO j = 0, np-1
  391
  392
  393
  394               CALL zlaqz1( .true., .true., k+i+j, istartb, istopb,
 
  395     $                      ihi,
  396     $                      a, lda, b, ldb, nblock, k+1, qc, ldqc,
  397     $                      nblock, k, zc, ldzc )
  398            END DO
  399         END DO
  400 
  401
  402 
  403
  404
  405
  406         sheight = ns+np
  407         swidth = istopm-( k+ns+np )+1
  408         IF ( swidth > 0 ) THEN
  409            CALL zgemm( 
'C', 
'N', sheight, swidth, sheight, cone, qc,
 
  410     $                  ldqc, a( k+1, k+ns+np ), lda, czero, work,
  411     $                  sheight )
  412            CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  413     $                   a( k+1,
  414     $                   k+ns+np ), lda )
  415            CALL zgemm( 
'C', 
'N', sheight, swidth, sheight, cone, qc,
 
  416     $                  ldqc, b( k+1, k+ns+np ), ldb, czero, work,
  417     $                  sheight )
  418            CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  419     $                   b( k+1,
  420     $                   k+ns+np ), ldb )
  421         END IF
  422         IF ( ilq ) THEN
  423            CALL zgemm( 
'N', 
'N', n, nblock, nblock, cone, q( 1,
 
  424     $                  k+1 ),
  425     $                  ldq, qc, ldqc, czero, work, n )
  426            CALL zlacpy( 
'ALL', n, nblock, work, n, q( 1, k+1 ),
 
  427     $                   ldq )
  428         END IF
  429 
  430
  431
  432         sheight = k-istartm+1
  433         swidth = nblock
  434         IF ( sheight > 0 ) THEN
  435            CALL zgemm( 
'N', 
'N', sheight, swidth, swidth, cone,
 
  436     $                  a( istartm, k ), lda, zc, ldzc, czero, work,
  437     $                  sheight )
  438            CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  439     $                   a( istartm, k ), lda )
  440            CALL zgemm( 
'N', 
'N', sheight, swidth, swidth, cone,
 
  441     $                  b( istartm, k ), ldb, zc, ldzc, czero, work,
  442     $                  sheight )
  443            CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  444     $                   b( istartm, k ), ldb )
  445         END IF
  446         IF ( ilz ) THEN
  447            CALL zgemm( 
'N', 
'N', n, nblock, nblock, cone, z( 1, k ),
 
  448     $                  ldz, zc, ldzc, czero, work, n )
  449            CALL zlacpy( 
'ALL', n, nblock, work, n, z( 1, k ), ldz )
 
  450         END IF
  451 
  452         k = k+np
  453 
  454      END DO
  455 
  456
  457
  458 
  459      CALL zlaset( 
'FULL', ns, ns, czero, cone, qc, ldqc )
 
  460      CALL zlaset( 
'FULL', ns+1, ns+1, czero, cone, zc, ldzc )
 
  461 
  462
  463      istartb = ihi-ns+1
  464
  465      istopb = ihi
  466 
  467      DO i = 1, ns
  468
  469         DO ishift = ihi-i, ihi-1
  470            CALL zlaqz1( .true., .true., ishift, istartb, istopb,
 
  471     $                   ihi,
  472     $                   a, lda, b, ldb, ns, ihi-ns+1, qc, ldqc, ns+1,
  473     $                   ihi-ns, zc, ldzc )
  474         END DO
  475         
  476      END DO
  477 
  478
  479 
  480
  481
  482      sheight = ns
  483      swidth = istopm-( ihi+1 )+1
  484      IF ( swidth > 0 ) THEN
  485         CALL zgemm( 
'C', 
'N', sheight, swidth, sheight, cone, qc,
 
  486     $               ldqc,
  487     $               a( ihi-ns+1, ihi+1 ), lda, czero, work, sheight )
  488         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  489     $                a( ihi-ns+1, ihi+1 ), lda )
  490         CALL zgemm( 
'C', 
'N', sheight, swidth, sheight, cone, qc,
 
  491     $               ldqc,
  492     $               b( ihi-ns+1, ihi+1 ), ldb, czero, work, sheight )
  493         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  494     $                b( ihi-ns+1, ihi+1 ), ldb )
  495      END IF
  496      IF ( ilq ) THEN
  497         CALL zgemm( 
'N', 
'N', n, ns, ns, cone, q( 1, ihi-ns+1 ),
 
  498     $               ldq,
  499     $               qc, ldqc, czero, work, n )
  500         CALL zlacpy( 
'ALL', n, ns, work, n, q( 1, ihi-ns+1 ), ldq )
 
  501      END IF
  502 
  503
  504
  505      sheight = ihi-ns-istartm+1
  506      swidth = ns+1
  507      IF ( sheight > 0 ) THEN
  508         CALL zgemm( 
'N', 
'N', sheight, swidth, swidth, cone,
 
  509     $               a( istartm, ihi-ns ), lda, zc, ldzc, czero, work,
  510     $               sheight )
  511         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  512     $                a( istartm,
  513     $                ihi-ns ), lda )
  514         CALL zgemm( 
'N', 
'N', sheight, swidth, swidth, cone,
 
  515     $               b( istartm, ihi-ns ), ldb, zc, ldzc, czero, work,
  516     $               sheight )
  517         CALL zlacpy( 
'ALL', sheight, swidth, work, sheight,
 
  518     $                b( istartm,
  519     $                ihi-ns ), ldb )
  520      END IF
  521      IF ( ilz ) THEN
  522         CALL zgemm( 
'N', 
'N', n, ns+1, ns+1, cone, z( 1, ihi-ns ),
 
  523     $               ldz,
  524     $               zc, ldzc, czero, work, n )
  525         CALL zlacpy( 
'ALL', n, ns+1, work, n, z( 1, ihi-ns ), ldz )
 
  526      END IF
  527 
subroutine xerbla(srname, info)
 
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
 
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
 
double precision function dlamch(cmach)
DLAMCH
 
subroutine zlaqz1(ilq, ilz, k, istartm, istopm, ihi, a, lda, b, ldb, nq, qstart, q, ldq, nz, zstart, z, ldz)
ZLAQZ1
 
subroutine zlartg(f, g, c, s, r)
ZLARTG generates a plane rotation with real cosine and complex sine.
 
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
 
subroutine zrot(n, cx, incx, cy, incy, c, s)
ZROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.