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
351 INTRINSIC abs, int, max
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 430 safmin = safmin + safmin
431 safmax = one / safmin
432 onepls = one + ( 4*eps )
436 anrm =
dlange(
'M', n, n, a, lda, work )
439 IF( anrm.LT.one )
THEN 440 IF( safmax*anrm.LT.one )
THEN 446 IF( anrm.GT.zero )
THEN 447 CALL dlascl(
'G', -1, -1, anrm, one, n, n, a, lda, iinfo )
448 IF( iinfo.NE.0 )
THEN 456 bnrm =
dlange(
'M', n, n, b, ldb, work )
459 IF( bnrm.LT.one )
THEN 460 IF( safmax*bnrm.LT.one )
THEN 466 IF( bnrm.GT.zero )
THEN 467 CALL dlascl(
'G', -1, -1, bnrm, one, n, n, b, ldb, iinfo )
468 IF( iinfo.NE.0 )
THEN 481 CALL dggbal(
'P', n, a, lda, b, ldb, ilo, ihi, work( ileft ),
482 $ work( iright ), work( iwork ), iinfo )
483 IF( iinfo.NE.0 )
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 IF( iinfo.NE.0 )
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 IF( iinfo.NE.0 )
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 IF( iinfo.NE.0 )
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 IF( iinfo.NE.0 )
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 IF( iinfo.NE.0 )
THEN 570 IF( iinfo.GT.0 .AND. iinfo.LE.n )
THEN 572 ELSE IF( iinfo.GT.n .AND. iinfo.LE.2*n )
THEN 594 CALL dtgevc( chtemp,
'B', ldumma, n, a, lda, b, ldb, vl, ldvl,
595 $ vr, ldvr, n, in, work( iwork ), iinfo )
596 IF( iinfo.NE.0 )
THEN 604 CALL dggbak(
'P',
'L', n, ilo, ihi, work( ileft ),
605 $ work( iright ), n, vl, ldvl, iinfo )
606 IF( iinfo.NE.0 )
THEN 611 IF( alphai( jc ).LT.zero )
614 IF( alphai( jc ).EQ.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 IF( alphai( jc ).EQ.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 IF( iinfo.NE.0 )
THEN 647 IF( alphai( jc ).LT.zero )
650 IF( alphai( jc ).EQ.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 IF( alphai( jc ).EQ.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 IF( abs( salfai ).LT.safmin .AND. absai.GE.
701 $ max( safmin, eps*absar, eps*absb ) )
THEN 703 scale = ( onepls*safmin / anrm1 ) /
704 $ max( onepls*safmin, anrm2*absai )
706 ELSE IF( salfai.EQ.zero )
THEN 711 IF( alphai( jc ).LT.zero .AND. jc.GT.1 )
THEN 712 alphai( jc-1 ) = zero
713 ELSE IF( alphai( jc ).GT.zero .AND. jc.LT.n )
THEN 714 alphai( jc+1 ) = zero
720 IF( abs( salfar ).LT.safmin .AND. absar.GE.
721 $ max( safmin, eps*absai, eps*absb ) )
THEN 723 scale = max( scale, ( onepls*safmin / anrm1 ) /
724 $ max( onepls*safmin, anrm2*absar ) )
729 IF( abs( sbeta ).LT.safmin .AND. absb.GE.
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
integer function ilaenv(ISPEC, NAME, OPTS, N1, N2, N3, N4)
ILAENV
logical function lsame(CA, CB)
LSAME
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMQR
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 dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGQR
double precision function dlamch(CMACH)
DLAMCH
subroutine dgghrd(COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, INFO)
DGGHRD
double precision function dlange(NORM, M, N, A, LDA, WORK)
DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine dhgeqz(JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)
DHGEQZ
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 dgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGEQRF
subroutine dtgevc(SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
DTGEVC