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