304 SUBROUTINE dgegv( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,
305 $ BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )
312 CHARACTER JOBVL, JOBVR
313 INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
316 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
317 $ b( ldb, * ), beta( * ), vl( ldvl, * ),
318 $ vr( ldvr, * ), work( * )
324 DOUBLE PRECISION ZERO, ONE
325 parameter( zero = 0.0d0, one = 1.0d0 )
328 LOGICAL ILIMIT, ILV, ILVL, ILVR, LQUERY
330 INTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
331 $ in, iright, irows, itau, iwork, jc, jr, lopt,
332 $ lwkmin, lwkopt, nb, nb1, nb2, nb3
333 DOUBLE PRECISION ABSAI, ABSAR, ABSB, ANRM, ANRM1, ANRM2, BNRM,
334 $ bnrm1, bnrm2, eps, onepls, safmax, safmin,
335 $ salfai, salfar, sbeta, scale, temp
347 DOUBLE PRECISION , DLANGE
348 EXTERNAL lsame, ilaenv,
dlamch, dlange
357 IF( lsame( jobvl,
'N' ) )
THEN
360 ELSE IF( lsame( jobvl,
'V' ) )
THEN
368 IF( lsame( jobvr,
'N' ) )
THEN
371 ELSE IF( lsame( jobvr,
'V' ) )
THEN
382 lwkmin =
max( 8*n, 1 )
385 lquery = ( lwork.EQ.-1 )
387 IF( ijobvl.LE.0 )
THEN
389 ELSE IF( ijobvr.LE.0 )
THEN
391 ELSE IF( n.LT.0 )
THEN
393 ELSE IF( lda.LT.
max( 1, n ) )
THEN
395 ELSE IF( ldb.LT.
max( 1, n ) )
THEN
397 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) )
THEN
399 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) )
THEN
401 ELSE IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
406 nb1 = ilaenv( 1, '
dgeqrf', ' ', N, N, -1, -1 )
407 NB2 = ILAENV( 1, 'dormqr', ' ', N, N, N, -1 )
408 NB3 = ILAENV( 1, 'dorgqr', ' ', N, N, N, -1 )
409 NB = MAX( NB1, NB2, NB3 )
410 LOPT = 2*N + MAX( 6*N, N*( NB+1 ) )
415 CALL XERBLA( 'dgegv', -INFO )
417 ELSE IF( LQUERY ) THEN
428 EPS = DLAMCH( 'e
' )*DLAMCH( 'b
' )
429 SAFMIN = DLAMCH( 's
' )
430 SAFMIN = SAFMIN + SAFMIN
431 SAFMAX = ONE / SAFMIN
432 ONEPLS = ONE + ( 4*EPS )
436 ANRM = DLANGE( 'm
', N, N, A, LDA, WORK )
439.LT.
IF( ANRMONE ) THEN
440.LT.
IF( SAFMAX*ANRMONE ) THEN
446.GT.
IF( ANRMZERO ) THEN
447 CALL DLASCL( 'g
', -1, -1, ANRM, ONE, N, N, A, LDA, IINFO )
448.NE.
IF( IINFO0 ) THEN
456 BNRM = DLANGE( 'm
', N, N, B, LDB, WORK )
459.LT.
IF( BNRMONE ) THEN
460.LT.
IF( SAFMAX*BNRMONE ) THEN
466.GT.
IF( BNRMZERO ) THEN
467 CALL DLASCL( 'g
', -1, -1, BNRM, ONE, N, N, B, LDB, IINFO )
468.NE.
IF( IINFO0 ) THEN
481 CALL DGGBAL( 'p
', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
482 $ WORK( IRIGHT ), WORK( IWORK ), IINFO )
483.NE.
IF( IINFO0 ) THEN
492 IROWS = IHI + 1 - ILO
500 CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
501 $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
503 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
504.NE.
IF( IINFO0 ) THEN
509 CALL DORMQR( 'l
', 't
', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
510 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
511 $ LWORK+1-IWORK, IINFO )
513 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
514.NE.
IF( IINFO0 ) THEN
520 CALL DLASET( 'full
', N, N, ZERO, ONE, VL, LDVL )
521 CALL DLACPY( 'l
', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
522 $ VL( ILO+1, ILO ), LDVL )
523 CALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
524 $ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
527 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
528.NE.
IF( IINFO0 ) THEN
535 $ CALL DLASET( 'full
', N, N, ZERO, ONE, VR, LDVR )
543 CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
544 $ LDVL, VR, LDVR, IINFO )
546 CALL DGGHRD( 'n
', 'n
', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
547 $ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IINFO )
549.NE.
IF( IINFO0 ) THEN
564 CALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
565 $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
566 $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
568 $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
569.NE.
IF( IINFO0 ) THEN
570.GT..AND..LE.
IF( IINFO0 IINFON ) THEN
572.GT..AND..LE.
ELSE IF( IINFON IINFO2*N ) THEN
594 CALL DTGEVC( CHTEMP, 'b
', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
595 $ VR, LDVR, N, IN, WORK( IWORK ), IINFO )
596.NE.
IF( IINFO0 ) THEN
604 CALL DGGBAK( 'p
', 'l
', N, ILO, IHI, WORK( ILEFT ),
605 $ WORK( IRIGHT ), N, VL, LDVL, IINFO )
606.NE.
IF( IINFO0 ) THEN
611.LT.
IF( ALPHAI( JC )ZERO )
614.EQ.
IF( ALPHAI( JC )ZERO ) THEN
616 TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
620 TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
621 $ ABS( VL( JR, JC+1 ) ) )
627.EQ.
IF( ALPHAI( JC )ZERO ) THEN
629 VL( JR, JC ) = VL( JR, JC )*TEMP
633 VL( JR, JC ) = VL( JR, JC )*TEMP
634 VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
640 CALL DGGBAK( 'p
', 'r
', N, ILO, IHI, WORK( ILEFT ),
641 $ WORK( IRIGHT ), N, VR, LDVR, IINFO )
642.NE.
IF( IINFO0 ) THEN
647.LT.
IF( ALPHAI( JC )ZERO )
650.EQ.
IF( ALPHAI( JC )ZERO ) THEN
652 TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
656 TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
657 $ ABS( VR( JR, JC+1 ) ) )
663.EQ.
IF( ALPHAI( JC )ZERO ) THEN
665 VR( JR, JC ) = VR( JR, JC )*TEMP
669 VR( JR, JC ) = VR( JR, JC )*TEMP
670 VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
689 ABSAR = ABS( ALPHAR( JC ) )
690 ABSAI = ABS( ALPHAI( JC ) )
691 ABSB = ABS( BETA( JC ) )
692 SALFAR = ANRM*ALPHAR( JC )
693 SALFAI = ANRM*ALPHAI( JC )
694 SBETA = BNRM*BETA( JC )
700.LT..AND..GE.
IF( ABS( SALFAI )SAFMIN ABSAI
701 $ MAX( SAFMIN, EPS*ABSAR, EPS*ABSB ) ) THEN
703 SCALE = ( ONEPLS*SAFMIN / ANRM1 ) /
704 $ MAX( ONEPLS*SAFMIN, ANRM2*ABSAI )
706.EQ.
ELSE IF( SALFAIZERO ) THEN
711.LT..AND..GT.
IF( ALPHAI( JC )ZERO JC1 ) THEN
712 ALPHAI( JC-1 ) = ZERO
713.GT..AND..LT.
ELSE IF( ALPHAI( JC )ZERO JCN ) THEN
714 ALPHAI( JC+1 ) = ZERO
720.LT..AND..GE.
IF( ABS( SALFAR )SAFMIN ABSAR
721 $ MAX( SAFMIN, EPS*ABSAI, EPS*ABSB ) ) THEN
723 SCALE = MAX( SCALE, ( ONEPLS*SAFMIN / ANRM1 ) /
724 $ MAX( ONEPLS*SAFMIN, ANRM2*ABSAR ) )
729.LT..AND..GE.
IF( ABS( SBETA )SAFMIN ABSB
730 $ MAX( SAFMIN, EPS*ABSAR, EPS*ABSAI ) ) THEN
732 SCALE = MAX( SCALE, ( ONEPLS*SAFMIN / BNRM1 ) /
733 $ MAX( ONEPLS*SAFMIN, BNRM2*ABSB ) )
739 TEMP = ( SCALE*SAFMIN )*MAX( ABS( SALFAR ), ABS( SALFAI ),
742 $ SCALE = SCALE / TEMP
750 SALFAR = ( SCALE*ALPHAR( JC ) )*ANRM
751 SALFAI = ( SCALE*ALPHAI( JC ) )*ANRM
752 SBETA = ( SCALE*BETA( JC ) )*BNRM
754 ALPHAR( JC ) = SALFAR
755 ALPHAI( JC ) = SALFAI
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 xerbla(srname, info)
XERBLA
subroutine dggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
DGGBAL
subroutine dggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
DGGBAK
subroutine dhgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
DHGEQZ
subroutine dtgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, info)
DTGEVC
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dgegv(jobvl, jobvr, n, a, lda, b, ldb, alphar, alphai, beta, vl, ldvl, vr, ldvr, work, lwork, info)
DGEEVX 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 dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
double precision function dlamch(cmach)
DLAMCH