1 /* ztrsen.f -- translated by f2c (version 20061008).
2 You must link the resulting object file with libf2c:
3 on Microsoft Windows system, link with libf2c.lib;
4 on Linux or Unix systems, link with .../path/to/libf2c.a -lm
5 or, if you install libf2c.a in a standard place, with -lf2c -lm
6 -- in that order, at the end of the command line, as in
7 cc *.o -lf2c -lm
8 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
9
10 http://www.netlib.org/f2c/libf2c.zip
11 */
12
13 #include "f2c.h"
14 #include "blaswrap.h"
15
16 /* Table of constant values */
17
18 static integer c_n1 = -1;
19
ztrsen_(char * job,char * compq,logical * select,integer * n,doublecomplex * t,integer * ldt,doublecomplex * q,integer * ldq,doublecomplex * w,integer * m,doublereal * s,doublereal * sep,doublecomplex * work,integer * lwork,integer * info)20 /* Subroutine */ int ztrsen_(char *job, char *compq, logical *select, integer
21 *n, doublecomplex *t, integer *ldt, doublecomplex *q, integer *ldq,
22 doublecomplex *w, integer *m, doublereal *s, doublereal *sep,
23 doublecomplex *work, integer *lwork, integer *info)
24 {
25 /* System generated locals */
26 integer q_dim1, q_offset, t_dim1, t_offset, i__1, i__2, i__3;
27
28 /* Builtin functions */
29 double sqrt(doublereal);
30
31 /* Local variables */
32 integer k, n1, n2, nn, ks;
33 doublereal est;
34 integer kase, ierr;
35 doublereal scale;
36 extern logical lsame_(char *, char *);
37 integer isave[3], lwmin;
38 logical wantq, wants;
39 doublereal rnorm, rwork[1];
40 extern /* Subroutine */ int zlacn2_(integer *, doublecomplex *,
41 doublecomplex *, doublereal *, integer *, integer *), xerbla_(
42 char *, integer *);
43 extern doublereal zlange_(char *, integer *, integer *, doublecomplex *,
44 integer *, doublereal *);
45 logical wantbh;
46 extern /* Subroutine */ int zlacpy_(char *, integer *, integer *,
47 doublecomplex *, integer *, doublecomplex *, integer *);
48 logical wantsp;
49 extern /* Subroutine */ int ztrexc_(char *, integer *, doublecomplex *,
50 integer *, doublecomplex *, integer *, integer *, integer *,
51 integer *);
52 logical lquery;
53 extern /* Subroutine */ int ztrsyl_(char *, char *, integer *, integer *,
54 integer *, doublecomplex *, integer *, doublecomplex *, integer *,
55 doublecomplex *, integer *, doublereal *, integer *);
56
57
58 /* -- LAPACK routine (version 3.2) -- */
59 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
60 /* November 2006 */
61
62 /* Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH. */
63
64 /* .. Scalar Arguments .. */
65 /* .. */
66 /* .. Array Arguments .. */
67 /* .. */
68
69 /* Purpose */
70 /* ======= */
71
72 /* ZTRSEN reorders the Schur factorization of a complex matrix */
73 /* A = Q*T*Q**H, so that a selected cluster of eigenvalues appears in */
74 /* the leading positions on the diagonal of the upper triangular matrix */
75 /* T, and the leading columns of Q form an orthonormal basis of the */
76 /* corresponding right invariant subspace. */
77
78 /* Optionally the routine computes the reciprocal condition numbers of */
79 /* the cluster of eigenvalues and/or the invariant subspace. */
80
81 /* Arguments */
82 /* ========= */
83
84 /* JOB (input) CHARACTER*1 */
85 /* Specifies whether condition numbers are required for the */
86 /* cluster of eigenvalues (S) or the invariant subspace (SEP): */
87 /* = 'N': none; */
88 /* = 'E': for eigenvalues only (S); */
89 /* = 'V': for invariant subspace only (SEP); */
90 /* = 'B': for both eigenvalues and invariant subspace (S and */
91 /* SEP). */
92
93 /* COMPQ (input) CHARACTER*1 */
94 /* = 'V': update the matrix Q of Schur vectors; */
95 /* = 'N': do not update Q. */
96
97 /* SELECT (input) LOGICAL array, dimension (N) */
98 /* SELECT specifies the eigenvalues in the selected cluster. To */
99 /* select the j-th eigenvalue, SELECT(j) must be set to .TRUE.. */
100
101 /* N (input) INTEGER */
102 /* The order of the matrix T. N >= 0. */
103
104 /* T (input/output) COMPLEX*16 array, dimension (LDT,N) */
105 /* On entry, the upper triangular matrix T. */
106 /* On exit, T is overwritten by the reordered matrix T, with the */
107 /* selected eigenvalues as the leading diagonal elements. */
108
109 /* LDT (input) INTEGER */
110 /* The leading dimension of the array T. LDT >= max(1,N). */
111
112 /* Q (input/output) COMPLEX*16 array, dimension (LDQ,N) */
113 /* On entry, if COMPQ = 'V', the matrix Q of Schur vectors. */
114 /* On exit, if COMPQ = 'V', Q has been postmultiplied by the */
115 /* unitary transformation matrix which reorders T; the leading M */
116 /* columns of Q form an orthonormal basis for the specified */
117 /* invariant subspace. */
118 /* If COMPQ = 'N', Q is not referenced. */
119
120 /* LDQ (input) INTEGER */
121 /* The leading dimension of the array Q. */
122 /* LDQ >= 1; and if COMPQ = 'V', LDQ >= N. */
123
124 /* W (output) COMPLEX*16 array, dimension (N) */
125 /* The reordered eigenvalues of T, in the same order as they */
126 /* appear on the diagonal of T. */
127
128 /* M (output) INTEGER */
129 /* The dimension of the specified invariant subspace. */
130 /* 0 <= M <= N. */
131
132 /* S (output) DOUBLE PRECISION */
133 /* If JOB = 'E' or 'B', S is a lower bound on the reciprocal */
134 /* condition number for the selected cluster of eigenvalues. */
135 /* S cannot underestimate the true reciprocal condition number */
136 /* by more than a factor of sqrt(N). If M = 0 or N, S = 1. */
137 /* If JOB = 'N' or 'V', S is not referenced. */
138
139 /* SEP (output) DOUBLE PRECISION */
140 /* If JOB = 'V' or 'B', SEP is the estimated reciprocal */
141 /* condition number of the specified invariant subspace. If */
142 /* M = 0 or N, SEP = norm(T). */
143 /* If JOB = 'N' or 'E', SEP is not referenced. */
144
145 /* WORK (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK)) */
146 /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
147
148 /* LWORK (input) INTEGER */
149 /* The dimension of the array WORK. */
150 /* If JOB = 'N', LWORK >= 1; */
151 /* if JOB = 'E', LWORK = max(1,M*(N-M)); */
152 /* if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)). */
153
154 /* If LWORK = -1, then a workspace query is assumed; the routine */
155 /* only calculates the optimal size of the WORK array, returns */
156 /* this value as the first entry of the WORK array, and no error */
157 /* message related to LWORK is issued by XERBLA. */
158
159 /* INFO (output) INTEGER */
160 /* = 0: successful exit */
161 /* < 0: if INFO = -i, the i-th argument had an illegal value */
162
163 /* Further Details */
164 /* =============== */
165
166 /* ZTRSEN first collects the selected eigenvalues by computing a unitary */
167 /* transformation Z to move them to the top left corner of T. In other */
168 /* words, the selected eigenvalues are the eigenvalues of T11 in: */
169
170 /* Z'*T*Z = ( T11 T12 ) n1 */
171 /* ( 0 T22 ) n2 */
172 /* n1 n2 */
173
174 /* where N = n1+n2 and Z' means the conjugate transpose of Z. The first */
175 /* n1 columns of Z span the specified invariant subspace of T. */
176
177 /* If T has been obtained from the Schur factorization of a matrix */
178 /* A = Q*T*Q', then the reordered Schur factorization of A is given by */
179 /* A = (Q*Z)*(Z'*T*Z)*(Q*Z)', and the first n1 columns of Q*Z span the */
180 /* corresponding invariant subspace of A. */
181
182 /* The reciprocal condition number of the average of the eigenvalues of */
183 /* T11 may be returned in S. S lies between 0 (very badly conditioned) */
184 /* and 1 (very well conditioned). It is computed as follows. First we */
185 /* compute R so that */
186
187 /* P = ( I R ) n1 */
188 /* ( 0 0 ) n2 */
189 /* n1 n2 */
190
191 /* is the projector on the invariant subspace associated with T11. */
192 /* R is the solution of the Sylvester equation: */
193
194 /* T11*R - R*T22 = T12. */
195
196 /* Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote */
197 /* the two-norm of M. Then S is computed as the lower bound */
198
199 /* (1 + F-norm(R)**2)**(-1/2) */
200
201 /* on the reciprocal of 2-norm(P), the true reciprocal condition number. */
202 /* S cannot underestimate 1 / 2-norm(P) by more than a factor of */
203 /* sqrt(N). */
204
205 /* An approximate error bound for the computed average of the */
206 /* eigenvalues of T11 is */
207
208 /* EPS * norm(T) / S */
209
210 /* where EPS is the machine precision. */
211
212 /* The reciprocal condition number of the right invariant subspace */
213 /* spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP. */
214 /* SEP is defined as the separation of T11 and T22: */
215
216 /* sep( T11, T22 ) = sigma-min( C ) */
217
218 /* where sigma-min(C) is the smallest singular value of the */
219 /* n1*n2-by-n1*n2 matrix */
220
221 /* C = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) ) */
222
223 /* I(m) is an m by m identity matrix, and kprod denotes the Kronecker */
224 /* product. We estimate sigma-min(C) by the reciprocal of an estimate of */
225 /* the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C) */
226 /* cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2). */
227
228 /* When SEP is small, small changes in T can cause large changes in */
229 /* the invariant subspace. An approximate bound on the maximum angular */
230 /* error in the computed right invariant subspace is */
231
232 /* EPS * norm(T) / SEP */
233
234 /* ===================================================================== */
235
236 /* .. Parameters .. */
237 /* .. */
238 /* .. Local Scalars .. */
239 /* .. */
240 /* .. Local Arrays .. */
241 /* .. */
242 /* .. External Functions .. */
243 /* .. */
244 /* .. External Subroutines .. */
245 /* .. */
246 /* .. Intrinsic Functions .. */
247 /* .. */
248 /* .. Executable Statements .. */
249
250 /* Decode and test the input parameters. */
251
252 /* Parameter adjustments */
253 --select;
254 t_dim1 = *ldt;
255 t_offset = 1 + t_dim1;
256 t -= t_offset;
257 q_dim1 = *ldq;
258 q_offset = 1 + q_dim1;
259 q -= q_offset;
260 --w;
261 --work;
262
263 /* Function Body */
264 wantbh = lsame_(job, "B");
265 wants = lsame_(job, "E") || wantbh;
266 wantsp = lsame_(job, "V") || wantbh;
267 wantq = lsame_(compq, "V");
268
269 /* Set M to the number of selected eigenvalues. */
270
271 *m = 0;
272 i__1 = *n;
273 for (k = 1; k <= i__1; ++k) {
274 if (select[k]) {
275 ++(*m);
276 }
277 /* L10: */
278 }
279
280 n1 = *m;
281 n2 = *n - *m;
282 nn = n1 * n2;
283
284 *info = 0;
285 lquery = *lwork == -1;
286
287 if (wantsp) {
288 /* Computing MAX */
289 i__1 = 1, i__2 = nn << 1;
290 lwmin = max(i__1,i__2);
291 } else if (lsame_(job, "N")) {
292 lwmin = 1;
293 } else if (lsame_(job, "E")) {
294 lwmin = max(1,nn);
295 }
296
297 if (! lsame_(job, "N") && ! wants && ! wantsp) {
298 *info = -1;
299 } else if (! lsame_(compq, "N") && ! wantq) {
300 *info = -2;
301 } else if (*n < 0) {
302 *info = -4;
303 } else if (*ldt < max(1,*n)) {
304 *info = -6;
305 } else if (*ldq < 1 || wantq && *ldq < *n) {
306 *info = -8;
307 } else if (*lwork < lwmin && ! lquery) {
308 *info = -14;
309 }
310
311 if (*info == 0) {
312 work[1].r = (doublereal) lwmin, work[1].i = 0.;
313 }
314
315 if (*info != 0) {
316 i__1 = -(*info);
317 xerbla_("ZTRSEN", &i__1);
318 return 0;
319 } else if (lquery) {
320 return 0;
321 }
322
323 /* Quick return if possible */
324
325 if (*m == *n || *m == 0) {
326 if (wants) {
327 *s = 1.;
328 }
329 if (wantsp) {
330 *sep = zlange_("1", n, n, &t[t_offset], ldt, rwork);
331 }
332 goto L40;
333 }
334
335 /* Collect the selected eigenvalues at the top left corner of T. */
336
337 ks = 0;
338 i__1 = *n;
339 for (k = 1; k <= i__1; ++k) {
340 if (select[k]) {
341 ++ks;
342
343 /* Swap the K-th eigenvalue to position KS. */
344
345 if (k != ks) {
346 ztrexc_(compq, n, &t[t_offset], ldt, &q[q_offset], ldq, &k, &
347 ks, &ierr);
348 }
349 }
350 /* L20: */
351 }
352
353 if (wants) {
354
355 /* Solve the Sylvester equation for R: */
356
357 /* T11*R - R*T22 = scale*T12 */
358
359 zlacpy_("F", &n1, &n2, &t[(n1 + 1) * t_dim1 + 1], ldt, &work[1], &n1);
360 ztrsyl_("N", "N", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 + 1 + (n1
361 + 1) * t_dim1], ldt, &work[1], &n1, &scale, &ierr);
362
363 /* Estimate the reciprocal of the condition number of the cluster */
364 /* of eigenvalues. */
365
366 rnorm = zlange_("F", &n1, &n2, &work[1], &n1, rwork);
367 if (rnorm == 0.) {
368 *s = 1.;
369 } else {
370 *s = scale / (sqrt(scale * scale / rnorm + rnorm) * sqrt(rnorm));
371 }
372 }
373
374 if (wantsp) {
375
376 /* Estimate sep(T11,T22). */
377
378 est = 0.;
379 kase = 0;
380 L30:
381 zlacn2_(&nn, &work[nn + 1], &work[1], &est, &kase, isave);
382 if (kase != 0) {
383 if (kase == 1) {
384
385 /* Solve T11*R - R*T22 = scale*X. */
386
387 ztrsyl_("N", "N", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 +
388 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, &
389 ierr);
390 } else {
391
392 /* Solve T11'*R - R*T22' = scale*X. */
393
394 ztrsyl_("C", "C", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 +
395 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, &
396 ierr);
397 }
398 goto L30;
399 }
400
401 *sep = scale / est;
402 }
403
404 L40:
405
406 /* Copy reordered eigenvalues to W. */
407
408 i__1 = *n;
409 for (k = 1; k <= i__1; ++k) {
410 i__2 = k;
411 i__3 = k + k * t_dim1;
412 w[i__2].r = t[i__3].r, w[i__2].i = t[i__3].i;
413 /* L50: */
414 }
415
416 work[1].r = (doublereal) lwmin, work[1].i = 0.;
417
418 return 0;
419
420 /* End of ZTRSEN */
421
422 } /* ztrsen_ */
423