370 SUBROUTINE cggevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB,
371 $ ALPHA, BETA, VL, LDVL, VR, LDVR, ILO, IHI,
372 $ LSCALE, RSCALE, ABNRM, BBNRM, RCONDE, RCONDV,
373 $ WORK, LWORK, RWORK, IWORK, BWORK, INFO )
380 CHARACTER BALANC, JOBVL, JOBVR, SENSE
381 INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
387 REAL LSCALE( * ), RCONDE( * ), RCONDV( * ),
388 $ rscale( * ), rwork( * )
389 COMPLEX A( LDA, * ), ALPHA( * ), B( LDB, * ),
390 $ beta( * ), vl( ldvl, * ), vr( ldvr, * ),
398 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
400 parameter( czero = ( 0.0e+0, 0.0e+0 ),
401 $ cone = ( 1.0e+0, 0.0e+0 ) )
404 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,
405 $ WANTSB, WANTSE, WANTSN, WANTSV
407 INTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,
408 $ ITAU, IWRK, IWRK1, J, JC, JR, M, MAXWRK, MINWRK
409 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
424 REAL CLANGE, SLAMCH, SROUNDUP_LWORK
425 EXTERNAL lsame, ilaenv, clange, slamch, sroundup_lwork
428 INTRINSIC abs, aimag, max, real, sqrt
434 abs1( x ) = abs( real( x ) ) + abs( aimag( x ) )
440 IF( lsame( jobvl,
'N' ) )
THEN
443 ELSE IF( lsame( jobvl,
'V' ) )
THEN
451 IF( lsame( jobvr,
'N' ) )
THEN
454 ELSE IF( lsame( jobvr,
'V' ) )
THEN
463 noscl = lsame( balanc,
'N' ) .OR. lsame( balanc,
'P' )
464 wantsn = lsame( sense,
'N' )
465 wantse = lsame( sense,
'E' )
466 wantsv = lsame( sense,
'V' )
467 wantsb = lsame( sense,
'B' )
472 lquery = ( lwork.EQ.-1 )
473 IF( .NOT.( noscl .OR. lsame( balanc,
'S' ) .OR.
474 $ lsame( balanc,
'B' ) ) )
THEN
476 ELSE IF( ijobvl.LE.0 )
THEN
478 ELSE IF( ijobvr.LE.0 )
THEN
480 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsb .OR. wantsv ) )
483 ELSE IF( n.LT.0 )
THEN
485 ELSE IF( lda.LT.max( 1, n ) )
THEN
487 ELSE IF( ldb.LT.max( 1, n ) )
THEN
489 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
491 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
511 ELSE IF( wantsv .OR. wantsb )
THEN
512 minwrk = 2*n*( n + 1)
515 maxwrk = max( maxwrk,
516 $ n + n*ilaenv( 1,
'CGEQRF',
' ', n, 1, n, 0 ) )
517 maxwrk = max( maxwrk,
518 $ n + n*ilaenv( 1,
'CUNMQR',
' ', n, 1, n, 0 ) )
520 maxwrk = max( maxwrk, n +
521 $ n*ilaenv( 1,
'CUNGQR',
' ', n, 1, n, 0 ) )
524 work( 1 ) = sroundup_lwork(maxwrk)
526 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
532 CALL xerbla(
'CGGEVX', -info )
534 ELSE IF( lquery )
THEN
546 smlnum = slamch(
'S' )
547 bignum = one / smlnum
548 smlnum = sqrt( smlnum ) / eps
549 bignum = one / smlnum
553 anrm = clange(
'M', n, n, a, lda, rwork )
555 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
558 ELSE IF( anrm.GT.bignum )
THEN
563 $
CALL clascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
567 bnrm = clange(
'M', n, n, b, ldb, rwork )
569 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
572 ELSE IF( bnrm.GT.bignum )
THEN
577 $
CALL clascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
582 CALL cggbal( balanc, n, a, lda, b, ldb, ilo, ihi, lscale, rscale,
587 abnrm = clange(
'1', n, n, a, lda, rwork( 1 ) )
590 CALL slascl(
'G', 0, 0, anrmto, anrm, 1, 1, rwork( 1 ), 1,
595 bbnrm = clange(
'1', n, n, b, ldb, rwork( 1 ) )
598 CALL slascl(
'G', 0, 0, bnrmto, bnrm, 1, 1, rwork( 1 ), 1,
606 irows = ihi + 1 - ilo
607 IF( ilv .OR. .NOT.wantsn )
THEN
614 CALL cgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
615 $ work( iwrk ), lwork+1-iwrk, ierr )
620 CALL cunmqr(
'L',
'C', irows, icols, irows, b( ilo, ilo ), ldb,
621 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
622 $ lwork+1-iwrk, ierr )
628 CALL claset(
'Full', n, n, czero, cone, vl, ldvl )
629 IF( irows.GT.1 )
THEN
630 CALL clacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
631 $ vl( ilo+1, ilo ), ldvl )
633 CALL cungqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
634 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
638 $
CALL claset(
'Full', n, n, czero, cone, vr, ldvr )
643 IF( ilv .OR. .NOT.wantsn )
THEN
647 CALL cgghrd( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
648 $ ldvl, vr, ldvr, ierr )
650 CALL cgghrd(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
651 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr, ierr )
660 IF( ilv .OR. .NOT.wantsn )
THEN
666 CALL chgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
667 $ alpha, beta, vl, ldvl, vr, ldvr, work( iwrk ),
668 $ lwork+1-iwrk, rwork, ierr )
670 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
672 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
686 IF( ilv .OR. .NOT.wantsn )
THEN
698 CALL ctgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl,
699 $ ldvl, vr, ldvr, n, in, work( iwrk ), rwork,
707 IF( .NOT.wantsn )
THEN
728 IF( wantse .OR. wantsb )
THEN
729 CALL ctgevc(
'B',
'S', bwork, n, a, lda, b, ldb,
730 $ work( 1 ), n, work( iwrk ), n, 1, m,
731 $ work( iwrk1 ), rwork, ierr )
738 CALL ctgsna( sense,
'S', bwork, n, a, lda, b, ldb,
739 $ work( 1 ), n, work( iwrk ), n, rconde( i ),
740 $ rcondv( i ), 1, m, work( iwrk1 ),
741 $ lwork-iwrk1+1, iwork, ierr )
751 CALL cggbak( balanc,
'L', n, ilo, ihi, lscale, rscale, n, vl,
757 temp = max( temp, abs1( vl( jr, jc ) ) )
763 vl( jr, jc ) = vl( jr, jc )*temp
769 CALL cggbak( balanc,
'R', n, ilo, ihi, lscale, rscale, n, vr,
774 temp = max( temp, abs1( vr( jr, jc ) ) )
780 vr( jr, jc ) = vr( jr, jc )*temp
790 $
CALL clascl(
'G', 0, 0, anrmto, anrm, n, 1, alpha, n, ierr )
793 $
CALL clascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
795 work( 1 ) = sroundup_lwork(maxwrk)
subroutine xerbla(srname, info)
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
subroutine cggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
CGGBAK
subroutine cggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
CGGBAL
subroutine cggevx(balanc, jobvl, jobvr, sense, n, a, lda, b, ldb, alpha, beta, vl, ldvl, vr, ldvr, ilo, ihi, lscale, rscale, abnrm, bbnrm, rconde, rcondv, work, lwork, rwork, iwork, bwork, info)
CGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices
subroutine cgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
CGGHRD
subroutine chgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alpha, beta, q, ldq, z, ldz, work, lwork, rwork, info)
CHGEQZ
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine ctgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, rwork, info)
CTGEVC
subroutine ctgsna(job, howmny, select, n, a, lda, b, ldb, vl, ldvl, vr, ldvr, s, dif, mm, m, work, lwork, iwork, info)
CTGSNA
subroutine cungqr(m, n, k, a, lda, tau, work, lwork, info)
CUNGQR
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR