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


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