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 + -
显示快捷键?