00001
00005
00006
00007
00008
00009
00010 #ifdef __cplusplus
00011 extern "C" {
00012 #endif
00013 #include "lapack/f2c.h"
00014 #include <stdio.h>
00015
00016 #ifdef _DOXYGEN
00017 # define integer long int
00018 # define doublereal double
00019 # define doublecomplex __complex__ double
00020 # define real float
00021 # define complex __complex__ float
00022 #endif
00023
00024
00025
00026 static integer c__9 = 9;
00027 static integer c__1 = 1;
00028 static doublereal c_b14 = 1.;
00029 static doublecomplex c_b26 = {0.,0.};
00030 static doublecomplex c_b27 = {1.,0.};
00031
00170 integer own_ew_(integer *job, integer *up, integer *n, integer *m, doublecomplex *
00171 ab, integer *ldab, doublecomplex *bb, integer *ldbb, doublereal *vl,
00172 doublereal *vu, doublereal *w, doublecomplex *q, integer *ldq,
00173 doublecomplex *work, doublereal *rwork, integer *iwork)
00174 {
00175
00176 integer ab_dim1, ab_offset, bb_dim1, bb_offset, q_dim1, q_offset, ret_val,
00177 i__1;
00178 doublereal d__1, d__2;
00179
00180
00181 double sqrt(doublereal);
00182 integer s_wsle(cilist *), do_lio(integer *, integer *, const char *, ftnlen),
00183 e_wsle();
00184
00185
00186 static integer indd, info;
00187 static doublereal anrm;
00188 static char vect[1], jobz[1];
00189 static doublereal rmin, rmax;
00190 static char uplo[1];
00191 static integer indnd;
00192 static doublereal sigma;
00193 static char order[1];
00194 static logical upper, wantz;
00195 static integer ka, kb, il;
00196 extern doublereal dlamch_(const char *, ftnlen);
00197 static integer iu, iscale, indibl;
00198 static logical valeig;
00199 static doublereal safmin;
00200 extern doublereal zlanhb_(const char *, const char *, integer *, integer *,
00201 doublecomplex *, integer *, doublereal *, ftnlen, ftnlen);
00202 extern int xerbla_(const char *, integer *, ftnlen);
00203 static doublereal abstll, bignum, abstol;
00204 static integer indiwk, indisp;
00205 extern int zlascl_(const char *, integer *, integer *,
00206 doublereal *, doublereal *, integer *, integer *,
00207 doublecomplex *, integer *, integer *, ftnlen),
00208 dstebz_(const char *, const char *, integer *, doublereal *,
00209 doublereal *, integer *, integer *, doublereal *, doublereal *,
00210 doublereal *, integer *, integer *, doublereal *, integer *,
00211 integer *, doublereal *, integer *, integer *, ftnlen, ftnlen),
00212 zhbtrd_(const char *, const char *, integer *, integer *,
00213 doublecomplex *, integer *, doublereal *, doublereal *,
00214 doublecomplex *, integer *, doublecomplex *, integer *, ftnlen,
00215 ftnlen);
00216 static integer indrwk;
00217 extern int zhbgst_(const char *, const char *, integer *,
00218 integer *, integer *, doublecomplex *, integer *,
00219 doublecomplex *, integer *, doublecomplex *, integer *,
00220 doublecomplex *, doublereal *, integer *, ftnlen, ftnlen),
00221 zpbstf_(const char *, integer *, integer *,
00222 doublecomplex *, integer *, integer *, ftnlen);
00223 static integer nsplit;
00224 static doublereal smlnum, eps, vll, vuu;
00225
00226
00227 static cilist io___22 = { 0, 6, 0, 0, 0 };
00228
00229
00230
00231
00232
00233
00234
00235
00236 ab_dim1 = *ldab;
00237 ab_offset = ab_dim1 + 1;
00238 ab -= ab_offset;
00239 bb_dim1 = *ldbb;
00240 bb_offset = bb_dim1 + 1;
00241 bb -= bb_offset;
00242 --w;
00243 q_dim1 = *ldq;
00244 q_offset = q_dim1 + 1;
00245 q -= q_offset;
00246 --work;
00247 --rwork;
00248 --iwork;
00249
00250
00251 wantz = *job == 1;
00252 if (wantz) {
00253 *jobz = 'V';
00254 } else {
00255 *jobz = 'N';
00256 }
00257 upper = *up == 1;
00258 if (upper) {
00259 *uplo = 'U';
00260 } else {
00261 *uplo = 'L';
00262 }
00263 valeig = TRUE_;
00264
00265 ka = *ldab - 1;
00266 kb = *ldbb - 1;
00267
00268 info = 0;
00269 if (*n < 0) {
00270 info = -3;
00271 } else if (ka < 0) {
00272 info = -4;
00273 } else if (kb < 0 || kb > ka) {
00274 info = -5;
00275 } else if (*ldab < ka + 1) {
00276 info = -7;
00277 } else if (*ldbb < kb + 1) {
00278 info = -9;
00279 } else if (*n <= 0) {
00280 info = -110;
00281 }
00282 if (info != 0) {
00283 i__1 = -info;
00284 xerbla_("ZHBGVX", &i__1, 6L);
00285 ret_val = -info;
00286 return ret_val;
00287 }
00288
00289
00290
00291 safmin = dlamch_("Safe minimum", 12L);
00292 eps = dlamch_("Precision", 9L);
00293 smlnum = safmin / eps;
00294 bignum = 1. / smlnum;
00295 rmin = sqrt(smlnum);
00296
00297 d__1 = sqrt(bignum), d__2 = 1. / sqrt(sqrt(safmin));
00298 rmax = min(d__1,d__2);
00299
00300
00301 abstol = safmin * 2.;
00302
00303
00304
00305 iscale = 0;
00306 abstll = abstol;
00307 vll = *vl;
00308 vuu = *vu;
00309 anrm = zlanhb_("M", uplo, n, &ka, &ab[ab_offset], ldab, &rwork[1], 1L, 1L)
00310 ;
00311 if (anrm > 0. && anrm < rmin) {
00312 iscale = 1;
00313 sigma = rmin / anrm;
00314 } else if (anrm > rmax) {
00315 iscale = 1;
00316 sigma = rmax / anrm;
00317 }
00318 if (iscale == 1) {
00319 s_wsle(&io___22);
00320 do_lio(&c__9, &c__1, "Matrix in bad condition, scale matrix ...", 49L);
00321 e_wsle();
00322 if (! upper) {
00323 zlascl_("B", &ka, &ka, &c_b14, &sigma, n, n, &ab[ab_offset], ldab,
00324 &info, 1L);
00325 zlascl_("B", &kb, &kb, &c_b14, &sigma, n, n, &bb[bb_offset], ldbb,
00326 &info, 1L);
00327 } else {
00328 zlascl_("Q", &ka, &ka, &c_b14, &sigma, n, n, &ab[ab_offset], ldab,
00329 &info, 1L);
00330 zlascl_("Q", &kb, &kb, &c_b14, &sigma, n, n, &bb[bb_offset], ldbb,
00331 &info, 1L);
00332 }
00333 if (abstol > 0.) {
00334 abstll = abstol * sigma;
00335 }
00336 vll = *vl * sigma;
00337 vuu = *vu * sigma;
00338 }
00339
00340
00341
00342 zpbstf_(uplo, n, &kb, &bb[bb_offset], ldbb, &info, 1L);
00343
00344
00345 if (info != 0) {
00346 info = *n + info;
00347 return info;
00348 }
00349
00350
00351
00352
00353 indd = 1;
00354 indnd = indd + *n;
00355 indrwk = *n << 1;
00356 zhbgst_(jobz, uplo, n, &ka, &kb, &ab[ab_offset], ldab, &bb[bb_offset],
00357 ldbb, &q[q_offset], ldq, &work[1], &rwork[indrwk], &info, 1L, 1L);
00358
00359
00360 if (info != 0) return info;
00361
00362
00363
00364
00365
00366
00367 if (wantz) {
00368 *vect = 'U';
00369 } else {
00370 *vect = 'N';
00371 }
00372 zhbtrd_(vect, uplo, n, &ka, &ab[ab_offset], ldab, &rwork[indd], &rwork[
00373 indnd], &q[q_offset], ldq, &work[1], &info, 1L, 1L);
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 if (wantz) {
00386 *order = 'B';
00387 } else {
00388 *order = 'E';
00389 }
00390
00391 indibl = 1;
00392 indisp = indibl + *n;
00393 indiwk = indisp + *n;
00394 dstebz_("V", order, n, &vll, &vuu, &il, &iu, &abstll, &rwork[indd], &
00395 rwork[indnd], m, &nsplit, &w[1], &iwork[indibl], &iwork[indisp], &
00396 rwork[indrwk], &iwork[indiwk], &info, 1L, 1L);
00397
00398
00399
00400
00401
00402 ret_val = info;
00403 return ret_val;
00404 }
00405
00406
00452 integer own_ev_(integer *n, integer *m, doublereal *w, doublecomplex *z, integer *
00453 ldz, doublecomplex *q, integer *ldq, doublecomplex *work, doublereal *
00454 rwork, integer *iwork, integer *ifail)
00455 {
00456
00457 integer z_dim1, z_offset, q_dim1, q_offset, ret_val, i__1, i__2;
00458
00459
00460 static integer indd, info, itmp1, i, j, indnd;
00461 extern int zgemv_(const char *, integer *, integer *,
00462 doublecomplex *, doublecomplex *, integer *, doublecomplex *,
00463 integer *, doublecomplex *, doublecomplex *, integer *, ftnlen),
00464 zcopy_(integer *, doublecomplex *, integer *, doublecomplex *,
00465 integer *),
00466 zswap_(integer *, doublecomplex *, integer *, doublecomplex *,
00467 integer *);
00468 static integer jj, indibl, indiwk, indisp, indrwk;
00469 extern int zstein_(integer *, doublereal *, doublereal *,
00470 integer *, doublereal *, integer *, integer *, doublecomplex *,
00471 integer *, doublereal *, integer *, integer *, integer *);
00472 static doublereal tmp1;
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 --w;
00487 z_dim1 = *ldz;
00488 z_offset = z_dim1 + 1;
00489 z -= z_offset;
00490 q_dim1 = *ldq;
00491 q_offset = q_dim1 + 1;
00492 q -= q_offset;
00493 --work;
00494 --rwork;
00495 --iwork;
00496 --ifail;
00497
00498
00499 indd = 1;
00500 indnd = indd + *n;
00501 indrwk = *n << 1;
00502 indibl = 1;
00503 indisp = indibl + *n;
00504 indiwk = indisp + *n;
00505
00506 zstein_(n, &rwork[indd], &rwork[indnd], m, &w[1], &iwork[indibl], &iwork[
00507 indisp], &z[z_offset], ldz, &rwork[indrwk], &iwork[indiwk], &
00508 ifail[1], &info);
00509
00510
00511
00512
00513 i__1 = *m;
00514 for (j = 1; j <= i__1; ++j) {
00515 zcopy_(n, &z[j * z_dim1 + 1], &c__1, &work[1], &c__1);
00516 zgemv_("N", n, n, &c_b27, &q[q_offset], ldq, &work[1], &c__1, &c_b26,
00517 &z[j * z_dim1 + 1], &c__1, 1L);
00518 }
00519
00520
00521
00522
00523 i__1 = *m - 1;
00524 for (j = 1; j <= i__1; ++j) {
00525 i = 0;
00526 tmp1 = w[j];
00527 i__2 = *m;
00528 for (jj = j + 1; jj <= i__2; ++jj) {
00529 if (w[jj] < tmp1) {
00530 i = jj;
00531 tmp1 = w[jj];
00532 }
00533 }
00534
00535 if (i != 0) {
00536 itmp1 = iwork[indibl + i - 1];
00537 w[i] = w[j];
00538 iwork[indibl + i - 1] = iwork[indibl + j - 1];
00539 w[j] = tmp1;
00540 iwork[indibl + j - 1] = itmp1;
00541 zswap_(n, &z[i * z_dim1 + 1], &c__1, &z[j * z_dim1 + 1], &c__1);
00542 if (info != 0) {
00543 itmp1 = ifail[i];
00544 ifail[i] = ifail[j];
00545 ifail[j] = itmp1;
00546 }
00547 }
00548 }
00549
00550
00551
00552 ret_val = info;
00553 return ret_val;
00554 }
00555
00556 #ifdef __cplusplus
00557 }
00558 #endif