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

📄 linefit_final.c

📁 最大似然估计算法
💻 C
字号:
#include "timeseries.h"double linefit_final(double *start, time_series ts, data_kernel dk, noise_model nm, options op, double *params_mle, double *cov_mle) {	int i, j, k;	int n_params, info;	int liwork, lwork;	int *iwork, *ipiv;	double *params;	double *fit, *cov_fit, *data_hat, *work;	double *Eig_vectors, *Eig_values, *C_unit, *C;	double *residuals, *Ioo;	double *cov_wh, *params_wh;	double *cov_cn, *params_cn;	double min_mle, wh_mle, cn_mle, b;	double F1, F2, F3, F4, second_partial, cross_partial;	/******************************************************************/	/* This is for a power-law noise plus white noise so n_params = 2 */	/******************************************************************/	n_params = 2;	/*******************************************************************************/	/* First of all generate all the relevant matrices for the rest of the simplex */	/*******************************************************************************/	Eig_vectors = (double *) calloc((size_t)(dk.n_data*dk.n_data), sizeof(double));	C           = (double *) calloc((size_t)(dk.n_data*dk.n_data), sizeof(double));	C_unit      = (double *) calloc((size_t)(dk.n_data*dk.n_data), sizeof(double));	Eig_values  = (double *) calloc((size_t) dk.n_data,            sizeof(double));	residuals   = (double *) calloc((size_t) dk.n_data,            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));	data_hat    = (double *) calloc((size_t) dk.n_data,            sizeof(double));	/* lwork = 100 + 6 * dk.n_data + 2 * dk.n_data * dk.n_data;	liwork = 30 + 5 * dk.n_data; */	lwork = 35 * dk.n_data;	liwork = 5 * dk.n_data;	work        = (double *) calloc((size_t) lwork,                sizeof(double));	iwork       = (int *)    calloc((size_t) liwork,               sizeof(int));	/*************************************************************************/	/* Create the unit power law covariance matrix and find the eigen values */	/* and the eigen vectors                                                 */	/*************************************************************************/	create_covariance(nm, ts, op.cov_method, Eig_vectors, 1);	dlacpy_("Full", &dk.n_data, &dk.n_data, Eig_vectors, &dk.n_data, C_unit, &dk.n_data);	/* dsyevd_("V","L",&dk.n_data,Eig_vectors,&dk.n_data,Eig_values,work,&lwork,iwork,&liwork,&info);  */	dsyev_("V","L",&dk.n_data,Eig_vectors,&dk.n_data,Eig_values,work,&lwork,&info);	free(iwork);	free(work);	/***************************************************************/	/* While this is a "mimimum" we still need to check it against */	/* the white noise only case and the pl only case              */	/***************************************************************/	i = dk.n_par + 1;	cov_wh    = (double *) calloc((size_t)(i*i), sizeof(double));	cov_cn    = (double *) calloc((size_t)(i*i), sizeof(double));	params_wh = (double *) calloc((size_t) i,    sizeof(double));	params_cn = (double *) calloc((size_t) i,    sizeof(double));	wh_mle = est_line_WH_only(dk, op, params_wh, cov_wh);	cn_mle = cats_CN_only(dk, C_unit, Eig_values, Eig_vectors, params_cn, cov_cn, op.speed);	cn_mle = -cn_mle;	/*****************************************************************/	/* Now calculate an estimate of the covariance matrix of the MLE */	/*****************************************************************/	i = dk.n_par + n_params;	cov_scale(C_unit,dk.n_data,start,C);	linefit_all_fast(dk.A,dk.d,C,dk.n_data,dk.n_par,fit,cov_fit,data_hat);	if (op.speed == 3) {		for (j = 0; j < dk.n_data; j++) residuals[j] = dk.d[j];		for (j = 0; j < dk.n_par; j++) fit[j] = 0.0;	} else {		for (j = 0; j < dk.n_data; j++) residuals[j] = dk.d[j] - data_hat[j];	}	F2 = MLE_withline_CN(start, dk.n_data, Eig_values, Eig_vectors, residuals);	min_mle = -F2;	/* fprintf(stderr, " min_mle = %.8f wh_mle = %.8f cn_mle = %.8f\n", min_mle, wh_mle, cn_mle); */	/* fprintf(stderr, " min_mle-wh_mle = %.8f min_mle-cn_mle = %.8f\n", min_mle-wh_mle, min_mle-cn_mle); */	if (abs(min_mle-wh_mle) < 1e-8) {		start[0] = params_wh[dk.n_par];		start[1] = 0.0;		for (j = 0; j < dk.n_par; j++) {			params_mle[j] = params_wh[j];			for (k = 0; k < dk.n_par; k++) cov_mle[j+k*i] = cov_wh[j+k*(dk.n_par+1)];		}		params_mle[dk.n_par] = params_wh[dk.n_par];		params_mle[i-1]    = 0.0;		cov_mle[dk.n_par + dk.n_par * i] = cov_wh[dk.n_par * (dk.n_par + 2)];		min_mle = wh_mle;	} else if (abs(min_mle-cn_mle) < 1e-8) {		start[0] = 0.0;		start[1] = params_cn[dk.n_par];			for (j = 0; j < dk.n_par; j++) {			params_mle[j] = params_cn[j];			for (k = 0; k < dk.n_par; k++) cov_mle[j+k*i] = cov_cn[j+k*(dk.n_par+1)];		}		params_mle[i-1]    = params_cn[dk.n_par];		params_mle[dk.n_par] = 0.0;		cov_mle[i * i - 1] = cov_cn[dk.n_par * (dk.n_par + 2)];		min_mle = cn_mle;	} else {				/*********************************************/		/* Invert cov_fit and substitute it into Ioo */		/*********************************************/		Ioo = (double *) calloc((size_t)(i*i), sizeof(double) ); 			lwork = dk.n_par;		ipiv = (int *)    calloc((size_t) lwork, sizeof(int));		work = (double *) calloc((size_t) lwork, sizeof(double));			dgetrf_(&dk.n_par, &dk.n_par, cov_fit, &dk.n_par, ipiv, &info);		dgetri_(&dk.n_par, cov_fit, &dk.n_par, ipiv, work, &lwork, &info);		free(ipiv);		free(work);			for (j = 0; j < dk.n_par; j++) {			for (k = 0; k < dk.n_par; k++) Ioo[j+k*i] = -cov_fit[j+k*dk.n_par];		}		work   = (double *) calloc( (size_t) i, sizeof(double) );		params = (double *) calloc( (size_t) i, sizeof(double) );		for (j = 0; j < dk.n_par; j++) work[j]          = params[j]          = fit[j];		for (j = 0; j < n_params; j++) work[j+dk.n_par] = params[j+dk.n_par] = start[j]; 			/******************************************************************************/		/* For the linear parts we already have the covariance matrix so we just      */		/* need to obtain the parts of the covariance matrix for the non-linear parts */		/* which is obtained using the Fisher information matrix                      */		/******************************************************************************/		for (j = dk.n_par; j < i; j++) {			params[j] = work[j] + 1e-3 * fabs(work[j]);			F1 = MLE_nparam_CN(params,i,dk.n_par,dk.n_data,dk.d,dk.A,Eig_values, Eig_vectors);			params[j] = work[j] - 1e-3 * fabs(work[j]);			F3 = MLE_nparam_CN(params,i,dk.n_par,dk.n_data,dk.d,dk.A,Eig_values, Eig_vectors);			second_partial = -(F1-2.0*F2+F3)/pow(1e-3*fabs(work[j]),2.0);			Ioo[j + j * i] = second_partial;			params[j] = work[j];		}					for (j = dk.n_par; j < i; j++) {			for (k = 0; k < j; k++) {				params[j] = work[j] + 1e-3 / 2.0 * fabs(work[j]);				params[k] = work[k] + 1e-3 / 2.0 * fabs(work[k]);				F1 = MLE_nparam_CN(params,i,dk.n_par,dk.n_data,dk.d,dk.A,Eig_values, Eig_vectors);				params[j] = work[j] - 1e-3 / 2.0 * fabs(work[j]);				params[k] = work[k] + 1e-3 / 2.0 * fabs(work[k]);				F2 = MLE_nparam_CN(params,i,dk.n_par,dk.n_data,dk.d,dk.A,Eig_values, Eig_vectors);				params[j] = work[j] + 1e-3 / 2.0 * fabs(work[j]);				params[k] = work[k] - 1e-3 / 2.0 * fabs(work[k]);				F3 = MLE_nparam_CN(params,i,dk.n_par,dk.n_data,dk.d,dk.A,Eig_values, Eig_vectors);				params[j] = work[j] - 1e-3 / 2.0 * fabs(work[j]);				params[k] = work[k] - 1e-3 / 2.0 * fabs(work[k]);				F4 = MLE_nparam_CN(params,i,dk.n_par,dk.n_data,dk.d,dk.A,Eig_values, Eig_vectors);				cross_partial = -(F1-F2-F3+F4) / (1e-3 * fabs(work[j]) * 1e-3 * fabs(work[k]));				Ioo[j + k * i] = Ioo[k + j * i] = cross_partial;							params[j] = work[j];				params[k] = work[k];			}		}		/************************************/		/* Store the params into params_mle */		/************************************/			for (j = 0; j < i; j++) params_mle[j] = work[j];			/**********************/		/* Calculate inv(Ioo) */		/**********************/			lwork = i;		free(work);		ipiv = (int *)    calloc((size_t) lwork, sizeof(int));		work = (double *) calloc((size_t) lwork, sizeof(double));			dgetrf_(&i, &i, Ioo, &i, ipiv, &info);		dgetri_(&i, Ioo, &i, ipiv, work, &lwork, &info);		free(ipiv);		free(work);			/***************************/		/* Store -Ioo into cov_mle */		/***************************/			for (j = 0; j < i; j++) {			for (k = 0; k < i; k++) cov_mle[j + k * i] = -Ioo[j + k * i];		}		free(Ioo);		free(params);	}	free(Eig_vectors);	free(Eig_values);	free(C);	free(C_unit);	free(residuals);	free(fit);	free(cov_fit);	free(data_hat);	free(cov_wh);	free(params_wh);	free(cov_cn);	free(params_cn);	return(min_mle);}

⌨️ 快捷键说明

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