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)); }
//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); */ } }