LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ dggevx()

subroutine dggevx ( character balanc,
character jobvl,
character jobvr,
character sense,
integer n,
double precision, dimension( lda, * ) a,
integer lda,
double precision, dimension( ldb, * ) b,
integer ldb,
double precision, dimension( * ) alphar,
double precision, dimension( * ) alphai,
double precision, dimension( * ) beta,
double precision, dimension( ldvl, * ) vl,
integer ldvl,
double precision, dimension( ldvr, * ) vr,
integer ldvr,
integer ilo,
integer ihi,
double precision, dimension( * ) lscale,
double precision, dimension( * ) rscale,
double precision abnrm,
double precision bbnrm,
double precision, dimension( * ) rconde,
double precision, dimension( * ) rcondv,
double precision, dimension( * ) work,
integer lwork,
integer, dimension( * ) iwork,
logical, dimension( * ) bwork,
integer info )

DGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices

Download DGGEVX + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DGGEVX computes for a pair of N-by-N real nonsymmetric matrices (A,B)
!> the generalized eigenvalues, and optionally, the left and/or right
!> generalized eigenvectors.
!>
!> Optionally also, it computes a balancing transformation to improve
!> the conditioning of the eigenvalues and eigenvectors (ILO, IHI,
!> LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for
!> the eigenvalues (RCONDE), and reciprocal condition numbers for the
!> right eigenvectors (RCONDV).
!>
!> A generalized eigenvalue for a pair of matrices (A,B) is a scalar
!> lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
!> singular. It is usually represented as the pair (alpha,beta), as
!> there is a reasonable interpretation for beta=0, and even for both
!> being zero.
!>
!> The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
!> of (A,B) satisfies
!>
!>                  A * v(j) = lambda(j) * B * v(j) .
!>
!> The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
!> of (A,B) satisfies
!>
!>                  u(j)**H * A  = lambda(j) * u(j)**H * B.
!>
!> where u(j)**H is the conjugate-transpose of u(j).
!>
!> 
Parameters
[in]BALANC
!>          BALANC is CHARACTER*1
!>          Specifies the balance option to be performed.
!>          = 'N':  do not diagonally scale or permute;
!>          = 'P':  permute only;
!>          = 'S':  scale only;
!>          = 'B':  both permute and scale.
!>          Computed reciprocal condition numbers will be for the
!>          matrices after permuting and/or balancing. Permuting does
!>          not change condition numbers (in exact arithmetic), but
!>          balancing does.
!> 
[in]JOBVL
!>          JOBVL is CHARACTER*1
!>          = 'N':  do not compute the left generalized eigenvectors;
!>          = 'V':  compute the left generalized eigenvectors.
!> 
[in]JOBVR
!>          JOBVR is CHARACTER*1
!>          = 'N':  do not compute the right generalized eigenvectors;
!>          = 'V':  compute the right generalized eigenvectors.
!> 
[in]SENSE
!>          SENSE is CHARACTER*1
!>          Determines which reciprocal condition numbers are computed.
!>          = 'N': none are computed;
!>          = 'E': computed for eigenvalues only;
!>          = 'V': computed for eigenvectors only;
!>          = 'B': computed for eigenvalues and eigenvectors.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrices A, B, VL, and VR.  N >= 0.
!> 
[in,out]A
!>          A is DOUBLE PRECISION array, dimension (LDA, N)
!>          On entry, the matrix A in the pair (A,B).
!>          On exit, A has been overwritten. If JOBVL='V' or JOBVR='V'
!>          or both, then A contains the first part of the real Schur
!>          form of the  versions of the input A and B.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of A.  LDA >= max(1,N).
!> 
[in,out]B
!>          B is DOUBLE PRECISION array, dimension (LDB, N)
!>          On entry, the matrix B in the pair (A,B).
!>          On exit, B has been overwritten. If JOBVL='V' or JOBVR='V'
!>          or both, then B contains the second part of the real Schur
!>          form of the  versions of the input A and B.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of B.  LDB >= max(1,N).
!> 
[out]ALPHAR
!>          ALPHAR is DOUBLE PRECISION array, dimension (N)
!> 
[out]ALPHAI
!>          ALPHAI is DOUBLE PRECISION array, dimension (N)
!> 
[out]BETA
!>          BETA is DOUBLE PRECISION array, dimension (N)
!>          On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
!>          be the generalized eigenvalues.  If ALPHAI(j) is zero, then
!>          the j-th eigenvalue is real; if positive, then the j-th and
!>          (j+1)-st eigenvalues are a complex conjugate pair, with
!>          ALPHAI(j+1) negative.
!>
!>          Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
!>          may easily over- or underflow, and BETA(j) may even be zero.
!>          Thus, the user should avoid naively computing the ratio
!>          ALPHA/BETA. However, ALPHAR and ALPHAI will be always less
!>          than and usually comparable with norm(A) in magnitude, and
!>          BETA always less than and usually comparable with norm(B).
!> 
[out]VL
!>          VL is DOUBLE PRECISION array, dimension (LDVL,N)
!>          If JOBVL = 'V', the left eigenvectors u(j) are stored one
!>          after another in the columns of VL, in the same order as
!>          their eigenvalues. If the j-th eigenvalue is real, then
!>          u(j) = VL(:,j), the j-th column of VL. If the j-th and
!>          (j+1)-th eigenvalues form a complex conjugate pair, then
!>          u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).
!>          Each eigenvector will be scaled so the largest component have
!>          abs(real part) + abs(imag. part) = 1.
!>          Not referenced if JOBVL = 'N'.
!> 
[in]LDVL
!>          LDVL is INTEGER
!>          The leading dimension of the matrix VL. LDVL >= 1, and
!>          if JOBVL = 'V', LDVL >= N.
!> 
[out]VR
!>          VR is DOUBLE PRECISION array, dimension (LDVR,N)
!>          If JOBVR = 'V', the right eigenvectors v(j) are stored one
!>          after another in the columns of VR, in the same order as
!>          their eigenvalues. If the j-th eigenvalue is real, then
!>          v(j) = VR(:,j), the j-th column of VR. If the j-th and
!>          (j+1)-th eigenvalues form a complex conjugate pair, then
!>          v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
!>          Each eigenvector will be scaled so the largest component have
!>          abs(real part) + abs(imag. part) = 1.
!>          Not referenced if JOBVR = 'N'.
!> 
[in]LDVR
!>          LDVR is INTEGER
!>          The leading dimension of the matrix VR. LDVR >= 1, and
!>          if JOBVR = 'V', LDVR >= N.
!> 
[out]ILO
!>          ILO is INTEGER
!> 
[out]IHI
!>          IHI is INTEGER
!>          ILO and IHI are integer values such that on exit
!>          A(i,j) = 0 and B(i,j) = 0 if i > j and
!>          j = 1,...,ILO-1 or i = IHI+1,...,N.
!>          If BALANC = 'N' or 'S', ILO = 1 and IHI = N.
!> 
[out]LSCALE
!>          LSCALE is DOUBLE PRECISION array, dimension (N)
!>          Details of the permutations and scaling factors applied
!>          to the left side of A and B.  If PL(j) is the index of the
!>          row interchanged with row j, and DL(j) is the scaling
!>          factor applied to row j, then
!>            LSCALE(j) = PL(j)  for j = 1,...,ILO-1
!>                      = DL(j)  for j = ILO,...,IHI
!>                      = PL(j)  for j = IHI+1,...,N.
!>          The order in which the interchanges are made is N to IHI+1,
!>          then 1 to ILO-1.
!> 
[out]RSCALE
!>          RSCALE is DOUBLE PRECISION array, dimension (N)
!>          Details of the permutations and scaling factors applied
!>          to the right side of A and B.  If PR(j) is the index of the
!>          column interchanged with column j, and DR(j) is the scaling
!>          factor applied to column j, then
!>            RSCALE(j) = PR(j)  for j = 1,...,ILO-1
!>                      = DR(j)  for j = ILO,...,IHI
!>                      = PR(j)  for j = IHI+1,...,N
!>          The order in which the interchanges are made is N to IHI+1,
!>          then 1 to ILO-1.
!> 
[out]ABNRM
!>          ABNRM is DOUBLE PRECISION
!>          The one-norm of the balanced matrix A.
!> 
[out]BBNRM
!>          BBNRM is DOUBLE PRECISION
!>          The one-norm of the balanced matrix B.
!> 
[out]RCONDE
!>          RCONDE is DOUBLE PRECISION array, dimension (N)
!>          If SENSE = 'E' or 'B', the reciprocal condition numbers of
!>          the eigenvalues, stored in consecutive elements of the array.
!>          For a complex conjugate pair of eigenvalues two consecutive
!>          elements of RCONDE are set to the same value. Thus RCONDE(j),
!>          RCONDV(j), and the j-th columns of VL and VR all correspond
!>          to the j-th eigenpair.
!>          If SENSE = 'N or 'V', RCONDE is not referenced.
!> 
[out]RCONDV
!>          RCONDV is DOUBLE PRECISION array, dimension (N)
!>          If SENSE = 'V' or 'B', the estimated reciprocal condition
!>          numbers of the eigenvectors, stored in consecutive elements
!>          of the array. For a complex eigenvector two consecutive
!>          elements of RCONDV are set to the same value. If the
!>          eigenvalues cannot be reordered to compute RCONDV(j),
!>          RCONDV(j) is set to 0; this can only occur when the true
!>          value would be very small anyway.
!>          If SENSE = 'N' or 'E', RCONDV is not referenced.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK. LWORK >= max(1,2*N).
!>          If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V',
!>          LWORK >= max(1,6*N).
!>          If SENSE = 'E' or 'B', LWORK >= max(1,10*N).
!>          If SENSE = 'V' or 'B', LWORK >= 2*N*N+8*N+16.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (N+6)
!>          If SENSE = 'E', IWORK is not referenced.
!> 
[out]BWORK
!>          BWORK is LOGICAL array, dimension (N)
!>          If SENSE = 'N', BWORK is not referenced.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          = 1,...,N:
!>                The QZ iteration failed.  No eigenvectors have been
!>                calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
!>                should be correct for j=INFO+1,...,N.
!>          > N:  =N+1: other than QZ iteration failed in DHGEQZ.
!>                =N+2: error return from DTGEVC.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  Balancing a matrix pair (A,B) includes, first, permuting rows and
!>  columns to isolate eigenvalues, second, applying diagonal similarity
!>  transformation to the rows and columns to make the rows and columns
!>  as close in norm as possible. The computed reciprocal condition
!>  numbers correspond to the balanced matrix. Permuting rows and columns
!>  will not change the condition numbers (in exact arithmetic) but
!>  diagonal scaling will.  For further explanation of balancing, see
!>  section 4.11.1.2 of LAPACK Users' Guide.
!>
!>  An approximate error bound on the chordal distance between the i-th
!>  computed generalized eigenvalue w and the corresponding exact
!>  eigenvalue lambda is
!>
!>       chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)
!>
!>  An approximate error bound for the angle between the i-th computed
!>  eigenvector VL(i) or VR(i) is given by
!>
!>       EPS * norm(ABNRM, BBNRM) / DIF(i).
!>
!>  For further explanation of the reciprocal condition numbers RCONDE
!>  and RCONDV, see section 4.11 of LAPACK User's Guide.
!> 

