361 SUBROUTINE dggesx( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
362 $ B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
363 $ VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK,
364 $ LIWORK, BWORK, INFO )
371 CHARACTER JOBVSL, JOBVSR, , SORT
372 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
378 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
379 $ b( ldb, * ), beta( * ), rconde( 2 ),
380 $ rcondv( 2 ), vsl( ldvsl, * ), vsr( ldvsr, * ),
391 DOUBLE PRECISION ZERO, ONE
392 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
395 LOGICAL CURSL, , ILBSCL, ILVSL, ILVSR, LASTSL,
396 $ LQUERY, LST2SL, WANTSB, WANTSE, WANTSN, WANTST,
398 INTEGER I, ICOLS, IERR, IHI, , IJOBVL, IJOBVR,
399 $ ILEFT, ILO, IP, IRIGHT, IROWS, ITAU, IWRK,
400 $ LIWMIN, LWRK, MAXWRK, MINWRK
401 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
402 $ PR, SAFMAX, SAFMIN, SMLNUM
405 DOUBLE PRECISION DIF( 2 )
415 DOUBLE PRECISION DLAMCH, DLANGE
416 EXTERNAL lsame, ilaenv, dlamch, dlange
419 INTRINSIC abs,
max, sqrt
425 IF( lsame( jobvsl,
'N' ) )
THEN
428 ELSE IF( lsame( jobvsl,
'V' ) )
THEN
436 IF( lsame( jobvsr,
'N' ) )
THEN
439 ELSE IF( lsame( jobvsr,
'V' ) )
THEN
447 wantst = lsame( sort,
'S' )
448 wantsn = lsame( sense,
'N' )
449 wantse = lsame( sense,
'E' )
450 wantsv = lsame( sense,
'V' )
451 wantsb = lsame( sense,
'B' )
452 lquery = ( lwork.EQ.-1 .OR. liwork.EQ.-1 )
455 ELSE IF( wantse )
THEN
457 ELSE IF( wantsv )
THEN
459 ELSE IF( wantsb )
THEN
466 IF( ijobvl.LE.0 )
THEN
470 ELSE IF( ( .NOT.wantst ) .AND. ( .NOT.lsame( sort,
'N' ) ) )
THEN
472 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsv .OR. wantsb ) .OR.
475 ELSE IF( n.LT.0 )
THEN
477 ELSE IF( lda.LT.
max( 1, n ) )
THEN
479 ELSE IF( ldb.LT.
max( 1, n ) )
THEN
481 ELSE IF( ldvsl.LT.1 .OR. ( ilvsl .AND. ldvsl.LT.n ) )
THEN
483 ELSE IF( ldvsr.LT.1 .OR. ( ilvsr .AND. ldvsr.LT.n ) )
THEN
496 minwrk =
max( 8*n, 6*n + 16 )
497 maxwrk = minwrk - n +
498 $ n*ilaenv( 1,
'DGEQRF', '
', N, 1, N, 0 )
499 MAXWRK = MAX( MAXWRK, MINWRK - N +
500 $ N*ILAENV( 1, 'dormqr', ' ', N, 1, N, -1 ) )
502 MAXWRK = MAX( MAXWRK, MINWRK - N +
503 $ N*ILAENV( 1, 'dorgqr', '
', N, 1, N, -1 ) )
507 $ LWRK = MAX( LWRK, N*N/2 )
514.OR..EQ.
IF( WANTSN N0 ) THEN
521.LT..AND..NOT.
IF( LWORKMINWRK LQUERY ) THEN
523.LT..AND..NOT.
ELSE IF( LIWORKLIWMIN LQUERY ) THEN
529 CALL XERBLA( 'dggesx', -INFO )
531 ELSE IF (LQUERY) THEN
545 SAFMIN = DLAMCH( 's
' )
546 SAFMAX = ONE / SAFMIN
547 CALL DLABAD( SAFMIN, SAFMAX )
548 SMLNUM = SQRT( SAFMIN ) / EPS
549 BIGNUM = ONE / SMLNUM
553 ANRM = DLANGE( 'm
', N, N, A, LDA, WORK )
555.GT..AND..LT.
IF( ANRMZERO ANRMSMLNUM ) THEN
558.GT.
ELSE IF( ANRMBIGNUM ) THEN
563 $ CALL DLASCL( 'g
', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
567 BNRM = DLANGE( 'm
', N, N, B, LDB, WORK )
569.GT..AND..LT.
IF( BNRMZERO BNRMSMLNUM ) THEN
572.GT.
ELSE IF( BNRMBIGNUM ) THEN
577 $ CALL DLASCL( 'g
', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
585 CALL DGGBAL( 'p
', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
586 $ WORK( IRIGHT ), WORK( IWRK ), IERR )
591 IROWS = IHI + 1 - ILO
595 CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
596 $ WORK( IWRK ), LWORK+1-IWRK, IERR )
601 CALL DORMQR( 'l
', 't
', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
602 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
603 $ LWORK+1-IWRK, IERR )
609 CALL DLASET( 'full
', N, N, ZERO, ONE, VSL, LDVSL )
610.GT.
IF( IROWS1 ) THEN
611 CALL DLACPY( 'l
', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
612 $ VSL( ILO+1, ILO ), LDVSL )
614 CALL DORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
615 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
621 $ CALL DLASET( 'full
', N, N, ZERO, ONE, VSR, LDVSR )
626 CALL DGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
627 $ LDVSL, VSR, LDVSR, IERR )
635 CALL DHGEQZ( 's
', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
636 $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
637 $ WORK( IWRK ), LWORK+1-IWRK, IERR )
639.GT..AND..LE.
IF( IERR0 IERRN ) THEN
641.GT..AND..LE.
ELSE IF( IERRN IERR2*N ) THEN
659 CALL DLASCL( 'g
', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N,
661 CALL DLASCL( 'g
', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N,
665 $ CALL DLASCL( 'g', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
670 bwork( i ) = selctg( alphar( i ), alphai( i ), beta( i ) )
676 CALL dtgsen( ijob, ilvsl, ilvsr, bwork, n, a, lda, b, ldb,
677 $ alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr,
678 $ sdim, pl, pr, dif, work( iwrk ), lwork-iwrk+1,
679 $ iwork, liwork, ierr )
682 $ maxwrk =
max( maxwrk, 2*sdim*( n-sdim ) )
683 IF( ierr.EQ.-22 )
THEN
689 IF( ijob.EQ.1 .OR. ijob.EQ.4 )
THEN
693 IF( ijob.EQ.2 .OR. ijob.EQ.4 )
THEN
694 rcondv( 1 ) = dif( 1 )
695 rcondv( 2 ) = dif( 2 )
707 $
CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
708 $ work( iright ), n, vsl, ldvsl, ierr )
711 $
CALL dggbak(
'P',
'R', n, ilo, ihi, work( ileft ),
712 $ work( iright ), n, vsr, ldvsr, ierr )
720 IF( alphai( i ).NE.zero )
THEN
721 IF( ( alphar( i ) / safmax ).GT.( anrmto / anrm ) .OR.
722 $ ( safmin / alphar( i ) ).GT.( anrm / anrmto ) )
THEN
723 work( 1 ) = abs( a( i, i ) / alphar( i ) )
724 beta( i ) = beta( i )*work( 1 )
725 alphar( i ) = alphar( i )*work( 1 )
726 alphai( i ) = alphai( i )*work( 1 )
727 ELSE IF( ( alphai( i ) / safmax ).GT.
728 $ ( anrmto / anrm ) .OR.
729 $ ( safmin / alphai( i ) ).GT.( anrm / anrmto ) )
731 work( 1 ) = abs( a( i, i+1 ) / alphai( i ) )
732 beta( i ) = beta( i )*work( 1 )
733 alphar( i ) = alphar( i )*work( 1 )
734 alphai( i ) = alphai( i )*work( 1 )
742 IF( alphai( i ).NE.zero )
THEN
743 IF( ( beta( i ) / safmax ).GT.( bnrmto / bnrm ) .OR.
744 $ ( safmin / beta( i ) ).GT.( bnrm / bnrmto ) )
THEN
745 work( 1 ) = abs( b( i, i ) / beta( i ) )
746 beta( i ) = beta( i )*work( 1 )
747 alphar( i ) = alphar( i )*work( 1 )
748 alphai( i ) = alphai( i )*work( 1 )
757 CALL dlascl(
'H', 0, 0, anrmto, anrm, n, n, a, lda, ierr )
758 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphar, n, ierr )
759 CALL dlascl(
'G', 0, 0, anrmto, anrm, n, 1, alphai, n, ierr )
763 CALL dlascl(
'U', 0, 0, bnrmto, bnrm, n, n, b, ldb, ierr )
764 CALL dlascl(
'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
776 cursl = selctg( alphar( i ), alphai( i ), beta( i ) )
777 IF( alphai( i ).EQ.zero )
THEN
781 IF( cursl .AND. .NOT.lastsl )
788 cursl = cursl .OR. lastsl
793 IF( cursl .AND. .NOT.lst2sl )
subroutine dggesx(jobvsl, jobvsr, sort, selctg, sense, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, rconde, rcondv, work, lwork, iwork, liwork, bwork, info)
DGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE ...