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
322 INTEGER :: istart, istop, iiter, maxit, istart2, k, ld, nshifts,
323 $ nblock, nw, nmin, nibble, n_undeflated, n_deflated,
324 $ ns, sweep_info, shiftpos, lworkreq, k2, istartm,
325 $ istopm, iwants, iwantq, iwantz, norm_info, aed_info,
326 $ nwr, nbr, nsr, itemp1, itemp2, rcost, i
327 LOGICAL :: ilschur, ilq, ilz
328 CHARACTER :: jbcmpz*3
334 LOGICAL,
EXTERNAL ::
lsame
335 INTEGER,
EXTERNAL ::
ilaenv
340 IF(
lsame( wants,
'E' ) )
THEN
343 ELSE IF(
lsame( wants,
'S' ) )
THEN
350 IF(
lsame( wantq,
'N' ) )
THEN
353 ELSE IF(
lsame( wantq,
'V' ) )
THEN
356 ELSE IF(
lsame( wantq,
'I' ) )
THEN
363 IF(
lsame( wantz,
'N' ) )
THEN
366 ELSE IF(
lsame( wantz,
'V' ) )
THEN
369 ELSE IF(
lsame( wantz,
'I' ) )
THEN
379 IF( iwants.EQ.0 )
THEN
381 ELSE IF( iwantq.EQ.0 )
THEN
383 ELSE IF( iwantz.EQ.0 )
THEN
385 ELSE IF( n.LT.0 )
THEN
387 ELSE IF( ilo.LT.1 )
THEN
389 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
391 ELSE IF( lda.LT.n )
THEN
393 ELSE IF( ldb.LT.n )
THEN
395 ELSE IF( ldq.LT.1 .OR. ( ilq .AND. ldq.LT.n ) )
THEN
397 ELSE IF( ldz.LT.1 .OR. ( ilz .AND. ldz.LT.n ) )
THEN
401 CALL xerbla(
'SLAQZ0', -info )
409 work( 1 ) = real( 1 )
416 jbcmpz( 1:1 ) = wants
417 jbcmpz( 2:2 ) = wantq
418 jbcmpz( 3:3 ) = wantz
420 nmin =
ilaenv( 12,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
422 nwr =
ilaenv( 13,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
424 nwr = min( ihi-ilo+1, ( n-1 ) / 3, nwr )
426 nibble =
ilaenv( 14,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
428 nsr =
ilaenv( 15,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
429 nsr = min( nsr, ( n+6 ) / 9, ihi-ilo )
430 nsr = max( 2, nsr-mod( nsr, 2 ) )
432 rcost =
ilaenv( 17,
'SLAQZ0', jbcmpz, n, ilo, ihi, lwork )
433 itemp1 = int( nsr/sqrt( 1+2*nsr/( real( rcost )/100*n ) ) )
434 itemp1 = ( ( itemp1-1 )/4 )*4+4
437 IF( n .LT. nmin .OR. rec .GE. 2 )
THEN
438 CALL shgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
439 $ alphar, alphai, beta, q, ldq, z, ldz, work,
449 nw = max( nwr, nmin )
450 CALL slaqz3( ilschur, ilq, ilz, n, ilo, ihi, nw, a, lda, b, ldb,
451 $ q, ldq, z, ldz, n_undeflated, n_deflated, alphar,
452 $ alphai, beta, work, nw, work, nw, work, -1, rec,
454 itemp1 = int( work( 1 ) )
456 CALL slaqz4( ilschur, ilq, ilz, n, ilo, ihi, nsr, nbr, alphar,
457 $ alphai, beta, a, lda, b, ldb, q, ldq, z, ldz, work,
458 $ nbr, work, nbr, work, -1, sweep_info )
459 itemp2 = int( work( 1 ) )
461 lworkreq = max( itemp1+2*nw**2, itemp2+2*nbr**2 )
462 IF ( lwork .EQ.-1 )
THEN
463 work( 1 ) = real( lworkreq )
465 ELSE IF ( lwork .LT. lworkreq )
THEN
469 CALL xerbla(
'SLAQZ0', info )
475 IF( iwantq.EQ.3 )
CALL slaset(
'FULL', n, n, zero, one, q, ldq )
476 IF( iwantz.EQ.3 )
CALL slaset(
'FULL', n, n, zero, one, z, ldz )
479 safmin =
slamch(
'SAFE MINIMUM' )
481 CALL slabad( safmin, safmax )
482 ulp =
slamch(
'PRECISION' )
483 smlnum = safmin*( real( n )/ulp )
487 maxit = 3*( ihi-ilo+1 )
491 IF( iiter .GE. maxit )
THEN
495 IF ( istart+1 .GE. istop )
THEN
501 IF ( abs( a( istop-1, istop-2 ) ) .LE. max( smlnum,
502 $ ulp*( abs( a( istop-1, istop-1 ) )+abs( a( istop-2,
503 $ istop-2 ) ) ) ) )
THEN
504 a( istop-1, istop-2 ) = zero
508 ELSE IF ( abs( a( istop, istop-1 ) ) .LE. max( smlnum,
509 $ ulp*( abs( a( istop, istop ) )+abs( a( istop-1,
510 $ istop-1 ) ) ) ) )
THEN
511 a( istop, istop-1 ) = zero
517 IF ( abs( a( istart+2, istart+1 ) ) .LE. max( smlnum,
518 $ ulp*( abs( a( istart+1, istart+1 ) )+abs( a( istart+2,
519 $ istart+2 ) ) ) ) )
THEN
520 a( istart+2, istart+1 ) = zero
524 ELSE IF ( abs( a( istart+1, istart ) ) .LE. max( smlnum,
525 $ ulp*( abs( a( istart, istart ) )+abs( a( istart+1,
526 $ istart+1 ) ) ) ) )
THEN
527 a( istart+1, istart ) = zero
533 IF ( istart+1 .GE. istop )
THEN
539 DO k = istop, istart+1, -1
540 IF ( abs( a( k, k-1 ) ) .LE. max( smlnum, ulp*( abs( a( k,
541 $ k ) )+abs( a( k-1, k-1 ) ) ) ) )
THEN
560 DO WHILE ( k.GE.istart2 )
562 IF( k .LT. istop )
THEN
563 temp = temp+abs( b( k, k+1 ) )
565 IF( k .GT. istart2 )
THEN
566 temp = temp+abs( b( k-1, k ) )
569 IF( abs( b( k, k ) ) .LT. max( smlnum, ulp*temp ) )
THEN
573 DO k2 = k, istart2+1, -1
574 CALL slartg( b( k2-1, k2 ), b( k2-1, k2-1 ), c1, s1,
577 b( k2-1, k2-1 ) = zero
579 CALL srot( k2-2-istartm+1, b( istartm, k2 ), 1,
580 $ b( istartm, k2-1 ), 1, c1, s1 )
581 CALL srot( min( k2+1, istop )-istartm+1, a( istartm,
582 $ k2 ), 1, a( istartm, k2-1 ), 1, c1, s1 )
584 CALL srot( n, z( 1, k2 ), 1, z( 1, k2-1 ), 1, c1,
588 IF( k2.LT.istop )
THEN
589 CALL slartg( a( k2, k2-1 ), a( k2+1, k2-1 ), c1,
592 a( k2+1, k2-1 ) = zero
594 CALL srot( istopm-k2+1, a( k2, k2 ), lda, a( k2+1,
595 $ k2 ), lda, c1, s1 )
596 CALL srot( istopm-k2+1, b( k2, k2 ), ldb, b( k2+1,
597 $ k2 ), ldb, c1, s1 )
599 CALL srot( n, q( 1, k2 ), 1, q( 1, k2+1 ), 1,
606 IF( istart2.LT.istop )
THEN
607 CALL slartg( a( istart2, istart2 ), a( istart2+1,
608 $ istart2 ), c1, s1, temp )
609 a( istart2, istart2 ) = temp
610 a( istart2+1, istart2 ) = zero
612 CALL srot( istopm-( istart2+1 )+1, a( istart2,
613 $ istart2+1 ), lda, a( istart2+1,
614 $ istart2+1 ), lda, c1, s1 )
615 CALL srot( istopm-( istart2+1 )+1, b( istart2,
616 $ istart2+1 ), ldb, b( istart2+1,
617 $ istart2+1 ), ldb, c1, s1 )
619 CALL srot( n, q( 1, istart2 ), 1, q( 1,
620 $ istart2+1 ), 1, c1, s1 )
632 IF ( istart2 .GE. istop )
THEN
643 IF ( istop-istart2+1 .LT. nmin )
THEN
647 IF ( istop-istart+1 .LT. nmin )
THEN
658 CALL slaqz3( ilschur, ilq, ilz, n, istart2, istop, nw, a, lda,
659 $ b, ldb, q, ldq, z, ldz, n_undeflated, n_deflated,
660 $ alphar, alphai, beta, work, nw, work( nw**2+1 ),
661 $ nw, work( 2*nw**2+1 ), lwork-2*nw**2, rec,
664 IF ( n_deflated > 0 )
THEN
665 istop = istop-n_deflated
670 IF ( 100*n_deflated > nibble*( n_deflated+n_undeflated ) .OR.
671 $ istop-istart2+1 .LT. nmin )
THEN
679 ns = min( nshifts, istop-istart2 )
680 ns = min( ns, n_undeflated )
681 shiftpos = istop-n_deflated-n_undeflated+1
686 DO i = shiftpos, shiftpos+n_undeflated-1, 2
687 IF( alphai( i ).NE.-alphai( i+1 ) )
THEN
690 alphar( i ) = alphar( i+1 )
691 alphar( i+1 ) = alphar( i+2 )
695 alphai( i ) = alphai( i+1 )
696 alphai( i+1 ) = alphai( i+2 )
700 beta( i ) = beta( i+1 )
701 beta( i+1 ) = beta( i+2 )
706 IF ( mod( ld, 6 ) .EQ. 0 )
THEN
710 IF( ( real( maxit )*safmin )*abs( a( istop,
711 $ istop-1 ) ).LT.abs( a( istop-1, istop-1 ) ) )
THEN
712 eshift = a( istop, istop-1 )/b( istop-1, istop-1 )
714 eshift = eshift+one/( safmin*real( maxit ) )
716 alphar( shiftpos ) = one
717 alphar( shiftpos+1 ) = zero
718 alphai( shiftpos ) = zero
719 alphai( shiftpos+1 ) = zero
720 beta( shiftpos ) = eshift
721 beta( shiftpos+1 ) = eshift
728 CALL slaqz4( ilschur, ilq, ilz, n, istart2, istop, ns, nblock,
729 $ alphar( shiftpos ), alphai( shiftpos ),
730 $ beta( shiftpos ), a, lda, b, ldb, q, ldq, z, ldz,
731 $ work, nblock, work( nblock**2+1 ), nblock,
732 $ work( 2*nblock**2+1 ), lwork-2*nblock**2,
743 80
CALL shgeqz( wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb,
744 $ alphar, alphai, beta, q, ldq, z, ldz, work, lwork,
subroutine slabad(SMALL, LARGE)
SLABAD
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.
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
integer function ilaenv(ISPEC, NAME, OPTS, N1, N2, N3, N4)
ILAENV
subroutine xerbla(SRNAME, INFO)
XERBLA
logical function lsame(CA, CB)
LSAME
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
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
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
subroutine shgeqz(JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
SHGEQZ
subroutine srot(N, SX, INCX, SY, INCY, C, S)
SROT
real function slamch(CMACH)
SLAMCH