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 sspevx_(char *jobz, char *range, char *uplo, integer *n,
00021 real *ap, 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 indd, inde;
00036 real anrm;
00037 integer imax;
00038 real rmin, rmax;
00039 logical test;
00040 integer itmp1, indee;
00041 real sigma;
00042 extern logical lsame_(char *, char *);
00043 integer iinfo;
00044 extern int sscal_(integer *, real *, real *, integer *);
00045 char order[1];
00046 extern int scopy_(integer *, real *, integer *, real *,
00047 integer *), sswap_(integer *, real *, integer *, real *, integer *
00048 );
00049 logical wantz, alleig, indeig;
00050 integer iscale, indibl;
00051 logical valeig;
00052 extern doublereal slamch_(char *);
00053 real safmin;
00054 extern int xerbla_(char *, integer *);
00055 real abstll, bignum;
00056 integer indtau, indisp, indiwo, indwrk;
00057 extern doublereal slansp_(char *, char *, integer *, real *, real *);
00058 extern int sstein_(integer *, real *, real *, integer *,
00059 real *, integer *, integer *, real *, integer *, real *, integer *
00060 , integer *, integer *), ssterf_(integer *, real *, real *,
00061 integer *);
00062 integer nsplit;
00063 extern int sstebz_(char *, char *, integer *, real *,
00064 real *, integer *, integer *, real *, real *, real *, integer *,
00065 integer *, real *, integer *, integer *, real *, integer *,
00066 integer *);
00067 real smlnum;
00068 extern int sopgtr_(char *, integer *, real *, real *,
00069 real *, integer *, real *, integer *), ssptrd_(char *,
00070 integer *, real *, real *, real *, real *, integer *),
00071 ssteqr_(char *, integer *, real *, real *, real *, integer *,
00072 real *, integer *), sopmtr_(char *, char *, char *,
00073 integer *, integer *, real *, real *, real *, integer *, real *,
00074 integer *);
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
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 --ap;
00222 --w;
00223 z_dim1 = *ldz;
00224 z_offset = 1 + z_dim1;
00225 z__ -= z_offset;
00226 --work;
00227 --iwork;
00228 --ifail;
00229
00230
00231 wantz = lsame_(jobz, "V");
00232 alleig = lsame_(range, "A");
00233 valeig = lsame_(range, "V");
00234 indeig = lsame_(range, "I");
00235
00236 *info = 0;
00237 if (! (wantz || lsame_(jobz, "N"))) {
00238 *info = -1;
00239 } else if (! (alleig || valeig || indeig)) {
00240 *info = -2;
00241 } else if (! (lsame_(uplo, "L") || lsame_(uplo,
00242 "U"))) {
00243 *info = -3;
00244 } else if (*n < 0) {
00245 *info = -4;
00246 } else {
00247 if (valeig) {
00248 if (*n > 0 && *vu <= *vl) {
00249 *info = -7;
00250 }
00251 } else if (indeig) {
00252 if (*il < 1 || *il > max(1,*n)) {
00253 *info = -8;
00254 } else if (*iu < min(*n,*il) || *iu > *n) {
00255 *info = -9;
00256 }
00257 }
00258 }
00259 if (*info == 0) {
00260 if (*ldz < 1 || wantz && *ldz < *n) {
00261 *info = -14;
00262 }
00263 }
00264
00265 if (*info != 0) {
00266 i__1 = -(*info);
00267 xerbla_("SSPEVX", &i__1);
00268 return 0;
00269 }
00270
00271
00272
00273 *m = 0;
00274 if (*n == 0) {
00275 return 0;
00276 }
00277
00278 if (*n == 1) {
00279 if (alleig || indeig) {
00280 *m = 1;
00281 w[1] = ap[1];
00282 } else {
00283 if (*vl < ap[1] && *vu >= ap[1]) {
00284 *m = 1;
00285 w[1] = ap[1];
00286 }
00287 }
00288 if (wantz) {
00289 z__[z_dim1 + 1] = 1.f;
00290 }
00291 return 0;
00292 }
00293
00294
00295
00296 safmin = slamch_("Safe minimum");
00297 eps = slamch_("Precision");
00298 smlnum = safmin / eps;
00299 bignum = 1.f / smlnum;
00300 rmin = sqrt(smlnum);
00301
00302 r__1 = sqrt(bignum), r__2 = 1.f / sqrt(sqrt(safmin));
00303 rmax = dmin(r__1,r__2);
00304
00305
00306
00307 iscale = 0;
00308 abstll = *abstol;
00309 if (valeig) {
00310 vll = *vl;
00311 vuu = *vu;
00312 } else {
00313 vll = 0.f;
00314 vuu = 0.f;
00315 }
00316 anrm = slansp_("M", uplo, n, &ap[1], &work[1]);
00317 if (anrm > 0.f && anrm < rmin) {
00318 iscale = 1;
00319 sigma = rmin / anrm;
00320 } else if (anrm > rmax) {
00321 iscale = 1;
00322 sigma = rmax / anrm;
00323 }
00324 if (iscale == 1) {
00325 i__1 = *n * (*n + 1) / 2;
00326 sscal_(&i__1, &sigma, &ap[1], &c__1);
00327 if (*abstol > 0.f) {
00328 abstll = *abstol * sigma;
00329 }
00330 if (valeig) {
00331 vll = *vl * sigma;
00332 vuu = *vu * sigma;
00333 }
00334 }
00335
00336
00337
00338 indtau = 1;
00339 inde = indtau + *n;
00340 indd = inde + *n;
00341 indwrk = indd + *n;
00342 ssptrd_(uplo, n, &ap[1], &work[indd], &work[inde], &work[indtau], &iinfo);
00343
00344
00345
00346
00347
00348 test = FALSE_;
00349 if (indeig) {
00350 if (*il == 1 && *iu == *n) {
00351 test = TRUE_;
00352 }
00353 }
00354 if ((alleig || test) && *abstol <= 0.f) {
00355 scopy_(n, &work[indd], &c__1, &w[1], &c__1);
00356 indee = indwrk + (*n << 1);
00357 if (! wantz) {
00358 i__1 = *n - 1;
00359 scopy_(&i__1, &work[inde], &c__1, &work[indee], &c__1);
00360 ssterf_(n, &w[1], &work[indee], info);
00361 } else {
00362 sopgtr_(uplo, n, &ap[1], &work[indtau], &z__[z_offset], ldz, &
00363 work[indwrk], &iinfo);
00364 i__1 = *n - 1;
00365 scopy_(&i__1, &work[inde], &c__1, &work[indee], &c__1);
00366 ssteqr_(jobz, n, &w[1], &work[indee], &z__[z_offset], ldz, &work[
00367 indwrk], info);
00368 if (*info == 0) {
00369 i__1 = *n;
00370 for (i__ = 1; i__ <= i__1; ++i__) {
00371 ifail[i__] = 0;
00372
00373 }
00374 }
00375 }
00376 if (*info == 0) {
00377 *m = *n;
00378 goto L20;
00379 }
00380 *info = 0;
00381 }
00382
00383
00384
00385 if (wantz) {
00386 *(unsigned char *)order = 'B';
00387 } else {
00388 *(unsigned char *)order = 'E';
00389 }
00390 indibl = 1;
00391 indisp = indibl + *n;
00392 indiwo = indisp + *n;
00393 sstebz_(range, order, n, &vll, &vuu, il, iu, &abstll, &work[indd], &work[
00394 inde], m, &nsplit, &w[1], &iwork[indibl], &iwork[indisp], &work[
00395 indwrk], &iwork[indiwo], info);
00396
00397 if (wantz) {
00398 sstein_(n, &work[indd], &work[inde], m, &w[1], &iwork[indibl], &iwork[
00399 indisp], &z__[z_offset], ldz, &work[indwrk], &iwork[indiwo], &
00400 ifail[1], info);
00401
00402
00403
00404
00405 sopmtr_("L", uplo, "N", n, m, &ap[1], &work[indtau], &z__[z_offset],
00406 ldz, &work[indwrk], &iinfo);
00407 }
00408
00409
00410
00411 L20:
00412 if (iscale == 1) {
00413 if (*info == 0) {
00414 imax = *m;
00415 } else {
00416 imax = *info - 1;
00417 }
00418 r__1 = 1.f / sigma;
00419 sscal_(&imax, &r__1, &w[1], &c__1);
00420 }
00421
00422
00423
00424
00425 if (wantz) {
00426 i__1 = *m - 1;
00427 for (j = 1; j <= i__1; ++j) {
00428 i__ = 0;
00429 tmp1 = w[j];
00430 i__2 = *m;
00431 for (jj = j + 1; jj <= i__2; ++jj) {
00432 if (w[jj] < tmp1) {
00433 i__ = jj;
00434 tmp1 = w[jj];
00435 }
00436
00437 }
00438
00439 if (i__ != 0) {
00440 itmp1 = iwork[indibl + i__ - 1];
00441 w[i__] = w[j];
00442 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
00443 w[j] = tmp1;
00444 iwork[indibl + j - 1] = itmp1;
00445 sswap_(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
00446 &c__1);
00447 if (*info != 0) {
00448 itmp1 = ifail[i__];
00449 ifail[i__] = ifail[j];
00450 ifail[j] = itmp1;
00451 }
00452 }
00453
00454 }
00455 }
00456
00457 return 0;
00458
00459
00460
00461 }