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

📄 fitmrq.h

📁 经典numerical receip 配套代码
💻 H
字号:
struct Fitmrq {
	static const Int NDONE=4, ITMAX=1000;
	Int ndat, ma, mfit;
	VecDoub_I &x,&y,&sig;
	Doub tol;
	void (*funcs)(const Doub, VecDoub_I &, Doub &, VecDoub_O &);
	VecBool ia;
	VecDoub a;
	MatDoub covar;
	MatDoub alpha;
	Doub chisq;

	Fitmrq(VecDoub_I &xx, VecDoub_I &yy, VecDoub_I &ssig, VecDoub_I &aa,
	void funks(const Doub, VecDoub_I &, Doub &, VecDoub_O &), const Doub
	TOL=1.e-3) : ndat(xx.size()), ma(aa.size()), x(xx), y(yy), sig(ssig),
	tol(TOL), funcs(funks), ia(ma), alpha(ma,ma), a(aa), covar(ma,ma) {
		for (Int i=0;i<ma;i++) ia[i] = true;
	}

	void hold(const Int i, const Doub val) {ia[i]=false; a[i]=val;}
	void free(const Int i) {ia[i]=true;}

	void fit() {
		Int j,k,l,iter,done=0;
		Doub alamda=.001,ochisq;
		VecDoub atry(ma),beta(ma),da(ma);
		mfit=0;
		for (j=0;j<ma;j++) if (ia[j]) mfit++;
		MatDoub oneda(mfit,1), temp(mfit,mfit);
		mrqcof(a,alpha,beta);
		for (j=0;j<ma;j++) atry[j]=a[j];
		ochisq=chisq;
		for (iter=0;iter<ITMAX;iter++) {
			if (done==NDONE) alamda=0.;
			for (j=0;j<mfit;j++) {
				for (k=0;k<mfit;k++) covar[j][k]=alpha[j][k];
				covar[j][j]=alpha[j][j]*(1.0+alamda);
				for (k=0;k<mfit;k++) temp[j][k]=covar[j][k];
				oneda[j][0]=beta[j];
			}
			gaussj(temp,oneda);
			for (j=0;j<mfit;j++) {
				for (k=0;k<mfit;k++) covar[j][k]=temp[j][k];
				da[j]=oneda[j][0];
			}
			if (done==NDONE) {
				covsrt(covar);
				covsrt(alpha);
				return;
			}
			for (j=0,l=0;l<ma;l++)
				if (ia[l]) atry[l]=a[l]+da[j++];
			mrqcof(atry,covar,da);
			if (abs(chisq-ochisq) < MAX(tol,tol*chisq)) done++;
			if (chisq < ochisq) {
				alamda *= 0.1;
				ochisq=chisq;
				for (j=0;j<mfit;j++) {
					for (k=0;k<mfit;k++) alpha[j][k]=covar[j][k];
						beta[j]=da[j];
				}
				for (l=0;l<ma;l++) a[l]=atry[l];
			} else {
				alamda *= 10.0;
				chisq=ochisq;
			}
		}
		throw("Fitmrq too many iterations");
	}


	void mrqcof(VecDoub_I &a, MatDoub_O &alpha, VecDoub_O &beta) {
		Int i,j,k,l,m;
		Doub ymod,wt,sig2i,dy;
		VecDoub dyda(ma);
		for (j=0;j<mfit;j++) {
			for (k=0;k<=j;k++) alpha[j][k]=0.0;
			beta[j]=0.;
		}
		chisq=0.;
		for (i=0;i<ndat;i++) {
			funcs(x[i],a,ymod,dyda);
			sig2i=1.0/(sig[i]*sig[i]);
			dy=y[i]-ymod;
			for (j=0,l=0;l<ma;l++) {
				if (ia[l]) {
					wt=dyda[l]*sig2i;
					for (k=0,m=0;m<l+1;m++)
						if (ia[m]) alpha[j][k++] += wt*dyda[m];
					beta[j++] += dy*wt;
				}
			}
			chisq += dy*dy*sig2i;
		}
		for (j=1;j<mfit;j++)
			for (k=0;k<j;k++) alpha[k][j]=alpha[j][k];
	}

	void covsrt(MatDoub_IO &covar) {
		Int i,j,k;
		for (i=mfit;i<ma;i++)
			for (j=0;j<i+1;j++) covar[i][j]=covar[j][i]=0.0;
		k=mfit-1;
		for (j=ma-1;j>=0;j--) {
			if (ia[j]) {
				for (i=0;i<ma;i++) SWAP(covar[i][k],covar[i][j]);
				for (i=0;i<ma;i++) SWAP(covar[k][i],covar[j][i]);
				k--;
			}
		}
	}

};

⌨️ 快捷键说明

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