sgebal.c
Go to the documentation of this file.
00001 /* sgebal.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 
00020 /* Subroutine */ int sgebal_(char *job, integer *n, real *a, integer *lda, 
00021         integer *ilo, integer *ihi, real *scale, integer *info)
00022 {
00023     /* System generated locals */
00024     integer a_dim1, a_offset, i__1, i__2;
00025     real r__1, r__2;
00026 
00027     /* Local variables */
00028     real c__, f, g;
00029     integer i__, j, k, l, m;
00030     real r__, s, ca, ra;
00031     integer ica, ira, iexc;
00032     extern logical lsame_(char *, char *);
00033     extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *), 
00034             sswap_(integer *, real *, integer *, real *, integer *);
00035     real sfmin1, sfmin2, sfmax1, sfmax2;
00036     extern doublereal slamch_(char *);
00037     extern /* Subroutine */ int xerbla_(char *, integer *);
00038     extern integer isamax_(integer *, real *, integer *);
00039     logical noconv;
00040 
00041 
00042 /*  -- LAPACK routine (version 3.2) -- */
00043 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00044 /*     November 2006 */
00045 
00046 /*     .. Scalar Arguments .. */
00047 /*     .. */
00048 /*     .. Array Arguments .. */
00049 /*     .. */
00050 
00051 /*  Purpose */
00052 /*  ======= */
00053 
00054 /*  SGEBAL balances a general real matrix A.  This involves, first, */
00055 /*  permuting A by a similarity transformation to isolate eigenvalues */
00056 /*  in the first 1 to ILO-1 and last IHI+1 to N elements on the */
00057 /*  diagonal; and second, applying a diagonal similarity transformation */
00058 /*  to rows and columns ILO to IHI to make the rows and columns as */
00059 /*  close in norm as possible.  Both steps are optional. */
00060 
00061 /*  Balancing may reduce the 1-norm of the matrix, and improve the */
00062 /*  accuracy of the computed eigenvalues and/or eigenvectors. */
00063 
00064 /*  Arguments */
00065 /*  ========= */
00066 
00067 /*  JOB     (input) CHARACTER*1 */
00068 /*          Specifies the operations to be performed on A: */
00069 /*          = 'N':  none:  simply set ILO = 1, IHI = N, SCALE(I) = 1.0 */
00070 /*                  for i = 1,...,N; */
00071 /*          = 'P':  permute only; */
00072 /*          = 'S':  scale only; */
00073 /*          = 'B':  both permute and scale. */
00074 
00075 /*  N       (input) INTEGER */
00076 /*          The order of the matrix A.  N >= 0. */
00077 
00078 /*  A       (input/output) REAL array, dimension (LDA,N) */
00079 /*          On entry, the input matrix A. */
00080 /*          On exit,  A is overwritten by the balanced matrix. */
00081 /*          If JOB = 'N', A is not referenced. */
00082 /*          See Further Details. */
00083 
00084 /*  LDA     (input) INTEGER */
00085 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00086 
00087 /*  ILO     (output) INTEGER */
00088 /*  IHI     (output) INTEGER */
00089 /*          ILO and IHI are set to integers such that on exit */
00090 /*          A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N. */
00091 /*          If JOB = 'N' or 'S', ILO = 1 and IHI = N. */
00092 
00093 /*  SCALE   (output) REAL array, dimension (N) */
00094 /*          Details of the permutations and scaling factors applied to */
00095 /*          A.  If P(j) is the index of the row and column interchanged */
00096 /*          with row and column j and D(j) is the scaling factor */
00097 /*          applied to row and column j, then */
00098 /*          SCALE(j) = P(j)    for j = 1,...,ILO-1 */
00099 /*                   = D(j)    for j = ILO,...,IHI */
00100 /*                   = P(j)    for j = IHI+1,...,N. */
00101 /*          The order in which the interchanges are made is N to IHI+1, */
00102 /*          then 1 to ILO-1. */
00103 
00104 /*  INFO    (output) INTEGER */
00105 /*          = 0:  successful exit. */
00106 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00107 
00108 /*  Further Details */
00109 /*  =============== */
00110 
00111 /*  The permutations consist of row and column interchanges which put */
00112 /*  the matrix in the form */
00113 
00114 /*             ( T1   X   Y  ) */
00115 /*     P A P = (  0   B   Z  ) */
00116 /*             (  0   0   T2 ) */
00117 
00118 /*  where T1 and T2 are upper triangular matrices whose eigenvalues lie */
00119 /*  along the diagonal.  The column indices ILO and IHI mark the starting */
00120 /*  and ending columns of the submatrix B. Balancing consists of applying */
00121 /*  a diagonal similarity transformation inv(D) * B * D to make the */
00122 /*  1-norms of each row of B and its corresponding column nearly equal. */
00123 /*  The output matrix is */
00124 
00125 /*     ( T1     X*D          Y    ) */
00126 /*     (  0  inv(D)*B*D  inv(D)*Z ). */
00127 /*     (  0      0           T2   ) */
00128 
00129 /*  Information about the permutations P and the diagonal matrix D is */
00130 /*  returned in the vector SCALE. */
00131 
00132 /*  This subroutine is based on the EISPACK routine BALANC. */
00133 
00134 /*  Modified by Tzu-Yi Chen, Computer Science Division, University of */
00135 /*    California at Berkeley, USA */
00136 
00137 /*  ===================================================================== */
00138 
00139 /*     .. Parameters .. */
00140 /*     .. */
00141 /*     .. Local Scalars .. */
00142 /*     .. */
00143 /*     .. External Functions .. */
00144 /*     .. */
00145 /*     .. External Subroutines .. */
00146 /*     .. */
00147 /*     .. Intrinsic Functions .. */
00148 /*     .. */
00149 /*     .. Executable Statements .. */
00150 
00151 /*     Test the input parameters */
00152 
00153     /* Parameter adjustments */
00154     a_dim1 = *lda;
00155     a_offset = 1 + a_dim1;
00156     a -= a_offset;
00157     --scale;
00158 
00159     /* Function Body */
00160     *info = 0;
00161     if (! lsame_(job, "N") && ! lsame_(job, "P") && ! lsame_(job, "S") 
00162             && ! lsame_(job, "B")) {
00163         *info = -1;
00164     } else if (*n < 0) {
00165         *info = -2;
00166     } else if (*lda < max(1,*n)) {
00167         *info = -4;
00168     }
00169     if (*info != 0) {
00170         i__1 = -(*info);
00171         xerbla_("SGEBAL", &i__1);
00172         return 0;
00173     }
00174 
00175     k = 1;
00176     l = *n;
00177 
00178     if (*n == 0) {
00179         goto L210;
00180     }
00181 
00182     if (lsame_(job, "N")) {
00183         i__1 = *n;
00184         for (i__ = 1; i__ <= i__1; ++i__) {
00185             scale[i__] = 1.f;
00186 /* L10: */
00187         }
00188         goto L210;
00189     }
00190 
00191     if (lsame_(job, "S")) {
00192         goto L120;
00193     }
00194 
00195 /*     Permutation to isolate eigenvalues if possible */
00196 
00197     goto L50;
00198 
00199 /*     Row and column exchange. */
00200 
00201 L20:
00202     scale[m] = (real) j;
00203     if (j == m) {
00204         goto L30;
00205     }
00206 
00207     sswap_(&l, &a[j * a_dim1 + 1], &c__1, &a[m * a_dim1 + 1], &c__1);
00208     i__1 = *n - k + 1;
00209     sswap_(&i__1, &a[j + k * a_dim1], lda, &a[m + k * a_dim1], lda);
00210 
00211 L30:
00212     switch (iexc) {
00213         case 1:  goto L40;
00214         case 2:  goto L80;
00215     }
00216 
00217 /*     Search for rows isolating an eigenvalue and push them down. */
00218 
00219 L40:
00220     if (l == 1) {
00221         goto L210;
00222     }
00223     --l;
00224 
00225 L50:
00226     for (j = l; j >= 1; --j) {
00227 
00228         i__1 = l;
00229         for (i__ = 1; i__ <= i__1; ++i__) {
00230             if (i__ == j) {
00231                 goto L60;
00232             }
00233             if (a[j + i__ * a_dim1] != 0.f) {
00234                 goto L70;
00235             }
00236 L60:
00237             ;
00238         }
00239 
00240         m = l;
00241         iexc = 1;
00242         goto L20;
00243 L70:
00244         ;
00245     }
00246 
00247     goto L90;
00248 
00249 /*     Search for columns isolating an eigenvalue and push them left. */
00250 
00251 L80:
00252     ++k;
00253 
00254 L90:
00255     i__1 = l;
00256     for (j = k; j <= i__1; ++j) {
00257 
00258         i__2 = l;
00259         for (i__ = k; i__ <= i__2; ++i__) {
00260             if (i__ == j) {
00261                 goto L100;
00262             }
00263             if (a[i__ + j * a_dim1] != 0.f) {
00264                 goto L110;
00265             }
00266 L100:
00267             ;
00268         }
00269 
00270         m = k;
00271         iexc = 2;
00272         goto L20;
00273 L110:
00274         ;
00275     }
00276 
00277 L120:
00278     i__1 = l;
00279     for (i__ = k; i__ <= i__1; ++i__) {
00280         scale[i__] = 1.f;
00281 /* L130: */
00282     }
00283 
00284     if (lsame_(job, "P")) {
00285         goto L210;
00286     }
00287 
00288 /*     Balance the submatrix in rows K to L. */
00289 
00290 /*     Iterative loop for norm reduction */
00291 
00292     sfmin1 = slamch_("S") / slamch_("P");
00293     sfmax1 = 1.f / sfmin1;
00294     sfmin2 = sfmin1 * 2.f;
00295     sfmax2 = 1.f / sfmin2;
00296 L140:
00297     noconv = FALSE_;
00298 
00299     i__1 = l;
00300     for (i__ = k; i__ <= i__1; ++i__) {
00301         c__ = 0.f;
00302         r__ = 0.f;
00303 
00304         i__2 = l;
00305         for (j = k; j <= i__2; ++j) {
00306             if (j == i__) {
00307                 goto L150;
00308             }
00309             c__ += (r__1 = a[j + i__ * a_dim1], dabs(r__1));
00310             r__ += (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00311 L150:
00312             ;
00313         }
00314         ica = isamax_(&l, &a[i__ * a_dim1 + 1], &c__1);
00315         ca = (r__1 = a[ica + i__ * a_dim1], dabs(r__1));
00316         i__2 = *n - k + 1;
00317         ira = isamax_(&i__2, &a[i__ + k * a_dim1], lda);
00318         ra = (r__1 = a[i__ + (ira + k - 1) * a_dim1], dabs(r__1));
00319 
00320 /*        Guard against zero C or R due to underflow. */
00321 
00322         if (c__ == 0.f || r__ == 0.f) {
00323             goto L200;
00324         }
00325         g = r__ / 2.f;
00326         f = 1.f;
00327         s = c__ + r__;
00328 L160:
00329 /* Computing MAX */
00330         r__1 = max(f,c__);
00331 /* Computing MIN */
00332         r__2 = min(r__,g);
00333         if (c__ >= g || dmax(r__1,ca) >= sfmax2 || dmin(r__2,ra) <= sfmin2) {
00334             goto L170;
00335         }
00336         f *= 2.f;
00337         c__ *= 2.f;
00338         ca *= 2.f;
00339         r__ /= 2.f;
00340         g /= 2.f;
00341         ra /= 2.f;
00342         goto L160;
00343 
00344 L170:
00345         g = c__ / 2.f;
00346 L180:
00347 /* Computing MIN */
00348         r__1 = min(f,c__), r__1 = min(r__1,g);
00349         if (g < r__ || dmax(r__,ra) >= sfmax2 || dmin(r__1,ca) <= sfmin2) {
00350             goto L190;
00351         }
00352         f /= 2.f;
00353         c__ /= 2.f;
00354         g /= 2.f;
00355         ca /= 2.f;
00356         r__ *= 2.f;
00357         ra *= 2.f;
00358         goto L180;
00359 
00360 /*        Now balance. */
00361 
00362 L190:
00363         if (c__ + r__ >= s * .95f) {
00364             goto L200;
00365         }
00366         if (f < 1.f && scale[i__] < 1.f) {
00367             if (f * scale[i__] <= sfmin1) {
00368                 goto L200;
00369             }
00370         }
00371         if (f > 1.f && scale[i__] > 1.f) {
00372             if (scale[i__] >= sfmax1 / f) {
00373                 goto L200;
00374             }
00375         }
00376         g = 1.f / f;
00377         scale[i__] *= f;
00378         noconv = TRUE_;
00379 
00380         i__2 = *n - k + 1;
00381         sscal_(&i__2, &g, &a[i__ + k * a_dim1], lda);
00382         sscal_(&l, &f, &a[i__ * a_dim1 + 1], &c__1);
00383 
00384 L200:
00385         ;
00386     }
00387 
00388     if (noconv) {
00389         goto L140;
00390     }
00391 
00392 L210:
00393     *ilo = k;
00394     *ihi = l;
00395 
00396     return 0;
00397 
00398 /*     End of SGEBAL */
00399 
00400 } /* sgebal_ */


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