📄 dstebz.c
字号:
#include <math.h>#include "gmx_lapack.h"#include "lapack_limits.h"#include <types/simple.h>voidF77_FUNC(dstebz,DSTEBZ)(char *range, char *order, int *n, double *vl, double *vu, int *il, int *iu, double *abstol, double *d__, double *e, int *m, int *nsplit, double *w, int *iblock, int *isplit, double *work, int *iwork, int *info){ int i__1, i__2, i__3; double d__1, d__2, d__3, d__4, d__5; int c__1 = 1; int c__3 = 3; int c__2 = 2; int c__0 = 0; int j, ib, jb, ie, je, nb; double gl; int im, in; double gu; int iw; double wl, wu; int nwl; double ulp, wlu, wul; int nwu; double tmp1, tmp2; int iend, ioff, iout, itmp1, jdisc; int iinfo; double atoli; int iwoff; double bnorm; int itmax; double wkill, rtoli, tnorm; int ibegin; int irange, idiscl; int idumma[1]; int idiscu, iorder; int ncnvrg; double pivmin; int toofew; const double safemn = GMX_DOUBLE_MIN*(1.0+GMX_DOUBLE_EPS); --iwork; --work; --isplit; --iblock; --w; --e; --d__; *info = 0; if (*range=='A' || *range=='a') { irange = 1; } else if (*range=='V' || *range=='v') { irange = 2; } else if (*range=='I' || *range=='i') { irange = 3; } else { irange = 0; } if (*order=='B' || *order=='b') { iorder = 2; } else if (*order=='E' || *order=='e') { iorder = 1; } else { iorder = 0; } if (irange <= 0) { *info = -1; } else if (iorder <= 0) { *info = -2; } else if (*n < 0) { *info = -3; } else if (irange == 2) { if (*vl >= *vu) { *info = -5; } } else if (irange == 3 && (*il < 1 || *il > (*n))) { *info = -6; } else if (irange == 3 && (*iu < ((*n<*il) ? *n : *il) || *iu > *n)) { *info = -7; } if (*info != 0) { i__1 = -(*info); return; } *info = 0; ncnvrg = 0; toofew = 0; *m = 0; if (*n == 0) { return; } if (irange == 3 && *il == 1 && *iu == *n) { irange = 1; } ulp = 2*GMX_DOUBLE_EPS; rtoli = ulp * 2.; nb = DSTEBZ_BLOCKSIZE; if (nb <= 1) { nb = 0; } if (*n == 1) { *nsplit = 1; isplit[1] = 1; if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) { *m = 0; } else { w[1] = d__[1]; iblock[1] = 1; *m = 1; } return; } *nsplit = 1; work[*n] = 0.; pivmin = 1.; i__1 = *n; for (j = 2; j <= i__1; ++j) { d__1 = e[j - 1]; tmp1 = d__1 * d__1; d__2 = ulp; if (fabs(d__[j] * d__[j - 1]) * (d__2 * d__2) + safemn > tmp1) { isplit[*nsplit] = j - 1; ++(*nsplit); work[j - 1] = 0.; } else { work[j - 1] = tmp1; pivmin = (pivmin>tmp1) ? pivmin : tmp1; } } isplit[*nsplit] = *n; pivmin *= safemn; if (irange == 3) { gu = d__[1]; gl = d__[1]; tmp1 = 0.; i__1 = *n - 1; for (j = 1; j <= i__1; ++j) { tmp2 = sqrt(work[j]); d__1 = gu, d__2 = d__[j] + tmp1 + tmp2; gu = (d__1>d__2) ? d__1 : d__2; d__1 = gl, d__2 = d__[j] - tmp1 - tmp2; gl = (d__1<d__2) ? d__1 : d__2; tmp1 = tmp2; } d__1 = gu, d__2 = d__[*n] + tmp1; gu = (d__1>d__2) ? d__1 : d__2; d__1 = gl, d__2 = d__[*n] - tmp1; gl = (d__1<d__2) ? d__1 : d__2; d__1 = fabs(gl); d__2 = fabs(gu); tnorm = (d__1>d__2) ? d__1 : d__2; gl = gl - tnorm * 2. * ulp * *n - pivmin * 4.; gu = gu + tnorm * 2. * ulp * *n + pivmin * 2.; itmax = (int) ((log(tnorm + pivmin) - log(pivmin)) / log(2.)) + 2; if (*abstol <= 0.) { atoli = ulp * tnorm; } else { atoli = *abstol; } work[*n + 1] = gl; work[*n + 2] = gl; work[*n + 3] = gu; work[*n + 4] = gu; work[*n + 5] = gl; work[*n + 6] = gu; iwork[1] = -1; iwork[2] = -1; iwork[3] = *n + 1; iwork[4] = *n + 1; iwork[5] = *il - 1; iwork[6] = *iu; F77_FUNC(dlaebz,DLAEBZ)(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin, &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo); if (iwork[6] == *iu) { wl = work[*n + 1]; wlu = work[*n + 3]; nwl = iwork[1]; wu = work[*n + 4]; wul = work[*n + 2]; nwu = iwork[4]; } else { wl = work[*n + 2]; wlu = work[*n + 4]; nwl = iwork[2]; wu = work[*n + 3]; wul = work[*n + 1]; nwu = iwork[3]; } if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) { *info = 4; return; } } else { /* avoid warnings for high gcc optimization */ wlu = wul = 1.0; d__3 = fabs(d__[1]) + fabs(e[1]); d__4 = fabs(d__[*n]) + fabs(e[*n - 1]); tnorm = (d__3>d__4) ? d__3 : d__4; i__1 = *n - 1; for (j = 2; j <= i__1; ++j) { d__4 = tnorm; d__5 = fabs(d__[j]) + fabs(e[j - 1]) + fabs(e[j]); tnorm = (d__4>d__5) ? d__4 : d__5; } if (*abstol <= 0.) { atoli = ulp * tnorm; } else { atoli = *abstol; } if (irange == 2) { wl = *vl; wu = *vu; } else { wl = 0.; wu = 0.; } } *m = 0; iend = 0; *info = 0; nwl = 0; nwu = 0; i__1 = *nsplit; for (jb = 1; jb <= i__1; ++jb) { ioff = iend; ibegin = ioff + 1; iend = isplit[jb]; in = iend - ioff; if (in == 1) { if (irange == 1 || wl >= d__[ibegin] - pivmin) { ++nwl; } if (irange == 1 || wu >= d__[ibegin] - pivmin) { ++nwu; } if (irange == 1 || ((wl < d__[ibegin] - pivmin) && (wu >= d__[ibegin] - pivmin))) { ++(*m); w[*m] = d__[ibegin]; iblock[*m] = jb; } } else { gu = d__[ibegin]; gl = d__[ibegin]; tmp1 = 0.; i__2 = iend - 1; for (j = ibegin; j <= i__2; ++j) { tmp2 = fabs(e[j]); d__1 = gu, d__2 = d__[j] + tmp1 + tmp2; gu = (d__1>d__2) ? d__1 : d__2; d__1 = gl, d__2 = d__[j] - tmp1 - tmp2; gl = (d__1<d__2) ? d__1 : d__2; tmp1 = tmp2; } d__1 = gu, d__2 = d__[iend] + tmp1; gu = (d__1>d__2) ? d__1 : d__2; d__1 = gl, d__2 = d__[iend] - tmp1; gl = (d__1<d__2) ? d__1 : d__2; d__1 = fabs(gl); d__2 = fabs(gu); bnorm = (d__1>d__2) ? d__1 : d__2; gl = gl - bnorm * 2. * ulp * in - pivmin * 2.; gu = gu + bnorm * 2. * ulp * in + pivmin * 2.; if (*abstol <= 0.) { d__1 = fabs(gl); d__2 = fabs(gu); atoli = ulp * ((d__1>d__2) ? d__1 : d__2); } else { atoli = *abstol; } if (irange > 1) { if (gu < wl) { nwl += in; nwu += in; } gl = (gl>wl) ? gl : wl; gu = (gu<wu) ? gu : wu; if (gl >= gu) { } continue; } work[*n + 1] = gl; work[*n + in + 1] = gu; F77_FUNC(dlaebz,DLAEBZ)(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, & pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, & work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], & w[*m + 1], &iblock[*m + 1], &iinfo); nwl += iwork[1]; nwu += iwork[in + 1]; iwoff = *m - iwork[1]; itmax = (int) ((log(gu - gl + pivmin) - log(pivmin)) / log(2.) ) + 2; F77_FUNC(dlaebz,DLAEBZ)(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, & pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, & work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1], &w[*m + 1], &iblock[*m + 1], &iinfo); i__2 = iout; for (j = 1; j <= i__2; ++j) { tmp1 = (work[j + *n] + work[j + in + *n]) * .5; if (j > iout - iinfo) { ncnvrg = 1; ib = -jb; } else { ib = jb; } i__3 = iwork[j + in] + iwoff; for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) { w[je] = tmp1; iblock[je] = ib; } } *m += im; } } if (irange == 3) { im = 0; idiscl = *il - 1 - nwl; idiscu = nwu - *iu; if (idiscl > 0 || idiscu > 0) { i__1 = *m; for (je = 1; je <= i__1; ++je) { if (w[je] <= wlu && idiscl > 0) { --idiscl; } else if (w[je] >= wul && idiscu > 0) { --idiscu; } else { ++im; w[im] = w[je]; iblock[im] = iblock[je]; } } *m = im; } if (idiscl > 0 || idiscu > 0) { if (idiscl > 0) { wkill = wu; i__1 = idiscl; for (jdisc = 1; jdisc <= i__1; ++jdisc) { iw = 0; i__2 = *m; for (je = 1; je <= i__2; ++je) { if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) { iw = je; wkill = w[je]; } } iblock[iw] = 0; } } if (idiscu > 0) { wkill = wl; i__1 = idiscu; for (jdisc = 1; jdisc <= i__1; ++jdisc) { iw = 0; i__2 = *m; for (je = 1; je <= i__2; ++je) { if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) { iw = je; wkill = w[je]; } } iblock[iw] = 0; } } im = 0; i__1 = *m; for (je = 1; je <= i__1; ++je) { if (iblock[je] != 0) { ++im; w[im] = w[je]; iblock[im] = iblock[je]; } } *m = im; } if (idiscl < 0 || idiscu < 0) { toofew = 1; } } if (iorder == 1 && *nsplit > 1) { i__1 = *m - 1; for (je = 1; je <= i__1; ++je) { ie = 0; tmp1 = w[je]; i__2 = *m; for (j = je + 1; j <= i__2; ++j) { if (w[j] < tmp1) { ie = j; tmp1 = w[j]; } } if (ie != 0) { itmp1 = iblock[ie]; w[ie] = w[je]; iblock[ie] = iblock[je]; w[je] = tmp1; iblock[je] = itmp1; } } } *info = 0; if (ncnvrg) { ++(*info); } if (toofew) { *info += 2; } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -