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