230 RECURSIVE SUBROUTINE zlaqz2( ILSCHUR, ILQ, ILZ, N, ILO, IHI, NW,
231 $ A, LDA, B, LDB, Q, LDQ, Z, LDZ, NS,
232 $ ND, ALPHA, BETA, QC, LDQC, ZC, LDZC,
233 $ WORK, LWORK, RWORK, REC, INFO )
237 LOGICAL,
INTENT( IN ) :: ilschur, ilq, ilz
238 INTEGER,
INTENT( IN ) :: n, ilo, ihi, nw, lda, ldb, ldq, ldz,
239 $ ldqc, ldzc, lwork, rec
241 COMPLEX*16,
INTENT( INOUT ) :: a( lda, * ), b( ldb, * ), q( ldq,
242 $ * ), z( ldz, * ), alpha( * ), beta( * )
243 INTEGER,
INTENT( OUT ) :: ns, nd, info
244 COMPLEX*16 :: qc( ldqc, * ), zc( ldzc, * ), work( * )
245 DOUBLE PRECISION :: rwork( * )
248 COMPLEX*16 czero, cone
249 PARAMETER ( czero = ( 0.0d+0, 0.0d+0 ), cone = ( 1.0d+0,
251 DOUBLE PRECISION :: zero, one, half
252 parameter( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
255 INTEGER :: jw, kwtop, kwbot, istopm, istartm, k, k2, ztgexc_info,
256 $ ifst, ilst, lworkreq, qz_small_info
257 DOUBLE PRECISION ::smlnum, ulp, safmin, safmax, c1, tempr
258 COMPLEX*16 :: s, s1, temp
263 DOUBLE PRECISION,
EXTERNAL ::
dlamch
268 jw = min( nw, ihi-ilo+1 )
270 IF ( kwtop .EQ. ilo )
THEN
273 s = a( kwtop, kwtop-1 )
279 CALL zlaqz0(
'S',
'V',
'V', jw, 1, jw, a( kwtop, kwtop ), lda,
280 $ b( kwtop, kwtop ), ldb, alpha, beta, qc, ldqc, zc,
281 $ ldzc, work, -1, rwork, rec+1, qz_small_info )
282 lworkreq = int( work( 1 ) )+2*jw**2
283 lworkreq = max( lworkreq, n*nw, 2*nw**2+n )
284 IF ( lwork .EQ.-1 )
THEN
288 ELSE IF ( lwork .LT. lworkreq )
THEN
293 CALL xerbla(
'ZLAQZ2', -info )
298 safmin =
dlamch(
'SAFE MINIMUM' )
300 CALL dlabad( safmin, safmax )
301 ulp =
dlamch(
'PRECISION' )
302 smlnum = safmin*( dble( n )/ulp )
304 IF ( ihi .EQ. kwtop )
THEN
306 alpha( kwtop ) = a( kwtop, kwtop )
307 beta( kwtop ) = b( kwtop, kwtop )
310 IF ( abs( s ) .LE. max( smlnum, ulp*abs( a( kwtop,
314 IF ( kwtop .GT. ilo )
THEN
315 a( kwtop, kwtop-1 ) = czero
322 CALL zlacpy(
'ALL', jw, jw, a( kwtop, kwtop ), lda, work, jw )
323 CALL zlacpy(
'ALL', jw, jw, b( kwtop, kwtop ), ldb, work( jw**2+
327 CALL zlaset(
'FULL', jw, jw, czero, cone, qc, ldqc )
328 CALL zlaset(
'FULL', jw, jw, czero, cone, zc, ldzc )
329 CALL zlaqz0(
'S',
'V',
'V', jw, 1, jw, a( kwtop, kwtop ), lda,
330 $ b( kwtop, kwtop ), ldb, alpha, beta, qc, ldqc, zc,
331 $ ldzc, work( 2*jw**2+1 ), lwork-2*jw**2, rwork,
332 $ rec+1, qz_small_info )
334 IF( qz_small_info .NE. 0 )
THEN
337 ns = jw-qz_small_info
338 CALL zlacpy(
'ALL', jw, jw, work, jw, a( kwtop, kwtop ), lda )
339 CALL zlacpy(
'ALL', jw, jw, work( jw**2+1 ), jw, b( kwtop,
345 IF ( kwtop .EQ. ilo .OR. s .EQ. czero )
THEN
351 DO WHILE ( k .LE. jw )
353 tempr = abs( a( kwbot, kwbot ) )
354 IF( tempr .EQ. zero )
THEN
357 IF ( ( abs( s*qc( 1, kwbot-kwtop+1 ) ) ) .LE. max( ulp*
358 $ tempr, smlnum ) )
THEN
365 CALL ztgexc( .true., .true., jw, a( kwtop, kwtop ),
366 $ lda, b( kwtop, kwtop ), ldb, qc, ldqc,
367 $ zc, ldzc, ifst, ilst, ztgexc_info )
379 DO WHILE ( k .LE. ihi )
380 alpha( k ) = a( k, k )
381 beta( k ) = b( k, k )
385 IF ( kwtop .NE. ilo .AND. s .NE. czero )
THEN
387 a( kwtop:kwbot, kwtop-1 ) = a( kwtop, kwtop-1 ) *dconjg( qc( 1,
389 DO k = kwbot-1, kwtop, -1
390 CALL zlartg( a( k, kwtop-1 ), a( k+1, kwtop-1 ), c1, s1,
392 a( k, kwtop-1 ) = temp
393 a( k+1, kwtop-1 ) = czero
394 k2 = max( kwtop, k-1 )
395 CALL zrot( ihi-k2+1, a( k, k2 ), lda, a( k+1, k2 ), lda, c1,
397 CALL zrot( ihi-( k-1 )+1, b( k, k-1 ), ldb, b( k+1, k-1 ),
399 CALL zrot( jw, qc( 1, k-kwtop+1 ), 1, qc( 1, k+1-kwtop+1 ),
400 $ 1, c1, dconjg( s1 ) )
407 DO WHILE ( k .GE. kwtop )
411 CALL zlaqz1( .true., .true., k2, kwtop, kwtop+jw-1,
412 $ kwbot, a, lda, b, ldb, jw, kwtop, qc, ldqc,
413 $ jw, kwtop, zc, ldzc )
430 IF ( istopm-ihi > 0 )
THEN
431 CALL zgemm(
'C',
'N', jw, istopm-ihi, jw, cone, qc, ldqc,
432 $ a( kwtop, ihi+1 ), lda, czero, work, jw )
433 CALL zlacpy(
'ALL', jw, istopm-ihi, work, jw, a( kwtop,
435 CALL zgemm(
'C',
'N', jw, istopm-ihi, jw, cone, qc, ldqc,
436 $ b( kwtop, ihi+1 ), ldb, czero, work, jw )
437 CALL zlacpy(
'ALL', jw, istopm-ihi, work, jw, b( kwtop,
441 CALL zgemm(
'N',
'N', n, jw, jw, cone, q( 1, kwtop ), ldq, qc,
442 $ ldqc, czero, work, n )
443 CALL zlacpy(
'ALL', n, jw, work, n, q( 1, kwtop ), ldq )
446 IF ( kwtop-1-istartm+1 > 0 )
THEN
447 CALL zgemm(
'N',
'N', kwtop-istartm, jw, jw, cone, a( istartm,
448 $ kwtop ), lda, zc, ldzc, czero, work,
450 CALL zlacpy(
'ALL', kwtop-istartm, jw, work, kwtop-istartm,
451 $ a( istartm, kwtop ), lda )
452 CALL zgemm(
'N',
'N', kwtop-istartm, jw, jw, cone, b( istartm,
453 $ kwtop ), ldb, zc, ldzc, czero, work,
455 CALL zlacpy(
'ALL', kwtop-istartm, jw, work, kwtop-istartm,
456 $ b( istartm, kwtop ), ldb )
459 CALL zgemm(
'N',
'N', n, jw, jw, cone, z( 1, kwtop ), ldz, zc,
460 $ ldzc, czero, work, n )
461 CALL zlacpy(
'ALL', n, jw, work, n, z( 1, kwtop ), ldz )
double precision function dlamch(CMACH)
DLAMCH
subroutine zlartg(f, g, c, s, r)
ZLARTG generates a plane rotation with real cosine and complex sine.
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
ZGEMM
subroutine zlaqz1(ILQ, ILZ, K, ISTARTM, ISTOPM, IHI, A, LDA, B, LDB, NQ, QSTART, Q, LDQ, NZ, ZSTART, Z, LDZ)
ZLAQZ1
recursive subroutine zlaqz0(WANTS, WANTQ, WANTZ, N, ILO, IHI, A, LDA, B, LDB, ALPHA, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, RWORK, REC, INFO)
ZLAQZ0
subroutine ztgexc(WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z, LDZ, IFST, ILST, INFO)
ZTGEXC
recursive subroutine zlaqz2(ILSCHUR, ILQ, ILZ, N, ILO, IHI, NW, A, LDA, B, LDB, Q, LDQ, Z, LDZ, NS, ND, ALPHA, BETA, QC, LDQC, ZC, LDZC, WORK, LWORK, RWORK, REC, INFO)
ZLAQZ2
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.
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
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.