1      SUBROUTINE DGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,
2     &                  LDVR, WORK, LWORK, INFO )
3*
4*  -- LAPACK driver routine (version 3.2) --
5*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
6*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
7*     November 2006
8*
9*     .. Scalar Arguments ..
10      CHARACTER          JOBVL, JOBVR
11      INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
12*     ..
13*     .. Array Arguments ..
14      DOUBLE PRECISION   A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
15     &                   WI( * ), WORK( * ), WR( * )
16*     ..
17*
18*  Purpose
19*  =======
20*
21*  DGEEV computes for an N-by-N real nonsymmetric matrix A, the
22*  eigenvalues and, optionally, the left and/or right eigenvectors.
23*
24*  The right eigenvector v(j) of A satisfies
25*                   A * v(j) = lambda(j) * v(j)
26*  where lambda(j) is its eigenvalue.
27*  The left eigenvector u(j) of A satisfies
28*                u(j)**H * A = lambda(j) * u(j)**H
29*  where u(j)**H denotes the conjugate transpose of u(j).
30*
31*  The computed eigenvectors are normalized to have Euclidean norm
32*  equal to 1 and largest component real.
33*
34*  Arguments
35*  =========
36*
37*  JOBVL   (input) CHARACTER*1
38*          = 'N': left eigenvectors of A are not computed;
39*          = 'V': left eigenvectors of A are computed.
40*
41*  JOBVR   (input) CHARACTER*1
42*          = 'N': right eigenvectors of A are not computed;
43*          = 'V': right eigenvectors of A are computed.
44*
45*  N       (input) INTEGER
46*          The order of the matrix A. N >= 0.
47*
48*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
49*          On entry, the N-by-N matrix A.
50*          On exit, A has been overwritten.
51*
52*  LDA     (input) INTEGER
53*          The leading dimension of the array A.  LDA >= max(1,N).
54*
55*  WR      (output) DOUBLE PRECISION array, dimension (N)
56*  WI      (output) DOUBLE PRECISION array, dimension (N)
57*          WR and WI contain the real and imaginary parts,
58*          respectively, of the computed eigenvalues.  Complex
59*          conjugate pairs of eigenvalues appear consecutively
60*          with the eigenvalue having the positive imaginary part
61*          first.
62*
63*  VL      (output) DOUBLE PRECISION array, dimension (LDVL,N)
64*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
65*          after another in the columns of VL, in the same order
66*          as their eigenvalues.
67*          If JOBVL = 'N', VL is not referenced.
68*          If the j-th eigenvalue is real, then u(j) = VL(:,j),
69*          the j-th column of VL.
70*          If the j-th and (j+1)-st eigenvalues form a complex
71*          conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and
72*          u(j+1) = VL(:,j) - i*VL(:,j+1).
73*
74*  LDVL    (input) INTEGER
75*          The leading dimension of the array VL.  LDVL >= 1; if
76*          JOBVL = 'V', LDVL >= N.
77*
78*  VR      (output) DOUBLE PRECISION array, dimension (LDVR,N)
79*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
80*          after another in the columns of VR, in the same order
81*          as their eigenvalues.
82*          If JOBVR = 'N', VR is not referenced.
83*          If the j-th eigenvalue is real, then v(j) = VR(:,j),
84*          the j-th column of VR.
85*          If the j-th and (j+1)-st eigenvalues form a complex
86*          conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and
87*          v(j+1) = VR(:,j) - i*VR(:,j+1).
88*
89*  LDVR    (input) INTEGER
90*          The leading dimension of the array VR.  LDVR >= 1; if
91*          JOBVR = 'V', LDVR >= N.
92*
93*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
94*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
95*
96*  LWORK   (input) INTEGER
97*          The dimension of the array WORK.  LWORK >= max(1,3*N), and
98*          if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N.  For good
99*          performance, LWORK must generally be larger.
100*
101*          If LWORK = -1, then a workspace query is assumed; the routine
102*          only calculates the optimal size of the WORK array, returns
103*          this value as the first entry of the WORK array, and no error
104*          message related to LWORK is issued by XERBLA.
105*
106*  INFO    (output) INTEGER
107*          = 0:  successful exit
108*          < 0:  if INFO = -i, the i-th argument had an illegal value.
109*          > 0:  if INFO = i, the QR algorithm failed to compute all the
110*                eigenvalues, and no eigenvectors have been computed;
111*                elements i+1:N of WR and WI contain eigenvalues which
112*                have converged.
113*
114*  =====================================================================
115*
116*     .. Parameters ..
117      DOUBLE PRECISION   ZERO, ONE
118      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
119*     ..
120*     .. Local Scalars ..
121      LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
122      CHARACTER          SIDE
123      INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
124     $                   MAXWRK, MINWRK, NOUT
125      DOUBLE PRECISION   ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
126     $                   SN
127*     ..
128*     .. Local Arrays ..
129      LOGICAL            SELECT( 1 )
130      DOUBLE PRECISION   DUM( 1 )
131*     ..
132*     .. External Subroutines ..
133      EXTERNAL           DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,
134     $                   DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC,
135     $                   XERBLA
136*     ..
137*     .. External Functions ..
138      LOGICAL            LSAME
139      INTEGER            IDAMAX, ILAENV
140      DOUBLE PRECISION   DLAMCH, DLANGE, DLAPY2, DNRM2
141      EXTERNAL           LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,
142     $                   DNRM2
143*     ..
144*     .. Intrinsic Functions ..
145      INTRINSIC          MAX, SQRT
146*     ..
147*     .. Executable Statements ..
148*
149*     Test the input arguments
150*
151      INFO = 0
152      LQUERY = ( LWORK.EQ.-1 )
153      WANTVL = LSAME( JOBVL, 'V' )
154      WANTVR = LSAME( JOBVR, 'V' )
155      IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
156         INFO = -1
157      ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
158         INFO = -2
159      ELSE IF( N.LT.0 ) THEN
160         INFO = -3
161      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
162         INFO = -5
163      ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
164         INFO = -9
165      ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
166         INFO = -11
167      END IF
168*
169*     Compute workspace
170*      (Note: Comments in the code beginning "Workspace:" describe the
171*       minimal amount of workspace needed at that point in the code,
172*       as well as the preferred amount for good performance.
173*       NB refers to the optimal block size for the immediately
174*       following subroutine, as returned by ILAENV.
175*       HSWORK refers to the workspace preferred by DHSEQR, as
176*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
177*       the worst case.)
178*
179      IF( INFO.EQ.0 ) THEN
180         IF( N.EQ.0 ) THEN
181            MINWRK = 1
182            MAXWRK = 1
183         ELSE
184            MAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
185            IF( WANTVL ) THEN
186               MINWRK = 4*N
187               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
188     $                       'DORGHR', ' ', N, 1, N, -1 ) )
189               CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
190     $                WORK, -1, INFO )
191               HSWORK = WORK( 1 )
192               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
193               MAXWRK = MAX( MAXWRK, 4*N )
194            ELSE IF( WANTVR ) THEN
195               MINWRK = 4*N
196               MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
197     $                       'DORGHR', ' ', N, 1, N, -1 ) )
198               CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
199     $                WORK, -1, INFO )
200               HSWORK = WORK( 1 )
201               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
202               MAXWRK = MAX( MAXWRK, 4*N )
203            ELSE
204               MINWRK = 3*N
205               CALL DHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR, LDVR,
206     $                WORK, -1, INFO )
207               HSWORK = WORK( 1 )
208               MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
209            END IF
210            MAXWRK = MAX( MAXWRK, MINWRK )
211         END IF
212         WORK( 1 ) = MAXWRK
213*
214         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
215            INFO = -13
216         END IF
217      END IF
218*
219      IF( INFO.NE.0 ) THEN
220         CALL XERBLA( 'DGEEV ', -INFO )
221         RETURN
222      ELSE IF( LQUERY ) THEN
223         RETURN
224      END IF
225*
226*     Quick return if possible
227*
228      IF( N.EQ.0 )
229     $   RETURN
230*
231*     Get machine constants
232*
233      EPS = DLAMCH( 'P' )
234      SMLNUM = DLAMCH( 'S' )
235      BIGNUM = ONE / SMLNUM
236      CALL DLABAD( SMLNUM, BIGNUM )
237      SMLNUM = SQRT( SMLNUM ) / EPS
238      BIGNUM = ONE / SMLNUM
239*
240*     Scale A if max element outside range [SMLNUM,BIGNUM]
241*
242      ANRM = DLANGE( 'M', N, N, A, LDA, DUM )
243      SCALEA = .FALSE.
244      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
245         SCALEA = .TRUE.
246         CSCALE = SMLNUM
247      ELSE IF( ANRM.GT.BIGNUM ) THEN
248         SCALEA = .TRUE.
249         CSCALE = BIGNUM
250      END IF
251      IF( SCALEA )
252     $   CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
253*
254*     Balance the matrix
255*     (Workspace: need N)
256*
257      IBAL = 1
258      CALL DGEBAL( 'B', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
259*
260*     Reduce to upper Hessenberg form
261*     (Workspace: need 3*N, prefer 2*N+N*NB)
262*
263      ITAU = IBAL + N
264      IWRK = ITAU + N
265      CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
266     $             LWORK-IWRK+1, IERR )
267*
268      IF( WANTVL ) THEN
269*
270*        Want left eigenvectors
271*        Copy Householder vectors to VL
272*
273         SIDE = 'L'
274         CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )
275*
276*        Generate orthogonal matrix in VL
277*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
278*
279         CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
280     $                LWORK-IWRK+1, IERR )
281*
282*        Perform QR iteration, accumulating Schur vectors in VL
283*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
284*
285         IWRK = ITAU
286         CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,
287     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
288*
289         IF( WANTVR ) THEN
290*
291*           Want left and right eigenvectors
292*           Copy Schur vectors to VR
293*
294            SIDE = 'B'
295            CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
296         END IF
297*
298      ELSE IF( WANTVR ) THEN
299*
300*        Want right eigenvectors
301*        Copy Householder vectors to VR
302*
303         SIDE = 'R'
304         CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )
305*
306*        Generate orthogonal matrix in VR
307*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
308*
309         CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
310     $                LWORK-IWRK+1, IERR )
311*
312*        Perform QR iteration, accumulating Schur vectors in VR
313*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
314*
315         IWRK = ITAU
316         CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
317     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
318*
319      ELSE
320*
321*        Compute eigenvalues only
322*        (Workspace: need N+1, prefer N+HSWORK (see comments) )
323*
324         IWRK = ITAU
325         CALL DHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
326     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
327      END IF
328*
329*     If INFO > 0 from DHSEQR, then quit
330*
331      IF( INFO.GT.0 )
332     $   GO TO 50
333*
334      IF( WANTVL .OR. WANTVR ) THEN
335*
336*        Compute left and/or right eigenvectors
337*        (Workspace: need 4*N)
338*
339         CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
340     $                N, NOUT, WORK( IWRK ), IERR )
341      END IF
342*
343      IF( WANTVL ) THEN
344*
345*        Undo balancing of left eigenvectors
346*        (Workspace: need N)
347*
348         CALL DGEBAK( 'B', 'L', N, ILO, IHI, WORK( IBAL ), N, VL, LDVL,
349     $                IERR )
350*
351*        Normalize left eigenvectors and make largest component real
352*
353         DO 20 I = 1, N
354            IF( WI( I ).EQ.ZERO ) THEN
355               SCL = ONE / DNRM2( N, VL( 1, I ), 1 )
356               CALL DSCAL( N, SCL, VL( 1, I ), 1 )
357            ELSE IF( WI( I ).GT.ZERO ) THEN
358               SCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),
359     $               DNRM2( N, VL( 1, I+1 ), 1 ) )
360               CALL DSCAL( N, SCL, VL( 1, I ), 1 )
361               CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )
362               DO 10 K = 1, N
363                  WORK( IWRK+K-1 ) = VL( K, I )**2 + VL( K, I+1 )**2
364   10          CONTINUE
365               K = IDAMAX( N, WORK( IWRK ), 1 )
366               CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )
367               CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )
368               VL( K, I+1 ) = ZERO
369            END IF
370   20    CONTINUE
371      END IF
372*
373      IF( WANTVR ) THEN
374*
375*        Undo balancing of right eigenvectors
376*        (Workspace: need N)
377*
378         CALL DGEBAK( 'B', 'R', N, ILO, IHI, WORK( IBAL ), N, VR, LDVR,
379     $                IERR )
380*
381*        Normalize right eigenvectors and make largest component real
382*
383         DO 40 I = 1, N
384            IF( WI( I ).EQ.ZERO ) THEN
385               SCL = ONE / DNRM2( N, VR( 1, I ), 1 )
386               CALL DSCAL( N, SCL, VR( 1, I ), 1 )
387            ELSE IF( WI( I ).GT.ZERO ) THEN
388               SCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),
389     $               DNRM2( N, VR( 1, I+1 ), 1 ) )
390               CALL DSCAL( N, SCL, VR( 1, I ), 1 )
391               CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )
392               DO 30 K = 1, N
393                  WORK( IWRK+K-1 ) = VR( K, I )**2 + VR( K, I+1 )**2
394   30          CONTINUE
395               K = IDAMAX( N, WORK( IWRK ), 1 )
396               CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )
397               CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )
398               VR( K, I+1 ) = ZERO
399            END IF
400   40    CONTINUE
401      END IF
402*
403*     Undo scaling if necessary
404*
405   50 CONTINUE
406      IF( SCALEA ) THEN
407         CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),
408     $                MAX( N-INFO, 1 ), IERR )
409         CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),
410     $                MAX( N-INFO, 1 ), IERR )
411         IF( INFO.GT.0 ) THEN
412            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,
413     $                   IERR )
414            CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
415     $                   IERR )
416         END IF
417      END IF
418*
419      WORK( 1 ) = MAXWRK
420      RETURN
421*
422*     End of DGEEV
423*
424      END
425*=================
426      SUBROUTINE ZGEEV( JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR,
427     $                  WORK, LWORK, RWORK, INFO )
428*
429*  -- LAPACK driver routine (version 3.2) --
430*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
431*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
432*     November 2006
433*
434*     .. Scalar Arguments ..
435      CHARACTER          JOBVL, JOBVR
436      INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N
437*     ..
438*     .. Array Arguments ..
439      DOUBLE PRECISION   RWORK( * )
440      COMPLEX*16         A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
441     $                   W( * ), WORK( * )
442*     ..
443*
444*  Purpose
445*  =======
446*
447*  ZGEEV computes for an N-by-N complex nonsymmetric matrix A, the
448*  eigenvalues and, optionally, the left and/or right eigenvectors.
449*
450*  The right eigenvector v(j) of A satisfies
451*                   A * v(j) = lambda(j) * v(j)
452*  where lambda(j) is its eigenvalue.
453*  The left eigenvector u(j) of A satisfies
454*                u(j)**H * A = lambda(j) * u(j)**H
455*  where u(j)**H denotes the conjugate transpose of u(j).
456*
457*  The computed eigenvectors are normalized to have Euclidean norm
458*  equal to 1 and largest component real.
459*
460*  Arguments
461*  =========
462*
463*  JOBVL   (input) CHARACTER*1
464*          = 'N': left eigenvectors of A are not computed;
465*          = 'V': left eigenvectors of are computed.
466*
467*  JOBVR   (input) CHARACTER*1
468*          = 'N': right eigenvectors of A are not computed;
469*          = 'V': right eigenvectors of A are computed.
470*
471*  N       (input) INTEGER
472*          The order of the matrix A. N >= 0.
473*
474*  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
475*          On entry, the N-by-N matrix A.
476*          On exit, A has been overwritten.
477*
478*  LDA     (input) INTEGER
479*          The leading dimension of the array A.  LDA >= max(1,N).
480*
481*  W       (output) COMPLEX*16 array, dimension (N)
482*          W contains the computed eigenvalues.
483*
484*  VL      (output) COMPLEX*16 array, dimension (LDVL,N)
485*          If JOBVL = 'V', the left eigenvectors u(j) are stored one
486*          after another in the columns of VL, in the same order
487*          as their eigenvalues.
488*          If JOBVL = 'N', VL is not referenced.
489*          u(j) = VL(:,j), the j-th column of VL.
490*
491*  LDVL    (input) INTEGER
492*          The leading dimension of the array VL.  LDVL >= 1; if
493*          JOBVL = 'V', LDVL >= N.
494*
495*  VR      (output) COMPLEX*16 array, dimension (LDVR,N)
496*          If JOBVR = 'V', the right eigenvectors v(j) are stored one
497*          after another in the columns of VR, in the same order
498*          as their eigenvalues.
499*          If JOBVR = 'N', VR is not referenced.
500*          v(j) = VR(:,j), the j-th column of VR.
501*
502*  LDVR    (input) INTEGER
503*          The leading dimension of the array VR.  LDVR >= 1; if
504*          JOBVR = 'V', LDVR >= N.
505*
506*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
507*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
508*
509*  LWORK   (input) INTEGER
510*          The dimension of the array WORK.  LWORK >= max(1,2*N).
511*          For good performance, LWORK must generally be larger.
512*
513*          If LWORK = -1, then a workspace query is assumed; the routine
514*          only calculates the optimal size of the WORK array, returns
515*          this value as the first entry of the WORK array, and no error
516*          message related to LWORK is issued by XERBLA.
517*
518*  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
519*
520*  INFO    (output) INTEGER
521*          = 0:  successful exit
522*          < 0:  if INFO = -i, the i-th argument had an illegal value.
523*          > 0:  if INFO = i, the QR algorithm failed to compute all the
524*                eigenvalues, and no eigenvectors have been computed;
525*                elements and i+1:N of W contain eigenvalues which have
526*                converged.
527*
528*  =====================================================================
529*
530*     .. Parameters ..
531      DOUBLE PRECISION   ZERO, ONE
532      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
533*     ..
534*     .. Local Scalars ..
535      LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR
536      CHARACTER          SIDE
537      INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, IRWORK, ITAU,
538     $                   IWRK, K, MAXWRK, MINWRK, NOUT
539      DOUBLE PRECISION   ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
540      COMPLEX*16         TMP
541*     ..
542*     .. Local Arrays ..
543      LOGICAL            SELECT( 1 )
544      DOUBLE PRECISION   DUM( 1 )
545*     ..
546*     .. External Subroutines ..
547      EXTERNAL           DLABAD, XERBLA, ZDSCAL, ZGEBAK, ZGEBAL, ZGEHRD,
548     $                   ZHSEQR, ZLACPY, ZLASCL, ZSCAL, ZTREVC, ZUNGHR
549*     ..
550*     .. External Functions ..
551      LOGICAL            LSAME
552      INTEGER            IDAMAX, ILAENV
553      DOUBLE PRECISION   DLAMCH, DZNRM2, ZLANGE
554      EXTERNAL           LSAME, IDAMAX, ILAENV, DLAMCH, DZNRM2, ZLANGE
555*     ..
556*     .. Intrinsic Functions ..
557      INTRINSIC          DBLE, DCMPLX, DCONJG, DIMAG, MAX, SQRT
558*     ..
559*     .. Executable Statements ..
560*
561*     Test the input arguments
562*
563      INFO = 0
564      LQUERY = ( LWORK.EQ.-1 )
565      WANTVL = LSAME( JOBVL, 'V' )
566      WANTVR = LSAME( JOBVR, 'V' )
567      IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
568         INFO = -1
569      ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
570         INFO = -2
571      ELSE IF( N.LT.0 ) THEN
572         INFO = -3
573      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
574         INFO = -5
575      ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
576         INFO = -8
577      ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
578         INFO = -10
579      END IF
580*
581*     Compute workspace
582*      (Note: Comments in the code beginning "Workspace:" describe the
583*       minimal amount of workspace needed at that point in the code,
584*       as well as the preferred amount for good performance.
585*       CWorkspace refers to complex workspace, and RWorkspace to real
586*       workspace. NB refers to the optimal block size for the
587*       immediately following subroutine, as returned by ILAENV.
588*       HSWORK refers to the workspace preferred by ZHSEQR, as
589*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
590*       the worst case.)
591*
592      IF( INFO.EQ.0 ) THEN
593         IF( N.EQ.0 ) THEN
594            MINWRK = 1
595            MAXWRK = 1
596         ELSE
597            MAXWRK = N + N*ILAENV( 1, 'ZGEHRD', ' ', N, 1, N, 0 )
598            MINWRK = 2*N
599            IF( WANTVL ) THEN
600               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
601     $                       ' ', N, 1, N, -1 ) )
602               CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
603     $                WORK, -1, INFO )
604            ELSE IF( WANTVR ) THEN
605               MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
606     $                       ' ', N, 1, N, -1 ) )
607               CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
608     $                WORK, -1, INFO )
609            ELSE
610               CALL ZHSEQR( 'E', 'N', N, 1, N, A, LDA, W, VR, LDVR,
611     $                WORK, -1, INFO )
612            END IF
613            HSWORK = WORK( 1 )
614            MAXWRK = MAX( MAXWRK, HSWORK, MINWRK )
615         END IF
616         WORK( 1 ) = MAXWRK
617*
618         IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
619            INFO = -12
620         END IF
621      END IF
622*
623      IF( INFO.NE.0 ) THEN
624         CALL XERBLA( 'ZGEEV ', -INFO )
625         RETURN
626      ELSE IF( LQUERY ) THEN
627         RETURN
628      END IF
629*
630*     Quick return if possible
631*
632      IF( N.EQ.0 )
633     $   RETURN
634*
635*     Get machine constants
636*
637      EPS = DLAMCH( 'P' )
638      SMLNUM = DLAMCH( 'S' )
639      BIGNUM = ONE / SMLNUM
640      CALL DLABAD( SMLNUM, BIGNUM )
641      SMLNUM = SQRT( SMLNUM ) / EPS
642      BIGNUM = ONE / SMLNUM
643*
644*     Scale A if max element outside range [SMLNUM,BIGNUM]
645*
646      ANRM = ZLANGE( 'M', N, N, A, LDA, DUM )
647      SCALEA = .FALSE.
648      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
649         SCALEA = .TRUE.
650         CSCALE = SMLNUM
651      ELSE IF( ANRM.GT.BIGNUM ) THEN
652         SCALEA = .TRUE.
653         CSCALE = BIGNUM
654      END IF
655      IF( SCALEA )
656     $   CALL ZLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
657*
658*     Balance the matrix
659*     (CWorkspace: none)
660*     (RWorkspace: need N)
661*
662      IBAL = 1
663      CALL ZGEBAL( 'B', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
664*
665*     Reduce to upper Hessenberg form
666*     (CWorkspace: need 2*N, prefer N+N*NB)
667*     (RWorkspace: none)
668*
669      ITAU = 1
670      IWRK = ITAU + N
671      CALL ZGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
672     $             LWORK-IWRK+1, IERR )
673*
674      IF( WANTVL ) THEN
675*
676*        Want left eigenvectors
677*        Copy Householder vectors to VL
678*
679         SIDE = 'L'
680         CALL ZLACPY( 'L', N, N, A, LDA, VL, LDVL )
681*
682*        Generate unitary matrix in VL
683*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
684*        (RWorkspace: none)
685*
686         CALL ZUNGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
687     $                LWORK-IWRK+1, IERR )
688*
689*        Perform QR iteration, accumulating Schur vectors in VL
690*        (CWorkspace: need 1, prefer HSWORK (see comments) )
691*        (RWorkspace: none)
692*
693         IWRK = ITAU
694         CALL ZHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VL, LDVL,
695     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
696*
697         IF( WANTVR ) THEN
698*
699*           Want left and right eigenvectors
700*           Copy Schur vectors to VR
701*
702            SIDE = 'B'
703            CALL ZLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
704         END IF
705*
706      ELSE IF( WANTVR ) THEN
707*
708*        Want right eigenvectors
709*        Copy Householder vectors to VR
710*
711         SIDE = 'R'
712         CALL ZLACPY( 'L', N, N, A, LDA, VR, LDVR )
713*
714*        Generate unitary matrix in VR
715*        (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
716*        (RWorkspace: none)
717*
718         CALL ZUNGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
719     $                LWORK-IWRK+1, IERR )
720*
721*        Perform QR iteration, accumulating Schur vectors in VR
722*        (CWorkspace: need 1, prefer HSWORK (see comments) )
723*        (RWorkspace: none)
724*
725         IWRK = ITAU
726         CALL ZHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VR, LDVR,
727     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
728*
729      ELSE
730*
731*        Compute eigenvalues only
732*        (CWorkspace: need 1, prefer HSWORK (see comments) )
733*        (RWorkspace: none)
734*
735         IWRK = ITAU
736         CALL ZHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, W, VR, LDVR,
737     $                WORK( IWRK ), LWORK-IWRK+1, INFO )
738      END IF
739*
740*     If INFO > 0 from ZHSEQR, then quit
741*
742      IF( INFO.GT.0 )
743     $   GO TO 50
744*
745      IF( WANTVL .OR. WANTVR ) THEN
746*
747*        Compute left and/or right eigenvectors
748*        (CWorkspace: need 2*N)
749*        (RWorkspace: need 2*N)
750*
751         IRWORK = IBAL + N
752         CALL ZTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
753     $                N, NOUT, WORK( IWRK ), RWORK( IRWORK ), IERR )
754      END IF
755*
756      IF( WANTVL ) THEN
757*
758*        Undo balancing of left eigenvectors
759*        (CWorkspace: none)
760*        (RWorkspace: need N)
761*
762         CALL ZGEBAK( 'B', 'L', N, ILO, IHI, RWORK( IBAL ), N, VL, LDVL,
763     $                IERR )
764*
765*        Normalize left eigenvectors and make largest component real
766*
767         DO 20 I = 1, N
768            SCL = ONE / DZNRM2( N, VL( 1, I ), 1 )
769            CALL ZDSCAL( N, SCL, VL( 1, I ), 1 )
770            DO 10 K = 1, N
771               RWORK( IRWORK+K-1 ) = DBLE( VL( K, I ) )**2 +
772     $                               DIMAG( VL( K, I ) )**2
773   10       CONTINUE
774            K = IDAMAX( N, RWORK( IRWORK ), 1 )
775            TMP = DCONJG( VL( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
776            CALL ZSCAL( N, TMP, VL( 1, I ), 1 )
777            VL( K, I ) = DCMPLX( DBLE( VL( K, I ) ), ZERO )
778   20    CONTINUE
779      END IF
780*
781      IF( WANTVR ) THEN
782*
783*        Undo balancing of right eigenvectors
784*        (CWorkspace: none)
785*        (RWorkspace: need N)
786*
787         CALL ZGEBAK( 'B', 'R', N, ILO, IHI, RWORK( IBAL ), N, VR, LDVR,
788     $                IERR )
789*
790*        Normalize right eigenvectors and make largest component real
791*
792         DO 40 I = 1, N
793            SCL = ONE / DZNRM2( N, VR( 1, I ), 1 )
794            CALL ZDSCAL( N, SCL, VR( 1, I ), 1 )
795            DO 30 K = 1, N
796               RWORK( IRWORK+K-1 ) = DBLE( VR( K, I ) )**2 +
797     $                               DIMAG( VR( K, I ) )**2
798   30       CONTINUE
799            K = IDAMAX( N, RWORK( IRWORK ), 1 )
800            TMP = DCONJG( VR( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
801            CALL ZSCAL( N, TMP, VR( 1, I ), 1 )
802            VR( K, I ) = DCMPLX( DBLE( VR( K, I ) ), ZERO )
803   40    CONTINUE
804      END IF
805*
806*     Undo scaling if necessary
807*
808   50 CONTINUE
809      IF( SCALEA ) THEN
810         CALL ZLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, W( INFO+1 ),
811     $                MAX( N-INFO, 1 ), IERR )
812         IF( INFO.GT.0 ) THEN
813            CALL ZLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, W, N, IERR )
814         END IF
815      END IF
816*
817      WORK( 1 ) = MAXWRK
818      RETURN
819*
820*     End of ZGEEV
821*
822      END
823