Beispiel #1
0
double
esterror2(double *h, int ind, int max)
{
	int i, s, e, n, lo = 0, hi = 0;
	double error;
	double x[SPLINEN], y[SPLINEN];
	double y2[SPLINEN], u[SPLINEN];

	s = ind - SPLINEN/2;
	if (s < 0)
		s = 0;
	e = ind + SPLINEN/2;
	if (e > max)
		e = max;

	n = 0;
	for (i = s; i <= e && n < SPLINEN; i++) {
		if (i == ind) {
			lo = n - 1;
			hi = n;
			continue;
		}
		x[n] = i;
		y[n] = h[i];
		n++;
	}

	if (hi >= n)
		err(1, "F**K: %d,%d: %d >= %d", s, e, hi, n);

	spline_setup(x, y, n, y2, u);

	error = spline_inter(x, y, y2, n, lo, hi);
	error -= h[ind];

	return (abs(error));
}
long populate_mass_function(char *filename, double Mmin, double Lbox, float **halo_masses,long seed, int nthreads){
	fprintf(stderr,"\tpopulate_mass_function.c V4.0\n");		
	long Npoints,Nshort,Nhalos,i,j;
	double *mass_arr,*mass_inv_arr, *dens_arr, *dens_inv_arr, *y2, d_rand;
	double dens_max;

	if (nthreads<1){
		nthreads = omp_get_max_threads();
	}

	//Reading cumulative mass function
	fprintf(stderr,"\tReading Mass Function... \n");		
	if (read_mass_function(filename,&mass_arr,&dens_arr,&Npoints,Mmin,&Nshort)!=1){
		fprintf(stderr,"ERROR: could not read %s\n",filename);
		return -1;	
	}
	Nshort+=2; //Add 2 points to avoid border effects
	fprintf(stderr,"\t... read\n");		
	srand(seed);
	#ifdef VERB
	fprintf(stderr,"\tSeed used: %ld\n",seed);
	#endif

	//prepare splines for Cumulative density as a funtion of M: n(M)
	y2 = (double *) calloc(Npoints,sizeof(double));

	get_cubic_splines(mass_arr,dens_arr,Npoints,y2);
	
	#ifndef NDENS
	 dens_max = spline_inter(mass_arr,dens_arr,Npoints,y2,Mmin);
	#else
	 dens_max = Mmin;
	#endif

	Nhalos = (long)(dens_max*Lbox*Lbox*Lbox+0.5);	

	fprintf(stderr,"\tNumber of halos: %ld\n",Nhalos);	



	fprintf(stderr,"\tInverting Mass Function... \n");	
	//prepare splines for inverse function M(n)
	mass_inv_arr = (double *) calloc(Nshort,sizeof(double));
	dens_inv_arr = (double *) calloc(Nshort,sizeof(double)); 
	for (i=0;i<Nshort;i++){
		j = Npoints-1-i;
		mass_inv_arr[i]=mass_arr[j];
		dens_inv_arr[i]=dens_arr[j];
	}
	fprintf(stderr,"\t...done!\n");
	*halo_masses = (float *) calloc(Nhalos,sizeof(float));
	get_cubic_splines(dens_inv_arr,mass_inv_arr,Nshort,y2);



	//Generate masses
	fprintf(stderr,"\tGenerating halo masses...\n");	
	#pragma omp parallel for num_threads(nthreads) private(i,d_rand) shared(dens_max,halo_masses,Nhalos,dens_inv_arr,mass_inv_arr,Nshort,y2) default(none)
	for (i=0;i<Nhalos;i++){
		d_rand = (double) rand()*dens_max/RAND_MAX;
		(*halo_masses)[i] = (float) spline_inter(dens_inv_arr,mass_inv_arr,Nshort,y2,d_rand);
	}
	fprintf(stderr,"\t...sorting them...\n");	
	
	qsort(*halo_masses, Nhalos, sizeof(*halo_masses[0]), compare_float);
	
	fprintf(stderr,"\t...done\n");

	return Nhalos;
}