ctgsja.c
Go to the documentation of this file.
00001 /* ctgsja.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static complex c_b1 = {0.f,0.f};
00019 static complex c_b2 = {1.f,0.f};
00020 static integer c__1 = 1;
00021 static real c_b39 = -1.f;
00022 static real c_b42 = 1.f;
00023 
00024 /* Subroutine */ int ctgsja_(char *jobu, char *jobv, char *jobq, integer *m, 
00025         integer *p, integer *n, integer *k, integer *l, complex *a, integer *
00026         lda, complex *b, integer *ldb, real *tola, real *tolb, real *alpha, 
00027         real *beta, complex *u, integer *ldu, complex *v, integer *ldv, 
00028         complex *q, integer *ldq, complex *work, integer *ncycle, integer *
00029         info)
00030 {
00031     /* System generated locals */
00032     integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, u_dim1, 
00033             u_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4;
00034     real r__1;
00035     complex q__1;
00036 
00037     /* Builtin functions */
00038     void r_cnjg(complex *, complex *);
00039 
00040     /* Local variables */
00041     integer i__, j;
00042     real a1, b1, a3, b3;
00043     complex a2, b2;
00044     real csq, csu, csv;
00045     complex snq;
00046     real rwk;
00047     complex snu, snv;
00048     extern /* Subroutine */ int crot_(integer *, complex *, integer *, 
00049             complex *, integer *, real *, complex *);
00050     real gamma;
00051     extern logical lsame_(char *, char *);
00052     extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, 
00053             complex *, integer *);
00054     logical initq, initu, initv, wantq, upper;
00055     real error, ssmin;
00056     logical wantu, wantv;
00057     extern /* Subroutine */ int clags2_(logical *, real *, complex *, real *, 
00058             real *, complex *, real *, real *, complex *, real *, complex *, 
00059             real *, complex *), clapll_(integer *, complex *, integer *, 
00060             complex *, integer *, real *), csscal_(integer *, real *, complex 
00061             *, integer *);
00062     integer kcycle;
00063     extern /* Subroutine */ int claset_(char *, integer *, integer *, complex 
00064             *, complex *, complex *, integer *), xerbla_(char *, 
00065             integer *), slartg_(real *, real *, real *, real *, real *
00066 );
00067 
00068 
00069 /*  -- LAPACK routine (version 3.2) -- */
00070 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00071 /*     November 2006 */
00072 
00073 /*     .. Scalar Arguments .. */
00074 /*     .. */
00075 /*     .. Array Arguments .. */
00076 /*     .. */
00077 
00078 /*  Purpose */
00079 /*  ======= */
00080 
00081 /*  CTGSJA computes the generalized singular value decomposition (GSVD) */
00082 /*  of two complex upper triangular (or trapezoidal) matrices A and B. */
00083 
00084 /*  On entry, it is assumed that matrices A and B have the following */
00085 /*  forms, which may be obtained by the preprocessing subroutine CGGSVP */
00086 /*  from a general M-by-N matrix A and P-by-N matrix B: */
00087 
00088 /*               N-K-L  K    L */
00089 /*     A =    K ( 0    A12  A13 ) if M-K-L >= 0; */
00090 /*            L ( 0     0   A23 ) */
00091 /*        M-K-L ( 0     0    0  ) */
00092 
00093 /*             N-K-L  K    L */
00094 /*     A =  K ( 0    A12  A13 ) if M-K-L < 0; */
00095 /*        M-K ( 0     0   A23 ) */
00096 
00097 /*             N-K-L  K    L */
00098 /*     B =  L ( 0     0   B13 ) */
00099 /*        P-L ( 0     0    0  ) */
00100 
00101 /*  where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular */
00102 /*  upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0, */
00103 /*  otherwise A23 is (M-K)-by-L upper trapezoidal. */
00104 
00105 /*  On exit, */
00106 
00107 /*         U'*A*Q = D1*( 0 R ),    V'*B*Q = D2*( 0 R ), */
00108 
00109 /*  where U, V and Q are unitary matrices, Z' denotes the conjugate */
00110 /*  transpose of Z, R is a nonsingular upper triangular matrix, and D1 */
00111 /*  and D2 are ``diagonal'' matrices, which are of the following */
00112 /*  structures: */
00113 
00114 /*  If M-K-L >= 0, */
00115 
00116 /*                      K  L */
00117 /*         D1 =     K ( I  0 ) */
00118 /*                  L ( 0  C ) */
00119 /*              M-K-L ( 0  0 ) */
00120 
00121 /*                     K  L */
00122 /*         D2 = L   ( 0  S ) */
00123 /*              P-L ( 0  0 ) */
00124 
00125 /*                 N-K-L  K    L */
00126 /*    ( 0 R ) = K (  0   R11  R12 ) K */
00127 /*              L (  0    0   R22 ) L */
00128 
00129 /*  where */
00130 
00131 /*    C = diag( ALPHA(K+1), ... , ALPHA(K+L) ), */
00132 /*    S = diag( BETA(K+1),  ... , BETA(K+L) ), */
00133 /*    C**2 + S**2 = I. */
00134 
00135 /*    R is stored in A(1:K+L,N-K-L+1:N) on exit. */
00136 
00137 /*  If M-K-L < 0, */
00138 
00139 /*                 K M-K K+L-M */
00140 /*      D1 =   K ( I  0    0   ) */
00141 /*           M-K ( 0  C    0   ) */
00142 
00143 /*                   K M-K K+L-M */
00144 /*      D2 =   M-K ( 0  S    0   ) */
00145 /*           K+L-M ( 0  0    I   ) */
00146 /*             P-L ( 0  0    0   ) */
00147 
00148 /*                 N-K-L  K   M-K  K+L-M */
00149 /* ( 0 R ) =    K ( 0    R11  R12  R13  ) */
00150 /*            M-K ( 0     0   R22  R23  ) */
00151 /*          K+L-M ( 0     0    0   R33  ) */
00152 
00153 /*  where */
00154 /*  C = diag( ALPHA(K+1), ... , ALPHA(M) ), */
00155 /*  S = diag( BETA(K+1),  ... , BETA(M) ), */
00156 /*  C**2 + S**2 = I. */
00157 
00158 /*  R = ( R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N) and R33 is stored */
00159 /*      (  0  R22 R23 ) */
00160 /*  in B(M-K+1:L,N+M-K-L+1:N) on exit. */
00161 
00162 /*  The computation of the unitary transformation matrices U, V or Q */
00163 /*  is optional.  These matrices may either be formed explicitly, or they */
00164 /*  may be postmultiplied into input matrices U1, V1, or Q1. */
00165 
00166 /*  Arguments */
00167 /*  ========= */
00168 
00169 /*  JOBU    (input) CHARACTER*1 */
00170 /*          = 'U':  U must contain a unitary matrix U1 on entry, and */
00171 /*                  the product U1*U is returned; */
00172 /*          = 'I':  U is initialized to the unit matrix, and the */
00173 /*                  unitary matrix U is returned; */
00174 /*          = 'N':  U is not computed. */
00175 
00176 /*  JOBV    (input) CHARACTER*1 */
00177 /*          = 'V':  V must contain a unitary matrix V1 on entry, and */
00178 /*                  the product V1*V is returned; */
00179 /*          = 'I':  V is initialized to the unit matrix, and the */
00180 /*                  unitary matrix V is returned; */
00181 /*          = 'N':  V is not computed. */
00182 
00183 /*  JOBQ    (input) CHARACTER*1 */
00184 /*          = 'Q':  Q must contain a unitary matrix Q1 on entry, and */
00185 /*                  the product Q1*Q is returned; */
00186 /*          = 'I':  Q is initialized to the unit matrix, and the */
00187 /*                  unitary matrix Q is returned; */
00188 /*          = 'N':  Q is not computed. */
00189 
00190 /*  M       (input) INTEGER */
00191 /*          The number of rows of the matrix A.  M >= 0. */
00192 
00193 /*  P       (input) INTEGER */
00194 /*          The number of rows of the matrix B.  P >= 0. */
00195 
00196 /*  N       (input) INTEGER */
00197 /*          The number of columns of the matrices A and B.  N >= 0. */
00198 
00199 /*  K       (input) INTEGER */
00200 /*  L       (input) INTEGER */
00201 /*          K and L specify the subblocks in the input matrices A and B: */
00202 /*          A23 = A(K+1:MIN(K+L,M),N-L+1:N) and B13 = B(1:L,,N-L+1:N) */
00203 /*          of A and B, whose GSVD is going to be computed by CTGSJA. */
00204 /*          See Further details. */
00205 
00206 /*  A       (input/output) COMPLEX array, dimension (LDA,N) */
00207 /*          On entry, the M-by-N matrix A. */
00208 /*          On exit, A(N-K+1:N,1:MIN(K+L,M) ) contains the triangular */
00209 /*          matrix R or part of R.  See Purpose for details. */
00210 
00211 /*  LDA     (input) INTEGER */
00212 /*          The leading dimension of the array A. LDA >= max(1,M). */
00213 
00214 /*  B       (input/output) COMPLEX array, dimension (LDB,N) */
00215 /*          On entry, the P-by-N matrix B. */
00216 /*          On exit, if necessary, B(M-K+1:L,N+M-K-L+1:N) contains */
00217 /*          a part of R.  See Purpose for details. */
00218 
00219 /*  LDB     (input) INTEGER */
00220 /*          The leading dimension of the array B. LDB >= max(1,P). */
00221 
00222 /*  TOLA    (input) REAL */
00223 /*  TOLB    (input) REAL */
00224 /*          TOLA and TOLB are the convergence criteria for the Jacobi- */
00225 /*          Kogbetliantz iteration procedure. Generally, they are the */
00226 /*          same as used in the preprocessing step, say */
00227 /*              TOLA = MAX(M,N)*norm(A)*MACHEPS, */
00228 /*              TOLB = MAX(P,N)*norm(B)*MACHEPS. */
00229 
00230 /*  ALPHA   (output) REAL array, dimension (N) */
00231 /*  BETA    (output) REAL array, dimension (N) */
00232 /*          On exit, ALPHA and BETA contain the generalized singular */
00233 /*          value pairs of A and B; */
00234 /*            ALPHA(1:K) = 1, */
00235 /*            BETA(1:K)  = 0, */
00236 /*          and if M-K-L >= 0, */
00237 /*            ALPHA(K+1:K+L) = diag(C), */
00238 /*            BETA(K+1:K+L)  = diag(S), */
00239 /*          or if M-K-L < 0, */
00240 /*            ALPHA(K+1:M)= C, ALPHA(M+1:K+L)= 0 */
00241 /*            BETA(K+1:M) = S, BETA(M+1:K+L) = 1. */
00242 /*          Furthermore, if K+L < N, */
00243 /*            ALPHA(K+L+1:N) = 0 */
00244 /*            BETA(K+L+1:N)  = 0. */
00245 
00246 /*  U       (input/output) COMPLEX array, dimension (LDU,M) */
00247 /*          On entry, if JOBU = 'U', U must contain a matrix U1 (usually */
00248 /*          the unitary matrix returned by CGGSVP). */
00249 /*          On exit, */
00250 /*          if JOBU = 'I', U contains the unitary matrix U; */
00251 /*          if JOBU = 'U', U contains the product U1*U. */
00252 /*          If JOBU = 'N', U is not referenced. */
00253 
00254 /*  LDU     (input) INTEGER */
00255 /*          The leading dimension of the array U. LDU >= max(1,M) if */
00256 /*          JOBU = 'U'; LDU >= 1 otherwise. */
00257 
00258 /*  V       (input/output) COMPLEX array, dimension (LDV,P) */
00259 /*          On entry, if JOBV = 'V', V must contain a matrix V1 (usually */
00260 /*          the unitary matrix returned by CGGSVP). */
00261 /*          On exit, */
00262 /*          if JOBV = 'I', V contains the unitary matrix V; */
00263 /*          if JOBV = 'V', V contains the product V1*V. */
00264 /*          If JOBV = 'N', V is not referenced. */
00265 
00266 /*  LDV     (input) INTEGER */
00267 /*          The leading dimension of the array V. LDV >= max(1,P) if */
00268 /*          JOBV = 'V'; LDV >= 1 otherwise. */
00269 
00270 /*  Q       (input/output) COMPLEX array, dimension (LDQ,N) */
00271 /*          On entry, if JOBQ = 'Q', Q must contain a matrix Q1 (usually */
00272 /*          the unitary matrix returned by CGGSVP). */
00273 /*          On exit, */
00274 /*          if JOBQ = 'I', Q contains the unitary matrix Q; */
00275 /*          if JOBQ = 'Q', Q contains the product Q1*Q. */
00276 /*          If JOBQ = 'N', Q is not referenced. */
00277 
00278 /*  LDQ     (input) INTEGER */
00279 /*          The leading dimension of the array Q. LDQ >= max(1,N) if */
00280 /*          JOBQ = 'Q'; LDQ >= 1 otherwise. */
00281 
00282 /*  WORK    (workspace) COMPLEX array, dimension (2*N) */
00283 
00284 /*  NCYCLE  (output) INTEGER */
00285 /*          The number of cycles required for convergence. */
00286 
00287 /*  INFO    (output) INTEGER */
00288 /*          = 0:  successful exit */
00289 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00290 /*          = 1:  the procedure does not converge after MAXIT cycles. */
00291 
00292 /*  Internal Parameters */
00293 /*  =================== */
00294 
00295 /*  MAXIT   INTEGER */
00296 /*          MAXIT specifies the total loops that the iterative procedure */
00297 /*          may take. If after MAXIT cycles, the routine fails to */
00298 /*          converge, we return INFO = 1. */
00299 
00300 /*  Further Details */
00301 /*  =============== */
00302 
00303 /*  CTGSJA essentially uses a variant of Kogbetliantz algorithm to reduce */
00304 /*  min(L,M-K)-by-L triangular (or trapezoidal) matrix A23 and L-by-L */
00305 /*  matrix B13 to the form: */
00306 
00307 /*           U1'*A13*Q1 = C1*R1; V1'*B13*Q1 = S1*R1, */
00308 
00309 /*  where U1, V1 and Q1 are unitary matrix, and Z' is the conjugate */
00310 /*  transpose of Z.  C1 and S1 are diagonal matrices satisfying */
00311 
00312 /*                C1**2 + S1**2 = I, */
00313 
00314 /*  and R1 is an L-by-L nonsingular upper triangular matrix. */
00315 
00316 /*  ===================================================================== */
00317 
00318 /*     .. Parameters .. */
00319 /*     .. */
00320 /*     .. Local Scalars .. */
00321 
00322 /*     .. */
00323 /*     .. External Functions .. */
00324 /*     .. */
00325 /*     .. External Subroutines .. */
00326 /*     .. */
00327 /*     .. Intrinsic Functions .. */
00328 /*     .. */
00329 /*     .. Executable Statements .. */
00330 
00331 /*     Decode and test the input parameters */
00332 
00333     /* Parameter adjustments */
00334     a_dim1 = *lda;
00335     a_offset = 1 + a_dim1;
00336     a -= a_offset;
00337     b_dim1 = *ldb;
00338     b_offset = 1 + b_dim1;
00339     b -= b_offset;
00340     --alpha;
00341     --beta;
00342     u_dim1 = *ldu;
00343     u_offset = 1 + u_dim1;
00344     u -= u_offset;
00345     v_dim1 = *ldv;
00346     v_offset = 1 + v_dim1;
00347     v -= v_offset;
00348     q_dim1 = *ldq;
00349     q_offset = 1 + q_dim1;
00350     q -= q_offset;
00351     --work;
00352 
00353     /* Function Body */
00354     initu = lsame_(jobu, "I");
00355     wantu = initu || lsame_(jobu, "U");
00356 
00357     initv = lsame_(jobv, "I");
00358     wantv = initv || lsame_(jobv, "V");
00359 
00360     initq = lsame_(jobq, "I");
00361     wantq = initq || lsame_(jobq, "Q");
00362 
00363     *info = 0;
00364     if (! (initu || wantu || lsame_(jobu, "N"))) {
00365         *info = -1;
00366     } else if (! (initv || wantv || lsame_(jobv, "N"))) 
00367             {
00368         *info = -2;
00369     } else if (! (initq || wantq || lsame_(jobq, "N"))) 
00370             {
00371         *info = -3;
00372     } else if (*m < 0) {
00373         *info = -4;
00374     } else if (*p < 0) {
00375         *info = -5;
00376     } else if (*n < 0) {
00377         *info = -6;
00378     } else if (*lda < max(1,*m)) {
00379         *info = -10;
00380     } else if (*ldb < max(1,*p)) {
00381         *info = -12;
00382     } else if (*ldu < 1 || wantu && *ldu < *m) {
00383         *info = -18;
00384     } else if (*ldv < 1 || wantv && *ldv < *p) {
00385         *info = -20;
00386     } else if (*ldq < 1 || wantq && *ldq < *n) {
00387         *info = -22;
00388     }
00389     if (*info != 0) {
00390         i__1 = -(*info);
00391         xerbla_("CTGSJA", &i__1);
00392         return 0;
00393     }
00394 
00395 /*     Initialize U, V and Q, if necessary */
00396 
00397     if (initu) {
00398         claset_("Full", m, m, &c_b1, &c_b2, &u[u_offset], ldu);
00399     }
00400     if (initv) {
00401         claset_("Full", p, p, &c_b1, &c_b2, &v[v_offset], ldv);
00402     }
00403     if (initq) {
00404         claset_("Full", n, n, &c_b1, &c_b2, &q[q_offset], ldq);
00405     }
00406 
00407 /*     Loop until convergence */
00408 
00409     upper = FALSE_;
00410     for (kcycle = 1; kcycle <= 40; ++kcycle) {
00411 
00412         upper = ! upper;
00413 
00414         i__1 = *l - 1;
00415         for (i__ = 1; i__ <= i__1; ++i__) {
00416             i__2 = *l;
00417             for (j = i__ + 1; j <= i__2; ++j) {
00418 
00419                 a1 = 0.f;
00420                 a2.r = 0.f, a2.i = 0.f;
00421                 a3 = 0.f;
00422                 if (*k + i__ <= *m) {
00423                     i__3 = *k + i__ + (*n - *l + i__) * a_dim1;
00424                     a1 = a[i__3].r;
00425                 }
00426                 if (*k + j <= *m) {
00427                     i__3 = *k + j + (*n - *l + j) * a_dim1;
00428                     a3 = a[i__3].r;
00429                 }
00430 
00431                 i__3 = i__ + (*n - *l + i__) * b_dim1;
00432                 b1 = b[i__3].r;
00433                 i__3 = j + (*n - *l + j) * b_dim1;
00434                 b3 = b[i__3].r;
00435 
00436                 if (upper) {
00437                     if (*k + i__ <= *m) {
00438                         i__3 = *k + i__ + (*n - *l + j) * a_dim1;
00439                         a2.r = a[i__3].r, a2.i = a[i__3].i;
00440                     }
00441                     i__3 = i__ + (*n - *l + j) * b_dim1;
00442                     b2.r = b[i__3].r, b2.i = b[i__3].i;
00443                 } else {
00444                     if (*k + j <= *m) {
00445                         i__3 = *k + j + (*n - *l + i__) * a_dim1;
00446                         a2.r = a[i__3].r, a2.i = a[i__3].i;
00447                     }
00448                     i__3 = j + (*n - *l + i__) * b_dim1;
00449                     b2.r = b[i__3].r, b2.i = b[i__3].i;
00450                 }
00451 
00452                 clags2_(&upper, &a1, &a2, &a3, &b1, &b2, &b3, &csu, &snu, &
00453                         csv, &snv, &csq, &snq);
00454 
00455 /*              Update (K+I)-th and (K+J)-th rows of matrix A: U'*A */
00456 
00457                 if (*k + j <= *m) {
00458                     r_cnjg(&q__1, &snu);
00459                     crot_(l, &a[*k + j + (*n - *l + 1) * a_dim1], lda, &a[*k 
00460                             + i__ + (*n - *l + 1) * a_dim1], lda, &csu, &q__1)
00461                             ;
00462                 }
00463 
00464 /*              Update I-th and J-th rows of matrix B: V'*B */
00465 
00466                 r_cnjg(&q__1, &snv);
00467                 crot_(l, &b[j + (*n - *l + 1) * b_dim1], ldb, &b[i__ + (*n - *
00468                         l + 1) * b_dim1], ldb, &csv, &q__1);
00469 
00470 /*              Update (N-L+I)-th and (N-L+J)-th columns of matrices */
00471 /*              A and B: A*Q and B*Q */
00472 
00473 /* Computing MIN */
00474                 i__4 = *k + *l;
00475                 i__3 = min(i__4,*m);
00476                 crot_(&i__3, &a[(*n - *l + j) * a_dim1 + 1], &c__1, &a[(*n - *
00477                         l + i__) * a_dim1 + 1], &c__1, &csq, &snq);
00478 
00479                 crot_(l, &b[(*n - *l + j) * b_dim1 + 1], &c__1, &b[(*n - *l + 
00480                         i__) * b_dim1 + 1], &c__1, &csq, &snq);
00481 
00482                 if (upper) {
00483                     if (*k + i__ <= *m) {
00484                         i__3 = *k + i__ + (*n - *l + j) * a_dim1;
00485                         a[i__3].r = 0.f, a[i__3].i = 0.f;
00486                     }
00487                     i__3 = i__ + (*n - *l + j) * b_dim1;
00488                     b[i__3].r = 0.f, b[i__3].i = 0.f;
00489                 } else {
00490                     if (*k + j <= *m) {
00491                         i__3 = *k + j + (*n - *l + i__) * a_dim1;
00492                         a[i__3].r = 0.f, a[i__3].i = 0.f;
00493                     }
00494                     i__3 = j + (*n - *l + i__) * b_dim1;
00495                     b[i__3].r = 0.f, b[i__3].i = 0.f;
00496                 }
00497 
00498 /*              Ensure that the diagonal elements of A and B are real. */
00499 
00500                 if (*k + i__ <= *m) {
00501                     i__3 = *k + i__ + (*n - *l + i__) * a_dim1;
00502                     i__4 = *k + i__ + (*n - *l + i__) * a_dim1;
00503                     r__1 = a[i__4].r;
00504                     a[i__3].r = r__1, a[i__3].i = 0.f;
00505                 }
00506                 if (*k + j <= *m) {
00507                     i__3 = *k + j + (*n - *l + j) * a_dim1;
00508                     i__4 = *k + j + (*n - *l + j) * a_dim1;
00509                     r__1 = a[i__4].r;
00510                     a[i__3].r = r__1, a[i__3].i = 0.f;
00511                 }
00512                 i__3 = i__ + (*n - *l + i__) * b_dim1;
00513                 i__4 = i__ + (*n - *l + i__) * b_dim1;
00514                 r__1 = b[i__4].r;
00515                 b[i__3].r = r__1, b[i__3].i = 0.f;
00516                 i__3 = j + (*n - *l + j) * b_dim1;
00517                 i__4 = j + (*n - *l + j) * b_dim1;
00518                 r__1 = b[i__4].r;
00519                 b[i__3].r = r__1, b[i__3].i = 0.f;
00520 
00521 /*              Update unitary matrices U, V, Q, if desired. */
00522 
00523                 if (wantu && *k + j <= *m) {
00524                     crot_(m, &u[(*k + j) * u_dim1 + 1], &c__1, &u[(*k + i__) *
00525                              u_dim1 + 1], &c__1, &csu, &snu);
00526                 }
00527 
00528                 if (wantv) {
00529                     crot_(p, &v[j * v_dim1 + 1], &c__1, &v[i__ * v_dim1 + 1], 
00530                             &c__1, &csv, &snv);
00531                 }
00532 
00533                 if (wantq) {
00534                     crot_(n, &q[(*n - *l + j) * q_dim1 + 1], &c__1, &q[(*n - *
00535                             l + i__) * q_dim1 + 1], &c__1, &csq, &snq);
00536                 }
00537 
00538 /* L10: */
00539             }
00540 /* L20: */
00541         }
00542 
00543         if (! upper) {
00544 
00545 /*           The matrices A13 and B13 were lower triangular at the start */
00546 /*           of the cycle, and are now upper triangular. */
00547 
00548 /*           Convergence test: test the parallelism of the corresponding */
00549 /*           rows of A and B. */
00550 
00551             error = 0.f;
00552 /* Computing MIN */
00553             i__2 = *l, i__3 = *m - *k;
00554             i__1 = min(i__2,i__3);
00555             for (i__ = 1; i__ <= i__1; ++i__) {
00556                 i__2 = *l - i__ + 1;
00557                 ccopy_(&i__2, &a[*k + i__ + (*n - *l + i__) * a_dim1], lda, &
00558                         work[1], &c__1);
00559                 i__2 = *l - i__ + 1;
00560                 ccopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &work[*
00561                         l + 1], &c__1);
00562                 i__2 = *l - i__ + 1;
00563                 clapll_(&i__2, &work[1], &c__1, &work[*l + 1], &c__1, &ssmin);
00564                 error = dmax(error,ssmin);
00565 /* L30: */
00566             }
00567 
00568             if (dabs(error) <= dmin(*tola,*tolb)) {
00569                 goto L50;
00570             }
00571         }
00572 
00573 /*        End of cycle loop */
00574 
00575 /* L40: */
00576     }
00577 
00578 /*     The algorithm has not converged after MAXIT cycles. */
00579 
00580     *info = 1;
00581     goto L100;
00582 
00583 L50:
00584 
00585 /*     If ERROR <= MIN(TOLA,TOLB), then the algorithm has converged. */
00586 /*     Compute the generalized singular value pairs (ALPHA, BETA), and */
00587 /*     set the triangular matrix R to array A. */
00588 
00589     i__1 = *k;
00590     for (i__ = 1; i__ <= i__1; ++i__) {
00591         alpha[i__] = 1.f;
00592         beta[i__] = 0.f;
00593 /* L60: */
00594     }
00595 
00596 /* Computing MIN */
00597     i__2 = *l, i__3 = *m - *k;
00598     i__1 = min(i__2,i__3);
00599     for (i__ = 1; i__ <= i__1; ++i__) {
00600 
00601         i__2 = *k + i__ + (*n - *l + i__) * a_dim1;
00602         a1 = a[i__2].r;
00603         i__2 = i__ + (*n - *l + i__) * b_dim1;
00604         b1 = b[i__2].r;
00605 
00606         if (a1 != 0.f) {
00607             gamma = b1 / a1;
00608 
00609             if (gamma < 0.f) {
00610                 i__2 = *l - i__ + 1;
00611                 csscal_(&i__2, &c_b39, &b[i__ + (*n - *l + i__) * b_dim1], 
00612                         ldb);
00613                 if (wantv) {
00614                     csscal_(p, &c_b39, &v[i__ * v_dim1 + 1], &c__1);
00615                 }
00616             }
00617 
00618             r__1 = dabs(gamma);
00619             slartg_(&r__1, &c_b42, &beta[*k + i__], &alpha[*k + i__], &rwk);
00620 
00621             if (alpha[*k + i__] >= beta[*k + i__]) {
00622                 i__2 = *l - i__ + 1;
00623                 r__1 = 1.f / alpha[*k + i__];
00624                 csscal_(&i__2, &r__1, &a[*k + i__ + (*n - *l + i__) * a_dim1], 
00625                          lda);
00626             } else {
00627                 i__2 = *l - i__ + 1;
00628                 r__1 = 1.f / beta[*k + i__];
00629                 csscal_(&i__2, &r__1, &b[i__ + (*n - *l + i__) * b_dim1], ldb)
00630                         ;
00631                 i__2 = *l - i__ + 1;
00632                 ccopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &a[*k 
00633                         + i__ + (*n - *l + i__) * a_dim1], lda);
00634             }
00635 
00636         } else {
00637             alpha[*k + i__] = 0.f;
00638             beta[*k + i__] = 1.f;
00639             i__2 = *l - i__ + 1;
00640             ccopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &a[*k + 
00641                     i__ + (*n - *l + i__) * a_dim1], lda);
00642         }
00643 /* L70: */
00644     }
00645 
00646 /*     Post-assignment */
00647 
00648     i__1 = *k + *l;
00649     for (i__ = *m + 1; i__ <= i__1; ++i__) {
00650         alpha[i__] = 0.f;
00651         beta[i__] = 1.f;
00652 /* L80: */
00653     }
00654 
00655     if (*k + *l < *n) {
00656         i__1 = *n;
00657         for (i__ = *k + *l + 1; i__ <= i__1; ++i__) {
00658             alpha[i__] = 0.f;
00659             beta[i__] = 0.f;
00660 /* L90: */
00661         }
00662     }
00663 
00664 L100:
00665     *ncycle = kcycle;
00666 
00667     return 0;
00668 
00669 /*     End of CTGSJA */
00670 
00671 } /* ctgsja_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:34