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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:43