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 sstevx_(char *jobz, char *range, integer *n, real *d__,
00021 real *e, real *vl, real *vu, integer *il, integer *iu, real *abstol,
00022 integer *m, real *w, real *z__, integer *ldz, real *work, integer *
00023 iwork, integer *ifail, integer *info)
00024 {
00025
00026 integer z_dim1, z_offset, i__1, i__2;
00027 real r__1, r__2;
00028
00029
00030 double sqrt(doublereal);
00031
00032
00033 integer i__, j, jj;
00034 real eps, vll, vuu, tmp1;
00035 integer imax;
00036 real rmin, rmax;
00037 logical test;
00038 real tnrm;
00039 integer itmp1;
00040 real sigma;
00041 extern logical lsame_(char *, char *);
00042 extern int sscal_(integer *, real *, real *, integer *);
00043 char order[1];
00044 extern int scopy_(integer *, real *, integer *, real *,
00045 integer *), sswap_(integer *, real *, integer *, real *, integer *
00046 );
00047 logical wantz, alleig, indeig;
00048 integer iscale, indibl;
00049 logical valeig;
00050 extern doublereal slamch_(char *);
00051 real safmin;
00052 extern int xerbla_(char *, integer *);
00053 real bignum;
00054 integer indisp, indiwo, indwrk;
00055 extern doublereal slanst_(char *, integer *, real *, real *);
00056 extern int sstein_(integer *, real *, real *, integer *,
00057 real *, integer *, integer *, real *, integer *, real *, integer *
00058 , integer *, integer *), ssterf_(integer *, real *, real *,
00059 integer *);
00060 integer nsplit;
00061 extern int sstebz_(char *, char *, integer *, real *,
00062 real *, integer *, integer *, real *, real *, real *, integer *,
00063 integer *, real *, integer *, integer *, real *, integer *,
00064 integer *);
00065 real smlnum;
00066 extern int ssteqr_(char *, integer *, real *, real *,
00067 real *, integer *, real *, integer *);
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
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 --d__;
00210 --e;
00211 --w;
00212 z_dim1 = *ldz;
00213 z_offset = 1 + z_dim1;
00214 z__ -= z_offset;
00215 --work;
00216 --iwork;
00217 --ifail;
00218
00219
00220 wantz = lsame_(jobz, "V");
00221 alleig = lsame_(range, "A");
00222 valeig = lsame_(range, "V");
00223 indeig = lsame_(range, "I");
00224
00225 *info = 0;
00226 if (! (wantz || lsame_(jobz, "N"))) {
00227 *info = -1;
00228 } else if (! (alleig || valeig || indeig)) {
00229 *info = -2;
00230 } else if (*n < 0) {
00231 *info = -3;
00232 } else {
00233 if (valeig) {
00234 if (*n > 0 && *vu <= *vl) {
00235 *info = -7;
00236 }
00237 } else if (indeig) {
00238 if (*il < 1 || *il > max(1,*n)) {
00239 *info = -8;
00240 } else if (*iu < min(*n,*il) || *iu > *n) {
00241 *info = -9;
00242 }
00243 }
00244 }
00245 if (*info == 0) {
00246 if (*ldz < 1 || wantz && *ldz < *n) {
00247 *info = -14;
00248 }
00249 }
00250
00251 if (*info != 0) {
00252 i__1 = -(*info);
00253 xerbla_("SSTEVX", &i__1);
00254 return 0;
00255 }
00256
00257
00258
00259 *m = 0;
00260 if (*n == 0) {
00261 return 0;
00262 }
00263
00264 if (*n == 1) {
00265 if (alleig || indeig) {
00266 *m = 1;
00267 w[1] = d__[1];
00268 } else {
00269 if (*vl < d__[1] && *vu >= d__[1]) {
00270 *m = 1;
00271 w[1] = d__[1];
00272 }
00273 }
00274 if (wantz) {
00275 z__[z_dim1 + 1] = 1.f;
00276 }
00277 return 0;
00278 }
00279
00280
00281
00282 safmin = slamch_("Safe minimum");
00283 eps = slamch_("Precision");
00284 smlnum = safmin / eps;
00285 bignum = 1.f / smlnum;
00286 rmin = sqrt(smlnum);
00287
00288 r__1 = sqrt(bignum), r__2 = 1.f / sqrt(sqrt(safmin));
00289 rmax = dmin(r__1,r__2);
00290
00291
00292
00293 iscale = 0;
00294 if (valeig) {
00295 vll = *vl;
00296 vuu = *vu;
00297 } else {
00298 vll = 0.f;
00299 vuu = 0.f;
00300 }
00301 tnrm = slanst_("M", n, &d__[1], &e[1]);
00302 if (tnrm > 0.f && tnrm < rmin) {
00303 iscale = 1;
00304 sigma = rmin / tnrm;
00305 } else if (tnrm > rmax) {
00306 iscale = 1;
00307 sigma = rmax / tnrm;
00308 }
00309 if (iscale == 1) {
00310 sscal_(n, &sigma, &d__[1], &c__1);
00311 i__1 = *n - 1;
00312 sscal_(&i__1, &sigma, &e[1], &c__1);
00313 if (valeig) {
00314 vll = *vl * sigma;
00315 vuu = *vu * sigma;
00316 }
00317 }
00318
00319
00320
00321
00322
00323 test = FALSE_;
00324 if (indeig) {
00325 if (*il == 1 && *iu == *n) {
00326 test = TRUE_;
00327 }
00328 }
00329 if ((alleig || test) && *abstol <= 0.f) {
00330 scopy_(n, &d__[1], &c__1, &w[1], &c__1);
00331 i__1 = *n - 1;
00332 scopy_(&i__1, &e[1], &c__1, &work[1], &c__1);
00333 indwrk = *n + 1;
00334 if (! wantz) {
00335 ssterf_(n, &w[1], &work[1], info);
00336 } else {
00337 ssteqr_("I", n, &w[1], &work[1], &z__[z_offset], ldz, &work[
00338 indwrk], info);
00339 if (*info == 0) {
00340 i__1 = *n;
00341 for (i__ = 1; i__ <= i__1; ++i__) {
00342 ifail[i__] = 0;
00343
00344 }
00345 }
00346 }
00347 if (*info == 0) {
00348 *m = *n;
00349 goto L20;
00350 }
00351 *info = 0;
00352 }
00353
00354
00355
00356 if (wantz) {
00357 *(unsigned char *)order = 'B';
00358 } else {
00359 *(unsigned char *)order = 'E';
00360 }
00361 indwrk = 1;
00362 indibl = 1;
00363 indisp = indibl + *n;
00364 indiwo = indisp + *n;
00365 sstebz_(range, order, n, &vll, &vuu, il, iu, abstol, &d__[1], &e[1], m, &
00366 nsplit, &w[1], &iwork[indibl], &iwork[indisp], &work[indwrk], &
00367 iwork[indiwo], info);
00368
00369 if (wantz) {
00370 sstein_(n, &d__[1], &e[1], m, &w[1], &iwork[indibl], &iwork[indisp], &
00371 z__[z_offset], ldz, &work[indwrk], &iwork[indiwo], &ifail[1],
00372 info);
00373 }
00374
00375
00376
00377 L20:
00378 if (iscale == 1) {
00379 if (*info == 0) {
00380 imax = *m;
00381 } else {
00382 imax = *info - 1;
00383 }
00384 r__1 = 1.f / sigma;
00385 sscal_(&imax, &r__1, &w[1], &c__1);
00386 }
00387
00388
00389
00390
00391 if (wantz) {
00392 i__1 = *m - 1;
00393 for (j = 1; j <= i__1; ++j) {
00394 i__ = 0;
00395 tmp1 = w[j];
00396 i__2 = *m;
00397 for (jj = j + 1; jj <= i__2; ++jj) {
00398 if (w[jj] < tmp1) {
00399 i__ = jj;
00400 tmp1 = w[jj];
00401 }
00402
00403 }
00404
00405 if (i__ != 0) {
00406 itmp1 = iwork[indibl + i__ - 1];
00407 w[i__] = w[j];
00408 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
00409 w[j] = tmp1;
00410 iwork[indibl + j - 1] = itmp1;
00411 sswap_(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
00412 &c__1);
00413 if (*info != 0) {
00414 itmp1 = ifail[i__];
00415 ifail[i__] = ifail[j];
00416 ifail[j] = itmp1;
00417 }
00418 }
00419
00420 }
00421 }
00422
00423 return 0;
00424
00425
00426
00427 }