⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 roots.h

📁 经典numerical receip 配套代码
💻 H
字号:
template <class T>
Bool zbrac(T &func, Doub &x1, Doub &x2)
{
	const Int NTRY=50;
	const Doub FACTOR=1.6;
	if (x1 == x2) throw("Bad initial range in zbrac");
	Doub f1=func(x1);
	Doub f2=func(x2);
	for (Int j=0;j<NTRY;j++) {
		if (f1*f2 < 0.0) return true;
		if (abs(f1) < abs(f2))
			f1=func(x1 += FACTOR*(x1-x2));
		else
			f2=func(x2 += FACTOR*(x2-x1));
	}
	return false;
}
template <class T>
void zbrak(T &fx, const Doub x1, const Doub x2, const Int n, VecDoub_O &xb1,
	VecDoub_O &xb2, Int &nroot)
{
	Int nb=20;
	xb1.resize(nb);
	xb2.resize(nb);
	nroot=0;
	Doub dx=(x2-x1)/n;
	Doub x=x1;
	Doub fp=fx(x1);
	for (Int i=0;i<n;i++) {
		Doub fc=fx(x += dx);
		if (fc*fp <= 0.0) {
			xb1[nroot]=x-dx;
			xb2[nroot++]=x;
			if(nroot == nb) {
				VecDoub tempvec1(xb1),tempvec2(xb2);
				xb1.resize(2*nb);
				xb2.resize(2*nb);
				for (Int j=0; j<nb; j++) {
					xb1[j]=tempvec1[j];
					xb2[j]=tempvec2[j];
				}
				nb *= 2;
			}
		}
		fp=fc;
	}
}
template <class T>
Doub rtbis(T &func, const Doub x1, const Doub x2, const Doub xacc) {
	const Int JMAX=50;
	Doub dx,xmid,rtb;
	Doub f=func(x1);
	Doub fmid=func(x2);
	if (f*fmid >= 0.0) throw("Root must be bracketed for bisection in rtbis");
	rtb = f < 0.0 ? (dx=x2-x1,x1) : (dx=x1-x2,x2);
	for (Int j=0;j<JMAX;j++) {
		fmid=func(xmid=rtb+(dx *= 0.5));
		if (fmid <= 0.0) rtb=xmid;
		if (abs(dx) < xacc || fmid == 0.0) return rtb;
	}
	throw("Too many bisections in rtbis");
}
template <class T>
Doub rtflsp(T &func, const Doub x1, const Doub x2, const Doub xacc) {
	const Int MAXIT=30;
	Doub xl,xh,del;
	Doub fl=func(x1);
	Doub fh=func(x2);
	if (fl*fh > 0.0) throw("Root must be bracketed in rtflsp");
	if (fl < 0.0) {
		xl=x1;
		xh=x2;
	} else {
		xl=x2;
		xh=x1;
		SWAP(fl,fh);
	}
	Doub dx=xh-xl;
	for (Int j=0;j<MAXIT;j++) {
		Doub rtf=xl+dx*fl/(fl-fh);
		Doub f=func(rtf);
		if (f < 0.0) {
			del=xl-rtf;
			xl=rtf;
			fl=f;
		} else {
			del=xh-rtf;
			xh=rtf;
			fh=f;
		}
		dx=xh-xl;
		if (abs(del) < xacc || f == 0.0) return rtf;
	}
	throw("Maximum number of iterations exceeded in rtflsp");
}
template <class T>
Doub rtsec(T &func, const Doub x1, const Doub x2, const Doub xacc) {
	const Int MAXIT=30;
	Doub xl,rts;
	Doub fl=func(x1);
	Doub f=func(x2);
	if (abs(fl) < abs(f)) {
		rts=x1;
		xl=x2;
		SWAP(fl,f);
	} else {
		xl=x1;
		rts=x2;
	}
	for (Int j=0;j<MAXIT;j++) {
		Doub dx=(xl-rts)*f/(f-fl);
		xl=rts;
		fl=f;
		rts += dx;
		f=func(rts);
		if (abs(dx) < xacc || f == 0.0) return rts;
	}
	throw("Maximum number of iterations exceeded in rtsec");
}
template <class T>
Doub zriddr(T &func, const Doub x1, const Doub x2, const Doub xacc) {
	const Int MAXIT=60;
	Doub fl=func(x1);
	Doub fh=func(x2);
	if ((fl > 0.0 && fh < 0.0) || (fl < 0.0 && fh > 0.0)) {
		Doub xl=x1;
		Doub xh=x2;
		Doub ans=-9.99e99;
		for (Int j=0;j<MAXIT;j++) {
			Doub xm=0.5*(xl+xh);
			Doub fm=func(xm);
			Doub s=sqrt(fm*fm-fl*fh);
			if (s == 0.0) return ans;
			Doub xnew=xm+(xm-xl)*((fl >= fh ? 1.0 : -1.0)*fm/s);
			if (abs(xnew-ans) <= xacc) return ans;
			ans=xnew;
			Doub fnew=func(ans);
			if (fnew == 0.0) return ans;
			if (SIGN(fm,fnew) != fm) {
				xl=xm;
				fl=fm;
				xh=ans;
				fh=fnew;
			} else if (SIGN(fl,fnew) != fl) {
				xh=ans;
				fh=fnew;
			} else if (SIGN(fh,fnew) != fh) {
				xl=ans;
				fl=fnew;
			} else throw("never get here.");
			if (abs(xh-xl) <= xacc) return ans;
		}
		throw("zriddr exceed maximum iterations");
	}
	else {
		if (fl == 0.0) return x1;
		if (fh == 0.0) return x2;
		throw("root must be bracketed in zriddr.");
	}
}
template <class T>
Doub zbrent(T &func, const Doub x1, const Doub x2, const Doub tol)
{
	const Int ITMAX=100;
	const Doub EPS=numeric_limits<Doub>::epsilon();
	Doub a=x1,b=x2,c=x2,d,e,fa=func(a),fb=func(b),fc,p,q,r,s,tol1,xm;
	if ((fa > 0.0 && fb > 0.0) || (fa < 0.0 && fb < 0.0))
		throw("Root must be bracketed in zbrent");
	fc=fb;
	for (Int iter=0;iter<ITMAX;iter++) {
		if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) {
			c=a;
			fc=fa;
			e=d=b-a;
		}
		if (abs(fc) < abs(fb)) {
			a=b;
			b=c;
			c=a;
			fa=fb;
			fb=fc;
			fc=fa;
		}
		tol1=2.0*EPS*abs(b)+0.5*tol;
		xm=0.5*(c-b);
		if (abs(xm) <= tol1 || fb == 0.0) return b;
		if (abs(e) >= tol1 && abs(fa) > abs(fb)) {
			s=fb/fa;
			if (a == c) {
				p=2.0*xm*s;
				q=1.0-s;
			} else {
				q=fa/fc;
				r=fb/fc;
				p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
				q=(q-1.0)*(r-1.0)*(s-1.0);
			}
			if (p > 0.0) q = -q;
			p=abs(p);
			Doub min1=3.0*xm*q-abs(tol1*q);
			Doub min2=abs(e*q);
			if (2.0*p < (min1 < min2 ? min1 : min2)) {
				e=d;
				d=p/q;
			} else {
				d=xm;
				e=d;
			}
		} else {
			d=xm;
			e=d;
		}
		a=b;
		fa=fb;
		if (abs(d) > tol1)
			b += d;
		else
			b += SIGN(tol1,xm);
			fb=func(b);
	}
	throw("Maximum number of iterations exceeded in zbrent");
}
template <class T>
Doub rtnewt(T &funcd, const Doub x1, const Doub x2, const Doub xacc) {
	const Int JMAX=20;
	Doub rtn=0.5*(x1+x2);
	for (Int j=0;j<JMAX;j++) {
		Doub f=funcd(rtn);
		Doub df=funcd.df(rtn);
		Doub dx=f/df;
		rtn -= dx;
		if ((x1-rtn)*(rtn-x2) < 0.0)
			throw("Jumped out of brackets in rtnewt");
		if (abs(dx) < xacc) return rtn;
	}
	throw("Maximum number of iterations exceeded in rtnewt");
}
template <class T>
Doub rtsafe(T &funcd, const Doub x1, const Doub x2, const Doub xacc) {
	const Int MAXIT=100;
	Doub xh,xl;
	Doub fl=funcd(x1);
	Doub fh=funcd(x2);
	if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0))
		throw("Root must be bracketed in rtsafe");
	if (fl == 0.0) return x1;
	if (fh == 0.0) return x2;
	if (fl < 0.0) {
		xl=x1;
		xh=x2;
	} else {
		xh=x1;
		xl=x2;
	}
	Doub rts=0.5*(x1+x2);
	Doub dxold=abs(x2-x1);
	Doub dx=dxold;
	Doub f=funcd(rts);
	Doub df=funcd.df(rts);
	for (Int j=0;j<MAXIT;j++) {
		if ((((rts-xh)*df-f)*((rts-xl)*df-f) > 0.0)
			|| (abs(2.0*f) > abs(dxold*df))) {
			dxold=dx;
			dx=0.5*(xh-xl);
			rts=xl+dx;
			if (xl == rts) return rts;
		} else {
			dxold=dx;
			dx=f/df;
			Doub temp=rts;
			rts -= dx;
			if (temp == rts) return rts;
		}
		if (abs(dx) < xacc) return rts;
		Doub f=funcd(rts);
		Doub df=funcd.df(rts);
		if (f < 0.0)
			xl=rts;
		else
			xh=rts;
	}
	throw("Maximum number of iterations exceeded in rtsafe");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -