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

📄 general_inner_simplex.c

📁 最大似然估计算法
💻 C
字号:
#include "timeseries.h" double general_inner_simplex(time_series ts, data_kernel dk, noise_model *nm, int n_models, options op, int end_flag) {			int    i, j, k, l, m;	int    n_vert, n_params, ilo, ihi, inhi, info;	int    nfun_eval, got_answer, n_squared;	double **p, *mle, *psum, *params, *ptry, *start;	double **Cunits, *Cfull, *unit, *fit, *cov_fit;	double mle_try, mle_save, min_mle;	double fac, fac1, fac2, r;	double md1, md2, md3, dist, scale;	clock_t time1, time2;	/*************************************************/	/* Just check that no models have fixed sigmas   */ 	/* Unfortunately you cant fix a sigma when using */        /* the angle method                              */	/*************************************************/	for (j = 0; j < n_models; j++) {		if (nm[j].sigma_flag[0] != 0) {			fprintf(stderr, "Cannot have fixed covariance in the stochastic model\n");			fprintf(stderr, "exiting....\n");			exit(EXIT_FAILURE);		}	}	n_vert   = n_models;	n_params = n_vert-1;	/***********************************/	/* Set the initial starting values */	/***********************************/	ptry   = (double *)  calloc((size_t) n_params, sizeof(double));	psum   = (double *)  calloc((size_t) n_params, sizeof(double));	start  = (double *)  calloc((size_t) n_params, sizeof(double));	params = (double *)  calloc((size_t) n_params, sizeof(double));	unit   = (double *)  calloc((size_t) n_vert,   sizeof(double));	mle    = (double *)  calloc((size_t) n_vert,   sizeof(double));	n_squared  = dk.n_data * dk.n_data;	Cunits   = (double **) calloc((size_t) n_models*n_squared, sizeof(double *));		for (j = 0; j < n_models; j++) Cunits[j] = (double *) calloc((size_t) n_squared, sizeof(double));	Cfull    = (double *)  calloc((size_t) n_squared, sizeof(double));	fit      = (double *) calloc((size_t) dk.n_par,            sizeof(double));	cov_fit  = (double *) calloc((size_t) (dk.n_par*dk.n_par), sizeof(double));	p        = (double **) calloc((size_t)(n_params*n_vert), sizeof(double *));	for (j = 0; j < n_vert; j++) p[j] = (double *) calloc((size_t) n_params, sizeof(double));	for (j = 0; j < n_params; j++) start[j] = 45.0;		for (k = 0; k < n_vert; k++) {		for (j = 0; j < n_params; j++) {			p[k][j] = start[j];			if (k == j+1) p[k][j] = op.delta * start[j];		}	}	for (i = 0; i < n_models; i++) {			create_covariance(nm[i], ts, op.cov_method, Cunits[i], 1);	}	if (op.verbose) fprintf(op.fpout, " general_inner_simplex : starting simplex\n");	if (op.verbose) fprintf(op.fpout, " general_inner_simplex : n_vert = %d\n", n_vert);	/*************************************/	/* setup starting values for simplex */	/*************************************/	for (k = 0; k < n_vert; k++) {		for (j = 0; j < n_params; j++) params[j] = p[k][j];		for (l = 0; l < n_squared; l++) Cfull[l] = 0.0;		sigma_from_rphi(n_vert,params,unit);		if (op.verbose) {			for (l = 0; l < n_vert; l++)   fprintf(op.fpout, " unit[%d] = %f\n", l, unit[l]);			for (l = 0; l < n_params; l++) fprintf(op.fpout, "  phi[%d] = %f\n", l, params[l]);			fprintf(stderr, "\n");		}		for (i = 0; i < n_models; i++) {			scale = unit[i]*unit[i];			time1 = clock();			for (l = 0; l < n_squared; l++) Cfull[l] += scale*Cunits[i][l];			time2 = clock();			if (op.verbose > 1) {				fprintf(op.fpout," Time to scale covariance matrix ");				fprintf(op.fpout,"%f seconds\n", ((double) (time2-time1)) / CLOCKS_PER_SEC);			}		}						mle[k] = general_MLE(dk, Cfull, op, fit, cov_fit, &r, 1);	/* if (op.verbose > 0) fprintf(op.fpout, "START : %12.8f %.8f\n", params[0], mle[k]); */		for (j = 0 ; j < n_params; j++) if (params[j] < 0.0 || params[j] > 90.0) mle[k] -= 1e5; 		mle[k] = -mle[k];	}	for (j = 0; j < n_params; j++) {		psum[j] = 0.0;		for (k = 0; k < n_vert; k++) psum[j] += p[k][j];	}			/*******************************/	/* Begin the simplex algorithm */	/*******************************/	nfun_eval = 0;	got_answer = 0;	while ((double) nfun_eval <= op.tol[0]) {		if (op.verbose) {			for (k = 0; k < n_vert; k++) {				fprintf(op.fpout, "%2d %3d %15.8f ", k, nfun_eval,  -mle[k]);				for (j = 0; j < n_params; j++) fprintf(op.fpout, "%12.8f ", p[k][j]);				fprintf(op.fpout, "\n");			}			fprintf(op.fpout, "\n");			fflush(op.fpout);		}					ilo = 0;		ihi = mle[0] > mle[1] ? (inhi=1,0) : (inhi=0,1);		for (i = 0; i < n_vert; i++) {			if (mle[i] <= mle[ilo]) ilo = i;			if (mle[i] > mle[ihi]) {				inhi = ihi;				ihi = i;			} else if (mle[i] > mle[inhi] && i != ihi) inhi = i;		}		/**************************************************/		/* Check that this stopping criteria is good..... */		/* It is not the same as the one in NR!           */		/* Yes it its better but does need tuning         */		/**************************************************/		md1 = md2 = md3 = 0.0;		for (k = 1; k < n_vert; k++) {			for (j = 0; j < n_params; j++) {				dist = fabs(p[k][j] - p[0][j]) / p[0][j]; 				md1 = dist > md1 ? dist : md1;				dist = fabs(p[k][j] - p[0][j]);				md2 = dist > md2 ? dist : md2;			}			dist = fabs((mle[k] - mle[0]) / mle[0]);			md3 = dist > md3 ? dist : md3;		}		if ((md1 <= op.tol[1] || md2 <= op.tol[3]) && (md3 <= op.tol[2])) {			if (op.verbose) {				fprintf(op.fpout, " Stopping criteria met.\n");				fprintf(op.fpout, " Stopping criteria :(%g <= %g ||  ", md1, op.tol[1]);				fprintf(op.fpout, " %g <= %g) &&  ", md2, op.tol[3]);				fprintf(op.fpout, " (%g <= %g)\n", md3, op.tol[2]);			}			got_answer = 1;			break;		}		nfun_eval += 2;		/************************************************************/		/* first extrapolate by a factor -1 through the face of the */		/* simplex across from the high point                       */		/************************************************************/		fac  = -1.0;		fac1 = (1.0 - fac) / (double) n_params;		fac2 = fac1 - fac;		for (j = 0 ; j < n_params; j++) ptry[j] = psum[j]*fac1 - p[ihi][j]*fac2;		sigma_from_rphi(n_vert,ptry,unit);		for (l = 0; l < n_squared; l++) Cfull[l] = 0.0;		for (i = 0; i < n_models; i++) {			scale = unit[i]*unit[i];			for (l = 0; l < n_squared; l++) Cfull[l] += scale*Cunits[i][l];		}						mle_try = general_MLE(dk, Cfull, op, fit, cov_fit, &r, 1);		/* if (op.verbose > 0) fprintf(op.fpout, "EXTRA : %12.8f %.8f\n", ptry[0], mle_try); */		for (j = 0 ; j < n_params; j++) if (ptry[j] < 0.0 || ptry[j] > 90.0) mle_try -= 1e5; 		mle_try = -mle_try;		if (mle_try < mle[ihi]) {			mle[ihi] = mle_try;			for (j = 0; j < n_params; j++) {				psum[j] += ptry[j]-p[ihi][j];				p[ihi][j] = ptry[j];			}		}		/************************************************************/		if (mle_try < mle[ilo]) {			fac = 2.0;			fac1 = (1.0 - fac) / (double) n_params;			fac2 = fac1 - fac;			for (j = 0 ; j < n_params; j++) ptry[j] = psum[j]*fac1 - p[ihi][j]*fac2;			sigma_from_rphi(n_vert,ptry,unit);			for (l = 0; l < n_squared; l++) Cfull[l] = 0.0;			for (i = 0; i < n_models; i++) {				scale = unit[i]*unit[i];				for (l = 0; l < n_squared; l++) Cfull[l] += scale*Cunits[i][l];			}			mle_try = general_MLE(dk, Cfull, op, fit, cov_fit, &r, 1);			/* if (op.verbose > 0) fprintf(op.fpout, "OTHER1 : %12.8f %.8f\n", ptry[0], mle_try); */			for (j = 0; j < n_params; j++) if (ptry[j] < 0.0 || ptry[j] > 90.0) mle_try -= 1e5; 			mle_try = -mle_try;			if (mle_try < mle[ihi]) {				mle[ihi] = mle_try;				for (j = 0; j < n_params; j++) {					psum[j] += ptry[j]-p[ihi][j];					p[ihi][j] = ptry[j];				}			}		} else if (mle_try >= mle[inhi]) {			mle_save = mle[ihi];			fac = 0.5;			fac1 = (1.0 - fac) / (double) n_params;			fac2 = fac1 - fac;				for (j = 0 ; j < n_params; j++) ptry[j] = psum[j]*fac1 - p[ihi][j]*fac2;			for (l = 0; l < n_squared; l++) Cfull[l] = 0.0;			sigma_from_rphi(n_vert,ptry,unit);			for (i = 0; i < n_models; i++) {				scale = unit[i]*unit[i];				for (l = 0; l < n_squared; l++) Cfull[l] += scale*Cunits[i][l];			}							mle_try = general_MLE(dk, Cfull, op, fit, cov_fit, &r, 1);			/* if (op.verbose > 0) fprintf(op.fpout, "OTHER2 : %12.8f %.8f\n", ptry[0], mle_try); */			for (j = 0 ; j < n_params; j++) if (ptry[j] < 0.0 || ptry[j] > 90.0) mle_try -= 1e5; 			mle_try = -mle_try;			if (mle_try < mle[ihi]) {				mle[ihi] = mle_try;				for (j = 0; j < n_params; j++) {					psum[j] += ptry[j]-p[ihi][j];					p[ihi][j] = ptry[j];				}			}				if (mle_try >= mle_save) {				for (i = 0; i < n_vert; i++) {					if (i != ilo) {						for (j = 0; j < n_params; j++) {							p[i][j] = psum[j] = 0.5 * (p[i][j] + p[ilo][j]);						}						for (j = 0; j < n_params; j++) params[j] = p[i][j];						for (l = 0; l < n_squared; l++) Cfull[l] = 0.0;						sigma_from_rphi(n_vert,params,unit);						for (i = 0; i < n_models; i++) {							scale = unit[i]*unit[i];							for (l = 0; l < n_squared; l++) Cfull[l] += scale*Cunits[i][l];						}										mle_try = general_MLE(dk, Cfull, op, fit, cov_fit, &r, 1);						/* if (op.verbose > 0) fprintf(op.fpout, "OTHER3 : %12.8f %.8f\n", params[0], mle_try); */						for (j = 0 ; j < n_params; j++) if (params[j] < 0.0 || params[j] > 0.0) mle_try -= 1e5; 						mle_try = -mle_try;					}				}			}			nfun_eval += n_params;			for (j = 0; j < n_params; j++) {				psum[j] = 0.0;				for (k = 0; k < n_vert; k++) psum[j] += p[k][j];			}		} else --nfun_eval;	}	/**************************/	/* The end of the simplex */	/**************************/	if (got_answer) {		for (j = 0; j < n_params;  j++) start[j] = p[ilo][j];		for (l = 0; l < n_squared; l++) Cfull[l] = 0.0;		sigma_from_rphi(n_vert,start,unit);		for (i = 0; i < n_models; i++) {			scale = unit[i]*unit[i];			for (l = 0; l < n_squared; l++) Cfull[l] += scale*Cunits[i][l];		}						min_mle = general_MLE(dk, Cfull, op, fit, cov_fit, &r, 1);		/* if (op.verbose > 0) fprintf(op.fpout, "END : %12.8f %.8f\n", start[0], min_mle); */		if (end_flag) {			for (i = 0; i < n_models; i++) nm[i].sigma[0] = unit[i] * r;			dk.MLE[0] = min_mle;			calculate_fisher(Cunits, dk, nm, n_models, fit, cov_fit);      			for (j = 0; j < dk.n_par; j++) {				dk.params[j] = fit[j];				for (k = 0; k < dk.n_par; k++) {					dk.covar[j + k * dk.n_par] = cov_fit[j + k * dk.n_par];				}			}		}	} else {		fprintf(op.fpout, " Stopping criteria not met.\n");		fprintf(op.fpout, " Stopping criteria :(%f <= %f ||  ", md1, op.tol[1]);		fprintf(op.fpout, " %f <= %f) &&  ", md2, op.tol[3]);		fprintf(op.fpout, " (%f <= %f)\n", md3, op.tol[2]);		fprintf(stderr, " general_inner_simplex : Could not converge on a solution\n");		min_mle = -1e10;		for (j = 0; j < n_params; j++) start[j] = 0.0;	}		free(ptry);	free(start);	free(params);	free(mle);	free(psum);	free(unit);	free(Cfull);	free(fit);	free(cov_fit);	for (j = 0; j < n_vert; j++) free(p[j]);	free(p);	for (j = 0; j < n_models; j++) free(Cunits[j]);	free(Cunits);	return(min_mle);}

⌨️ 快捷键说明

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