sstebz.c
来自「NIST Handwriting OCR Testbed」· C语言 代码 · 共 766 行 · 第 1/2 页
C
766 行
i__1 = *n - 1; for (j = 1; j <= *n-1; ++j) { tmp2 = sqrt(WORK(j));/* Computing MAX */ r__1 = gu, r__2 = D(j) + tmp1 + tmp2; gu = dmax(r__1,r__2);/* Computing MIN */ r__1 = gl, r__2 = D(j) - tmp1 - tmp2; gl = dmin(r__1,r__2); tmp1 = tmp2;/* L20: */ }/* Computing MAX */ r__1 = gu, r__2 = D(*n) + tmp1; gu = dmax(r__1,r__2);/* Computing MIN */ r__1 = gl, r__2 = D(*n) - tmp1; gl = dmin(r__1,r__2);/* Computing MAX */ r__1 = dabs(gl), r__2 = dabs(gu); tnorm = dmax(r__1,r__2); gl = gl - tnorm * 2.f * ulp * *n - pivmin * 4.f; gu = gu + tnorm * 2.f * ulp * *n + pivmin * 2.f;/* Compute Iteration parameters */ itmax = (integer) ((log(tnorm + pivmin) - log(pivmin)) / log(2.f)) + 2; if (*abstol <= 0.f) { 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; slaebz_(&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 0; } } else {/* RANGE='A' or 'V' -- Set ATOLI Computing MAX */ r__3 = dabs(D(1)) + dabs(E(1)), r__4 = (r__1 = D(*n), dabs(r__1)) + ( r__2 = E(*n - 1), dabs(r__2)); tnorm = dmax(r__3,r__4); i__1 = *n - 1; for (j = 2; j <= *n-1; ++j) {/* Computing MAX */ r__4 = tnorm, r__5 = (r__1 = D(j), dabs(r__1)) + (r__2 = E(j - 1), dabs(r__2)) + (r__3 = E(j), dabs(r__3)); tnorm = dmax(r__4,r__5);/* L30: */ } if (*abstol <= 0.f) { atoli = ulp * tnorm; } else { atoli = *abstol; } if (irange == 2) { wl = *vl; wu = *vu; } }/* Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU. NWL accumulates the number of eigenvalues .le. WL, NWU accumulates the number of eigenvalues .le. WU */ *m = 0; iend = 0; *info = 0; nwl = 0; nwu = 0; i__1 = *nsplit; for (jb = 1; jb <= *nsplit; ++jb) { ioff = iend; ibegin = ioff + 1; iend = ISPLIT(jb); in = iend - ioff; if (in == 1) {/* Special Case -- 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 {/* General Case -- IN > 1 Compute Gershgorin Interval and use it as the initial interval */ gu = D(ibegin); gl = D(ibegin); tmp1 = 0.f; i__2 = iend - 1; for (j = ibegin; j <= iend-1; ++j) { tmp2 = (r__1 = E(j), dabs(r__1));/* Computing MAX */ r__1 = gu, r__2 = D(j) + tmp1 + tmp2; gu = dmax(r__1,r__2);/* Computing MIN */ r__1 = gl, r__2 = D(j) - tmp1 - tmp2; gl = dmin(r__1,r__2); tmp1 = tmp2;/* L40: */ }/* Computing MAX */ r__1 = gu, r__2 = D(iend) + tmp1; gu = dmax(r__1,r__2);/* Computing MIN */ r__1 = gl, r__2 = D(iend) - tmp1; gl = dmin(r__1,r__2);/* Computing MAX */ r__1 = dabs(gl), r__2 = dabs(gu); bnorm = dmax(r__1,r__2); gl = gl - bnorm * 2.f * ulp * in - pivmin * 2.f; gu = gu + bnorm * 2.f * ulp * in + pivmin * 2.f;/* Compute ATOLI for the current submatrix */ if (*abstol <= 0.f) {/* Computing MAX */ r__1 = dabs(gl), r__2 = dabs(gu); atoli = ulp * dmax(r__1,r__2); } else { atoli = *abstol; } if (irange > 1) { if (gu < wl) { nwl += in; nwu += in; goto L70; } gl = dmax(gl,wl); gu = dmin(gu,wu); if (gl >= gu) { goto L70; } }/* Set Up Initial Interval */ WORK(*n + 1) = gl; WORK(*n + in + 1) = gu; slaebz_(&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);/* Compute Eigenvalues */ itmax = (integer) ((log(gu - gl + pivmin) - log(pivmin)) / log( 2.f)) + 2; slaebz_(&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);/* Copy Eigenvalues Into W and IBLOCK Use -JB for block number for unconverged eigenvalues. */ i__2 = iout; for (j = 1; j <= iout; ++j) { tmp1 = (WORK(j + *n) + WORK(j + in + *n)) * .5f;/* Flag non-convergence. */ if (j > iout - iinfo) { ncnvrg = TRUE_; ib = -jb; } else { ib = jb; } i__3 = IWORK(j + in) + iwoff; for (je = IWORK(j) + 1 + iwoff; je <= IWORK(j+in)+iwoff; ++je) { W(je) = tmp1; IBLOCK(je) = ib;/* L50: */ }/* L60: */ } *m += im; }L70: ; }/* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU If NWL+1 < IL or NWU > IU, discard extra eigenvalues. */ if (irange == 3) { im = 0; idiscl = *il - 1 - nwl; idiscu = nwu - *iu; if (idiscl > 0 || idiscu > 0) { i__1 = *m; for (je = 1; je <= *m; ++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); }/* L80: */ } *m = im; } if (idiscl > 0 || idiscu > 0) {/* Code to deal with effects of bad arithmetic: Some low eigenvalues to be discarded are not in (WL,WLU], or high eigenvalues to be discarded are not in (WUL,WU] so just kill off the smallest IDISCL/largest IDISCU eigenvalues, by simply finding the smallest/largest eigenvalue(s). (If N(w) is monotone non-decreasing, this should never happen.) */ if (idiscl > 0) { wkill = wu; i__1 = idiscl; for (jdisc = 1; jdisc <= idiscl; ++jdisc) { iw = 0; i__2 = *m; for (je = 1; je <= *m; ++je) { if (IBLOCK(je) != 0 && (W(je) < wkill || iw == 0)) { iw = je; wkill = W(je); }/* L90: */ } IBLOCK(iw) = 0;/* L100: */ } } if (idiscu > 0) { wkill = wl; i__1 = idiscu; for (jdisc = 1; jdisc <= idiscu; ++jdisc) { iw = 0; i__2 = *m; for (je = 1; je <= *m; ++je) { if (IBLOCK(je) != 0 && (W(je) > wkill || iw == 0)) { iw = je; wkill = W(je); }/* L110: */ } IBLOCK(iw) = 0;/* L120: */ } } im = 0; i__1 = *m; for (je = 1; je <= *m; ++je) { if (IBLOCK(je) != 0) { ++im; W(im) = W(je); IBLOCK(im) = IBLOCK(je); }/* L130: */ } *m = im; } if (idiscl < 0 || idiscu < 0) { toofew = TRUE_; } }/* If ORDER='B', do nothing -- the eigenvalues are already sorted by block. If ORDER='E', sort the eigenvalues from smallest to largest */ if (iorder == 1 && *nsplit > 1) { i__1 = *m - 1; for (je = 1; je <= *m-1; ++je) { ie = 0; tmp1 = W(je); i__2 = *m; for (j = je + 1; j <= *m; ++j) { if (W(j) < tmp1) { ie = j; tmp1 = W(j); }/* L140: */ } if (ie != 0) { itmp1 = IBLOCK(ie); W(ie) = W(je); IBLOCK(ie) = IBLOCK(je); W(je) = tmp1; IBLOCK(je) = itmp1; }/* L150: */ } } *info = 0; if (ncnvrg) { ++(*info); } if (toofew) { *info += 2; } return 0;/* End of SSTEBZ */} /* sstebz_ */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?