LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dgees.f
Go to the documentation of this file.
1*> \brief <b> DGEES computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DGEES + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgees.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgees.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgees.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, WR, WI,
20* VS, LDVS, WORK, LWORK, BWORK, INFO )
21*
22* .. Scalar Arguments ..
23* CHARACTER JOBVS, SORT
24* INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
25* ..
26* .. Array Arguments ..
27* LOGICAL BWORK( * )
28* DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
29* $ WR( * )
30* ..
31* .. Function Arguments ..
32* LOGICAL SELECT
33* EXTERNAL SELECT
34* ..
35*
36*
37*> \par Purpose:
38* =============
39*>
40*> \verbatim
41*>
42*> DGEES computes for an N-by-N real nonsymmetric matrix A, the
43*> eigenvalues, the real Schur form T, and, optionally, the matrix of
44*> Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).
45*>
46*> Optionally, it also orders the eigenvalues on the diagonal of the
47*> real Schur form so that selected eigenvalues are at the top left.
48*> The leading columns of Z then form an orthonormal basis for the
49*> invariant subspace corresponding to the selected eigenvalues.
50*>
51*> A matrix is in real Schur form if it is upper quasi-triangular with
52*> 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in the
53*> form
54*> [ a b ]
55*> [ c a ]
56*>
57*> where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).
58*> \endverbatim
59*
60* Arguments:
61* ==========
62*
63*> \param[in] JOBVS
64*> \verbatim
65*> JOBVS is CHARACTER*1
66*> = 'N': Schur vectors are not computed;
67*> = 'V': Schur vectors are computed.
68*> \endverbatim
69*>
70*> \param[in] SORT
71*> \verbatim
72*> SORT is CHARACTER*1
73*> Specifies whether or not to order the eigenvalues on the
74*> diagonal of the Schur form.
75*> = 'N': Eigenvalues are not ordered;
76*> = 'S': Eigenvalues are ordered (see SELECT).
77*> \endverbatim
78*>
79*> \param[in] SELECT
80*> \verbatim
81*> SELECT is a LOGICAL FUNCTION of two DOUBLE PRECISION arguments
82*> SELECT must be declared EXTERNAL in the calling subroutine.
83*> If SORT = 'S', SELECT is used to select eigenvalues to sort
84*> to the top left of the Schur form.
85*> If SORT = 'N', SELECT is not referenced.
86*> An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if
87*> SELECT(WR(j),WI(j)) is true; i.e., if either one of a complex
88*> conjugate pair of eigenvalues is selected, then both complex
89*> eigenvalues are selected.
90*> Note that a selected complex eigenvalue may no longer
91*> satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since
92*> ordering may change the value of complex eigenvalues
93*> (especially if the eigenvalue is ill-conditioned); in this
94*> case INFO is set to N+2 (see INFO below).
95*> \endverbatim
96*>
97*> \param[in] N
98*> \verbatim
99*> N is INTEGER
100*> The order of the matrix A. N >= 0.
101*> \endverbatim
102*>
103*> \param[in,out] A
104*> \verbatim
105*> A is DOUBLE PRECISION array, dimension (LDA,N)
106*> On entry, the N-by-N matrix A.
107*> On exit, A has been overwritten by its real Schur form T.
108*> \endverbatim
109*>
110*> \param[in] LDA
111*> \verbatim
112*> LDA is INTEGER
113*> The leading dimension of the array A. LDA >= max(1,N).
114*> \endverbatim
115*>
116*> \param[out] SDIM
117*> \verbatim
118*> SDIM is INTEGER
119*> If SORT = 'N', SDIM = 0.
120*> If SORT = 'S', SDIM = number of eigenvalues (after sorting)
121*> for which SELECT is true. (Complex conjugate
122*> pairs for which SELECT is true for either
123*> eigenvalue count as 2.)
124*> \endverbatim
125*>
126*> \param[out] WR
127*> \verbatim
128*> WR is DOUBLE PRECISION array, dimension (N)
129*> \endverbatim
130*>
131*> \param[out] WI
132*> \verbatim
133*> WI is DOUBLE PRECISION array, dimension (N)
134*> WR and WI contain the real and imaginary parts,
135*> respectively, of the computed eigenvalues in the same order
136*> that they appear on the diagonal of the output Schur form T.
137*> Complex conjugate pairs of eigenvalues will appear
138*> consecutively with the eigenvalue having the positive
139*> imaginary part first.
140*> \endverbatim
141*>
142*> \param[out] VS
143*> \verbatim
144*> VS is DOUBLE PRECISION array, dimension (LDVS,N)
145*> If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur
146*> vectors.
147*> If JOBVS = 'N', VS is not referenced.
148*> \endverbatim
149*>
150*> \param[in] LDVS
151*> \verbatim
152*> LDVS is INTEGER
153*> The leading dimension of the array VS. LDVS >= 1; if
154*> JOBVS = 'V', LDVS >= N.
155*> \endverbatim
156*>
157*> \param[out] WORK
158*> \verbatim
159*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
160*> On exit, if INFO = 0, WORK(1) contains the optimal LWORK.
161*> \endverbatim
162*>
163*> \param[in] LWORK
164*> \verbatim
165*> LWORK is INTEGER
166*> The dimension of the array WORK. LWORK >= max(1,3*N).
167*> For good performance, LWORK must generally be larger.
168*>
169*> If LWORK = -1, then a workspace query is assumed; the routine
170*> only calculates the optimal size of the WORK array, returns
171*> this value as the first entry of the WORK array, and no error
172*> message related to LWORK is issued by XERBLA.
173*> \endverbatim
174*>
175*> \param[out] BWORK
176*> \verbatim
177*> BWORK is LOGICAL array, dimension (N)
178*> Not referenced if SORT = 'N'.
179*> \endverbatim
180*>
181*> \param[out] INFO
182*> \verbatim
183*> INFO is INTEGER
184*> = 0: successful exit
185*> < 0: if INFO = -i, the i-th argument had an illegal value.
186*> > 0: if INFO = i, and i is
187*> <= N: the QR algorithm failed to compute all the
188*> eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI
189*> contain those eigenvalues which have converged; if
190*> JOBVS = 'V', VS contains the matrix which reduces A
191*> to its partially converged Schur form.
192*> = N+1: the eigenvalues could not be reordered because some
193*> eigenvalues were too close to separate (the problem
194*> is very ill-conditioned);
195*> = N+2: after reordering, roundoff changed values of some
196*> complex eigenvalues so that leading eigenvalues in
197*> the Schur form no longer satisfy SELECT=.TRUE. This
198*> could also be caused by underflow due to scaling.
199*> \endverbatim
200*
201* Authors:
202* ========
203*
204*> \author Univ. of Tennessee
205*> \author Univ. of California Berkeley
206*> \author Univ. of Colorado Denver
207*> \author NAG Ltd.
208*
209*> \ingroup gees
210*
211* =====================================================================
212 SUBROUTINE dgees( JOBVS, SORT, SELECT, N, A, LDA, SDIM, WR, WI,
213 $ VS, LDVS, WORK, LWORK, BWORK, INFO )
214*
215* -- LAPACK driver routine --
216* -- LAPACK is a software package provided by Univ. of Tennessee, --
217* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
218*
219* .. Scalar Arguments ..
220 CHARACTER JOBVS, SORT
221 INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
222* ..
223* .. Array Arguments ..
224 LOGICAL BWORK( * )
225 DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
226 $ wr( * )
227* ..
228* .. Function Arguments ..
229 LOGICAL SELECT
230 EXTERNAL SELECT
231* ..
232*
233* =====================================================================
234*
235* .. Parameters ..
236 DOUBLE PRECISION ZERO, ONE
237 parameter( zero = 0.0d0, one = 1.0d0 )
238* ..
239* .. Local Scalars ..
240 LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTST,
241 $ wantvs
242 INTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,
243 $ ihi, ilo, inxt, ip, itau, iwrk, maxwrk, minwrk
244 DOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, S, SEP, SMLNUM
245* ..
246* .. Local Arrays ..
247 INTEGER IDUM( 1 )
248 DOUBLE PRECISION DUM( 1 )
249* ..
250* .. External Subroutines ..
251 EXTERNAL dcopy, dgebak, dgebal, dgehrd, dhseqr,
252 $ dlacpy,
254* ..
255* .. External Functions ..
256 LOGICAL LSAME
257 INTEGER ILAENV
258 DOUBLE PRECISION DLAMCH, DLANGE
259 EXTERNAL lsame, ilaenv, dlamch, dlange
260* ..
261* .. Intrinsic Functions ..
262 INTRINSIC max, sqrt
263* ..
264* .. Executable Statements ..
265*
266* Test the input arguments
267*
268 info = 0
269 lquery = ( lwork.EQ.-1 )
270 wantvs = lsame( jobvs, 'V' )
271 wantst = lsame( sort, 'S' )
272 IF( ( .NOT.wantvs ) .AND. ( .NOT.lsame( jobvs, 'N' ) ) ) THEN
273 info = -1
274 ELSE IF( ( .NOT.wantst ) .AND.
275 $ ( .NOT.lsame( sort, 'N' ) ) ) THEN
276 info = -2
277 ELSE IF( n.LT.0 ) THEN
278 info = -4
279 ELSE IF( lda.LT.max( 1, n ) ) THEN
280 info = -6
281 ELSE IF( ldvs.LT.1 .OR. ( wantvs .AND. ldvs.LT.n ) ) THEN
282 info = -11
283 END IF
284*
285* Compute workspace
286* (Note: Comments in the code beginning "Workspace:" describe the
287* minimal amount of workspace needed at that point in the code,
288* as well as the preferred amount for good performance.
289* NB refers to the optimal block size for the immediately
290* following subroutine, as returned by ILAENV.
291* HSWORK refers to the workspace preferred by DHSEQR, as
292* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
293* the worst case.)
294*
295 IF( info.EQ.0 ) THEN
296 IF( n.EQ.0 ) THEN
297 minwrk = 1
298 maxwrk = 1
299 ELSE
300 maxwrk = 2*n + n*ilaenv( 1, 'DGEHRD', ' ', n, 1, n, 0 )
301 minwrk = 3*n
302*
303 CALL dhseqr( 'S', jobvs, n, 1, n, a, lda, wr, wi, vs,
304 $ ldvs,
305 $ work, -1, ieval )
306 hswork = int( work( 1 ) )
307*
308 IF( .NOT.wantvs ) THEN
309 maxwrk = max( maxwrk, n + hswork )
310 ELSE
311 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
312 $ 'DORGHR', ' ', n, 1, n, -1 ) )
313 maxwrk = max( maxwrk, n + hswork )
314 END IF
315 END IF
316 work( 1 ) = maxwrk
317*
318 IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
319 info = -13
320 END IF
321 END IF
322*
323 IF( info.NE.0 ) THEN
324 CALL xerbla( 'DGEES ', -info )
325 RETURN
326 ELSE IF( lquery ) THEN
327 RETURN
328 END IF
329*
330* Quick return if possible
331*
332 IF( n.EQ.0 ) THEN
333 sdim = 0
334 RETURN
335 END IF
336*
337* Get machine constants
338*
339 eps = dlamch( 'P' )
340 smlnum = dlamch( 'S' )
341 bignum = one / smlnum
342 smlnum = sqrt( smlnum ) / eps
343 bignum = one / smlnum
344*
345* Scale A if max element outside range [SMLNUM,BIGNUM]
346*
347 anrm = dlange( 'M', n, n, a, lda, dum )
348 scalea = .false.
349 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
350 scalea = .true.
351 cscale = smlnum
352 ELSE IF( anrm.GT.bignum ) THEN
353 scalea = .true.
354 cscale = bignum
355 END IF
356 IF( scalea )
357 $ CALL dlascl( 'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
358*
359* Permute the matrix to make it more nearly triangular
360* (Workspace: need N)
361*
362 ibal = 1
363 CALL dgebal( 'P', n, a, lda, ilo, ihi, work( ibal ), ierr )
364*
365* Reduce to upper Hessenberg form
366* (Workspace: need 3*N, prefer 2*N+N*NB)
367*
368 itau = n + ibal
369 iwrk = n + itau
370 CALL dgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
371 $ lwork-iwrk+1, ierr )
372*
373 IF( wantvs ) THEN
374*
375* Copy Householder vectors to VS
376*
377 CALL dlacpy( 'L', n, n, a, lda, vs, ldvs )
378*
379* Generate orthogonal matrix in VS
380* (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
381*
382 CALL dorghr( n, ilo, ihi, vs, ldvs, work( itau ),
383 $ work( iwrk ),
384 $ lwork-iwrk+1, ierr )
385 END IF
386*
387 sdim = 0
388*
389* Perform QR iteration, accumulating Schur vectors in VS if desired
390* (Workspace: need N+1, prefer N+HSWORK (see comments) )
391*
392 iwrk = itau
393 CALL dhseqr( 'S', jobvs, n, ilo, ihi, a, lda, wr, wi, vs, ldvs,
394 $ work( iwrk ), lwork-iwrk+1, ieval )
395 IF( ieval.GT.0 )
396 $ info = ieval
397*
398* Sort eigenvalues if desired
399*
400 IF( wantst .AND. info.EQ.0 ) THEN
401 IF( scalea ) THEN
402 CALL dlascl( 'G', 0, 0, cscale, anrm, n, 1, wr, n, ierr )
403 CALL dlascl( 'G', 0, 0, cscale, anrm, n, 1, wi, n, ierr )
404 END IF
405 DO 10 i = 1, n
406 bwork( i ) = SELECT( wr( i ), wi( i ) )
407 10 CONTINUE
408*
409* Reorder eigenvalues and transform Schur vectors
410* (Workspace: none needed)
411*
412 CALL dtrsen( 'N', jobvs, bwork, n, a, lda, vs, ldvs, wr, wi,
413 $ sdim, s, sep, work( iwrk ), lwork-iwrk+1, idum, 1,
414 $ icond )
415 IF( icond.GT.0 )
416 $ info = n + icond
417 END IF
418*
419 IF( wantvs ) THEN
420*
421* Undo balancing
422* (Workspace: need N)
423*
424 CALL dgebak( 'P', 'R', n, ilo, ihi, work( ibal ), n, vs,
425 $ ldvs,
426 $ ierr )
427 END IF
428*
429 IF( scalea ) THEN
430*
431* Undo scaling for the Schur form of A
432*
433 CALL dlascl( 'H', 0, 0, cscale, anrm, n, n, a, lda, ierr )
434 CALL dcopy( n, a, lda+1, wr, 1 )
435 IF( cscale.EQ.smlnum ) THEN
436*
437* If scaling back towards underflow, adjust WI if an
438* offdiagonal element of a 2-by-2 block in the Schur form
439* underflows.
440*
441 IF( ieval.GT.0 ) THEN
442 i1 = ieval + 1
443 i2 = ihi - 1
444 CALL dlascl( 'G', 0, 0, cscale, anrm, ilo-1, 1, wi,
445 $ max( ilo-1, 1 ), ierr )
446 ELSE IF( wantst ) THEN
447 i1 = 1
448 i2 = n - 1
449 ELSE
450 i1 = ilo
451 i2 = ihi - 1
452 END IF
453 inxt = i1 - 1
454 DO 20 i = i1, i2
455 IF( i.LT.inxt )
456 $ GO TO 20
457 IF( wi( i ).EQ.zero ) THEN
458 inxt = i + 1
459 ELSE
460 IF( a( i+1, i ).EQ.zero ) THEN
461 wi( i ) = zero
462 wi( i+1 ) = zero
463 ELSE IF( a( i+1, i ).NE.zero .AND. a( i, i+1 ).EQ.
464 $ zero ) THEN
465 wi( i ) = zero
466 wi( i+1 ) = zero
467 IF( i.GT.1 )
468 $ CALL dswap( i-1, a( 1, i ), 1, a( 1, i+1 ),
469 $ 1 )
470 IF( n.GT.i+1 )
471 $ CALL dswap( n-i-1, a( i, i+2 ), lda,
472 $ a( i+1, i+2 ), lda )
473 IF( wantvs ) THEN
474 CALL dswap( n, vs( 1, i ), 1, vs( 1, i+1 ),
475 $ 1 )
476 END IF
477 a( i, i+1 ) = a( i+1, i )
478 a( i+1, i ) = zero
479 END IF
480 inxt = i + 2
481 END IF
482 20 CONTINUE
483 END IF
484*
485* Undo scaling for the imaginary part of the eigenvalues
486*
487 CALL dlascl( 'G', 0, 0, cscale, anrm, n-ieval, 1,
488 $ wi( ieval+1 ), max( n-ieval, 1 ), ierr )
489 END IF
490*
491 IF( wantst .AND. info.EQ.0 ) THEN
492*
493* Check if reordering successful
494*
495 lastsl = .true.
496 lst2sl = .true.
497 sdim = 0
498 ip = 0
499 DO 30 i = 1, n
500 cursl = SELECT( wr( i ), wi( i ) )
501 IF( wi( i ).EQ.zero ) THEN
502 IF( cursl )
503 $ sdim = sdim + 1
504 ip = 0
505 IF( cursl .AND. .NOT.lastsl )
506 $ info = n + 2
507 ELSE
508 IF( ip.EQ.1 ) THEN
509*
510* Last eigenvalue of conjugate pair
511*
512 cursl = cursl .OR. lastsl
513 lastsl = cursl
514 IF( cursl )
515 $ sdim = sdim + 2
516 ip = -1
517 IF( cursl .AND. .NOT.lst2sl )
518 $ info = n + 2
519 ELSE
520*
521* First eigenvalue of conjugate pair
522*
523 ip = 1
524 END IF
525 END IF
526 lst2sl = lastsl
527 lastsl = cursl
528 30 CONTINUE
529 END IF
530*
531 work( 1 ) = maxwrk
532 RETURN
533*
534* End of DGEES
535*
536 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dgebak(job, side, n, ilo, ihi, scale, m, v, ldv, info)
DGEBAK
Definition dgebak.f:128
subroutine dgebal(job, n, a, lda, ilo, ihi, scale, info)
DGEBAL
Definition dgebal.f:161
subroutine dgees(jobvs, sort, select, n, a, lda, sdim, wr, wi, vs, ldvs, work, lwork, bwork, info)
DGEES computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE m...
Definition dgees.f:214
subroutine dgehrd(n, ilo, ihi, a, lda, tau, work, lwork, info)
DGEHRD
Definition dgehrd.f:166
subroutine dhseqr(job, compz, n, ilo, ihi, h, ldh, wr, wi, z, ldz, work, lwork, info)
DHSEQR
Definition dhseqr.f:314
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
Definition dlacpy.f:101
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition dlascl.f:142
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
Definition dswap.f:82
subroutine dtrsen(job, compq, select, n, t, ldt, q, ldq, wr, wi, m, s, sep, work, lwork, iwork, liwork, info)
DTRSEN
Definition dtrsen.f:312
subroutine dorghr(n, ilo, ihi, a, lda, tau, work, lwork, info)
DORGHR
Definition dorghr.f:125