LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ dgees()

subroutine dgees ( character jobvs,
character sort,
external select,
integer n,
double precision, dimension( lda, * ) a,
integer lda,
integer sdim,
double precision, dimension( * ) wr,
double precision, dimension( * ) wi,
double precision, dimension( ldvs, * ) vs,
integer ldvs,
double precision, dimension( * ) work,
integer lwork,
logical, dimension( * ) bwork,
integer info )

DGEES computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices

Download DGEES + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DGEES computes for an N-by-N real nonsymmetric matrix A, the
!> eigenvalues, the real Schur form T, and, optionally, the matrix of
!> Schur vectors Z.  This gives the Schur factorization A = Z*T*(Z**T).
!>
!> Optionally, it also orders the eigenvalues on the diagonal of the
!> real Schur form so that selected eigenvalues are at the top left.
!> The leading columns of Z then form an orthonormal basis for the
!> invariant subspace corresponding to the selected eigenvalues.
!>
!> A matrix is in real Schur form if it is upper quasi-triangular with
!> 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in the
!> form
!>         [  a  b  ]
!>         [  c  a  ]
!>
!> where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).
!> 
Parameters
[in]JOBVS
!>          JOBVS is CHARACTER*1
!>          = 'N': Schur vectors are not computed;
!>          = 'V': Schur vectors are computed.
!> 
[in]SORT
!>          SORT is CHARACTER*1
!>          Specifies whether or not to order the eigenvalues on the
!>          diagonal of the Schur form.
!>          = 'N': Eigenvalues are not ordered;
!>          = 'S': Eigenvalues are ordered (see SELECT).
!> 
[in]SELECT
!>          SELECT is a LOGICAL FUNCTION of two DOUBLE PRECISION arguments
!>          SELECT must be declared EXTERNAL in the calling subroutine.
!>          If SORT = 'S', SELECT is used to select eigenvalues to sort
!>          to the top left of the Schur form.
!>          If SORT = 'N', SELECT is not referenced.
!>          An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if
!>          SELECT(WR(j),WI(j)) is true; i.e., if either one of a complex
!>          conjugate pair of eigenvalues is selected, then both complex
!>          eigenvalues are selected.
!>          Note that a selected complex eigenvalue may no longer
!>          satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since
!>          ordering may change the value of complex eigenvalues
!>          (especially if the eigenvalue is ill-conditioned); in this
!>          case INFO is set to N+2 (see INFO below).
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A. N >= 0.
!> 
[in,out]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          On entry, the N-by-N matrix A.
!>          On exit, A has been overwritten by its real Schur form T.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[out]SDIM
!>          SDIM is INTEGER
!>          If SORT = 'N', SDIM = 0.
!>          If SORT = 'S', SDIM = number of eigenvalues (after sorting)
!>                         for which SELECT is true. (Complex conjugate
!>                         pairs for which SELECT is true for either
!>                         eigenvalue count as 2.)
!> 
[out]WR
!>          WR is DOUBLE PRECISION array, dimension (N)
!> 
[out]WI
!>          WI is DOUBLE PRECISION array, dimension (N)
!>          WR and WI contain the real and imaginary parts,
!>          respectively, of the computed eigenvalues in the same order
!>          that they appear on the diagonal of the output Schur form T.
!>          Complex conjugate pairs of eigenvalues will appear
!>          consecutively with the eigenvalue having the positive
!>          imaginary part first.
!> 
[out]VS
!>          VS is DOUBLE PRECISION array, dimension (LDVS,N)
!>          If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur
!>          vectors.
!>          If JOBVS = 'N', VS is not referenced.
!> 
[in]LDVS
!>          LDVS is INTEGER
!>          The leading dimension of the array VS.  LDVS >= 1; if
!>          JOBVS = 'V', LDVS >= N.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) contains the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK.  LWORK >= max(1,3*N).
!>          For good performance, LWORK must generally be larger.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]BWORK
!>          BWORK is LOGICAL array, dimension (N)
!>          Not referenced if SORT = 'N'.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0: successful exit
!>          < 0: if INFO = -i, the i-th argument had an illegal value.
!>          > 0: if INFO = i, and i is
!>             <= N: the QR algorithm failed to compute all the
!>                   eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI
!>                   contain those eigenvalues which have converged; if
!>                   JOBVS = 'V', VS contains the matrix which reduces A
!>                   to its partially converged Schur form.
!>             = N+1: the eigenvalues could not be reordered because some
!>                   eigenvalues were too close to separate (the problem
!>                   is very ill-conditioned);
!>             = N+2: after reordering, roundoff changed values of some
!>                   complex eigenvalues so that leading eigenvalues in
!>                   the Schur form no longer satisfy SELECT=.TRUE.  This
!>                   could also be caused by underflow due to scaling.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 212 of file dgees.f.

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*
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 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
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
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
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
double precision function dlange(norm, m, n, a, lda, work)
DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
Definition dlange.f:112
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
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
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
Here is the call graph for this function:
Here is the caller graph for this function: