387 SUBROUTINE sggevx( 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
404 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
405 $ b( ldb, * ), beta( * ), lscale( * ),
406 $ rconde( * ), rcondv( * ), rscale( * ),
407 $ vl( ldvl, * ), vr( ldvr, * ), work( * )
414 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+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 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
437 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
438 EXTERNAL lsame, ilaenv, slamch, slange, sroundup_lwork
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.( noscl .OR. lsame( balanc,
'S' ) .OR.
481 $ lsame( balanc,
'B' ) ) )
THEN
483 ELSE IF( ijobvl.LE.0 )
THEN
485 ELSE IF( ijobvr.LE.0 )
THEN
487 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsb .OR. wantsv ) )
490 ELSE IF( n.LT.0 )
THEN
492 ELSE IF( lda.LT.max( 1, n ) )
THEN
494 ELSE IF( ldb.LT.max( 1, n ) )
THEN
496 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
498 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
515 IF( noscl .AND. .NOT.ilv )
THEN
522 ELSE IF( wantsv .OR. wantsb )
THEN
523 minwrk = 2*n*( n + 4 ) + 16
526 maxwrk = max( maxwrk,
527 $ n + n*ilaenv( 1,
'SGEQRF',
' ', n, 1, n, 0 ) )
528 maxwrk = max( maxwrk,
529 $ n + n*ilaenv( 1,
'SORMQR',
' ', n, 1, n, 0 ) )
531 maxwrk = max( maxwrk, n +
532 $ n*ilaenv( 1,
'SORGQR',
' ', n, 1, n, 0 ) )
535 work( 1 ) = sroundup_lwork(maxwrk)
537 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
543 CALL xerbla(
'SGGEVX', -info )
545 ELSE IF( lquery )
THEN
558 smlnum = slamch(
'S' )
559 bignum = one / smlnum
560 smlnum = sqrt( smlnum ) / eps
561 bignum = one / smlnum
565 anrm = slange(
'M', n, n, a, lda, work )
567 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
570 ELSE IF( anrm.GT.bignum )
THEN
575 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
579 bnrm = slange(
'M', n, n, b, ldb, work )
581 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
584 ELSE IF( bnrm.GT.bignum )
THEN
589 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
594 CALL sggbal( balanc, n, a, lda, b, ldb, ilo, ihi, lscale, rscale,
599 abnrm = slange(
'1', n, n, a, lda, work( 1 ) )
602 CALL slascl(
'G', 0, 0, anrmto, anrm, 1, 1, work( 1 ), 1,
607 bbnrm = slange(
'1', n, n, b, ldb, work( 1 ) )
610 CALL slascl(
'G', 0, 0, bnrmto, bnrm, 1, 1, work( 1 ), 1,
618 irows = ihi + 1 - ilo
619 IF( ilv .OR. .NOT.wantsn )
THEN
626 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
627 $ work( iwrk ), lwork+1-iwrk, ierr )
632 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
633 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
634 $ lwork+1-iwrk, ierr )
640 CALL slaset(
'Full', n, n, zero, one, vl, ldvl )
641 IF( irows.GT.1 )
THEN
642 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
643 $ vl( ilo+1, ilo ), ldvl )
645 CALL sorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
646 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
650 $
CALL slaset(
'Full', n, n, zero, one, vr, ldvr )
655 IF( ilv .OR. .NOT.wantsn )
THEN
659 CALL sgghrd( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
660 $ ldvl, vr, ldvr, ierr )
662 CALL sgghrd(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
663 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr, ierr )
670 IF( ilv .OR. .NOT.wantsn )
THEN
676 CALL shgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
677 $ alphar, alphai, beta, vl, ldvl, vr, ldvr, work,
680 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
682 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
695 IF( ilv .OR. .NOT.wantsn )
THEN
707 CALL stgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl,
708 $ ldvl, vr, ldvr, n, in, work, ierr )
715 IF( .NOT.wantsn )
THEN
734 IF( a( i+1, i ).NE.zero )
THEN
745 ELSE IF( mm.EQ.2 )
THEN
747 bwork( i+1 ) = .true.
756 IF( wantse .OR. wantsb )
THEN
757 CALL stgevc(
'B',
'S', bwork, n, a, lda, b, ldb,
758 $ work( 1 ), n, work( iwrk ), n, mm, m,
759 $ work( iwrk1 ), ierr )
766 CALL stgsna( sense,
'S', bwork, n, a, lda, b, ldb,
767 $ work( 1 ), n, work( iwrk ), n, rconde( i ),
768 $ rcondv( i ), mm, m, work( iwrk1 ),
769 $ lwork-iwrk1+1, iwork, ierr )
779 CALL sggbak( balanc,
'L', n, ilo, ihi, lscale, rscale, n, vl,
783 IF( alphai( jc ).LT.zero )
786 IF( alphai( jc ).EQ.zero )
THEN
788 temp = max( temp, abs( vl( jr, jc ) ) )
792 temp = max( temp, abs( vl( jr, jc ) )+
793 $ abs( vl( jr, jc+1 ) ) )
799 IF( alphai( jc ).EQ.zero )
THEN
801 vl( jr, jc ) = vl( jr, jc )*temp
805 vl( jr, jc ) = vl( jr, jc )*temp
806 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
812 CALL sggbak( balanc,
'R', n, ilo, ihi, lscale, rscale, n, vr,
815 IF( alphai( jc ).LT.zero )
818 IF( alphai( jc ).EQ.zero )
THEN
820 temp = max( temp, abs( vr( jr, jc ) ) )
824 temp = max( temp, abs( vr( jr, jc ) )+
825 $ abs( vr( jr, jc+1 ) ) )
831 IF( alphai( jc ).EQ.zero )
THEN
833 vr( jr, jc ) = vr( jr, jc )*temp
837 vr( jr, jc ) = vr( jr, jc )*temp
838 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
849 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
850 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
854 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
857 work( 1 ) = sroundup_lwork(maxwrk)
subroutine xerbla(srname, info)
subroutine sgeqrf(m, n, a, lda, tau, work, lwork, info)
SGEQRF
subroutine sggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
SGGBAK
subroutine sggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
SGGBAL
subroutine sggevx(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)
SGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices
subroutine sgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
SGGHRD
subroutine shgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
SHGEQZ
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
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 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 stgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, info)
STGEVC
subroutine stgsna(job, howmny, select, n, a, lda, b, ldb, vl, ldvl, vr, ldvr, s, dif, mm, m, work, lwork, iwork, info)
STGSNA
subroutine sorgqr(m, n, k, a, lda, tau, work, lwork, info)
SORGQR
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR