202 SUBROUTINE zlaqz3( ILSCHUR, ILQ, ILZ, N, ILO, IHI, NSHIFTS,
203 $ NBLOCK_DESIRED, ALPHA, BETA, A, LDA, B, LDB,
204 $ Q, LDQ, Z, LDZ, QC, LDQC, ZC, LDZC, WORK,
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
213 COMPLEX*16,
INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ,
214 $ * ), Z( LDZ, * ), QC( LDQC, * ), ZC( LDZC, * ), WORK( * ),
215 $ ALPHA( * ), BETA( * )
217 INTEGER,
INTENT( OUT ) :: INFO
220 COMPLEX*16 CZERO, CONE
221 PARAMETER ( CZERO = ( 0.0d+0, 0.0d+0 ), cone = ( 1.0d+0,
223 DOUBLE PRECISION :: ZERO, ONE, HALF
224 parameter( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
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
235 DOUBLE PRECISION,
EXTERNAL :: DLAMCH
238 IF ( nblock_desired .LT. nshifts+1 )
THEN
241 IF ( lwork .EQ.-1 )
THEN
243 work( 1 ) = n*nblock_desired
245 ELSE IF ( lwork .LT. n*nblock_desired )
THEN
250 CALL xerbla(
'ZLAQZ3', -info )
259 safmin = dlamch(
'SAFE MINIMUM' )
262 IF ( ilo .GE. ihi )
THEN
275 npos = max( nblock_desired-ns, 1 )
283 CALL zlaset(
'FULL', ns+1, ns+1, czero, cone, qc, ldqc )
284 CALL zlaset(
'FULL', ns, ns, czero, cone, zc, ldzc )
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
294 temp2 = beta( i )*a( ilo, ilo )-alpha( i )*b( ilo, ilo )
295 temp3 = beta( i )*a( ilo+1, ilo )
297 IF ( abs( temp2 ) .GT. safmax .OR.
298 $ abs( temp3 ) .GT. safmax )
THEN
303 CALL zlartg( temp2, temp3, c, s, temp )
304 CALL zrot( ns, a( ilo, ilo ), lda, a( ilo+1, ilo ), lda, c,
306 CALL zrot( ns, b( ilo, ilo ), ldb, b( ilo+1, ilo ), ldb, c,
308 CALL zrot( ns+1, qc( 1, 1 ), 1, qc( 1, 2 ), 1, c,
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 )
327 swidth = istopm-( ilo+ns )+1
328 IF ( swidth > 0 )
THEN
329 CALL zgemm(
'C',
'N', sheight, swidth, sheight, cone, qc,
331 $ a( ilo, ilo+ns ), lda, czero, work, sheight )
332 CALL zlacpy(
'ALL', sheight, swidth, work, sheight, a( ilo,
334 CALL zgemm(
'C',
'N', sheight, swidth, sheight, cone, qc,
336 $ b( ilo, ilo+ns ), ldb, czero, work, sheight )
337 CALL zlacpy(
'ALL', sheight, swidth, work, sheight, b( ilo,
341 CALL zgemm(
'N',
'N', n, sheight, sheight, cone, q( 1,
343 $ ldq, qc, ldqc, czero, work, n )
344 CALL zlacpy(
'ALL', n, sheight, work, n, q( 1, ilo ), ldq )
349 sheight = ilo-1-istartm+1
351 IF ( sheight > 0 )
THEN
352 CALL zgemm(
'N',
'N', sheight, swidth, swidth, cone,
353 $ a( istartm, ilo ), lda, zc, ldzc, czero, work,
355 CALL zlacpy(
'ALL', sheight, swidth, work, sheight,
358 CALL zgemm(
'N',
'N', sheight, swidth, swidth, cone,
359 $ b( istartm, ilo ), ldb, zc, ldzc, czero, work,
361 CALL zlacpy(
'ALL', sheight, swidth, work, sheight,
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 )
376 DO WHILE ( k < ihi-ns )
377 np = min( ihi-ns-k, npos )
385 CALL zlaset(
'FULL', ns+np, ns+np, czero, cone, qc, ldqc )
386 CALL zlaset(
'FULL', ns+np, ns+np, czero, cone, zc, ldzc )
394 CALL zlaqz1( .true., .true., k+i+j, istartb, istopb,
396 $ a, lda, b, ldb, nblock, k+1, qc, ldqc,
397 $ nblock, k, zc, ldzc )
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,
412 CALL zlacpy(
'ALL', sheight, swidth, work, sheight,
415 CALL zgemm(
'C',
'N', sheight, swidth, sheight, cone, qc,
416 $ ldqc, b( k+1, k+ns+np ), ldb, czero, work,
418 CALL zlacpy(
'ALL', sheight, swidth, work, sheight,
423 CALL zgemm(
'N',
'N', n, nblock, nblock, cone, q( 1,
425 $ ldq, qc, ldqc, czero, work, n )
426 CALL zlacpy(
'ALL', n, nblock, work, n, q( 1, k+1 ),
432 sheight = k-istartm+1
434 IF ( sheight > 0 )
THEN
435 CALL zgemm(
'N',
'N', sheight, swidth, swidth, cone,
436 $ a( istartm, k ), lda, zc, ldzc, czero, work,
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,
443 CALL zlacpy(
'ALL', sheight, swidth, work, sheight,
444 $ b( istartm, k ), ldb )
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 )
459 CALL zlaset(
'FULL', ns, ns, czero, cone, qc, ldqc )
460 CALL zlaset(
'FULL', ns+1, ns+1, czero, cone, zc, ldzc )
469 DO ishift = ihi-i, ihi-1
470 CALL zlaqz1( .true., .true., ishift, istartb, istopb,
472 $ a, lda, b, ldb, ns, ihi-ns+1, qc, ldqc, ns+1,
483 swidth = istopm-( ihi+1 )+1
484 IF ( swidth > 0 )
THEN
485 CALL zgemm(
'C',
'N', sheight, swidth, sheight, cone, qc,
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,
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 )
497 CALL zgemm(
'N',
'N', n, ns, ns, cone, q( 1, ihi-ns+1 ),
499 $ qc, ldqc, czero, work, n )
500 CALL zlacpy(
'ALL', n, ns, work, n, q( 1, ihi-ns+1 ), ldq )
505 sheight = ihi-ns-istartm+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,
511 CALL zlacpy(
'ALL', sheight, swidth, work, sheight,
514 CALL zgemm(
'N',
'N', sheight, swidth, swidth, cone,
515 $ b( istartm, ihi-ns ), ldb, zc, ldzc, czero, work,
517 CALL zlacpy(
'ALL', sheight, swidth, work, sheight,
522 CALL zgemm(
'N',
'N', n, ns+1, ns+1, cone, z( 1, ihi-ns ),
524 $ zc, ldzc, czero, work, n )
525 CALL zlacpy(
'ALL', n, ns+1, work, n, z( 1, ihi-ns ), ldz )