LAPACK 3.3.0

zgegv.f

Go to the documentation of this file.
00001       SUBROUTINE ZGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
00002      $                  VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
00003 *
00004 *  -- LAPACK driver routine (version 3.2) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *     November 2006
00008 *
00009 *     .. Scalar Arguments ..
00010       CHARACTER          JOBVL, JOBVR
00011       INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, N
00012 *     ..
00013 *     .. Array Arguments ..
00014       DOUBLE PRECISION   RWORK( * )
00015       COMPLEX*16         A( LDA, * ), ALPHA( * ), B( LDB, * ),
00016      $                   BETA( * ), VL( LDVL, * ), VR( LDVR, * ),
00017      $                   WORK( * )
00018 *     ..
00019 *
00020 *  Purpose
00021 *  =======
00022 *
00023 *  This routine is deprecated and has been replaced by routine ZGGEV.
00024 *
00025 *  ZGEGV computes the eigenvalues and, optionally, the left and/or right
00026 *  eigenvectors of a complex matrix pair (A,B).
00027 *  Given two square matrices A and B,
00028 *  the generalized nonsymmetric eigenvalue problem (GNEP) is to find the
00029 *  eigenvalues lambda and corresponding (non-zero) eigenvectors x such
00030 *  that
00031 *     A*x = lambda*B*x.
00032 *
00033 *  An alternate form is to find the eigenvalues mu and corresponding
00034 *  eigenvectors y such that
00035 *     mu*A*y = B*y.
00036 *
00037 *  These two forms are equivalent with mu = 1/lambda and x = y if
00038 *  neither lambda nor mu is zero.  In order to deal with the case that
00039 *  lambda or mu is zero or small, two values alpha and beta are returned
00040 *  for each eigenvalue, such that lambda = alpha/beta and
00041 *  mu = beta/alpha.
00042 *
00043 *  The vectors x and y in the above equations are right eigenvectors of
00044 *  the matrix pair (A,B).  Vectors u and v satisfying
00045 *     u**H*A = lambda*u**H*B  or  mu*v**H*A = v**H*B
00046 *  are left eigenvectors of (A,B).
00047 *
00048 *  Note: this routine performs "full balancing" on A and B -- see
00049 *  "Further Details", below.
00050 *
00051 *  Arguments
00052 *  =========
00053 *
00054 *  JOBVL   (input) CHARACTER*1
00055 *          = 'N':  do not compute the left generalized eigenvectors;
00056 *          = 'V':  compute the left generalized eigenvectors (returned
00057 *                  in VL).
00058 *
00059 *  JOBVR   (input) CHARACTER*1
00060 *          = 'N':  do not compute the right generalized eigenvectors;
00061 *          = 'V':  compute the right generalized eigenvectors (returned
00062 *                  in VR).
00063 *
00064 *  N       (input) INTEGER
00065 *          The order of the matrices A, B, VL, and VR.  N >= 0.
00066 *
00067 *  A       (input/output) COMPLEX*16 array, dimension (LDA, N)
00068 *          On entry, the matrix A.
00069 *          If JOBVL = 'V' or JOBVR = 'V', then on exit A
00070 *          contains the Schur form of A from the generalized Schur
00071 *          factorization of the pair (A,B) after balancing.  If no
00072 *          eigenvectors were computed, then only the diagonal elements
00073 *          of the Schur form will be correct.  See ZGGHRD and ZHGEQZ
00074 *          for details.
00075 *
00076 *  LDA     (input) INTEGER
00077 *          The leading dimension of A.  LDA >= max(1,N).
00078 *
00079 *  B       (input/output) COMPLEX*16 array, dimension (LDB, N)
00080 *          On entry, the matrix B.
00081 *          If JOBVL = 'V' or JOBVR = 'V', then on exit B contains the
00082 *          upper triangular matrix obtained from B in the generalized
00083 *          Schur factorization of the pair (A,B) after balancing.
00084 *          If no eigenvectors were computed, then only the diagonal
00085 *          elements of B will be correct.  See ZGGHRD and ZHGEQZ for
00086 *          details.
00087 *
00088 *  LDB     (input) INTEGER
00089 *          The leading dimension of B.  LDB >= max(1,N).
00090 *
00091 *  ALPHA   (output) COMPLEX*16 array, dimension (N)
00092 *          The complex scalars alpha that define the eigenvalues of
00093 *          GNEP.
00094 *
00095 *  BETA    (output) COMPLEX*16 array, dimension (N)
00096 *          The complex scalars beta that define the eigenvalues of GNEP.
00097 *          
00098 *          Together, the quantities alpha = ALPHA(j) and beta = BETA(j)
00099 *          represent the j-th eigenvalue of the matrix pair (A,B), in
00100 *          one of the forms lambda = alpha/beta or mu = beta/alpha.
00101 *          Since either lambda or mu may overflow, they should not,
00102 *          in general, be computed.
00103 *
00104 *  VL      (output) COMPLEX*16 array, dimension (LDVL,N)
00105 *          If JOBVL = 'V', the left eigenvectors u(j) are stored
00106 *          in the columns of VL, in the same order as their eigenvalues.
00107 *          Each eigenvector is scaled so that its largest component has
00108 *          abs(real part) + abs(imag. part) = 1, except for eigenvectors
00109 *          corresponding to an eigenvalue with alpha = beta = 0, which
00110 *          are set to zero.
00111 *          Not referenced if JOBVL = 'N'.
00112 *
00113 *  LDVL    (input) INTEGER
00114 *          The leading dimension of the matrix VL. LDVL >= 1, and
00115 *          if JOBVL = 'V', LDVL >= N.
00116 *
00117 *  VR      (output) COMPLEX*16 array, dimension (LDVR,N)
00118 *          If JOBVR = 'V', the right eigenvectors x(j) are stored
00119 *          in the columns of VR, in the same order as their eigenvalues.
00120 *          Each eigenvector is scaled so that its largest component has
00121 *          abs(real part) + abs(imag. part) = 1, except for eigenvectors
00122 *          corresponding to an eigenvalue with alpha = beta = 0, which
00123 *          are set to zero.
00124 *          Not referenced if JOBVR = 'N'.
00125 *
00126 *  LDVR    (input) INTEGER
00127 *          The leading dimension of the matrix VR. LDVR >= 1, and
00128 *          if JOBVR = 'V', LDVR >= N.
00129 *
00130 *  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
00131 *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
00132 *
00133 *  LWORK   (input) INTEGER
00134 *          The dimension of the array WORK.  LWORK >= max(1,2*N).
00135 *          For good performance, LWORK must generally be larger.
00136 *          To compute the optimal value of LWORK, call ILAENV to get
00137 *          blocksizes (for ZGEQRF, ZUNMQR, and ZUNGQR.)  Then compute:
00138 *          NB  -- MAX of the blocksizes for ZGEQRF, ZUNMQR, and ZUNGQR;
00139 *          The optimal LWORK is  MAX( 2*N, N*(NB+1) ).
00140 *
00141 *          If LWORK = -1, then a workspace query is assumed; the routine
00142 *          only calculates the optimal size of the WORK array, returns
00143 *          this value as the first entry of the WORK array, and no error
00144 *          message related to LWORK is issued by XERBLA.
00145 *
00146 *  RWORK   (workspace/output) DOUBLE PRECISION array, dimension (8*N)
00147 *
00148 *  INFO    (output) INTEGER
00149 *          = 0:  successful exit
00150 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00151 *          =1,...,N:
00152 *                The QZ iteration failed.  No eigenvectors have been
00153 *                calculated, but ALPHA(j) and BETA(j) should be
00154 *                correct for j=INFO+1,...,N.
00155 *          > N:  errors that usually indicate LAPACK problems:
00156 *                =N+1: error return from ZGGBAL
00157 *                =N+2: error return from ZGEQRF
00158 *                =N+3: error return from ZUNMQR
00159 *                =N+4: error return from ZUNGQR
00160 *                =N+5: error return from ZGGHRD
00161 *                =N+6: error return from ZHGEQZ (other than failed
00162 *                                               iteration)
00163 *                =N+7: error return from ZTGEVC
00164 *                =N+8: error return from ZGGBAK (computing VL)
00165 *                =N+9: error return from ZGGBAK (computing VR)
00166 *                =N+10: error return from ZLASCL (various calls)
00167 *
00168 *  Further Details
00169 *  ===============
00170 *
00171 *  Balancing
00172 *  ---------
00173 *
00174 *  This driver calls ZGGBAL to both permute and scale rows and columns
00175 *  of A and B.  The permutations PL and PR are chosen so that PL*A*PR
00176 *  and PL*B*R will be upper triangular except for the diagonal blocks
00177 *  A(i:j,i:j) and B(i:j,i:j), with i and j as close together as
00178 *  possible.  The diagonal scaling matrices DL and DR are chosen so
00179 *  that the pair  DL*PL*A*PR*DR, DL*PL*B*PR*DR have elements close to
00180 *  one (except for the elements that start out zero.)
00181 *
00182 *  After the eigenvalues and eigenvectors of the balanced matrices
00183 *  have been computed, ZGGBAK transforms the eigenvectors back to what
00184 *  they would have been (in perfect arithmetic) if they had not been
00185 *  balanced.
00186 *
00187 *  Contents of A and B on Exit
00188 *  -------- -- - --- - -- ----
00189 *
00190 *  If any eigenvectors are computed (either JOBVL='V' or JOBVR='V' or
00191 *  both), then on exit the arrays A and B will contain the complex Schur
00192 *  form[*] of the "balanced" versions of A and B.  If no eigenvectors
00193 *  are computed, then only the diagonal blocks will be correct.
00194 *
00195 *  [*] In other words, upper triangular form.
00196 *
00197 *  =====================================================================
00198 *
00199 *     .. Parameters ..
00200       DOUBLE PRECISION   ZERO, ONE
00201       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
00202       COMPLEX*16         CZERO, CONE
00203       PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ),
00204      $                   CONE = ( 1.0D0, 0.0D0 ) )
00205 *     ..
00206 *     .. Local Scalars ..
00207       LOGICAL            ILIMIT, ILV, ILVL, ILVR, LQUERY
00208       CHARACTER          CHTEMP
00209       INTEGER            ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
00210      $                   IN, IRIGHT, IROWS, IRWORK, ITAU, IWORK, JC, JR,
00211      $                   LOPT, LWKMIN, LWKOPT, NB, NB1, NB2, NB3
00212       DOUBLE PRECISION   ABSAI, ABSAR, ABSB, ANRM, ANRM1, ANRM2, BNRM,
00213      $                   BNRM1, BNRM2, EPS, SAFMAX, SAFMIN, SALFAI,
00214      $                   SALFAR, SBETA, SCALE, TEMP
00215       COMPLEX*16         X
00216 *     ..
00217 *     .. Local Arrays ..
00218       LOGICAL            LDUMMA( 1 )
00219 *     ..
00220 *     .. External Subroutines ..
00221       EXTERNAL           XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD, ZHGEQZ,
00222      $                   ZLACPY, ZLASCL, ZLASET, ZTGEVC, ZUNGQR, ZUNMQR
00223 *     ..
00224 *     .. External Functions ..
00225       LOGICAL            LSAME
00226       INTEGER            ILAENV
00227       DOUBLE PRECISION   DLAMCH, ZLANGE
00228       EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
00229 *     ..
00230 *     .. Intrinsic Functions ..
00231       INTRINSIC          ABS, DBLE, DCMPLX, DIMAG, INT, MAX
00232 *     ..
00233 *     .. Statement Functions ..
00234       DOUBLE PRECISION   ABS1
00235 *     ..
00236 *     .. Statement Function definitions ..
00237       ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
00238 *     ..
00239 *     .. Executable Statements ..
00240 *
00241 *     Decode the input arguments
00242 *
00243       IF( LSAME( JOBVL, 'N' ) ) THEN
00244          IJOBVL = 1
00245          ILVL = .FALSE.
00246       ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
00247          IJOBVL = 2
00248          ILVL = .TRUE.
00249       ELSE
00250          IJOBVL = -1
00251          ILVL = .FALSE.
00252       END IF
00253 *
00254       IF( LSAME( JOBVR, 'N' ) ) THEN
00255          IJOBVR = 1
00256          ILVR = .FALSE.
00257       ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
00258          IJOBVR = 2
00259          ILVR = .TRUE.
00260       ELSE
00261          IJOBVR = -1
00262          ILVR = .FALSE.
00263       END IF
00264       ILV = ILVL .OR. ILVR
00265 *
00266 *     Test the input arguments
00267 *
00268       LWKMIN = MAX( 2*N, 1 )
00269       LWKOPT = LWKMIN
00270       WORK( 1 ) = LWKOPT
00271       LQUERY = ( LWORK.EQ.-1 )
00272       INFO = 0
00273       IF( IJOBVL.LE.0 ) THEN
00274          INFO = -1
00275       ELSE IF( IJOBVR.LE.0 ) THEN
00276          INFO = -2
00277       ELSE IF( N.LT.0 ) THEN
00278          INFO = -3
00279       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00280          INFO = -5
00281       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00282          INFO = -7
00283       ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
00284          INFO = -11
00285       ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
00286          INFO = -13
00287       ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
00288          INFO = -15
00289       END IF
00290 *
00291       IF( INFO.EQ.0 ) THEN
00292          NB1 = ILAENV( 1, 'ZGEQRF', ' ', N, N, -1, -1 )
00293          NB2 = ILAENV( 1, 'ZUNMQR', ' ', N, N, N, -1 )
00294          NB3 = ILAENV( 1, 'ZUNGQR', ' ', N, N, N, -1 )
00295          NB = MAX( NB1, NB2, NB3 )
00296          LOPT = MAX( 2*N, N*( NB+1 ) )
00297          WORK( 1 ) = LOPT
00298       END IF
00299 *
00300       IF( INFO.NE.0 ) THEN
00301          CALL XERBLA( 'ZGEGV ', -INFO )
00302          RETURN
00303       ELSE IF( LQUERY ) THEN
00304          RETURN
00305       END IF
00306 *
00307 *     Quick return if possible
00308 *
00309       IF( N.EQ.0 )
00310      $   RETURN
00311 *
00312 *     Get machine constants
00313 *
00314       EPS = DLAMCH( 'E' )*DLAMCH( 'B' )
00315       SAFMIN = DLAMCH( 'S' )
00316       SAFMIN = SAFMIN + SAFMIN
00317       SAFMAX = ONE / SAFMIN
00318 *
00319 *     Scale A
00320 *
00321       ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
00322       ANRM1 = ANRM
00323       ANRM2 = ONE
00324       IF( ANRM.LT.ONE ) THEN
00325          IF( SAFMAX*ANRM.LT.ONE ) THEN
00326             ANRM1 = SAFMIN
00327             ANRM2 = SAFMAX*ANRM
00328          END IF
00329       END IF
00330 *
00331       IF( ANRM.GT.ZERO ) THEN
00332          CALL ZLASCL( 'G', -1, -1, ANRM, ONE, N, N, A, LDA, IINFO )
00333          IF( IINFO.NE.0 ) THEN
00334             INFO = N + 10
00335             RETURN
00336          END IF
00337       END IF
00338 *
00339 *     Scale B
00340 *
00341       BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
00342       BNRM1 = BNRM
00343       BNRM2 = ONE
00344       IF( BNRM.LT.ONE ) THEN
00345          IF( SAFMAX*BNRM.LT.ONE ) THEN
00346             BNRM1 = SAFMIN
00347             BNRM2 = SAFMAX*BNRM
00348          END IF
00349       END IF
00350 *
00351       IF( BNRM.GT.ZERO ) THEN
00352          CALL ZLASCL( 'G', -1, -1, BNRM, ONE, N, N, B, LDB, IINFO )
00353          IF( IINFO.NE.0 ) THEN
00354             INFO = N + 10
00355             RETURN
00356          END IF
00357       END IF
00358 *
00359 *     Permute the matrix to make it more nearly triangular
00360 *     Also "balance" the matrix.
00361 *
00362       ILEFT = 1
00363       IRIGHT = N + 1
00364       IRWORK = IRIGHT + N
00365       CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
00366      $             RWORK( IRIGHT ), RWORK( IRWORK ), IINFO )
00367       IF( IINFO.NE.0 ) THEN
00368          INFO = N + 1
00369          GO TO 80
00370       END IF
00371 *
00372 *     Reduce B to triangular form, and initialize VL and/or VR
00373 *
00374       IROWS = IHI + 1 - ILO
00375       IF( ILV ) THEN
00376          ICOLS = N + 1 - ILO
00377       ELSE
00378          ICOLS = IROWS
00379       END IF
00380       ITAU = 1
00381       IWORK = ITAU + IROWS
00382       CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
00383      $             WORK( IWORK ), LWORK+1-IWORK, IINFO )
00384       IF( IINFO.GE.0 )
00385      $   LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00386       IF( IINFO.NE.0 ) THEN
00387          INFO = N + 2
00388          GO TO 80
00389       END IF
00390 *
00391       CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
00392      $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
00393      $             LWORK+1-IWORK, IINFO )
00394       IF( IINFO.GE.0 )
00395      $   LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00396       IF( IINFO.NE.0 ) THEN
00397          INFO = N + 3
00398          GO TO 80
00399       END IF
00400 *
00401       IF( ILVL ) THEN
00402          CALL ZLASET( 'Full', N, N, CZERO, CONE, VL, LDVL )
00403          CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
00404      $                VL( ILO+1, ILO ), LDVL )
00405          CALL ZUNGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
00406      $                WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
00407      $                IINFO )
00408          IF( IINFO.GE.0 )
00409      $      LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00410          IF( IINFO.NE.0 ) THEN
00411             INFO = N + 4
00412             GO TO 80
00413          END IF
00414       END IF
00415 *
00416       IF( ILVR )
00417      $   CALL ZLASET( 'Full', N, N, CZERO, CONE, VR, LDVR )
00418 *
00419 *     Reduce to generalized Hessenberg form
00420 *
00421       IF( ILV ) THEN
00422 *
00423 *        Eigenvectors requested -- work on whole matrix.
00424 *
00425          CALL ZGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
00426      $                LDVL, VR, LDVR, IINFO )
00427       ELSE
00428          CALL ZGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
00429      $                B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IINFO )
00430       END IF
00431       IF( IINFO.NE.0 ) THEN
00432          INFO = N + 5
00433          GO TO 80
00434       END IF
00435 *
00436 *     Perform QZ algorithm
00437 *
00438       IWORK = ITAU
00439       IF( ILV ) THEN
00440          CHTEMP = 'S'
00441       ELSE
00442          CHTEMP = 'E'
00443       END IF
00444       CALL ZHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
00445      $             ALPHA, BETA, VL, LDVL, VR, LDVR, WORK( IWORK ),
00446      $             LWORK+1-IWORK, RWORK( IRWORK ), IINFO )
00447       IF( IINFO.GE.0 )
00448      $   LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
00449       IF( IINFO.NE.0 ) THEN
00450          IF( IINFO.GT.0 .AND. IINFO.LE.N ) THEN
00451             INFO = IINFO
00452          ELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THEN
00453             INFO = IINFO - N
00454          ELSE
00455             INFO = N + 6
00456          END IF
00457          GO TO 80
00458       END IF
00459 *
00460       IF( ILV ) THEN
00461 *
00462 *        Compute Eigenvectors
00463 *
00464          IF( ILVL ) THEN
00465             IF( ILVR ) THEN
00466                CHTEMP = 'B'
00467             ELSE
00468                CHTEMP = 'L'
00469             END IF
00470          ELSE
00471             CHTEMP = 'R'
00472          END IF
00473 *
00474          CALL ZTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
00475      $                VR, LDVR, N, IN, WORK( IWORK ), RWORK( IRWORK ),
00476      $                IINFO )
00477          IF( IINFO.NE.0 ) THEN
00478             INFO = N + 7
00479             GO TO 80
00480          END IF
00481 *
00482 *        Undo balancing on VL and VR, rescale
00483 *
00484          IF( ILVL ) THEN
00485             CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
00486      $                   RWORK( IRIGHT ), N, VL, LDVL, IINFO )
00487             IF( IINFO.NE.0 ) THEN
00488                INFO = N + 8
00489                GO TO 80
00490             END IF
00491             DO 30 JC = 1, N
00492                TEMP = ZERO
00493                DO 10 JR = 1, N
00494                   TEMP = MAX( TEMP, ABS1( VL( JR, JC ) ) )
00495    10          CONTINUE
00496                IF( TEMP.LT.SAFMIN )
00497      $            GO TO 30
00498                TEMP = ONE / TEMP
00499                DO 20 JR = 1, N
00500                   VL( JR, JC ) = VL( JR, JC )*TEMP
00501    20          CONTINUE
00502    30       CONTINUE
00503          END IF
00504          IF( ILVR ) THEN
00505             CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
00506      $                   RWORK( IRIGHT ), N, VR, LDVR, IINFO )
00507             IF( IINFO.NE.0 ) THEN
00508                INFO = N + 9
00509                GO TO 80
00510             END IF
00511             DO 60 JC = 1, N
00512                TEMP = ZERO
00513                DO 40 JR = 1, N
00514                   TEMP = MAX( TEMP, ABS1( VR( JR, JC ) ) )
00515    40          CONTINUE
00516                IF( TEMP.LT.SAFMIN )
00517      $            GO TO 60
00518                TEMP = ONE / TEMP
00519                DO 50 JR = 1, N
00520                   VR( JR, JC ) = VR( JR, JC )*TEMP
00521    50          CONTINUE
00522    60       CONTINUE
00523          END IF
00524 *
00525 *        End of eigenvector calculation
00526 *
00527       END IF
00528 *
00529 *     Undo scaling in alpha, beta
00530 *
00531 *     Note: this does not give the alpha and beta for the unscaled
00532 *     problem.
00533 *
00534 *     Un-scaling is limited to avoid underflow in alpha and beta
00535 *     if they are significant.
00536 *
00537       DO 70 JC = 1, N
00538          ABSAR = ABS( DBLE( ALPHA( JC ) ) )
00539          ABSAI = ABS( DIMAG( ALPHA( JC ) ) )
00540          ABSB = ABS( DBLE( BETA( JC ) ) )
00541          SALFAR = ANRM*DBLE( ALPHA( JC ) )
00542          SALFAI = ANRM*DIMAG( ALPHA( JC ) )
00543          SBETA = BNRM*DBLE( BETA( JC ) )
00544          ILIMIT = .FALSE.
00545          SCALE = ONE
00546 *
00547 *        Check for significant underflow in imaginary part of ALPHA
00548 *
00549          IF( ABS( SALFAI ).LT.SAFMIN .AND. ABSAI.GE.
00550      $       MAX( SAFMIN, EPS*ABSAR, EPS*ABSB ) ) THEN
00551             ILIMIT = .TRUE.
00552             SCALE = ( SAFMIN / ANRM1 ) / MAX( SAFMIN, ANRM2*ABSAI )
00553          END IF
00554 *
00555 *        Check for significant underflow in real part of ALPHA
00556 *
00557          IF( ABS( SALFAR ).LT.SAFMIN .AND. ABSAR.GE.
00558      $       MAX( SAFMIN, EPS*ABSAI, EPS*ABSB ) ) THEN
00559             ILIMIT = .TRUE.
00560             SCALE = MAX( SCALE, ( SAFMIN / ANRM1 ) /
00561      $              MAX( SAFMIN, ANRM2*ABSAR ) )
00562          END IF
00563 *
00564 *        Check for significant underflow in BETA
00565 *
00566          IF( ABS( SBETA ).LT.SAFMIN .AND. ABSB.GE.
00567      $       MAX( SAFMIN, EPS*ABSAR, EPS*ABSAI ) ) THEN
00568             ILIMIT = .TRUE.
00569             SCALE = MAX( SCALE, ( SAFMIN / BNRM1 ) /
00570      $              MAX( SAFMIN, BNRM2*ABSB ) )
00571          END IF
00572 *
00573 *        Check for possible overflow when limiting scaling
00574 *
00575          IF( ILIMIT ) THEN
00576             TEMP = ( SCALE*SAFMIN )*MAX( ABS( SALFAR ), ABS( SALFAI ),
00577      $             ABS( SBETA ) )
00578             IF( TEMP.GT.ONE )
00579      $         SCALE = SCALE / TEMP
00580             IF( SCALE.LT.ONE )
00581      $         ILIMIT = .FALSE.
00582          END IF
00583 *
00584 *        Recompute un-scaled ALPHA, BETA if necessary.
00585 *
00586          IF( ILIMIT ) THEN
00587             SALFAR = ( SCALE*DBLE( ALPHA( JC ) ) )*ANRM
00588             SALFAI = ( SCALE*DIMAG( ALPHA( JC ) ) )*ANRM
00589             SBETA = ( SCALE*BETA( JC ) )*BNRM
00590          END IF
00591          ALPHA( JC ) = DCMPLX( SALFAR, SALFAI )
00592          BETA( JC ) = SBETA
00593    70 CONTINUE
00594 *
00595    80 CONTINUE
00596       WORK( 1 ) = LWKOPT
00597 *
00598       RETURN
00599 *
00600 *     End of ZGEGV
00601 *
00602       END
 All Files Functions