385 SUBROUTINE sggevx( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B,
387 $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,
388 $ IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,
389 $ RCONDV, WORK, LWORK, IWORK, BWORK, INFO )
396 CHARACTER BALANC, JOBVL, JOBVR, SENSE
397 INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
403 REAL A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
404 $ B( LDB, * ), BETA( * ), LSCALE( * ),
405 $ rconde( * ), rcondv( * ), rscale( * ),
406 $ vl( ldvl, * ), vr( ldvr, * ), work( * )
413 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
416 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,
417 $ pair, wantsb, wantse, wantsn, wantsv
419 INTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,
420 $ itau, iwrk, iwrk1, j, jc, jr, m, maxwrk,
422 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
429 EXTERNAL SGEQRF, SGGBAK, SGGBAL, SGGHRD, SHGEQZ,
437 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
438 EXTERNAL LSAME, ILAENV, SLAMCH,
439 $ slange, sroundup_lwork
442 INTRINSIC abs, max, sqrt
448 IF( lsame( jobvl,
'N' ) )
THEN
451 ELSE IF( lsame( jobvl,
'V' ) )
THEN
459 IF( lsame( jobvr,
'N' ) )
THEN
462 ELSE IF( lsame( jobvr,
'V' ) )
THEN
471 noscl = lsame( balanc,
'N' ) .OR. lsame( balanc,
'P' )
472 wantsn = lsame( sense,
'N' )
473 wantse = lsame( sense,
'E' )
474 wantsv = lsame( sense,
'V' )
475 wantsb = lsame( sense,
'B' )
480 lquery = ( lwork.EQ.-1 )
481 IF( .NOT.( noscl .OR. lsame( balanc,
'S' ) .OR.
482 $ lsame( balanc,
'B' ) ) )
THEN
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
523 ELSE IF( wantsv .OR. wantsb )
THEN
524 minwrk = 2*n*( n + 4 ) + 16
527 maxwrk = max( maxwrk,
528 $ n + n*ilaenv( 1,
'SGEQRF',
' ', n, 1, n,
530 maxwrk = max( maxwrk,
531 $ n + n*ilaenv( 1,
'SORMQR',
' ', n, 1, n,
534 maxwrk = max( maxwrk, n +
535 $ n*ilaenv( 1,
'SORGQR',
' ', n, 1, n,
539 work( 1 ) = sroundup_lwork(maxwrk)
541 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
547 CALL xerbla(
'SGGEVX', -info )
549 ELSE IF( lquery )
THEN
562 smlnum = slamch(
'S' )
563 bignum = one / smlnum
564 smlnum = sqrt( smlnum ) / eps
565 bignum = one / smlnum
569 anrm = slange(
'M', n, n, a, lda, work )
571 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
574 ELSE IF( anrm.GT.bignum )
THEN
579 $
CALL slascl(
'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
583 bnrm = slange(
'M', n, n, b, ldb, work )
585 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
588 ELSE IF( bnrm.GT.bignum )
THEN
593 $
CALL slascl(
'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
598 CALL sggbal( balanc, n, a, lda, b, ldb, ilo, ihi, lscale,
604 abnrm = slange(
'1', n, n, a, lda, work( 1 ) )
607 CALL slascl(
'G', 0, 0, anrmto, anrm, 1, 1, work( 1 ), 1,
612 bbnrm = slange(
'1', n, n, b, ldb, work( 1 ) )
615 CALL slascl(
'G', 0, 0, bnrmto, bnrm, 1, 1, work( 1 ), 1,
623 irows = ihi + 1 - ilo
624 IF( ilv .OR. .NOT.wantsn )
THEN
631 CALL sgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
632 $ work( iwrk ), lwork+1-iwrk, ierr )
637 CALL sormqr(
'L',
'T', irows, icols, irows, b( ilo, ilo ), ldb,
638 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
639 $ lwork+1-iwrk, ierr )
645 CALL slaset(
'Full', n, n, zero, one, vl, ldvl )
646 IF( irows.GT.1 )
THEN
647 CALL slacpy(
'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
648 $ vl( ilo+1, ilo ), ldvl )
650 CALL sorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
651 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
655 $
CALL slaset(
'Full', n, n, zero, one, vr, ldvr )
660 IF( ilv .OR. .NOT.wantsn )
THEN
664 CALL sgghrd( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
665 $ ldvl, vr, ldvr, ierr )
667 CALL sgghrd(
'N',
'N', irows, 1, irows, a( ilo, ilo ), lda,
668 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr, ierr )
675 IF( ilv .OR. .NOT.wantsn )
THEN
681 CALL shgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
682 $ alphar, alphai, beta, vl, ldvl, vr, ldvr, work,
685 IF( ierr.GT.0 .AND. ierr.LE.n )
THEN
687 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n )
THEN
700 IF( ilv .OR. .NOT.wantsn )
THEN
712 CALL stgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl,
713 $ ldvl, vr, ldvr, n, in, work, ierr )
720 IF( .NOT.wantsn )
THEN
739 IF( a( i+1, i ).NE.zero )
THEN
750 ELSE IF( mm.EQ.2 )
THEN
752 bwork( i+1 ) = .true.
761 IF( wantse .OR. wantsb )
THEN
762 CALL stgevc(
'B',
'S', bwork, n, a, lda, b, ldb,
763 $ work( 1 ), n, work( iwrk ), n, mm, m,
764 $ work( iwrk1 ), ierr )
771 CALL stgsna( sense,
'S', bwork, n, a, lda, b, ldb,
772 $ work( 1 ), n, work( iwrk ), n, rconde( i ),
773 $ rcondv( i ), mm, m, work( iwrk1 ),
774 $ lwork-iwrk1+1, iwork, ierr )
784 CALL sggbak( balanc,
'L', n, ilo, ihi, lscale, rscale, n,
789 IF( alphai( jc ).LT.zero )
792 IF( alphai( jc ).EQ.zero )
THEN
794 temp = max( temp, abs( vl( jr, jc ) ) )
798 temp = max( temp, abs( vl( jr, jc ) )+
799 $ abs( vl( jr, jc+1 ) ) )
805 IF( alphai( jc ).EQ.zero )
THEN
807 vl( jr, jc ) = vl( jr, jc )*temp
811 vl( jr, jc ) = vl( jr, jc )*temp
812 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
818 CALL sggbak( balanc,
'R', n, ilo, ihi, lscale, rscale, n,
822 IF( alphai( jc ).LT.zero )
825 IF( alphai( jc ).EQ.zero )
THEN
827 temp = max( temp, abs( vr( jr, jc ) ) )
831 temp = max( temp, abs( vr( jr, jc ) )+
832 $ abs( vr( jr, jc+1 ) ) )
838 IF( alphai( jc ).EQ.zero )
THEN
840 vr( jr, jc ) = vr( jr, jc )*temp
844 vr( jr, jc ) = vr( jr, jc )*temp
845 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
856 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
858 CALL slascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
863 CALL slascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
866 work( 1 ) = sroundup_lwork(maxwrk)