302 RECURSIVE SUBROUTINE dlaqz0( WANTS, WANTQ, WANTZ, N, ILO, IHI, A,
303 $ LDA, B, LDB, ALPHAR, ALPHAI, BETA,
304 $ Q, LDQ, Z, LDZ, WORK, LWORK, REC,
309 CHARACTER,
INTENT( IN ) :: wants, wantq, wantz
310 INTEGER,
INTENT( IN ) :: n, ilo, ihi, lda, ldb, ldq, ldz, lwork,
313 INTEGER,
INTENT( OUT ) :: info
315 DOUBLE PRECISION,
INTENT( INOUT ) :: a( lda, * ), b( ldb, * ),
316 $ q( ldq, * ), z( ldz, * ), alphar( * ),
317 $ alphai( * ), beta( * ), work( * )
320 DOUBLE PRECISION :: zero, one, half
321 PARAMETER( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
324 DOUBLE PRECISION :: smlnum, ulp, eshift, safmin, safmax, c1, s1,
325 $ temp, swap, bnorm, btol
326 INTEGER :: istart, istop, iiter, maxit, istart2, k, ld, nshifts,
327 $ nblock, nw, nmin, nibble, n_undeflated, n_deflated,
328 $ ns, sweep_info, shiftpos, lworkreq, k2, istartm,
329 $ istopm, iwants, iwantq, iwantz, norm_info, aed_info,
330 $ nwr, nbr, nsr, itemp1, itemp2, rcost, i
331 LOGICAL :: ilschur, ilq, ilz
332 CHARACTER :: jbcmpz*3
338 LOGICAL,
EXTERNAL ::
lsame
339 INTEGER,
EXTERNAL ::
ilaenv
344 IF(
lsame( wants,
'E' ) )
THEN
347 ELSE IF(
lsame( wants,
'S' ) )
THEN
354 IF(
lsame( wantq,
'N' ) )
THEN
357 ELSE IF(
lsame( wantq,
'V' ) )
THEN
360 ELSE IF(
lsame( wantq,
'I' ) )
THEN
367 IF(
lsame( wantz,
'N' ) )
THEN
370 ELSE IF(
lsame( wantz,
'V' ) )
THEN
373 ELSE IF(
lsame( wantz,
'I' ) )
THEN
383 IF( iwants.EQ.0 )
THEN
385 ELSE IF( iwantq.EQ.0 )
THEN
387 ELSE IF( iwantz.EQ.0 )
THEN
389 ELSE IF( n.LT.0 )
THEN
391 ELSE IF( ilo.LT.1 )
THEN
393 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
395 ELSE IF( lda.LT.n )
THEN
397 ELSE IF( ldb.LT.n )
THEN
399 ELSE IF( ldq.LT.1 .OR. ( ilq .AND. ldq.LT.n ) )
THEN
401 ELSE IF( ldz.LT.1 .OR. ( ilz .AND. ldz.LT.n ) )
THEN
405 CALL xerbla(
'DLAQZ0', -info )
413 work( 1 ) = dble( 1 )
420 jbcmpz( 1:1 ) = wants
421 jbcmpz( 2:2 ) = wantq
422 jbcmpz( 3:3 ) = wantz
424 nmin =
ilaenv( 12,
'DLAQZ0', jbcmpz, n, ilo, ihi, lwork )
426 nwr =
ilaenv( 13,
'DLAQZ0', jbcmpz, n, ilo, ihi, lwork )
428 nwr = min( ihi-ilo+1, ( n-1 ) / 3, nwr )
430 nibble =
ilaenv( 14,
'DLAQZ0', jbcmpz, n, ilo, ihi, lwork )
432 nsr =
ilaenv( 15,
'DLAQZ0', jbcmpz, n, ilo, ihi, lwork )
433 nsr = min( nsr, ( n+6 ) / 9, ihi-ilo )
434 nsr = max( 2, nsr-mod( nsr, 2 ) )
436 rcost =
ilaenv( 17,
'DLAQZ0', jbcmpz, n, ilo, ihi, lwork )
437 itemp1 = int( nsr/sqrt( 1+2*nsr/( dble( rcost )/100*n ) ) )
438 itemp1 = ( ( itemp1-1 )/4 )*4+4
441 IF( n .LT. nmin .OR. rec .GE. 2 )
THEN
442 CALL dhgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
443 $ alphar, alphai, beta, q, ldq, z, ldz, work,
453 nw = max( nwr, nmin )
454 CALL dlaqz3( ilschur, ilq, ilz, n, ilo, ihi, nw, a, lda, b, ldb,
455 $ q, ldq, z, ldz, n_undeflated, n_deflated, alphar,
456 $ alphai, beta, work, nw, work, nw, work, -1, rec,
458 itemp1 = int( work( 1 ) )
460 CALL dlaqz4( ilschur, ilq, ilz, n, ilo, ihi, nsr, nbr, alphar,
461 $ alphai, beta, a, lda, b, ldb, q, ldq, z, ldz, work,
462 $ nbr, work, nbr, work, -1, sweep_info )
463 itemp2 = int( work( 1 ) )
465 lworkreq = max( itemp1+2*nw**2, itemp2+2*nbr**2 )
466 IF ( lwork .EQ.-1 )
THEN
467 work( 1 ) = dble( lworkreq )
469 ELSE IF ( lwork .LT. lworkreq )
THEN
473 CALL xerbla(
'DLAQZ0', info )
479 IF( iwantq.EQ.3 )
CALL dlaset(
'FULL', n, n, zero, one, q, ldq )
480 IF( iwantz.EQ.3 )
CALL dlaset(
'FULL', n, n, zero, one, z, ldz )
483 safmin =
dlamch(
'SAFE MINIMUM' )
485 ulp =
dlamch(
'PRECISION' )
486 smlnum = safmin*( dble( n )/ulp )
488 bnorm =
dlanhs(
'F', ihi-ilo+1, b( ilo, ilo ), ldb, work )
489 btol = max( safmin, ulp*bnorm )
493 maxit = 3*( ihi-ilo+1 )
497 IF( iiter .GE. maxit )
THEN
501 IF ( istart+1 .GE. istop )
THEN
507 IF ( abs( a( istop-1, istop-2 ) ) .LE. max( smlnum,
508 $ ulp*( abs( a( istop-1, istop-1 ) )+abs( a( istop-2,
509 $ istop-2 ) ) ) ) )
THEN
510 a( istop-1, istop-2 ) = zero
514 ELSE IF ( abs( a( istop, istop-1 ) ) .LE. max( smlnum,
515 $ ulp*( abs( a( istop, istop ) )+abs( a( istop-1,
516 $ istop-1 ) ) ) ) )
THEN
517 a( istop, istop-1 ) = zero
523 IF ( abs( a( istart+2, istart+1 ) ) .LE. max( smlnum,
524 $ ulp*( abs( a( istart+1, istart+1 ) )+abs( a( istart+2,
525 $ istart+2 ) ) ) ) )
THEN
526 a( istart+2, istart+1 ) = zero
530 ELSE IF ( abs( a( istart+1, istart ) ) .LE. max( smlnum,
531 $ ulp*( abs( a( istart, istart ) )+abs( a( istart+1,
532 $ istart+1 ) ) ) ) )
THEN
533 a( istart+1, istart ) = zero
539 IF ( istart+1 .GE. istop )
THEN
545 DO k = istop, istart+1, -1
546 IF ( abs( a( k, k-1 ) ) .LE. max( smlnum, ulp*( abs( a( k,
547 $ k ) )+abs( a( k-1, k-1 ) ) ) ) )
THEN
566 DO WHILE ( k.GE.istart2 )
568 IF( abs( b( k, k ) ) .LT. btol )
THEN
572 DO k2 = k, istart2+1, -1
573 CALL dlartg( b( k2-1, k2 ), b( k2-1, k2-1 ), c1, s1,
576 b( k2-1, k2-1 ) = zero
578 CALL drot( k2-2-istartm+1, b( istartm, k2 ), 1,
579 $ b( istartm, k2-1 ), 1, c1, s1 )
580 CALL drot( min( k2+1, istop )-istartm+1, a( istartm,
581 $ k2 ), 1, a( istartm, k2-1 ), 1, c1, s1 )
583 CALL drot( n, z( 1, k2 ), 1, z( 1, k2-1 ), 1, c1,
587 IF( k2.LT.istop )
THEN
588 CALL dlartg( a( k2, k2-1 ), a( k2+1, k2-1 ), c1,
591 a( k2+1, k2-1 ) = zero
593 CALL drot( istopm-k2+1, a( k2, k2 ), lda, a( k2+1,
594 $ k2 ), lda, c1, s1 )
595 CALL drot( istopm-k2+1, b( k2, k2 ), ldb, b( k2+1,
596 $ k2 ), ldb, c1, s1 )
598 CALL drot( n, q( 1, k2 ), 1, q( 1, k2+1 ), 1,
605 IF( istart2.LT.istop )
THEN
606 CALL dlartg( a( istart2, istart2 ), a( istart2+1,
607 $ istart2 ), c1, s1, temp )
608 a( istart2, istart2 ) = temp
609 a( istart2+1, istart2 ) = zero
611 CALL drot( istopm-( istart2+1 )+1, a( istart2,
612 $ istart2+1 ), lda, a( istart2+1,
613 $ istart2+1 ), lda, c1, s1 )
614 CALL drot( istopm-( istart2+1 )+1, b( istart2,
615 $ istart2+1 ), ldb, b( istart2+1,
616 $ istart2+1 ), ldb, c1, s1 )
618 CALL drot( n, q( 1, istart2 ), 1, q( 1,
619 $ istart2+1 ), 1, c1, s1 )
631 IF ( istart2 .GE. istop )
THEN
642 IF ( istop-istart2+1 .LT. nmin )
THEN
646 IF ( istop-istart+1 .LT. nmin )
THEN
657 CALL dlaqz3( ilschur, ilq, ilz, n, istart2, istop, nw, a, lda,
658 $ b, ldb, q, ldq, z, ldz, n_undeflated, n_deflated,
659 $ alphar, alphai, beta, work, nw, work( nw**2+1 ),
660 $ nw, work( 2*nw**2+1 ), lwork-2*nw**2, rec,
663 IF ( n_deflated > 0 )
THEN
664 istop = istop-n_deflated
669 IF ( 100*n_deflated > nibble*( n_deflated+n_undeflated ) .OR.
670 $ istop-istart2+1 .LT. nmin )
THEN
678 ns = min( nshifts, istop-istart2 )
679 ns = min( ns, n_undeflated )
680 shiftpos = istop-n_undeflated+1
685 DO i = shiftpos, shiftpos+n_undeflated-1, 2
686 IF( alphai( i ).NE.-alphai( i+1 ) )
THEN
689 alphar( i ) = alphar( i+1 )
690 alphar( i+1 ) = alphar( i+2 )
694 alphai( i ) = alphai( i+1 )
695 alphai( i+1 ) = alphai( i+2 )
699 beta( i ) = beta( i+1 )
700 beta( i+1 ) = beta( i+2 )
705 IF ( mod( ld, 6 ) .EQ. 0 )
THEN
709 IF( ( dble( maxit )*safmin )*abs( a( istop,
710 $ istop-1 ) ).LT.abs( a( istop-1, istop-1 ) ) )
THEN
711 eshift = a( istop, istop-1 )/b( istop-1, istop-1 )
713 eshift = eshift+one/( safmin*dble( maxit ) )
715 alphar( shiftpos ) = one
716 alphar( shiftpos+1 ) = zero
717 alphai( shiftpos ) = zero
718 alphai( shiftpos+1 ) = zero
719 beta( shiftpos ) = eshift
720 beta( shiftpos+1 ) = eshift
727 CALL dlaqz4( ilschur, ilq, ilz, n, istart2, istop, ns, nblock,
728 $ alphar( shiftpos ), alphai( shiftpos ),
729 $ beta( shiftpos ), a, lda, b, ldb, q, ldq, z, ldz,
730 $ work, nblock, work( nblock**2+1 ), nblock,
731 $ work( 2*nblock**2+1 ), lwork-2*nblock**2,
742 80
CALL dhgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
743 $ alphar, alphai, beta, q, ldq, z, ldz, work, lwork,
subroutine xerbla(srname, info)
subroutine dhgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
DHGEQZ
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
double precision function dlamch(cmach)
DLAMCH
double precision function dlanhs(norm, n, a, lda, work)
DLANHS returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
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
recursive subroutine dlaqz3(ilschur, ilq, ilz, n, ilo, ihi, nw, a, lda, b, ldb, q, ldq, z, ldz, ns, nd, alphar, alphai, beta, qc, ldqc, zc, ldzc, work, lwork, rec, info)
DLAQZ3
subroutine dlaqz4(ilschur, ilq, ilz, n, ilo, ihi, nshifts, nblock_desired, sr, si, ss, a, lda, b, ldb, q, ldq, z, ldz, qc, ldqc, zc, ldzc, work, lwork, info)
DLAQZ4
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.
logical function lsame(ca, cb)
LSAME
subroutine drot(n, dx, incx, dy, incy, c, s)
DROT