Beispiel #1
0
void fit_halo_profile(struct halo *HALO)
{
	double c=0, r=0, rho0, rho0_halo, rs, chi, gof, per; 
	double *x, *y, *e, *R, *y_th, *x_bin, *y_bin, *e_bin, rMin, rMax; 
	int bins, skip, N, j=0;

		r = HALO->Rvir;
		c = HALO->c; 
		bins = HALO->n_bins;
		skip = HALO->neg_r_bins;

		N = bins - skip;

		rho0 = HALO->rho0;
		rs = HALO->r2;

		x = (double*) calloc(N, sizeof(double));
		y = (double*) calloc(N, sizeof(double));
		e = (double*) calloc(N, sizeof(double));
		R = (double*) calloc(N, sizeof(double));
		
		for(j=0; j<N; j++)
		{
			x[j] = HALO->radius[j+skip];
			y[j] = HALO->rho[j+skip];
			e[j] = HALO->err[j+skip];
			R[j] = HALO->radius[j+skip]/r;
		}

			best_fit_nfw(rho0, rs, N, x, y, e);

			HALO->fit_nfw.rho0 = rho0;
			HALO->fit_nfw.rs = rs;
			HALO->fit_nfw.c = HALO->Rvir/rs;

			y_th = (double*) calloc(bins-skip,sizeof(double));

		for(j=skip; j<bins; j++)
		{
			y_th[j-skip] = nfw(HALO->radius[j], HALO->fit_nfw.rs, HALO->fit_nfw.rho0);
			//fprintf(stderr, "%d) R=%e, %e %e  %e\n", j, R[j-skip], rho0, y[j-skip], y_th[j-skip]);
		}

	// Various estimators for the goodness of fit
	chi = chi_square(y_th, y, e, N);
	gof = goodness_of_fit(y_th, y, N);
	per = percentage_error(y_th, y, N);
	
	chi /= (double) (bins-skip);

	HALO->fit_nfw.chi = chi;
	HALO->fit_nfw.gof = gof;
	HALO->fit_nfw.per = per;

		x_bin = (double*) calloc(BIN_PROFILE+1, sizeof(double));
		y_bin = (double*) calloc(BIN_PROFILE, sizeof(double));
		e_bin = (double*) calloc(BIN_PROFILE, sizeof(double));

		rMin = 2 * Rvir_frac_min;
		rMax = F_MAX * 1.01; //HALO->radius[bins-1]/r;
		x_bin = log_stepper(rMin, rMax, BIN_PROFILE+1);

		average_bin(R, y, x_bin, y_bin, e_bin, BIN_PROFILE+1, N);

	for(j=0; j<BIN_PROFILE; j++)
	{
		HALO->nfw.x[j] = 0.5 * (x_bin[j] + x_bin[j+1]);
		HALO->nfw.y[j] = y_bin[j];
		//fprintf(stderr, "%d  %e  %e\n", j, x_bin[j+1], y_bin[j]);
	}

	free(x);
	free(y);
	free(R);
	free(y_th);
	free(e);
//	fprintf(stderr, "ThisTask=%d, skip=%d, bins=%d, rho=%f, rs=%f, ChiSquare=%lf, Red=%lf\n", 
//		ThisTask, skip, bins, rho0, rs, chi_sq, chi_sq/(bins-skip));
}
Beispiel #2
0
//We only care about rho and rs right now. Gamma is 2.
void compute_error_volume(double g_start, double g_stop, double g_step, Halo * h) {

	int i, j, k;	
	
	//check gamma. Imagine if g_start were 0, g_step were 5, and 
        //g_stop were 17. We wouldn't get all the requested range, so 
	//we would need to adjust g_stop to 20.
	double remainder, g_dist = g_stop - g_start;
	if(g_step > 1) {
		remainder = non_integer_modulus(g_dist, g_step);
		if(remainder != 0) g_dist += (g_step - remainder);
		assert(non_integer_modulus(g_dist, g_step) == 0.0);
	}
	//now the range fits into an integer number of steps
	int gsteps = g_dist / g_step;
	int rhosteps = h->nb;
	int rssteps = h->nb;

	//so alloc a space for it 
	double *** errvol = alloc_data(rhosteps, rssteps, gsteps);
	
	//we'll need to know the degrees of freedom
	double dof = 2; // because we know we're varying rho_0 and rs
	if(g_step != 0) dof++;
	
	//now we need to scan across the ranges and check NFW against
	//the actual density, take the square of the residual, and
	//keep track of the sum of residuals until we get to the end.
	//then handle dof and return.
	//and then fill it with chi squares

	int trigger = 1;
	double best_rs, best_rho_0, best_g, smallest;
	double g, rho_0, rs, r, chi, residual;
	for(i = 0; i < h->nb; i++) { rs = h->radii[i];
	  for(j = 0; j < h->nb; j++) { rho_0 = h->profile[j];
	    for(g = g_start; g < (g_start + g_dist); g += g_step) {
	      chi = 0;
	      for(k = 0; k < h->nb; k++) { r = h->radii[k];
		//compute the residual (actual density - expected)
		residual = h->profile[i] - nfw(rho_0, rs, g, r);
		//square it
		residual = pow(residual, 2);
		//and throw it on the pile
		chi += residual;
	      }
	      //now we want to store the sum in the error volume
	      chi /= (dof - 1);
	      int g_coord = (g - g_start) / g_step;
              errvol[i][j][g_coord] = chi;

	      //we can save some computation time later by tracking the 
	      //smallest value here
	      //let's take the first value to start off with
  	      if(trigger) {
	  	  trigger = 0;
		  smallest = chi;
	      }
	      if(chi < smallest) {
	  	  smallest = chi;
		  best_rs = rs;
		  best_rho_0 = rho_0;
		  best_g = g;
	      }
	    }
  	  }
        }

	if(TEST_MODE) {
		printf("best_g: %f\n", best_g);
/*
		printf("Halo %d\n", h->halo_id);
		printf("Number of bins: %d\n", h->nb);
		printf("best_rs: %f\nbest_rho_0: %f\nbest_g: %f\n",
				best_rs, best_rho_0, best_g);
		printf("Best chi: %f\n\n", smallest);
*/	}
}