csyequb.c
Go to the documentation of this file.
00001 /* csyequb.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 csyequb_(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 /*  Further Details */
00109 /*  ======= ======= */
00110 
00111 /*  Reference: Livne, O.E. and Golub, G.H., "Scaling by Binormalization", */
00112 /*  Numerical Algorithms, vol. 35, no. 1, pp. 97-120, January 2004. */
00113 /*  DOI 10.1023/B:NUMA.0000016606.32820.69 */
00114 /*  Tech report version: http://ruready.utah.edu/archive/papers/bin.pdf */
00115 
00116 /*  ===================================================================== */
00117 
00118 /*     .. Parameters .. */
00119 /*     .. */
00120 /*     .. Local Scalars .. */
00121 /*     .. */
00122 /*     .. External Functions .. */
00123 /*     .. */
00124 /*     .. External Subroutines .. */
00125 /*     .. */
00126 /*     .. Statement Functions .. */
00127 /*     .. */
00128 /*     Statement Function Definitions */
00129 /*     .. */
00130 /*     .. Executable Statements .. */
00131 
00132 /*     Test the input parameters. */
00133 
00134     /* Parameter adjustments */
00135     a_dim1 = *lda;
00136     a_offset = 1 + a_dim1;
00137     a -= a_offset;
00138     --s;
00139     --work;
00140 
00141     /* Function Body */
00142     *info = 0;
00143     if (! (lsame_(uplo, "U") || lsame_(uplo, "L"))) {
00144         *info = -1;
00145     } else if (*n < 0) {
00146         *info = -2;
00147     } else if (*lda < max(1,*n)) {
00148         *info = -4;
00149     }
00150     if (*info != 0) {
00151         i__1 = -(*info);
00152         xerbla_("CSYEQUB", &i__1);
00153         return 0;
00154     }
00155     up = lsame_(uplo, "U");
00156     *amax = 0.f;
00157 
00158 /*     Quick return if possible. */
00159 
00160     if (*n == 0) {
00161         *scond = 1.f;
00162         return 0;
00163     }
00164     i__1 = *n;
00165     for (i__ = 1; i__ <= i__1; ++i__) {
00166         s[i__] = 0.f;
00167     }
00168     *amax = 0.f;
00169     if (up) {
00170         i__1 = *n;
00171         for (j = 1; j <= i__1; ++j) {
00172             i__2 = j - 1;
00173             for (i__ = 1; i__ <= i__2; ++i__) {
00174 /* Computing MAX */
00175                 i__3 = i__ + j * a_dim1;
00176                 r__3 = s[i__], 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                 s[i__] = dmax(r__3,r__4);
00179 /* Computing MAX */
00180                 i__3 = i__ + j * a_dim1;
00181                 r__3 = s[j], r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00182                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00183                 s[j] = dmax(r__3,r__4);
00184 /* Computing MAX */
00185                 i__3 = i__ + j * a_dim1;
00186                 r__3 = *amax, r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00187                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00188                 *amax = dmax(r__3,r__4);
00189             }
00190 /* Computing MAX */
00191             i__2 = j + j * a_dim1;
00192             r__3 = s[j], r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00193                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00194             s[j] = dmax(r__3,r__4);
00195 /* Computing MAX */
00196             i__2 = j + j * a_dim1;
00197             r__3 = *amax, r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00198                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00199             *amax = dmax(r__3,r__4);
00200         }
00201     } else {
00202         i__1 = *n;
00203         for (j = 1; j <= i__1; ++j) {
00204 /* Computing MAX */
00205             i__2 = j + j * a_dim1;
00206             r__3 = s[j], r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00207                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00208             s[j] = dmax(r__3,r__4);
00209 /* Computing MAX */
00210             i__2 = j + j * a_dim1;
00211             r__3 = *amax, r__4 = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = 
00212                     r_imag(&a[j + j * a_dim1]), dabs(r__2));
00213             *amax = dmax(r__3,r__4);
00214             i__2 = *n;
00215             for (i__ = j + 1; i__ <= i__2; ++i__) {
00216 /* Computing MAX */
00217                 i__3 = i__ + j * a_dim1;
00218                 r__3 = s[i__], 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                 s[i__] = dmax(r__3,r__4);
00221 /* Computing MAX */
00222                 i__3 = i__ + j * a_dim1;
00223                 r__3 = s[j], r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00224                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00225                 s[j] = dmax(r__3,r__4);
00226 /* Computing MAX */
00227                 i__3 = i__ + j * a_dim1;
00228                 r__3 = *amax, r__4 = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = 
00229                         r_imag(&a[i__ + j * a_dim1]), dabs(r__2));
00230                 *amax = dmax(r__3,r__4);
00231             }
00232         }
00233     }
00234     i__1 = *n;
00235     for (j = 1; j <= i__1; ++j) {
00236         s[j] = 1.f / s[j];
00237     }
00238     tol = 1.f / sqrt(*n * 2.f);
00239     for (iter = 1; iter <= 100; ++iter) {
00240         scale = 0.f;
00241         sumsq = 0.f;
00242 /*       beta = |A|s */
00243         i__1 = *n;
00244         for (i__ = 1; i__ <= i__1; ++i__) {
00245             i__2 = i__;
00246             work[i__2].r = 0.f, work[i__2].i = 0.f;
00247         }
00248         if (up) {
00249             i__1 = *n;
00250             for (j = 1; j <= i__1; ++j) {
00251                 i__2 = j - 1;
00252                 for (i__ = 1; i__ <= i__2; ++i__) {
00253                     i__3 = i__ + j * a_dim1;
00254                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00255                             i__ + j * a_dim1]), dabs(r__2));
00256                     i__3 = i__;
00257                     i__4 = i__;
00258                     i__5 = i__ + j * a_dim1;
00259                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00260                             a[i__ + j * a_dim1]), dabs(r__2))) * s[j];
00261                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00262                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00263                     i__3 = j;
00264                     i__4 = j;
00265                     i__5 = i__ + j * a_dim1;
00266                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00267                             a[i__ + j * a_dim1]), dabs(r__2))) * s[i__];
00268                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00269                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00270                 }
00271                 i__2 = j;
00272                 i__3 = j;
00273                 i__4 = j + j * a_dim1;
00274                 r__3 = ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00275                         + j * a_dim1]), dabs(r__2))) * s[j];
00276                 q__1.r = work[i__3].r + r__3, q__1.i = work[i__3].i;
00277                 work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00278             }
00279         } else {
00280             i__1 = *n;
00281             for (j = 1; j <= i__1; ++j) {
00282                 i__2 = j;
00283                 i__3 = j;
00284                 i__4 = j + j * a_dim1;
00285                 r__3 = ((r__1 = a[i__4].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00286                         + j * a_dim1]), dabs(r__2))) * s[j];
00287                 q__1.r = work[i__3].r + r__3, q__1.i = work[i__3].i;
00288                 work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00289                 i__2 = *n;
00290                 for (i__ = j + 1; i__ <= i__2; ++i__) {
00291                     i__3 = i__ + j * a_dim1;
00292                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00293                             i__ + j * a_dim1]), dabs(r__2));
00294                     i__3 = i__;
00295                     i__4 = i__;
00296                     i__5 = i__ + j * a_dim1;
00297                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00298                             a[i__ + j * a_dim1]), dabs(r__2))) * s[j];
00299                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00300                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00301                     i__3 = j;
00302                     i__4 = j;
00303                     i__5 = i__ + j * a_dim1;
00304                     r__3 = ((r__1 = a[i__5].r, dabs(r__1)) + (r__2 = r_imag(&
00305                             a[i__ + j * a_dim1]), dabs(r__2))) * s[i__];
00306                     q__1.r = work[i__4].r + r__3, q__1.i = work[i__4].i;
00307                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00308                 }
00309             }
00310         }
00311 /*       avg = s^T beta / n */
00312         avg = 0.f;
00313         i__1 = *n;
00314         for (i__ = 1; i__ <= i__1; ++i__) {
00315             i__2 = i__;
00316             i__3 = i__;
00317             q__2.r = s[i__2] * work[i__3].r, q__2.i = s[i__2] * work[i__3].i;
00318             q__1.r = avg + q__2.r, q__1.i = q__2.i;
00319             avg = q__1.r;
00320         }
00321         avg /= *n;
00322         std = 0.f;
00323         i__1 = *n << 1;
00324         for (i__ = *n + 1; i__ <= i__1; ++i__) {
00325             i__2 = i__;
00326             i__3 = i__ - *n;
00327             i__4 = i__ - *n;
00328             q__2.r = s[i__3] * work[i__4].r, q__2.i = s[i__3] * work[i__4].i;
00329             q__1.r = q__2.r - avg, q__1.i = q__2.i;
00330             work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00331         }
00332         classq_(n, &work[*n + 1], &c__1, &scale, &sumsq);
00333         std = scale * sqrt(sumsq / *n);
00334         if (std < tol * avg) {
00335             goto L999;
00336         }
00337         i__1 = *n;
00338         for (i__ = 1; i__ <= i__1; ++i__) {
00339             i__2 = i__ + i__ * a_dim1;
00340             t = (r__1 = a[i__2].r, dabs(r__1)) + (r__2 = r_imag(&a[i__ + i__ *
00341                      a_dim1]), dabs(r__2));
00342             si = s[i__];
00343             c2 = (*n - 1) * t;
00344             i__2 = *n - 2;
00345             i__3 = i__;
00346             r__1 = t * si;
00347             q__2.r = work[i__3].r - r__1, q__2.i = work[i__3].i;
00348             d__1 = (doublereal) i__2;
00349             q__1.r = d__1 * q__2.r, q__1.i = d__1 * q__2.i;
00350             c1 = q__1.r;
00351             r__1 = -(t * si) * si;
00352             i__2 = i__;
00353             d__1 = 2.;
00354             q__4.r = d__1 * work[i__2].r, q__4.i = d__1 * work[i__2].i;
00355             q__3.r = si * q__4.r, q__3.i = si * q__4.i;
00356             q__2.r = r__1 + q__3.r, q__2.i = q__3.i;
00357             r__2 = *n * avg;
00358             q__1.r = q__2.r - r__2, q__1.i = q__2.i;
00359             c0 = q__1.r;
00360             d__ = c1 * c1 - c0 * 4 * c2;
00361             if (d__ <= 0.f) {
00362                 *info = -1;
00363                 return 0;
00364             }
00365             si = c0 * -2 / (c1 + sqrt(d__));
00366             d__ = si - s[i__];
00367             u = 0.f;
00368             if (up) {
00369                 i__2 = i__;
00370                 for (j = 1; j <= i__2; ++j) {
00371                     i__3 = j + i__ * a_dim1;
00372                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00373                             + i__ * a_dim1]), dabs(r__2));
00374                     u += s[j] * t;
00375                     i__3 = j;
00376                     i__4 = j;
00377                     r__1 = d__ * t;
00378                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00379                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00380                 }
00381                 i__2 = *n;
00382                 for (j = i__ + 1; j <= i__2; ++j) {
00383                     i__3 = i__ + j * a_dim1;
00384                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00385                             i__ + j * a_dim1]), dabs(r__2));
00386                     u += s[j] * t;
00387                     i__3 = j;
00388                     i__4 = j;
00389                     r__1 = d__ * t;
00390                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00391                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00392                 }
00393             } else {
00394                 i__2 = i__;
00395                 for (j = 1; j <= i__2; ++j) {
00396                     i__3 = i__ + j * a_dim1;
00397                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[
00398                             i__ + j * a_dim1]), dabs(r__2));
00399                     u += s[j] * t;
00400                     i__3 = j;
00401                     i__4 = j;
00402                     r__1 = d__ * t;
00403                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00404                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00405                 }
00406                 i__2 = *n;
00407                 for (j = i__ + 1; j <= i__2; ++j) {
00408                     i__3 = j + i__ * a_dim1;
00409                     t = (r__1 = a[i__3].r, dabs(r__1)) + (r__2 = r_imag(&a[j 
00410                             + i__ * a_dim1]), dabs(r__2));
00411                     u += s[j] * t;
00412                     i__3 = j;
00413                     i__4 = j;
00414                     r__1 = d__ * t;
00415                     q__1.r = work[i__4].r + r__1, q__1.i = work[i__4].i;
00416                     work[i__3].r = q__1.r, work[i__3].i = q__1.i;
00417                 }
00418             }
00419             i__2 = i__;
00420             q__4.r = u + work[i__2].r, q__4.i = work[i__2].i;
00421             q__3.r = d__ * q__4.r, q__3.i = d__ * q__4.i;
00422             d__1 = (doublereal) (*n);
00423             q__2.r = q__3.r / d__1, q__2.i = q__3.i / d__1;
00424             q__1.r = avg + q__2.r, q__1.i = q__2.i;
00425             avg = q__1.r;
00426             s[i__] = si;
00427         }
00428     }
00429 L999:
00430     smlnum = slamch_("SAFEMIN");
00431     bignum = 1.f / smlnum;
00432     smin = bignum;
00433     smax = 0.f;
00434     t = 1.f / sqrt(avg);
00435     base = slamch_("B");
00436     u = 1.f / log(base);
00437     i__1 = *n;
00438     for (i__ = 1; i__ <= i__1; ++i__) {
00439         i__2 = (integer) (u * log(s[i__] * t));
00440         s[i__] = pow_ri(&base, &i__2);
00441 /* Computing MIN */
00442         r__1 = smin, r__2 = s[i__];
00443         smin = dmin(r__1,r__2);
00444 /* Computing MAX */
00445         r__1 = smax, r__2 = s[i__];
00446         smax = dmax(r__1,r__2);
00447     }
00448     *scond = dmax(smin,smlnum) / dmin(smax,bignum);
00449 
00450     return 0;
00451 } /* csyequb_ */


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