1 *> \brief <b> SGEESX 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 SGEESX + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sgeesx.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sgeesx.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sgeesx.f">
21 * SUBROUTINE SGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,
22 * WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,
23 * IWORK, LIWORK, BWORK, INFO )
25 * .. Scalar Arguments ..
26 * CHARACTER JOBVS, SENSE, SORT
27 * INTEGER INFO, LDA, LDVS, LIWORK, LWORK, N, SDIM
30 * .. Array Arguments ..
33 * REAL A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
36 * .. Function Arguments ..
47 *> SGEESX computes for an N-by-N real nonsymmetric matrix A, the
48 *> eigenvalues, the real Schur form T, and, optionally, the matrix of
49 *> Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).
51 *> Optionally, it also orders the eigenvalues on the diagonal of the
52 *> real Schur form so that selected eigenvalues are at the top left;
53 *> computes a reciprocal condition number for the average of the
54 *> selected eigenvalues (RCONDE); and computes a reciprocal condition
55 *> number for the right invariant subspace corresponding to the
56 *> selected eigenvalues (RCONDV). The leading columns of Z form an
57 *> orthonormal basis for this invariant subspace.
59 *> For further explanation of the reciprocal condition numbers RCONDE
60 *> and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where
61 *> these quantities are called s and sep respectively).
63 *> A real matrix is in real Schur form if it is upper quasi-triangular
64 *> with 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in
69 *> where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).
77 *> JOBVS is CHARACTER*1
78 *> = 'N': Schur vectors are not computed;
79 *> = 'V': Schur vectors are computed.
84 *> SORT is CHARACTER*1
85 *> Specifies whether or not to order the eigenvalues on the
86 *> diagonal of the Schur form.
87 *> = 'N': Eigenvalues are not ordered;
88 *> = 'S': Eigenvalues are ordered (see SELECT).
93 *> SELECT is a LOGICAL FUNCTION of two REAL arguments
94 *> SELECT must be declared EXTERNAL in the calling subroutine.
95 *> If SORT = 'S', SELECT is used to select eigenvalues to sort
96 *> to the top left of the Schur form.
97 *> If SORT = 'N', SELECT is not referenced.
98 *> An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if
99 *> SELECT(WR(j),WI(j)) is true; i.e., if either one of a
100 *> complex conjugate pair of eigenvalues is selected, then both
101 *> are. Note that a selected complex eigenvalue may no longer
102 *> satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since
103 *> ordering may change the value of complex eigenvalues
104 *> (especially if the eigenvalue is ill-conditioned); in this
105 *> case INFO may be set to N+3 (see INFO below).
110 *> SENSE is CHARACTER*1
111 *> Determines which reciprocal condition numbers are computed.
112 *> = 'N': None are computed;
113 *> = 'E': Computed for average of selected eigenvalues only;
114 *> = 'V': Computed for selected right invariant subspace only;
115 *> = 'B': Computed for both.
116 *> If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.
122 *> The order of the matrix A. N >= 0.
127 *> A is REAL array, dimension (LDA, N)
128 *> On entry, the N-by-N matrix A.
129 *> On exit, A is overwritten by its real Schur form T.
135 *> The leading dimension of the array A. LDA >= max(1,N).
141 *> If SORT = 'N', SDIM = 0.
142 *> If SORT = 'S', SDIM = number of eigenvalues (after sorting)
143 *> for which SELECT is true. (Complex conjugate
144 *> pairs for which SELECT is true for either
145 *> eigenvalue count as 2.)
150 *> WR is REAL array, dimension (N)
155 *> WI is REAL array, dimension (N)
156 *> WR and WI contain the real and imaginary parts, respectively,
157 *> of the computed eigenvalues, in the same order that they
158 *> appear on the diagonal of the output Schur form T. Complex
159 *> conjugate pairs of eigenvalues appear consecutively with the
160 *> eigenvalue having the positive imaginary part first.
165 *> VS is REAL array, dimension (LDVS,N)
166 *> If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur
168 *> If JOBVS = 'N', VS is not referenced.
174 *> The leading dimension of the array VS. LDVS >= 1, and if
175 *> JOBVS = 'V', LDVS >= N.
178 *> \param[out] RCONDE
181 *> If SENSE = 'E' or 'B', RCONDE contains the reciprocal
182 *> condition number for the average of the selected eigenvalues.
183 *> Not referenced if SENSE = 'N' or 'V'.
186 *> \param[out] RCONDV
189 *> If SENSE = 'V' or 'B', RCONDV contains the reciprocal
190 *> condition number for the selected right invariant subspace.
191 *> Not referenced if SENSE = 'N' or 'E'.
196 *> WORK is REAL array, dimension (MAX(1,LWORK))
197 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
203 *> The dimension of the array WORK. LWORK >= max(1,3*N).
204 *> Also, if SENSE = 'E' or 'V' or 'B',
205 *> LWORK >= N+2*SDIM*(N-SDIM), where SDIM is the number of
206 *> selected eigenvalues computed by this routine. Note that
207 *> N+2*SDIM*(N-SDIM) <= N+N*N/2. Note also that an error is only
208 *> returned if LWORK < max(1,3*N), but if SENSE = 'E' or 'V' or
209 *> 'B' this may not be large enough.
210 *> For good performance, LWORK must generally be larger.
212 *> If LWORK = -1, then a workspace query is assumed; the routine
213 *> only calculates upper bounds on the optimal sizes of the
214 *> arrays WORK and IWORK, returns these values as the first
215 *> entries of the WORK and IWORK arrays, and no error messages
216 *> related to LWORK or LIWORK are issued by XERBLA.
221 *> IWORK is INTEGER array, dimension (MAX(1,LIWORK))
222 *> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
228 *> The dimension of the array IWORK.
229 *> LIWORK >= 1; if SENSE = 'V' or 'B', LIWORK >= SDIM*(N-SDIM).
230 *> Note that SDIM*(N-SDIM) <= N*N/4. Note also that an error is
231 *> only returned if LIWORK < 1, but if SENSE = 'V' or 'B' this
232 *> may not be large enough.
234 *> If LIWORK = -1, then a workspace query is assumed; the
235 *> routine only calculates upper bounds on the optimal sizes of
236 *> the arrays WORK and IWORK, returns these values as the first
237 *> entries of the WORK and IWORK arrays, and no error messages
238 *> related to LWORK or LIWORK are issued by XERBLA.
243 *> BWORK is LOGICAL array, dimension (N)
244 *> Not referenced if SORT = 'N'.
250 *> = 0: successful exit
251 *> < 0: if INFO = -i, the i-th argument had an illegal value.
252 *> > 0: if INFO = i, and i is
253 *> <= N: the QR algorithm failed to compute all the
254 *> eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI
255 *> contain those eigenvalues which have converged; if
256 *> JOBVS = 'V', VS contains the transformation which
257 *> reduces A to its partially converged Schur form.
258 *> = N+1: the eigenvalues could not be reordered because some
259 *> eigenvalues were too close to separate (the problem
260 *> is very ill-conditioned);
261 *> = N+2: after reordering, roundoff changed values of some
262 *> complex eigenvalues so that leading eigenvalues in
263 *> the Schur form no longer satisfy SELECT=.TRUE. This
264 *> could also be caused by underflow due to scaling.
270 *> \author Univ. of Tennessee
271 *> \author Univ. of California Berkeley
272 *> \author Univ. of Colorado Denver
277 *> \ingroup realGEeigen
279 * =====================================================================
280 SUBROUTINE SGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,
281 $ WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,
282 $ IWORK, LIWORK, BWORK, INFO )
284 * -- LAPACK driver routine (version 3.6.1) --
285 * -- LAPACK is a software package provided by Univ. of Tennessee, --
286 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
289 * .. Scalar Arguments ..
290 CHARACTER JOBVS, SENSE, SORT
291 INTEGER INFO, LDA, LDVS, LIWORK, LWORK, N, SDIM
294 * .. Array Arguments ..
297 REAL A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
300 * .. Function Arguments ..
305 * =====================================================================
309 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
311 * .. Local Scalars ..
312 LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTSB,
313 $ WANTSE, WANTSN, WANTST, WANTSV, WANTVS
314 INTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,
315 $ IHI, ILO, INXT, IP, ITAU, IWRK, LWRK, LIWRK,
317 REAL ANRM, BIGNUM, CSCALE, EPS, SMLNUM
322 * .. External Subroutines ..
323 EXTERNAL SCOPY, SGEBAK, SGEBAL, SGEHRD, SHSEQR, SLABAD,
324 $ SLACPY, SLASCL, SORGHR, SSWAP, STRSEN, XERBLA
326 * .. External Functions ..
330 EXTERNAL LSAME, ILAENV, SLAMCH, SLANGE
332 * .. Intrinsic Functions ..
335 * .. Executable Statements ..
337 * Test the input arguments
340 WANTVS = LSAME( JOBVS, 'V' )
341 WANTST = LSAME( SORT, 'S' )
342 WANTSN = LSAME( SENSE, 'N' )
343 WANTSE = LSAME( SENSE, 'E' )
344 WANTSV = LSAME( SENSE, 'V' )
345 WANTSB = LSAME( SENSE, 'B' )
346 LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
348 IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
350 ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
352 ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
353 $ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
355 ELSE IF( N.LT.0 ) THEN
357 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
359 ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
364 * (Note: Comments in the code beginning "RWorkspace:" describe the
365 * minimal amount of real workspace needed at that point in the
366 * code, as well as the preferred amount for good performance.
367 * IWorkspace refers to integer workspace.
368 * NB refers to the optimal block size for the immediately
369 * following subroutine, as returned by ILAENV.
370 * HSWORK refers to the workspace preferred by SHSEQR, as
371 * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
373 * If SENSE = 'E', 'V' or 'B', then the amount of workspace needed
374 * depends on SDIM, which is computed by the routine STRSEN later
383 MAXWRK = 2*N + N*ILAENV( 1, 'SGEHRD', ' ', N, 1, N, 0 )
386 CALL SHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,
390 IF( .NOT.WANTVS ) THEN
391 MAXWRK = MAX( MAXWRK, N + HSWORK )
393 MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
394 $ 'SORGHR', ' ', N, 1, N, -1 ) )
395 MAXWRK = MAX( MAXWRK, N + HSWORK )
399 $ LWRK = MAX( LWRK, N + ( N*N )/2 )
400 IF( WANTSV .OR. WANTSB )
406 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
408 ELSE IF( LIWORK.LT.1 .AND. .NOT.LQUERY ) THEN
414 CALL XERBLA( 'SGEESX', -INFO )
416 ELSE IF( LQUERY ) THEN
420 * Quick return if possible
427 * Get machine constants
430 SMLNUM = SLAMCH( 'S' )
431 BIGNUM = ONE / SMLNUM
432 CALL SLABAD( SMLNUM, BIGNUM )
433 SMLNUM = SQRT( SMLNUM ) / EPS
434 BIGNUM = ONE / SMLNUM
436 * Scale A if max element outside range [SMLNUM,BIGNUM]
438 ANRM = SLANGE( 'M', N, N, A, LDA, DUM )
440 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
443 ELSE IF( ANRM.GT.BIGNUM ) THEN
448 $ CALL SLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
450 * Permute the matrix to make it more nearly triangular
451 * (RWorkspace: need N)
454 CALL SGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
456 * Reduce to upper Hessenberg form
457 * (RWorkspace: need 3*N, prefer 2*N+N*NB)
461 CALL SGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
462 $ LWORK-IWRK+1, IERR )
466 * Copy Householder vectors to VS
468 CALL SLACPY( 'L', N, N, A, LDA, VS, LDVS )
470 * Generate orthogonal matrix in VS
471 * (RWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
473 CALL SORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
474 $ LWORK-IWRK+1, IERR )
479 * Perform QR iteration, accumulating Schur vectors in VS if desired
480 * (RWorkspace: need N+1, prefer N+HSWORK (see comments) )
483 CALL SHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,
484 $ WORK( IWRK ), LWORK-IWRK+1, IEVAL )
488 * Sort eigenvalues if desired
490 IF( WANTST .AND. INFO.EQ.0 ) THEN
492 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )
493 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )
496 BWORK( I ) = SELECT( WR( I ), WI( I ) )
499 * Reorder eigenvalues, transform Schur vectors, and compute
500 * reciprocal condition numbers
501 * (RWorkspace: if SENSE is not 'N', need N+2*SDIM*(N-SDIM)
502 * otherwise, need N )
503 * (IWorkspace: if SENSE is 'V' or 'B', need SDIM*(N-SDIM)
504 * otherwise, need 0 )
506 CALL STRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,
507 $ SDIM, RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,
508 $ IWORK, LIWORK, ICOND )
510 $ MAXWRK = MAX( MAXWRK, N+2*SDIM*( N-SDIM ) )
511 IF( ICOND.EQ.-15 ) THEN
513 * Not enough real workspace
516 ELSE IF( ICOND.EQ.-17 ) THEN
518 * Not enough integer workspace
521 ELSE IF( ICOND.GT.0 ) THEN
523 * STRSEN failed to reorder or to restore standard Schur form
532 * (RWorkspace: need N)
534 CALL SGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,
540 * Undo scaling for the Schur form of A
542 CALL SLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
543 CALL SCOPY( N, A, LDA+1, WR, 1 )
544 IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THEN
546 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
549 IF( CSCALE.EQ.SMLNUM ) THEN
551 * If scaling back towards underflow, adjust WI if an
552 * offdiagonal element of a 2-by-2 block in the Schur form
555 IF( IEVAL.GT.0 ) THEN
558 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
560 ELSE IF( WANTST ) THEN
571 IF( WI( I ).EQ.ZERO ) THEN
574 IF( A( I+1, I ).EQ.ZERO ) THEN
577 ELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.
582 $ CALL SSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )
584 $ CALL SSWAP( N-I-1, A( I, I+2 ), LDA,
585 $ A( I+1, I+2 ), LDA )
586 CALL SSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )
587 A( I, I+1 ) = A( I+1, I )
594 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,
595 $ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )
598 IF( WANTST .AND. INFO.EQ.0 ) THEN
600 * Check if reordering successful
607 CURSL = SELECT( WR( I ), WI( I ) )
608 IF( WI( I ).EQ.ZERO ) THEN
612 IF( CURSL .AND. .NOT.LASTSL )
617 * Last eigenvalue of conjugate pair
619 CURSL = CURSL .OR. LASTSL
624 IF( CURSL .AND. .NOT.LST2SL )
628 * First eigenvalue of conjugate pair
639 IF( WANTSV .OR. WANTSB ) THEN
640 IWORK( 1 ) = SDIM*(N-SDIM)