Definition at line 385 of file dggevx.f.

390*
391* -- LAPACK driver routine --
392* -- LAPACK is a software package provided by Univ. of Tennessee, --
393* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
394*
395* .. Scalar Arguments ..
396 CHARACTER BALANC, JOBVL, JOBVR, SENSE
397 INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
398 DOUBLE PRECISION ABNRM, BBNRM
399* ..
400* .. Array Arguments ..
401 LOGICAL BWORK( * )
402 INTEGER IWORK( * )
403 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
404 $ B( LDB, * ), BETA( * ), LSCALE( * ),
405 $ RCONDE( * ), RCONDV( * ), RSCALE( * ),
406 $ VL( LDVL, * ), VR( LDVR, * ), WORK( * )
407* ..
408*
409* =====================================================================
410*
411* .. Parameters ..
412 DOUBLE PRECISION ZERO, ONE
413 parameter( zero = 0.0d+0, one = 1.0d+0 )
414* ..
415* .. Local Scalars ..
416 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,
417 $ PAIR, WANTSB, WANTSE, WANTSN, WANTSV
418 CHARACTER CHTEMP
419 INTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,
420 $ ITAU, IWRK, IWRK1, J, JC, JR, M, MAXWRK,
421 $ MINWRK, MM
422 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
423 $ SMLNUM, TEMP
424* ..
425* .. Local Arrays ..
426 LOGICAL LDUMMA( 1 )
427* ..
428* .. External Subroutines ..
429 EXTERNAL dgeqrf, dggbak, dggbal, dgghrd, dhgeqz,
430 $ dlacpy,
432 $ xerbla
433* ..
434* .. External Functions ..
435 LOGICAL LSAME
436 INTEGER ILAENV
437 DOUBLE PRECISION DLAMCH, DLANGE
438 EXTERNAL lsame, ilaenv, dlamch, dlange
439* ..
440* .. Intrinsic Functions ..
441 INTRINSIC abs, max, sqrt
442* ..
443* .. Executable Statements ..
444*
445* Decode the input arguments
446*
447 IF( lsame( jobvl, 'N' ) ) THEN
448 ijobvl = 1
449 ilvl = .false.
450 ELSE IF( lsame( jobvl, 'V' ) ) THEN
451 ijobvl = 2
452 ilvl = .true.
453 ELSE
454 ijobvl = -1
455 ilvl = .false.
456 END IF
457*
458 IF( lsame( jobvr, 'N' ) ) THEN
459 ijobvr = 1
460 ilvr = .false.
461 ELSE IF( lsame( jobvr, 'V' ) ) THEN
462 ijobvr = 2
463 ilvr = .true.
464 ELSE
465 ijobvr = -1
466 ilvr = .false.
467 END IF
468 ilv = ilvl .OR. ilvr
469*
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' )
475*
476* Test the input arguments
477*
478 info = 0
479 lquery = ( lwork.EQ.-1 )
480 IF( .NOT.( lsame( balanc, 'N' ) .OR. lsame( balanc,
481 $ 'S' ) .OR.
482 $ lsame( balanc, 'P' ) .OR.
483 $ lsame( balanc, 'B' ) ) )
484 $ THEN
485 info = -1
486 ELSE IF( ijobvl.LE.0 ) THEN
487 info = -2
488 ELSE IF( ijobvr.LE.0 ) THEN
489 info = -3
490 ELSE IF( .NOT.( wantsn .OR. wantse .OR. wantsb .OR. wantsv ) )
491 $ THEN
492 info = -4
493 ELSE IF( n.LT.0 ) THEN
494 info = -5
495 ELSE IF( lda.LT.max( 1, n ) ) THEN
496 info = -7
497 ELSE IF( ldb.LT.max( 1, n ) ) THEN
498 info = -9
499 ELSE IF( ldvl.LT.1 .OR. ( ilvl .AND. ldvl.LT.n ) ) THEN
500 info = -14
501 ELSE IF( ldvr.LT.1 .OR. ( ilvr .AND. ldvr.LT.n ) ) THEN
502 info = -16
503 END IF
504*
505* Compute workspace
506* (Note: Comments in the code beginning "Workspace:" describe the
507* minimal amount of workspace needed at that point in the code,
508* as well as the preferred amount for good performance.
509* NB refers to the optimal block size for the immediately
510* following subroutine, as returned by ILAENV. The workspace is
511* computed assuming ILO = 1 and IHI = N, the worst case.)
512*
513 IF( info.EQ.0 ) THEN
514 IF( n.EQ.0 ) THEN
515 minwrk = 1
516 maxwrk = 1
517 ELSE
518 IF( noscl .AND. .NOT.ilv ) THEN
519 minwrk = 2*n
520 ELSE
521 minwrk = 6*n
522 END IF
523 IF( wantse .OR. wantsb ) THEN
524 minwrk = 10*n
525 END IF
526 IF( wantsv .OR. wantsb ) THEN
527 minwrk = max( minwrk, 2*n*( n + 4 ) + 16 )
528 END IF
529 maxwrk = minwrk
530 maxwrk = max( maxwrk,
531 $ n + n*ilaenv( 1, 'DGEQRF', ' ', n, 1, n,
532 $ 0 ) )
533 maxwrk = max( maxwrk,
534 $ n + n*ilaenv( 1, 'DORMQR', ' ', n, 1, n,
535 $ 0 ) )
536 IF( ilvl ) THEN
537 maxwrk = max( maxwrk, n +
538 $ n*ilaenv( 1, 'DORGQR', ' ', n, 1, n,
539 $ 0 ) )
540 END IF
541 END IF
542 work( 1 ) = maxwrk
543*
544 IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
545 info = -26
546 END IF
547 END IF
548*
549 IF( info.NE.0 ) THEN
550 CALL xerbla( 'DGGEVX', -info )
551 RETURN
552 ELSE IF( lquery ) THEN
553 RETURN
554 END IF
555*
556* Quick return if possible
557*
558 IF( n.EQ.0 )
559 $ RETURN
560*
561*
562* Get machine constants
563*
564 eps = dlamch( 'P' )
565 smlnum = dlamch( 'S' )
566 bignum = one / smlnum
567 smlnum = sqrt( smlnum ) / eps
568 bignum = one / smlnum
569*
570* Scale A if max element outside range [SMLNUM,BIGNUM]
571*
572 anrm = dlange( 'M', n, n, a, lda, work )
573 ilascl = .false.
574 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
575 anrmto = smlnum
576 ilascl = .true.
577 ELSE IF( anrm.GT.bignum ) THEN
578 anrmto = bignum
579 ilascl = .true.
580 END IF
581 IF( ilascl )
582 $ CALL dlascl( 'G', 0, 0, anrm, anrmto, n, n, a, lda, ierr )
583*
584* Scale B if max element outside range [SMLNUM,BIGNUM]
585*
586 bnrm = dlange( 'M', n, n, b, ldb, work )
587 ilbscl = .false.
588 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
589 bnrmto = smlnum
590 ilbscl = .true.
591 ELSE IF( bnrm.GT.bignum ) THEN
592 bnrmto = bignum
593 ilbscl = .true.
594 END IF
595 IF( ilbscl )
596 $ CALL dlascl( 'G', 0, 0, bnrm, bnrmto, n, n, b, ldb, ierr )
597*
598* Permute and/or balance the matrix pair (A,B)
599* (Workspace: need 6*N if BALANC = 'S' or 'B', 1 otherwise)
600*
601 CALL dggbal( balanc, n, a, lda, b, ldb, ilo, ihi, lscale,
602 $ rscale,
603 $ work, ierr )
604*
605* Compute ABNRM and BBNRM
606*
607 abnrm = dlange( '1', n, n, a, lda, work( 1 ) )
608 IF( ilascl ) THEN
609 work( 1 ) = abnrm
610 CALL dlascl( 'G', 0, 0, anrmto, anrm, 1, 1, work( 1 ), 1,
611 $ ierr )
612 abnrm = work( 1 )
613 END IF
614*
615 bbnrm = dlange( '1', n, n, b, ldb, work( 1 ) )
616 IF( ilbscl ) THEN
617 work( 1 ) = bbnrm
618 CALL dlascl( 'G', 0, 0, bnrmto, bnrm, 1, 1, work( 1 ), 1,
619 $ ierr )
620 bbnrm = work( 1 )
621 END IF
622*
623* Reduce B to triangular form (QR decomposition of B)
624* (Workspace: need N, prefer N*NB )
625*
626 irows = ihi + 1 - ilo
627 IF( ilv .OR. .NOT.wantsn ) THEN
628 icols = n + 1 - ilo
629 ELSE
630 icols = irows
631 END IF
632 itau = 1
633 iwrk = itau + irows
634 CALL dgeqrf( irows, icols, b( ilo, ilo ), ldb, work( itau ),
635 $ work( iwrk ), lwork+1-iwrk, ierr )
636*
637* Apply the orthogonal transformation to A
638* (Workspace: need N, prefer N*NB)
639*
640 CALL dormqr( 'L', 'T', irows, icols, irows, b( ilo, ilo ), ldb,
641 $ work( itau ), a( ilo, ilo ), lda, work( iwrk ),
642 $ lwork+1-iwrk, ierr )
643*
644* Initialize VL and/or VR
645* (Workspace: need N, prefer N*NB)
646*
647 IF( ilvl ) THEN
648 CALL dlaset( 'Full', n, n, zero, one, vl, ldvl )
649 IF( irows.GT.1 ) THEN
650 CALL dlacpy( 'L', irows-1, irows-1, b( ilo+1, ilo ), ldb,
651 $ vl( ilo+1, ilo ), ldvl )
652 END IF
653 CALL dorgqr( irows, irows, irows, vl( ilo, ilo ), ldvl,
654 $ work( itau ), work( iwrk ), lwork+1-iwrk, ierr )
655 END IF
656*
657 IF( ilvr )
658 $ CALL dlaset( 'Full', n, n, zero, one, vr, ldvr )
659*
660* Reduce to generalized Hessenberg form
661* (Workspace: none needed)
662*
663 IF( ilv .OR. .NOT.wantsn ) THEN
664*
665* Eigenvectors requested -- work on whole matrix.
666*
667 CALL dgghrd( jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb, vl,
668 $ ldvl, vr, ldvr, ierr )
669 ELSE
670 CALL dgghrd( 'N', 'N', irows, 1, irows, a( ilo, ilo ), lda,
671 $ b( ilo, ilo ), ldb, vl, ldvl, vr, ldvr, ierr )
672 END IF
673*
674* Perform QZ algorithm (Compute eigenvalues, and optionally, the
675* Schur forms and Schur vectors)
676* (Workspace: need N)
677*
678 IF( ilv .OR. .NOT.wantsn ) THEN
679 chtemp = 'S'
680 ELSE
681 chtemp = 'E'
682 END IF
683*
684 CALL dhgeqz( chtemp, jobvl, jobvr, n, ilo, ihi, a, lda, b, ldb,
685 $ alphar, alphai, beta, vl, ldvl, vr, ldvr, work,
686 $ lwork, ierr )
687 IF( ierr.NE.0 ) THEN
688 IF( ierr.GT.0 .AND. ierr.LE.n ) THEN
689 info = ierr
690 ELSE IF( ierr.GT.n .AND. ierr.LE.2*n ) THEN
691 info = ierr - n
692 ELSE
693 info = n + 1
694 END IF
695 GO TO 130
696 END IF
697*
698* Compute Eigenvectors and estimate condition numbers if desired
699* (Workspace: DTGEVC: need 6*N
700* DTGSNA: need 2*N*(N+2)+16 if SENSE = 'V' or 'B',
701* need N otherwise )
702*
703 IF( ilv .OR. .NOT.wantsn ) THEN
704 IF( ilv ) THEN
705 IF( ilvl ) THEN
706 IF( ilvr ) THEN
707 chtemp = 'B'
708 ELSE
709 chtemp = 'L'
710 END IF
711 ELSE
712 chtemp = 'R'
713 END IF
714*
715 CALL dtgevc( chtemp, 'B', ldumma, n, a, lda, b, ldb, vl,
716 $ ldvl, vr, ldvr, n, in, work, ierr )
717 IF( ierr.NE.0 ) THEN
718 info = n + 2
719 GO TO 130
720 END IF
721 END IF
722*
723 IF( .NOT.wantsn ) THEN
724*
725* compute eigenvectors (DTGEVC) and estimate condition
726* numbers (DTGSNA). Note that the definition of the condition
727* number is not invariant under transformation (u,v) to
728* (Q*u, Z*v), where (u,v) are eigenvectors of the generalized
729* Schur form (S,T), Q and Z are orthogonal matrices. In order
730* to avoid using extra 2*N*N workspace, we have to recalculate
731* eigenvectors and estimate one condition numbers at a time.
732*
733 pair = .false.
734 DO 20 i = 1, n
735*
736 IF( pair ) THEN
737 pair = .false.
738 GO TO 20
739 END IF
740 mm = 1
741 IF( i.LT.n ) THEN
742 IF( a( i+1, i ).NE.zero ) THEN
743 pair = .true.
744 mm = 2
745 END IF
746 END IF
747*
748 DO 10 j = 1, n
749 bwork( j ) = .false.
750 10 CONTINUE
751 IF( mm.EQ.1 ) THEN
752 bwork( i ) = .true.
753 ELSE IF( mm.EQ.2 ) THEN
754 bwork( i ) = .true.
755 bwork( i+1 ) = .true.
756 END IF
757*
758 iwrk = mm*n + 1
759 iwrk1 = iwrk + mm*n
760*
761* Compute a pair of left and right eigenvectors.
762* (compute workspace: need up to 4*N + 6*N)
763*
764 IF( wantse .OR. wantsb ) THEN
765 CALL dtgevc( 'B', 'S', bwork, n, a, lda, b, ldb,
766 $ work( 1 ), n, work( iwrk ), n, mm, m,
767 $ work( iwrk1 ), ierr )
768 IF( ierr.NE.0 ) THEN
769 info = n + 2
770 GO TO 130
771 END IF
772 END IF
773*
774 CALL dtgsna( sense, 'S', bwork, n, a, lda, b, ldb,
775 $ work( 1 ), n, work( iwrk ), n, rconde( i ),
776 $ rcondv( i ), mm, m, work( iwrk1 ),
777 $ lwork-iwrk1+1, iwork, ierr )
778*
779 20 CONTINUE
780 END IF
781 END IF
782*
783* Undo balancing on VL and VR and normalization
784* (Workspace: none needed)
785*
786 IF( ilvl ) THEN
787 CALL dggbak( balanc, 'L', n, ilo, ihi, lscale, rscale, n,
788 $ vl,
789 $ ldvl, ierr )
790*
791 DO 70 jc = 1, n
792 IF( alphai( jc ).LT.zero )
793 $ GO TO 70
794 temp = zero
795 IF( alphai( jc ).EQ.zero ) THEN
796 DO 30 jr = 1, n
797 temp = max( temp, abs( vl( jr, jc ) ) )
798 30 CONTINUE
799 ELSE
800 DO 40 jr = 1, n
801 temp = max( temp, abs( vl( jr, jc ) )+
802 $ abs( vl( jr, jc+1 ) ) )
803 40 CONTINUE
804 END IF
805 IF( temp.LT.smlnum )
806 $ GO TO 70
807 temp = one / temp
808 IF( alphai( jc ).EQ.zero ) THEN
809 DO 50 jr = 1, n
810 vl( jr, jc ) = vl( jr, jc )*temp
811 50 CONTINUE
812 ELSE
813 DO 60 jr = 1, n
814 vl( jr, jc ) = vl( jr, jc )*temp
815 vl( jr, jc+1 ) = vl( jr, jc+1 )*temp
816 60 CONTINUE
817 END IF
818 70 CONTINUE
819 END IF
820 IF( ilvr ) THEN
821 CALL dggbak( balanc, 'R', n, ilo, ihi, lscale, rscale, n,
822 $ vr,
823 $ ldvr, ierr )
824 DO 120 jc = 1, n
825 IF( alphai( jc ).LT.zero )
826 $ GO TO 120
827 temp = zero
828 IF( alphai( jc ).EQ.zero ) THEN
829 DO 80 jr = 1, n
830 temp = max( temp, abs( vr( jr, jc ) ) )
831 80 CONTINUE
832 ELSE
833 DO 90 jr = 1, n
834 temp = max( temp, abs( vr( jr, jc ) )+
835 $ abs( vr( jr, jc+1 ) ) )
836 90 CONTINUE
837 END IF
838 IF( temp.LT.smlnum )
839 $ GO TO 120
840 temp = one / temp
841 IF( alphai( jc ).EQ.zero ) THEN
842 DO 100 jr = 1, n
843 vr( jr, jc ) = vr( jr, jc )*temp
844 100 CONTINUE
845 ELSE
846 DO 110 jr = 1, n
847 vr( jr, jc ) = vr( jr, jc )*temp
848 vr( jr, jc+1 ) = vr( jr, jc+1 )*temp
849 110 CONTINUE
850 END IF
851 120 CONTINUE
852 END IF
853*
854* Undo scaling if necessary
855*
856 130 CONTINUE
857*
858 IF( ilascl ) THEN
859 CALL dlascl( 'G', 0, 0, anrmto, anrm, n, 1, alphar, n,
860 $ ierr )
861 CALL dlascl( 'G', 0, 0, anrmto, anrm, n, 1, alphai, n,
862 $ ierr )
863 END IF
864*
865 IF( ilbscl ) THEN
866 CALL dlascl( 'G', 0, 0, bnrmto, bnrm, n, 1, beta, n, ierr )
867 END IF
868*
869 work( 1 ) = maxwrk
870 RETURN
871*
872* End of DGGEVX
873*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
Definition dgeqrf.f:144
subroutine dggbak(job, side, n, ilo, ihi, lscale, rscale, m, v, ldv, info)
DGGBAK
Definition dggbak.f:146
subroutine dggbal(job, n, a, lda, b, ldb, ilo, ihi, lscale, rscale, work, info)
DGGBAL
Definition dggbal.f:175
subroutine dgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
DGGHRD
Definition dgghrd.f:206
subroutine dhgeqz(job, compq, compz, n, ilo, ihi, h, ldh, t, ldt, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, info)
DHGEQZ
Definition dhgeqz.f:303
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
Definition dlacpy.f:101
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
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 ...
Definition dlange.f:112
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.
Definition dlascl.f:142
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.
Definition dlaset.f:108
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine dtgevc(side, howmny, select, n, s, lds, p, ldp, vl, ldvl, vr, ldvr, mm, m, work, info)
DTGEVC
Definition dtgevc.f:293
subroutine dtgsna(job, howmny, select, n, a, lda, b, ldb, vl, ldvl, vr, ldvr, s, dif, mm, m, work, lwork, iwork, info)
DTGSNA
Definition dtgsna.f:379
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
Definition dorgqr.f:126
subroutine dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMQR
Definition dormqr.f:165
Here is the call graph for this function:
Here is the caller graph for this function: