1: *> \brief <b> ZGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download ZGEGV + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgegv.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgegv.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgegv.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE ZGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
22: * VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
23: *
24: * .. Scalar Arguments ..
25: * CHARACTER JOBVL, JOBVR
26: * INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
27: * ..
28: * .. Array Arguments ..
29: * DOUBLE PRECISION RWORK( * )
30: * COMPLEX*16 A( LDA, * ), ALPHA( * ), B( LDB, * ),
31: * $ BETA( * ), VL( LDVL, * ), VR( LDVR, * ),
32: * $ WORK( * )
33: * ..
34: *
35: *
36: *> \par Purpose:
37: * =============
38: *>
39: *> \verbatim
40: *>
41: *> This routine is deprecated and has been replaced by routine ZGGEV.
42: *>
43: *> ZGEGV computes the eigenvalues and, optionally, the left and/or right
44: *> eigenvectors of a complex matrix pair (A,B).
45: *> Given two square matrices A and B,
46: *> the generalized nonsymmetric eigenvalue problem (GNEP) is to find the
47: *> eigenvalues lambda and corresponding (non-zero) eigenvectors x such
48: *> that
49: *> A*x = lambda*B*x.
50: *>
51: *> An alternate form is to find the eigenvalues mu and corresponding
52: *> eigenvectors y such that
53: *> mu*A*y = B*y.
54: *>
55: *> These two forms are equivalent with mu = 1/lambda and x = y if
56: *> neither lambda nor mu is zero. In order to deal with the case that
57: *> lambda or mu is zero or small, two values alpha and beta are returned
58: *> for each eigenvalue, such that lambda = alpha/beta and
59: *> mu = beta/alpha.
60: *>
61: *> The vectors x and y in the above equations are right eigenvectors of
62: *> the matrix pair (A,B). Vectors u and v satisfying
63: *> u**H*A = lambda*u**H*B or mu*v**H*A = v**H*B
64: *> are left eigenvectors of (A,B).
65: *>
66: *> Note: this routine performs "full balancing" on A and B
67: *> \endverbatim
68: *
69: * Arguments:
70: * ==========
71: *
72: *> \param[in] JOBVL
73: *> \verbatim
74: *> JOBVL is CHARACTER*1
75: *> = 'N': do not compute the left generalized eigenvectors;
76: *> = 'V': compute the left generalized eigenvectors (returned
77: *> in VL).
78: *> \endverbatim
79: *>
80: *> \param[in] JOBVR
81: *> \verbatim
82: *> JOBVR is CHARACTER*1
83: *> = 'N': do not compute the right generalized eigenvectors;
84: *> = 'V': compute the right generalized eigenvectors (returned
85: *> in VR).
86: *> \endverbatim
87: *>
88: *> \param[in] N
89: *> \verbatim
90: *> N is INTEGER
91: *> The order of the matrices A, B, VL, and VR. N >= 0.
92: *> \endverbatim
93: *>
94: *> \param[in,out] A
95: *> \verbatim
96: *> A is COMPLEX*16 array, dimension (LDA, N)
97: *> On entry, the matrix A.
98: *> If JOBVL = 'V' or JOBVR = 'V', then on exit A
99: *> contains the Schur form of A from the generalized Schur
100: *> factorization of the pair (A,B) after balancing. If no
101: *> eigenvectors were computed, then only the diagonal elements
102: *> of the Schur form will be correct. See ZGGHRD and ZHGEQZ
103: *> for details.
104: *> \endverbatim
105: *>
106: *> \param[in] LDA
107: *> \verbatim
108: *> LDA is INTEGER
109: *> The leading dimension of A. LDA >= max(1,N).
110: *> \endverbatim
111: *>
112: *> \param[in,out] B
113: *> \verbatim
114: *> B is COMPLEX*16 array, dimension (LDB, N)
115: *> On entry, the matrix B.
116: *> If JOBVL = 'V' or JOBVR = 'V', then on exit B contains the
117: *> upper triangular matrix obtained from B in the generalized
118: *> Schur factorization of the pair (A,B) after balancing.
119: *> If no eigenvectors were computed, then only the diagonal
120: *> elements of B will be correct. See ZGGHRD and ZHGEQZ for
121: *> details.
122: *> \endverbatim
123: *>
124: *> \param[in] LDB
125: *> \verbatim
126: *> LDB is INTEGER
127: *> The leading dimension of B. LDB >= max(1,N).
128: *> \endverbatim
129: *>
130: *> \param[out] ALPHA
131: *> \verbatim
132: *> ALPHA is COMPLEX*16 array, dimension (N)
133: *> The complex scalars alpha that define the eigenvalues of
134: *> GNEP.
135: *> \endverbatim
136: *>
137: *> \param[out] BETA
138: *> \verbatim
139: *> BETA is COMPLEX*16 array, dimension (N)
140: *> The complex scalars beta that define the eigenvalues of GNEP.
141: *>
142: *> Together, the quantities alpha = ALPHA(j) and beta = BETA(j)
143: *> represent the j-th eigenvalue of the matrix pair (A,B), in
144: *> one of the forms lambda = alpha/beta or mu = beta/alpha.
145: *> Since either lambda or mu may overflow, they should not,
146: *> in general, be computed.
147: *> \endverbatim
148: *>
149: *> \param[out] VL
150: *> \verbatim
151: *> VL is COMPLEX*16 array, dimension (LDVL,N)
152: *> If JOBVL = 'V', the left eigenvectors u(j) are stored
153: *> in the columns of VL, in the same order as their eigenvalues.
154: *> Each eigenvector is scaled so that its largest component has
155: *> abs(real part) + abs(imag. part) = 1, except for eigenvectors
156: *> corresponding to an eigenvalue with alpha = beta = 0, which
157: *> are set to zero.
158: *> Not referenced if JOBVL = 'N'.
159: *> \endverbatim
160: *>
161: *> \param[in] LDVL
162: *> \verbatim
163: *> LDVL is INTEGER
164: *> The leading dimension of the matrix VL. LDVL >= 1, and
165: *> if JOBVL = 'V', LDVL >= N.
166: *> \endverbatim
167: *>
168: *> \param[out] VR
169: *> \verbatim
170: *> VR is COMPLEX*16 array, dimension (LDVR,N)
171: *> If JOBVR = 'V', the right eigenvectors x(j) are stored
172: *> in the columns of VR, in the same order as their eigenvalues.
173: *> Each eigenvector is scaled so that its largest component has
174: *> abs(real part) + abs(imag. part) = 1, except for eigenvectors
175: *> corresponding to an eigenvalue with alpha = beta = 0, which
176: *> are set to zero.
177: *> Not referenced if JOBVR = 'N'.
178: *> \endverbatim
179: *>
180: *> \param[in] LDVR
181: *> \verbatim
182: *> LDVR is INTEGER
183: *> The leading dimension of the matrix VR. LDVR >= 1, and
184: *> if JOBVR = 'V', LDVR >= N.
185: *> \endverbatim
186: *>
187: *> \param[out] WORK
188: *> \verbatim
189: *> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
190: *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
191: *> \endverbatim
192: *>
193: *> \param[in] LWORK
194: *> \verbatim
195: *> LWORK is INTEGER
196: *> The dimension of the array WORK. LWORK >= max(1,2*N).
197: *> For good performance, LWORK must generally be larger.
198: *> To compute the optimal value of LWORK, call ILAENV to get
199: *> blocksizes (for ZGEQRF, ZUNMQR, and ZUNGQR.) Then compute:
200: *> NB -- MAX of the blocksizes for ZGEQRF, ZUNMQR, and ZUNGQR;
201: *> The optimal LWORK is MAX( 2*N, N*(NB+1) ).
202: *>
203: *> If LWORK = -1, then a workspace query is assumed; the routine
204: *> only calculates the optimal size of the WORK array, returns
205: *> this value as the first entry of the WORK array, and no error
206: *> message related to LWORK is issued by XERBLA.
207: *> \endverbatim
208: *>
209: *> \param[out] RWORK
210: *> \verbatim
211: *> RWORK is DOUBLE PRECISION array, dimension (8*N)
212: *> \endverbatim
213: *>
214: *> \param[out] INFO
215: *> \verbatim
216: *> INFO is INTEGER
217: *> = 0: successful exit
218: *> < 0: if INFO = -i, the i-th argument had an illegal value.
219: *> =1,...,N:
220: *> The QZ iteration failed. No eigenvectors have been
221: *> calculated, but ALPHA(j) and BETA(j) should be
222: *> correct for j=INFO+1,...,N.
223: *> > N: errors that usually indicate LAPACK problems:
224: *> =N+1: error return from ZGGBAL
225: *> =N+2: error return from ZGEQRF
226: *> =N+3: error return from ZUNMQR
227: *> =N+4: error return from ZUNGQR
228: *> =N+5: error return from ZGGHRD
229: *> =N+6: error return from ZHGEQZ (other than failed
230: *> iteration)
231: *> =N+7: error return from ZTGEVC
232: *> =N+8: error return from ZGGBAK (computing VL)
233: *> =N+9: error return from ZGGBAK (computing VR)
234: *> =N+10: error return from ZLASCL (various calls)
235: *> \endverbatim
236: *
237: * Authors:
238: * ========
239: *
240: *> \author Univ. of Tennessee
241: *> \author Univ. of California Berkeley
242: *> \author Univ. of Colorado Denver
243: *> \author NAG Ltd.
244: *
245: *> \ingroup complex16GEeigen
246: *
247: *> \par Further Details:
248: * =====================
249: *>
250: *> \verbatim
251: *>
252: *> Balancing
253: *> ---------
254: *>
255: *> This driver calls ZGGBAL to both permute and scale rows and columns
256: *> of A and B. The permutations PL and PR are chosen so that PL*A*PR
257: *> and PL*B*R will be upper triangular except for the diagonal blocks
258: *> A(i:j,i:j) and B(i:j,i:j), with i and j as close together as
259: *> possible. The diagonal scaling matrices DL and DR are chosen so
260: *> that the pair DL*PL*A*PR*DR, DL*PL*B*PR*DR have elements close to
261: *> one (except for the elements that start out zero.)
262: *>
263: *> After the eigenvalues and eigenvectors of the balanced matrices
264: *> have been computed, ZGGBAK transforms the eigenvectors back to what
265: *> they would have been (in perfect arithmetic) if they had not been
266: *> balanced.
267: *>
268: *> Contents of A and B on Exit
269: *> -------- -- - --- - -- ----
270: *>
271: *> If any eigenvectors are computed (either JOBVL='V' or JOBVR='V' or
272: *> both), then on exit the arrays A and B will contain the complex Schur
273: *> form[*] of the "balanced" versions of A and B. If no eigenvectors
274: *> are computed, then only the diagonal blocks will be correct.
275: *>
276: *> [*] In other words, upper triangular form.
277: *> \endverbatim
278: *>
279: * =====================================================================
280: SUBROUTINE ZGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
281: $ VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
282: *
283: * -- LAPACK driver routine --
284: * -- LAPACK is a software package provided by Univ. of Tennessee, --
285: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
286: *
287: * .. Scalar Arguments ..
288: CHARACTER JOBVL, JOBVR
289: INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
290: * ..
291: * .. Array Arguments ..
292: DOUBLE PRECISION RWORK( * )
293: COMPLEX*16 A( LDA, * ), ALPHA( * ), B( LDB, * ),
294: $ BETA( * ), VL( LDVL, * ), VR( LDVR, * ),
295: $ WORK( * )
296: * ..
297: *
298: * =====================================================================
299: *
300: * .. Parameters ..
301: DOUBLE PRECISION ZERO, ONE
302: PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
303: COMPLEX*16 CZERO, CONE
304: PARAMETER ( CZERO = ( 0.0D0, 0.0D0 ),
305: $ CONE = ( 1.0D0, 0.0D0 ) )
306: * ..
307: * .. Local Scalars ..
308: LOGICAL ILIMIT, ILV, ILVL, ILVR, LQUERY
309: CHARACTER CHTEMP
310: INTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
311: $ IN, IRIGHT, IROWS, IRWORK, ITAU, IWORK, JC, JR,
312: $ LOPT, LWKMIN, LWKOPT, NB, NB1, NB2, NB3
313: DOUBLE PRECISION ABSAI, ABSAR, ABSB, ANRM, ANRM1, ANRM2, BNRM,
314: $ BNRM1, BNRM2, EPS, SAFMAX, SAFMIN, SALFAI,
315: $ SALFAR, SBETA, SCALE, TEMP
316: COMPLEX*16 X
317: * ..
318: * .. Local Arrays ..
319: LOGICAL LDUMMA( 1 )
320: * ..
321: * .. External Subroutines ..
322: EXTERNAL XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD, ZHGEQZ,
323: $ ZLACPY, ZLASCL, ZLASET, ZTGEVC, ZUNGQR, ZUNMQR
324: * ..
325: * .. External Functions ..
326: LOGICAL LSAME
327: INTEGER ILAENV
328: DOUBLE PRECISION DLAMCH, ZLANGE
329: EXTERNAL LSAME, ILAENV, DLAMCH, ZLANGE
330: * ..
331: * .. Intrinsic Functions ..
332: INTRINSIC ABS, DBLE, DCMPLX, DIMAG, INT, MAX
333: * ..
334: * .. Statement Functions ..
335: DOUBLE PRECISION ABS1
336: * ..
337: * .. Statement Function definitions ..
338: ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
339: * ..
340: * .. Executable Statements ..
341: *
342: * Decode the input arguments
343: *
344: IF( LSAME( JOBVL, 'N' ) ) THEN
345: IJOBVL = 1
346: ILVL = .FALSE.
347: ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
348: IJOBVL = 2
349: ILVL = .TRUE.
350: ELSE
351: IJOBVL = -1
352: ILVL = .FALSE.
353: END IF
354: *
355: IF( LSAME( JOBVR, 'N' ) ) THEN
356: IJOBVR = 1
357: ILVR = .FALSE.
358: ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
359: IJOBVR = 2
360: ILVR = .TRUE.
361: ELSE
362: IJOBVR = -1
363: ILVR = .FALSE.
364: END IF
365: ILV = ILVL .OR. ILVR
366: *
367: * Test the input arguments
368: *
369: LWKMIN = MAX( 2*N, 1 )
370: LWKOPT = LWKMIN
371: WORK( 1 ) = LWKOPT
372: LQUERY = ( LWORK.EQ.-1 )
373: INFO = 0
374: IF( IJOBVL.LE.0 ) THEN
375: INFO = -1
376: ELSE IF( IJOBVR.LE.0 ) THEN
377: INFO = -2
378: ELSE IF( N.LT.0 ) THEN
379: INFO = -3
380: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
381: INFO = -5
382: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
383: INFO = -7
384: ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
385: INFO = -11
386: ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
387: INFO = -13
388: ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
389: INFO = -15
390: END IF
391: *
392: IF( INFO.EQ.0 ) THEN
393: NB1 = ILAENV( 1, 'ZGEQRF', ' ', N, N, -1, -1 )
394: NB2 = ILAENV( 1, 'ZUNMQR', ' ', N, N, N, -1 )
395: NB3 = ILAENV( 1, 'ZUNGQR', ' ', N, N, N, -1 )
396: NB = MAX( NB1, NB2, NB3 )
397: LOPT = MAX( 2*N, N*( NB+1 ) )
398: WORK( 1 ) = LOPT
399: END IF
400: *
401: IF( INFO.NE.0 ) THEN
402: CALL XERBLA( 'ZGEGV ', -INFO )
403: RETURN
404: ELSE IF( LQUERY ) THEN
405: RETURN
406: END IF
407: *
408: * Quick return if possible
409: *
410: IF( N.EQ.0 )
411: $ RETURN
412: *
413: * Get machine constants
414: *
415: EPS = DLAMCH( 'E' )*DLAMCH( 'B' )
416: SAFMIN = DLAMCH( 'S' )
417: SAFMIN = SAFMIN + SAFMIN
418: SAFMAX = ONE / SAFMIN
419: *
420: * Scale A
421: *
422: ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
423: ANRM1 = ANRM
424: ANRM2 = ONE
425: IF( ANRM.LT.ONE ) THEN
426: IF( SAFMAX*ANRM.LT.ONE ) THEN
427: ANRM1 = SAFMIN
428: ANRM2 = SAFMAX*ANRM
429: END IF
430: END IF
431: *
432: IF( ANRM.GT.ZERO ) THEN
433: CALL ZLASCL( 'G', -1, -1, ANRM, ONE, N, N, A, LDA, IINFO )
434: IF( IINFO.NE.0 ) THEN
435: INFO = N + 10
436: RETURN
437: END IF
438: END IF
439: *
440: * Scale B
441: *
442: BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
443: BNRM1 = BNRM
444: BNRM2 = ONE
445: IF( BNRM.LT.ONE ) THEN
446: IF( SAFMAX*BNRM.LT.ONE ) THEN
447: BNRM1 = SAFMIN
448: BNRM2 = SAFMAX*BNRM
449: END IF
450: END IF
451: *
452: IF( BNRM.GT.ZERO ) THEN
453: CALL ZLASCL( 'G', -1, -1, BNRM, ONE, N, N, B, LDB, IINFO )
454: IF( IINFO.NE.0 ) THEN
455: INFO = N + 10
456: RETURN
457: END IF
458: END IF
459: *
460: * Permute the matrix to make it more nearly triangular
461: * Also "balance" the matrix.
462: *
463: ILEFT = 1
464: IRIGHT = N + 1
465: IRWORK = IRIGHT + N
466: CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
467: $ RWORK( IRIGHT ), RWORK( IRWORK ), IINFO )
468: IF( IINFO.NE.0 ) THEN
469: INFO = N + 1
470: GO TO 80
471: END IF
472: *
473: * Reduce B to triangular form, and initialize VL and/or VR
474: *
475: IROWS = IHI + 1 - ILO
476: IF( ILV ) THEN
477: ICOLS = N + 1 - ILO
478: ELSE
479: ICOLS = IROWS
480: END IF
481: ITAU = 1
482: IWORK = ITAU + IROWS
483: CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
484: $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
485: IF( IINFO.GE.0 )
486: $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
487: IF( IINFO.NE.0 ) THEN
488: INFO = N + 2
489: GO TO 80
490: END IF
491: *
492: CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
493: $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
494: $ LWORK+1-IWORK, IINFO )
495: IF( IINFO.GE.0 )
496: $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
497: IF( IINFO.NE.0 ) THEN
498: INFO = N + 3
499: GO TO 80
500: END IF
501: *
502: IF( ILVL ) THEN
503: CALL ZLASET( 'Full', N, N, CZERO, CONE, VL, LDVL )
504: CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
505: $ VL( ILO+1, ILO ), LDVL )
506: CALL ZUNGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
507: $ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
508: $ IINFO )
509: IF( IINFO.GE.0 )
510: $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
511: IF( IINFO.NE.0 ) THEN
512: INFO = N + 4
513: GO TO 80
514: END IF
515: END IF
516: *
517: IF( ILVR )
518: $ CALL ZLASET( 'Full', N, N, CZERO, CONE, VR, LDVR )
519: *
520: * Reduce to generalized Hessenberg form
521: *
522: IF( ILV ) THEN
523: *
524: * Eigenvectors requested -- work on whole matrix.
525: *
526: CALL ZGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
527: $ LDVL, VR, LDVR, IINFO )
528: ELSE
529: CALL ZGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
530: $ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IINFO )
531: END IF
532: IF( IINFO.NE.0 ) THEN
533: INFO = N + 5
534: GO TO 80
535: END IF
536: *
537: * Perform QZ algorithm
538: *
539: IWORK = ITAU
540: IF( ILV ) THEN
541: CHTEMP = 'S'
542: ELSE
543: CHTEMP = 'E'
544: END IF
545: CALL ZHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
546: $ ALPHA, BETA, VL, LDVL, VR, LDVR, WORK( IWORK ),
547: $ LWORK+1-IWORK, RWORK( IRWORK ), IINFO )
548: IF( IINFO.GE.0 )
549: $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
550: IF( IINFO.NE.0 ) THEN
551: IF( IINFO.GT.0 .AND. IINFO.LE.N ) THEN
552: INFO = IINFO
553: ELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THEN
554: INFO = IINFO - N
555: ELSE
556: INFO = N + 6
557: END IF
558: GO TO 80
559: END IF
560: *
561: IF( ILV ) THEN
562: *
563: * Compute Eigenvectors
564: *
565: IF( ILVL ) THEN
566: IF( ILVR ) THEN
567: CHTEMP = 'B'
568: ELSE
569: CHTEMP = 'L'
570: END IF
571: ELSE
572: CHTEMP = 'R'
573: END IF
574: *
575: CALL ZTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
576: $ VR, LDVR, N, IN, WORK( IWORK ), RWORK( IRWORK ),
577: $ IINFO )
578: IF( IINFO.NE.0 ) THEN
579: INFO = N + 7
580: GO TO 80
581: END IF
582: *
583: * Undo balancing on VL and VR, rescale
584: *
585: IF( ILVL ) THEN
586: CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
587: $ RWORK( IRIGHT ), N, VL, LDVL, IINFO )
588: IF( IINFO.NE.0 ) THEN
589: INFO = N + 8
590: GO TO 80
591: END IF
592: DO 30 JC = 1, N
593: TEMP = ZERO
594: DO 10 JR = 1, N
595: TEMP = MAX( TEMP, ABS1( VL( JR, JC ) ) )
596: 10 CONTINUE
597: IF( TEMP.LT.SAFMIN )
598: $ GO TO 30
599: TEMP = ONE / TEMP
600: DO 20 JR = 1, N
601: VL( JR, JC ) = VL( JR, JC )*TEMP
602: 20 CONTINUE
603: 30 CONTINUE
604: END IF
605: IF( ILVR ) THEN
606: CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
607: $ RWORK( IRIGHT ), N, VR, LDVR, IINFO )
608: IF( IINFO.NE.0 ) THEN
609: INFO = N + 9
610: GO TO 80
611: END IF
612: DO 60 JC = 1, N
613: TEMP = ZERO
614: DO 40 JR = 1, N
615: TEMP = MAX( TEMP, ABS1( VR( JR, JC ) ) )
616: 40 CONTINUE
617: IF( TEMP.LT.SAFMIN )
618: $ GO TO 60
619: TEMP = ONE / TEMP
620: DO 50 JR = 1, N
621: VR( JR, JC ) = VR( JR, JC )*TEMP
622: 50 CONTINUE
623: 60 CONTINUE
624: END IF
625: *
626: * End of eigenvector calculation
627: *
628: END IF
629: *
630: * Undo scaling in alpha, beta
631: *
632: * Note: this does not give the alpha and beta for the unscaled
633: * problem.
634: *
635: * Un-scaling is limited to avoid underflow in alpha and beta
636: * if they are significant.
637: *
638: DO 70 JC = 1, N
639: ABSAR = ABS( DBLE( ALPHA( JC ) ) )
640: ABSAI = ABS( DIMAG( ALPHA( JC ) ) )
641: ABSB = ABS( DBLE( BETA( JC ) ) )
642: SALFAR = ANRM*DBLE( ALPHA( JC ) )
643: SALFAI = ANRM*DIMAG( ALPHA( JC ) )
644: SBETA = BNRM*DBLE( BETA( JC ) )
645: ILIMIT = .FALSE.
646: SCALE = ONE
647: *
648: * Check for significant underflow in imaginary part of ALPHA
649: *
650: IF( ABS( SALFAI ).LT.SAFMIN .AND. ABSAI.GE.
651: $ MAX( SAFMIN, EPS*ABSAR, EPS*ABSB ) ) THEN
652: ILIMIT = .TRUE.
653: SCALE = ( SAFMIN / ANRM1 ) / MAX( SAFMIN, ANRM2*ABSAI )
654: END IF
655: *
656: * Check for significant underflow in real part of ALPHA
657: *
658: IF( ABS( SALFAR ).LT.SAFMIN .AND. ABSAR.GE.
659: $ MAX( SAFMIN, EPS*ABSAI, EPS*ABSB ) ) THEN
660: ILIMIT = .TRUE.
661: SCALE = MAX( SCALE, ( SAFMIN / ANRM1 ) /
662: $ MAX( SAFMIN, ANRM2*ABSAR ) )
663: END IF
664: *
665: * Check for significant underflow in BETA
666: *
667: IF( ABS( SBETA ).LT.SAFMIN .AND. ABSB.GE.
668: $ MAX( SAFMIN, EPS*ABSAR, EPS*ABSAI ) ) THEN
669: ILIMIT = .TRUE.
670: SCALE = MAX( SCALE, ( SAFMIN / BNRM1 ) /
671: $ MAX( SAFMIN, BNRM2*ABSB ) )
672: END IF
673: *
674: * Check for possible overflow when limiting scaling
675: *
676: IF( ILIMIT ) THEN
677: TEMP = ( SCALE*SAFMIN )*MAX( ABS( SALFAR ), ABS( SALFAI ),
678: $ ABS( SBETA ) )
679: IF( TEMP.GT.ONE )
680: $ SCALE = SCALE / TEMP
681: IF( SCALE.LT.ONE )
682: $ ILIMIT = .FALSE.
683: END IF
684: *
685: * Recompute un-scaled ALPHA, BETA if necessary.
686: *
687: IF( ILIMIT ) THEN
688: SALFAR = ( SCALE*DBLE( ALPHA( JC ) ) )*ANRM
689: SALFAI = ( SCALE*DIMAG( ALPHA( JC ) ) )*ANRM
690: SBETA = ( SCALE*BETA( JC ) )*BNRM
691: END IF
692: ALPHA( JC ) = DCMPLX( SALFAR, SALFAI )
693: BETA( JC ) = SBETA
694: 70 CONTINUE
695: *
696: 80 CONTINUE
697: WORK( 1 ) = LWKOPT
698: *
699: RETURN
700: *
701: * End of ZGEGV
702: *
703: END
CVSweb interface <joel.bertrand@systella.fr>