387 SUBROUTINE dggevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB,
388 $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,
389 $ IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,
390 $ RCONDV, WORK, LWORK, IWORK, BWORK, INFO )
397 CHARACTER BALANC, JOBVL, JOBVR, SENSE
398 INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
399 DOUBLE PRECISION ABNRM, BBNRM
404 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
405 $ b( ldb, * ), beta( * ), lscale( * ),
406 $ rconde( * ), rcondv( * ), rscale( * ),
407 $ vl( ldvl, * ), vr( ldvr, * ), work( * )
413 DOUBLE PRECISION ZERO, ONE
414 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
417 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,
418 $ PAIR, WANTSB, WANTSE, WANTSN, WANTSV
420 INTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,
421 $ ITAU, IWRK, IWRK1, J, JC, JR, M, MAXWRK,
423 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
437 DOUBLE PRECISION DLAMCH, DLANGE
438 EXTERNAL lsame, ilaenv, dlamch, dlange
441 INTRINSIC abs, max, sqrt
447 IF( lsame( jobvl,
'N' ) )
THEN
450 ELSE IF( lsame( jobvl,
'V' ) )
THEN
458 IF( lsame( jobvr,
'N' ) )
THEN
461 ELSE IF( lsame( jobvr,
'V' ) )
THEN
470 noscl = lsame( balanc,
'N' ) .OR. lsame( balanc,
'P' )
471 wantsn = lsame( sense,
'N' )
472 wantse = lsame( sense,
'E' )
473 wantsv = lsame( sense,
'V' )
474 wantsb = lsame( sense,
'B' )
479 lquery = ( lwork.EQ.-1 )
480 IF( .NOT.( lsame( balanc,
'N' ) .OR. lsame( balanc,
481 $
'S' ) .OR. lsame( balanc,
'P' ) .OR. lsame( balanc,
'B' ) ) )
484 ELSE IF( ijobvl.LE.0 )
THEN
486 ELSE IF( ijobvr.LE.0 )
THEN
488 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsb .OR. wantsv ) )
491 ELSE IF( n.LT.0 )
THEN
493 ELSE IF( lda.LT.max( 1, n ) )
THEN
495 ELSE IF( ldb.LT.max( 1, n ) )
THEN
497 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
499 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
516 IF( noscl .AND. .NOT.ilv )
THEN
521 IF( wantse .OR. wantsb )
THEN
524 IF( wantsv .OR. wantsb )
THEN
525 minwrk = max( minwrk, 2*n*( n + 4 ) + 16 )
528 maxwrk = max( maxwrk,
529 $ n + n*ilaenv( 1,
'DGEQRF',
' ', n, 1, n, 0 ) )
530 maxwrk = max( maxwrk,
531 $ n + n*ilaenv( 1,
'DORMQR',
' ', n, 1, n, 0 ) )
533 maxwrk = max( maxwrk, n +
534 $ n*ilaenv( 1,
'DORGQR',
' ', n, 1, n, 0 ) )
539 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
545 CALL xerbla(
'DGGEVX', -info )
547 ELSE IF( lquery )
THEN
560 smlnum = dlamch(
'S' )
561 bignum = one / smlnum
562 smlnum = sqrt( smlnum ) / eps
563 bignum = one / smlnum
567 anrm = dlange(
'M', n, n, a, lda, work )
569 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
572 ELSE IF( anrm.GT.bignum )
THEN
577 $
CALL dlascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
581 bnrm = dlange(
'M', n, n, b, ldb, work )
583 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
586 ELSE IF( bnrm.GT.bignum )
THEN
591 $
CALL dlascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
596 CALL dggbal( balanc, n, a, lda, b, ldb, ilo, ihi, lscale, rscale,
601 abnrm = dlange(
'1', n, n, a, lda, work( 1 ) )
604 CALL dlascl(
'G', 0, 0, anrmto, anrm, 1, 1, work( 1 ), 1,
609 bbnrm = dlange(
'1', n, n, b, ldb, work( 1 ) )
612 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, 1, 1, work( 1 ), 1,
620 irows = ihi + 1 - ilo
621 IF( ilv .OR. .NOT.wantsn )
THEN
628 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
629 $ work( iwrk ), lwork+1-iwrk, ierr )
634 CALL dormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
635 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
636 $ lwork+1-iwrk, ierr )
642 CALL dlaset(
'Full', n, n, zero, one, vl, ldvl )
643 IF( irows.GT.1 )
THEN
644 CALL dlacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
645 $ vl( ilo+1, ilo ), ldvl )
647 CALL dorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
648 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
652 $
CALL dlaset(
'Full', n, n, zero, one, vr, ldvr )
657 IF( ilv .OR. .NOT.wantsn )
THEN
661 CALL dgghrd( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
662 $ ldvl, vr, ldvr, ierr )
664 CALL dgghrd(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
665 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr, ierr )
672 IF( ilv .OR. .NOT.wantsn )
THEN
678 CALL dhgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
679 $ alphar, alphai, beta, vl, ldvl, vr, ldvr, work,
682 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
684 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
697 IF( ilv .OR. .NOT.wantsn )
THEN
709 CALL dtgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl,
710 $ ldvl, vr, ldvr, n, in, work, ierr )
717 IF( .NOT.wantsn )
THEN
736 IF( a( i+1, i ).NE.zero )
THEN
747 ELSE IF( mm.EQ.2 )
THEN
749 bwork( i+1 ) = .true.
758 IF( wantse .OR. wantsb )
THEN
759 CALL dtgevc(
'B',
'S', bwork, n, a, lda, b, ldb,
760 $ work( 1 ), n, work( iwrk ), n, mm, m,
761 $ work( iwrk1 ), ierr )
768 CALL dtgsna( sense,
'S', bwork, n, a, lda, b, ldb,
769 $ work( 1 ), n, work( iwrk ), n, rconde( i ),
770 $ rcondv( i ), mm, m, work( iwrk1 ),
771 $ lwork-iwrk1+1, iwork, ierr )
781 CALL dggbak( balanc,
'L', n, ilo, ihi, lscale, rscale, n, vl,
785 IF( alphai( jc ).LT.zero )
788 IF( alphai( jc ).EQ.zero )
THEN
790 temp = max( temp, abs( vl( jr, jc ) ) )
794 temp = max( temp, abs( vl( jr, jc ) )+
795 $ abs( vl( jr, jc+1 ) ) )
801 IF( alphai( jc ).EQ.zero )
THEN
803 vl( jr, jc ) = vl( jr, jc )*temp
807 vl( jr, jc ) = vl( jr, jc )*temp
808 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
814 CALL dggbak( balanc,
'R', n, ilo, ihi, lscale, rscale, n, vr,
817 IF( alphai( jc ).LT.zero )
820 IF( alphai( jc ).EQ.zero )
THEN
822 temp = max( temp, abs( vr( jr, jc ) ) )
826 temp = max( temp, abs( vr( jr, jc ) )+
827 $ abs( vr( jr, jc+1 ) ) )
833 IF( alphai( jc ).EQ.zero )
THEN
835 vr( jr, jc ) = vr( jr, jc )*temp
839 vr( jr, jc ) = vr( jr, jc )*temp
840 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
851 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
852 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
856 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
subroutine xerbla(srname, info)
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
DGGBAK
subroutine dggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
DGGBAL
subroutine dggevx(balanc, jobvl, jobvr, sense, n, a, lda, b, ldb, alphar, alphai, beta, vl, ldvl, vr, ldvr, ilo, ihi, lscale, rscale, abnrm, bbnrm, rconde, rcondv, work, lwork, iwork, bwork, info)
DGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices
subroutine dgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
DGGHRD
subroutine dhgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
DHGEQZ
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
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.
subroutine dtgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, info)
DTGEVC
subroutine dtgsna(job, howmny, select, n, a, lda, b, ldb, vl, ldvl, vr, ldvr, s, dif, mm, m, work, lwork, iwork, info)
DTGSNA
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR