Beispiel #1
0
// Find a point in space with high density.
void TChain::find_center(double* const center, gsl_matrix *const cov, gsl_matrix *const inv_cov, double* det_cov, double dmax, unsigned int iterations) const {
	// Check that the matrices are the correct size
	/*assert(cov->size1 == N);
	assert(cov->size2 == N);
	assert(inv_cov->size1 == N);
	assert(inv_cov->size2 == N);*/
	
	// Choose random point in chain as starting point
	gsl_rng *r;
	seed_gsl_rng(&r);
	
	long unsigned int index_tmp = gsl_rng_uniform_int(r, length);
	const double *x_tmp = get_element(index_tmp);
	for(unsigned int i=0; i<N; i++) { center[i] = x_tmp[i]; }
	
	// Iterate
	double *sum = new double[N];
	double weight;
	for(unsigned int i=0; i<iterations; i++) {
		// Set mean of nearby points as center
		weight = 0.;
		for(unsigned int n=0; n<N; n++) { sum[n] = 0.; }
		for(unsigned int k=0; k<length; k++) {
			x_tmp = get_element(k);
			if(metric_dist2(inv_cov, x_tmp, center, N) < dmax*dmax) {
				for(unsigned int n=0; n<N; n++) { sum[n] += w[k] * x_tmp[n]; }
				weight += w[k];
			}
		}
		for(unsigned int n=0; n<N; n++) { center[n] = sum[n] / (double)weight; }
		
		dmax *= 0.9;
	}
	
	//for(unsigned int n=0; n<N; n++) { std::cout << " " << center[n]; }
	//std::cout << std::endl;
	
	gsl_rng_free(r);
	delete[] sum;
}
Beispiel #2
0
// Uses a variant of the bounded harmonic mean approximation to determine the evidence.
// Essentially, the regulator chosen is an ellipsoid with radius nsigma standard deviations
// along each principal axis. The regulator is then 1/V inside the ellipsoid and 0 without,
// where V is the volume of the ellipsoid. In this form, the harmonic mean approximation
// has finite variance. See Gelfand & Dey (1994) and Robert & Wraith (2009) for details.
double TChain::get_ln_Z_harmonic(bool use_peak, double nsigma_max, double nsigma_peak, double chain_frac) const {
	// Get the covariance and determinant of the chain
	gsl_matrix* Sigma = gsl_matrix_alloc(N, N);
	gsl_matrix* invSigma = gsl_matrix_alloc(N, N);
	double detSigma;
	stats.get_cov_matrix(Sigma, invSigma, &detSigma);
	
	// Determine the center of the prior volume to use
	double* mu = new double[N];
	if(use_peak) {	// Use the peak density as the center
		find_center(mu, Sigma, invSigma, &detSigma, nsigma_peak, 5);
		//density_peak(mu, nsigma_peak);
	} else {	// Get the mean from the stats class
		for(unsigned int i=0; i<N; i++) { mu[i] = stats.mean(i); }
	}
	
	// Sort elements in chain by distance from center, filtering out values of L which are not finite
	std::vector<TChainSort> sorted_indices;
	sorted_indices.reserve(length);
	unsigned int filt_length = 0;
	for(unsigned int i=0; i<length; i++) {
		if(!(isnan(L[i]) || is_inf_replacement(L[i]))) {
			TChainSort tmp_el;
			tmp_el.index = i;
			tmp_el.dist2 = metric_dist2(invSigma, get_element(i), mu, N);
			sorted_indices.push_back(tmp_el);
			filt_length++;
		}
	}
	unsigned int npoints = (unsigned int)(chain_frac * (double)filt_length);
	std::partial_sort(sorted_indices.begin(), sorted_indices.begin() + npoints, sorted_indices.end());
	
	// Determine <1/L> inside the prior volume
	double sum_invL = 0.;
	double tmp_invL;
	double nsigma = sqrt(sorted_indices[npoints-1].dist2);
	unsigned int tmp_index = sorted_indices[0].index;;
	double L_0 = L[tmp_index];
	//std::cout << "index_0 = " << sorted_indices[0].index << std::endl;
	for(unsigned int i=0; i<npoints; i++) {
		if(sorted_indices[i].dist2 > nsigma_max * nsigma_max) {
			nsigma = nsigma_max;
			break;
		}
		tmp_index = sorted_indices[i].index;
		tmp_invL = w[tmp_index] / exp(L[tmp_index] - L_0);
		//std::cout << w[tmp_index] << ", " << L[tmp_index] << std::endl;
		//if(isnan(tmp_invL)) {
		//	std::cout << "\t\tL, L_0 = " << L[tmp_index] << ", " << L_0 << std::endl;
		//}
		if((tmp_invL + sum_invL > 1.e100) && (i != 0)) {
			nsigma = sqrt(sorted_indices[i-1].dist2);
			break;
		}
		sum_invL += tmp_invL;
	}
	
	// Determine the volume normalization (the prior volume)
	double V = sqrt(detSigma) * 2. * pow(SQRTPI * nsigma, (double)N) / (double)(N) / gsl_sf_gamma((double)(N)/2.);
	
	// Return an estimate of ln(Z)
	double lnZ = log(V) - log(sum_invL) + log(total_weight) + L_0;
	
	if(isnan(lnZ)) {
		std::cout << std::endl;
		std::cout << "NaN Error! lnZ = " << lnZ << std::endl;
		std::cout << "\tsum_invL = e^(" << -L_0 << ") * " << sum_invL << " = " << exp(-L_0) * sum_invL << std::endl;
		std::cout << "\tV = " << V << std::endl;
		std::cout << "\ttotal_weight = " << total_weight << std::endl;
		std::cout << std::endl;
	} else if(is_inf_replacement(lnZ)) {
		std::cout << std::endl;
		std::cout << "inf Error! lnZ = " << lnZ << std::endl;
		std::cout << "\tsum_invL = e^(" << -L_0 << ") * " << sum_invL << " = " << exp(-L_0) * sum_invL << std::endl;
		std::cout << "\tV = " << V << std::endl;
		std::cout << "\ttotal_weight = " << total_weight << std::endl;
		std::cout << "\tnsigma = " << nsigma << std::endl;
		std::cout << "\tIndex\tDist^2:" << std::endl;
		for(unsigned int i=0; i<10; i++) {
			std::cout << sorted_indices[i].index << "\t\t" << sorted_indices[i].dist2 << std::endl;
			std::cout << "  ";
			const double *tmp_x = get_element(sorted_indices[i].index);
			for(unsigned int k=0; k<N; k++) { std::cout << " " << tmp_x[k]; }
			std::cout << std::endl;
		}
		std::cout << "mu =";
		for(unsigned int i=0; i<N; i++) { std::cout << " " << mu[i]; }
		std::cout << std::endl;
	}
	
	// Cleanup
	gsl_matrix_free(Sigma);
	gsl_matrix_free(invSigma);
	delete[] mu;
	
	return lnZ;
}
Beispiel #3
0
// Find a point in space with high density.
void TChain::find_center(double* const center, gsl_matrix *const cov, gsl_matrix *const inv_cov, double* det_cov, double dmax, unsigned int iterations) const {
	// Check that the matrices are the correct size
	/*assert(cov->size1 == N);
	assert(cov->size2 == N);
	assert(inv_cov->size1 == N);
	assert(inv_cov->size2 == N);*/
	
	// Choose random point in chain as starting point
	gsl_rng *r;
	seed_gsl_rng(&r);
	
	long unsigned int index_tmp = gsl_rng_uniform_int(r, length);
	const double *x_tmp = get_element(index_tmp);
	for(unsigned int i=0; i<N; i++) { center[i] = x_tmp[i]; }
	
	//std::cout << "center #0:";
	//for(unsigned int n=0; n<N; n++) { std::cout << " " << center[n]; }
	//std::cout << std::endl;
	
	/*double *E_k = new double[N];
	double *E_ij = new double[N*N];
	for(unsigned int n1=0; n1<N; n1++) {
		E_k[n1] = 0.;
		for(unsigned int n2=0; n2<N; n2++) { E_ij[n1 + N*n2] = 0.; }
	}*/
	
	// Iterate
	double *sum = new double[N];
	double weight;
	for(unsigned int i=0; i<iterations; i++) {
		// Set mean of nearby points as center
		weight = 0.;
		for(unsigned int n=0; n<N; n++) { sum[n] = 0.; }
		for(unsigned int k=0; k<length; k++) {
			x_tmp = get_element(k);
			if(metric_dist2(inv_cov, x_tmp, center, N) < dmax*dmax) {
				for(unsigned int n=0; n<N; n++) { sum[n] += w[k] * x_tmp[n]; }
				weight += w[k];
				
				// Calculate the covariance
				/*if(i == iterations - 1) {
					for(unsigned int n1=0; n1<N; n1++) {
						E_k[n1] += w[k] * x_tmp[n1];
						for(unsigned int n2=0; n2<N; n2++) { E_ij[n1 + N*n2] += w[k] * x_tmp[n1] * x_tmp[n2]; }
					}
				}*/
			}
		}
		//std::cout << "center #" << i+1 << ":";
		for(unsigned int n=0; n<N; n++) { center[n] = sum[n] / (double)weight; }//std::cout << " " << center[n]; }
		//std::cout << " (" << weight << ")" << std::endl;
		
		dmax *= 0.9;
	}
	
	for(unsigned int n=0; n<N; n++) { std::cout << " " << center[n]; }
	std::cout << std::endl;
	
	// Calculate the covariance matrix of the enclosed points
	/*double tmp;
	for(unsigned int i=0; i<N; i++) {
		for(unsigned int j=i; j<N; j++) {
			tmp = (E_ij[i + N*j] - E_k[i]*E_k[j]/(double)weight) / (double)weight;
			gsl_matrix_set(cov, i, j, tmp);
			if(i != j) { gsl_matrix_set(cov, j, i, tmp); }
		}
	}*/
	
	// Get the inverse of the covariance
	/*int s;
	gsl_permutation* p = gsl_permutation_alloc(N);
	gsl_matrix* LU = gsl_matrix_alloc(N, N);
	gsl_matrix_memcpy(LU, cov);
	gsl_linalg_LU_decomp(LU, p, &s);
	gsl_linalg_LU_invert(LU, p, inv_cov);
	
	// Get the determinant of the covariance
	*det_cov = gsl_linalg_LU_det(LU, s);
	
	// Cleanup
	gsl_matrix_free(LU);
	gsl_permutation_free(p);
	delete[] E_k;
	delete[] E_ij;*/
	
	gsl_rng_free(r);
	delete[] sum;
}