300 RECURSIVE SUBROUTINE slaqz0( WANTS, WANTQ, WANTZ, N, ILO, IHI, A,
301 $ LDA, B, LDB, ALPHAR, ALPHAI, BETA,
302 $ Q, LDQ, Z, LDZ, WORK, LWORK, REC,
307 CHARACTER,
INTENT( IN ) :: wants, wantq, wantz
308 INTEGER,
INTENT( IN ) :: n, ilo, ihi, lda, ldb, ldq, ldz, lwork,
311 INTEGER,
INTENT( OUT ) :: info
313 REAL,
INTENT( INOUT ) :: a( lda, * ), b( ldb, * ), q( ldq, * ),
314 $ z( ldz, * ), alphar( * ), alphai( * ), beta( * ), work( * )
317 REAL :: zero, one, half
318 PARAMETER( zero = 0.0, one = 1.0, half = 0.5 )
321 REAL :: smlnum, ulp, eshift, safmin, safmax, c1, s1, temp, swap,
323 INTEGER :: istart, istop, iiter, maxit, istart2, k, ld, nshifts,
324 $ nblock, nw, nmin, nibble, n_undeflated, n_deflated,
325 $ ns, sweep_info, shiftpos, lworkreq, k2, istartm,
326 $ istopm, iwants, iwantq, iwantz, norm_info, aed_info,
327 $ nwr, nbr, nsr, itemp1, itemp2, rcost, i
328 LOGICAL :: ilschur, ilq, ilz
329 CHARACTER :: jbcmpz*3
335 LOGICAL,
EXTERNAL ::
lsame
336 INTEGER,
EXTERNAL ::
ilaenv
341 IF(
lsame( wants,
'E' ) )
THEN
344 ELSE IF(
lsame( wants,
'S' ) )
THEN
351 IF(
lsame( wantq,
'N' ) )
THEN
354 ELSE IF(
lsame( wantq,
'V' ) )
THEN
357 ELSE IF(
lsame( wantq,
'I' ) )
THEN
364 IF(
lsame( wantz,
'N' ) )
THEN
367 ELSE IF(
lsame( wantz,
'V' ) )
THEN
370 ELSE IF(
lsame( wantz,
'I' ) )
THEN
380 IF( iwants.EQ.0 )
THEN
382 ELSE IF( iwantq.EQ.0 )
THEN
384 ELSE IF( iwantz.EQ.0 )
THEN
386 ELSE IF( n.LT.0 )
THEN
388 ELSE IF( ilo.LT.1 )
THEN
390 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
392 ELSE IF( lda.LT.n )
THEN
394 ELSE IF( ldb.LT.n )
THEN
396 ELSE IF( ldq.LT.1 .OR. ( ilq .AND. ldq.LT.n ) )
THEN
398 ELSE IF( ldz.LT.1 .OR. ( ilz .AND. ldz.LT.n ) )
THEN
402 CALL xerbla(
'SLAQZ0', -info )
410 work( 1 ) = real( 1 )
417 jbcmpz( 1:1 ) = wants
418 jbcmpz( 2:2 ) = wantq
419 jbcmpz( 3:3 ) = wantz
421 nmin =
ilaenv( 12,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
423 nwr =
ilaenv( 13,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
425 nwr = min( ihi-ilo+1, ( n-1 ) / 3, nwr )
427 nibble =
ilaenv( 14,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
429 nsr =
ilaenv( 15,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
430 nsr = min( nsr, ( n+6 ) / 9, ihi-ilo )
431 nsr = max( 2, nsr-mod( nsr, 2 ) )
433 rcost =
ilaenv( 17,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
434 itemp1 = int( nsr/sqrt( 1+2*nsr/( real( rcost )/100*n ) ) )
435 itemp1 = ( ( itemp1-1 )/4 )*4+4
438 IF( n .LT. nmin .OR. rec .GE. 2 )
THEN
439 CALL shgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
440 $ alphar, alphai, beta, q, ldq, z, ldz, work,
450 nw = max( nwr, nmin )
451 CALL slaqz3( ilschur, ilq, ilz, n, ilo, ihi, nw, a, lda, b, ldb,
452 $ q, ldq, z, ldz, n_undeflated, n_deflated, alphar,
453 $ alphai, beta, work, nw, work, nw, work, -1, rec,
455 itemp1 = int( work( 1 ) )
457 CALL slaqz4( ilschur, ilq, ilz, n, ilo, ihi, nsr, nbr, alphar,
458 $ alphai, beta, a, lda, b, ldb, q, ldq, z, ldz, work,
459 $ nbr, work, nbr, work, -1, sweep_info )
460 itemp2 = int( work( 1 ) )
462 lworkreq = max( itemp1+2*nw**2, itemp2+2*nbr**2 )
463 IF ( lwork .EQ.-1 )
THEN
466 ELSE IF ( lwork .LT. lworkreq )
THEN
470 CALL xerbla(
'SLAQZ0', info )
476 IF( iwantq.EQ.3 )
CALL slaset(
'FULL', n, n, zero, one, q, ldq )
477 IF( iwantz.EQ.3 )
CALL slaset(
'FULL', n, n, zero, one, z, ldz )
480 safmin =
slamch(
'SAFE MINIMUM' )
482 ulp =
slamch(
'PRECISION' )
483 smlnum = safmin*( real( n )/ulp )
485 bnorm =
slanhs(
'F', ihi-ilo+1, b( ilo, ilo ), ldb, work )
486 btol = max( safmin, ulp*bnorm )
490 maxit = 3*( ihi-ilo+1 )
494 IF( iiter .GE. maxit )
THEN
498 IF ( istart+1 .GE. istop )
THEN
504 IF ( abs( a( istop-1, istop-2 ) ) .LE. max( smlnum,
505 $ ulp*( abs( a( istop-1, istop-1 ) )+abs( a( istop-2,
506 $ istop-2 ) ) ) ) )
THEN
507 a( istop-1, istop-2 ) = zero
511 ELSE IF ( abs( a( istop, istop-1 ) ) .LE. max( smlnum,
512 $ ulp*( abs( a( istop, istop ) )+abs( a( istop-1,
513 $ istop-1 ) ) ) ) )
THEN
514 a( istop, istop-1 ) = zero
520 IF ( abs( a( istart+2, istart+1 ) ) .LE. max( smlnum,
521 $ ulp*( abs( a( istart+1, istart+1 ) )+abs( a( istart+2,
522 $ istart+2 ) ) ) ) )
THEN
523 a( istart+2, istart+1 ) = zero
527 ELSE IF ( abs( a( istart+1, istart ) ) .LE. max( smlnum,
528 $ ulp*( abs( a( istart, istart ) )+abs( a( istart+1,
529 $ istart+1 ) ) ) ) )
THEN
530 a( istart+1, istart ) = zero
536 IF ( istart+1 .GE. istop )
THEN
542 DO k = istop, istart+1, -1
543 IF ( abs( a( k, k-1 ) ) .LE. max( smlnum, ulp*( abs( a( k,
544 $ k ) )+abs( a( k-1, k-1 ) ) ) ) )
THEN
563 DO WHILE ( k.GE.istart2 )
565 IF( abs( b( k, k ) ) .LT. btol )
THEN
569 DO k2 = k, istart2+1, -1
570 CALL slartg( b( k2-1, k2 ), b( k2-1, k2-1 ), c1, s1,
573 b( k2-1, k2-1 ) = zero
575 CALL srot( k2-2-istartm+1, b( istartm, k2 ), 1,
576 $ b( istartm, k2-1 ), 1, c1, s1 )
577 CALL srot( min( k2+1, istop )-istartm+1, a( istartm,
578 $ k2 ), 1, a( istartm, k2-1 ), 1, c1, s1 )
580 CALL srot( n, z( 1, k2 ), 1, z( 1, k2-1 ), 1, c1,
584 IF( k2.LT.istop )
THEN
585 CALL slartg( a( k2, k2-1 ), a( k2+1, k2-1 ), c1,
588 a( k2+1, k2-1 ) = zero
590 CALL srot( istopm-k2+1, a( k2, k2 ), lda, a( k2+1,
591 $ k2 ), lda, c1, s1 )
592 CALL srot( istopm-k2+1, b( k2, k2 ), ldb, b( k2+1,
593 $ k2 ), ldb, c1, s1 )
595 CALL srot( n, q( 1, k2 ), 1, q( 1, k2+1 ), 1,
602 IF( istart2.LT.istop )
THEN
603 CALL slartg( a( istart2, istart2 ), a( istart2+1,
604 $ istart2 ), c1, s1, temp )
605 a( istart2, istart2 ) = temp
606 a( istart2+1, istart2 ) = zero
608 CALL srot( istopm-( istart2+1 )+1, a( istart2,
609 $ istart2+1 ), lda, a( istart2+1,
610 $ istart2+1 ), lda, c1, s1 )
611 CALL srot( istopm-( istart2+1 )+1, b( istart2,
612 $ istart2+1 ), ldb, b( istart2+1,
613 $ istart2+1 ), ldb, c1, s1 )
615 CALL srot( n, q( 1, istart2 ), 1, q( 1,
616 $ istart2+1 ), 1, c1, s1 )
628 IF ( istart2 .GE. istop )
THEN
639 IF ( istop-istart2+1 .LT. nmin )
THEN
643 IF ( istop-istart+1 .LT. nmin )
THEN
654 CALL slaqz3( ilschur, ilq, ilz, n, istart2, istop, nw, a, lda,
655 $ b, ldb, q, ldq, z, ldz, n_undeflated, n_deflated,
656 $ alphar, alphai, beta, work, nw, work( nw**2+1 ),
657 $ nw, work( 2*nw**2+1 ), lwork-2*nw**2, rec,
660 IF ( n_deflated > 0 )
THEN
661 istop = istop-n_deflated
666 IF ( 100*n_deflated > nibble*( n_deflated+n_undeflated ) .OR.
667 $ istop-istart2+1 .LT. nmin )
THEN
675 ns = min( nshifts, istop-istart2 )
676 ns = min( ns, n_undeflated )
677 shiftpos = istop-n_undeflated+1
682 DO i = shiftpos, shiftpos+n_undeflated-1, 2
683 IF( alphai( i ).NE.-alphai( i+1 ) )
THEN
686 alphar( i ) = alphar( i+1 )
687 alphar( i+1 ) = alphar( i+2 )
691 alphai( i ) = alphai( i+1 )
692 alphai( i+1 ) = alphai( i+2 )
696 beta( i ) = beta( i+1 )
697 beta( i+1 ) = beta( i+2 )
702 IF ( mod( ld, 6 ) .EQ. 0 )
THEN
706 IF( ( real( maxit )*safmin )*abs( a( istop,
707 $ istop-1 ) ).LT.abs( a( istop-1, istop-1 ) ) )
THEN
708 eshift = a( istop, istop-1 )/b( istop-1, istop-1 )
710 eshift = eshift+one/( safmin*real( maxit ) )
712 alphar( shiftpos ) = one
713 alphar( shiftpos+1 ) = zero
714 alphai( shiftpos ) = zero
715 alphai( shiftpos+1 ) = zero
716 beta( shiftpos ) = eshift
717 beta( shiftpos+1 ) = eshift
724 CALL slaqz4( ilschur, ilq, ilz, n, istart2, istop, ns, nblock,
725 $ alphar( shiftpos ), alphai( shiftpos ),
726 $ beta( shiftpos ), a, lda, b, ldb, q, ldq, z, ldz,
727 $ work, nblock, work( nblock**2+1 ), nblock,
728 $ work( 2*nblock**2+1 ), lwork-2*nblock**2,
739 80
CALL shgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
740 $ alphar, alphai, beta, q, ldq, z, ldz, work, lwork,
subroutine xerbla(srname, info)
subroutine shgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
SHGEQZ
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
real function slamch(cmach)
SLAMCH
real function slanhs(norm, n, a, lda, work)
SLANHS returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
recursive subroutine slaqz0(wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, rec, info)
SLAQZ0
recursive subroutine slaqz3(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)
SLAQZ3
subroutine slaqz4(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)
SLAQZ4
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
logical function lsame(ca, cb)
LSAME
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT
real function sroundup_lwork(lwork)
SROUNDUP_LWORK