KTH framework for Nek5000 toolboxes; testing version  0.0.1
dgeev.f
Go to the documentation of this file.
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.0) --
5 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
6 * Courant Institute, Argonne National Lab, and Rice University
7 * December 8, 1999
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 (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  $ maxb, 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, dlacpy, dlartg,
135 * ..
136 * .. External Functions ..
137  LOGICAL LSAME
138  INTEGER IDAMAX, ILAENV
139  DOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2
140  EXTERNAL lsame, idamax, ilaenv, dlamch, dlange, dlapy2,
141  $ dnrm2
142 * ..
143 * .. Intrinsic Functions ..
144  INTRINSIC max, min, sqrt
145 * ..
146 * .. Executable Statements ..
147 *
148 * Test the input arguments
149 *
150  info = 0
151  lquery = ( lwork.EQ.-1 )
152  wantvl = lsame( jobvl, 'V' )
153  wantvr = lsame( jobvr, 'V' )
154  IF( ( .NOT.wantvl ) .AND. ( .NOT.lsame( jobvl, 'N' ) ) ) THEN
155  info = -1
156  ELSE IF( ( .NOT.wantvr ) .AND. ( .NOT.lsame( jobvr, 'N' ) ) ) THEN
157  info = -2
158  ELSE IF( n.LT.0 ) THEN
159  info = -3
160  ELSE IF( lda.LT.max( 1, n ) ) THEN
161  info = -5
162  ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) ) THEN
163  info = -9
164  ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) ) THEN
165  info = -11
166  END IF
167 *
168 * Compute workspace
169 * (Note: Comments in the code beginning "Workspace:" describe the
170 * minimal amount of workspace needed at that point in the code,
171 * as well as the preferred amount for good performance.
172 * NB refers to the optimal block size for the immediately
173 * following subroutine, as returned by ILAENV.
174 * HSWORK refers to the workspace preferred by DHSEQR, as
175 * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
176 * the worst case.)
177 *
178  minwrk = 1
179  IF( info.EQ.0 .AND. ( lwork.GE.1 .OR. lquery ) ) THEN
180  maxwrk = 2*n + n*ilaenv( 1, 'DGEHRD', ' ', n, 1, n, 0 )
181  IF( ( .NOT.wantvl ) .AND. ( .NOT.wantvr ) ) THEN
182  minwrk = max( 1, 3*n )
183  maxb = max( ilaenv( 8, 'DHSEQR', 'EN', n, 1, n, -1 ), 2 )
184  k = min( maxb, n, max( 2, ilaenv( 4, 'DHSEQR', 'EN', n, 1,
185  $ n, -1 ) ) )
186  hswork = max( k*( k+2 ), 2*n )
187  maxwrk = max( maxwrk, n+1, n+hswork )
188  ELSE
189  minwrk = max( 1, 4*n )
190  maxwrk = max( maxwrk, 2*n+( n-1 )*
191  $ ilaenv( 1, 'DORGHR', ' ', n, 1, n, -1 ) )
192  maxb = max( ilaenv( 8, 'DHSEQR', 'SV', n, 1, n, -1 ), 2 )
193  k = min( maxb, n, max( 2, ilaenv( 4, 'DHSEQR', 'SV', n, 1,
194  $ n, -1 ) ) )
195  hswork = max( k*( k+2 ), 2*n )
196  maxwrk = max( maxwrk, n+1, n+hswork )
197  maxwrk = max( maxwrk, 4*n )
198  END IF
199  work( 1 ) = maxwrk
200  END IF
201  IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
202  info = -13
203  END IF
204  IF( info.NE.0 ) THEN
205  CALL xerbla( 'DGEEV ', -info )
206  RETURN
207  ELSE IF( lquery ) THEN
208  RETURN
209  END IF
210 *
211 * Quick return if possible
212 *
213  IF( n.EQ.0 )
214  $ RETURN
215 *
216 * Get machine constants
217 *
218  eps = dlamch( 'P' )
219  smlnum = dlamch( 'S' )
220  bignum = one / smlnum
221  CALL dlabad( smlnum, bignum )
222  smlnum = sqrt( smlnum ) / eps
223  bignum = one / smlnum
224 *
225 * Scale A if max element outside range [SMLNUM,BIGNUM]
226 *
227  anrm = dlange( 'M', n, n, a, lda, dum )
228  scalea = .false.
229  IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
230  scalea = .true.
231  cscale = smlnum
232  ELSE IF( anrm.GT.bignum ) THEN
233  scalea = .true.
234  cscale = bignum
235  END IF
236  IF( scalea )
237  $ CALL dlascl( 'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
238 *
239 * Balance the matrix
240 * (Workspace: need N)
241 *
242  ibal = 1
243  CALL dgebal( 'B', n, a, lda, ilo, ihi, work( ibal ), ierr )
244 *
245 * Reduce to upper Hessenberg form
246 * (Workspace: need 3*N, prefer 2*N+N*NB)
247 *
248  itau = ibal + n
249  iwrk = itau + n
250  CALL dgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
251  $ lwork-iwrk+1, ierr )
252 *
253  IF( wantvl ) THEN
254 *
255 * Want left eigenvectors
256 * Copy Householder vectors to VL
257 *
258  side = 'L'
259  CALL dlacpy( 'L', n, n, a, lda, vl, ldvl )
260 *
261 * Generate orthogonal matrix in VL
262 * (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
263 *
264  CALL dorghr( n, ilo, ihi, vl, ldvl, work( itau ), work( iwrk ),
265  $ lwork-iwrk+1, ierr )
266 *
267 * Perform QR iteration, accumulating Schur vectors in VL
268 * (Workspace: need N+1, prefer N+HSWORK (see comments) )
269 *
270  iwrk = itau
271  CALL dhseqr( 'S', 'V', n, ilo, ihi, a, lda, wr, wi, vl, ldvl,
272  $ work( iwrk ), lwork-iwrk+1, info )
273 *
274  IF( wantvr ) THEN
275 *
276 * Want left and right eigenvectors
277 * Copy Schur vectors to VR
278 *
279  side = 'B'
280  CALL dlacpy( 'F', n, n, vl, ldvl, vr, ldvr )
281  END IF
282 *
283  ELSE IF( wantvr ) THEN
284 *
285 * Want right eigenvectors
286 * Copy Householder vectors to VR
287 *
288  side = 'R'
289  CALL dlacpy( 'L', n, n, a, lda, vr, ldvr )
290 *
291 * Generate orthogonal matrix in VR
292 * (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
293 *
294  CALL dorghr( n, ilo, ihi, vr, ldvr, work( itau ), work( iwrk ),
295  $ lwork-iwrk+1, ierr )
296 *
297 * Perform QR iteration, accumulating Schur vectors in VR
298 * (Workspace: need N+1, prefer N+HSWORK (see comments) )
299 *
300  iwrk = itau
301  CALL dhseqr( 'S', 'V', n, ilo, ihi, a, lda, wr, wi, vr, ldvr,
302  $ work( iwrk ), lwork-iwrk+1, info )
303 *
304  ELSE
305 *
306 * Compute eigenvalues only
307 * (Workspace: need N+1, prefer N+HSWORK (see comments) )
308 *
309  iwrk = itau
310  CALL dhseqr( 'E', 'N', n, ilo, ihi, a, lda, wr, wi, vr, ldvr,
311  $ work( iwrk ), lwork-iwrk+1, info )
312  END IF
313 *
314 * If INFO > 0 from DHSEQR, then quit
315 *
316  IF( info.GT.0 )
317  $ GO TO 50
318 *
319  IF( wantvl .OR. wantvr ) THEN
320 *
321 * Compute left and/or right eigenvectors
322 * (Workspace: need 4*N)
323 *
324  CALL dtrevc( side, 'B', SELECT, n, a, lda, vl, ldvl, vr, ldvr,
325  $ n, nout, work( iwrk ), ierr )
326  END IF
327 *
328  IF( wantvl ) THEN
329 *
330 * Undo balancing of left eigenvectors
331 * (Workspace: need N)
332 *
333  CALL dgebak( 'B', 'L', n, ilo, ihi, work( ibal ), n, vl, ldvl,
334  $ ierr )
335 *
336 * Normalize left eigenvectors and make largest component real
337 *
338  DO 20 i = 1, n
339  IF( wi( i ).EQ.zero ) THEN
340  scl = one / dnrm2( n, vl( 1, i ), 1 )
341  CALL dscal( n, scl, vl( 1, i ), 1 )
342  ELSE IF( wi( i ).GT.zero ) THEN
343  scl = one / dlapy2( dnrm2( n, vl( 1, i ), 1 ),
344  $ dnrm2( n, vl( 1, i+1 ), 1 ) )
345  CALL dscal( n, scl, vl( 1, i ), 1 )
346  CALL dscal( n, scl, vl( 1, i+1 ), 1 )
347  DO 10 k = 1, n
348  work( iwrk+k-1 ) = vl( k, i )**2 + vl( k, i+1 )**2
349  10 CONTINUE
350  k = idamax( n, work( iwrk ), 1 )
351  CALL dlartg( vl( k, i ), vl( k, i+1 ), cs, sn, r )
352  CALL drot( n, vl( 1, i ), 1, vl( 1, i+1 ), 1, cs, sn )
353  vl( k, i+1 ) = zero
354  END IF
355  20 CONTINUE
356  END IF
357 *
358  IF( wantvr ) THEN
359 *
360 * Undo balancing of right eigenvectors
361 * (Workspace: need N)
362 *
363  CALL dgebak( 'B', 'R', n, ilo, ihi, work( ibal ), n, vr, ldvr,
364  $ ierr )
365 *
366 * Normalize right eigenvectors and make largest component real
367 *
368  DO 40 i = 1, n
369  IF( wi( i ).EQ.zero ) THEN
370  scl = one / dnrm2( n, vr( 1, i ), 1 )
371  CALL dscal( n, scl, vr( 1, i ), 1 )
372  ELSE IF( wi( i ).GT.zero ) THEN
373  scl = one / dlapy2( dnrm2( n, vr( 1, i ), 1 ),
374  $ dnrm2( n, vr( 1, i+1 ), 1 ) )
375  CALL dscal( n, scl, vr( 1, i ), 1 )
376  CALL dscal( n, scl, vr( 1, i+1 ), 1 )
377  DO 30 k = 1, n
378  work( iwrk+k-1 ) = vr( k, i )**2 + vr( k, i+1 )**2
379  30 CONTINUE
380  k = idamax( n, work( iwrk ), 1 )
381  CALL dlartg( vr( k, i ), vr( k, i+1 ), cs, sn, r )
382  CALL drot( n, vr( 1, i ), 1, vr( 1, i+1 ), 1, cs, sn )
383  vr( k, i+1 ) = zero
384  END IF
385  40 CONTINUE
386  END IF
387 *
388 * Undo scaling if necessary
389 *
390  50 CONTINUE
391  IF( scalea ) THEN
392  CALL dlascl( 'G', 0, 0, cscale, anrm, n-info, 1, wr( info+1 ),
393  $ max( n-info, 1 ), ierr )
394  CALL dlascl( 'G', 0, 0, cscale, anrm, n-info, 1, wi( info+1 ),
395  $ max( n-info, 1 ), ierr )
396  IF( info.GT.0 ) THEN
397  CALL dlascl( 'G', 0, 0, cscale, anrm, ilo-1, 1, wr, n,
398  $ ierr )
399  CALL dlascl( 'G', 0, 0, cscale, anrm, ilo-1, 1, wi, n,
400  $ ierr )
401  END IF
402  END IF
403 *
404  work( 1 ) = maxwrk
405  RETURN
406 *
407 * End of DGEEV
408 *
409  END
subroutine dgebak(JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV, INFO)
Definition: dgebak.f:3
subroutine dgebal(JOB, N, A, LDA, ILO, IHI, SCALE, INFO)
Definition: dgebal.f:2
subroutine dgeev(JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR, LDVR, WORK, LWORK, INFO)
Definition: dgeev.f:3
subroutine dgehrd(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
Definition: dgehrd.f:2
subroutine dhseqr(JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z, LDZ, WORK, LWORK, INFO)
Definition: dhseqr.f:3
subroutine dlabad(SMALL, LARGE)
Definition: dlabad.f:2
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
Definition: dlacpy.f:2
subroutine dlartg(F, G, CS, SN, R)
Definition: dlartg.f:2
subroutine dlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
Definition: dlascl.f:2
subroutine dorghr(N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)
Definition: dorghr.f:2
subroutine drot(n, dx, incx, dy, incy, c, s)
Definition: drot.f:2
subroutine dscal(n, da, dx, incx)
Definition: dscal.f:2
subroutine dtrevc(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
Definition: dtrevc.f:3
subroutine xerbla(SRNAME, INFO)
Definition: xerbla.f:2