sggbal.c
Go to the documentation of this file.
00001 /* sggbal.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__1 = 1;
00019 static real c_b35 = 10.f;
00020 static real c_b71 = .5f;
00021 
00022 /* Subroutine */ int sggbal_(char *job, integer *n, real *a, integer *lda, 
00023         real *b, integer *ldb, integer *ilo, integer *ihi, real *lscale, real 
00024         *rscale, real *work, integer *info)
00025 {
00026     /* System generated locals */
00027     integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
00028     real r__1, r__2, r__3;
00029 
00030     /* Builtin functions */
00031     double r_lg10(real *), r_sign(real *, real *), pow_ri(real *, integer *);
00032 
00033     /* Local variables */
00034     integer i__, j, k, l, m;
00035     real t;
00036     integer jc;
00037     real ta, tb, tc;
00038     integer ir;
00039     real ew;
00040     integer it, nr, ip1, jp1, lm1;
00041     real cab, rab, ewc, cor, sum;
00042     integer nrp2, icab, lcab;
00043     real beta, coef;
00044     integer irab, lrab;
00045     real basl, cmax;
00046     extern doublereal sdot_(integer *, real *, integer *, real *, integer *);
00047     real coef2, coef5, gamma, alpha;
00048     extern logical lsame_(char *, char *);
00049     extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *);
00050     real sfmin, sfmax;
00051     integer iflow;
00052     extern /* Subroutine */ int sswap_(integer *, real *, integer *, real *, 
00053             integer *);
00054     integer kount;
00055     extern /* Subroutine */ int saxpy_(integer *, real *, real *, integer *, 
00056             real *, integer *);
00057     real pgamma;
00058     extern doublereal slamch_(char *);
00059     extern /* Subroutine */ int xerbla_(char *, integer *);
00060     extern integer isamax_(integer *, real *, integer *);
00061     integer lsfmin, lsfmax;
00062 
00063 
00064 /*  -- LAPACK routine (version 3.2) -- */
00065 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00066 /*     November 2006 */
00067 
00068 /*     .. Scalar Arguments .. */
00069 /*     .. */
00070 /*     .. Array Arguments .. */
00071 /*     .. */
00072 
00073 /*  Purpose */
00074 /*  ======= */
00075 
00076 /*  SGGBAL balances a pair of general real matrices (A,B).  This */
00077 /*  involves, first, permuting A and B by similarity transformations to */
00078 /*  isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N */
00079 /*  elements on the diagonal; and second, applying a diagonal similarity */
00080 /*  transformation to rows and columns ILO to IHI to make the rows */
00081 /*  and columns as close in norm as possible. Both steps are optional. */
00082 
00083 /*  Balancing may reduce the 1-norm of the matrices, and improve the */
00084 /*  accuracy of the computed eigenvalues and/or eigenvectors in the */
00085 /*  generalized eigenvalue problem A*x = lambda*B*x. */
00086 
00087 /*  Arguments */
00088 /*  ========= */
00089 
00090 /*  JOB     (input) CHARACTER*1 */
00091 /*          Specifies the operations to be performed on A and B: */
00092 /*          = 'N':  none:  simply set ILO = 1, IHI = N, LSCALE(I) = 1.0 */
00093 /*                  and RSCALE(I) = 1.0 for i = 1,...,N. */
00094 /*          = 'P':  permute only; */
00095 /*          = 'S':  scale only; */
00096 /*          = 'B':  both permute and scale. */
00097 
00098 /*  N       (input) INTEGER */
00099 /*          The order of the matrices A and B.  N >= 0. */
00100 
00101 /*  A       (input/output) REAL array, dimension (LDA,N) */
00102 /*          On entry, the input matrix A. */
00103 /*          On exit,  A is overwritten by the balanced matrix. */
00104 /*          If JOB = 'N', A is not referenced. */
00105 
00106 /*  LDA     (input) INTEGER */
00107 /*          The leading dimension of the array A. LDA >= max(1,N). */
00108 
00109 /*  B       (input/output) REAL array, dimension (LDB,N) */
00110 /*          On entry, the input matrix B. */
00111 /*          On exit,  B is overwritten by the balanced matrix. */
00112 /*          If JOB = 'N', B is not referenced. */
00113 
00114 /*  LDB     (input) INTEGER */
00115 /*          The leading dimension of the array B. LDB >= max(1,N). */
00116 
00117 /*  ILO     (output) INTEGER */
00118 /*  IHI     (output) INTEGER */
00119 /*          ILO and IHI are set to integers such that on exit */
00120 /*          A(i,j) = 0 and B(i,j) = 0 if i > j and */
00121 /*          j = 1,...,ILO-1 or i = IHI+1,...,N. */
00122 /*          If JOB = 'N' or 'S', ILO = 1 and IHI = N. */
00123 
00124 /*  LSCALE  (output) REAL array, dimension (N) */
00125 /*          Details of the permutations and scaling factors applied */
00126 /*          to the left side of A and B.  If P(j) is the index of the */
00127 /*          row interchanged with row j, and D(j) */
00128 /*          is the scaling factor applied to row j, then */
00129 /*            LSCALE(j) = P(j)    for J = 1,...,ILO-1 */
00130 /*                      = D(j)    for J = ILO,...,IHI */
00131 /*                      = P(j)    for J = IHI+1,...,N. */
00132 /*          The order in which the interchanges are made is N to IHI+1, */
00133 /*          then 1 to ILO-1. */
00134 
00135 /*  RSCALE  (output) REAL array, dimension (N) */
00136 /*          Details of the permutations and scaling factors applied */
00137 /*          to the right side of A and B.  If P(j) is the index of the */
00138 /*          column interchanged with column j, and D(j) */
00139 /*          is the scaling factor applied to column j, then */
00140 /*            LSCALE(j) = P(j)    for J = 1,...,ILO-1 */
00141 /*                      = D(j)    for J = ILO,...,IHI */
00142 /*                      = P(j)    for J = IHI+1,...,N. */
00143 /*          The order in which the interchanges are made is N to IHI+1, */
00144 /*          then 1 to ILO-1. */
00145 
00146 /*  WORK    (workspace) REAL array, dimension (lwork) */
00147 /*          lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and */
00148 /*          at least 1 when JOB = 'N' or 'P'. */
00149 
00150 /*  INFO    (output) INTEGER */
00151 /*          = 0:  successful exit */
00152 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00153 
00154 /*  Further Details */
00155 /*  =============== */
00156 
00157 /*  See R.C. WARD, Balancing the generalized eigenvalue problem, */
00158 /*                 SIAM J. Sci. Stat. Comp. 2 (1981), 141-152. */
00159 
00160 /*  ===================================================================== */
00161 
00162 /*     .. Parameters .. */
00163 /*     .. */
00164 /*     .. Local Scalars .. */
00165 /*     .. */
00166 /*     .. External Functions .. */
00167 /*     .. */
00168 /*     .. External Subroutines .. */
00169 /*     .. */
00170 /*     .. Intrinsic Functions .. */
00171 /*     .. */
00172 /*     .. Executable Statements .. */
00173 
00174 /*     Test the input parameters */
00175 
00176     /* Parameter adjustments */
00177     a_dim1 = *lda;
00178     a_offset = 1 + a_dim1;
00179     a -= a_offset;
00180     b_dim1 = *ldb;
00181     b_offset = 1 + b_dim1;
00182     b -= b_offset;
00183     --lscale;
00184     --rscale;
00185     --work;
00186 
00187     /* Function Body */
00188     *info = 0;
00189     if (! lsame_(job, "N") && ! lsame_(job, "P") && ! lsame_(job, "S") 
00190             && ! lsame_(job, "B")) {
00191         *info = -1;
00192     } else if (*n < 0) {
00193         *info = -2;
00194     } else if (*lda < max(1,*n)) {
00195         *info = -4;
00196     } else if (*ldb < max(1,*n)) {
00197         *info = -6;
00198     }
00199     if (*info != 0) {
00200         i__1 = -(*info);
00201         xerbla_("SGGBAL", &i__1);
00202         return 0;
00203     }
00204 
00205 /*     Quick return if possible */
00206 
00207     if (*n == 0) {
00208         *ilo = 1;
00209         *ihi = *n;
00210         return 0;
00211     }
00212 
00213     if (*n == 1) {
00214         *ilo = 1;
00215         *ihi = *n;
00216         lscale[1] = 1.f;
00217         rscale[1] = 1.f;
00218         return 0;
00219     }
00220 
00221     if (lsame_(job, "N")) {
00222         *ilo = 1;
00223         *ihi = *n;
00224         i__1 = *n;
00225         for (i__ = 1; i__ <= i__1; ++i__) {
00226             lscale[i__] = 1.f;
00227             rscale[i__] = 1.f;
00228 /* L10: */
00229         }
00230         return 0;
00231     }
00232 
00233     k = 1;
00234     l = *n;
00235     if (lsame_(job, "S")) {
00236         goto L190;
00237     }
00238 
00239     goto L30;
00240 
00241 /*     Permute the matrices A and B to isolate the eigenvalues. */
00242 
00243 /*     Find row with one nonzero in columns 1 through L */
00244 
00245 L20:
00246     l = lm1;
00247     if (l != 1) {
00248         goto L30;
00249     }
00250 
00251     rscale[1] = 1.f;
00252     lscale[1] = 1.f;
00253     goto L190;
00254 
00255 L30:
00256     lm1 = l - 1;
00257     for (i__ = l; i__ >= 1; --i__) {
00258         i__1 = lm1;
00259         for (j = 1; j <= i__1; ++j) {
00260             jp1 = j + 1;
00261             if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00262                 goto L50;
00263             }
00264 /* L40: */
00265         }
00266         j = l;
00267         goto L70;
00268 
00269 L50:
00270         i__1 = l;
00271         for (j = jp1; j <= i__1; ++j) {
00272             if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00273                 goto L80;
00274             }
00275 /* L60: */
00276         }
00277         j = jp1 - 1;
00278 
00279 L70:
00280         m = l;
00281         iflow = 1;
00282         goto L160;
00283 L80:
00284         ;
00285     }
00286     goto L100;
00287 
00288 /*     Find column with one nonzero in rows K through N */
00289 
00290 L90:
00291     ++k;
00292 
00293 L100:
00294     i__1 = l;
00295     for (j = k; j <= i__1; ++j) {
00296         i__2 = lm1;
00297         for (i__ = k; i__ <= i__2; ++i__) {
00298             ip1 = i__ + 1;
00299             if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00300                 goto L120;
00301             }
00302 /* L110: */
00303         }
00304         i__ = l;
00305         goto L140;
00306 L120:
00307         i__2 = l;
00308         for (i__ = ip1; i__ <= i__2; ++i__) {
00309             if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00310                 goto L150;
00311             }
00312 /* L130: */
00313         }
00314         i__ = ip1 - 1;
00315 L140:
00316         m = k;
00317         iflow = 2;
00318         goto L160;
00319 L150:
00320         ;
00321     }
00322     goto L190;
00323 
00324 /*     Permute rows M and I */
00325 
00326 L160:
00327     lscale[m] = (real) i__;
00328     if (i__ == m) {
00329         goto L170;
00330     }
00331     i__1 = *n - k + 1;
00332     sswap_(&i__1, &a[i__ + k * a_dim1], lda, &a[m + k * a_dim1], lda);
00333     i__1 = *n - k + 1;
00334     sswap_(&i__1, &b[i__ + k * b_dim1], ldb, &b[m + k * b_dim1], ldb);
00335 
00336 /*     Permute columns M and J */
00337 
00338 L170:
00339     rscale[m] = (real) j;
00340     if (j == m) {
00341         goto L180;
00342     }
00343     sswap_(&l, &a[j * a_dim1 + 1], &c__1, &a[m * a_dim1 + 1], &c__1);
00344     sswap_(&l, &b[j * b_dim1 + 1], &c__1, &b[m * b_dim1 + 1], &c__1);
00345 
00346 L180:
00347     switch (iflow) {
00348         case 1:  goto L20;
00349         case 2:  goto L90;
00350     }
00351 
00352 L190:
00353     *ilo = k;
00354     *ihi = l;
00355 
00356     if (lsame_(job, "P")) {
00357         i__1 = *ihi;
00358         for (i__ = *ilo; i__ <= i__1; ++i__) {
00359             lscale[i__] = 1.f;
00360             rscale[i__] = 1.f;
00361 /* L195: */
00362         }
00363         return 0;
00364     }
00365 
00366     if (*ilo == *ihi) {
00367         return 0;
00368     }
00369 
00370 /*     Balance the submatrix in rows ILO to IHI. */
00371 
00372     nr = *ihi - *ilo + 1;
00373     i__1 = *ihi;
00374     for (i__ = *ilo; i__ <= i__1; ++i__) {
00375         rscale[i__] = 0.f;
00376         lscale[i__] = 0.f;
00377 
00378         work[i__] = 0.f;
00379         work[i__ + *n] = 0.f;
00380         work[i__ + (*n << 1)] = 0.f;
00381         work[i__ + *n * 3] = 0.f;
00382         work[i__ + (*n << 2)] = 0.f;
00383         work[i__ + *n * 5] = 0.f;
00384 /* L200: */
00385     }
00386 
00387 /*     Compute right side vector in resulting linear equations */
00388 
00389     basl = r_lg10(&c_b35);
00390     i__1 = *ihi;
00391     for (i__ = *ilo; i__ <= i__1; ++i__) {
00392         i__2 = *ihi;
00393         for (j = *ilo; j <= i__2; ++j) {
00394             tb = b[i__ + j * b_dim1];
00395             ta = a[i__ + j * a_dim1];
00396             if (ta == 0.f) {
00397                 goto L210;
00398             }
00399             r__1 = dabs(ta);
00400             ta = r_lg10(&r__1) / basl;
00401 L210:
00402             if (tb == 0.f) {
00403                 goto L220;
00404             }
00405             r__1 = dabs(tb);
00406             tb = r_lg10(&r__1) / basl;
00407 L220:
00408             work[i__ + (*n << 2)] = work[i__ + (*n << 2)] - ta - tb;
00409             work[j + *n * 5] = work[j + *n * 5] - ta - tb;
00410 /* L230: */
00411         }
00412 /* L240: */
00413     }
00414 
00415     coef = 1.f / (real) (nr << 1);
00416     coef2 = coef * coef;
00417     coef5 = coef2 * .5f;
00418     nrp2 = nr + 2;
00419     beta = 0.f;
00420     it = 1;
00421 
00422 /*     Start generalized conjugate gradient iteration */
00423 
00424 L250:
00425 
00426     gamma = sdot_(&nr, &work[*ilo + (*n << 2)], &c__1, &work[*ilo + (*n << 2)]
00427 , &c__1) + sdot_(&nr, &work[*ilo + *n * 5], &c__1, &work[*ilo + *
00428             n * 5], &c__1);
00429 
00430     ew = 0.f;
00431     ewc = 0.f;
00432     i__1 = *ihi;
00433     for (i__ = *ilo; i__ <= i__1; ++i__) {
00434         ew += work[i__ + (*n << 2)];
00435         ewc += work[i__ + *n * 5];
00436 /* L260: */
00437     }
00438 
00439 /* Computing 2nd power */
00440     r__1 = ew;
00441 /* Computing 2nd power */
00442     r__2 = ewc;
00443 /* Computing 2nd power */
00444     r__3 = ew - ewc;
00445     gamma = coef * gamma - coef2 * (r__1 * r__1 + r__2 * r__2) - coef5 * (
00446             r__3 * r__3);
00447     if (gamma == 0.f) {
00448         goto L350;
00449     }
00450     if (it != 1) {
00451         beta = gamma / pgamma;
00452     }
00453     t = coef5 * (ewc - ew * 3.f);
00454     tc = coef5 * (ew - ewc * 3.f);
00455 
00456     sscal_(&nr, &beta, &work[*ilo], &c__1);
00457     sscal_(&nr, &beta, &work[*ilo + *n], &c__1);
00458 
00459     saxpy_(&nr, &coef, &work[*ilo + (*n << 2)], &c__1, &work[*ilo + *n], &
00460             c__1);
00461     saxpy_(&nr, &coef, &work[*ilo + *n * 5], &c__1, &work[*ilo], &c__1);
00462 
00463     i__1 = *ihi;
00464     for (i__ = *ilo; i__ <= i__1; ++i__) {
00465         work[i__] += tc;
00466         work[i__ + *n] += t;
00467 /* L270: */
00468     }
00469 
00470 /*     Apply matrix to vector */
00471 
00472     i__1 = *ihi;
00473     for (i__ = *ilo; i__ <= i__1; ++i__) {
00474         kount = 0;
00475         sum = 0.f;
00476         i__2 = *ihi;
00477         for (j = *ilo; j <= i__2; ++j) {
00478             if (a[i__ + j * a_dim1] == 0.f) {
00479                 goto L280;
00480             }
00481             ++kount;
00482             sum += work[j];
00483 L280:
00484             if (b[i__ + j * b_dim1] == 0.f) {
00485                 goto L290;
00486             }
00487             ++kount;
00488             sum += work[j];
00489 L290:
00490             ;
00491         }
00492         work[i__ + (*n << 1)] = (real) kount * work[i__ + *n] + sum;
00493 /* L300: */
00494     }
00495 
00496     i__1 = *ihi;
00497     for (j = *ilo; j <= i__1; ++j) {
00498         kount = 0;
00499         sum = 0.f;
00500         i__2 = *ihi;
00501         for (i__ = *ilo; i__ <= i__2; ++i__) {
00502             if (a[i__ + j * a_dim1] == 0.f) {
00503                 goto L310;
00504             }
00505             ++kount;
00506             sum += work[i__ + *n];
00507 L310:
00508             if (b[i__ + j * b_dim1] == 0.f) {
00509                 goto L320;
00510             }
00511             ++kount;
00512             sum += work[i__ + *n];
00513 L320:
00514             ;
00515         }
00516         work[j + *n * 3] = (real) kount * work[j] + sum;
00517 /* L330: */
00518     }
00519 
00520     sum = sdot_(&nr, &work[*ilo + *n], &c__1, &work[*ilo + (*n << 1)], &c__1) 
00521             + sdot_(&nr, &work[*ilo], &c__1, &work[*ilo + *n * 3], &c__1);
00522     alpha = gamma / sum;
00523 
00524 /*     Determine correction to current iteration */
00525 
00526     cmax = 0.f;
00527     i__1 = *ihi;
00528     for (i__ = *ilo; i__ <= i__1; ++i__) {
00529         cor = alpha * work[i__ + *n];
00530         if (dabs(cor) > cmax) {
00531             cmax = dabs(cor);
00532         }
00533         lscale[i__] += cor;
00534         cor = alpha * work[i__];
00535         if (dabs(cor) > cmax) {
00536             cmax = dabs(cor);
00537         }
00538         rscale[i__] += cor;
00539 /* L340: */
00540     }
00541     if (cmax < .5f) {
00542         goto L350;
00543     }
00544 
00545     r__1 = -alpha;
00546     saxpy_(&nr, &r__1, &work[*ilo + (*n << 1)], &c__1, &work[*ilo + (*n << 2)]
00547 , &c__1);
00548     r__1 = -alpha;
00549     saxpy_(&nr, &r__1, &work[*ilo + *n * 3], &c__1, &work[*ilo + *n * 5], &
00550             c__1);
00551 
00552     pgamma = gamma;
00553     ++it;
00554     if (it <= nrp2) {
00555         goto L250;
00556     }
00557 
00558 /*     End generalized conjugate gradient iteration */
00559 
00560 L350:
00561     sfmin = slamch_("S");
00562     sfmax = 1.f / sfmin;
00563     lsfmin = (integer) (r_lg10(&sfmin) / basl + 1.f);
00564     lsfmax = (integer) (r_lg10(&sfmax) / basl);
00565     i__1 = *ihi;
00566     for (i__ = *ilo; i__ <= i__1; ++i__) {
00567         i__2 = *n - *ilo + 1;
00568         irab = isamax_(&i__2, &a[i__ + *ilo * a_dim1], lda);
00569         rab = (r__1 = a[i__ + (irab + *ilo - 1) * a_dim1], dabs(r__1));
00570         i__2 = *n - *ilo + 1;
00571         irab = isamax_(&i__2, &b[i__ + *ilo * b_dim1], ldb);
00572 /* Computing MAX */
00573         r__2 = rab, r__3 = (r__1 = b[i__ + (irab + *ilo - 1) * b_dim1], dabs(
00574                 r__1));
00575         rab = dmax(r__2,r__3);
00576         r__1 = rab + sfmin;
00577         lrab = (integer) (r_lg10(&r__1) / basl + 1.f);
00578         ir = lscale[i__] + r_sign(&c_b71, &lscale[i__]);
00579 /* Computing MIN */
00580         i__2 = max(ir,lsfmin), i__2 = min(i__2,lsfmax), i__3 = lsfmax - lrab;
00581         ir = min(i__2,i__3);
00582         lscale[i__] = pow_ri(&c_b35, &ir);
00583         icab = isamax_(ihi, &a[i__ * a_dim1 + 1], &c__1);
00584         cab = (r__1 = a[icab + i__ * a_dim1], dabs(r__1));
00585         icab = isamax_(ihi, &b[i__ * b_dim1 + 1], &c__1);
00586 /* Computing MAX */
00587         r__2 = cab, r__3 = (r__1 = b[icab + i__ * b_dim1], dabs(r__1));
00588         cab = dmax(r__2,r__3);
00589         r__1 = cab + sfmin;
00590         lcab = (integer) (r_lg10(&r__1) / basl + 1.f);
00591         jc = rscale[i__] + r_sign(&c_b71, &rscale[i__]);
00592 /* Computing MIN */
00593         i__2 = max(jc,lsfmin), i__2 = min(i__2,lsfmax), i__3 = lsfmax - lcab;
00594         jc = min(i__2,i__3);
00595         rscale[i__] = pow_ri(&c_b35, &jc);
00596 /* L360: */
00597     }
00598 
00599 /*     Row scaling of matrices A and B */
00600 
00601     i__1 = *ihi;
00602     for (i__ = *ilo; i__ <= i__1; ++i__) {
00603         i__2 = *n - *ilo + 1;
00604         sscal_(&i__2, &lscale[i__], &a[i__ + *ilo * a_dim1], lda);
00605         i__2 = *n - *ilo + 1;
00606         sscal_(&i__2, &lscale[i__], &b[i__ + *ilo * b_dim1], ldb);
00607 /* L370: */
00608     }
00609 
00610 /*     Column scaling of matrices A and B */
00611 
00612     i__1 = *ihi;
00613     for (j = *ilo; j <= i__1; ++j) {
00614         sscal_(ihi, &rscale[j], &a[j * a_dim1 + 1], &c__1);
00615         sscal_(ihi, &rscale[j], &b[j * b_dim1 + 1], &c__1);
00616 /* L380: */
00617     }
00618 
00619     return 0;
00620 
00621 /*     End of SGGBAL */
00622 
00623 } /* sggbal_ */


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