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 doublereal c_b14 = 1.;
00019 static integer c__1 = 1;
00020 static doublereal c_b34 = 0.;
00021
00022 int dsbevx_(char *jobz, char *range, char *uplo, integer *n,
00023 integer *kd, doublereal *ab, integer *ldab, doublereal *q, integer *
00024 ldq, doublereal *vl, doublereal *vu, integer *il, integer *iu,
00025 doublereal *abstol, integer *m, doublereal *w, doublereal *z__,
00026 integer *ldz, doublereal *work, integer *iwork, integer *ifail,
00027 integer *info)
00028 {
00029
00030 integer ab_dim1, ab_offset, q_dim1, q_offset, z_dim1, z_offset, i__1,
00031 i__2;
00032 doublereal d__1, d__2;
00033
00034
00035 double sqrt(doublereal);
00036
00037
00038 integer i__, j, jj;
00039 doublereal eps, vll, vuu, tmp1;
00040 integer indd, inde;
00041 doublereal anrm;
00042 integer imax;
00043 doublereal rmin, rmax;
00044 logical test;
00045 integer itmp1, indee;
00046 extern int dscal_(integer *, doublereal *, doublereal *,
00047 integer *);
00048 doublereal sigma;
00049 extern logical lsame_(char *, char *);
00050 extern int dgemv_(char *, integer *, integer *,
00051 doublereal *, doublereal *, integer *, doublereal *, integer *,
00052 doublereal *, doublereal *, integer *);
00053 integer iinfo;
00054 char order[1];
00055 extern int dcopy_(integer *, doublereal *, integer *,
00056 doublereal *, integer *), dswap_(integer *, doublereal *, integer
00057 *, doublereal *, integer *);
00058 logical lower, wantz;
00059 extern doublereal dlamch_(char *);
00060 logical alleig, indeig;
00061 integer iscale, indibl;
00062 extern int dlascl_(char *, integer *, integer *,
00063 doublereal *, doublereal *, integer *, integer *, doublereal *,
00064 integer *, integer *);
00065 extern doublereal dlansb_(char *, char *, integer *, integer *,
00066 doublereal *, integer *, doublereal *);
00067 logical valeig;
00068 extern int dlacpy_(char *, integer *, integer *,
00069 doublereal *, integer *, doublereal *, integer *);
00070 doublereal safmin;
00071 extern int xerbla_(char *, integer *);
00072 doublereal abstll, bignum;
00073 extern int dsbtrd_(char *, char *, integer *, integer *,
00074 doublereal *, integer *, doublereal *, doublereal *, doublereal *,
00075 integer *, doublereal *, integer *);
00076 integer indisp;
00077 extern int dstein_(integer *, doublereal *, doublereal *,
00078 integer *, doublereal *, integer *, integer *, doublereal *,
00079 integer *, doublereal *, integer *, integer *, integer *),
00080 dsterf_(integer *, doublereal *, doublereal *, integer *);
00081 integer indiwo;
00082 extern int dstebz_(char *, char *, integer *, doublereal
00083 *, doublereal *, integer *, integer *, doublereal *, doublereal *,
00084 doublereal *, integer *, integer *, doublereal *, integer *,
00085 integer *, doublereal *, integer *, integer *);
00086 integer indwrk;
00087 extern int dsteqr_(char *, integer *, doublereal *,
00088 doublereal *, doublereal *, integer *, doublereal *, integer *);
00089 integer nsplit;
00090 doublereal smlnum;
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
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 ab_dim1 = *ldab;
00256 ab_offset = 1 + ab_dim1;
00257 ab -= ab_offset;
00258 q_dim1 = *ldq;
00259 q_offset = 1 + q_dim1;
00260 q -= q_offset;
00261 --w;
00262 z_dim1 = *ldz;
00263 z_offset = 1 + z_dim1;
00264 z__ -= z_offset;
00265 --work;
00266 --iwork;
00267 --ifail;
00268
00269
00270 wantz = lsame_(jobz, "V");
00271 alleig = lsame_(range, "A");
00272 valeig = lsame_(range, "V");
00273 indeig = lsame_(range, "I");
00274 lower = lsame_(uplo, "L");
00275
00276 *info = 0;
00277 if (! (wantz || lsame_(jobz, "N"))) {
00278 *info = -1;
00279 } else if (! (alleig || valeig || indeig)) {
00280 *info = -2;
00281 } else if (! (lower || lsame_(uplo, "U"))) {
00282 *info = -3;
00283 } else if (*n < 0) {
00284 *info = -4;
00285 } else if (*kd < 0) {
00286 *info = -5;
00287 } else if (*ldab < *kd + 1) {
00288 *info = -7;
00289 } else if (wantz && *ldq < max(1,*n)) {
00290 *info = -9;
00291 } else {
00292 if (valeig) {
00293 if (*n > 0 && *vu <= *vl) {
00294 *info = -11;
00295 }
00296 } else if (indeig) {
00297 if (*il < 1 || *il > max(1,*n)) {
00298 *info = -12;
00299 } else if (*iu < min(*n,*il) || *iu > *n) {
00300 *info = -13;
00301 }
00302 }
00303 }
00304 if (*info == 0) {
00305 if (*ldz < 1 || wantz && *ldz < *n) {
00306 *info = -18;
00307 }
00308 }
00309
00310 if (*info != 0) {
00311 i__1 = -(*info);
00312 xerbla_("DSBEVX", &i__1);
00313 return 0;
00314 }
00315
00316
00317
00318 *m = 0;
00319 if (*n == 0) {
00320 return 0;
00321 }
00322
00323 if (*n == 1) {
00324 *m = 1;
00325 if (lower) {
00326 tmp1 = ab[ab_dim1 + 1];
00327 } else {
00328 tmp1 = ab[*kd + 1 + ab_dim1];
00329 }
00330 if (valeig) {
00331 if (! (*vl < tmp1 && *vu >= tmp1)) {
00332 *m = 0;
00333 }
00334 }
00335 if (*m == 1) {
00336 w[1] = tmp1;
00337 if (wantz) {
00338 z__[z_dim1 + 1] = 1.;
00339 }
00340 }
00341 return 0;
00342 }
00343
00344
00345
00346 safmin = dlamch_("Safe minimum");
00347 eps = dlamch_("Precision");
00348 smlnum = safmin / eps;
00349 bignum = 1. / smlnum;
00350 rmin = sqrt(smlnum);
00351
00352 d__1 = sqrt(bignum), d__2 = 1. / sqrt(sqrt(safmin));
00353 rmax = min(d__1,d__2);
00354
00355
00356
00357 iscale = 0;
00358 abstll = *abstol;
00359 if (valeig) {
00360 vll = *vl;
00361 vuu = *vu;
00362 } else {
00363 vll = 0.;
00364 vuu = 0.;
00365 }
00366 anrm = dlansb_("M", uplo, n, kd, &ab[ab_offset], ldab, &work[1]);
00367 if (anrm > 0. && anrm < rmin) {
00368 iscale = 1;
00369 sigma = rmin / anrm;
00370 } else if (anrm > rmax) {
00371 iscale = 1;
00372 sigma = rmax / anrm;
00373 }
00374 if (iscale == 1) {
00375 if (lower) {
00376 dlascl_("B", kd, kd, &c_b14, &sigma, n, n, &ab[ab_offset], ldab,
00377 info);
00378 } else {
00379 dlascl_("Q", kd, kd, &c_b14, &sigma, n, n, &ab[ab_offset], ldab,
00380 info);
00381 }
00382 if (*abstol > 0.) {
00383 abstll = *abstol * sigma;
00384 }
00385 if (valeig) {
00386 vll = *vl * sigma;
00387 vuu = *vu * sigma;
00388 }
00389 }
00390
00391
00392
00393 indd = 1;
00394 inde = indd + *n;
00395 indwrk = inde + *n;
00396 dsbtrd_(jobz, uplo, n, kd, &ab[ab_offset], ldab, &work[indd], &work[inde],
00397 &q[q_offset], ldq, &work[indwrk], &iinfo);
00398
00399
00400
00401
00402
00403 test = FALSE_;
00404 if (indeig) {
00405 if (*il == 1 && *iu == *n) {
00406 test = TRUE_;
00407 }
00408 }
00409 if ((alleig || test) && *abstol <= 0.) {
00410 dcopy_(n, &work[indd], &c__1, &w[1], &c__1);
00411 indee = indwrk + (*n << 1);
00412 if (! wantz) {
00413 i__1 = *n - 1;
00414 dcopy_(&i__1, &work[inde], &c__1, &work[indee], &c__1);
00415 dsterf_(n, &w[1], &work[indee], info);
00416 } else {
00417 dlacpy_("A", n, n, &q[q_offset], ldq, &z__[z_offset], ldz);
00418 i__1 = *n - 1;
00419 dcopy_(&i__1, &work[inde], &c__1, &work[indee], &c__1);
00420 dsteqr_(jobz, n, &w[1], &work[indee], &z__[z_offset], ldz, &work[
00421 indwrk], info);
00422 if (*info == 0) {
00423 i__1 = *n;
00424 for (i__ = 1; i__ <= i__1; ++i__) {
00425 ifail[i__] = 0;
00426
00427 }
00428 }
00429 }
00430 if (*info == 0) {
00431 *m = *n;
00432 goto L30;
00433 }
00434 *info = 0;
00435 }
00436
00437
00438
00439 if (wantz) {
00440 *(unsigned char *)order = 'B';
00441 } else {
00442 *(unsigned char *)order = 'E';
00443 }
00444 indibl = 1;
00445 indisp = indibl + *n;
00446 indiwo = indisp + *n;
00447 dstebz_(range, order, n, &vll, &vuu, il, iu, &abstll, &work[indd], &work[
00448 inde], m, &nsplit, &w[1], &iwork[indibl], &iwork[indisp], &work[
00449 indwrk], &iwork[indiwo], info);
00450
00451 if (wantz) {
00452 dstein_(n, &work[indd], &work[inde], m, &w[1], &iwork[indibl], &iwork[
00453 indisp], &z__[z_offset], ldz, &work[indwrk], &iwork[indiwo], &
00454 ifail[1], info);
00455
00456
00457
00458
00459 i__1 = *m;
00460 for (j = 1; j <= i__1; ++j) {
00461 dcopy_(n, &z__[j * z_dim1 + 1], &c__1, &work[1], &c__1);
00462 dgemv_("N", n, n, &c_b14, &q[q_offset], ldq, &work[1], &c__1, &
00463 c_b34, &z__[j * z_dim1 + 1], &c__1);
00464
00465 }
00466 }
00467
00468
00469
00470 L30:
00471 if (iscale == 1) {
00472 if (*info == 0) {
00473 imax = *m;
00474 } else {
00475 imax = *info - 1;
00476 }
00477 d__1 = 1. / sigma;
00478 dscal_(&imax, &d__1, &w[1], &c__1);
00479 }
00480
00481
00482
00483
00484 if (wantz) {
00485 i__1 = *m - 1;
00486 for (j = 1; j <= i__1; ++j) {
00487 i__ = 0;
00488 tmp1 = w[j];
00489 i__2 = *m;
00490 for (jj = j + 1; jj <= i__2; ++jj) {
00491 if (w[jj] < tmp1) {
00492 i__ = jj;
00493 tmp1 = w[jj];
00494 }
00495
00496 }
00497
00498 if (i__ != 0) {
00499 itmp1 = iwork[indibl + i__ - 1];
00500 w[i__] = w[j];
00501 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
00502 w[j] = tmp1;
00503 iwork[indibl + j - 1] = itmp1;
00504 dswap_(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
00505 &c__1);
00506 if (*info != 0) {
00507 itmp1 = ifail[i__];
00508 ifail[i__] = ifail[j];
00509 ifail[j] = itmp1;
00510 }
00511 }
00512
00513 }
00514 }
00515
00516 return 0;
00517
00518
00519
00520 }