Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/lapack/cgegs.f
5198 views
1
SUBROUTINE CGEGS( JOBVSL, JOBVSR, N, A, LDA, B, LDB, ALPHA, BETA,
2
$ VSL, LDVSL, VSR, LDVSR, WORK, LWORK, RWORK,
3
$ INFO )
4
*
5
* -- LAPACK driver routine (version 3.0) --
6
* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
7
* Courant Institute, Argonne National Lab, and Rice University
8
* June 30, 1999
9
*
10
* .. Scalar Arguments ..
11
CHARACTER JOBVSL, JOBVSR
12
INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N
13
* ..
14
* .. Array Arguments ..
15
REAL RWORK( * )
16
COMPLEX A( LDA, * ), ALPHA( * ), B( LDB, * ),
17
$ BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
18
$ WORK( * )
19
* ..
20
*
21
* Purpose
22
* =======
23
*
24
* This routine is deprecated and has been replaced by routine CGGES.
25
*
26
* CGEGS computes for a pair of N-by-N complex nonsymmetric matrices A,
27
* B: the generalized eigenvalues (alpha, beta), the complex Schur
28
* form (A, B), and optionally left and/or right Schur vectors
29
* (VSL and VSR).
30
*
31
* (If only the generalized eigenvalues are needed, use the driver CGEGV
32
* instead.)
33
*
34
* A generalized eigenvalue for a pair of matrices (A,B) is, roughly
35
* speaking, a scalar w or a ratio alpha/beta = w, such that A - w*B
36
* is singular. It is usually represented as the pair (alpha,beta),
37
* as there is a reasonable interpretation for beta=0, and even for
38
* both being zero. A good beginning reference is the book, "Matrix
39
* Computations", by G. Golub & C. van Loan (Johns Hopkins U. Press)
40
*
41
* The (generalized) Schur form of a pair of matrices is the result of
42
* multiplying both matrices on the left by one unitary matrix and
43
* both on the right by another unitary matrix, these two unitary
44
* matrices being chosen so as to bring the pair of matrices into
45
* upper triangular form with the diagonal elements of B being
46
* non-negative real numbers (this is also called complex Schur form.)
47
*
48
* The left and right Schur vectors are the columns of VSL and VSR,
49
* respectively, where VSL and VSR are the unitary matrices
50
* which reduce A and B to Schur form:
51
*
52
* Schur form of (A,B) = ( (VSL)**H A (VSR), (VSL)**H B (VSR) )
53
*
54
* Arguments
55
* =========
56
*
57
* JOBVSL (input) CHARACTER*1
58
* = 'N': do not compute the left Schur vectors;
59
* = 'V': compute the left Schur vectors.
60
*
61
* JOBVSR (input) CHARACTER*1
62
* = 'N': do not compute the right Schur vectors;
63
* = 'V': compute the right Schur vectors.
64
*
65
* N (input) INTEGER
66
* The order of the matrices A, B, VSL, and VSR. N >= 0.
67
*
68
* A (input/output) COMPLEX array, dimension (LDA, N)
69
* On entry, the first of the pair of matrices whose generalized
70
* eigenvalues and (optionally) Schur vectors are to be
71
* computed.
72
* On exit, the generalized Schur form of A.
73
*
74
* LDA (input) INTEGER
75
* The leading dimension of A. LDA >= max(1,N).
76
*
77
* B (input/output) COMPLEX array, dimension (LDB, N)
78
* On entry, the second of the pair of matrices whose
79
* generalized eigenvalues and (optionally) Schur vectors are
80
* to be computed.
81
* On exit, the generalized Schur form of B.
82
*
83
* LDB (input) INTEGER
84
* The leading dimension of B. LDB >= max(1,N).
85
*
86
* ALPHA (output) COMPLEX array, dimension (N)
87
* BETA (output) COMPLEX array, dimension (N)
88
* On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the
89
* generalized eigenvalues. ALPHA(j), j=1,...,N and BETA(j),
90
* j=1,...,N are the diagonals of the complex Schur form (A,B)
91
* output by CGEGS. The BETA(j) will be non-negative real.
92
*
93
* Note: the quotients ALPHA(j)/BETA(j) may easily over- or
94
* underflow, and BETA(j) may even be zero. Thus, the user
95
* should avoid naively computing the ratio alpha/beta.
96
* However, ALPHA will be always less than and usually
97
* comparable with norm(A) in magnitude, and BETA always less
98
* than and usually comparable with norm(B).
99
*
100
* VSL (output) COMPLEX array, dimension (LDVSL,N)
101
* If JOBVSL = 'V', VSL will contain the left Schur vectors.
102
* (See "Purpose", above.)
103
* Not referenced if JOBVSL = 'N'.
104
*
105
* LDVSL (input) INTEGER
106
* The leading dimension of the matrix VSL. LDVSL >= 1, and
107
* if JOBVSL = 'V', LDVSL >= N.
108
*
109
* VSR (output) COMPLEX array, dimension (LDVSR,N)
110
* If JOBVSR = 'V', VSR will contain the right Schur vectors.
111
* (See "Purpose", above.)
112
* Not referenced if JOBVSR = 'N'.
113
*
114
* LDVSR (input) INTEGER
115
* The leading dimension of the matrix VSR. LDVSR >= 1, and
116
* if JOBVSR = 'V', LDVSR >= N.
117
*
118
* WORK (workspace/output) COMPLEX array, dimension (LWORK)
119
* On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
120
*
121
* LWORK (input) INTEGER
122
* The dimension of the array WORK. LWORK >= max(1,2*N).
123
* For good performance, LWORK must generally be larger.
124
* To compute the optimal value of LWORK, call ILAENV to get
125
* blocksizes (for CGEQRF, CUNMQR, and CUNGQR.) Then compute:
126
* NB -- MAX of the blocksizes for CGEQRF, CUNMQR, and CUNGQR;
127
* the optimal LWORK is N*(NB+1).
128
*
129
* If LWORK = -1, then a workspace query is assumed; the routine
130
* only calculates the optimal size of the WORK array, returns
131
* this value as the first entry of the WORK array, and no error
132
* message related to LWORK is issued by XERBLA.
133
*
134
* RWORK (workspace) REAL array, dimension (3*N)
135
*
136
* INFO (output) INTEGER
137
* = 0: successful exit
138
* < 0: if INFO = -i, the i-th argument had an illegal value.
139
* =1,...,N:
140
* The QZ iteration failed. (A,B) are not in Schur
141
* form, but ALPHA(j) and BETA(j) should be correct for
142
* j=INFO+1,...,N.
143
* > N: errors that usually indicate LAPACK problems:
144
* =N+1: error return from CGGBAL
145
* =N+2: error return from CGEQRF
146
* =N+3: error return from CUNMQR
147
* =N+4: error return from CUNGQR
148
* =N+5: error return from CGGHRD
149
* =N+6: error return from CHGEQZ (other than failed
150
* iteration)
151
* =N+7: error return from CGGBAK (computing VSL)
152
* =N+8: error return from CGGBAK (computing VSR)
153
* =N+9: error return from CLASCL (various places)
154
*
155
* =====================================================================
156
*
157
* .. Parameters ..
158
REAL ZERO, ONE
159
PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
160
COMPLEX CZERO, CONE
161
PARAMETER ( CZERO = ( 0.0E0, 0.0E0 ),
162
$ CONE = ( 1.0E0, 0.0E0 ) )
163
* ..
164
* .. Local Scalars ..
165
LOGICAL ILASCL, ILBSCL, ILVSL, ILVSR, LQUERY
166
INTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT,
167
$ ILO, IRIGHT, IROWS, IRWORK, ITAU, IWORK,
168
$ LOPT, LWKMIN, LWKOPT, NB, NB1, NB2, NB3
169
REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
170
$ SAFMIN, SMLNUM
171
* ..
172
* .. External Subroutines ..
173
EXTERNAL CGEQRF, CGGBAK, CGGBAL, CGGHRD, CHGEQZ, CLACPY,
174
$ CLASCL, CLASET, CUNGQR, CUNMQR, XERBLA
175
* ..
176
* .. External Functions ..
177
LOGICAL LSAME
178
INTEGER ILAENV
179
REAL CLANGE, SLAMCH
180
EXTERNAL ILAENV, LSAME, CLANGE, SLAMCH
181
* ..
182
* .. Intrinsic Functions ..
183
INTRINSIC INT, MAX
184
* ..
185
* .. Executable Statements ..
186
*
187
* Decode the input arguments
188
*
189
IF( LSAME( JOBVSL, 'N' ) ) THEN
190
IJOBVL = 1
191
ILVSL = .FALSE.
192
ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
193
IJOBVL = 2
194
ILVSL = .TRUE.
195
ELSE
196
IJOBVL = -1
197
ILVSL = .FALSE.
198
END IF
199
*
200
IF( LSAME( JOBVSR, 'N' ) ) THEN
201
IJOBVR = 1
202
ILVSR = .FALSE.
203
ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
204
IJOBVR = 2
205
ILVSR = .TRUE.
206
ELSE
207
IJOBVR = -1
208
ILVSR = .FALSE.
209
END IF
210
*
211
* Test the input arguments
212
*
213
LWKMIN = MAX( 2*N, 1 )
214
LWKOPT = LWKMIN
215
WORK( 1 ) = LWKOPT
216
LQUERY = ( LWORK.EQ.-1 )
217
INFO = 0
218
IF( IJOBVL.LE.0 ) THEN
219
INFO = -1
220
ELSE IF( IJOBVR.LE.0 ) THEN
221
INFO = -2
222
ELSE IF( N.LT.0 ) THEN
223
INFO = -3
224
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
225
INFO = -5
226
ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
227
INFO = -7
228
ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
229
INFO = -11
230
ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
231
INFO = -13
232
ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
233
INFO = -15
234
END IF
235
*
236
IF( INFO.EQ.0 ) THEN
237
NB1 = ILAENV( 1, 'CGEQRF', ' ', N, N, -1, -1 )
238
NB2 = ILAENV( 1, 'CUNMQR', ' ', N, N, N, -1 )
239
NB3 = ILAENV( 1, 'CUNGQR', ' ', N, N, N, -1 )
240
NB = MAX( NB1, NB2, NB3 )
241
LOPT = N*(NB+1)
242
WORK( 1 ) = LOPT
243
END IF
244
*
245
IF( INFO.NE.0 ) THEN
246
CALL XERBLA( 'CGEGS ', -INFO )
247
RETURN
248
ELSE IF( LQUERY ) THEN
249
RETURN
250
END IF
251
*
252
* Quick return if possible
253
*
254
IF( N.EQ.0 )
255
$ RETURN
256
*
257
* Get machine constants
258
*
259
EPS = SLAMCH( 'E' )*SLAMCH( 'B' )
260
SAFMIN = SLAMCH( 'S' )
261
SMLNUM = N*SAFMIN / EPS
262
BIGNUM = ONE / SMLNUM
263
*
264
* Scale A if max element outside range [SMLNUM,BIGNUM]
265
*
266
ANRM = CLANGE( 'M', N, N, A, LDA, RWORK )
267
ILASCL = .FALSE.
268
IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
269
ANRMTO = SMLNUM
270
ILASCL = .TRUE.
271
ELSE IF( ANRM.GT.BIGNUM ) THEN
272
ANRMTO = BIGNUM
273
ILASCL = .TRUE.
274
END IF
275
*
276
IF( ILASCL ) THEN
277
CALL CLASCL( 'G', -1, -1, ANRM, ANRMTO, N, N, A, LDA, IINFO )
278
IF( IINFO.NE.0 ) THEN
279
INFO = N + 9
280
RETURN
281
END IF
282
END IF
283
*
284
* Scale B if max element outside range [SMLNUM,BIGNUM]
285
*
286
BNRM = CLANGE( 'M', N, N, B, LDB, RWORK )
287
ILBSCL = .FALSE.
288
IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
289
BNRMTO = SMLNUM
290
ILBSCL = .TRUE.
291
ELSE IF( BNRM.GT.BIGNUM ) THEN
292
BNRMTO = BIGNUM
293
ILBSCL = .TRUE.
294
END IF
295
*
296
IF( ILBSCL ) THEN
297
CALL CLASCL( 'G', -1, -1, BNRM, BNRMTO, N, N, B, LDB, IINFO )
298
IF( IINFO.NE.0 ) THEN
299
INFO = N + 9
300
RETURN
301
END IF
302
END IF
303
*
304
* Permute the matrix to make it more nearly triangular
305
*
306
ILEFT = 1
307
IRIGHT = N + 1
308
IRWORK = IRIGHT + N
309
IWORK = 1
310
CALL CGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
311
$ RWORK( IRIGHT ), RWORK( IRWORK ), IINFO )
312
IF( IINFO.NE.0 ) THEN
313
INFO = N + 1
314
GO TO 10
315
END IF
316
*
317
* Reduce B to triangular form, and initialize VSL and/or VSR
318
*
319
IROWS = IHI + 1 - ILO
320
ICOLS = N + 1 - ILO
321
ITAU = IWORK
322
IWORK = ITAU + IROWS
323
CALL CGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
324
$ WORK( IWORK ), LWORK+1-IWORK, IINFO )
325
IF( IINFO.GE.0 )
326
$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
327
IF( IINFO.NE.0 ) THEN
328
INFO = N + 2
329
GO TO 10
330
END IF
331
*
332
CALL CUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
333
$ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
334
$ LWORK+1-IWORK, IINFO )
335
IF( IINFO.GE.0 )
336
$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
337
IF( IINFO.NE.0 ) THEN
338
INFO = N + 3
339
GO TO 10
340
END IF
341
*
342
IF( ILVSL ) THEN
343
CALL CLASET( 'Full', N, N, CZERO, CONE, VSL, LDVSL )
344
CALL CLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
345
$ VSL( ILO+1, ILO ), LDVSL )
346
CALL CUNGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
347
$ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
348
$ IINFO )
349
IF( IINFO.GE.0 )
350
$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
351
IF( IINFO.NE.0 ) THEN
352
INFO = N + 4
353
GO TO 10
354
END IF
355
END IF
356
*
357
IF( ILVSR )
358
$ CALL CLASET( 'Full', N, N, CZERO, CONE, VSR, LDVSR )
359
*
360
* Reduce to generalized Hessenberg form
361
*
362
CALL CGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
363
$ LDVSL, VSR, LDVSR, IINFO )
364
IF( IINFO.NE.0 ) THEN
365
INFO = N + 5
366
GO TO 10
367
END IF
368
*
369
* Perform QZ algorithm, computing Schur vectors if desired
370
*
371
IWORK = ITAU
372
CALL CHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
373
$ ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK( IWORK ),
374
$ LWORK+1-IWORK, RWORK( IRWORK ), IINFO )
375
IF( IINFO.GE.0 )
376
$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
377
IF( IINFO.NE.0 ) THEN
378
IF( IINFO.GT.0 .AND. IINFO.LE.N ) THEN
379
INFO = IINFO
380
ELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THEN
381
INFO = IINFO - N
382
ELSE
383
INFO = N + 6
384
END IF
385
GO TO 10
386
END IF
387
*
388
* Apply permutation to VSL and VSR
389
*
390
IF( ILVSL ) THEN
391
CALL CGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
392
$ RWORK( IRIGHT ), N, VSL, LDVSL, IINFO )
393
IF( IINFO.NE.0 ) THEN
394
INFO = N + 7
395
GO TO 10
396
END IF
397
END IF
398
IF( ILVSR ) THEN
399
CALL CGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
400
$ RWORK( IRIGHT ), N, VSR, LDVSR, IINFO )
401
IF( IINFO.NE.0 ) THEN
402
INFO = N + 8
403
GO TO 10
404
END IF
405
END IF
406
*
407
* Undo scaling
408
*
409
IF( ILASCL ) THEN
410
CALL CLASCL( 'U', -1, -1, ANRMTO, ANRM, N, N, A, LDA, IINFO )
411
IF( IINFO.NE.0 ) THEN
412
INFO = N + 9
413
RETURN
414
END IF
415
CALL CLASCL( 'G', -1, -1, ANRMTO, ANRM, N, 1, ALPHA, N, IINFO )
416
IF( IINFO.NE.0 ) THEN
417
INFO = N + 9
418
RETURN
419
END IF
420
END IF
421
*
422
IF( ILBSCL ) THEN
423
CALL CLASCL( 'U', -1, -1, BNRMTO, BNRM, N, N, B, LDB, IINFO )
424
IF( IINFO.NE.0 ) THEN
425
INFO = N + 9
426
RETURN
427
END IF
428
CALL CLASCL( 'G', -1, -1, BNRMTO, BNRM, N, 1, BETA, N, IINFO )
429
IF( IINFO.NE.0 ) THEN
430
INFO = N + 9
431
RETURN
432
END IF
433
END IF
434
*
435
10 CONTINUE
436
WORK( 1 ) = LWKOPT
437
*
438
RETURN
439
*
440
* End of CGEGS
441
*
442
END
443
444