1 /* ../netlib/strsen.f -- translated by f2c (version 20100827). You must link the resulting object file with libf2c: on Microsoft Windows system, link with libf2c.lib;
2  on Linux or Unix systems, link with .../path/to/libf2c.a -lm or, if you install libf2c.a in a standard place, with -lf2c -lm -- in that order, at the end of the command line, as in cc *.o -lf2c -lm Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., http://www.netlib.org/f2c/libf2c.zip */
3 #include "FLA_f2c.h" /* Table of constant values */
4 static integer c_n1 = -1;
5 /* > \brief \b STRSEN */
6 /* =========== DOCUMENTATION =========== */
7 /* Online html documentation available at */
8 /* http://www.netlib.org/lapack/explore-html/ */
9 /* > \htmlonly */
10 /* > Download STRSEN + dependencies */
11 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/strsen. f"> */
12 /* > [TGZ]</a> */
13 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/strsen. f"> */
14 /* > [ZIP]</a> */
15 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/strsen. f"> */
16 /* > [TXT]</a> */
17 /* > \endhtmlonly */
18 /* Definition: */
19 /* =========== */
20 /* SUBROUTINE STRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, WR, WI, */
21 /* M, S, SEP, WORK, LWORK, IWORK, LIWORK, INFO ) */
22 /* .. Scalar Arguments .. */
23 /* CHARACTER COMPQ, JOB */
24 /* INTEGER INFO, LDQ, LDT, LIWORK, LWORK, M, N */
25 /* REAL S, SEP */
26 /* .. */
27 /* .. Array Arguments .. */
28 /* LOGICAL SELECT( * ) */
29 /* INTEGER IWORK( * ) */
30 /* REAL Q( LDQ, * ), T( LDT, * ), WI( * ), WORK( * ), */
31 /* $ WR( * ) */
32 /* .. */
33 /* > \par Purpose: */
34 /* ============= */
35 /* > */
36 /* > \verbatim */
37 /* > */
38 /* > STRSEN reorders the real Schur factorization of a real matrix */
39 /* > A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in */
40 /* > the leading diagonal blocks of the upper quasi-triangular matrix T, */
41 /* > and the leading columns of Q form an orthonormal basis of the */
42 /* > corresponding right invariant subspace. */
43 /* > */
44 /* > Optionally the routine computes the reciprocal condition numbers of */
45 /* > the cluster of eigenvalues and/or the invariant subspace. */
46 /* > */
47 /* > T must be in Schur canonical form (as returned by SHSEQR), that is, */
48 /* > block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;
49 each */
50 /* > 2-by-2 diagonal block has its diagonal elements equal and its */
51 /* > off-diagonal elements of opposite sign. */
52 /* > \endverbatim */
53 /* Arguments: */
54 /* ========== */
55 /* > \param[in] JOB */
56 /* > \verbatim */
57 /* > JOB is CHARACTER*1 */
58 /* > Specifies whether condition numbers are required for the */
59 /* > cluster of eigenvalues (S) or the invariant subspace (SEP): */
60 /* > = 'N': none;
61 */
62 /* > = 'E': for eigenvalues only (S);
63 */
64 /* > = 'V': for invariant subspace only (SEP);
65 */
66 /* > = 'B': for both eigenvalues and invariant subspace (S and */
67 /* > SEP). */
68 /* > \endverbatim */
69 /* > */
70 /* > \param[in] COMPQ */
71 /* > \verbatim */
72 /* > COMPQ is CHARACTER*1 */
73 /* > = 'V': update the matrix Q of Schur vectors;
74 */
75 /* > = 'N': do not update Q. */
76 /* > \endverbatim */
77 /* > */
78 /* > \param[in] SELECT */
79 /* > \verbatim */
80 /* > SELECT is LOGICAL array, dimension (N) */
81 /* > SELECT specifies the eigenvalues in the selected cluster. To */
82 /* > select a real eigenvalue w(j), SELECT(j) must be set to */
83 /* > .TRUE.. To select a complex conjugate pair of eigenvalues */
84 /* > w(j) and w(j+1), corresponding to a 2-by-2 diagonal block, */
85 /* > either SELECT(j) or SELECT(j+1) or both must be set to */
86 /* > .TRUE.;
87 a complex conjugate pair of eigenvalues must be */
88 /* > either both included in the cluster or both excluded. */
89 /* > \endverbatim */
90 /* > */
91 /* > \param[in] N */
92 /* > \verbatim */
93 /* > N is INTEGER */
94 /* > The order of the matrix T. N >= 0. */
95 /* > \endverbatim */
96 /* > */
97 /* > \param[in,out] T */
98 /* > \verbatim */
99 /* > T is REAL array, dimension (LDT,N) */
100 /* > On entry, the upper quasi-triangular matrix T, in Schur */
101 /* > canonical form. */
102 /* > On exit, T is overwritten by the reordered matrix T, again in */
103 /* > Schur canonical form, with the selected eigenvalues in the */
104 /* > leading diagonal blocks. */
105 /* > \endverbatim */
106 /* > */
107 /* > \param[in] LDT */
108 /* > \verbatim */
109 /* > LDT is INTEGER */
110 /* > The leading dimension of the array T. LDT >= max(1,N). */
111 /* > \endverbatim */
112 /* > */
113 /* > \param[in,out] Q */
114 /* > \verbatim */
115 /* > Q is REAL array, dimension (LDQ,N) */
116 /* > On entry, if COMPQ = 'V', the matrix Q of Schur vectors. */
117 /* > On exit, if COMPQ = 'V', Q has been postmultiplied by the */
118 /* > orthogonal transformation matrix which reorders T;
119 the */
120 /* > leading M columns of Q form an orthonormal basis for the */
121 /* > specified invariant subspace. */
122 /* > If COMPQ = 'N', Q is not referenced. */
123 /* > \endverbatim */
124 /* > */
125 /* > \param[in] LDQ */
126 /* > \verbatim */
127 /* > LDQ is INTEGER */
128 /* > The leading dimension of the array Q. */
129 /* > LDQ >= 1;
130 and if COMPQ = 'V', LDQ >= N. */
131 /* > \endverbatim */
132 /* > */
133 /* > \param[out] WR */
134 /* > \verbatim */
135 /* > WR is REAL array, dimension (N) */
136 /* > \endverbatim */
137 /* > */
138 /* > \param[out] WI */
139 /* > \verbatim */
140 /* > WI is REAL array, dimension (N) */
141 /* > */
142 /* > The real and imaginary parts, respectively, of the reordered */
143 /* > eigenvalues of T. The eigenvalues are stored in the same */
144 /* > order as on the diagonal of T, with WR(i) = T(i,i) and, if */
145 /* > T(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) > 0 and */
146 /* > WI(i+1) = -WI(i). Note that if a complex eigenvalue is */
147 /* > sufficiently ill-conditioned, then its value may differ */
148 /* > significantly from its value before reordering. */
149 /* > \endverbatim */
150 /* > */
151 /* > \param[out] M */
152 /* > \verbatim */
153 /* > M is INTEGER */
154 /* > The dimension of the specified invariant subspace. */
155 /* > 0 < = M <= N. */
156 /* > \endverbatim */
157 /* > */
158 /* > \param[out] S */
159 /* > \verbatim */
160 /* > S is REAL */
161 /* > If JOB = 'E' or 'B', S is a lower bound on the reciprocal */
162 /* > condition number for the selected cluster of eigenvalues. */
163 /* > S cannot underestimate the true reciprocal condition number */
164 /* > by more than a factor of sqrt(N). If M = 0 or N, S = 1. */
165 /* > If JOB = 'N' or 'V', S is not referenced. */
166 /* > \endverbatim */
167 /* > */
168 /* > \param[out] SEP */
169 /* > \verbatim */
170 /* > SEP is REAL */
171 /* > If JOB = 'V' or 'B', SEP is the estimated reciprocal */
172 /* > condition number of the specified invariant subspace. If */
173 /* > M = 0 or N, SEP = norm(T). */
174 /* > If JOB = 'N' or 'E', SEP is not referenced. */
175 /* > \endverbatim */
176 /* > */
177 /* > \param[out] WORK */
178 /* > \verbatim */
179 /* > WORK is REAL array, dimension (MAX(1,LWORK)) */
180 /* > On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
181 /* > \endverbatim */
182 /* > */
183 /* > \param[in] LWORK */
184 /* > \verbatim */
185 /* > LWORK is INTEGER */
186 /* > The dimension of the array WORK. */
187 /* > If JOB = 'N', LWORK >= max(1,N);
188 */
189 /* > if JOB = 'E', LWORK >= max(1,M*(N-M));
190 */
191 /* > if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)). */
192 /* > */
193 /* > If LWORK = -1, then a workspace query is assumed;
194 the routine */
195 /* > only calculates the optimal size of the WORK array, returns */
196 /* > this value as the first entry of the WORK array, and no error */
197 /* > message related to LWORK is issued by XERBLA. */
198 /* > \endverbatim */
199 /* > */
200 /* > \param[out] IWORK */
201 /* > \verbatim */
202 /* > IWORK is INTEGER array, dimension (MAX(1,LIWORK)) */
203 /* > On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK. */
204 /* > \endverbatim */
205 /* > */
206 /* > \param[in] LIWORK */
207 /* > \verbatim */
208 /* > LIWORK is INTEGER */
209 /* > The dimension of the array IWORK. */
210 /* > If JOB = 'N' or 'E', LIWORK >= 1;
211 */
212 /* > if JOB = 'V' or 'B', LIWORK >= max(1,M*(N-M)). */
213 /* > */
214 /* > If LIWORK = -1, then a workspace query is assumed;
215 the */
216 /* > routine only calculates the optimal size of the IWORK array, */
217 /* > returns this value as the first entry of the IWORK array, and */
218 /* > no error message related to LIWORK is issued by XERBLA. */
219 /* > \endverbatim */
220 /* > */
221 /* > \param[out] INFO */
222 /* > \verbatim */
223 /* > INFO is INTEGER */
224 /* > = 0: successful exit */
225 /* > < 0: if INFO = -i, the i-th argument had an illegal value */
226 /* > = 1: reordering of T failed because some eigenvalues are too */
227 /* > close to separate (the problem is very ill-conditioned);
228 */
229 /* > T may have been partially reordered, and WR and WI */
230 /* > contain the eigenvalues in the same order as in T;
231 S and */
232 /* > SEP (if requested) are set to zero. */
233 /* > \endverbatim */
234 /* Authors: */
235 /* ======== */
236 /* > \author Univ. of Tennessee */
237 /* > \author Univ. of California Berkeley */
238 /* > \author Univ. of Colorado Denver */
239 /* > \author NAG Ltd. */
240 /* > \date April 2012 */
241 /* > \ingroup realOTHERcomputational */
242 /* > \par Further Details: */
243 /* ===================== */
244 /* > */
245 /* > \verbatim */
246 /* > */
247 /* > STRSEN first collects the selected eigenvalues by computing an */
248 /* > orthogonal transformation Z to move them to the top left corner of T. */
249 /* > In other words, the selected eigenvalues are the eigenvalues of T11 */
250 /* > in: */
251 /* > */
252 /* > Z**T * T * Z = ( T11 T12 ) n1 */
253 /* > ( 0 T22 ) n2 */
254 /* > n1 n2 */
255 /* > */
256 /* > where N = n1+n2 and Z**T means the transpose of Z. The first n1 columns */
257 /* > of Z span the specified invariant subspace of T. */
258 /* > */
259 /* > If T has been obtained from the real Schur factorization of a matrix */
260 /* > A = Q*T*Q**T, then the reordered real Schur factorization of A is given */
261 /* > by A = (Q*Z)*(Z**T*T*Z)*(Q*Z)**T, and the first n1 columns of Q*Z span */
262 /* > the corresponding invariant subspace of A. */
263 /* > */
264 /* > The reciprocal condition number of the average of the eigenvalues of */
265 /* > T11 may be returned in S. S lies between 0 (very badly conditioned) */
266 /* > and 1 (very well conditioned). It is computed as follows. First we */
267 /* > compute R so that */
268 /* > */
269 /* > P = ( I R ) n1 */
270 /* > ( 0 0 ) n2 */
271 /* > n1 n2 */
272 /* > */
273 /* > is the projector on the invariant subspace associated with T11. */
274 /* > R is the solution of the Sylvester equation: */
275 /* > */
276 /* > T11*R - R*T22 = T12. */
277 /* > */
278 /* > Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote */
279 /* > the two-norm of M. Then S is computed as the lower bound */
280 /* > */
281 /* > (1 + F-norm(R)**2)**(-1/2) */
282 /* > */
283 /* > on the reciprocal of 2-norm(P), the true reciprocal condition number. */
284 /* > S cannot underestimate 1 / 2-norm(P) by more than a factor of */
285 /* > sqrt(N). */
286 /* > */
287 /* > An approximate error bound for the computed average of the */
288 /* > eigenvalues of T11 is */
289 /* > */
290 /* > EPS * norm(T) / S */
291 /* > */
292 /* > where EPS is the machine precision. */
293 /* > */
294 /* > The reciprocal condition number of the right invariant subspace */
295 /* > spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP. */
296 /* > SEP is defined as the separation of T11 and T22: */
297 /* > */
298 /* > sep( T11, T22 ) = sigma-min( C ) */
299 /* > */
300 /* > where sigma-min(C) is the smallest singular value of the */
301 /* > n1*n2-by-n1*n2 matrix */
302 /* > */
303 /* > C = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) ) */
304 /* > */
305 /* > I(m) is an m by m identity matrix, and kprod denotes the Kronecker */
306 /* > product. We estimate sigma-min(C) by the reciprocal of an estimate of */
307 /* > the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C) */
308 /* > cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2). */
309 /* > */
310 /* > When SEP is small, small changes in T can cause large changes in */
311 /* > the invariant subspace. An approximate bound on the maximum angular */
312 /* > error in the computed right invariant subspace is */
313 /* > */
314 /* > EPS * norm(T) / SEP */
315 /* > \endverbatim */
316 /* > */
317 /* ===================================================================== */
318 /* Subroutine */
strsen_(char * job,char * compq,logical * select,integer * n,real * t,integer * ldt,real * q,integer * ldq,real * wr,real * wi,integer * m,real * s,real * sep,real * work,integer * lwork,integer * iwork,integer * liwork,integer * info)319 int strsen_(char *job, char *compq, logical *select, integer *n, real *t, integer *ldt, real *q, integer *ldq, real *wr, real *wi, integer *m, real *s, real *sep, real *work, integer *lwork, integer * iwork, integer *liwork, integer *info)
320 {
321     /* System generated locals */
322     integer q_dim1, q_offset, t_dim1, t_offset, i__1, i__2;
323     real r__1, r__2;
324     /* Builtin functions */
325     double sqrt(doublereal);
326     /* Local variables */
327     integer k, n1, n2, kk, nn, ks;
328     real est;
329     integer kase;
330     logical pair;
331     integer ierr;
332     logical swap;
333     real scale;
334     extern logical lsame_(char *, char *);
335     integer isave[3], lwmin;
336     logical wantq, wants;
337     real rnorm;
338     extern /* Subroutine */
339     int slacn2_(integer *, real *, real *, integer *, real *, integer *, integer *);
340     extern real slange_(char *, integer *, integer *, real *, integer *, real *);
341     extern /* Subroutine */
342     int xerbla_(char *, integer *);
343     logical wantbh;
344     extern /* Subroutine */
345     int slacpy_(char *, integer *, integer *, real *, integer *, real *, integer *);
346     integer liwmin;
347     extern /* Subroutine */
348     int strexc_(char *, integer *, real *, integer *, real *, integer *, integer *, integer *, real *, integer *);
349     logical wantsp, lquery;
350     extern /* Subroutine */
351     int strsyl_(char *, char *, integer *, integer *, integer *, real *, integer *, real *, integer *, real *, integer * , real *, integer *);
352     /* -- LAPACK computational routine (version 3.4.1) -- */
353     /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
354     /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
355     /* April 2012 */
356     /* .. Scalar Arguments .. */
357     /* .. */
358     /* .. Array Arguments .. */
359     /* .. */
360     /* ===================================================================== */
361     /* .. Parameters .. */
362     /* .. */
363     /* .. Local Scalars .. */
364     /* .. */
365     /* .. Local Arrays .. */
366     /* .. */
367     /* .. External Functions .. */
368     /* .. */
369     /* .. External Subroutines .. */
370     /* .. */
371     /* .. Intrinsic Functions .. */
372     /* .. */
373     /* .. Executable Statements .. */
374     /* Decode and test the input parameters */
375     /* Parameter adjustments */
376     --select;
377     t_dim1 = *ldt;
378     t_offset = 1 + t_dim1;
379     t -= t_offset;
380     q_dim1 = *ldq;
381     q_offset = 1 + q_dim1;
382     q -= q_offset;
383     --wr;
384     --wi;
385     --work;
386     --iwork;
387     /* Function Body */
388     wantbh = lsame_(job, "B");
389     wants = lsame_(job, "E") || wantbh;
390     wantsp = lsame_(job, "V") || wantbh;
391     wantq = lsame_(compq, "V");
392     *info = 0;
393     lquery = *lwork == -1;
394     if (! lsame_(job, "N") && ! wants && ! wantsp)
395     {
396         *info = -1;
397     }
398     else if (! lsame_(compq, "N") && ! wantq)
399     {
400         *info = -2;
401     }
402     else if (*n < 0)
403     {
404         *info = -4;
405     }
406     else if (*ldt < max(1,*n))
407     {
408         *info = -6;
409     }
410     else if (*ldq < 1 || wantq && *ldq < *n)
411     {
412         *info = -8;
413     }
414     else
415     {
416         /* Set M to the dimension of the specified invariant subspace, */
417         /* and test LWORK and LIWORK. */
418         *m = 0;
419         pair = FALSE_;
420         i__1 = *n;
421         for (k = 1;
422                 k <= i__1;
423                 ++k)
424         {
425             if (pair)
426             {
427                 pair = FALSE_;
428             }
429             else
430             {
431                 if (k < *n)
432                 {
433                     if (t[k + 1 + k * t_dim1] == 0.f)
434                     {
435                         if (select[k])
436                         {
437                             ++(*m);
438                         }
439                     }
440                     else
441                     {
442                         pair = TRUE_;
443                         if (select[k] || select[k + 1])
444                         {
445                             *m += 2;
446                         }
447                     }
448                 }
449                 else
450                 {
451                     if (select[*n])
452                     {
453                         ++(*m);
454                     }
455                 }
456             }
457             /* L10: */
458         }
459         n1 = *m;
460         n2 = *n - *m;
461         nn = n1 * n2;
462         if (wantsp)
463         {
464             /* Computing MAX */
465             i__1 = 1;
466             i__2 = nn << 1; // , expr subst
467             lwmin = max(i__1,i__2);
468             liwmin = max(1,nn);
469         }
470         else if (lsame_(job, "N"))
471         {
472             lwmin = max(1,*n);
473             liwmin = 1;
474         }
475         else if (lsame_(job, "E"))
476         {
477             lwmin = max(1,nn);
478             liwmin = 1;
479         }
480         if (*lwork < lwmin && ! lquery)
481         {
482             *info = -15;
483         }
484         else if (*liwork < liwmin && ! lquery)
485         {
486             *info = -17;
487         }
488     }
489     if (*info == 0)
490     {
491         work[1] = (real) lwmin;
492         iwork[1] = liwmin;
493     }
494     if (*info != 0)
495     {
496         i__1 = -(*info);
497         xerbla_("STRSEN", &i__1);
498         return 0;
499     }
500     else if (lquery)
501     {
502         return 0;
503     }
504     /* Quick return if possible. */
505     if (*m == *n || *m == 0)
506     {
507         if (wants)
508         {
509             *s = 1.f;
510         }
511         if (wantsp)
512         {
513             *sep = slange_("1", n, n, &t[t_offset], ldt, &work[1]);
514         }
515         goto L40;
516     }
517     /* Collect the selected blocks at the top-left corner of T. */
518     ks = 0;
519     pair = FALSE_;
520     i__1 = *n;
521     for (k = 1;
522             k <= i__1;
523             ++k)
524     {
525         if (pair)
526         {
527             pair = FALSE_;
528         }
529         else
530         {
531             swap = select[k];
532             if (k < *n)
533             {
534                 if (t[k + 1 + k * t_dim1] != 0.f)
535                 {
536                     pair = TRUE_;
537                     swap = swap || select[k + 1];
538                 }
539             }
540             if (swap)
541             {
542                 ++ks;
543                 /* Swap the K-th block to position KS. */
544                 ierr = 0;
545                 kk = k;
546                 if (k != ks)
547                 {
548                     strexc_(compq, n, &t[t_offset], ldt, &q[q_offset], ldq, & kk, &ks, &work[1], &ierr);
549                 }
550                 if (ierr == 1 || ierr == 2)
551                 {
552                     /* Blocks too close to swap: exit. */
553                     *info = 1;
554                     if (wants)
555                     {
556                         *s = 0.f;
557                     }
558                     if (wantsp)
559                     {
560                         *sep = 0.f;
561                     }
562                     goto L40;
563                 }
564                 if (pair)
565                 {
566                     ++ks;
567                 }
568             }
569         }
570         /* L20: */
571     }
572     if (wants)
573     {
574         /* Solve Sylvester equation for R: */
575         /* T11*R - R*T22 = scale*T12 */
576         slacpy_("F", &n1, &n2, &t[(n1 + 1) * t_dim1 + 1], ldt, &work[1], &n1);
577         strsyl_("N", "N", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 + 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, &ierr);
578         /* Estimate the reciprocal of the condition number of the cluster */
579         /* of eigenvalues. */
580         rnorm = slange_("F", &n1, &n2, &work[1], &n1, &work[1]);
581         if (rnorm == 0.f)
582         {
583             *s = 1.f;
584         }
585         else
586         {
587             *s = scale / (sqrt(scale * scale / rnorm + rnorm) * sqrt(rnorm));
588         }
589     }
590     if (wantsp)
591     {
592         /* Estimate sep(T11,T22). */
593         est = 0.f;
594         kase = 0;
595 L30:
596         slacn2_(&nn, &work[nn + 1], &work[1], &iwork[1], &est, &kase, isave);
597         if (kase != 0)
598         {
599             if (kase == 1)
600             {
601                 /* Solve T11*R - R*T22 = scale*X. */
602                 strsyl_("N", "N", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 + 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, & ierr);
603             }
604             else
605             {
606                 /* Solve T11**T*R - R*T22**T = scale*X. */
607                 strsyl_("T", "T", &c_n1, &n1, &n2, &t[t_offset], ldt, &t[n1 + 1 + (n1 + 1) * t_dim1], ldt, &work[1], &n1, &scale, & ierr);
608             }
609             goto L30;
610         }
611         *sep = scale / est;
612     }
613 L40: /* Store the output eigenvalues in WR and WI. */
614     i__1 = *n;
615     for (k = 1;
616             k <= i__1;
617             ++k)
618     {
619         wr[k] = t[k + k * t_dim1];
620         wi[k] = 0.f;
621         /* L50: */
622     }
623     i__1 = *n - 1;
624     for (k = 1;
625             k <= i__1;
626             ++k)
627     {
628         if (t[k + 1 + k * t_dim1] != 0.f)
629         {
630             wi[k] = sqrt((r__1 = t[k + (k + 1) * t_dim1], f2c_abs(r__1))) * sqrt(( r__2 = t[k + 1 + k * t_dim1], f2c_abs(r__2)));
631             wi[k + 1] = -wi[k];
632         }
633         /* L60: */
634     }
635     work[1] = (real) lwmin;
636     iwork[1] = liwmin;
637     return 0;
638     /* End of STRSEN */
639 }
640 /* strsen_ */
641