ctgsyl.c
Go to the documentation of this file.
00001 /* ctgsyl.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 integer c__2 = 2;
00020 static integer c_n1 = -1;
00021 static integer c__5 = 5;
00022 static integer c__1 = 1;
00023 static complex c_b44 = {-1.f,0.f};
00024 static complex c_b45 = {1.f,0.f};
00025 
00026 /* Subroutine */ int ctgsyl_(char *trans, integer *ijob, integer *m, integer *
00027         n, complex *a, integer *lda, complex *b, integer *ldb, complex *c__, 
00028         integer *ldc, complex *d__, integer *ldd, complex *e, integer *lde, 
00029         complex *f, integer *ldf, real *scale, real *dif, complex *work, 
00030         integer *lwork, integer *iwork, integer *info)
00031 {
00032     /* System generated locals */
00033     integer a_dim1, a_offset, b_dim1, b_offset, c_dim1, c_offset, d_dim1, 
00034             d_offset, e_dim1, e_offset, f_dim1, f_offset, i__1, i__2, i__3, 
00035             i__4;
00036     complex q__1;
00037 
00038     /* Builtin functions */
00039     double sqrt(doublereal);
00040 
00041     /* Local variables */
00042     integer i__, j, k, p, q, ie, je, mb, nb, is, js, pq;
00043     real dsum;
00044     extern /* Subroutine */ int cscal_(integer *, complex *, complex *, 
00045             integer *), cgemm_(char *, char *, integer *, integer *, integer *
00046 , complex *, complex *, integer *, complex *, integer *, complex *
00047 , complex *, integer *);
00048     extern logical lsame_(char *, char *);
00049     integer ifunc, linfo, lwmin;
00050     real scale2;
00051     extern /* Subroutine */ int ctgsy2_(char *, integer *, integer *, integer 
00052             *, complex *, integer *, complex *, integer *, complex *, integer 
00053             *, complex *, integer *, complex *, integer *, complex *, integer 
00054             *, real *, real *, real *, integer *);
00055     real dscale, scaloc;
00056     extern /* Subroutine */ int clacpy_(char *, integer *, integer *, complex 
00057             *, integer *, complex *, integer *), claset_(char *, 
00058             integer *, integer *, complex *, complex *, complex *, integer *), xerbla_(char *, integer *);
00059     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00060             integer *, integer *);
00061     integer iround;
00062     logical notran;
00063     integer isolve;
00064     logical lquery;
00065 
00066 
00067 /*  -- LAPACK routine (version 3.2) -- */
00068 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00069 /*     January 2007 */
00070 
00071 /*     .. Scalar Arguments .. */
00072 /*     .. */
00073 /*     .. Array Arguments .. */
00074 /*     .. */
00075 
00076 /*  Purpose */
00077 /*  ======= */
00078 
00079 /*  CTGSYL solves the generalized Sylvester equation: */
00080 
00081 /*              A * R - L * B = scale * C            (1) */
00082 /*              D * R - L * E = scale * F */
00083 
00084 /*  where R and L are unknown m-by-n matrices, (A, D), (B, E) and */
00085 /*  (C, F) are given matrix pairs of size m-by-m, n-by-n and m-by-n, */
00086 /*  respectively, with complex entries. A, B, D and E are upper */
00087 /*  triangular (i.e., (A,D) and (B,E) in generalized Schur form). */
00088 
00089 /*  The solution (R, L) overwrites (C, F). 0 <= SCALE <= 1 */
00090 /*  is an output scaling factor chosen to avoid overflow. */
00091 
00092 /*  In matrix notation (1) is equivalent to solve Zx = scale*b, where Z */
00093 /*  is defined as */
00094 
00095 /*         Z = [ kron(In, A)  -kron(B', Im) ]        (2) */
00096 /*             [ kron(In, D)  -kron(E', Im) ], */
00097 
00098 /*  Here Ix is the identity matrix of size x and X' is the conjugate */
00099 /*  transpose of X. Kron(X, Y) is the Kronecker product between the */
00100 /*  matrices X and Y. */
00101 
00102 /*  If TRANS = 'C', y in the conjugate transposed system Z'*y = scale*b */
00103 /*  is solved for, which is equivalent to solve for R and L in */
00104 
00105 /*              A' * R + D' * L = scale * C           (3) */
00106 /*              R * B' + L * E' = scale * -F */
00107 
00108 /*  This case (TRANS = 'C') is used to compute an one-norm-based estimate */
00109 /*  of Dif[(A,D), (B,E)], the separation between the matrix pairs (A,D) */
00110 /*  and (B,E), using CLACON. */
00111 
00112 /*  If IJOB >= 1, CTGSYL computes a Frobenius norm-based estimate of */
00113 /*  Dif[(A,D),(B,E)]. That is, the reciprocal of a lower bound on the */
00114 /*  reciprocal of the smallest singular value of Z. */
00115 
00116 /*  This is a level-3 BLAS algorithm. */
00117 
00118 /*  Arguments */
00119 /*  ========= */
00120 
00121 /*  TRANS   (input) CHARACTER*1 */
00122 /*          = 'N': solve the generalized sylvester equation (1). */
00123 /*          = 'C': solve the "conjugate transposed" system (3). */
00124 
00125 /*  IJOB    (input) INTEGER */
00126 /*          Specifies what kind of functionality to be performed. */
00127 /*          =0: solve (1) only. */
00128 /*          =1: The functionality of 0 and 3. */
00129 /*          =2: The functionality of 0 and 4. */
00130 /*          =3: Only an estimate of Dif[(A,D), (B,E)] is computed. */
00131 /*              (look ahead strategy is used). */
00132 /*          =4: Only an estimate of Dif[(A,D), (B,E)] is computed. */
00133 /*              (CGECON on sub-systems is used). */
00134 /*          Not referenced if TRANS = 'C'. */
00135 
00136 /*  M       (input) INTEGER */
00137 /*          The order of the matrices A and D, and the row dimension of */
00138 /*          the matrices C, F, R and L. */
00139 
00140 /*  N       (input) INTEGER */
00141 /*          The order of the matrices B and E, and the column dimension */
00142 /*          of the matrices C, F, R and L. */
00143 
00144 /*  A       (input) COMPLEX array, dimension (LDA, M) */
00145 /*          The upper triangular matrix A. */
00146 
00147 /*  LDA     (input) INTEGER */
00148 /*          The leading dimension of the array A. LDA >= max(1, M). */
00149 
00150 /*  B       (input) COMPLEX array, dimension (LDB, N) */
00151 /*          The upper triangular matrix B. */
00152 
00153 /*  LDB     (input) INTEGER */
00154 /*          The leading dimension of the array B. LDB >= max(1, N). */
00155 
00156 /*  C       (input/output) COMPLEX array, dimension (LDC, N) */
00157 /*          On entry, C contains the right-hand-side of the first matrix */
00158 /*          equation in (1) or (3). */
00159 /*          On exit, if IJOB = 0, 1 or 2, C has been overwritten by */
00160 /*          the solution R. If IJOB = 3 or 4 and TRANS = 'N', C holds R, */
00161 /*          the solution achieved during the computation of the */
00162 /*          Dif-estimate. */
00163 
00164 /*  LDC     (input) INTEGER */
00165 /*          The leading dimension of the array C. LDC >= max(1, M). */
00166 
00167 /*  D       (input) COMPLEX array, dimension (LDD, M) */
00168 /*          The upper triangular matrix D. */
00169 
00170 /*  LDD     (input) INTEGER */
00171 /*          The leading dimension of the array D. LDD >= max(1, M). */
00172 
00173 /*  E       (input) COMPLEX array, dimension (LDE, N) */
00174 /*          The upper triangular matrix E. */
00175 
00176 /*  LDE     (input) INTEGER */
00177 /*          The leading dimension of the array E. LDE >= max(1, N). */
00178 
00179 /*  F       (input/output) COMPLEX array, dimension (LDF, N) */
00180 /*          On entry, F contains the right-hand-side of the second matrix */
00181 /*          equation in (1) or (3). */
00182 /*          On exit, if IJOB = 0, 1 or 2, F has been overwritten by */
00183 /*          the solution L. If IJOB = 3 or 4 and TRANS = 'N', F holds L, */
00184 /*          the solution achieved during the computation of the */
00185 /*          Dif-estimate. */
00186 
00187 /*  LDF     (input) INTEGER */
00188 /*          The leading dimension of the array F. LDF >= max(1, M). */
00189 
00190 /*  DIF     (output) REAL */
00191 /*          On exit DIF is the reciprocal of a lower bound of the */
00192 /*          reciprocal of the Dif-function, i.e. DIF is an upper bound of */
00193 /*          Dif[(A,D), (B,E)] = sigma-min(Z), where Z as in (2). */
00194 /*          IF IJOB = 0 or TRANS = 'C', DIF is not referenced. */
00195 
00196 /*  SCALE   (output) REAL */
00197 /*          On exit SCALE is the scaling factor in (1) or (3). */
00198 /*          If 0 < SCALE < 1, C and F hold the solutions R and L, resp., */
00199 /*          to a slightly perturbed system but the input matrices A, B, */
00200 /*          D and E have not been changed. If SCALE = 0, R and L will */
00201 /*          hold the solutions to the homogenious system with C = F = 0. */
00202 
00203 /*  WORK    (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) */
00204 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00205 
00206 /*  LWORK   (input) INTEGER */
00207 /*          The dimension of the array WORK. LWORK > = 1. */
00208 /*          If IJOB = 1 or 2 and TRANS = 'N', LWORK >= max(1,2*M*N). */
00209 
00210 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00211 /*          only calculates the optimal size of the WORK array, returns */
00212 /*          this value as the first entry of the WORK array, and no error */
00213 /*          message related to LWORK is issued by XERBLA. */
00214 
00215 /*  IWORK   (workspace) INTEGER array, dimension (M+N+2) */
00216 
00217 /*  INFO    (output) INTEGER */
00218 /*            =0: successful exit */
00219 /*            <0: If INFO = -i, the i-th argument had an illegal value. */
00220 /*            >0: (A, D) and (B, E) have common or very close */
00221 /*                eigenvalues. */
00222 
00223 /*  Further Details */
00224 /*  =============== */
00225 
00226 /*  Based on contributions by */
00227 /*     Bo Kagstrom and Peter Poromaa, Department of Computing Science, */
00228 /*     Umea University, S-901 87 Umea, Sweden. */
00229 
00230 /*  [1] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software */
00231 /*      for Solving the Generalized Sylvester Equation and Estimating the */
00232 /*      Separation between Regular Matrix Pairs, Report UMINF - 93.23, */
00233 /*      Department of Computing Science, Umea University, S-901 87 Umea, */
00234 /*      Sweden, December 1993, Revised April 1994, Also as LAPACK Working */
00235 /*      Note 75.  To appear in ACM Trans. on Math. Software, Vol 22, */
00236 /*      No 1, 1996. */
00237 
00238 /*  [2] B. Kagstrom, A Perturbation Analysis of the Generalized Sylvester */
00239 /*      Equation (AR - LB, DR - LE ) = (C, F), SIAM J. Matrix Anal. */
00240 /*      Appl., 15(4):1045-1060, 1994. */
00241 
00242 /*  [3] B. Kagstrom and L. Westin, Generalized Schur Methods with */
00243 /*      Condition Estimators for Solving the Generalized Sylvester */
00244 /*      Equation, IEEE Transactions on Automatic Control, Vol. 34, No. 7, */
00245 /*      July 1989, pp 745-751. */
00246 
00247 /*  ===================================================================== */
00248 /*  Replaced various illegal calls to CCOPY by calls to CLASET. */
00249 /*  Sven Hammarling, 1/5/02. */
00250 
00251 /*     .. Parameters .. */
00252 /*     .. */
00253 /*     .. Local Scalars .. */
00254 /*     .. */
00255 /*     .. External Functions .. */
00256 /*     .. */
00257 /*     .. External Subroutines .. */
00258 /*     .. */
00259 /*     .. Intrinsic Functions .. */
00260 /*     .. */
00261 /*     .. Executable Statements .. */
00262 
00263 /*     Decode and test input parameters */
00264 
00265     /* Parameter adjustments */
00266     a_dim1 = *lda;
00267     a_offset = 1 + a_dim1;
00268     a -= a_offset;
00269     b_dim1 = *ldb;
00270     b_offset = 1 + b_dim1;
00271     b -= b_offset;
00272     c_dim1 = *ldc;
00273     c_offset = 1 + c_dim1;
00274     c__ -= c_offset;
00275     d_dim1 = *ldd;
00276     d_offset = 1 + d_dim1;
00277     d__ -= d_offset;
00278     e_dim1 = *lde;
00279     e_offset = 1 + e_dim1;
00280     e -= e_offset;
00281     f_dim1 = *ldf;
00282     f_offset = 1 + f_dim1;
00283     f -= f_offset;
00284     --work;
00285     --iwork;
00286 
00287     /* Function Body */
00288     *info = 0;
00289     notran = lsame_(trans, "N");
00290     lquery = *lwork == -1;
00291 
00292     if (! notran && ! lsame_(trans, "C")) {
00293         *info = -1;
00294     } else if (notran) {
00295         if (*ijob < 0 || *ijob > 4) {
00296             *info = -2;
00297         }
00298     }
00299     if (*info == 0) {
00300         if (*m <= 0) {
00301             *info = -3;
00302         } else if (*n <= 0) {
00303             *info = -4;
00304         } else if (*lda < max(1,*m)) {
00305             *info = -6;
00306         } else if (*ldb < max(1,*n)) {
00307             *info = -8;
00308         } else if (*ldc < max(1,*m)) {
00309             *info = -10;
00310         } else if (*ldd < max(1,*m)) {
00311             *info = -12;
00312         } else if (*lde < max(1,*n)) {
00313             *info = -14;
00314         } else if (*ldf < max(1,*m)) {
00315             *info = -16;
00316         }
00317     }
00318 
00319     if (*info == 0) {
00320         if (notran) {
00321             if (*ijob == 1 || *ijob == 2) {
00322 /* Computing MAX */
00323                 i__1 = 1, i__2 = (*m << 1) * *n;
00324                 lwmin = max(i__1,i__2);
00325             } else {
00326                 lwmin = 1;
00327             }
00328         } else {
00329             lwmin = 1;
00330         }
00331         work[1].r = (real) lwmin, work[1].i = 0.f;
00332 
00333         if (*lwork < lwmin && ! lquery) {
00334             *info = -20;
00335         }
00336     }
00337 
00338     if (*info != 0) {
00339         i__1 = -(*info);
00340         xerbla_("CTGSYL", &i__1);
00341         return 0;
00342     } else if (lquery) {
00343         return 0;
00344     }
00345 
00346 /*     Quick return if possible */
00347 
00348     if (*m == 0 || *n == 0) {
00349         *scale = 1.f;
00350         if (notran) {
00351             if (*ijob != 0) {
00352                 *dif = 0.f;
00353             }
00354         }
00355         return 0;
00356     }
00357 
00358 /*     Determine  optimal block sizes MB and NB */
00359 
00360     mb = ilaenv_(&c__2, "CTGSYL", trans, m, n, &c_n1, &c_n1);
00361     nb = ilaenv_(&c__5, "CTGSYL", trans, m, n, &c_n1, &c_n1);
00362 
00363     isolve = 1;
00364     ifunc = 0;
00365     if (notran) {
00366         if (*ijob >= 3) {
00367             ifunc = *ijob - 2;
00368             claset_("F", m, n, &c_b1, &c_b1, &c__[c_offset], ldc);
00369             claset_("F", m, n, &c_b1, &c_b1, &f[f_offset], ldf);
00370         } else if (*ijob >= 1 && notran) {
00371             isolve = 2;
00372         }
00373     }
00374 
00375     if (mb <= 1 && nb <= 1 || mb >= *m && nb >= *n) {
00376 
00377 /*        Use unblocked Level 2 solver */
00378 
00379         i__1 = isolve;
00380         for (iround = 1; iround <= i__1; ++iround) {
00381 
00382             *scale = 1.f;
00383             dscale = 0.f;
00384             dsum = 1.f;
00385             pq = *m * *n;
00386             ctgsy2_(trans, &ifunc, m, n, &a[a_offset], lda, &b[b_offset], ldb, 
00387                      &c__[c_offset], ldc, &d__[d_offset], ldd, &e[e_offset], 
00388                     lde, &f[f_offset], ldf, scale, &dsum, &dscale, info);
00389             if (dscale != 0.f) {
00390                 if (*ijob == 1 || *ijob == 3) {
00391                     *dif = sqrt((real) ((*m << 1) * *n)) / (dscale * sqrt(
00392                             dsum));
00393                 } else {
00394                     *dif = sqrt((real) pq) / (dscale * sqrt(dsum));
00395                 }
00396             }
00397             if (isolve == 2 && iround == 1) {
00398                 if (notran) {
00399                     ifunc = *ijob;
00400                 }
00401                 scale2 = *scale;
00402                 clacpy_("F", m, n, &c__[c_offset], ldc, &work[1], m);
00403                 clacpy_("F", m, n, &f[f_offset], ldf, &work[*m * *n + 1], m);
00404                 claset_("F", m, n, &c_b1, &c_b1, &c__[c_offset], ldc);
00405                 claset_("F", m, n, &c_b1, &c_b1, &f[f_offset], ldf)
00406                         ;
00407             } else if (isolve == 2 && iround == 2) {
00408                 clacpy_("F", m, n, &work[1], m, &c__[c_offset], ldc);
00409                 clacpy_("F", m, n, &work[*m * *n + 1], m, &f[f_offset], ldf);
00410                 *scale = scale2;
00411             }
00412 /* L30: */
00413         }
00414 
00415         return 0;
00416 
00417     }
00418 
00419 /*     Determine block structure of A */
00420 
00421     p = 0;
00422     i__ = 1;
00423 L40:
00424     if (i__ > *m) {
00425         goto L50;
00426     }
00427     ++p;
00428     iwork[p] = i__;
00429     i__ += mb;
00430     if (i__ >= *m) {
00431         goto L50;
00432     }
00433     goto L40;
00434 L50:
00435     iwork[p + 1] = *m + 1;
00436     if (iwork[p] == iwork[p + 1]) {
00437         --p;
00438     }
00439 
00440 /*     Determine block structure of B */
00441 
00442     q = p + 1;
00443     j = 1;
00444 L60:
00445     if (j > *n) {
00446         goto L70;
00447     }
00448 
00449     ++q;
00450     iwork[q] = j;
00451     j += nb;
00452     if (j >= *n) {
00453         goto L70;
00454     }
00455     goto L60;
00456 
00457 L70:
00458     iwork[q + 1] = *n + 1;
00459     if (iwork[q] == iwork[q + 1]) {
00460         --q;
00461     }
00462 
00463     if (notran) {
00464         i__1 = isolve;
00465         for (iround = 1; iround <= i__1; ++iround) {
00466 
00467 /*           Solve (I, J) - subsystem */
00468 /*               A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J) */
00469 /*               D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J) */
00470 /*           for I = P, P - 1, ..., 1; J = 1, 2, ..., Q */
00471 
00472             pq = 0;
00473             *scale = 1.f;
00474             dscale = 0.f;
00475             dsum = 1.f;
00476             i__2 = q;
00477             for (j = p + 2; j <= i__2; ++j) {
00478                 js = iwork[j];
00479                 je = iwork[j + 1] - 1;
00480                 nb = je - js + 1;
00481                 for (i__ = p; i__ >= 1; --i__) {
00482                     is = iwork[i__];
00483                     ie = iwork[i__ + 1] - 1;
00484                     mb = ie - is + 1;
00485                     ctgsy2_(trans, &ifunc, &mb, &nb, &a[is + is * a_dim1], 
00486                             lda, &b[js + js * b_dim1], ldb, &c__[is + js * 
00487                             c_dim1], ldc, &d__[is + is * d_dim1], ldd, &e[js 
00488                             + js * e_dim1], lde, &f[is + js * f_dim1], ldf, &
00489                             scaloc, &dsum, &dscale, &linfo);
00490                     if (linfo > 0) {
00491                         *info = linfo;
00492                     }
00493                     pq += mb * nb;
00494                     if (scaloc != 1.f) {
00495                         i__3 = js - 1;
00496                         for (k = 1; k <= i__3; ++k) {
00497                             q__1.r = scaloc, q__1.i = 0.f;
00498                             cscal_(m, &q__1, &c__[k * c_dim1 + 1], &c__1);
00499                             q__1.r = scaloc, q__1.i = 0.f;
00500                             cscal_(m, &q__1, &f[k * f_dim1 + 1], &c__1);
00501 /* L80: */
00502                         }
00503                         i__3 = je;
00504                         for (k = js; k <= i__3; ++k) {
00505                             i__4 = is - 1;
00506                             q__1.r = scaloc, q__1.i = 0.f;
00507                             cscal_(&i__4, &q__1, &c__[k * c_dim1 + 1], &c__1);
00508                             i__4 = is - 1;
00509                             q__1.r = scaloc, q__1.i = 0.f;
00510                             cscal_(&i__4, &q__1, &f[k * f_dim1 + 1], &c__1);
00511 /* L90: */
00512                         }
00513                         i__3 = je;
00514                         for (k = js; k <= i__3; ++k) {
00515                             i__4 = *m - ie;
00516                             q__1.r = scaloc, q__1.i = 0.f;
00517                             cscal_(&i__4, &q__1, &c__[ie + 1 + k * c_dim1], &
00518                                     c__1);
00519                             i__4 = *m - ie;
00520                             q__1.r = scaloc, q__1.i = 0.f;
00521                             cscal_(&i__4, &q__1, &f[ie + 1 + k * f_dim1], &
00522                                     c__1);
00523 /* L100: */
00524                         }
00525                         i__3 = *n;
00526                         for (k = je + 1; k <= i__3; ++k) {
00527                             q__1.r = scaloc, q__1.i = 0.f;
00528                             cscal_(m, &q__1, &c__[k * c_dim1 + 1], &c__1);
00529                             q__1.r = scaloc, q__1.i = 0.f;
00530                             cscal_(m, &q__1, &f[k * f_dim1 + 1], &c__1);
00531 /* L110: */
00532                         }
00533                         *scale *= scaloc;
00534                     }
00535 
00536 /*                 Substitute R(I,J) and L(I,J) into remaining equation. */
00537 
00538                     if (i__ > 1) {
00539                         i__3 = is - 1;
00540                         cgemm_("N", "N", &i__3, &nb, &mb, &c_b44, &a[is * 
00541                                 a_dim1 + 1], lda, &c__[is + js * c_dim1], ldc, 
00542                                  &c_b45, &c__[js * c_dim1 + 1], ldc);
00543                         i__3 = is - 1;
00544                         cgemm_("N", "N", &i__3, &nb, &mb, &c_b44, &d__[is * 
00545                                 d_dim1 + 1], ldd, &c__[is + js * c_dim1], ldc, 
00546                                  &c_b45, &f[js * f_dim1 + 1], ldf);
00547                     }
00548                     if (j < q) {
00549                         i__3 = *n - je;
00550                         cgemm_("N", "N", &mb, &i__3, &nb, &c_b45, &f[is + js *
00551                                  f_dim1], ldf, &b[js + (je + 1) * b_dim1], 
00552                                 ldb, &c_b45, &c__[is + (je + 1) * c_dim1], 
00553                                 ldc);
00554                         i__3 = *n - je;
00555                         cgemm_("N", "N", &mb, &i__3, &nb, &c_b45, &f[is + js *
00556                                  f_dim1], ldf, &e[js + (je + 1) * e_dim1], 
00557                                 lde, &c_b45, &f[is + (je + 1) * f_dim1], ldf);
00558                     }
00559 /* L120: */
00560                 }
00561 /* L130: */
00562             }
00563             if (dscale != 0.f) {
00564                 if (*ijob == 1 || *ijob == 3) {
00565                     *dif = sqrt((real) ((*m << 1) * *n)) / (dscale * sqrt(
00566                             dsum));
00567                 } else {
00568                     *dif = sqrt((real) pq) / (dscale * sqrt(dsum));
00569                 }
00570             }
00571             if (isolve == 2 && iround == 1) {
00572                 if (notran) {
00573                     ifunc = *ijob;
00574                 }
00575                 scale2 = *scale;
00576                 clacpy_("F", m, n, &c__[c_offset], ldc, &work[1], m);
00577                 clacpy_("F", m, n, &f[f_offset], ldf, &work[*m * *n + 1], m);
00578                 claset_("F", m, n, &c_b1, &c_b1, &c__[c_offset], ldc);
00579                 claset_("F", m, n, &c_b1, &c_b1, &f[f_offset], ldf)
00580                         ;
00581             } else if (isolve == 2 && iround == 2) {
00582                 clacpy_("F", m, n, &work[1], m, &c__[c_offset], ldc);
00583                 clacpy_("F", m, n, &work[*m * *n + 1], m, &f[f_offset], ldf);
00584                 *scale = scale2;
00585             }
00586 /* L150: */
00587         }
00588     } else {
00589 
00590 /*        Solve transposed (I, J)-subsystem */
00591 /*            A(I, I)' * R(I, J) + D(I, I)' * L(I, J) = C(I, J) */
00592 /*            R(I, J) * B(J, J)  + L(I, J) * E(J, J) = -F(I, J) */
00593 /*        for I = 1,2,..., P; J = Q, Q-1,..., 1 */
00594 
00595         *scale = 1.f;
00596         i__1 = p;
00597         for (i__ = 1; i__ <= i__1; ++i__) {
00598             is = iwork[i__];
00599             ie = iwork[i__ + 1] - 1;
00600             mb = ie - is + 1;
00601             i__2 = p + 2;
00602             for (j = q; j >= i__2; --j) {
00603                 js = iwork[j];
00604                 je = iwork[j + 1] - 1;
00605                 nb = je - js + 1;
00606                 ctgsy2_(trans, &ifunc, &mb, &nb, &a[is + is * a_dim1], lda, &
00607                         b[js + js * b_dim1], ldb, &c__[is + js * c_dim1], ldc, 
00608                          &d__[is + is * d_dim1], ldd, &e[js + js * e_dim1], 
00609                         lde, &f[is + js * f_dim1], ldf, &scaloc, &dsum, &
00610                         dscale, &linfo);
00611                 if (linfo > 0) {
00612                     *info = linfo;
00613                 }
00614                 if (scaloc != 1.f) {
00615                     i__3 = js - 1;
00616                     for (k = 1; k <= i__3; ++k) {
00617                         q__1.r = scaloc, q__1.i = 0.f;
00618                         cscal_(m, &q__1, &c__[k * c_dim1 + 1], &c__1);
00619                         q__1.r = scaloc, q__1.i = 0.f;
00620                         cscal_(m, &q__1, &f[k * f_dim1 + 1], &c__1);
00621 /* L160: */
00622                     }
00623                     i__3 = je;
00624                     for (k = js; k <= i__3; ++k) {
00625                         i__4 = is - 1;
00626                         q__1.r = scaloc, q__1.i = 0.f;
00627                         cscal_(&i__4, &q__1, &c__[k * c_dim1 + 1], &c__1);
00628                         i__4 = is - 1;
00629                         q__1.r = scaloc, q__1.i = 0.f;
00630                         cscal_(&i__4, &q__1, &f[k * f_dim1 + 1], &c__1);
00631 /* L170: */
00632                     }
00633                     i__3 = je;
00634                     for (k = js; k <= i__3; ++k) {
00635                         i__4 = *m - ie;
00636                         q__1.r = scaloc, q__1.i = 0.f;
00637                         cscal_(&i__4, &q__1, &c__[ie + 1 + k * c_dim1], &c__1)
00638                                 ;
00639                         i__4 = *m - ie;
00640                         q__1.r = scaloc, q__1.i = 0.f;
00641                         cscal_(&i__4, &q__1, &f[ie + 1 + k * f_dim1], &c__1);
00642 /* L180: */
00643                     }
00644                     i__3 = *n;
00645                     for (k = je + 1; k <= i__3; ++k) {
00646                         q__1.r = scaloc, q__1.i = 0.f;
00647                         cscal_(m, &q__1, &c__[k * c_dim1 + 1], &c__1);
00648                         q__1.r = scaloc, q__1.i = 0.f;
00649                         cscal_(m, &q__1, &f[k * f_dim1 + 1], &c__1);
00650 /* L190: */
00651                     }
00652                     *scale *= scaloc;
00653                 }
00654 
00655 /*              Substitute R(I,J) and L(I,J) into remaining equation. */
00656 
00657                 if (j > p + 2) {
00658                     i__3 = js - 1;
00659                     cgemm_("N", "C", &mb, &i__3, &nb, &c_b45, &c__[is + js * 
00660                             c_dim1], ldc, &b[js * b_dim1 + 1], ldb, &c_b45, &
00661                             f[is + f_dim1], ldf);
00662                     i__3 = js - 1;
00663                     cgemm_("N", "C", &mb, &i__3, &nb, &c_b45, &f[is + js * 
00664                             f_dim1], ldf, &e[js * e_dim1 + 1], lde, &c_b45, &
00665                             f[is + f_dim1], ldf);
00666                 }
00667                 if (i__ < p) {
00668                     i__3 = *m - ie;
00669                     cgemm_("C", "N", &i__3, &nb, &mb, &c_b44, &a[is + (ie + 1)
00670                              * a_dim1], lda, &c__[is + js * c_dim1], ldc, &
00671                             c_b45, &c__[ie + 1 + js * c_dim1], ldc);
00672                     i__3 = *m - ie;
00673                     cgemm_("C", "N", &i__3, &nb, &mb, &c_b44, &d__[is + (ie + 
00674                             1) * d_dim1], ldd, &f[is + js * f_dim1], ldf, &
00675                             c_b45, &c__[ie + 1 + js * c_dim1], ldc);
00676                 }
00677 /* L200: */
00678             }
00679 /* L210: */
00680         }
00681     }
00682 
00683     work[1].r = (real) lwmin, work[1].i = 0.f;
00684 
00685     return 0;
00686 
00687 /*     End of CTGSYL */
00688 
00689 } /* ctgsyl_ */


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