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


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