Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/lapack/cgees.f
5192 views
1
SUBROUTINE CGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, W, VS,
2
$ LDVS, WORK, LWORK, RWORK, BWORK, 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
* June 30, 1999
8
*
9
* .. Scalar Arguments ..
10
CHARACTER JOBVS, SORT
11
INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
12
* ..
13
* .. Array Arguments ..
14
LOGICAL BWORK( * )
15
REAL RWORK( * )
16
COMPLEX A( LDA, * ), VS( LDVS, * ), W( * ), WORK( * )
17
* ..
18
* .. Function Arguments ..
19
LOGICAL SELECT
20
EXTERNAL SELECT
21
* ..
22
*
23
* Purpose
24
* =======
25
*
26
* CGEES computes for an N-by-N complex nonsymmetric matrix A, the
27
* eigenvalues, the Schur form T, and, optionally, the matrix of Schur
28
* vectors Z. This gives the Schur factorization A = Z*T*(Z**H).
29
*
30
* Optionally, it also orders the eigenvalues on the diagonal of the
31
* Schur form so that selected eigenvalues are at the top left.
32
* The leading columns of Z then form an orthonormal basis for the
33
* invariant subspace corresponding to the selected eigenvalues.
34
35
* A complex matrix is in Schur form if it is upper triangular.
36
*
37
* Arguments
38
* =========
39
*
40
* JOBVS (input) CHARACTER*1
41
* = 'N': Schur vectors are not computed;
42
* = 'V': Schur vectors are computed.
43
*
44
* SORT (input) CHARACTER*1
45
* Specifies whether or not to order the eigenvalues on the
46
* diagonal of the Schur form.
47
* = 'N': Eigenvalues are not ordered:
48
* = 'S': Eigenvalues are ordered (see SELECT).
49
*
50
* SELECT (input) LOGICAL FUNCTION of one COMPLEX argument
51
* SELECT must be declared EXTERNAL in the calling subroutine.
52
* If SORT = 'S', SELECT is used to select eigenvalues to order
53
* to the top left of the Schur form.
54
* IF SORT = 'N', SELECT is not referenced.
55
* The eigenvalue W(j) is selected if SELECT(W(j)) is true.
56
*
57
* N (input) INTEGER
58
* The order of the matrix A. N >= 0.
59
*
60
* A (input/output) COMPLEX array, dimension (LDA,N)
61
* On entry, the N-by-N matrix A.
62
* On exit, A has been overwritten by its Schur form T.
63
*
64
* LDA (input) INTEGER
65
* The leading dimension of the array A. LDA >= max(1,N).
66
*
67
* SDIM (output) INTEGER
68
* If SORT = 'N', SDIM = 0.
69
* If SORT = 'S', SDIM = number of eigenvalues for which
70
* SELECT is true.
71
*
72
* W (output) COMPLEX array, dimension (N)
73
* W contains the computed eigenvalues, in the same order that
74
* they appear on the diagonal of the output Schur form T.
75
*
76
* VS (output) COMPLEX array, dimension (LDVS,N)
77
* If JOBVS = 'V', VS contains the unitary matrix Z of Schur
78
* vectors.
79
* If JOBVS = 'N', VS is not referenced.
80
*
81
* LDVS (input) INTEGER
82
* The leading dimension of the array VS. LDVS >= 1; if
83
* JOBVS = 'V', LDVS >= N.
84
*
85
* WORK (workspace/output) COMPLEX array, dimension (LWORK)
86
* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
87
*
88
* LWORK (input) INTEGER
89
* The dimension of the array WORK. LWORK >= max(1,2*N).
90
* For good performance, LWORK must generally be larger.
91
*
92
* If LWORK = -1, then a workspace query is assumed; the routine
93
* only calculates the optimal size of the WORK array, returns
94
* this value as the first entry of the WORK array, and no error
95
* message related to LWORK is issued by XERBLA.
96
*
97
* RWORK (workspace) REAL array, dimension (N)
98
*
99
* BWORK (workspace) LOGICAL array, dimension (N)
100
* Not referenced if SORT = 'N'.
101
*
102
* INFO (output) INTEGER
103
* = 0: successful exit
104
* < 0: if INFO = -i, the i-th argument had an illegal value.
105
* > 0: if INFO = i, and i is
106
* <= N: the QR algorithm failed to compute all the
107
* eigenvalues; elements 1:ILO-1 and i+1:N of W
108
* contain those eigenvalues which have converged;
109
* if JOBVS = 'V', VS contains the matrix which
110
* reduces A to its partially converged Schur form.
111
* = N+1: the eigenvalues could not be reordered because
112
* some eigenvalues were too close to separate (the
113
* problem is very ill-conditioned);
114
* = N+2: after reordering, roundoff changed values of
115
* some complex eigenvalues so that leading
116
* eigenvalues in the Schur form no longer satisfy
117
* SELECT = .TRUE.. This could also be caused by
118
* underflow due to scaling.
119
*
120
* =====================================================================
121
*
122
* .. Parameters ..
123
REAL ZERO, ONE
124
PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
125
* ..
126
* .. Local Scalars ..
127
LOGICAL LQUERY, SCALEA, WANTST, WANTVS
128
INTEGER HSWORK, I, IBAL, ICOND, IERR, IEVAL, IHI, ILO,
129
$ ITAU, IWRK, K, MAXB, MAXWRK, MINWRK
130
REAL ANRM, BIGNUM, CSCALE, EPS, S, SEP, SMLNUM
131
* ..
132
* .. Local Arrays ..
133
REAL DUM( 1 )
134
* ..
135
* .. External Subroutines ..
136
EXTERNAL CCOPY, CGEBAK, CGEBAL, CGEHRD, CHSEQR, CLACPY,
137
$ CLASCL, CTRSEN, CUNGHR, SLABAD, XERBLA
138
* ..
139
* .. External Functions ..
140
LOGICAL LSAME
141
INTEGER ILAENV
142
REAL CLANGE, SLAMCH
143
EXTERNAL LSAME, ILAENV, CLANGE, SLAMCH
144
* ..
145
* .. Intrinsic Functions ..
146
INTRINSIC MAX, MIN, SQRT
147
* ..
148
* .. Executable Statements ..
149
*
150
* Test the input arguments
151
*
152
INFO = 0
153
LQUERY = ( LWORK.EQ.-1 )
154
WANTVS = LSAME( JOBVS, 'V' )
155
WANTST = LSAME( SORT, 'S' )
156
IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
157
INFO = -1
158
ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
159
INFO = -2
160
ELSE IF( N.LT.0 ) THEN
161
INFO = -4
162
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
163
INFO = -6
164
ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
165
INFO = -10
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
* CWorkspace refers to complex workspace, and RWorkspace to real
173
* workspace. NB refers to the optimal block size for the
174
* immediately following subroutine, as returned by ILAENV.
175
* HSWORK refers to the workspace preferred by CHSEQR, as
176
* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
177
* the worst case.)
178
*
179
MINWRK = 1
180
IF( INFO.EQ.0 .AND. ( LWORK.GE.1 .OR. LQUERY ) ) THEN
181
MAXWRK = N + N*ILAENV( 1, 'CGEHRD', ' ', N, 1, N, 0 )
182
MINWRK = MAX( 1, 2*N )
183
IF( .NOT.WANTVS ) THEN
184
MAXB = MAX( ILAENV( 8, 'CHSEQR', 'SN', N, 1, N, -1 ), 2 )
185
K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'CHSEQR', 'SN', N, 1,
186
$ N, -1 ) ) )
187
HSWORK = MAX( K*( K+2 ), 2*N )
188
MAXWRK = MAX( MAXWRK, HSWORK, 1 )
189
ELSE
190
MAXWRK = MAX( MAXWRK, N+( N-1 )*
191
$ ILAENV( 1, 'CUNGHR', ' ', N, 1, N, -1 ) )
192
MAXB = MAX( ILAENV( 8, 'CHSEQR', 'EN', N, 1, N, -1 ), 2 )
193
K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'CHSEQR', 'EN', N, 1,
194
$ N, -1 ) ) )
195
HSWORK = MAX( K*( K+2 ), 2*N )
196
MAXWRK = MAX( MAXWRK, HSWORK, 1 )
197
END IF
198
WORK( 1 ) = MAXWRK
199
END IF
200
IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
201
INFO = -12
202
END IF
203
IF( INFO.NE.0 ) THEN
204
CALL XERBLA( 'CGEES ', -INFO )
205
RETURN
206
ELSE IF( LQUERY ) THEN
207
RETURN
208
END IF
209
*
210
* Quick return if possible
211
*
212
IF( N.EQ.0 ) THEN
213
SDIM = 0
214
RETURN
215
END IF
216
*
217
* Get machine constants
218
*
219
EPS = SLAMCH( 'P' )
220
SMLNUM = SLAMCH( 'S' )
221
BIGNUM = ONE / SMLNUM
222
CALL SLABAD( SMLNUM, BIGNUM )
223
SMLNUM = SQRT( SMLNUM ) / EPS
224
BIGNUM = ONE / SMLNUM
225
*
226
* Scale A if max element outside range [SMLNUM,BIGNUM]
227
*
228
ANRM = CLANGE( 'M', N, N, A, LDA, DUM )
229
SCALEA = .FALSE.
230
IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
231
SCALEA = .TRUE.
232
CSCALE = SMLNUM
233
ELSE IF( ANRM.GT.BIGNUM ) THEN
234
SCALEA = .TRUE.
235
CSCALE = BIGNUM
236
END IF
237
IF( SCALEA )
238
$ CALL CLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
239
*
240
* Permute the matrix to make it more nearly triangular
241
* (CWorkspace: none)
242
* (RWorkspace: need N)
243
*
244
IBAL = 1
245
CALL CGEBAL( 'P', N, A, LDA, ILO, IHI, RWORK( IBAL ), IERR )
246
*
247
* Reduce to upper Hessenberg form
248
* (CWorkspace: need 2*N, prefer N+N*NB)
249
* (RWorkspace: none)
250
*
251
ITAU = 1
252
IWRK = N + ITAU
253
CALL CGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
254
$ LWORK-IWRK+1, IERR )
255
*
256
IF( WANTVS ) THEN
257
*
258
* Copy Householder vectors to VS
259
*
260
CALL CLACPY( 'L', N, N, A, LDA, VS, LDVS )
261
*
262
* Generate unitary matrix in VS
263
* (CWorkspace: need 2*N-1, prefer N+(N-1)*NB)
264
* (RWorkspace: none)
265
*
266
CALL CUNGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
267
$ LWORK-IWRK+1, IERR )
268
END IF
269
*
270
SDIM = 0
271
*
272
* Perform QR iteration, accumulating Schur vectors in VS if desired
273
* (CWorkspace: need 1, prefer HSWORK (see comments) )
274
* (RWorkspace: none)
275
*
276
IWRK = ITAU
277
CALL CHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, W, VS, LDVS,
278
$ WORK( IWRK ), LWORK-IWRK+1, IEVAL )
279
IF( IEVAL.GT.0 )
280
$ INFO = IEVAL
281
*
282
* Sort eigenvalues if desired
283
*
284
IF( WANTST .AND. INFO.EQ.0 ) THEN
285
IF( SCALEA )
286
$ CALL CLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, W, N, IERR )
287
DO 10 I = 1, N
288
BWORK( I ) = SELECT( W( I ) )
289
10 CONTINUE
290
*
291
* Reorder eigenvalues and transform Schur vectors
292
* (CWorkspace: none)
293
* (RWorkspace: none)
294
*
295
CALL CTRSEN( 'N', JOBVS, BWORK, N, A, LDA, VS, LDVS, W, SDIM,
296
$ S, SEP, WORK( IWRK ), LWORK-IWRK+1, ICOND )
297
END IF
298
*
299
IF( WANTVS ) THEN
300
*
301
* Undo balancing
302
* (CWorkspace: none)
303
* (RWorkspace: need N)
304
*
305
CALL CGEBAK( 'P', 'R', N, ILO, IHI, RWORK( IBAL ), N, VS, LDVS,
306
$ IERR )
307
END IF
308
*
309
IF( SCALEA ) THEN
310
*
311
* Undo scaling for the Schur form of A
312
*
313
CALL CLASCL( 'U', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
314
CALL CCOPY( N, A, LDA+1, W, 1 )
315
END IF
316
*
317
WORK( 1 ) = MAXWRK
318
RETURN
319
*
320
* End of CGEES
321
*
322
END
323
324