1 *> \brief <b> CGEES computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CGEES + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgees.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgees.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgees.f">
21 * SUBROUTINE CGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, W, VS,
22 * LDVS, WORK, LWORK, RWORK, BWORK, INFO )
24 * .. Scalar Arguments ..
25 * CHARACTER JOBVS, SORT
26 * INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
28 * .. Array Arguments ..
31 * COMPLEX A( LDA, * ), VS( LDVS, * ), W( * ), WORK( * )
33 * .. Function Arguments ..
44 *> CGEES computes for an N-by-N complex nonsymmetric matrix A, the
45 *> eigenvalues, the Schur form T, and, optionally, the matrix of Schur
46 *> vectors Z. This gives the Schur factorization A = Z*T*(Z**H).
48 *> Optionally, it also orders the eigenvalues on the diagonal of the
49 *> Schur form so that selected eigenvalues are at the top left.
50 *> The leading columns of Z then form an orthonormal basis for the
51 *> invariant subspace corresponding to the selected eigenvalues.
53 *> A complex matrix is in Schur form if it is upper triangular.
61 *> JOBVS is CHARACTER*1
62 *> = 'N': Schur vectors are not computed;
63 *> = 'V': Schur vectors are computed.
68 *> SORT is CHARACTER*1
69 *> Specifies whether or not to order the eigenvalues on the
70 *> diagonal of the Schur form.
71 *> = 'N': Eigenvalues are not ordered:
72 *> = 'S': Eigenvalues are ordered (see SELECT).
77 *> SELECT is a LOGICAL FUNCTION of one COMPLEX argument
78 *> SELECT must be declared EXTERNAL in the calling subroutine.
79 *> If SORT = 'S', SELECT is used to select eigenvalues to order
80 *> to the top left of the Schur form.
81 *> IF SORT = 'N', SELECT is not referenced.
82 *> The eigenvalue W(j) is selected if SELECT(W(j)) is true.
88 *> The order of the matrix A. N >= 0.
93 *> A is COMPLEX array, dimension (LDA,N)
94 *> On entry, the N-by-N matrix A.
95 *> On exit, A has been overwritten by its Schur form T.
101 *> The leading dimension of the array A. LDA >= max(1,N).
107 *> If SORT = 'N', SDIM = 0.
108 *> If SORT = 'S', SDIM = number of eigenvalues for which
114 *> W is COMPLEX array, dimension (N)
115 *> W contains the computed eigenvalues, in the same order that
116 *> they appear on the diagonal of the output Schur form T.
121 *> VS is COMPLEX array, dimension (LDVS,N)
122 *> If JOBVS = 'V', VS contains the unitary matrix Z of Schur
124 *> If JOBVS = 'N', VS is not referenced.
130 *> The leading dimension of the array VS. LDVS >= 1; if
131 *> JOBVS = 'V', LDVS >= N.
136 *> WORK is COMPLEX array, dimension (MAX(1,LWORK))
137 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
143 *> The dimension of the array WORK. LWORK >= max(1,2*N).
144 *> For good performance, LWORK must generally be larger.
146 *> If LWORK = -1, then a workspace query is assumed; the routine
147 *> only calculates the optimal size of the WORK array, returns
148 *> this value as the first entry of the WORK array, and no error
149 *> message related to LWORK is issued by XERBLA.
154 *> RWORK is REAL array, dimension (N)
159 *> BWORK is LOGICAL array, dimension (N)
160 *> Not referenced if SORT = 'N'.
166 *> = 0: successful exit
167 *> < 0: if INFO = -i, the i-th argument had an illegal value.
168 *> > 0: if INFO = i, and i is
169 *> <= N: the QR algorithm failed to compute all the
170 *> eigenvalues; elements 1:ILO-1 and i+1:N of W
171 *> contain those eigenvalues which have converged;
172 *> if JOBVS = 'V', VS contains the matrix which
173 *> reduces A to its partially converged Schur form.
174 *> = N+1: the eigenvalues could not be reordered because
175 *> some eigenvalues were too close to separate (the
176 *> problem is very ill-conditioned);
177 *> = N+2: after reordering, roundoff changed values of
178 *> some complex eigenvalues so that leading
179 *> eigenvalues in the Schur form no longer satisfy
180 *> SELECT = .TRUE.. This could also be caused by
181 *> underflow due to scaling.
187 *> \author Univ. of Tennessee
188 *> \author Univ. of California Berkeley
189 *> \author Univ. of Colorado Denver
192 *> \date November 2011
194 *> \ingroup complexGEeigen
196 * =====================================================================
197 SUBROUTINE CGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, W, VS,
198 $ LDVS, WORK, LWORK, RWORK, BWORK, INFO )
200 * -- LAPACK driver routine (version 3.4.0) --
201 * -- LAPACK is a software package provided by Univ. of Tennessee, --
202 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
205 * .. Scalar Arguments ..
206 CHARACTER JOBVS, SORT
207 INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
209 * .. Array Arguments ..
212 COMPLEX A( LDA, * ), VS( LDVS, * ), W( * ), WORK( * )
214 * .. Function Arguments ..
219 * =====================================================================
223 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
225 * .. Local Scalars ..
226 LOGICAL LQUERY, SCALEA, WANTST, WANTVS
227 INTEGER HSWORK, I, IBAL, ICOND, IERR, IEVAL, IHI, ILO,
228 $ ITAU, IWRK, MAXWRK, MINWRK
229 REAL ANRM, BIGNUM, CSCALE, EPS, S, SEP, SMLNUM
234 * .. External Subroutines ..
235 EXTERNAL CCOPY, CGEBAK, CGEBAL, CGEHRD, CHSEQR, CLACPY,
236 $ CLASCL, CTRSEN, CUNGHR, SLABAD, XERBLA
238 * .. External Functions ..
242 EXTERNAL LSAME, ILAENV, CLANGE, SLAMCH
244 * .. Intrinsic Functions ..
247 * .. Executable Statements ..
249 * Test the input arguments
252 LQUERY = ( LWORK.EQ.-1 )
253 WANTVS = LSAME( JOBVS, 'V' )
254 WANTST = LSAME( SORT, 'S' )
255 IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
257 ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
259 ELSE IF( N.LT.0 ) THEN
261 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
263 ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
268 * (Note: Comments in the code beginning "Workspace:" describe the
269 * minimal amount of workspace needed at that point in the code,
270 * as well as the preferred amount for good performance.
271 * CWorkspace refers to complex workspace, and RWorkspace to real
272 * workspace. NB refers to the optimal block size for the
273 * immediately following subroutine, as returned by ILAENV.
274 * HSWORK refers to the workspace preferred by CHSEQR, as
275 * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
283 MAXWRK = N + N*ILAENV( 1, 'CGEHRD', ' ', N, 1, N, 0 )
286 CALL CHSEQR( 'S', JOBVS, N, 1, N, A, LDA, W, VS, LDVS,
290 IF( .NOT.WANTVS ) THEN
291 MAXWRK = MAX( MAXWRK, HSWORK )
293 MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'CUNGHR',
294 $ ' ', N, 1, N, -1 ) )
295 MAXWRK = MAX( MAXWRK, HSWORK )
300 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
306 CALL XERBLA( 'CGEES ', -INFO )
308 ELSE IF( LQUERY ) THEN
312 * Quick return if possible
319 * Get machine constants
322 SMLNUM = SLAMCH( 'S' )
323 BIGNUM = ONE / SMLNUM
324 CALL SLABAD( SMLNUM, BIGNUM )
325 SMLNUM = SQRT( SMLNUM ) / EPS
326 BIGNUM = ONE / SMLNUM
328 * Scale A if max element outside range [SMLNUM,BIGNUM]
330 ANRM = CLANGE( 'M', N, N, A, LDA, DUM )
332 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
335 ELSE IF( ANRM.GT.BIGNUM ) THEN
340 $ CALL CLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
342 * Permute the matrix to make it more nearly triangular
344 * (RWorkspace: need N)
347 CALL CGEBAL( 'P', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
349 * Reduce to upper Hessenberg form
350 * (CWorkspace: need 2*N, prefer N+N*NB)
355 CALL CGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
356 $ LWORK-IWRK+1, IERR )
360 * Copy Householder vectors to VS
362 CALL CLACPY( 'L', N, N, A, LDA, VS, LDVS )
364 * Generate unitary matrix in VS
365 * (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
368 CALL CUNGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
369 $ LWORK-IWRK+1, IERR )
374 * Perform QR iteration, accumulating Schur vectors in VS if desired
375 * (CWorkspace: need 1, prefer HSWORK (see comments) )
379 CALL CHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, W, VS, LDVS,
380 $ WORK( IWRK ), LWORK-IWRK+1, IEVAL )
384 * Sort eigenvalues if desired
386 IF( WANTST .AND. INFO.EQ.0 ) THEN
388 $ CALL CLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, W, N, IERR )
390 BWORK( I ) = SELECT( W( I ) )
393 * Reorder eigenvalues and transform Schur vectors
397 CALL CTRSEN( 'N', JOBVS, BWORK, N, A, LDA, VS, LDVS, W, SDIM,
398 $ S, SEP, WORK( IWRK ), LWORK-IWRK+1, ICOND )
405 * (RWorkspace: need N)
407 CALL CGEBAK( 'P', 'R', N, ILO, IHI, RWORK( IBAL ), N, VS, LDVS,
413 * Undo scaling for the Schur form of A
415 CALL CLASCL( 'U', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
416 CALL CCOPY( N, A, LDA+1, W, 1 )