1 /* ../netlib/ctgsja.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 complex c_b1 =
5 {
6     0.f,0.f
7 }
8 ;
9 static complex c_b2 =
10 {
11     1.f,0.f
12 }
13 ;
14 static integer c__1 = 1;
15 static real c_b39 = -1.f;
16 static real c_b42 = 1.f;
17 /* > \brief \b CTGSJA */
18 /* =========== DOCUMENTATION =========== */
19 /* Online html documentation available at */
20 /* http://www.netlib.org/lapack/explore-html/ */
21 /* > \htmlonly */
22 /* > Download CTGSJA + dependencies */
23 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ctgsja. f"> */
24 /* > [TGZ]</a> */
25 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ctgsja. f"> */
26 /* > [ZIP]</a> */
27 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ctgsja. f"> */
28 /* > [TXT]</a> */
29 /* > \endhtmlonly */
30 /* Definition: */
31 /* =========== */
32 /* SUBROUTINE CTGSJA( JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B, */
33 /* LDB, TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV, */
34 /* Q, LDQ, WORK, NCYCLE, INFO ) */
35 /* .. Scalar Arguments .. */
36 /* CHARACTER JOBQ, JOBU, JOBV */
37 /* INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, */
38 /* $ NCYCLE, P */
39 /* REAL TOLA, TOLB */
40 /* .. */
41 /* .. Array Arguments .. */
42 /* REAL ALPHA( * ), BETA( * ) */
43 /* COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ), */
44 /* $ U( LDU, * ), V( LDV, * ), WORK( * ) */
45 /* .. */
46 /* > \par Purpose: */
47 /* ============= */
48 /* > */
49 /* > \verbatim */
50 /* > */
51 /* > CTGSJA computes the generalized singular value decomposition (GSVD) */
52 /* > of two complex upper triangular (or trapezoidal) matrices A and B. */
53 /* > */
54 /* > On entry, it is assumed that matrices A and B have the following */
55 /* > forms, which may be obtained by the preprocessing subroutine CGGSVP */
56 /* > from a general M-by-N matrix A and P-by-N matrix B: */
57 /* > */
58 /* > N-K-L K L */
59 /* > A = K ( 0 A12 A13 ) if M-K-L >= 0;
60 */
61 /* > L ( 0 0 A23 ) */
62 /* > M-K-L ( 0 0 0 ) */
63 /* > */
64 /* > N-K-L K L */
65 /* > A = K ( 0 A12 A13 ) if M-K-L < 0;
66 */
67 /* > M-K ( 0 0 A23 ) */
68 /* > */
69 /* > N-K-L K L */
70 /* > B = L ( 0 0 B13 ) */
71 /* > P-L ( 0 0 0 ) */
72 /* > */
73 /* > where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular */
74 /* > upper triangular;
75 A23 is L-by-L upper triangular if M-K-L >= 0, */
76 /* > otherwise A23 is (M-K)-by-L upper trapezoidal. */
77 /* > */
78 /* > On exit, */
79 /* > */
80 /* > U**H *A*Q = D1*( 0 R ), V**H *B*Q = D2*( 0 R ), */
81 /* > */
82 /* > where U, V and Q are unitary matrices. */
83 /* > R is a nonsingular upper triangular matrix, and D1 */
84 /* > and D2 are ``diagonal'' matrices, which are of the following */
85 /* > structures: */
86 /* > */
87 /* > If M-K-L >= 0, */
88 /* > */
89 /* > K L */
90 /* > D1 = K ( I 0 ) */
91 /* > L ( 0 C ) */
92 /* > M-K-L ( 0 0 ) */
93 /* > */
94 /* > K L */
95 /* > D2 = L ( 0 S ) */
96 /* > P-L ( 0 0 ) */
97 /* > */
98 /* > N-K-L K L */
99 /* > ( 0 R ) = K ( 0 R11 R12 ) K */
100 /* > L ( 0 0 R22 ) L */
101 /* > */
102 /* > where */
103 /* > */
104 /* > C = diag( ALPHA(K+1), ... , ALPHA(K+L) ), */
105 /* > S = diag( BETA(K+1), ... , BETA(K+L) ), */
106 /* > C**2 + S**2 = I. */
107 /* > */
108 /* > R is stored in A(1:K+L,N-K-L+1:N) on exit. */
109 /* > */
110 /* > If M-K-L < 0, */
111 /* > */
112 /* > K M-K K+L-M */
113 /* > D1 = K ( I 0 0 ) */
114 /* > M-K ( 0 C 0 ) */
115 /* > */
116 /* > K M-K K+L-M */
117 /* > D2 = M-K ( 0 S 0 ) */
118 /* > K+L-M ( 0 0 I ) */
119 /* > P-L ( 0 0 0 ) */
120 /* > */
121 /* > N-K-L K M-K K+L-M */
122 /* > ( 0 R ) = K ( 0 R11 R12 R13 ) */
123 /* > M-K ( 0 0 R22 R23 ) */
124 /* > K+L-M ( 0 0 0 R33 ) */
125 /* > */
126 /* > where */
127 /* > C = diag( ALPHA(K+1), ... , ALPHA(M) ), */
128 /* > S = diag( BETA(K+1), ... , BETA(M) ), */
129 /* > C**2 + S**2 = I. */
130 /* > */
131 /* > R = ( R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N) and R33 is stored */
132 /* > ( 0 R22 R23 ) */
133 /* > in B(M-K+1:L,N+M-K-L+1:N) on exit. */
134 /* > */
135 /* > The computation of the unitary transformation matrices U, V or Q */
136 /* > is optional. These matrices may either be formed explicitly, or they */
137 /* > may be postmultiplied into input matrices U1, V1, or Q1. */
138 /* > \endverbatim */
139 /* Arguments: */
140 /* ========== */
141 /* > \param[in] JOBU */
142 /* > \verbatim */
143 /* > JOBU is CHARACTER*1 */
144 /* > = 'U': U must contain a unitary matrix U1 on entry, and */
145 /* > the product U1*U is returned;
146 */
147 /* > = 'I': U is initialized to the unit matrix, and the */
148 /* > unitary matrix U is returned;
149 */
150 /* > = 'N': U is not computed. */
151 /* > \endverbatim */
152 /* > */
153 /* > \param[in] JOBV */
154 /* > \verbatim */
155 /* > JOBV is CHARACTER*1 */
156 /* > = 'V': V must contain a unitary matrix V1 on entry, and */
157 /* > the product V1*V is returned;
158 */
159 /* > = 'I': V is initialized to the unit matrix, and the */
160 /* > unitary matrix V is returned;
161 */
162 /* > = 'N': V is not computed. */
163 /* > \endverbatim */
164 /* > */
165 /* > \param[in] JOBQ */
166 /* > \verbatim */
167 /* > JOBQ is CHARACTER*1 */
168 /* > = 'Q': Q must contain a unitary matrix Q1 on entry, and */
169 /* > the product Q1*Q is returned;
170 */
171 /* > = 'I': Q is initialized to the unit matrix, and the */
172 /* > unitary matrix Q is returned;
173 */
174 /* > = 'N': Q is not computed. */
175 /* > \endverbatim */
176 /* > */
177 /* > \param[in] M */
178 /* > \verbatim */
179 /* > M is INTEGER */
180 /* > The number of rows of the matrix A. M >= 0. */
181 /* > \endverbatim */
182 /* > */
183 /* > \param[in] P */
184 /* > \verbatim */
185 /* > P is INTEGER */
186 /* > The number of rows of the matrix B. P >= 0. */
187 /* > \endverbatim */
188 /* > */
189 /* > \param[in] N */
190 /* > \verbatim */
191 /* > N is INTEGER */
192 /* > The number of columns of the matrices A and B. N >= 0. */
193 /* > \endverbatim */
194 /* > */
195 /* > \param[in] K */
196 /* > \verbatim */
197 /* > K is INTEGER */
198 /* > \endverbatim */
199 /* > */
200 /* > \param[in] L */
201 /* > \verbatim */
202 /* > L is INTEGER */
203 /* > */
204 /* > K and L specify the subblocks in the input matrices A and B: */
205 /* > A23 = A(K+1:MIN(K+L,M),N-L+1:N) and B13 = B(1:L,,N-L+1:N) */
206 /* > of A and B, whose GSVD is going to be computed by CTGSJA. */
207 /* > See Further Details. */
208 /* > \endverbatim */
209 /* > */
210 /* > \param[in,out] A */
211 /* > \verbatim */
212 /* > A is COMPLEX array, dimension (LDA,N) */
213 /* > On entry, the M-by-N matrix A. */
214 /* > On exit, A(N-K+1:N,1:MIN(K+L,M) ) contains the triangular */
215 /* > matrix R or part of R. See Purpose for details. */
216 /* > \endverbatim */
217 /* > */
218 /* > \param[in] LDA */
219 /* > \verbatim */
220 /* > LDA is INTEGER */
221 /* > The leading dimension of the array A. LDA >= max(1,M). */
222 /* > \endverbatim */
223 /* > */
224 /* > \param[in,out] B */
225 /* > \verbatim */
226 /* > B is COMPLEX array, dimension (LDB,N) */
227 /* > On entry, the P-by-N matrix B. */
228 /* > On exit, if necessary, B(M-K+1:L,N+M-K-L+1:N) contains */
229 /* > a part of R. See Purpose for details. */
230 /* > \endverbatim */
231 /* > */
232 /* > \param[in] LDB */
233 /* > \verbatim */
234 /* > LDB is INTEGER */
235 /* > The leading dimension of the array B. LDB >= max(1,P). */
236 /* > \endverbatim */
237 /* > */
238 /* > \param[in] TOLA */
239 /* > \verbatim */
240 /* > TOLA is REAL */
241 /* > \endverbatim */
242 /* > */
243 /* > \param[in] TOLB */
244 /* > \verbatim */
245 /* > TOLB is REAL */
246 /* > */
247 /* > TOLA and TOLB are the convergence criteria for the Jacobi- */
248 /* > Kogbetliantz iteration procedure. Generally, they are the */
249 /* > same as used in the preprocessing step, say */
250 /* > TOLA = MAX(M,N)*norm(A)*MACHEPS, */
251 /* > TOLB = MAX(P,N)*norm(B)*MACHEPS. */
252 /* > \endverbatim */
253 /* > */
254 /* > \param[out] ALPHA */
255 /* > \verbatim */
256 /* > ALPHA is REAL array, dimension (N) */
257 /* > \endverbatim */
258 /* > */
259 /* > \param[out] BETA */
260 /* > \verbatim */
261 /* > BETA is REAL array, dimension (N) */
262 /* > */
263 /* > On exit, ALPHA and BETA contain the generalized singular */
264 /* > value pairs of A and B;
265 */
266 /* > ALPHA(1:K) = 1, */
267 /* > BETA(1:K) = 0, */
268 /* > and if M-K-L >= 0, */
269 /* > ALPHA(K+1:K+L) = diag(C), */
270 /* > BETA(K+1:K+L) = diag(S), */
271 /* > or if M-K-L < 0, */
272 /* > ALPHA(K+1:M)= C, ALPHA(M+1:K+L)= 0 */
273 /* > BETA(K+1:M) = S, BETA(M+1:K+L) = 1. */
274 /* > Furthermore, if K+L < N, */
275 /* > ALPHA(K+L+1:N) = 0 */
276 /* > BETA(K+L+1:N) = 0. */
277 /* > \endverbatim */
278 /* > */
279 /* > \param[in,out] U */
280 /* > \verbatim */
281 /* > U is COMPLEX array, dimension (LDU,M) */
282 /* > On entry, if JOBU = 'U', U must contain a matrix U1 (usually */
283 /* > the unitary matrix returned by CGGSVP). */
284 /* > On exit, */
285 /* > if JOBU = 'I', U contains the unitary matrix U;
286 */
287 /* > if JOBU = 'U', U contains the product U1*U. */
288 /* > If JOBU = 'N', U is not referenced. */
289 /* > \endverbatim */
290 /* > */
291 /* > \param[in] LDU */
292 /* > \verbatim */
293 /* > LDU is INTEGER */
294 /* > The leading dimension of the array U. LDU >= max(1,M) if */
295 /* > JOBU = 'U';
296 LDU >= 1 otherwise. */
297 /* > \endverbatim */
298 /* > */
299 /* > \param[in,out] V */
300 /* > \verbatim */
301 /* > V is COMPLEX array, dimension (LDV,P) */
302 /* > On entry, if JOBV = 'V', V must contain a matrix V1 (usually */
303 /* > the unitary matrix returned by CGGSVP). */
304 /* > On exit, */
305 /* > if JOBV = 'I', V contains the unitary matrix V;
306 */
307 /* > if JOBV = 'V', V contains the product V1*V. */
308 /* > If JOBV = 'N', V is not referenced. */
309 /* > \endverbatim */
310 /* > */
311 /* > \param[in] LDV */
312 /* > \verbatim */
313 /* > LDV is INTEGER */
314 /* > The leading dimension of the array V. LDV >= max(1,P) if */
315 /* > JOBV = 'V';
316 LDV >= 1 otherwise. */
317 /* > \endverbatim */
318 /* > */
319 /* > \param[in,out] Q */
320 /* > \verbatim */
321 /* > Q is COMPLEX array, dimension (LDQ,N) */
322 /* > On entry, if JOBQ = 'Q', Q must contain a matrix Q1 (usually */
323 /* > the unitary matrix returned by CGGSVP). */
324 /* > On exit, */
325 /* > if JOBQ = 'I', Q contains the unitary matrix Q;
326 */
327 /* > if JOBQ = 'Q', Q contains the product Q1*Q. */
328 /* > If JOBQ = 'N', Q is not referenced. */
329 /* > \endverbatim */
330 /* > */
331 /* > \param[in] LDQ */
332 /* > \verbatim */
333 /* > LDQ is INTEGER */
334 /* > The leading dimension of the array Q. LDQ >= max(1,N) if */
335 /* > JOBQ = 'Q';
336 LDQ >= 1 otherwise. */
337 /* > \endverbatim */
338 /* > */
339 /* > \param[out] WORK */
340 /* > \verbatim */
341 /* > WORK is COMPLEX array, dimension (2*N) */
342 /* > \endverbatim */
343 /* > */
344 /* > \param[out] NCYCLE */
345 /* > \verbatim */
346 /* > NCYCLE is INTEGER */
347 /* > The number of cycles required for convergence. */
348 /* > \endverbatim */
349 /* > */
350 /* > \param[out] INFO */
351 /* > \verbatim */
352 /* > INFO is INTEGER */
353 /* > = 0: successful exit */
354 /* > < 0: if INFO = -i, the i-th argument had an illegal value. */
355 /* > = 1: the procedure does not converge after MAXIT cycles. */
356 /* > \endverbatim */
357 /* > \par Internal Parameters: */
358 /* ========================= */
359 /* > */
360 /* > \verbatim */
361 /* > MAXIT INTEGER */
362 /* > MAXIT specifies the total loops that the iterative procedure */
363 /* > may take. If after MAXIT cycles, the routine fails to */
364 /* > converge, we return INFO = 1. */
365 /* > \endverbatim */
366 /* Authors: */
367 /* ======== */
368 /* > \author Univ. of Tennessee */
369 /* > \author Univ. of California Berkeley */
370 /* > \author Univ. of Colorado Denver */
371 /* > \author NAG Ltd. */
372 /* > \date November 2011 */
373 /* > \ingroup complexOTHERcomputational */
374 /* > \par Further Details: */
375 /* ===================== */
376 /* > */
377 /* > \verbatim */
378 /* > */
379 /* > CTGSJA essentially uses a variant of Kogbetliantz algorithm to reduce */
380 /* > min(L,M-K)-by-L triangular (or trapezoidal) matrix A23 and L-by-L */
381 /* > matrix B13 to the form: */
382 /* > */
383 /* > U1**H *A13*Q1 = C1*R1;
384 V1**H *B13*Q1 = S1*R1, */
385 /* > */
386 /* > where U1, V1 and Q1 are unitary matrix. */
387 /* > C1 and S1 are diagonal matrices satisfying */
388 /* > */
389 /* > C1**2 + S1**2 = I, */
390 /* > */
391 /* > and R1 is an L-by-L nonsingular upper triangular matrix. */
392 /* > \endverbatim */
393 /* > */
394 /* ===================================================================== */
395 /* Subroutine */
ctgsja_(char * jobu,char * jobv,char * jobq,integer * m,integer * p,integer * n,integer * k,integer * l,complex * a,integer * lda,complex * b,integer * ldb,real * tola,real * tolb,real * alpha,real * beta,complex * u,integer * ldu,complex * v,integer * ldv,complex * q,integer * ldq,complex * work,integer * ncycle,integer * info)396 int ctgsja_(char *jobu, char *jobv, char *jobq, integer *m, integer *p, integer *n, integer *k, integer *l, complex *a, integer * lda, complex *b, integer *ldb, real *tola, real *tolb, real *alpha, real *beta, complex *u, integer *ldu, complex *v, integer *ldv, complex *q, integer *ldq, complex *work, integer *ncycle, integer * info)
397 {
398     /* System generated locals */
399     integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4;
400     real r__1;
401     complex q__1;
402     /* Builtin functions */
403     void r_cnjg(complex *, complex *);
404     /* Local variables */
405     integer i__, j;
406     real a1, b1, a3, b3;
407     complex a2, b2;
408     real csq, csu, csv;
409     complex snq;
410     real rwk;
411     complex snu, snv;
412     extern /* Subroutine */
413     int crot_(integer *, complex *, integer *, complex *, integer *, real *, complex *);
414     real gamma;
415     extern logical lsame_(char *, char *);
416     extern /* Subroutine */
417     int ccopy_(integer *, complex *, integer *, complex *, integer *);
418     logical initq, initu, initv, wantq, upper;
419     real error, ssmin;
420     logical wantu, wantv;
421     extern /* Subroutine */
422     int clags2_(logical *, real *, complex *, real *, real *, complex *, real *, real *, complex *, real *, complex *, real *, complex *), clapll_(integer *, complex *, integer *, complex *, integer *, real *), csscal_(integer *, real *, complex *, integer *);
423     integer kcycle;
424     extern /* Subroutine */
425     int claset_(char *, integer *, integer *, complex *, complex *, complex *, integer *), xerbla_(char *, integer *), slartg_(real *, real *, real *, real *, real * );
426     /* -- LAPACK computational routine (version 3.4.0) -- */
427     /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
428     /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
429     /* November 2011 */
430     /* .. Scalar Arguments .. */
431     /* .. */
432     /* .. Array Arguments .. */
433     /* .. */
434     /* ===================================================================== */
435     /* .. Parameters .. */
436     /* .. */
437     /* .. Local Scalars .. */
438     /* .. */
439     /* .. External Functions .. */
440     /* .. */
441     /* .. External Subroutines .. */
442     /* .. */
443     /* .. Intrinsic Functions .. */
444     /* .. */
445     /* .. Executable Statements .. */
446     /* Decode and test the input parameters */
447     /* Parameter adjustments */
448     a_dim1 = *lda;
449     a_offset = 1 + a_dim1;
450     a -= a_offset;
451     b_dim1 = *ldb;
452     b_offset = 1 + b_dim1;
453     b -= b_offset;
454     --alpha;
455     --beta;
456     u_dim1 = *ldu;
457     u_offset = 1 + u_dim1;
458     u -= u_offset;
459     v_dim1 = *ldv;
460     v_offset = 1 + v_dim1;
461     v -= v_offset;
462     q_dim1 = *ldq;
463     q_offset = 1 + q_dim1;
464     q -= q_offset;
465     --work;
466     /* Function Body */
467     initu = lsame_(jobu, "I");
468     wantu = initu || lsame_(jobu, "U");
469     initv = lsame_(jobv, "I");
470     wantv = initv || lsame_(jobv, "V");
471     initq = lsame_(jobq, "I");
472     wantq = initq || lsame_(jobq, "Q");
473     *info = 0;
474     if (! (initu || wantu || lsame_(jobu, "N")))
475     {
476         *info = -1;
477     }
478     else if (! (initv || wantv || lsame_(jobv, "N")))
479     {
480         *info = -2;
481     }
482     else if (! (initq || wantq || lsame_(jobq, "N")))
483     {
484         *info = -3;
485     }
486     else if (*m < 0)
487     {
488         *info = -4;
489     }
490     else if (*p < 0)
491     {
492         *info = -5;
493     }
494     else if (*n < 0)
495     {
496         *info = -6;
497     }
498     else if (*lda < max(1,*m))
499     {
500         *info = -10;
501     }
502     else if (*ldb < max(1,*p))
503     {
504         *info = -12;
505     }
506     else if (*ldu < 1 || wantu && *ldu < *m)
507     {
508         *info = -18;
509     }
510     else if (*ldv < 1 || wantv && *ldv < *p)
511     {
512         *info = -20;
513     }
514     else if (*ldq < 1 || wantq && *ldq < *n)
515     {
516         *info = -22;
517     }
518     if (*info != 0)
519     {
520         i__1 = -(*info);
521         xerbla_("CTGSJA", &i__1);
522         return 0;
523     }
524     /* Initialize U, V and Q, if necessary */
525     if (initu)
526     {
527         claset_("Full", m, m, &c_b1, &c_b2, &u[u_offset], ldu);
528     }
529     if (initv)
530     {
531         claset_("Full", p, p, &c_b1, &c_b2, &v[v_offset], ldv);
532     }
533     if (initq)
534     {
535         claset_("Full", n, n, &c_b1, &c_b2, &q[q_offset], ldq);
536     }
537     /* Loop until convergence */
538     upper = FALSE_;
539     for (kcycle = 1;
540             kcycle <= 40;
541             ++kcycle)
542     {
543         upper = ! upper;
544         i__1 = *l - 1;
545         for (i__ = 1;
546                 i__ <= i__1;
547                 ++i__)
548         {
549             i__2 = *l;
550             for (j = i__ + 1;
551                     j <= i__2;
552                     ++j)
553             {
554                 a1 = 0.f;
555                 a2.r = 0.f;
556                 a2.i = 0.f; // , expr subst
557                 a3 = 0.f;
558                 if (*k + i__ <= *m)
559                 {
560                     i__3 = *k + i__ + (*n - *l + i__) * a_dim1;
561                     a1 = a[i__3].r;
562                 }
563                 if (*k + j <= *m)
564                 {
565                     i__3 = *k + j + (*n - *l + j) * a_dim1;
566                     a3 = a[i__3].r;
567                 }
568                 i__3 = i__ + (*n - *l + i__) * b_dim1;
569                 b1 = b[i__3].r;
570                 i__3 = j + (*n - *l + j) * b_dim1;
571                 b3 = b[i__3].r;
572                 if (upper)
573                 {
574                     if (*k + i__ <= *m)
575                     {
576                         i__3 = *k + i__ + (*n - *l + j) * a_dim1;
577                         a2.r = a[i__3].r;
578                         a2.i = a[i__3].i; // , expr subst
579                     }
580                     i__3 = i__ + (*n - *l + j) * b_dim1;
581                     b2.r = b[i__3].r;
582                     b2.i = b[i__3].i; // , expr subst
583                 }
584                 else
585                 {
586                     if (*k + j <= *m)
587                     {
588                         i__3 = *k + j + (*n - *l + i__) * a_dim1;
589                         a2.r = a[i__3].r;
590                         a2.i = a[i__3].i; // , expr subst
591                     }
592                     i__3 = j + (*n - *l + i__) * b_dim1;
593                     b2.r = b[i__3].r;
594                     b2.i = b[i__3].i; // , expr subst
595                 }
596                 clags2_(&upper, &a1, &a2, &a3, &b1, &b2, &b3, &csu, &snu, & csv, &snv, &csq, &snq);
597                 /* Update (K+I)-th and (K+J)-th rows of matrix A: U**H *A */
598                 if (*k + j <= *m)
599                 {
600                     r_cnjg(&q__1, &snu);
601                     crot_(l, &a[*k + j + (*n - *l + 1) * a_dim1], lda, &a[*k + i__ + (*n - *l + 1) * a_dim1], lda, &csu, &q__1) ;
602                 }
603                 /* Update I-th and J-th rows of matrix B: V**H *B */
604                 r_cnjg(&q__1, &snv);
605                 crot_(l, &b[j + (*n - *l + 1) * b_dim1], ldb, &b[i__ + (*n - * l + 1) * b_dim1], ldb, &csv, &q__1);
606                 /* Update (N-L+I)-th and (N-L+J)-th columns of matrices */
607                 /* A and B: A*Q and B*Q */
608                 /* Computing MIN */
609                 i__4 = *k + *l;
610                 i__3 = min(i__4,*m);
611                 crot_(&i__3, &a[(*n - *l + j) * a_dim1 + 1], &c__1, &a[(*n - * l + i__) * a_dim1 + 1], &c__1, &csq, &snq);
612                 crot_(l, &b[(*n - *l + j) * b_dim1 + 1], &c__1, &b[(*n - *l + i__) * b_dim1 + 1], &c__1, &csq, &snq);
613                 if (upper)
614                 {
615                     if (*k + i__ <= *m)
616                     {
617                         i__3 = *k + i__ + (*n - *l + j) * a_dim1;
618                         a[i__3].r = 0.f;
619                         a[i__3].i = 0.f; // , expr subst
620                     }
621                     i__3 = i__ + (*n - *l + j) * b_dim1;
622                     b[i__3].r = 0.f;
623                     b[i__3].i = 0.f; // , expr subst
624                 }
625                 else
626                 {
627                     if (*k + j <= *m)
628                     {
629                         i__3 = *k + j + (*n - *l + i__) * a_dim1;
630                         a[i__3].r = 0.f;
631                         a[i__3].i = 0.f; // , expr subst
632                     }
633                     i__3 = j + (*n - *l + i__) * b_dim1;
634                     b[i__3].r = 0.f;
635                     b[i__3].i = 0.f; // , expr subst
636                 }
637                 /* Ensure that the diagonal elements of A and B are real. */
638                 if (*k + i__ <= *m)
639                 {
640                     i__3 = *k + i__ + (*n - *l + i__) * a_dim1;
641                     i__4 = *k + i__ + (*n - *l + i__) * a_dim1;
642                     r__1 = a[i__4].r;
643                     a[i__3].r = r__1;
644                     a[i__3].i = 0.f; // , expr subst
645                 }
646                 if (*k + j <= *m)
647                 {
648                     i__3 = *k + j + (*n - *l + j) * a_dim1;
649                     i__4 = *k + j + (*n - *l + j) * a_dim1;
650                     r__1 = a[i__4].r;
651                     a[i__3].r = r__1;
652                     a[i__3].i = 0.f; // , expr subst
653                 }
654                 i__3 = i__ + (*n - *l + i__) * b_dim1;
655                 i__4 = i__ + (*n - *l + i__) * b_dim1;
656                 r__1 = b[i__4].r;
657                 b[i__3].r = r__1;
658                 b[i__3].i = 0.f; // , expr subst
659                 i__3 = j + (*n - *l + j) * b_dim1;
660                 i__4 = j + (*n - *l + j) * b_dim1;
661                 r__1 = b[i__4].r;
662                 b[i__3].r = r__1;
663                 b[i__3].i = 0.f; // , expr subst
664                 /* Update unitary matrices U, V, Q, if desired. */
665                 if (wantu && *k + j <= *m)
666                 {
667                     crot_(m, &u[(*k + j) * u_dim1 + 1], &c__1, &u[(*k + i__) * u_dim1 + 1], &c__1, &csu, &snu);
668                 }
669                 if (wantv)
670                 {
671                     crot_(p, &v[j * v_dim1 + 1], &c__1, &v[i__ * v_dim1 + 1], &c__1, &csv, &snv);
672                 }
673                 if (wantq)
674                 {
675                     crot_(n, &q[(*n - *l + j) * q_dim1 + 1], &c__1, &q[(*n - * l + i__) * q_dim1 + 1], &c__1, &csq, &snq);
676                 }
677                 /* L10: */
678             }
679             /* L20: */
680         }
681         if (! upper)
682         {
683             /* The matrices A13 and B13 were lower triangular at the start */
684             /* of the cycle, and are now upper triangular. */
685             /* Convergence test: test the parallelism of the corresponding */
686             /* rows of A and B. */
687             error = 0.f;
688             /* Computing MIN */
689             i__2 = *l;
690             i__3 = *m - *k; // , expr subst
691             i__1 = min(i__2,i__3);
692             for (i__ = 1;
693                     i__ <= i__1;
694                     ++i__)
695             {
696                 i__2 = *l - i__ + 1;
697                 ccopy_(&i__2, &a[*k + i__ + (*n - *l + i__) * a_dim1], lda, & work[1], &c__1);
698                 i__2 = *l - i__ + 1;
699                 ccopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &work[* l + 1], &c__1);
700                 i__2 = *l - i__ + 1;
701                 clapll_(&i__2, &work[1], &c__1, &work[*l + 1], &c__1, &ssmin);
702                 error = max(error,ssmin);
703                 /* L30: */
704             }
705             if (f2c_abs(error) <= min(*tola,*tolb))
706             {
707                 goto L50;
708             }
709         }
710         /* End of cycle loop */
711         /* L40: */
712     }
713     /* The algorithm has not converged after MAXIT cycles. */
714     *info = 1;
715     goto L100;
716 L50: /* If ERROR <= MIN(TOLA,TOLB), then the algorithm has converged. */
717     /* Compute the generalized singular value pairs (ALPHA, BETA), and */
718     /* set the triangular matrix R to array A. */
719     i__1 = *k;
720     for (i__ = 1;
721             i__ <= i__1;
722             ++i__)
723     {
724         alpha[i__] = 1.f;
725         beta[i__] = 0.f;
726         /* L60: */
727     }
728     /* Computing MIN */
729     i__2 = *l;
730     i__3 = *m - *k; // , expr subst
731     i__1 = min(i__2,i__3);
732     for (i__ = 1;
733             i__ <= i__1;
734             ++i__)
735     {
736         i__2 = *k + i__ + (*n - *l + i__) * a_dim1;
737         a1 = a[i__2].r;
738         i__2 = i__ + (*n - *l + i__) * b_dim1;
739         b1 = b[i__2].r;
740         if (a1 != 0.f)
741         {
742             gamma = b1 / a1;
743             if (gamma < 0.f)
744             {
745                 i__2 = *l - i__ + 1;
746                 csscal_(&i__2, &c_b39, &b[i__ + (*n - *l + i__) * b_dim1], ldb);
747                 if (wantv)
748                 {
749                     csscal_(p, &c_b39, &v[i__ * v_dim1 + 1], &c__1);
750                 }
751             }
752             r__1 = f2c_abs(gamma);
753             slartg_(&r__1, &c_b42, &beta[*k + i__], &alpha[*k + i__], &rwk);
754             if (alpha[*k + i__] >= beta[*k + i__])
755             {
756                 i__2 = *l - i__ + 1;
757                 r__1 = 1.f / alpha[*k + i__];
758                 csscal_(&i__2, &r__1, &a[*k + i__ + (*n - *l + i__) * a_dim1], lda);
759             }
760             else
761             {
762                 i__2 = *l - i__ + 1;
763                 r__1 = 1.f / beta[*k + i__];
764                 csscal_(&i__2, &r__1, &b[i__ + (*n - *l + i__) * b_dim1], ldb) ;
765                 i__2 = *l - i__ + 1;
766                 ccopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &a[*k + i__ + (*n - *l + i__) * a_dim1], lda);
767             }
768         }
769         else
770         {
771             alpha[*k + i__] = 0.f;
772             beta[*k + i__] = 1.f;
773             i__2 = *l - i__ + 1;
774             ccopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &a[*k + i__ + (*n - *l + i__) * a_dim1], lda);
775         }
776         /* L70: */
777     }
778     /* Post-assignment */
779     i__1 = *k + *l;
780     for (i__ = *m + 1;
781             i__ <= i__1;
782             ++i__)
783     {
784         alpha[i__] = 0.f;
785         beta[i__] = 1.f;
786         /* L80: */
787     }
788     if (*k + *l < *n)
789     {
790         i__1 = *n;
791         for (i__ = *k + *l + 1;
792                 i__ <= i__1;
793                 ++i__)
794         {
795             alpha[i__] = 0.f;
796             beta[i__] = 0.f;
797             /* L90: */
798         }
799     }
800 L100:
801     *ncycle = kcycle;
802     return 0;
803     /* End of CTGSJA */
804 }
805 /* ctgsja_ */
806