00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
00017
00018 static integer c__1 = 1;
00019
00020 int ssyequb_(char *uplo, integer *n, real *a, integer *lda,
00021 real *s, real *scond, real *amax, real *work, integer *info)
00022 {
00023
00024 integer a_dim1, a_offset, i__1, i__2;
00025 real r__1, r__2, r__3;
00026
00027
00028 double sqrt(doublereal), log(doublereal), pow_ri(real *, integer *);
00029
00030
00031 real d__;
00032 integer i__, j;
00033 real t, u, c0, c1, c2, si;
00034 logical up;
00035 real avg, std, tol, base;
00036 integer iter;
00037 real smin, smax, scale;
00038 extern logical lsame_(char *, char *);
00039 real sumsq;
00040 extern doublereal slamch_(char *);
00041 extern int xerbla_(char *, integer *);
00042 real bignum;
00043 extern int slassq_(integer *, real *, integer *, real *,
00044 real *);
00045 real smlnum;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 a_dim1 = *lda;
00129 a_offset = 1 + a_dim1;
00130 a -= a_offset;
00131 --s;
00132 --work;
00133
00134
00135 *info = 0;
00136 if (! (lsame_(uplo, "U") || lsame_(uplo, "L"))) {
00137 *info = -1;
00138 } else if (*n < 0) {
00139 *info = -2;
00140 } else if (*lda < max(1,*n)) {
00141 *info = -4;
00142 }
00143 if (*info != 0) {
00144 i__1 = -(*info);
00145 xerbla_("SSYEQUB", &i__1);
00146 return 0;
00147 }
00148 up = lsame_(uplo, "U");
00149 *amax = 0.f;
00150
00151
00152
00153 if (*n == 0) {
00154 *scond = 1.f;
00155 return 0;
00156 }
00157 i__1 = *n;
00158 for (i__ = 1; i__ <= i__1; ++i__) {
00159 s[i__] = 0.f;
00160 }
00161 *amax = 0.f;
00162 if (up) {
00163 i__1 = *n;
00164 for (j = 1; j <= i__1; ++j) {
00165 i__2 = j - 1;
00166 for (i__ = 1; i__ <= i__2; ++i__) {
00167
00168 r__2 = s[i__], r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1))
00169 ;
00170 s[i__] = dmax(r__2,r__3);
00171
00172 r__2 = s[j], r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00173 s[j] = dmax(r__2,r__3);
00174
00175 r__2 = *amax, r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00176 *amax = dmax(r__2,r__3);
00177 }
00178
00179 r__2 = s[j], r__3 = (r__1 = a[j + j * a_dim1], dabs(r__1));
00180 s[j] = dmax(r__2,r__3);
00181
00182 r__2 = *amax, r__3 = (r__1 = a[j + j * a_dim1], dabs(r__1));
00183 *amax = dmax(r__2,r__3);
00184 }
00185 } else {
00186 i__1 = *n;
00187 for (j = 1; j <= i__1; ++j) {
00188
00189 r__2 = s[j], r__3 = (r__1 = a[j + j * a_dim1], dabs(r__1));
00190 s[j] = dmax(r__2,r__3);
00191
00192 r__2 = *amax, r__3 = (r__1 = a[j + j * a_dim1], dabs(r__1));
00193 *amax = dmax(r__2,r__3);
00194 i__2 = *n;
00195 for (i__ = j + 1; i__ <= i__2; ++i__) {
00196
00197 r__2 = s[i__], r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1))
00198 ;
00199 s[i__] = dmax(r__2,r__3);
00200
00201 r__2 = s[j], r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00202 s[j] = dmax(r__2,r__3);
00203
00204 r__2 = *amax, r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00205 *amax = dmax(r__2,r__3);
00206 }
00207 }
00208 }
00209 i__1 = *n;
00210 for (j = 1; j <= i__1; ++j) {
00211 s[j] = 1.f / s[j];
00212 }
00213 tol = 1.f / sqrt(*n * 2.f);
00214 for (iter = 1; iter <= 100; ++iter) {
00215 scale = 0.f;
00216 sumsq = 0.f;
00217
00218 i__1 = *n;
00219 for (i__ = 1; i__ <= i__1; ++i__) {
00220 work[i__] = 0.f;
00221 }
00222 if (up) {
00223 i__1 = *n;
00224 for (j = 1; j <= i__1; ++j) {
00225 i__2 = j - 1;
00226 for (i__ = 1; i__ <= i__2; ++i__) {
00227 t = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00228 work[i__] += (r__1 = a[i__ + j * a_dim1], dabs(r__1)) * s[
00229 j];
00230 work[j] += (r__1 = a[i__ + j * a_dim1], dabs(r__1)) * s[
00231 i__];
00232 }
00233 work[j] += (r__1 = a[j + j * a_dim1], dabs(r__1)) * s[j];
00234 }
00235 } else {
00236 i__1 = *n;
00237 for (j = 1; j <= i__1; ++j) {
00238 work[j] += (r__1 = a[j + j * a_dim1], dabs(r__1)) * s[j];
00239 i__2 = *n;
00240 for (i__ = j + 1; i__ <= i__2; ++i__) {
00241 t = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00242 work[i__] += (r__1 = a[i__ + j * a_dim1], dabs(r__1)) * s[
00243 j];
00244 work[j] += (r__1 = a[i__ + j * a_dim1], dabs(r__1)) * s[
00245 i__];
00246 }
00247 }
00248 }
00249
00250 avg = 0.f;
00251 i__1 = *n;
00252 for (i__ = 1; i__ <= i__1; ++i__) {
00253 avg += s[i__] * work[i__];
00254 }
00255 avg /= *n;
00256 std = 0.f;
00257 i__1 = *n * 3;
00258 for (i__ = (*n << 1) + 1; i__ <= i__1; ++i__) {
00259 work[i__] = s[i__ - (*n << 1)] * work[i__ - (*n << 1)] - avg;
00260 }
00261 slassq_(n, &work[(*n << 1) + 1], &c__1, &scale, &sumsq);
00262 std = scale * sqrt(sumsq / *n);
00263 if (std < tol * avg) {
00264 goto L999;
00265 }
00266 i__1 = *n;
00267 for (i__ = 1; i__ <= i__1; ++i__) {
00268 t = (r__1 = a[i__ + i__ * a_dim1], dabs(r__1));
00269 si = s[i__];
00270 c2 = (*n - 1) * t;
00271 c1 = (*n - 2) * (work[i__] - t * si);
00272 c0 = -(t * si) * si + work[i__] * 2 * si - *n * avg;
00273 d__ = c1 * c1 - c0 * 4 * c2;
00274 if (d__ <= 0.f) {
00275 *info = -1;
00276 return 0;
00277 }
00278 si = c0 * -2 / (c1 + sqrt(d__));
00279 d__ = si - s[i__];
00280 u = 0.f;
00281 if (up) {
00282 i__2 = i__;
00283 for (j = 1; j <= i__2; ++j) {
00284 t = (r__1 = a[j + i__ * a_dim1], dabs(r__1));
00285 u += s[j] * t;
00286 work[j] += d__ * t;
00287 }
00288 i__2 = *n;
00289 for (j = i__ + 1; j <= i__2; ++j) {
00290 t = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00291 u += s[j] * t;
00292 work[j] += d__ * t;
00293 }
00294 } else {
00295 i__2 = i__;
00296 for (j = 1; j <= i__2; ++j) {
00297 t = (r__1 = a[i__ + j * a_dim1], dabs(r__1));
00298 u += s[j] * t;
00299 work[j] += d__ * t;
00300 }
00301 i__2 = *n;
00302 for (j = i__ + 1; j <= i__2; ++j) {
00303 t = (r__1 = a[j + i__ * a_dim1], dabs(r__1));
00304 u += s[j] * t;
00305 work[j] += d__ * t;
00306 }
00307 }
00308 avg += (u + work[i__]) * d__ / *n;
00309 s[i__] = si;
00310 }
00311 }
00312 L999:
00313 smlnum = slamch_("SAFEMIN");
00314 bignum = 1.f / smlnum;
00315 smin = bignum;
00316 smax = 0.f;
00317 t = 1.f / sqrt(avg);
00318 base = slamch_("B");
00319 u = 1.f / log(base);
00320 i__1 = *n;
00321 for (i__ = 1; i__ <= i__1; ++i__) {
00322 i__2 = (integer) (u * log(s[i__] * t));
00323 s[i__] = pow_ri(&base, &i__2);
00324
00325 r__1 = smin, r__2 = s[i__];
00326 smin = dmin(r__1,r__2);
00327
00328 r__1 = smax, r__2 = s[i__];
00329 smax = dmax(r__1,r__2);
00330 }
00331 *scond = dmax(smin,smlnum) / dmin(smax,bignum);
00332
00333 return 0;
00334 }