File:
[local] /
rpl /
lapack /
lapack /
zgeev.f
Revision
1.12:
download - view:
text,
annotated -
select for diffs -
revision graph
Mon Jan 27 09:28:32 2014 UTC (10 years, 7 months ago) by
bertrand
Branches:
MAIN
CVS tags:
rpl-4_1_24,
rpl-4_1_23,
rpl-4_1_22,
rpl-4_1_21,
rpl-4_1_20,
rpl-4_1_19,
rpl-4_1_18,
rpl-4_1_17,
HEAD
Cohérence.
1: *> \brief <b> ZGEEV 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 ZGEEV + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgeev.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgeev.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgeev.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE ZGEEV( JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR,
22: * WORK, LWORK, RWORK, INFO )
23: *
24: * .. Scalar Arguments ..
25: * CHARACTER JOBVL, JOBVR
26: * INTEGER INFO, LDA, LDVL, LDVR, LWORK, N
27: * ..
28: * .. Array Arguments ..
29: * DOUBLE PRECISION RWORK( * )
30: * COMPLEX*16 A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
31: * $ W( * ), WORK( * )
32: * ..
33: *
34: *
35: *> \par Purpose:
36: * =============
37: *>
38: *> \verbatim
39: *>
40: *> ZGEEV computes for an N-by-N complex nonsymmetric matrix A, the
41: *> eigenvalues and, optionally, the left and/or right eigenvectors.
42: *>
43: *> The right eigenvector v(j) of A satisfies
44: *> A * v(j) = lambda(j) * v(j)
45: *> where lambda(j) is its eigenvalue.
46: *> The left eigenvector u(j) of A satisfies
47: *> u(j)**H * A = lambda(j) * u(j)**H
48: *> where u(j)**H denotes the conjugate transpose of u(j).
49: *>
50: *> The computed eigenvectors are normalized to have Euclidean norm
51: *> equal to 1 and largest component real.
52: *> \endverbatim
53: *
54: * Arguments:
55: * ==========
56: *
57: *> \param[in] JOBVL
58: *> \verbatim
59: *> JOBVL is CHARACTER*1
60: *> = 'N': left eigenvectors of A are not computed;
61: *> = 'V': left eigenvectors of are computed.
62: *> \endverbatim
63: *>
64: *> \param[in] JOBVR
65: *> \verbatim
66: *> JOBVR is CHARACTER*1
67: *> = 'N': right eigenvectors of A are not computed;
68: *> = 'V': right eigenvectors of A are computed.
69: *> \endverbatim
70: *>
71: *> \param[in] N
72: *> \verbatim
73: *> N is INTEGER
74: *> The order of the matrix A. N >= 0.
75: *> \endverbatim
76: *>
77: *> \param[in,out] A
78: *> \verbatim
79: *> A is COMPLEX*16 array, dimension (LDA,N)
80: *> On entry, the N-by-N matrix A.
81: *> On exit, A has been overwritten.
82: *> \endverbatim
83: *>
84: *> \param[in] LDA
85: *> \verbatim
86: *> LDA is INTEGER
87: *> The leading dimension of the array A. LDA >= max(1,N).
88: *> \endverbatim
89: *>
90: *> \param[out] W
91: *> \verbatim
92: *> W is COMPLEX*16 array, dimension (N)
93: *> W contains the computed eigenvalues.
94: *> \endverbatim
95: *>
96: *> \param[out] VL
97: *> \verbatim
98: *> VL is COMPLEX*16 array, dimension (LDVL,N)
99: *> If JOBVL = 'V', the left eigenvectors u(j) are stored one
100: *> after another in the columns of VL, in the same order
101: *> as their eigenvalues.
102: *> If JOBVL = 'N', VL is not referenced.
103: *> u(j) = VL(:,j), the j-th column of VL.
104: *> \endverbatim
105: *>
106: *> \param[in] LDVL
107: *> \verbatim
108: *> LDVL is INTEGER
109: *> The leading dimension of the array VL. LDVL >= 1; if
110: *> JOBVL = 'V', LDVL >= N.
111: *> \endverbatim
112: *>
113: *> \param[out] VR
114: *> \verbatim
115: *> VR is COMPLEX*16 array, dimension (LDVR,N)
116: *> If JOBVR = 'V', the right eigenvectors v(j) are stored one
117: *> after another in the columns of VR, in the same order
118: *> as their eigenvalues.
119: *> If JOBVR = 'N', VR is not referenced.
120: *> v(j) = VR(:,j), the j-th column of VR.
121: *> \endverbatim
122: *>
123: *> \param[in] LDVR
124: *> \verbatim
125: *> LDVR is INTEGER
126: *> The leading dimension of the array VR. LDVR >= 1; if
127: *> JOBVR = 'V', LDVR >= N.
128: *> \endverbatim
129: *>
130: *> \param[out] WORK
131: *> \verbatim
132: *> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
133: *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
134: *> \endverbatim
135: *>
136: *> \param[in] LWORK
137: *> \verbatim
138: *> LWORK is INTEGER
139: *> The dimension of the array WORK. LWORK >= max(1,2*N).
140: *> For good performance, LWORK must generally be larger.
141: *>
142: *> If LWORK = -1, then a workspace query is assumed; the routine
143: *> only calculates the optimal size of the WORK array, returns
144: *> this value as the first entry of the WORK array, and no error
145: *> message related to LWORK is issued by XERBLA.
146: *> \endverbatim
147: *>
148: *> \param[out] RWORK
149: *> \verbatim
150: *> RWORK is DOUBLE PRECISION array, dimension (2*N)
151: *> \endverbatim
152: *>
153: *> \param[out] INFO
154: *> \verbatim
155: *> INFO is INTEGER
156: *> = 0: successful exit
157: *> < 0: if INFO = -i, the i-th argument had an illegal value.
158: *> > 0: if INFO = i, the QR algorithm failed to compute all the
159: *> eigenvalues, and no eigenvectors have been computed;
160: *> elements and i+1:N of W contain eigenvalues which have
161: *> converged.
162: *> \endverbatim
163: *
164: * Authors:
165: * ========
166: *
167: *> \author Univ. of Tennessee
168: *> \author Univ. of California Berkeley
169: *> \author Univ. of Colorado Denver
170: *> \author NAG Ltd.
171: *
172: *> \date November 2011
173: *
174: *> \ingroup complex16GEeigen
175: *
176: * =====================================================================
177: SUBROUTINE ZGEEV( JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR,
178: $ WORK, LWORK, RWORK, INFO )
179: *
180: * -- LAPACK driver routine (version 3.4.0) --
181: * -- LAPACK is a software package provided by Univ. of Tennessee, --
182: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
183: * November 2011
184: *
185: * .. Scalar Arguments ..
186: CHARACTER JOBVL, JOBVR
187: INTEGER INFO, LDA, LDVL, LDVR, LWORK, N
188: * ..
189: * .. Array Arguments ..
190: DOUBLE PRECISION RWORK( * )
191: COMPLEX*16 A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
192: $ W( * ), WORK( * )
193: * ..
194: *
195: * =====================================================================
196: *
197: * .. Parameters ..
198: DOUBLE PRECISION ZERO, ONE
199: PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
200: * ..
201: * .. Local Scalars ..
202: LOGICAL LQUERY, SCALEA, WANTVL, WANTVR
203: CHARACTER SIDE
204: INTEGER HSWORK, I, IBAL, IERR, IHI, ILO, IRWORK, ITAU,
205: $ IWRK, K, MAXWRK, MINWRK, NOUT
206: DOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, SCL, SMLNUM
207: COMPLEX*16 TMP
208: * ..
209: * .. Local Arrays ..
210: LOGICAL SELECT( 1 )
211: DOUBLE PRECISION DUM( 1 )
212: * ..
213: * .. External Subroutines ..
214: EXTERNAL DLABAD, XERBLA, ZDSCAL, ZGEBAK, ZGEBAL, ZGEHRD,
215: $ ZHSEQR, ZLACPY, ZLASCL, ZSCAL, ZTREVC, ZUNGHR
216: * ..
217: * .. External Functions ..
218: LOGICAL LSAME
219: INTEGER IDAMAX, ILAENV
220: DOUBLE PRECISION DLAMCH, DZNRM2, ZLANGE
221: EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DZNRM2, ZLANGE
222: * ..
223: * .. Intrinsic Functions ..
224: INTRINSIC DBLE, DCMPLX, DCONJG, DIMAG, MAX, SQRT
225: * ..
226: * .. Executable Statements ..
227: *
228: * Test the input arguments
229: *
230: INFO = 0
231: LQUERY = ( LWORK.EQ.-1 )
232: WANTVL = LSAME( JOBVL, 'V' )
233: WANTVR = LSAME( JOBVR, 'V' )
234: IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
235: INFO = -1
236: ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
237: INFO = -2
238: ELSE IF( N.LT.0 ) THEN
239: INFO = -3
240: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
241: INFO = -5
242: ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
243: INFO = -8
244: ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
245: INFO = -10
246: END IF
247: *
248: * Compute workspace
249: * (Note: Comments in the code beginning "Workspace:" describe the
250: * minimal amount of workspace needed at that point in the code,
251: * as well as the preferred amount for good performance.
252: * CWorkspace refers to complex workspace, and RWorkspace to real
253: * workspace. NB refers to the optimal block size for the
254: * immediately following subroutine, as returned by ILAENV.
255: * HSWORK refers to the workspace preferred by ZHSEQR, as
256: * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
257: * the worst case.)
258: *
259: IF( INFO.EQ.0 ) THEN
260: IF( N.EQ.0 ) THEN
261: MINWRK = 1
262: MAXWRK = 1
263: ELSE
264: MAXWRK = N + N*ILAENV( 1, 'ZGEHRD', ' ', N, 1, N, 0 )
265: MINWRK = 2*N
266: IF( WANTVL ) THEN
267: MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
268: $ ' ', N, 1, N, -1 ) )
269: CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VL, LDVL,
270: $ WORK, -1, INFO )
271: ELSE IF( WANTVR ) THEN
272: MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'ZUNGHR',
273: $ ' ', N, 1, N, -1 ) )
274: CALL ZHSEQR( 'S', 'V', N, 1, N, A, LDA, W, VR, LDVR,
275: $ WORK, -1, INFO )
276: ELSE
277: CALL ZHSEQR( 'E', 'N', N, 1, N, A, LDA, W, VR, LDVR,
278: $ WORK, -1, INFO )
279: END IF
280: HSWORK = WORK( 1 )
281: MAXWRK = MAX( MAXWRK, HSWORK, MINWRK )
282: END IF
283: WORK( 1 ) = MAXWRK
284: *
285: IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
286: INFO = -12
287: END IF
288: END IF
289: *
290: IF( INFO.NE.0 ) THEN
291: CALL XERBLA( 'ZGEEV ', -INFO )
292: RETURN
293: ELSE IF( LQUERY ) THEN
294: RETURN
295: END IF
296: *
297: * Quick return if possible
298: *
299: IF( N.EQ.0 )
300: $ RETURN
301: *
302: * Get machine constants
303: *
304: EPS = DLAMCH( 'P' )
305: SMLNUM = DLAMCH( 'S' )
306: BIGNUM = ONE / SMLNUM
307: CALL DLABAD( SMLNUM, BIGNUM )
308: SMLNUM = SQRT( SMLNUM ) / EPS
309: BIGNUM = ONE / SMLNUM
310: *
311: * Scale A if max element outside range [SMLNUM,BIGNUM]
312: *
313: ANRM = ZLANGE( 'M', N, N, A, LDA, DUM )
314: SCALEA = .FALSE.
315: IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
316: SCALEA = .TRUE.
317: CSCALE = SMLNUM
318: ELSE IF( ANRM.GT.BIGNUM ) THEN
319: SCALEA = .TRUE.
320: CSCALE = BIGNUM
321: END IF
322: IF( SCALEA )
323: $ CALL ZLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
324: *
325: * Balance the matrix
326: * (CWorkspace: none)
327: * (RWorkspace: need N)
328: *
329: IBAL = 1
330: CALL ZGEBAL( 'B', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
331: *
332: * Reduce to upper Hessenberg form
333: * (CWorkspace: need 2*N, prefer N+N*NB)
334: * (RWorkspace: none)
335: *
336: ITAU = 1
337: IWRK = ITAU + N
338: CALL ZGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
339: $ LWORK-IWRK+1, IERR )
340: *
341: IF( WANTVL ) THEN
342: *
343: * Want left eigenvectors
344: * Copy Householder vectors to VL
345: *
346: SIDE = 'L'
347: CALL ZLACPY( 'L', N, N, A, LDA, VL, LDVL )
348: *
349: * Generate unitary matrix in VL
350: * (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
351: * (RWorkspace: none)
352: *
353: CALL ZUNGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
354: $ LWORK-IWRK+1, IERR )
355: *
356: * Perform QR iteration, accumulating Schur vectors in VL
357: * (CWorkspace: need 1, prefer HSWORK (see comments) )
358: * (RWorkspace: none)
359: *
360: IWRK = ITAU
361: CALL ZHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VL, LDVL,
362: $ WORK( IWRK ), LWORK-IWRK+1, INFO )
363: *
364: IF( WANTVR ) THEN
365: *
366: * Want left and right eigenvectors
367: * Copy Schur vectors to VR
368: *
369: SIDE = 'B'
370: CALL ZLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
371: END IF
372: *
373: ELSE IF( WANTVR ) THEN
374: *
375: * Want right eigenvectors
376: * Copy Householder vectors to VR
377: *
378: SIDE = 'R'
379: CALL ZLACPY( 'L', N, N, A, LDA, VR, LDVR )
380: *
381: * Generate unitary matrix in VR
382: * (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
383: * (RWorkspace: none)
384: *
385: CALL ZUNGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
386: $ LWORK-IWRK+1, IERR )
387: *
388: * Perform QR iteration, accumulating Schur vectors in VR
389: * (CWorkspace: need 1, prefer HSWORK (see comments) )
390: * (RWorkspace: none)
391: *
392: IWRK = ITAU
393: CALL ZHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, W, VR, LDVR,
394: $ WORK( IWRK ), LWORK-IWRK+1, INFO )
395: *
396: ELSE
397: *
398: * Compute eigenvalues only
399: * (CWorkspace: need 1, prefer HSWORK (see comments) )
400: * (RWorkspace: none)
401: *
402: IWRK = ITAU
403: CALL ZHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, W, VR, LDVR,
404: $ WORK( IWRK ), LWORK-IWRK+1, INFO )
405: END IF
406: *
407: * If INFO > 0 from ZHSEQR, then quit
408: *
409: IF( INFO.GT.0 )
410: $ GO TO 50
411: *
412: IF( WANTVL .OR. WANTVR ) THEN
413: *
414: * Compute left and/or right eigenvectors
415: * (CWorkspace: need 2*N)
416: * (RWorkspace: need 2*N)
417: *
418: IRWORK = IBAL + N
419: CALL ZTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
420: $ N, NOUT, WORK( IWRK ), RWORK( IRWORK ), IERR )
421: END IF
422: *
423: IF( WANTVL ) THEN
424: *
425: * Undo balancing of left eigenvectors
426: * (CWorkspace: none)
427: * (RWorkspace: need N)
428: *
429: CALL ZGEBAK( 'B', 'L', N, ILO, IHI, RWORK( IBAL ), N, VL, LDVL,
430: $ IERR )
431: *
432: * Normalize left eigenvectors and make largest component real
433: *
434: DO 20 I = 1, N
435: SCL = ONE / DZNRM2( N, VL( 1, I ), 1 )
436: CALL ZDSCAL( N, SCL, VL( 1, I ), 1 )
437: DO 10 K = 1, N
438: RWORK( IRWORK+K-1 ) = DBLE( VL( K, I ) )**2 +
439: $ DIMAG( VL( K, I ) )**2
440: 10 CONTINUE
441: K = IDAMAX( N, RWORK( IRWORK ), 1 )
442: TMP = DCONJG( VL( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
443: CALL ZSCAL( N, TMP, VL( 1, I ), 1 )
444: VL( K, I ) = DCMPLX( DBLE( VL( K, I ) ), ZERO )
445: 20 CONTINUE
446: END IF
447: *
448: IF( WANTVR ) THEN
449: *
450: * Undo balancing of right eigenvectors
451: * (CWorkspace: none)
452: * (RWorkspace: need N)
453: *
454: CALL ZGEBAK( 'B', 'R', N, ILO, IHI, RWORK( IBAL ), N, VR, LDVR,
455: $ IERR )
456: *
457: * Normalize right eigenvectors and make largest component real
458: *
459: DO 40 I = 1, N
460: SCL = ONE / DZNRM2( N, VR( 1, I ), 1 )
461: CALL ZDSCAL( N, SCL, VR( 1, I ), 1 )
462: DO 30 K = 1, N
463: RWORK( IRWORK+K-1 ) = DBLE( VR( K, I ) )**2 +
464: $ DIMAG( VR( K, I ) )**2
465: 30 CONTINUE
466: K = IDAMAX( N, RWORK( IRWORK ), 1 )
467: TMP = DCONJG( VR( K, I ) ) / SQRT( RWORK( IRWORK+K-1 ) )
468: CALL ZSCAL( N, TMP, VR( 1, I ), 1 )
469: VR( K, I ) = DCMPLX( DBLE( VR( K, I ) ), ZERO )
470: 40 CONTINUE
471: END IF
472: *
473: * Undo scaling if necessary
474: *
475: 50 CONTINUE
476: IF( SCALEA ) THEN
477: CALL ZLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, W( INFO+1 ),
478: $ MAX( N-INFO, 1 ), IERR )
479: IF( INFO.GT.0 ) THEN
480: CALL ZLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, W, N, IERR )
481: END IF
482: END IF
483: *
484: WORK( 1 ) = MAXWRK
485: RETURN
486: *
487: * End of ZGEEV
488: *
489: END
CVSweb interface <joel.bertrand@systella.fr>