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; }