cheequb.c
Go to the documentation of this file.
00001 /* cheequb.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 cheequb_(char *uplo, integer *n, complex *a, integer *
00021         lda, real *s, real *scond, real *amax, complex *work, integer *info)
00022 {
00023     /* System generated locals */
00024     integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5;
00025     real r__1, r__2, r__3, r__4;
00026     doublereal d__1;
00027     complex q__1, q__2, q__3, q__4;
00028 
00029     /* Builtin functions */
00030     double r_imag(complex *), sqrt(doublereal), log(doublereal), pow_ri(real *
00031             , integer *);
00032 
00033     /* Local variables */
00034     real d__;
00035     integer i__, j;
00036     real t, u, c0, c1, c2, si;
00037     logical up;
00038     real avg, std, tol, base;
00039     integer iter;
00040     real smin, smax, scale;
00041     extern logical lsame_(char *, char *);
00042     real sumsq;
00043     extern doublereal slamch_(char *);
00044     extern /* Subroutine */ int xerbla_(char *, integer *);
00045     real bignum;
00046     extern /* Subroutine */ int classq_(integer *, complex *, integer *, real 
00047             *, real *);
00048     real smlnum;
00049 
00050 
00051 /*     -- LAPACK routine (version 3.2)                                 -- */
00052 /*     -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */
00053 /*     -- Jason Riedy of Univ. of California Berkeley.                 -- */
00054 /*     -- November 2008                                                -- */
00055 
00056 /*     -- LAPACK is a software package provided by Univ. of Tennessee, -- */
00057 /*     -- Univ. of California Berkeley and NAG Ltd.                    -- */
00058 
00059 /*     .. */
00060 /*     .. Scalar Arguments .. */
00061 /*     .. */
00062 /*     .. Array Arguments .. */
00063 /*     .. */
00064 
00065 /*  Purpose */
00066 /*  ======= */
00067 
00068 /*  CSYEQUB computes row and column scalings intended to equilibrate a */
00069 /*  symmetric matrix A and reduce its condition number */
00070 /*  (with respect to the two-norm).  S contains the scale factors, */
00071 /*  S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with */
00072 /*  elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This */
00073 /*  choice of S puts the condition number of B within a factor N of the */
00074 /*  smallest possible condition number over all possible diagonal */
00075 /*  scalings. */
00076 
00077 /*  Arguments */
00078 /*  ========= */
00079 
00080 /*  N       (input) INTEGER */
00081 /*          The order of the matrix A.  N >= 0. */
00082 
00083 /*  A       (input) COMPLEX array, dimension (LDA,N) */
00084 /*          The N-by-N symmetric matrix whose scaling */
00085 /*          factors are to be computed.  Only the diagonal elements of A */
00086 /*          are referenced. */
00087 
00088 /*  LDA     (input) INTEGER */
00089 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00090 
00091 /*  S       (output) REAL array, dimension (N) */
00092 /*          If INFO = 0, S contains the scale factors for A. */
00093 
00094 /*  SCOND   (output) REAL */
00095 /*          If INFO = 0, S contains the ratio of the smallest S(i) to */
00096 /*          the largest S(i).  If SCOND >= 0.1 and AMAX is neither too */
00097 /*          large nor too small, it is not worth scaling by S. */
00098 
00099 /*  AMAX    (output) REAL */
00100 /*          Absolute value of largest matrix element.  If AMAX is very */
00101 /*          close to overflow or very close to underflow, the matrix */
00102 /*          should be scaled. */
00103 /*  INFO    (output) INTEGER */
00104 /*          = 0:  successful exit */
00105 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00106 /*          > 0:  if INFO = i, the i-th diagonal element is nonpositive. */
00107 
00108 /*  ===================================================================== */
00109 
00110 /*     .. Parameters .. */
00111 /*     .. */
00112 /*     .. Local Scalars .. */
00113 /*     .. */
00114 /*     .. External Functions .. */
00115 /*     .. */
00116 /*     .. External Subroutines .. */
00117 /*     .. */
00118 /*     .. Statement Functions .. */
00119 /*     .. */
00120 /*     .. Statement Function Definitions .. */
00121 
00122 /*     Test input parameters. */
00123 
00124     /* Parameter adjustments */
00125     a_dim1 = *lda;
00126     a_offset = 1 + a_dim1;
00127     a -= a_offset;
00128     --s;
00129     --work;
00130 
00131     /* Function Body */
00132     *info = 0;
00133     if (! (lsame_(uplo, "U") || lsame_(uplo, "L"))) {
00134         *info = -1;
00135     } else if (*n < 0) {
00136         *info = -2;
00137     } else if (*lda < max(1,*n)) {
00138         *info = -4;
00139     }
00140     if (*info != 0) {
00141         i__1 = -(*info);
00142         xerbla_("CHEEQUB", &i__1);
00143         return 0;
00144     }
00145     up = lsame_(uplo, "U");
00146     *amax = 0.f;
00147 
00148 /*     Quick return if possible. */
00149 
00150     if (*n == 0) {
00151         *scond = 1.f;
00152         return 0;
00153     }
00154     i__1 = *n;
00155     for (i__ = 1; i__ <= i__1; ++i__) {
00156         s[i__] = 0.f;
00157     }
00158     *amax = 0.f;
00159     if (up) {
00160         i__1 = *n;
00161         for (j = 1; j <= i__1; ++j) {
00162             i__2 = j - 1;
00163             for (i__ = 1; i__ <= i__2; ++i__) {
00164 /* Computing MAX */
00165                 i__3 = i__ + j * a_dim1;
00166                 r__3 = s[i__], r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 =
00167                          r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00168                 s[i__] = dmax(r__3,r__4);
00169 /* Computing MAX */
00170                 i__3 = i__ + j * a_dim1;
00171                 r__3 = s[j], r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00172                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00173                 s[j] = dmax(r__3,r__4);
00174 /* Computing MAX */
00175                 i__3 = i__ + j * a_dim1;
00176                 r__3 = *amax, r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00177                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00178                 *amax = dmax(r__3,r__4);
00179             }
00180 /* Computing MAX */
00181             i__2 = j + j * a_dim1;
00182             r__3 = s[j], r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00183                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00184             s[j] = dmax(r__3,r__4);
00185 /* Computing MAX */
00186             i__2 = j + j * a_dim1;
00187             r__3 = *amax, r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00188                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00189             *amax = dmax(r__3,r__4);
00190         }
00191     } else {
00192         i__1 = *n;
00193         for (j = 1; j <= i__1; ++j) {
00194 /* Computing MAX */
00195             i__2 = j + j * a_dim1;
00196             r__3 = s[j], r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00197                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00198             s[j] = dmax(r__3,r__4);
00199 /* Computing MAX */
00200             i__2 = j + j * a_dim1;
00201             r__3 = *amax, r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00202                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00203             *amax = dmax(r__3,r__4);
00204             i__2 = *n;
00205             for (i__ = j + 1; i__ <= i__2; ++i__) {
00206 /* Computing MAX */
00207                 i__3 = i__ + j * a_dim1;
00208                 r__3 = s[i__], r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 =
00209                          r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00210                 s[i__] = dmax(r__3,r__4);
00211 /* Computing MAX */
00212                 i__3 = i__ + j * a_dim1;
00213                 r__3 = s[j], r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00214                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00215                 s[j] = dmax(r__3,r__4);
00216 /* Computing MAX */
00217                 i__3 = i__ + j * a_dim1;
00218                 r__3 = *amax, r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00219                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00220                 *amax = dmax(r__3,r__4);
00221             }
00222         }
00223     }
00224     i__1 = *n;
00225     for (j = 1; j <= i__1; ++j) {
00226         s[j] = 1.f / s[j];
00227     }
00228     tol = 1.f / sqrt(*n * 2.f);
00229     for (iter = 1; iter <= 100; ++iter) {
00230         scale = 0.f;
00231         sumsq = 0.f;
00232 /*       beta = |A|s */
00233         i__1 = *n;
00234         for (i__ = 1; i__ <= i__1; ++i__) {
00235             i__2 = i__;
00236             work[i__2].r = 0.f, work[i__2].i = 0.f;
00237         }
00238         if (up) {
00239             i__1 = *n;
00240             for (j = 1; j <= i__1; ++j) {
00241                 i__2 = j - 1;
00242                 for (i__ = 1; i__ <= i__2; ++i__) {
00243                     i__3 = i__ + j * a_dim1;
00244                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00245                             i__ + j * a_dim1]), dabs(r__2));
00246                     i__3 = i__;
00247                     i__4 = i__;
00248                     i__5 = i__ + j * a_dim1;
00249                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00250                             a[i__ + j * a_dim1]), dabs(r__2))) * s[j];
00251                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00252                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00253                     i__3 = j;
00254                     i__4 = j;
00255                     i__5 = i__ + j * a_dim1;
00256                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00257                             a[i__ + j * a_dim1]), dabs(r__2))) * s[i__];
00258                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00259                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00260                 }
00261                 i__2 = j;
00262                 i__3 = j;
00263                 i__4 = j + j * a_dim1;
00264                 r__3 = ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00265                         + j * a_dim1]), dabs(r__2))) * s[j];
00266                 q__1.r = work[i__3].r + r__3, q__1.i = work[i__3].i;
00267                 work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00268             }
00269         } else {
00270             i__1 = *n;
00271             for (j = 1; j <= i__1; ++j) {
00272                 i__2 = j;
00273                 i__3 = j;
00274                 i__4 = j + j * a_dim1;
00275                 r__3 = ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00276                         + j * a_dim1]), dabs(r__2))) * s[j];
00277                 q__1.r = work[i__3].r + r__3, q__1.i = work[i__3].i;
00278                 work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00279                 i__2 = *n;
00280                 for (i__ = j + 1; i__ <= i__2; ++i__) {
00281                     i__3 = i__ + j * a_dim1;
00282                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00283                             i__ + j * a_dim1]), dabs(r__2));
00284                     i__3 = i__;
00285                     i__4 = i__;
00286                     i__5 = i__ + j * a_dim1;
00287                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00288                             a[i__ + j * a_dim1]), dabs(r__2))) * s[j];
00289                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00290                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00291                     i__3 = j;
00292                     i__4 = j;
00293                     i__5 = i__ + j * a_dim1;
00294                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00295                             a[i__ + j * a_dim1]), dabs(r__2))) * s[i__];
00296                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00297                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00298                 }
00299             }
00300         }
00301 /*       avg = s^T beta / n */
00302         avg = 0.f;
00303         i__1 = *n;
00304         for (i__ = 1; i__ <= i__1; ++i__) {
00305             i__2 = i__;
00306             i__3 = i__;
00307             q__2.r = s[i__2] * work[i__3].r, q__2.i = s[i__2] * work[i__3].i;
00308             q__1.r = avg + q__2.r, q__1.i = q__2.i;
00309             avg = q__1.r;
00310         }
00311         avg /= *n;
00312         std = 0.f;
00313         i__1 = *n * 3;
00314         for (i__ = (*n << 1) + 1; i__ <= i__1; ++i__) {
00315             i__2 = i__;
00316             i__3 = i__ - (*n << 1);
00317             i__4 = i__ - (*n << 1);
00318             q__2.r = s[i__3] * work[i__4].r, q__2.i = s[i__3] * work[i__4].i;
00319             q__1.r = q__2.r - avg, q__1.i = q__2.i;
00320             work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00321         }
00322         classq_(n, &work[(*n << 1) + 1], &c__1, &scale, &sumsq);
00323         std = scale * sqrt(sumsq / *n);
00324         if (std < tol * avg) {
00325             goto L999;
00326         }
00327         i__1 = *n;
00328         for (i__ = 1; i__ <= i__1; ++i__) {
00329             i__2 = i__ + i__ * a_dim1;
00330             t = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = r_imag(&a[i__ + i__ *
00331                      a_dim1]), dabs(r__2));
00332             si = s[i__];
00333             c2 = (*n - 1) * t;
00334             i__2 = *n - 2;
00335             i__3 = i__;
00336             r__1 = t * si;
00337             q__2.r = work[i__3].r - r__1, q__2.i = work[i__3].i;
00338             d__1 = (doublereal) i__2;
00339             q__1.r = d__1 * q__2.r, q__1.i = d__1 * q__2.i;
00340             c1 = q__1.r;
00341             r__1 = -(t * si) * si;
00342             i__2 = i__;
00343             d__1 = 2.;
00344             q__4.r = d__1 * work[i__2].r, q__4.i = d__1 * work[i__2].i;
00345             q__3.r = si * q__4.r, q__3.i = si * q__4.i;
00346             q__2.r = r__1 + q__3.r, q__2.i = q__3.i;
00347             r__2 = *n * avg;
00348             q__1.r = q__2.r - r__2, q__1.i = q__2.i;
00349             c0 = q__1.r;
00350             d__ = c1 * c1 - c0 * 4 * c2;
00351             if (d__ <= 0.f) {
00352                 *info = -1;
00353                 return 0;
00354             }
00355             si = c0 * -2 / (c1 + sqrt(d__));
00356             d__ = si - s[i__];
00357             u = 0.f;
00358             if (up) {
00359                 i__2 = i__;
00360                 for (j = 1; j <= i__2; ++j) {
00361                     i__3 = j + i__ * a_dim1;
00362                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00363                             + i__ * a_dim1]), dabs(r__2));
00364                     u += s[j] * t;
00365                     i__3 = j;
00366                     i__4 = j;
00367                     r__1 = d__ * t;
00368                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00369                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00370                 }
00371                 i__2 = *n;
00372                 for (j = i__ + 1; j <= i__2; ++j) {
00373                     i__3 = i__ + j * a_dim1;
00374                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00375                             i__ + j * a_dim1]), dabs(r__2));
00376                     u += s[j] * t;
00377                     i__3 = j;
00378                     i__4 = j;
00379                     r__1 = d__ * t;
00380                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00381                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00382                 }
00383             } else {
00384                 i__2 = i__;
00385                 for (j = 1; j <= i__2; ++j) {
00386                     i__3 = i__ + j * a_dim1;
00387                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00388                             i__ + j * a_dim1]), dabs(r__2));
00389                     u += s[j] * t;
00390                     i__3 = j;
00391                     i__4 = j;
00392                     r__1 = d__ * t;
00393                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00394                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00395                 }
00396                 i__2 = *n;
00397                 for (j = i__ + 1; j <= i__2; ++j) {
00398                     i__3 = j + i__ * a_dim1;
00399                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00400                             + i__ * a_dim1]), dabs(r__2));
00401                     u += s[j] * t;
00402                     i__3 = j;
00403                     i__4 = j;
00404                     r__1 = d__ * t;
00405                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00406                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00407                 }
00408             }
00409             i__2 = i__;
00410             q__4.r = u + work[i__2].r, q__4.i = work[i__2].i;
00411             q__3.r = d__ * q__4.r, q__3.i = d__ * q__4.i;
00412             d__1 = (doublereal) (*n);
00413             q__2.r = q__3.r / d__1, q__2.i = q__3.i / d__1;
00414             q__1.r = avg + q__2.r, q__1.i = q__2.i;
00415             avg = q__1.r;
00416             s[i__] = si;
00417         }
00418     }
00419 L999:
00420     smlnum = slamch_("SAFEMIN");
00421     bignum = 1.f / smlnum;
00422     smin = bignum;
00423     smax = 0.f;
00424     t = 1.f / sqrt(avg);
00425     base = slamch_("B");
00426     u = 1.f / log(base);
00427     i__1 = *n;
00428     for (i__ = 1; i__ <= i__1; ++i__) {
00429         i__2 = (integer) (u * log(s[i__] * t));
00430         s[i__] = pow_ri(&base, &i__2);
00431 /* Computing MIN */
00432         r__1 = smin, r__2 = s[i__];
00433         smin = dmin(r__1,r__2);
00434 /* Computing MAX */
00435         r__1 = smax, r__2 = s[i__];
00436         smax = dmax(r__1,r__2);
00437     }
00438     *scond = dmax(smin,smlnum) / dmin(smax,bignum);
00439     return 0;
00440 } /* cheequb_ */


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