This commit is contained in:
P.M. Sutter 2014-01-03 19:46:50 -06:00
commit e92d30301b
98 changed files with 22013 additions and 47 deletions

64
c_tools/hod/amoeba.c Normal file
View file

@ -0,0 +1,64 @@
#include <math.h>
#define NRANSI
#include "nrutil.h"
#define NMAX 5000
#define GET_PSUM \
for (j=1;j<=ndim;j++) {\
for (sum=0.0,i=1;i<=mpts;i++) sum += p[i][j];\
psum[j]=sum;}
#define SWAP(a,b) {swap=(a);(a)=(b);(b)=swap;}
void amoeba(double **p, double y[], int ndim, double ftol,
double (*funk)(double []), int *nfunk)
{
double amotry(double **p, double y[], double psum[], int ndim,
double (*funk)(double []), int ihi, double fac);
int i,ihi,ilo,inhi,j,mpts=ndim+1;
double rtol,sum,swap,ysave,ytry,*psum;
psum=dvector(1,ndim);
*nfunk=0;
GET_PSUM
for (;;) {
ilo=1;
ihi = y[1]>y[2] ? (inhi=2,1) : (inhi=1,2);
for (i=1;i<=mpts;i++) {
if (y[i] <= y[ilo]) ilo=i;
if (y[i] > y[ihi]) {
inhi=ihi;
ihi=i;
} else if (y[i] > y[inhi] && i != ihi) inhi=i;
}
rtol=2.0*fabs(y[ihi]-y[ilo])/(fabs(y[ihi])+fabs(y[ilo]));
if (rtol < ftol) {
SWAP(y[1],y[ilo])
for (i=1;i<=ndim;i++) SWAP(p[1][i],p[ilo][i])
break;
}
if (*nfunk >= NMAX) nrerror("NMAX exceeded");
*nfunk += 2;
ytry=amotry(p,y,psum,ndim,funk,ihi,-1.0);
if (ytry <= y[ilo])
ytry=amotry(p,y,psum,ndim,funk,ihi,2.0);
else if (ytry >= y[inhi]) {
ysave=y[ihi];
ytry=amotry(p,y,psum,ndim,funk,ihi,0.5);
if (ytry >= ysave) {
for (i=1;i<=mpts;i++) {
if (i != ilo) {
for (j=1;j<=ndim;j++)
p[i][j]=psum[j]=0.5*(p[i][j]+p[ilo][j]);
y[i]=(*funk)(psum);
}
}
*nfunk += ndim;
GET_PSUM
}
} else --(*nfunk);
}
free_dvector(psum,1,ndim);
}
#undef SWAP
#undef GET_PSUM
#undef NMAX
#undef NRANSI

25
c_tools/hod/amotry.c Normal file
View file

@ -0,0 +1,25 @@
#define NRANSI
#include "nrutil.h"
double amotry(double **p, double y[], double psum[], int ndim,
double (*funk)(double []), int ihi, double fac)
{
int j;
double fac1,fac2,ytry,*ptry;
ptry=dvector(1,ndim);
fac1=(1.0-fac)/ndim;
fac2=fac1-fac;
for (j=1;j<=ndim;j++) ptry[j]=psum[j]*fac1-p[ihi][j]*fac2;
ytry=(*funk)(ptry);
if (ytry < y[ihi]) {
y[ihi]=ytry;
for (j=1;j<=ndim;j++) {
psum[j] += ptry[j]-p[ihi][j];
p[ihi][j]=ptry[j];
}
}
free_dvector(ptry,1,ndim);
return ytry;
}
#undef NRANSI

View file

@ -0,0 +1,301 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
void output_hod(char fname[]);
void output_wp(char fname[]);
double func_find_mone(double m);
double func_find_mone2(double m);
double func_find_alpha(double a);
double fsat_g1;
void aspen_breakout()
{
int i,j,k,i1;
double x1,x2,x3,x4,x5,x6,r,dr,fsat,m1,mcut,mmin,dlogm;
char fname[100];
FILE *fp;
//goto loop_m1;
// goto loop_cvir;
//goto loop_alpha;
//goto loop_mcut2;
/* Vary M_min, find M1 such that fsat is fixed.
*/
OUTPUT=3;
HOD.alpha = 1.0;
for(i=1;i<=5;++i)
{
muh(0);
RESET_FLAG_1H++;
RESET_FLAG_2H++;
RESET_KAISER++;
sprintf(Task.root_filename,"fsat.%d",i);
HOD.M_min = pow(10.0,i+9.0);
HOD.M_cut = 4*HOD.M_min;
if(i==1) {
HOD.M1 = 30*HOD.M_min;
set_HOD_params();
fsat = fsat_g1 = qromo(func_satfrac,log(HOD.M_min),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
fprintf(stderr,"%e %e %e %f %f\n",HOD.M_min,HOD.M1,GALAXY_DENSITY,fsat,HOD.M1/HOD.M_min);
muh(2);
}
set_HOD_params();
HOD.M1 = exp(zbrent(func_find_mone2,log(HOD.M_low/10),log(HOD.M_max),1.0E-4));
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
fprintf(stdout,"MUH %e %e %e %f %f\n",HOD.M_min,HOD.M1,GALAXY_DENSITY,fsat,HOD.M1/HOD.M_min);
sprintf(fname,"fsat_1h.%d",i);
output_wp(fname);
sprintf(fname,"fsat_wp.%d",i);
output_wp(fname);
sprintf(fname,"fsat_hod.%d",i);
output_hod(fname);
}
exit(0);
/* Vary sigma8 at fixed HOD/ngal (so change mmin)
*/
for(i=0;i<=3;++i)
{
SIGMA_8 = 0.9*growthfactor((double)i);
fprintf(stderr,"z=%d, sigma8= %f\n",i,SIGMA_8);
RESET_COSMOLOGY++;
RESET_FLAG_1H++;
RESET_FLAG_2H++;
RESET_KAISER++;
//HOD.M_min = 0;
set_HOD_params();
sprintf(fname,"SIGMA8a.%d",i);
output_wp(fname);
}
exit(0);
SIGMA_8=0.9;
RESET_COSMOLOGY++;
loop_m1:
/* Vary fsat by varying M1
*/
m1 = HOD.M1;
i1 = 0;
for(i=-2;i<=2;++i)
{
HOD.M1 = m1*pow(10.0,i/10.0);
RESET_FLAG_1H++;
RESET_FLAG_2H++;
RESET_KAISER++;
HOD.M_min = HOD.M_low = 0;
set_HOD_params();
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
fprintf(stderr,"M1= %e fsat=%f\n",HOD.M1,fsat);
sprintf(fname,"M1_wp.%d",++i1);
output_wp(fname);
sprintf(fname,"M1_hod.%d",i1);
output_hod(fname);
}
HOD.M1 = m1;
exit(0);
loop_mcut1:
/* Vary M_cut, fix M1 and fsat
*/
mcut = HOD.M_cut;
HOD.M_min = 0;
set_HOD_params();
dlogm = (log(HOD.M1) - log(HOD.M_min))/4;
mmin = log(HOD.M_min);
fsat_g1 = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
i1 = 0;
for(i=0;i<5;++i)
{
HOD.M_cut = exp(dlogm*i+mmin);
HOD.M1 = exp(zbrent(func_find_mone,log(HOD.M_min),log(HOD.M_max),1.0E-4));
RESET_FLAG_1H++;
RESET_FLAG_2H++;
RESET_KAISER++;
HOD.M_min = HOD.M_low = 0;
set_HOD_params();
fprintf(stderr,"M_cut= %e M1= %e %f\n",HOD.M_cut,HOD.M1,HOD.M1/HOD.M_cut);
sprintf(fname,"Mcut1_wp.%d",++i1);
output_wp(fname);
sprintf(fname,"Mcut1_hod.%d",i1);
output_hod(fname);
}
loop_mcut2:
/* Vary M_cut/fsat, keep M_cut/M1 = 1
*/
mcut = 3.0e13;
m1 = 3.0e13;
i1 = 0;
dlogm = (log(3.0e13) - log(10.0e12))/4;
for(i=0;i<5;++i)
{
HOD.M_cut = HOD.M1 = exp(dlogm*i)*10.0e12;
RESET_FLAG_1H++;
RESET_FLAG_2H++;
RESET_KAISER++;
HOD.M_min = HOD.M_low = 0;
set_HOD_params();
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
fprintf(stderr,"M_min= %e M1= %e fsat=%f\n",HOD.M_min,HOD.M1,fsat);
sprintf(fname,"Mcut2_wp.%d",++i1);
output_wp(fname);
sprintf(fname,"Mcut2_hod.%d",i1);
output_hod(fname);
}
loop_alpha:
/* Vary Mcut as above, but fix f_sat by varying alpha
*/
mcut = 3.0e13;
m1 = 3.0e13;
i1 = 0;
mmin = log(6.0e12);
dlogm = (log(3.0e13) - mmin)/4;
HOD.M_cut = HOD.M1 = exp(mmin);
HOD.alpha = 0.1;
HOD.M_min = HOD.M_low = 0;
set_HOD_params();
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
fprintf(stderr,"fsat = %f %e\n",fsat,HOD.M_min);
for(i=0;i<5;++i)
{
HOD.M_cut = HOD.M1 = exp(dlogm*i + mmin);
RESET_FLAG_1H++;
RESET_FLAG_2H++;
RESET_KAISER++;
HOD.alpha = zbrent(func_find_alpha,0.05,2.0,1.0E-4);
fprintf(stderr,"M_cut= %e alpha = %f\n",HOD.M_cut,HOD.alpha);
sprintf(fname,"alpha_wp.%d",++i1);
output_wp(fname);
sprintf(fname,"alpha_hod.%d",i1);
output_hod(fname);
}
loop_cvir:
/* Vary cvir with central one above
*/
HOD.M_cut = HOD.M1 = exp(dlogm*2 + mmin);
HOD.alpha = zbrent(func_find_alpha,0.05,2.0,1.0E-4);
fprintf(stderr,"M_cut= %e alpha = %f\n",HOD.M_cut,HOD.alpha);
i1 = 0;
for(i=0;i<5;++i)
{
CVIR_FAC = pow(3.0,i-2);
RESET_FLAG_1H++;
RESET_FLAG_2H++;
RESET_KAISER++;
sprintf(fname,"cvir_wp.%d",++i1);
output_wp(fname);
sprintf(fname,"cvir_hod.%d",i1);
output_hod(fname);
}
exit(0);
}
double func_find_alpha(double a)
{
HOD.alpha = a;
return qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt) - GALAXY_DENSITY;
}
double func_find_mone(double m)
{
double fsat;
HOD.M1=exp(m);
HOD.M_min = 0;
set_HOD_params();
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
return fsat-fsat_g1;
}
double func_find_mone2(double m)
{
double fsat;
HOD.M1=exp(m);
set_HOD_params();
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
return fsat-fsat_g1;
}
void output_hod(char fname[])
{
FILE *fp;
double dlogm,sig,m;
int i;
fp=fopen(fname,"w");
dlogm=(log(HOD.M_max)-log(HOD.M_low))/99;
for(i=1;i<=100;++i)
{
m=exp((i-1)*dlogm)*HOD.M_low;
sig = N_sat(m)*N_sat(m) + N_cen(m)*(1-N_cen(m));
fprintf(fp,"%e %e %e %e %e %e\n",
m,N_cen(m),N_sat(m),N_avg(m),sig,sig/(N_avg(m)*N_avg(m)));
}
fclose(fp);
}
void output_wp(char fname[])
{
FILE *fp;
double r,dr,x1,x2,x3,x4,x5;
int j;
fp=fopen(fname,"w");
dr=(log(70.0)-log(0.05))/49.0;
for(j=0;j<50;++j)
{
r=exp(j*dr+log(0.05));
x1=one_halo_real_space(r);
x2=two_halo_real_space(r);
x3=projected_xi(r);
//x4 = projected_xi1h(r);
//x5 = projected_xi2h(r);
fprintf(fp,"%f %e %e %e %e\n",r,x1,x2,x1+x2,x3);
fflush(fp);
}
fclose(fp);
}

74
c_tools/hod/brent.c Normal file
View file

@ -0,0 +1,74 @@
#include <math.h>
#define NRANSI
#include "nrutil.h"
#define ITMAX 100
#define CGOLD 0.3819660
#define ZEPS 1.0e-10
#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
double brent(double ax, double bx, double cx, double (*f)(double), double tol,
double *xmin)
{
int iter;
double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
double e=0.0;
a=(ax < cx ? ax : cx);
b=(ax > cx ? ax : cx);
x=w=v=bx;
fw=fv=fx=(*f)(x);
for (iter=1;iter<=ITMAX;iter++) {
xm=0.5*(a+b);
tol2=2.0*(tol1=tol*fabs(x)+ZEPS);
if (fabs(x-xm) <= (tol2-0.5*(b-a))) {
*xmin=x;
return fx;
}
if (fabs(e) > tol1) {
r=(x-w)*(fx-fv);
q=(x-v)*(fx-fw);
p=(x-v)*q-(x-w)*r;
q=2.0*(q-r);
if (q > 0.0) p = -p;
q=fabs(q);
etemp=e;
e=d;
if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x))
d=CGOLD*(e=(x >= xm ? a-x : b-x));
else {
d=p/q;
u=x+d;
if (u-a < tol2 || b-u < tol2)
d=SIGN(tol1,xm-x);
}
} else {
d=CGOLD*(e=(x >= xm ? a-x : b-x));
}
u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d));
fu=(*f)(u);
if (fu <= fx) {
if (u >= x) a=x; else b=x;
SHFT(v,w,x,u)
SHFT(fv,fw,fx,fu)
} else {
if (u < x) a=u; else b=u;
if (fu <= fw || w == x) {
v=w;
w=u;
fv=fw;
fw=fu;
} else if (fu <= fv || v == x || v == w) {
v=u;
fv=fu;
}
}
}
nrerror("Too many iterations in brent");
*xmin=x;
return fx;
}
#undef ITMAX
#undef CGOLD
#undef ZEPS
#undef SHFT
#undef NRANSI

2289
c_tools/hod/buh.c Normal file

File diff suppressed because it is too large Load diff

44
c_tools/hod/chi2_dist.c Normal file
View file

@ -0,0 +1,44 @@
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#define pi 3.14159265358979323846
double nu;
double func(double);
double func_gam(double);
double func_gauss(double);
int main(int argc, char **argv)
{
int i,n;
double x,f,qromo(),midinf(),fgam,midpnt(),fgauss;
nu=2;
if(argc>1)
nu=atof(argv[1]);
fgam = qromo(func_gam,0.0,0.1,midpnt) + qromo(func_gam,0.1,1.0E+30,midinf);
for(i=1;i<=200;++i)
{
x=i/10.0;
f=qromo(func,x,1.0E+30,midinf);
fgauss = 2*qromo(func_gauss,0.0,x,midpnt);
f*=1/(pow(2.0,nu/2.0)*fgam);
printf("%f %e %e\n",x,1-f,fgauss);
}
}
double func(double x)
{
return(pow(x,nu/2-1)*exp(-x/2));
}
double func_gam(double x)
{
return(pow(x,nu/2-1)*exp(-x));
}
double func_gauss(double x)
{
return(exp(-x*x/2)/sqrt(2*pi));
}

124
c_tools/hod/chi2_grid.c Normal file
View file

@ -0,0 +1,124 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
void wp_input(void);
void chi2_grid(int argc, char**argv)
{
int i1,i2,i3,i4,n,nhod = 3,i,j;
double alo[4],ahi[5],*a;
float avector[100][3],chi2,bias,mmin;
FILE *fp;
char fname[100];
/*
* OMEGA_M
* SIGMA_8
* VBIAS
* VBIAS_C
*/
n = 10;
alo[0] = 0.18;
ahi[0] = 0.26;
alo[1] = 0.84;
ahi[1] = 0.94;
alo[2] = 0.5;
ahi[2] = 1.0;
alo[3] = 0.0;
ahi[3] = 0.5;
a = dvector(1,nhod);
wp_input();
if(!ThisTask)
{
sprintf(fname,"%s.grid",Task.root_filename);
fp = fopen(fname,"w");
}
MCMC=1;
for(i3=1;i3<=n;++i3)
{
VBIAS = (i3-1)*(ahi[2] - alo[2])/(n-1) + alo[2];
for(i4=1;i4<=n;++i4)
{
VBIAS_C = (i4-1)*(ahi[3] - alo[3])/(n-1) + alo[3];
RESET_COSMOLOGY++;
one_halo_real_space(1);
two_halo_real_space(1);
a[1] = VBIAS;
a[2] = VBIAS_C;
chi2 = chi2_zspace(a);
if(!ThisTask)
{
printf("GRID %d %d %f %f %e\n",i3,i4,VBIAS,VBIAS_C,chi2);
fprintf(fp,"%d %d %f %f %e\n",i3,i4,VBIAS,VBIAS_C,chi2);
}
}
}
exit(0);
for(i=66;i<=98;++i)
{
sprintf(fname,"xi_%d.fit",i);
fp = openfile(fname);
fscanf(fp,"%e %e %e %e %e %e",&chi2,&mmin,&avector[i][0],&avector[i][1],&avector[i][2],&bias);
fclose(fp);
}
wp.ncf = 3;
for(i1=1;i1<=n;++i1)
{
OMEGA_M = (i1-1)*(ahi[0] - alo[0])/(n-1) + alo[0];
for(i2=1;i2<=n;++i2)
{
SIGMA_8= (i2-1)*(ahi[1] - alo[1])/(n-1) + alo[1];
for(i3=1;i3<=n;++i3)
{
VBIAS = (i3-1)*(ahi[2] - alo[2])/(n-1) + alo[2];
for(i4=1;i4<=n;++i4)
{
VBIAS_C = (i4-1)*(ahi[3] - alo[3])/(n-1) + alo[3];
RESET_COSMOLOGY++;
j = 100.001*SIGMA_8;
a[1] = avector[j][0]*OMEGA_M/0.25;
a[2] = avector[j][1];
a[3] = avector[j][2]*OMEGA_M/0.25;
if(!ThisTask)
{
printf("GOO %f %d %e %e %e\n",SIGMA_8,j,a[1],a[2],a[3]);
fflush(stdout);
}
chi2 = chi2_wp(a);
chi2 += chi2_zspace(a);
if(!ThisTask)
{
printf("GRID %d %d %d %d %f %f %f %f %e\n",i1,i2,i3,i4,OMEGA_M,SIGMA_8,VBIAS,VBIAS_C,chi2);
fprintf(fp,"%d %d %d %d %f %f %f %f %e\n",i1,i2,i3,i4,OMEGA_M,SIGMA_8,VBIAS,VBIAS_C,chi2);
}
}
}
}
}
if(!ThisTask)
fclose(fp);
exit(0);
}

80
c_tools/hod/cisi.c Normal file
View file

@ -0,0 +1,80 @@
#include <math.h>
#include "complex.h"
#define EPS 6.0e-8
#define EULER 0.57721566
#define MAXIT 100
#define PIBY2 1.5707963
#define FPMIN 1.0e-30
#define TMIN 2.0
#define TRUE 1
#define ONE Complex(1.0,0.0)
void cisi(double x, double *ci, double *si)
{
void endrun(char *error_text);
int i,k,odd;
float a,err,fact,sign,sum,sumc,sums,t,term;
fcomplex h,b,c,d,del;
t=fabs(x);
if (t == 0.0) {
*si=0.0;
*ci = -1.0/FPMIN;
return;
}
if (t > TMIN) {
b=Complex(1.0,t);
c=Complex(1.0/FPMIN,0.0);
d=h=Cdiv(ONE,b);
for (i=2;i<=MAXIT;i++) {
a = -(i-1)*(i-1);
b=Cadd(b,Complex(2.0,0.0));
d=Cdiv(ONE,Cadd(RCmul(a,d),b));
c=Cadd(b,Cdiv(Complex(a,0.0),c));
del=Cmul(c,d);
h=Cmul(h,del);
if (fabs(del.r-1.0)+fabs(del.i) < EPS) break;
}
if (i > MAXIT) endrun("cf failed in cisi");
h=Cmul(Complex(cos(t),-sin(t)),h);
*ci = -h.r;
*si=PIBY2+h.i;
} else {
if (t < sqrt(FPMIN)) {
sumc=0.0;
sums=t;
} else {
sum=sums=sumc=0.0;
sign=fact=1.0;
odd=TRUE;
for (k=1;k<=MAXIT;k++) {
fact *= t/k;
term=fact/k;
sum += sign*term;
err=term/fabs(sum);
if (odd) {
sign = -sign;
sums=sum;
sum=sumc;
} else {
sumc=sum;
sum=sums;
}
if (err < EPS) break;
odd=!odd;
}
if (k > MAXIT) endrun("maxits exceeded in cisi");
}
*si=sums;
*ci=sumc+log(t)+EULER;
}
if (x < 0.0) *si = -(*si);
}
#undef EPS
#undef EULER
#undef MAXIT
#undef PIBY2
#undef FPMIN
#undef TMIN
#undef TRUE
#undef ONE

168
c_tools/hod/cobenorm.c Normal file
View file

@ -0,0 +1,168 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* This is the one that Andrew Zentner gave me:
* taken from Bunn, Liddle & White (and appears to
* give different answers from the Bunn & White functions.
*/
double cobenorm(double Om)
{
double Ol, n, f, pwr, g, r=0, d0,
cobe_norm;
n = SPECTRAL_INDX;
Ol = 1 - Om;
f= 0.750 - 0.130*(Ol*Ol);
pwr = -0.8 - 0.05*log(Om);
g = 1.0-0.180*(1.0-n)*Ol - 0.03*r*Ol;
d0 = 1.91e-5*(pow(7.0,((n-1.0)/2.0)));
cobe_norm = d0*(exp(1.010*(1.0-n))/
sqrt(1.0+r*f))*(pow(Om,pwr))*g;
return cobe_norm;
}
/*
Ol = 1.d0-Om
f=0.75d0-0.13d0*(Ol**2.d0)
pwr = -0.8d0 - 0.05d0*log(Om)
g = 1.d0-0.18d0*(1.d0-n)*Ol - 0.03d0*r*Ol
d0 = 1.91d-5*(7.d0**((n-1.d0)/2.d0))
cobe_norm = d0*(exp(1.01d0*(1.d0-n))/
& dsqrt(1.d0+r*f))*(Om**pwr)*g
*/
/* The function below was supplied by Risa Wechsler;
* I set it up to always assume flat universe.
*/
double cobenorm_risa(double omega_m)
/* Return the Bunn & White (1997) fit for delta_H */
/* Given lambda, omega_m, qtensors, and tilt */
/* Open model with tensors is from Hu & White */
{
// cout<<omega_m<<" "<<lambda<<endl;
double n,
// omega_m,
lambda;
int qtensors = 0;
/* n = tilt-1; */
n = SPECTRAL_INDX;
/* omega_m = OMEGA_M; */
lambda = 1-omega_m;
if (fabs(omega_m+lambda-1.0)<1e-5) { /* Flat universe */
if (qtensors)
return 1.94e-5*pow(omega_m, -0.785-0.05*log(omega_m))*
exp(n+1.97*n*n);
else
return 1.94e-5*pow(omega_m, -0.785-0.05*log(omega_m))*
exp(-0.95*n-0.169*n*n);
} else if (fabs(lambda)<1e-5) { /* No lambda */
if (qtensors)
return 1.95e-5*pow(omega_m,-0.35-0.19*log(omega_m)-0.15*n)*
exp(+1.02*n+1.7*n*n);
else return 1.95e-5*pow(omega_m, -0.35-0.19*log(omega_m)-0.17*n)*
exp(-n-0.14*n*n);
} else return 1e-5*(2.422-1.166*exp(omega_m)+0.800*exp(lambda)
+3.780*omega_m-2.267*omega_m*exp(lambda)+0.487*SQR(omega_m)+
0.561*lambda+3.329*lambda*exp(omega_m)-8.568*omega_m*lambda+
1.080*SQR(lambda));
}
/* Read in the cosmo parameters from a completed chain and calculate the chi^2
* of the matter power spectrum
* with respect to the COBE normalization.
*/
double cobe_prior(double omega_m)
{
double pk_model,pk_cobe,chi2;
pk_model = linear_power_spectrum(0.0023/7)/pow(transfnc(0.0023/7),2.0);
pk_cobe = cobenorm(omega_m);
pk_cobe*=pk_cobe;
chi2 = (pk_cobe - pk_model)*(pk_cobe - pk_model)/(0.07*pk_cobe*0.07*pk_cobe);
return chi2;
}
/* Read in the cosmo parameters from a completed chain and calculate the chi^2
* of the matter power spectrum
* with respect to the COBE normalization.
*/
void cobe_prior_from_file(char *filename)
{
FILE *fp;
int n,i,j,k,i1,i2,ip=0;
float xx[10];
char aa[4];
double pk_model,pk_cobe,chi2,pnorm,p2,xk;
double pka[20][41];
fp = openfile(filename);
n = filesize(fp);
for(i=1;i<=n;++i)
{
fscanf(fp,"%4s %d %d",aa,&i1,&i2);
for(j=0;j<10;++j)fscanf(fp,"%f",&xx[j]);
SIGMA_8 = xx[6];
SPECTRAL_INDX = xx[7];
OMEGA_TEMP = xx[5];
RESET_COSMOLOGY++;
pk_model = linear_power_spectrum(0.0023/7)/pow(transfnc(0.0023/7),2.0);
pk_cobe = cobenorm(OMEGA_TEMP)*cobenorm(OMEGA_TEMP);
chi2 = (pk_cobe - pk_model)*(pk_cobe - pk_model)/(0.07*pk_cobe*0.07*pk_cobe);
printf("%d %e %e %e %f %f %f\n",
i1,pk_model,pk_cobe,chi2,SIGMA_8,SPECTRAL_INDX,OMEGA_TEMP);
fflush(stdout);
if(i%(n/20)==0 && ip<20) {
for(k=0,j=-40;j<=0;++j)
{
xk = pow(10.0,j/10.0);
pka[ip][k] = linear_power_spectrum(xk)/(xk*xk*xk)*2*PI*PI;
k++;
}
ip++;
}
}
for(i=0;i<=41;++i)
{
printf("BOO %f ",(i-40)/10.0);
for(j=0;j<20;++j)
printf("%e ",pka[j][i]);
printf("\n");
}
exit(0);
}

488
c_tools/hod/color_samples.c Normal file
View file

@ -0,0 +1,488 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* This file contains routines to fit a red/blue color-selected sample.
* It does a simultaneous fit to the red, blue, and all samples. It basically
* acts as a wrapper around the normal wp_minimization routines.
*/
void initial_color_values(double *a, double **pp, double *yy);
void wp_input(void);
void wp_color_input(void);
double chi2_wp_color(double *a);
double dd_func_red_fraction(double x);
/* external functions
*/
void mcmc_color_minimization(void);
void fit_color_samples()
{
int n,niter,i,j;
double *a,**pp,*yy,FTOL=1.0E-3,chi2min,s1,dlogm,m;
FILE *fp;
char aa[1000];
mcmc_color_minimization();
fprintf(stderr,"\n\nCHI2 MINIMIZATION OF W_P(R_P) COLOR DATA..........\n");
fprintf(stderr, "--------------------------------------------\n\n");
HOD.blue_fraction = 0.5857; /* <- Millenium fraction (sloan);; SDSS fraction -> 0.565; */
HOD.blue_fraction = 0.6555; /* <- Millenium fraction (B-V>0.8) */
HOD.blue_fraction = 0.565; /* SDSS -19,-20 */
HOD.blue_fraction = 0.492; /* SDSS -20,-21 */
HOD.blue_fraction = 0.379; /* SDSS -21 */
wp_color.ON = 1;
if(POWELL)
FTOL=1.0E-3;
else
FTOL=1.0E-5;
for(n=0,i=1;i<=7;++i)
{
n+=HOD.free[i];
if(!OUTPUT)continue;
printf("wp_min> free[%i] = %d\n",i,HOD.free[i]);
}
/* The parameters that govern the blue fraction aren't
* listed in the HOD.free array, so add them in.
* NB: There are four parameters for these two functions,
* one of which is fit by the number densities.
*/
n+=3;
if(OUTPUT)printf("wp_min> Number of free parameters: %d\n",n);
wp_color_input();
wp.ncf=n;
a=dvector(1,n);
if(POWELL)
pp=dmatrix(1,n,1,n);
else
pp=dmatrix(1,n+1,1,n);
yy=dvector(1,n+1);
initial_color_values(a,pp,yy);
if(POWELL)
{
if(OUTPUT)printf("wp_min> starting powell.\n");
powell(a,pp,n,FTOL,&niter,&chi2min,chi2_wp_color);
chi2min = chi2_wp_color(a);
}
else
{
if(OUTPUT)printf("wp_min> starting amoeba.\n");
amoeba(pp,yy,n,FTOL,chi2_wp_color,&niter);
for(i=1;i<=n;++i)a[i]=pp[1][i];
chi2min = chi2_wp_color(a);
}
s1=qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt);
GALAXY_BIAS=s1/GALAXY_DENSITY;
printf("POWELL %e %e %e ",chi2min,HOD.M_min,HOD.fblue0_cen);
if(HOD.pdfc==7)
printf("%e ",HOD.M_cen_max);
for(i=1;i<=n;++i)printf("%e ",a[i]);
printf(" %f\n",GALAXY_BIAS);
/* Output the fit and the HOD curve.
*/
sprintf(aa,"%s.fit",Task.root_filename);
fp=fopen(aa,"w");
fprintf(fp,"%e %e %e ",chi2min,HOD.M_min,HOD.fblue0_cen);
if(HOD.pdfc==7)
fprintf(fp,"%e ",HOD.M_cen_max);
for(i=1;i<=n;++i)fprintf(fp,"%e ",a[i]);
fprintf(fp," %f\n",GALAXY_BIAS);
fclose(fp);
sprintf(aa,"%s.HOD",Task.root_filename);
fp=fopen(aa,"w");
dlogm=(log(HOD.M_max)-log(HOD.M_low))/99;
for(i=1;i<=100;++i)
{
m=exp((i-1)*dlogm)*HOD.M_low;
fprintf(fp,"%e %e %e %e\n",m,N_cen(m),N_sat(m),N_avg(m));
}
fclose(fp);
}
double chi2_wp_color(double *a)
{
double chi2,nsat_blue,ncen_blue,dlogm,m,func_blue_fraction(),temp1,temp2,fsat_blue,fsat_red,fsat_all;
int i,j;
static int iter=0;
COVAR = 0;
HOD.color = 0;
GALAXY_DENSITY2 = GALAXY_DENSITY = wp_color.ngal_full;
wp.np = wp_color.n_full;
for(i=wp.ncf-2;i<=wp.ncf;++i)
if(a[i]<0)return(1.0e+7);
for(i=1;i<=wp.np;++i)
{
wp.r[i] = wp_color.r_full[i];
wp.x[i] = wp_color.x_full[i];
wp.e[i] = wp_color.e_full[i];
for(j=1;j<=wp.np;++j)
wp.covar[i][j] = wp_color.covar_full[i][j];
}
chi2 = chi2_wp(a);
HOD.M_low0 = set_low_mass();
fsat_all = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
/*
dlogm=(log(HOD.M_max)-log(HOD.M_low))/99;
for(i=1;i<=100;++i)
{
m=exp((i-1)*dlogm)*HOD.M_low;
printf("HODFULL %e %f %f %f\n",m,N_cen(m)+N_sat(m),N_cen(m),N_sat(m));
}
printf("GALDEN FULL %e\n",qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt));
sprintf(Task.root_filename,"gal_full");
populate_simulation();
*/
if(!iter)
for(i=1;i<=wp.np;++i)
for(j=1;j<=wp.np;++j)
wp_color.covar_full[i][j] = wp.covar[i][j];
HOD.fblue0_sat = a[wp.ncf - 2];
HOD.sigma_fblue_sat = a[wp.ncf - 1];
HOD.sigma_fblue_cen = a[wp.ncf - 0];
HOD.fblue0_cen = 1.0;
HOD.color = 1;
HOD.fblue0_cen = pow(10.0,zbrent(func_blue_fraction,-5.0,1.0,1.0E-5));
if(OUTPUT)
fprintf(stdout,"old fblue0_cen= %e %e\n",HOD.fblue0_cen,HOD.M_min);
if(DENSITY_DEPENDENCE)
{
HOD.color = 2;
temp1 = HOD.M_min;
temp2 = HOD.M_low;
populate_simulation();
HOD.M_min = temp1;
HOD.M_low = temp2;
HOD.fblue0_cen = pow(10.0,zbrent(dd_func_red_fraction,-5.0,1.0,1.0E-5));
HOD.color = 1;
if(OUTPUT)
fprintf(stdout,"new fblue0_cen= %e %e\n",HOD.fblue0_cen,
(1. - HOD.M_min_fac*(1.0 - HOD.fblue0_cen)));
// populate_simulation();
//exit(0);
}
else
HOD.fblue0_cen = pow(10.0,zbrent(func_blue_fraction,-5.0,1.0,1.0E-5));
if(ERROR_FLAG)
{
ERROR_FLAG=0;
return(1.0e7);
}
/* This is only if you have square functions for the central occupation
*/
/*
nsat_blue = qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt);
ncen_blue = qromo(func_central_density,log(HOD.M_low),log(HOD.M_cen_max),midpnt);
HOD.fblue0_cen = (wp_color.ngal_blue - nsat_blue)/ncen_blue;
*/
GALAXY_DENSITY2 = GALAXY_DENSITY = wp_color.ngal_blue;
wp.np = wp_color.n_blue;
for(i=1;i<=wp.np;++i)
{
wp.r[i] = wp_color.r_blue[i];
wp.x[i] = wp_color.x_blue[i];
wp.e[i] = wp_color.e_blue[i];
for(j=1;j<=wp.np;++j)
wp.covar[i][j] = wp_color.covar_blue[i][j];
}
chi2 += chi2_wp(a);
fsat_blue = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
/*
dlogm=(log(HOD.M_max)-log(HOD.M_low))/99;
for(i=1;i<=100;++i)
{
m=exp((i-1)*dlogm)*HOD.M_low;
printf("HODBLUE %e %f %f %f\n",m,N_cen(m)+N_sat(m),N_cen(m),N_sat(m));
}
printf("GALDEN BLUE %e\n",qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt));
sprintf(Task.root_filename,"gal_blue");
populate_simulation();
*/
if(!iter)
for(i=1;i<=wp.np;++i)
for(j=1;j<=wp.np;++j)
wp_color.covar_blue[i][j] = wp.covar[i][j];
HOD.color = 2;
GALAXY_DENSITY2 = GALAXY_DENSITY = wp_color.ngal_red;
wp.np = wp_color.n_red;
for(i=1;i<=wp.np;++i)
{
wp.r[i] = wp_color.r_red[i];
wp.x[i] = wp_color.x_red[i];
wp.e[i] = wp_color.e_red[i];
for(j=1;j<=wp.np;++j)
wp.covar[i][j] = wp_color.covar_red[i][j];
}
chi2 += chi2_wp(a);
fsat_red = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
/*
dlogm=(log(HOD.M_max)-log(HOD.M_low))/99;
for(i=1;i<=100;++i)
{
m=exp((i-1)*dlogm)*HOD.M_low;
printf("HODRED %e %f %f %f\n",m,N_cen(m)+N_sat(m),N_cen(m),N_sat(m));
}
printf("GALDEN RED %e\n",qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt));
sprintf(Task.root_filename,"gal_red");
populate_simulation();
exit(0);
*/
if(!iter)
for(i=1;i<=wp.np;++i)
for(j=1;j<=wp.np;++j)
wp_color.covar_red[i][j] = wp.covar[i][j];
iter++;
wp.fsat_all = fsat_all;
wp.fsat_red = fsat_red;
wp.fsat_blue = fsat_blue;
printf("COLOR_PARAMS %d %e %e %e %e %e %e %e %e\n",iter,chi2,HOD.M_min,HOD.M1,HOD.alpha,HOD.fblue0_cen,HOD.fblue0_sat,HOD.sigma_fblue_cen,HOD.sigma_fblue_sat);
printf("COLOR_ITER %d %e %e %f %f %f\n",iter,chi2,HOD.fblue0_cen,fsat_all,fsat_blue,fsat_red);
fflush(stdout);
return(chi2);
}
double func_blue_fraction(double x)
{
double n;
HOD.fblue0_cen=pow(10.0,x);
n = qtrap(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),1.0E-4);
//printf("%f %e %e %e %e\n",HOD.fblue0_cen,n,wp_color.ngal_blue,central_blue_fraction(HOD.M_min),HOD.M_low);
return n - wp_color.ngal_blue;
}
void initial_color_values(double *a, double **pp, double *yy)
{
static int flag=0;
int i,j;
double d[100];
COVAR=0;
if(!flag) {
i=0;j=0;
if(HOD.free[++i])a[++j]=HOD.M_min;
if(HOD.free[++i])a[++j]=HOD.M1;
if(HOD.free[++i])a[++j]=HOD.alpha;
if(HOD.free[++i])a[++j]=HOD.M_cut;
if(HOD.free[++i])a[++j]=HOD.sigma_logM;
if(HOD.free[++i])a[++j]=CVIR_FAC;
if(HOD.pdfc>=7){
if(HOD.free[++i])a[++j]=HOD.M_cen_max; }
else {
if(HOD.free[++i])a[++j]=HOD.MaxCen; }
a[++j] = HOD.fblue0_sat;
a[++j] = HOD.sigma_fblue_sat;
a[++j] = HOD.sigma_fblue_cen;
printf("INITIAL VALUES: ");
for(i=1;i<=wp.ncf;++i)printf("%e ",a[i]);
printf("\n");
}
flag++;
/* Make the starting stepsize 10% of the initial values.
*/
for(i=1;i<=wp.ncf;++i)
d[i]=a[i]*0.25/flag;
if(POWELL)
{
for(i=1;i<=wp.ncf;++i)
{
for(j=1;j<=wp.ncf;++j)
{
pp[i][j]=0;
if(i==j)pp[i][j]+=d[j];
}
}
}
else
{
for(j=1;j<=wp.ncf;++j)
pp[1][j]=a[j];
yy[1]=chi2_wp_color(a);
for(i=1;i<=wp.ncf;++i)
{
a[i]+=d[i];
if(i>1)a[i-1]-=d[i-1];
for(j=1;j<=wp.ncf;++j)
yy[i+1]=chi2_wp_color(a);
pp[i+1][j]=a[j];
}
a[wp.ncf]-=d[wp.ncf];
}
}
void wp_color_input()
{
float x1,x2,x3;
FILE *fp;
int i,j,n=11;
char a[1000],b[1000];
/* The first call to wp_input() will be the standard full sample.
*/
wp_input();
/* Put the data into the wp_color arrays
*/
wp_color.r_full = dvector(1,wp.np);
wp_color.x_full = dvector(1,wp.np);
wp_color.e_full = dvector(1,wp.np);
wp_color.covar_full = dmatrix(1,wp.np,1,wp.np);
wp_color.n_full = wp.np;
if(wp.np>n)wp_color.n_full = n;
wp_color.ngal_full = GALAXY_DENSITY;
for(i=1;i<=wp.np;++i)
{
wp_color.r_full[i] = wp.r[i];
wp_color.x_full[i] = wp.x[i];
wp_color.e_full[i] = wp.e[i];
for(j=1;j<=wp.np;++j)
wp_color.covar_full[i][j] = wp.covar[i][j];
}
free_dvector(wp.r,1,wp.np);
free_dvector(wp.x,1,wp.np);
free_dvector(wp.e,1,wp.np);
free_dmatrix(wp.covar,1,wp.np,1,wp.np);
/* The second call is the blue sample.
*/
sprintf(a,"%s",wp.fname_wp);
sprintf(b,"%s",wp.fname_covar);
sprintf(wp.fname_wp,"%s_blue",a);
sprintf(wp.fname_covar,"%s_blue",b);
wp_input();
wp_color.r_blue = dvector(1,wp.np);
wp_color.x_blue = dvector(1,wp.np);
wp_color.e_blue = dvector(1,wp.np);
wp_color.covar_blue = dmatrix(1,wp.np,1,wp.np);
wp_color.n_blue = wp.np;
if(wp.np>n)wp_color.n_blue = n;
wp_color.ngal_blue = GALAXY_DENSITY*HOD.blue_fraction;
for(i=1;i<=wp.np;++i)
{
wp_color.r_blue[i] = wp.r[i];
wp_color.x_blue[i] = wp.x[i];
wp_color.e_blue[i] = wp.e[i];
for(j=1;j<=wp.np;++j)
wp_color.covar_blue[i][j] = wp.covar[i][j];
}
free_dvector(wp.r,1,wp.np);
free_dvector(wp.x,1,wp.np);
free_dvector(wp.e,1,wp.np);
free_dmatrix(wp.covar,1,wp.np,1,wp.np);
/* The third call is the red sample.
*/
sprintf(wp.fname_wp,"%s_red",a);
sprintf(wp.fname_covar,"%s_red",b);
wp_input();
wp_color.r_red = dvector(1,wp.np);
wp_color.x_red = dvector(1,wp.np);
wp_color.e_red = dvector(1,wp.np);
wp_color.covar_red = dmatrix(1,wp.np,1,wp.np);
wp_color.n_red = wp.np;
if(wp.np>n)wp_color.n_red = n;
wp_color.ngal_red = GALAXY_DENSITY*(1-HOD.blue_fraction);
for(i=1;i<=wp.np;++i)
{
wp_color.r_red[i] = wp.r[i];
wp_color.x_red[i] = wp.x[i];
wp_color.e_red[i] = wp.e[i];
for(j=1;j<=wp.np;++j)
wp_color.covar_red[i][j] = wp.covar[i][j];
}
free_dvector(wp.r,1,wp.np);
free_dvector(wp.x,1,wp.np);
free_dvector(wp.e,1,wp.np);
free_dmatrix(wp.covar,1,wp.np,1,wp.np);
/* Open permanent arrays that are larger than any individual array in
* the color sequence.
*/
wp.r = dvector(1,15);
wp.x = dvector(1,15);
wp.e = dvector(1,15);
wp.covar = dmatrix(1,15,1,15);
}
/*
double N_cen_blue(double m)
{
if(m<HOD.M_low)return(0);
x = (log10(m) - log10(HOD.M_min_blue))/HOD.sigma_logM_blue;
return(HOD.MaxCen_blue*exp(-x*x/2));
}
double N_cen_red(double m)
{
if(m<HOD.M_low)return(0);
x = (log10(m) - log10(HOD.M_min_red))/HOD.sigma_logM_red;
return(HOD.MaxCen_red*exp(-x*x/2));
}
*/

125
c_tools/hod/complex.c Normal file
View file

@ -0,0 +1,125 @@
/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
utility file complex.c. Do not confuse this file with the same-named
file complex.c that is supplied in the 'misc' subdirectory.
*That* file is the one from the book, and contains both ANSI and
traditional K&R versions, along with #ifdef macros to select the
correct version. *This* file contains only ANSI C. */
#include <math.h>
typedef struct FCOMPLEX {float r,i;} fcomplex;
fcomplex Cadd(fcomplex a, fcomplex b)
{
fcomplex c;
c.r=a.r+b.r;
c.i=a.i+b.i;
return c;
}
fcomplex Csub(fcomplex a, fcomplex b)
{
fcomplex c;
c.r=a.r-b.r;
c.i=a.i-b.i;
return c;
}
fcomplex Cmul(fcomplex a, fcomplex b)
{
fcomplex c;
c.r=a.r*b.r-a.i*b.i;
c.i=a.i*b.r+a.r*b.i;
return c;
}
fcomplex Complex(float re, float im)
{
fcomplex c;
c.r=re;
c.i=im;
return c;
}
fcomplex Conjg(fcomplex z)
{
fcomplex c;
c.r=z.r;
c.i = -z.i;
return c;
}
fcomplex Cdiv(fcomplex a, fcomplex b)
{
fcomplex c;
float r,den;
if (fabs(b.r) >= fabs(b.i)) {
r=b.i/b.r;
den=b.r+r*b.i;
c.r=(a.r+r*a.i)/den;
c.i=(a.i-r*a.r)/den;
} else {
r=b.r/b.i;
den=b.i+r*b.r;
c.r=(a.r*r+a.i)/den;
c.i=(a.i*r-a.r)/den;
}
return c;
}
float Cabs(fcomplex z)
{
float x,y,ans,temp;
x=fabs(z.r);
y=fabs(z.i);
if (x == 0.0)
ans=y;
else if (y == 0.0)
ans=x;
else if (x > y) {
temp=y/x;
ans=x*sqrt(1.0+temp*temp);
} else {
temp=x/y;
ans=y*sqrt(1.0+temp*temp);
}
return ans;
}
fcomplex Csqrt(fcomplex z)
{
fcomplex c;
float x,y,w,r;
if ((z.r == 0.0) && (z.i == 0.0)) {
c.r=0.0;
c.i=0.0;
return c;
} else {
x=fabs(z.r);
y=fabs(z.i);
if (x >= y) {
r=y/x;
w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r)));
} else {
r=x/y;
w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r)));
}
if (z.r >= 0.0) {
c.r=w;
c.i=z.i/(2.0*w);
} else {
c.i=(z.i >= 0) ? w : -w;
c.r=z.i/(2.0*c.i);
}
return c;
}
}
fcomplex RCmul(float x, fcomplex a)
{
fcomplex c;
c.r=x*a.r;
c.i=x*a.i;
return c;
}

26
c_tools/hod/complex.h Normal file
View file

@ -0,0 +1,26 @@
/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
utility file complex.h. Do not confuse this file with the same-named
file complex.h that is supplied in the 'misc' subdirectory.
*That* file is the one from the book, and contains both ANSI and
traditional K&R versions, along with #ifdef macros to select the
correct version. *This* file contains only ANSI C. */
#ifndef _NR_COMPLEX_H_
#define _NR_COMPLEX_H_
#ifndef _FCOMPLEX_DECLARE_T_
typedef struct FCOMPLEX {float r,i;} fcomplex;
#define _FCOMPLEX_DECLARE_T_
#endif /* _FCOMPLEX_DECLARE_T_ */
fcomplex Cadd(fcomplex a, fcomplex b);
fcomplex Csub(fcomplex a, fcomplex b);
fcomplex Cmul(fcomplex a, fcomplex b);
fcomplex Complex(float re, float im);
fcomplex Conjg(fcomplex z);
fcomplex Cdiv(fcomplex a, fcomplex b);
float Cabs(fcomplex z);
fcomplex Csqrt(fcomplex z);
fcomplex RCmul(float x, fcomplex a);
#endif /* _NR_COMPLEX_H_ */

114
c_tools/hod/covar_test.c Normal file
View file

@ -0,0 +1,114 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
void covar_test()
{
int i,j,k,n,nd=2,nrot;
float x[5],x1,x2,x3,x4,x0;
double **cov,**tmp,*avg,**tmp1,*eval,**evect,*a,*atemp;
FILE *fp;
fp = openfile("acc.out");
n = filesize(fp);
a = dvector(1,nd);
atemp = dvector(1,nd);
cov = dmatrix(1,nd,1,nd);
evect = dmatrix(1,nd,1,nd);
avg = dvector(1,nd);
eval = dvector(1,nd);
tmp = dmatrix(1,nd,1,nd);
tmp1 = dmatrix(1,nd,1,1);
for(j=1;j<=nd;++j)
{
avg[j] = 0;
tmp1[j][1] = 0;
for(k=1;k<=nd;++k)
cov[j][k] = 0;
}
for(i=1;i<=n;++i)
{
fscanf(fp,"%f %d %f %f %f %f",&x0,&j,&x[1],&x[2],&x[3],&x[4]);
x[1] = log(x[1]);
x[3] = log(x[3]);
x[4] = log(x[4]);
for(j=1;j<=nd;++j)
{
avg[j] += x[j];
for(k=1;k<=nd;++k)
cov[j][k] += x[j]*x[k];
}
}
for(j=1;j<=nd;++j)
for(k=1;k<=nd;++k)
cov[j][k] = cov[j][k]/n - avg[j]*avg[k]/(n*n);
for(j=1;j<=nd;++j)
{
printf("cov %d> ",j);
for(k=1;k<=nd;++k)
printf("%f ",cov[j][k]);
printf("\n");
}
printf("\n");
n = nd;
jacobi(cov,n,eval,evect,&nrot);
for(j=1;j<=nd;++j)
{
printf("jac %d> ",j);
for(k=1;k<=nd;++k)
printf("%f ",evect[j][k]);
printf("\n");
}
printf("\n");
for(k=1;k<=nd;++k)
printf("%f ",eval[k]);
printf(" %d \n",nrot);
printf("\n");
gaussj(evect,n,tmp1,1);
for(j=1;j<=nd;++j)
{
printf("gj %d> ",j);
for(k=1;k<=nd;++k)
printf("%f ",evect[j][k]);
printf("\n");
}
printf("\n");
for(i=1;i<=n;++i)
atemp[i] = sqrt(eval[i]);
for(i=1;i<=n;++i)
for(a[i]=0,j=1;j<=n;++j)
a[i] += atemp[j]*evect[j][i];
for(k=1;k<=nd;++k)
printf("%f ",a[k]);
printf("\n\n");
exit(0);
}

157
c_tools/hod/dFdx.c Normal file
View file

@ -0,0 +1,157 @@
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "header.h"
/** halo pair separation profile for halo with concentration c_NFW
[satellite-satellite]
x=r/(2*R_vir) 0<=x<=1
analytic solution of Sheth et al (2001) MNRAS 325, 1288 (eq.A25)
dF/dx \propto \lambda(r)*r^2
normalized so that \int_0^1 dF/dx dx =1
The normalization factor in this subroutine is obtained from my
fitting formula, which has a fractional error less than 0.2% for
c_NFW in the range ~1 to ~100. The formula is basically a double
powerlaw with a smooth transition and the residuals are further
reduced with a (1+sine) function.
**/
double dFdx_ss(double x, double c_NFW)
{
double f,y,a,Anorm;
double A0=4.915,alpha=-3.099,beta=0.617,cNFWc=1.651,mu=4.706;
double B0=0.0336,omega=2.684,phi=0.4079;
/** above are parameters in fitting formula of the normalization **/
double t;
double t1,t2,t3,ta;
if(x<=0.0 || x>=1.0) return 0.0;
a=1.0/c_NFW;
y=2.0*c_NFW*x;
if(x<0.5)
{
f=(-4.0*(1.0+a)+2.0*a*y*(1.0+2.0*a)+a*a*y*y)/(2.0*(1.0+a)*(1.0+a)*(2.0+y));
f=f+log(fabs((1.0+a-a*y)*(1.0+y))/(1.0+a))/y+y*log(1.0+y)/(2.0+y)/(2.0+y);
}
else
{
f=y*log((1.0+a)/fabs(a*y+a-1))/(2.0+y)/(2.0+y);
f=f+0.5*y*(a*a*y-2.0*a)/(1.0+a)/(1.0+a)/(2.0+y);
}
/** get the normalization factor from a fitting formula **/
t=pow(c_NFW/cNFWc,(beta-alpha)/mu);
Anorm=A0*pow(c_NFW,alpha)*pow(1.0+t,mu)*(1.0+B0*sin(omega*(log10(c_NFW)-phi)));
return Anorm*f;
}
/** [central-satellite] i.e. the NFW profile rho(r)*r^2
x=r/(2*R_vir)
**/
double dFdx_cs(double x, double c_NFW)
{
double f,A,y;
if(x>0.5) return 0.0;
else {
y=1.0+2.0*c_NFW*x;
f=x/(y*y);
A=(log(1.0+c_NFW)-c_NFW/(1.0+c_NFW))/(4.0*c_NFW*c_NFW);
return f/A;
}
}
/* The redshift-space one-halo term spends the majority of its time
* calculating NFW pair densities for sat-sat pairs. To speed up
* the calculation, this tabulates the values of dFdx_ss on a grid
* for bilinear interpolation.
*
* In tests, accuracy is usually about 1E-5, and at worst 1E-3.
*/
double dFdx_ss_interp(double r, double c)
{
static int flag=0,reset=0;
static double **x;
static double clo,dlogc,chi;
int nx=2000, nc=100, i,j,ir,ic;
double c_nfw,x1,x2,x3,c_fac=2;
if(!flag)
{
x=dmatrix(0,nc,1,nx);
flag=1;
if(OUTPUT)
fprintf(stdout,"dFdx_ss_interp> Tabulating dFdx_ss...\n");
clo = 0.1;
chi = 1000.0;
dlogc = (log(chi)-log(clo))/(nc-1);
for(j=1;j<=nx;++j)
x[0][j]=0;
for(i=1;i<=nc;++i)
{
c_nfw=exp((i-1)*dlogc)*clo;
for(j=1;j<=nx;++j) {
x[i][j]=dFdx_ss((double)j/nx,c_nfw); }
}
if(OUTPUT)
fprintf(stdout,"dFdx_ss_interp> ...Finished.\n");
}
r*=nx;
c_fac = log(c/clo)/dlogc+1;
ir=(int)r;
ic=(int)c_fac;
if(ic==0)ic++;
if(ic==nc)ic--;
if(ic==0 || ic>=nc) {
printf("%f %f %f %d\n",r/nx,c,c_fac,ic);
endrun("dFdx error"); }
x1=(x[ic][ir+1]-x[ic][ir])*(r-ir)+x[ic][ir];
x2=(x[ic+1][ir+1]-x[ic+1][ir])*(r-ir)+x[ic+1][ir];
return((x2-x1)*(c_fac-ic)+x1);
}
/* Well, it looks like it really doesn't help much of anything to tabulate
* the central-satellite function (which isn't too surprising since the number
* of computations isn't very large). But the above one seems to do very well.
*/
double dFdx_cs_interp(double r, double c)
{
static int flag=0;
static double **x;
int nx=1000, nc=19, i,j,ir,ic;
double c_nfw,x1,x2,x3;
if(r>0.5)return(0);
if(!flag++)
{
fprintf(stderr,"Tabulating dFdx_cs...\n");
x=dmatrix(0,nc,1,nx);
for(i=1;i<=nc;++i)
{
c_nfw=i;
x[0][j]=0;
for(j=1;j<=nx;++j)
x[i][j]=dFdx_cs((double)j/nx,c_nfw);
fprintf(stderr,"%d\n",i);
}
fprintf(stderr,"Finished.\n");
}
r*=nx;
ir=(int)r;
ic=(int)c;
if(ic==0 || ic>=nc)
endrun("dFdx error");
x1=(x[ic][ir+1]-x[ic][ir])*(r-ir)+x[ic][ir];
x2=(x[ic+1][ir+1]-x[ic+1][ir])*(r-ir)+x[ic+1][ir];
return((x2-x1)*(c-ic)+x1);
}

View file

@ -0,0 +1,161 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "header.h"
void output_matter_power_spectrum()
{
int k;
double dlogk,xk,plin,pnl;
FILE *fp;
char aa[100];
fprintf(stderr,"\n\nCALCULATING MATTER POWER SPECTRA.\n");
fprintf(stderr, "---------------------------------\n\n");
sprintf(aa,"%s.matter_pk",Task.root_filename);
fp = fopen(aa,"w");
for(k=-300;k<=100;++k)
{
xk=pow(10.0,k/100.0);
plin = linear_power_spectrum(xk)/(xk*xk*xk)*TWOPI*PI;
pnl = nonlinear_power_spectrum(xk)/(xk*xk*xk)*TWOPI*PI;
fprintf(fp,"%e %e %e\n",xk,plin,pnl);
}
fclose(fp);
}
void output_matter_correlation_function()
{
int k,nr=50;
double dlogr,r,xlin,xnl,rmin = 0.05,rmax = 80.0;
FILE *fp;
char aa[100];
fprintf(stderr,"\n\nCALCULATING MATTER CORRELATION FUNCTIONIONS.\n");
fprintf(stderr, "--------------------------------------------\n\n");
sprintf(aa,"%s.matter_xi",Task.root_filename);
fp = fopen(aa,"w");
dlogr = (log(rmax) - log(rmin))/(nr-1);
for(k=0;k<nr;++k)
{
r = exp(k*dlogr)*rmin;
xlin = xi_linear_interp(r);
xnl = xi_interp(r);
fprintf(fp,"%e %e %e\n",r,xlin,xnl);
}
fclose(fp);
}
void output_halo_correlation_function(double mass)
{
int k,nr=50;
double dlogr,r,xlin,xnl,rmin = 0.15,rmax = 40.0;
FILE *fp;
char aa[100];
fprintf(stderr,"\n\nCALCULATING HALO CORRELATION FUNCTIONION (M=%.2e)\n",mass);
fprintf(stderr, "-------------------------------------------------\n\n");
sprintf(aa,"%s.halo_xi",Task.root_filename);
fp = fopen(aa,"w");
rmin = pow(3*mass/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),THIRD);
dlogr = (log(rmax) - log(rmin))/(nr-1);
for(k=0;k<nr;++k)
{
r = exp(k*dlogr)*rmin;
xlin = bias_interp(mass,r);
xnl = xi_interp(r);
fprintf(fp,"%e %e\n",r,xnl*xlin*xlin);
}
fclose(fp);
}
void output_matter_variance()
{
int k,nr=50;
double dlogr,r,slin,snl,mass,rmin = 0.05,rmax = 80.0,pnorm,pnorm_nl;
FILE *fp;
char aa[100];
fprintf(stderr,"\n\nCALCULATING MATTER VARIANCE.\n");
fprintf(stderr, "----------------------------\n\n");
sprintf(aa,"%s.sigma_r",Task.root_filename);
fp = fopen(aa,"w");
dlogr = (log(rmax) - log(rmin))/(nr-1);
pnorm = SIGMA_8/sigmac(8.0);
pnorm_nl = pnorm*sigmac(80.0)/nonlinear_sigmac(80.0);
for(k=0;k<nr;++k)
{
r = exp(k*dlogr)*rmin;
mass = 4./3.*PI*r*r*r*RHO_CRIT*OMEGA_M;
slin = sigmac(r)*pnorm;
snl = nonlinear_sigmac(r)*pnorm_nl;
fprintf(fp,"%e %e %e %e\n",r,slin,snl,mass);
}
fclose(fp);
}
void output_halo_concentrations()
{
int k,nr=100;
double x,dlogm,m,mvir,cdelta,mmin=1e8,mmax=1e16,delta_vir;
FILE *fp;
char aa[100];
fprintf(stderr,"\n\nCALCULATING HALO CONCENTRATIONS.\n");
fprintf(stderr, "--------------------------------\n\n");
sprintf(aa,"%s.cvir",Task.root_filename);
fp = fopen(aa,"w");
dlogm = (log(mmax) - log(mmin))/(nr-1);
x=OMEGA_M-1;
delta_vir=(18*PI*PI+82*x-39*x*x)/(1+x);
for(k=0;k<nr;++k)
{
m = exp(k*dlogm)*mmin;
cdelta = halo_concentration(m);
fprintf(fp,"%e %e\n",m,cdelta);
}
fclose(fp);
}
void output_halo_mass_function()
{
int k,nr=100;
double x,dlogm,m,mvir,cdelta,mmin=1e8,mmax=1e16,delta_vir;
FILE *fp;
char aa[100];
fprintf(stderr,"\n\nCALCULATING HALO MASS FUNCTION.\n");
fprintf(stderr, "-------------------------------\n\n");
sprintf(aa,"%s.massfunc",Task.root_filename);
fp = fopen(aa,"w");
dlogm = (log(mmax) - log(mmin))/(nr-1);
for(k=0;k<nr;++k)
{
m = exp(k*dlogm)*mmin;
x = dndM_interp(m);
fprintf(fp,"%e %e\n",m,x);
}
fclose(fp);
}

View file

@ -0,0 +1,220 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "header.h"
#define NBINLOOKUP2 10000000
double *xm1,*xf1,*dx1,*mfunc1,*mfy1,*xm2;
int inx;
double N_cen_hiden(double m);
double func_ng6(double m);
void dd_hod_functions(float *hmass, float *hdensity, int nhalo)
{
static int flag=0;
int i,j,k,nh,i1,i2,ibin,*nbin,*fbin;
float *den,*mbin,mass,density,ng1,ng2;
FILE *fp,*fp2;
char a[1000];
double func_ng3(),func_ng4();
/* Variables for the log bins.
*/
float dlogm,dmax=5.0e16,dmin=1.0e9,*dupp,binfac;
int idmax=1000,kbin,*binlookup;
if(flag)goto SKIP1;
flag=1;
/***********************
*initializing the logarithmic bins
*/
idmax = 100;
dlogm=log(dmax/dmin)/(float)(idmax-1) ;
dupp=malloc(idmax*sizeof(float));
binlookup=(int *)calloc(NBINLOOKUP2+2,sizeof(int)) ;
ibin=0 ;
for (i=0;i<=NBINLOOKUP2;i++) {
mass=dmax*i/NBINLOOKUP2 ;
if (mass>0) {
kbin=(int)floor(log(mass/dmin)/dlogm+1.0) ;
}
else {
kbin=0 ;
}
if (kbin<0) kbin=0 ;
if (kbin>ibin) {
dupp[ibin]=mass ;
ibin=kbin ;
}
binlookup[i]=kbin ;
}
binlookup[NBINLOOKUP2+1]=idmax ;
binfac=NBINLOOKUP2/dmax ;
dupp[idmax-1]=dmax;
nbin=calloc(idmax,sizeof(int));
mbin=calloc(idmax,sizeof(double));
fbin=calloc(idmax,sizeof(int));
for(i=1;i<=nhalo;++i)
{
mass=hmass[i];
j=binlookup[(int)(mass*binfac)];
mbin[j]+=mass;
nbin[j]++;
if(GAO_EFFECT) {
if(hdensity[i]>DENSITY_THRESHOLD)
fbin[j]++;
} else {
if(hdensity[i]<DENSITY_THRESHOLD)
fbin[j]++;
}
}
for(j=i=0;i<idmax;++i)
if(nbin[i])j++;
xm1 = dvector(1,j);
xm2 = dvector(1,j);
xf1 = dvector(1,j);
dx1 = dvector(1,j);
mfunc1=dvector(1,j);
mfy1=dvector(1,j);
inx = j;
for(j=i=0;i<idmax;++i)
if(nbin[i])
{
xm1[++j] = mbin[i]/nbin[i];
xf1[j] = (double)fbin[i]/nbin[i];
mfunc1[j] = log(nbin[i]/pow(BOX_SIZE,3.0)/(dlogm*xm1[j]));
xm2[j] = log(xm1[j]);
printf("DENFRAC %e %e %e %e %d %e\n",
xm1[j],xf1[j],mfunc1[j],dndM_interp(xm1[j]),nbin[i],dlogm);
fflush(stdout);
}
spline(xm1,xf1,inx,1.0E+30,1.0E+30,dx1);
spline(xm2,mfunc1,inx,1.0E+30,1.0E+30,mfy1);
SKIP1:
if(wp_color.ON)
return;
fprintf(stdout,"Old M_min: %e\n",HOD.M_min);
fflush(stdout);
if(GAO_EFFECT)
{
HOD.M_min_loden = exp(zbrent(func_ng4,log(HOD.M_min/10.0),log(HOD.M_min*10),1.0E-5));
HOD.M_min = HOD.M_min_loden;
}
else
{
HOD.M_min_hiden = exp(zbrent(func_ng4,log(HOD.M_min/10.0),log(HOD.M_min*10),1.0E-5));
HOD.M_min_loden = HOD.M_min_hiden*HOD.M_min_fac;
HOD.M_min = HOD.M_min_hiden;
}
fprintf(stdout,"New M_min: %e %e %e\n",HOD.M_min,HOD.M_min_loden,HOD.M_min_fac);
fflush(stdout);
}
double func_ng3(double m)
{
double x,dn;
splint(xm2,mfunc1,mfy1,inx,m,&dn);
dn=exp(dn);
m=exp(m);
// dn = dndM_interp(m);
splint(xm1,xf1,dx1,inx,m,&x);
if(x>1)x=1;
if(x<0)x=0;
// x=x*dn*(N_sat(m) + N_cen_hiden(m))*m; <-- this is for GAO EFFECT
x=x*dn*N_avg(m)*m;
return(x);
}
double func_ng5(double m)
{
double x,dn;
splint(xm2,mfunc1,mfy1,inx,m,&dn);
dn=exp(dn);
m=exp(m);
// dn = dndM_interp(m);
splint(xm1,xf1,dx1,inx,m,&x);
if(x>1)x=1;
if(x<0)x=0;
x=(1-x)*dn*N_avg(m)*m;
return(x);
}
double func_ng4(double m)
{
double mlo,x1,x2,func_ng5(),func_mlow();
HOD.M_min=exp(m);
if(SOFT_CENTRAL_CUTOFF)
mlo = (zbrent(func_mlow,log(HOD.M_min*1.0E-4),log(HOD.M_min),1.0E-5));
else
mlo = m;
HOD.M_low=exp(mlo);
x1 = qromo(func_ng5,mlo,log(HOD.M_max),midpnt);
HOD.M_min=HOD.M_min*HOD.M_min_fac;
x2 = qromo(func_ng3,mlo,log(HOD.M_max),midpnt);
// printf("%e %e %e\n",x1,x2,GALAXY_DENSITY);
return((x1+x2)-GALAXY_DENSITY);
}
double density_fraction(double m)
{
double x;
splint(xm1,xf1,dx1,inx,m,&x);
return(x);
}
double func_ng_hiden(double m)
{
return(0);
}
double func_ng_loden(double m)
{
return(0);
}
/* Color-dependent models.
*/
double dd_func_red_fraction(double x)
{
double n;
HOD.fblue0_cen=pow(10.0,x);
//HOD.fblue0_cen = 0.67;
n = qtrap(func_ng6,log(HOD.M_low),log(HOD.M_max),1.0E-5);
printf("%f %e %e %e %e %e\n",HOD.fblue0_cen,n,wp_color.ngal_red,N_avg(8.0e11),HOD.M_min,HOD.M_low);
// exit(0);
return n - wp_color.ngal_red;
}
double func_ng6(double m)
{
double x,x1,dn,xt;
splint(xm2,mfunc1,mfy1,inx,m,&dn);
dn=exp(dn);
m=exp(m);
//dn = dndM_interp(m);
splint(xm1,xf1,dx1,inx,m,&x);
if(x>1)x=1;
if(x<0)x=0;
// printf("%e %e\n",m,x);
x1=(1-x)*dn*N_avg(m)*m; // 1-x is fraction above critical density.
xt = HOD.fblue0_cen;
HOD.fblue0_cen = (1. - HOD.M_min_fac*(1.0 - HOD.fblue0_cen));
x1+=x*dn*N_avg(m)*m;
HOD.fblue0_cen = xt;
return(x1);
}

15
c_tools/hod/dump.c Normal file
View file

@ -0,0 +1,15 @@
if(Work.iquad && Work.iquad_covar)
{
calc_rquad(Work.r_quad,rquad,Work.n_quad);
for(i=0;i<Work.n_quad;++i)
for(j=0;j<Work.n_quad;++j)
{
if(Work.r_quad[i]<Work.rhlo || Work.r_quad[j]<Work.rhlo)continue;
e=esys_quad(Work.r_quad[i])*rquad[i]*esys_quad(Work.r_quad[j]);
chi2c+=(rquad[i]-Work.data_h[i])*(rquad[j]-Work.data_h[j])*
(Work.covar_q[i][j]);
if(!ThisTask && OUTPUTZ)
printf("CHIQUAD%d %d %d %d %f %e %e %e %e %e %e\n",Work.imodel,iter,i,j,Work.r_quad[j],
rquad[i],Work.data_h[i],rquad[j],Work.data_h[j],Work.covar_h[i][j],e);
}
}

18
c_tools/hod/f1dim.c Normal file
View file

@ -0,0 +1,18 @@
#define NRANSI
#include "nrutil.h"
extern int ncom;
extern double *pcom,*xicom,(*nrfunc)(double []);
double f1dim(double x)
{
int j;
double f,*xt;
xt=dvector(1,ncom);
for (j=1;j<=ncom;j++) xt[j]=pcom[j]+x*xicom[j];
f=(*nrfunc)(xt);
free_dvector(xt,1,ncom);
return f;
}
#undef NRANSI

View file

@ -0,0 +1,105 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
void initial_scale_bias_parameters(double **pp, double *yy);
double chi2_scale_bias(double *a);
char *BIAS_FILENAME;
double LARGE_SCALE_BIAS;
void fit_scale_bias(int argc, char **argv)
{
FILE *fp;
int n,i,j,k,niter;
double FTOL = 1.e-3;
double **pp,*yy;
BIAS_FILENAME = argv[3];
LARGE_SCALE_BIAS = atof(argv[4]);
wp.ncf = 4;
pp=dmatrix(1,wp.ncf+1,1,wp.ncf);
yy=dvector(1,wp.ncf+1);
initial_scale_bias_parameters(pp,yy);
amoeba(pp,yy,wp.ncf,FTOL,chi2_scale_bias,&niter);
}
void initial_scale_bias_parameters(double **pp, double *yy)
{
int i,j;
double d[100],a[100];
a[1] = 1.17;
a[2] = 1.79;
a[3] = 1.01;
a[4] = 2.03;
for(i=1;i<=wp.ncf;++i)
d[i]=a[i]*0.2;
for(j=1;j<=wp.ncf;++j)
pp[1][j]=a[j];
yy[1]=chi2_scale_bias(a);
for(i=1;i<=wp.ncf;++i)
{
a[i]+=d[i];
if(i>1)a[i-1]-=d[i-1];
yy[i+1]=chi2_scale_bias(a);
for(j=1;j<=wp.ncf;++j)
pp[i+1][j]=a[j];
}
a[wp.ncf]-=d[wp.ncf];
}
double chi2_scale_bias(double *a)
{
static FILE *fp;
static int n, flag = 1;
static float *r,*x,*e;
int i;
double xi,chi2=0,b;
char aa[1000];
if(flag)
{
fp = openfile(BIAS_FILENAME);
n = filesize(fp);
r = vector(1,n);
x = vector(1,n);
e = vector(1,n);
for(i=1;i<=n;++i) {
fscanf(fp,"%f %f %f",&r[i],&x[i],&e[i]);
x[i] = x[i]/LARGE_SCALE_BIAS; //bias_interp(7.70e10,-1);
e[i] = 0.05*x[i];
fgets(aa,1000,fp); }
flag = 0;
}
for(i=1;i<=n;++i)
{
if(r[i]>20)continue;
xi = xi_interp(r[i]);
b = pow(1+a[1]*xi,a[2])/pow(1+a[3]*xi,a[4]);
chi2 += (b - x[i])*(b - x[i])/e[i]/e[i];
}
if(isnan(chi2))chi2 = 1.0E7;
printf("ITER %e %f %f %f %f\n",chi2,a[1],a[2],a[3],a[4]);
return(chi2);
}

51
c_tools/hod/ftread.c Normal file
View file

@ -0,0 +1,51 @@
/* ftread reads unformatted data that has been written by fortran
or in fortran convention -- i.e. an integer with the number of
bytes in the record, the record data, and another integer with
the number of bytes in the record. ftread does various error
checks, writing a message to stderr and returning a negative
value if an error or warning occurs. The call is identical to
the standard i/o library routine fread.
*/
#include <stdio.h>
int ftread(ptr,size,nitems,stream)
char *ptr ;
unsigned size, nitems ;
FILE *stream ;
{
int nbyte1, nbyte2, nitem1 ;
int errno ;
errno = 0 ;
if ( fread(&nbyte1,sizeof(int),1,stream) != 1 ) {
errno = -10 ;
fprintf(stderr,"read error, file empty ? \n") ;
}
nitem1 = fread(ptr,size,nitems,stream) ;
if ( nitem1 != nitems ) {
errno = -20 ;
fprintf(stderr,"read error, %d items expected, %d items read. \n",
nitems,nitem1) ;
}
if ( fread(&nbyte2,sizeof(int),1,stream) != 1 ) {
errno = -30 ;
fprintf(stderr,"read error, file too short ? \n") ;
}
if ( nbyte1 != nbyte2 ) {
errno = errno - 1 ;
fprintf(stderr,
"read warning, byte #s do not match, nbyte1 = %d, nbyte2 = %d \n",
nbyte1,nbyte2) ;
}
if ( nbyte1 != size*nitems) {
errno = errno - 2 ;
fprintf(stderr,
"read warning, byte # does not match item #, nbyte1 = %d, nitems = %d \n",
nbyte1,nitems) ;
}
return(errno) ;
}

38
c_tools/hod/ftwrite.c Normal file
View file

@ -0,0 +1,38 @@
/* ftwrite writes data unformatted using fortran convention --
i.e. an integer specifying the number of bytes in the record,
the data record, and another integer specifying the number of
bytes in the record. The call is identical to the standard
i/o library routine fwrite.
*/
#include <stdio.h>
int ftwrite(ptr,size,nitems,stream)
char *ptr ;
unsigned size, nitems ;
FILE *stream ;
{
int nbytes, nitem1 ;
int errno ;
errno = 0 ;
nbytes = size*nitems ;
if ( fwrite(&nbytes,sizeof(int),1,stream) != 1 ) {
errno = -10 ;
fprintf(stderr,"write error, is the file open ? \n") ;
}
nitem1 = fwrite(ptr,size,nitems,stream) ;
if ( nitem1 != nitems ) {
errno = -20 ;
fprintf(stderr,"write error, %d items requested, %d items written. \n",
nitems,nitem1) ;
}
if ( fwrite(&nbytes,sizeof(int),1,stream) != 1 ) {
errno = -30 ;
fprintf(stderr,"write error on second byte label \n") ;
}
return(errno) ;
}

View file

@ -0,0 +1,484 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* These are the parameters for creating the pdf table.
*/
int nv1,nr1,nphi1;
void create_pdf_table();
double ***ppp,*vvv,*rbin,*phibin,***yy2,FIRSTFLAG=1;
double BINSIZE;
double galaxy_prob_vz(double vel, double rad, double theta)
{
static int flag=0,prev_cosmo=0;
static double *y,*ya,*yb,*y2b,*xb,rv[21],rmin,rmax,dlogr;
int i,j,k,irad,iphi;
double vprob,m1,m2;
if(!flag || RESET_PVZ || RESET_COSMOLOGY!=prev_cosmo)
{
rmin=1.7*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
rmax=XI_MAX_RADIUS;
dlogr=log(rmax/rmin)/(nr1-1);
if((RESET_PVZ || RESET_COSMOLOGY!=prev_cosmo) && !ThisTask)
{
printf("RESET: creating new table for:\n");
printf(" > OMEGA_M = %f\n",OMEGA_M);
printf(" > SIGMA_8 = %f\n",SIGMA_8);
printf(" > VBIAS = %f\n",VBIAS);
printf(" > VBIAS_C = %f\n",VBIAS_C);
fflush(stdout);
}
RESET_PVZ=0;
prev_cosmo=RESET_COSMOLOGY;
create_pdf_table();
if(!flag)
{
y=dvector(1,nphi1);
ya=dvector(1,nphi1);
yb=dvector(1,4);
y2b=dvector(1,4);
xb=dvector(1,4);
}
flag=1;
for(i=1;i<=nr1;++i)
for(j=1;j<=nphi1;++j)
spline(vvv,ppp[i][j],nv1,1.0E+30,1.0E+30,yy2[i][j]);
}
if(fabs(vel)>MAXVEL)return(0);
if(theta<0)theta*=-1;
for(i=1;i<=nr1;++i)
if(rad<rbin[i])break;
if(i<3)i=3;
if(i>nr1-1)i=nr1-1;
irad=i;
while(rbin[irad-2]==0)irad++;
if(irad>nr1-1)
{
printf("ERROR CANNOT ITERPOLATE FOR r=%f\n",rad);
exit(0);
}
for(j=1,i=irad-2;i<=irad+1;++i,++j)
{
for(k=1;k<=nphi1;++k)
{
splint(vvv,ppp[i][k],yy2[i][k],nv1,vel,&y[k]);
}
spline(phibin,y,nphi1,1.0E+30,1.0E+30,ya);
splint(phibin,y,ya,nphi1,theta,&yb[j]);
xb[j]=rbin[i];
}
spline(xb,yb,4,1.0E30,1.0E30,y2b);
splint(xb,yb,y2b,4,rad,&vprob);
if(vprob<0)vprob=0;
return(vprob);
irad=i;
if(irad<2)irad=2;
if(irad>nr1)irad=nr1;
iphi = (int)theta/(PI/18.0)+1;
if(iphi==nphi1)iphi=nphi1-1;
for(j=1,i=irad-1;i<=irad;++i)
{
for(k=iphi;k<=iphi+1;++k)
{
splint(vvv,ppp[i][k],yy2[i][k],nv1,vel,&y[j++]);
}
}
m1 = (y[1]-y[2])/(phibin[iphi]-phibin[iphi+1])*(theta-phibin[iphi])+y[1];
m2 = (y[3]-y[4])/(phibin[iphi]-phibin[iphi+1])*(theta-phibin[iphi])+y[3];
vprob = (m2-m1)/(rbin[irad]-rbin[irad-1])*(rad-rbin[irad-1])+m1;
if(vprob<0)vprob=0;
return(vprob);
}
/* For consistency, the MAXVEL and BINSIZE variables will be scaled by
* OMEGA_M^0.6.
*
*/
void create_pdf_table()
{
#define NZMASS 19
int TEST=1;
FILE *fp;
double dlogr,vbias1,vbias2;
static int CNT=0;
double sgal[NZMASS][NZMASS],sgal_cs[NZMASS][NZMASS],sgal_cc[NZMASS][NZMASS],
*cf,fdat[10],s2gal[4],wgal[3],**mtemp,
***ptemp,*vtemp,*temp,*p1temp,*p2temp,*precv,*rvir,*ngal,**ngal2,**ngal2x,*mbin;
double binsize,ptot,vprob,p0,p1,p2,p3,s1,s2,s3,s4,v1,v,
mass,mlo,mhi,qromo(),midpnt(),sgal1[NZMASS][NZMASS],hmass[NZMASS],
sgal2[NZMASS][NZMASS],w1[NZMASS][NZMASS],w2[NZMASS][NZMASS],mass1,mass2,wsum,fac,
w3[NZMASS][NZMASS],t0,tsum=0,t1,tdiff,frac1,frac2,frac3,frac4,x1,x2,deltar,
haloweight,immax,mmax,rmax,rmin,exfac,xx1=0,weightsum;
int i,j,k,n,nzmass,imass=0,irad,im1,im2,istep=1,istart=1,jstart=1,jstep=1,
idat[10],nitems;
float f1;
CNT++;
#ifdef PARALLEL
istep = 1;
istart = 1;
jstart = ThisTask + 1;
jstep = NTask;
#endif
BINSIZE=20*pow(OMEGA_M/0.3,0.6);
rmin=R_MIN_2HALO;
rmin=1.1*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
rmax=XI_MAX_RADIUS;
nr1=30;
nv1=301;
nphi1=9;
MAXVEL=BINSIZE*floor(nv1/2);
/* This assumes that even if the cosmology is changed, that
* the dimensions of these arrays won't change.
*/
if(FIRSTFLAG)
{
vvv=dvector(1,nv1);
rbin=dvector(1,nr1);
phibin=dvector(1,nphi1);
yy2=d3tensor(1,nr1,1,nphi1,1,nv1);
ppp=d3tensor(1,nr1,1,nphi1,1,nv1);
FIRSTFLAG=0;
}
if(TEST)
{
HOD.pdfs=0;
HOD.M_min = HOD.M_low = 4.4e11;
rmin=1.1*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
}
dlogr=log(rmax/rmin)/(nr1-1);
for(i=1;i<=nr1;++i)
rbin[i]=rmin*exp((i-1)*dlogr);
for(i=1;i<=nphi1;++i)
phibin[i]=(i-0.5)/nphi1*PI/2;
for(i=1;i<=nv1;++i)
vvv[i]=-MAXVEL+(i-1)*BINSIZE;
nzmass=NUM_POW2MASS_BINS-1;
ptemp=d3tensor(0,nzmass-1,0,nzmass-1,1,nv1);
vtemp=dvector(1,nv1);
temp=dvector(1,nv1);
p1temp=dvector(1,nv1);
p2temp=dvector(1,nv1);
precv=dvector(1,nv1);
rvir=dvector(0,nzmass);
mbin=dvector(0,nzmass);
for(i=1;i<=nr1;++i)
for(j=1;j<=nphi1;++j)
for(k=1;k<=nv1;++k)
ppp[i][j][k]=0;
binsize=BINSIZE;
fac=sqrt(4.499E-48/2.0)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19;
fac=fac*fac;
/* w1 -> number of i_sat + j_cen pairs
* w2 -> number of j_sat + i_cen pairs
* w3 -> number of i_sat + j_sat pairs
*
* Okay, I know that all you have to do is switch the indices on
* w1 to get w2, but just to keep things really clear, I'll have three
* different matrices.
*/
for(i=0;i<nzmass;++i)
for(j=0;j<nzmass;++j)
{
mass1=1.5*pow(2.0,i)*HOD.M_low;
vbias1 = (VBIAS_SLOPE*(log(mass1)-34.5)+VBIAS);
if(vbias1<0.1)vbias1=0.1;
//vbias1 = 0.4/3*log(mass1)/LOGE_10 - 1;
//if(vbias1<0.6)vbias1=0.6;
/* TEMP-> mass threshold
*/
/*
vbias1=1;
if(mass1<VBIAS_MASS_THRESHOLD)
vbias1=VBIAS;
*/
vbias1 *= vbias1;
mass2=1.5*pow(2.0,j)*HOD.M_low;
vbias2 = (VBIAS_SLOPE*(log(mass2)-34.5)+VBIAS);
if(vbias2<0.1)vbias2=0.1;
//vbias2 = 0.4/3*log(mass2)/LOGE_10 - 1;
//if(vbias2<0.6)vbias2=0.6;
/* TEMP-> mass threshold
*/
/*
vbias2=1;
if(mass2<VBIAS_MASS_THRESHOLD)
vbias2=VBIAS;
*/
vbias2 *= vbias2;
mbin[i]=mass1;
s1=vbias1*fac*pow(mass1,0.66666666667);
s2=vbias2*fac*pow(mass2,0.66666666667);
sgal[i][j]=s1+s2;
s1=fac*pow(mass1,0.66666666667)*VBIAS_C*VBIAS_C;
sgal_cs[i][j]=s1+s2;
s2=fac*pow(mass2,0.66666666667)*VBIAS_C*VBIAS_C;
sgal_cc[i][j]=s1+s2;
wsum=N_avg(mass1)*dndM_interp(mass1)*N_avg(mass2)*dndM_interp(mass2);
w1[i][j]=N_sat(mass1)*dndM_interp(mass1)*N_cen(mass2)*dndM_interp(mass2);
w2[i][j]=N_sat(mass2)*dndM_interp(mass2)*N_cen(mass1)*dndM_interp(mass1);
w3[i][j]=N_sat(mass1)*dndM_interp(mass1)*N_sat(mass2)*dndM_interp(mass2);
// this is for testing sat-sat 2halo term
//w1[i][j] = w2[i][j] = 0;
//wsum = w3[i][j];
//w1[i][j] = w2[i][j] = w3[i][j] = 0;
//wsum = w3[i][j];
//w1[i][j] = w2[i][j] = 0;
w1[i][j]/=wsum;
w2[i][j]/=wsum;
w3[i][j]/=wsum;
}
/* Calculate the average number of galaxy
* pairs in each combination of halo mass bins.
*/
ngal=dvector(0,nzmass-1);
ngal2=dmatrix(0,nzmass-1,0,nzmass-1);
ngal2x=dmatrix(0,nzmass-1,0,nzmass-1);
for(i=0;i<nzmass;++i)
{
mlo=pow(2.0,i)*HOD.M_low;
mhi=mlo*2;
ngal[i]=qromo(func_galaxy_density,log(mlo),log(mhi),midpnt);
ngal2[i][i]=ngal[i]*ngal[i]*0.5;
}
for(i=0;i<nzmass;++i)
for(j=i+1;j<nzmass;++j)
ngal2[i][j]=ngal[i]*ngal[j];
/* Calculate the virial radius for each halo bin.
*/
for(i=0;i<nzmass;++i)
rvir[i]=pow(3*pow(2.0,i)*HOD.M_low*ROOT2/
(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
for(i=0;i<nzmass;++i)
hmass[i] = 1.5*pow(2.0,i)*HOD.M_low;
for(k=1;k<=nv1;++k)
vtemp[k]=vvv[k];
/* TEMP TEMP TEMP
*/
for(i=0;i<nzmass;++i)
for(j=i;j<nzmass;++j)
//ngal2x[i][j] = N_cen(hmass[i])*N_sat(hmass[j]) + N_cen(hmass[j])*N_sat(hmass[i]);
//ngal2x[i][j] = N_sat(hmass[i])*N_sat(hmass[j]);
ngal2x[i][j] = N_cen(hmass[i])*N_cen(hmass[j]);
for(i=0;i<nzmass;++i)
ngal2x[i][i]/=2;
/* For each r/phi combination, first calculate the pdf for all possible
* halo-halo pairs. Once the h-h pdf is calculates, convolve with the
* galaxy Gaussian pdf.
*/
j=jstart;
if(NTask==1 && OUTPUT)
{
printf("TASK %d starting: %d %d\n",ThisTask,istart,jstart);
fflush(stdout);
}
t0=second();
for(i=istart;i<=nr1;)
{
while(j>nphi1) { i++; j=j-nphi1; }
if(i>nr1)break;
jstart=j;
for(j=jstart;j<=nphi1;j+=jstep)
{
t1=second();
tdiff=timediff(t0,t1);
tsum+=tdiff;
t0=second();
if(NTask==1 && OUTPUT)
{
fprintf(stdout,"P(v_z) r[%d]= %5.2f phi[%d]=%4.1f [dt= %.2f T=%7.2f] (task= %d)\n",
i,rbin[i],j,phibin[j]*180/PI,tdiff,tsum,ThisTask);
fflush(stdout);
}
for(im1=0;im1<nzmass;++im1)
{
for(im2=im1;im2<nzmass;++im2)
{
/* NEW VERSION, with varying VBIAS_C
*/
s1=sgal_cs[im2][im1];
s2=sgal_cs[im1][im2];
s3=sgal[im1][im2];
s4=sgal_cc[im1][im2];
s2gal[0]=s1;
s2gal[1]=s2;
s2gal[2]=s3;
s2gal[3]=s4;
wgal[0]=w1[im1][im2];
wgal[1]=w2[im1][im2];
wgal[2]=w3[im1][im2];
vdelta_v4(mbin[im1],mbin[im2],rbin[i],phibin[j],BINSIZE,-MAXVEL,nv1,cf,
temp,p1temp,ptemp[im1][im2],wgal,s2gal);
}
}
/* Output some stuff for testing purposes
*/
if(TEST && (j==1 || j==9))
//if(j==1 || j==9)
{
for(im1=0;im1<nzmass;++im1)
{
p0=p1=p2=0;
for(k=1;k<=nv1;++k)
{
v = -MAXVEL + (k-1)*BINSIZE;
p0 += ptemp[im1][im1][k]*BINSIZE;
p1 += ptemp[im1][im1][k]*v*BINSIZE;
p2 += ptemp[im1][im1][k]*v*v*BINSIZE;
//printf("xTEST%d MASS%d %f %e\n",j,im1+1,ptemp[im1][im1][k]);
}
p1 = p1/p0;
p2 = sqrt(p2/p0 - p1*p1);
if(!isnan(p0+p1+p2))
printf("TEST%d MASS%d %e %f %f %f\n",j,im1+1,hmass[im1],rbin[i],-p1,p2);
}
}
/* Now calculate the galaxy-number-wieghted average
* of the v_z pdf by summing over all halo-halo pairs.
* (Using sum of virial radii for halo exclusion.)
*/
ptot=0;
weightsum=0;
for(k=1;k<=nv1;++k)
for(ppp[i][j][k]=0,im1=0;im1<nzmass;++im1)
for(im2=im1;im2<nzmass;++im2)
{
if(rbin[i]>rvir[im2]*0.75)
{
ppp[i][j][k]+=ptemp[im1][im2][k]*ngal2[im1][im2]*
(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
if(k==1)weightsum+=ngal2[im1][im2]*
(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
}
continue;
if(rbin[i]/(rvir[im1]+rvir[im2])>0.5)
{
exfac=1;
if(rbin[i]/(rvir[im1]+rvir[im2])<1.5)
exfac=ellipsoidal_exclusion_probability(rvir[im2]/rvir[im1],
rbin[i]/(rvir[im1]+rvir[im2]));
/*
if(rbin[i]<(rvir[im1]+rvir[im2]))
exfac = 0;
if(rvir[im2]/rvir[im1]>pow(100.0,.333) && rbin[i]>(rvir[im1]+rvir[im2])*0.5)
exfac = 1;
*/
ppp[i][j][k]+=ptemp[im1][im2][k]*ngal2[im1][im2]*exfac*1*
sqrt(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
if(k==1)weightsum+=ngal2[im1][im2]*exfac*1*
sqrt(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
}
}
//printf("WEIGHTSUM %d %d %e %.0f\n",
// i,j,weightsum,weightsum*BOX_SIZE*BOX_SIZE*BOX_SIZE);
if(weightsum>0)
{
for(k=1;k<=nv1;++k)
ppp[i][j][k]/=weightsum;
// for(k=1;k<=nv1;++k)
//printf("yTEST %d %d %f %e\n",i,j,vvv[k],ppp[i][j][k]);
for(ptot=0,k=1;k<=nv1;++k)
ptot+=ppp[i][j][k]*binsize;
}
else
for(k=1;k<=nv1;++k)
ppp[i][j][k]=0;
}
}
#ifdef PARALLEL
for(i=1;i<=nr1;++i)
for(j=1;j<=nphi1;++j)
{
for(k=1;k<=nv1;++k)
temp[k]=ppp[i][j][k];
MPI_Allreduce(&temp[1],&precv[1],nv1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
for(k=1;k<=nv1;++k)
ppp[i][j][k]=precv[k];
}
#endif
free_d3tensor(ptemp,0,nzmass-1,0,nzmass-1,1,nv1);
free_dvector(vtemp,1,nv1);
free_dvector(temp,1,nv1);
free_dvector(p1temp,1,nv1);
free_dvector(p2temp,1,nv1);
free_dvector(precv,1,nv1);
free_dvector(rvir,0,nzmass);
free_dvector(mbin,0,nzmass);
free_dvector(ngal,0,nzmass-1);
free_dmatrix(ngal2,0,nzmass-1,0,nzmass-1);
}

24
c_tools/hod/gasdev.c Normal file
View file

@ -0,0 +1,24 @@
#include <math.h>
float gasdev(long *idum)
{
float ran1(long *idum);
static int iset=0;
static float gset;
float fac,rsq,v1,v2;
if (iset == 0) {
do {
v1=2.0*ran1(idum)-1.0;
v2=2.0*ran1(idum)-1.0;
rsq=v1*v1+v2*v2;
} while (rsq >= 1.0 || rsq == 0.0);
fac=sqrt(-2.0*log(rsq)/rsq);
gset=v1*fac;
iset=1;
return v2*fac;
} else {
iset=0;
return gset;
}
}

59
c_tools/hod/gaussj.c Normal file
View file

@ -0,0 +1,59 @@
#include <math.h>
#define NRANSI
#include "nrutil.h"
#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
void gaussj(double **a, int n, double **b, int m)
{
int *indxc,*indxr,*ipiv;
int i,icol,irow,j,k,l,ll;
double big,dum,pivinv,temp;
indxc=ivector(1,n);
indxr=ivector(1,n);
ipiv=ivector(1,n);
for (j=1;j<=n;j++) ipiv[j]=0;
for (i=1;i<=n;i++) {
big=0.0;
for (j=1;j<=n;j++)
if (ipiv[j] != 1)
for (k=1;k<=n;k++) {
if (ipiv[k] == 0) {
if (fabs(a[j][k]) >= big) {
big=fabs(a[j][k]);
irow=j;
icol=k;
}
} else if (ipiv[k] > 1) nrerror("gaussj: Singular Matrix-1");
}
++(ipiv[icol]);
if (irow != icol) {
for (l=1;l<=n;l++) SWAP(a[irow][l],a[icol][l])
for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
}
indxr[i]=irow;
indxc[i]=icol;
if (a[icol][icol] == 0.0) nrerror("gaussj: Singular Matrix-2");
pivinv=1.0/a[icol][icol];
a[icol][icol]=1.0;
for (l=1;l<=n;l++) a[icol][l] *= pivinv;
for (l=1;l<=m;l++) b[icol][l] *= pivinv;
for (ll=1;ll<=n;ll++)
if (ll != icol) {
dum=a[ll][icol];
a[ll][icol]=0.0;
for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
for (l=1;l<=m;l++) b[ll][l] -= b[icol][l]*dum;
}
}
for (l=n;l>=1;l--) {
if (indxr[l] != indxc[l])
for (k=1;k<=n;k++)
SWAP(a[k][indxr[l]],a[k][indxc[l]]);
}
free_ivector(ipiv,1,n);
free_ivector(indxr,1,n);
free_ivector(indxc,1,n);
}
#undef SWAP
#undef NRANSI

View file

@ -0,0 +1,73 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "header.h"
/* This calculates the linear growthfactor at redshift z.
* Currently, the default is a flat LCDM universe, but can easily
* be changed.
*/
double x03_g1,
xi3_g1;
double func_D0(double);
double func_Di(double);
double growthfactor(double z)
{
int i;
double zp1,x03,xi3,bi,b0,yy,sqx,sqx1,dbdx,x0,xi,lambda_i,htemp,omega_L,omega_i,hubble_i,
astart,fac,redshift;
redshift=z;
astart=1.0/(z+1);
zp1=redshift+1;
omega_L=1-OMEGA_M;
hubble_i = sqrt(OMEGA_M/(astart*astart*astart) +
(1.0-OMEGA_M-omega_L)/(astart*astart) +omega_L);
if(omega_L>0)
{
lambda_i=omega_L/(omega_L+(1.0-OMEGA_M-omega_L)*zp1*zp1+OMEGA_M*pow(zp1,3.0));
omega_i=OMEGA_M*pow(zp1,3.0)*lambda_i/omega_L;
}
else
{
lambda_i=0;
omega_i=OMEGA_M*zp1/(1.0+OMEGA_M*redshift);
}
fac=astart;
if((OMEGA_M < 0.99) && (omega_L > 0.001))
{
x03_g1=x03=1.0/OMEGA_M-1.0;
xi3_g1=xi3=1.0/omega_i-1.0;
b0 = qromo(func_D0,0.0,1.0,midpnt);
bi = qromo(func_Di,0.0,1.0,midpnt);
b0=b0*sqrt(x03+1.0);
bi=bi*sqrt(xi3+1.0)*astart;
fac=bi/b0;
}
if((OMEGA_M < 0.99) && (omega_L == 0))
{
x0=1.0/OMEGA_M-1.0;
xi=x0*astart;
b0 = 1.+3./x0+3.*sqrt(1+x0)*log(sqrt(1.+x0)-sqrt(x0))/pow(x0,1.5);
bi = 1.+3./xi+3.*sqrt(1+xi)*log(sqrt(1.+xi)-sqrt(xi))/pow(xi,1.5);
fac = bi/b0;
}
return(fac);
}
double func_Di(double y)
{
return(pow(1.0+xi3_g1*pow(y,1.2),-1.5));
}
double func_D0(double y)
{
return(pow(1.0+x03_g1*pow(y,1.2),-1.5));
}

300
c_tools/hod/halo_bias.c Normal file
View file

@ -0,0 +1,300 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This is the bias factor for halos. Mass (in h^{-1} M_sol) is the input.
* This is not the scale-dependent bias factor, which can be calculated later.
*
* There are many variants of the bias in this function.
* The one it is set up to use is from the Tinker etal (in prep, currently)
* bias paper calibrated from the SO halo catalogs from the Tinker et al mass functino
* paper. The parameters of the bias functions are calibrated such that they will
* work with any chosen halo overdensity.
*
* Other variants:
*
* The parameterization of b(M) is taken from Sheth Mo & Tormen (2001 MNRAS 232 1)
* but the actual parameters have been replaced by the values of Appendix A in
* Tinker, Weinberg, Zheng, & Zehavi. 2005 Apj (M/L paper)
*
* See also Seljak & Warren (2004).
* See also Sheth & Tormen (1999)
* See also Mo & White (1996)
*/
double bias_from_file(double m, double r);
double bias(double mass)
{
double rm,sig,k,neff,b,logk,khi,klo,phi,plo,nu,psp,x;
static int flag=0;
static double pnorm, prev_delta=-1;
// variables for the SO(DELTA) bias functions
static double bias_A, bias_a, bias_B, bias_b;
/* Original SMT parameters */
double a=0.707,bb=0.5,c=0.6;
pnorm=SIGMA_8/sigmac(8.0);
rm=pow(3.0*mass/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=pnorm*sigmac(rm);
/* Tinker et al parameters */
a=0.707;
bb=0.35;
c=0.8;
/* Fitting to Mike Warren's simulations. */
bb=0.28;
/* Use the globel parameters. */
a=BIAS_A; bb=BIAS_B; c=BIAS_C;
/* First normalize the power spectrum
*/
pnorm=SIGMA_8/sigmac(8.0);
rm=pow(3.0*mass/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=pnorm*sigmac(rm);
/* This is from Tinker etal in prep for SO halos
*/
if(DELTA_HALO != prev_delta)
{
bias_A = pow(fabs(log10(DELTA_HALO)-2.69),2)*0.16 + 0.785;
bias_a = (log10(DELTA_HALO) - 2.28)*0.45;
bias_B = 0.4*(log10(DELTA_HALO)-2.3)+0.7*log10(DELTA_HALO)*exp(-pow(4/log10(DELTA_HALO),4.0))+1.23;
bias_b = 2.4;
fprintf(stderr,"BIAS PARAMS: %f %f %f %f\n",bias_A, bias_a, bias_B, bias_b);
prev_delta = DELTA_HALO;
}
a = pow(sig,-bias_a);
b = 1 - bias_A*a/(a+1) + bias_B*pow(sig,-bias_b);
return(b);
/* This is the Seljak & Warren (2004) bias.
* There's an alpha_s in the correction term, which here I set to zero. (RUNNING.)
* See App. A of Tinker et al (M/L) for a comparison of this bias with above bias.
*/
x=mass/MSTAR;
b=(0.53+0.39*pow(x,0.45)+0.13/(40*x+1) + 5.0e-4*pow(x,1.5));
b=b+log10(x)*(0.4*(OMEGA_M-0.3+SPECTRAL_INDX-1)+0.3*(SIGMA_8-0.9+HUBBLE-0.7)+0.8*0.0);
return(b);
/* This is the Sheth Mo Tormen bias.
* (possible that parameter values have been changed to better fit simulations,
* ie from Tinker etal 2005 ML paper).
*/
nu=DELTA_CRIT/sig;
b=1+1.0/(sqrt(a)*DELTA_CRIT)*(sqrt(a)*a*nu*nu + sqrt(a)*bb*pow(a*nu*nu,1-c) -
(pow(a*nu*nu,c)/(pow(a*nu*nu,c)+bb*(1-c)*(1-c/2.))));
return(b);
/* This is Sheth & Tormen
*/
nu = DELTA_CRIT/sig;
nu = nu*nu;
return(1 + (0.707*nu - 1)/DELTA_CRIT + 2*0.3/DELTA_CRIT/(1+pow(0.707*nu,0.3)));
/* This is the old Mo & White (1996) formula
*/
return(1+DELTA_CRIT/sig/sig-1/DELTA_CRIT);
}
/* Just like the halo mass function, we'll set this up such that
* you just need to interpolate.
*
* Now this has been changed to calculate the spatial-scale dependence
* of the bias factor. If you don't want the scale dep. b, then just
* input r<0.
*
* If the global flag LINEAR_PSP==0, uses the scale dependence calculated for
* for halo bias relative to the non-linear matter \xi_m(r):
*
* f^2(r) = (1.0+xi*1.17)^1.49/(1.0+xi*0.69)^2.09 --> b(r) = b0*f(r)
*
* For LINEAR_PSP==1, use scale dependence determined for the linear P(k):
*
* f(r) = 1 + exp[-(r/A)^0.7] --> where A is a parameter that we're gonna have to
* determine in more detail, but now A \approx 1
*/
double bias_interp(double m, double r)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2, pnorm;
int i,n=100;
double dm,max=16.3,min=9,a,b,m1,m2,dm1,xi,power,rm,sig,b1,b2,mass,rvir,a1;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting bias for %f %f\n",OMEGA_M,SIGMA_8);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dm=(double)(max-min)/n;
for(i=1;i<=n;++i)
{
x[i]=pow(10.0,min+i*dm);
y[i]=log(bias(x[i]));
x[i] = log(x[i]);
//printf("BIAS %f %f\n",x[i]/2.302, y[i]/2.302);
continue;
// no longer need to do this part, since we're taking into account
// halo overdensity in the bias formula.
if(DELTA_HALO!=200)
{
x[i]=log(halo_mass_conversion2(x[i],halo_c200(x[i]),200.0,DELTA_HALO));
}
else
{
x[i]=log(x[i]);
}
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
pnorm=SIGMA_8/sigmac(8.0);
}
m=log(m);
splint(x,y,y2,n,m,&a);
a = exp(a);
// if we're using systematic errors in an MCMC, adjust parameter a1 (amplitude)
if(USE_ERRORS)
a *= M2N.bias_amp;
// if no scale-dependence required, return the large-scale value
if(r<0) return a;
/*
* SCALE DEPENDENT BIAS!!!
*----------------------------------------------------------------------
*/
/* first, calculate the standard Zheng-like, mass-independent scale bias
* based on the non-linear correlation function
* (re-calibrated using the SO catalogs)
*/
xi = xi_interp(r);
b = pow(1.0+xi*0.92,2.08)*pow(1.0+xi*0.74,-2.37);
if(b<0.6)b=0.6;
/* Now the mass-dependent term.
* Where the mass-dependence comes in the form of the large-scale bias itself
*/
/*
sig = sigmac_radius_interp(r);
if(a<0)
b *= pow(1 + 0.028*pow(a,1.53)*pow(sig,1.57),2.59)/
pow(1 + 0.253*pow(a,1.24)*pow(sig,1.71),0.397);
*/
// if we're using systematic errors in an MCMC, adjust parameter a1 (amplitude)
if(USE_ERRORS) {
b = (b-1)*M2N.scalebias_amp + 1;
if(b<0)b=0;
}
return b*a;
}
/* This is the integrand which qromo or qtrap would call
* to calculate the large-scale galaxy bias.
* The integral is a number-weighted average of the halo
* bias function, integrated over the halo mass function.
*/
double func_galaxy_bias(double m)
{
m=exp(m);
return(dndM_interp(m)*N_avg(m)*bias_interp(m,-1.)*m);
}
/*
* This is to get the bias from a series of files.
*
*/
double bias_from_file(double m, double r)
{
FILE *fp;
static int nfiles=10, *n, flag =1;
static double *mass, **rad, **bias;
float x1,x2,x3;
char fname[1000];
int i,j,i1,i2;
double b;
if(flag)
{
n = ivector(0,nfiles-1);
mass = dvector(0,nfiles-1);
rad = dmatrix(0,nfiles-1,1,30);
bias = dmatrix(0,nfiles-1,1,30);
fp = openfile("/home/tinker/cosmo/SDSS/zspace_analysis/SO_calibration/halofiles/sigma.dat");
for(i=0;i<nfiles;++i)
fscanf(fp,"%lf %f",&mass[i],&x1);
for(i=0;i<nfiles;++i)
mass[i] = log(mass[i]);
fclose(fp);
for(i=0;i<nfiles;++i)
{
sprintf(fname,"/home/tinker/cosmo/SDSS/zspace_analysis/SO_calibration/halofiles/bias_nl.200.m%d",i);
fp = openfile(fname);
n[i] = filesize(fp);
for(j=1;j<=n[i];++j)
{
fscanf(fp,"%lf %lf %f %f %f",&rad[i][j],&bias[i][j],&x1,&x2,&x3);
rad[i][j] = log(rad[i][j]);
}
fclose(fp);
}
flag = 0;
}
r = log(r);
if(m>mass[nfiles-1])return -1;
for(i=1;i<nfiles;++i)
if(mass[i]>=m)break;
i2 = i;
i1 = i-1;
for(j=2;j<=n[i1];++j)
if(rad[i1][j]>r)break;
x1 = (bias[i1][j] - bias[i1][j-1])/(rad[i1][j] - rad[i1][j-1])*(r-rad[i1][j-1]) + bias[i1][j-1];
for(j=2;j<=n[i2];++j)
if(rad[i2][j]>r)break;
x2 = (bias[i2][j] - bias[i2][j-1])/(rad[i2][j] - rad[i2][j-1])*(r-rad[i2][j-1]) + bias[i2][j-1];
b = (x2 - x1)/(mass[i2] - mass[i1])*(m - mass[i1]) + x1;
// if(r>log(4))
// printf("%e %e %f %f %f %f %f\n",m,r,b,x2,x1,mass[i2],mass[i1]);
return b;
}

View file

@ -0,0 +1,178 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This is the bias factor for halos. Mass (in h^{-1} M_sol) is the input.
* This is not the scale-dependent bias factor, which can be calculated later.
*
* The parameterization of b(M) is taken from Sheth Mo & Tormen (2001 MNRAS 232 1)
* but the actual parameters have been replaced by the values of Appendix A in
* Tinker, Weinberg, Zheng, & Zehavi. 2005 Apj (submitted)
*/
double bias(double mass)
{
static int prev_cosmo=-1;
static long IDUM=-3333;
double rm,sig,k,neff,b,logk,khi,klo,phi,plo,nu,psp,x,fac,fac1,fac2;
static int flag=0,na=4;
static double pnorm,*xa,*ya,*za;
int i;
/* Original SMT parameters */
double a=0.707,bb=0.5,c=0.6;
/* Tinker et al parameters */
a=0.707;
bb=0.35;
c=0.8;
/* Fitting to Mike Warren's simulations. */
bb=0.28;
/* Use the globel parameters. */
a=BIAS_A; bb=BIAS_B; c=BIAS_C;
if(!flag)
{
xa=dvector(1,na);
ya=dvector(1,na);
za=dvector(1,na);
flag=1;
xa[1] = log(1/2.51);
xa[2] = log(1/1.49);
xa[3] = log(1/0.905);
xa[4] = log(1/0.501);
}
if(prev_cosmo != RESET_COSMOLOGY)
{
prev_cosmo=RESET_COSMOLOGY;
for(i=1;i<=4;++i)
ya[i] = gasdev(&IDUM);
spline(xa,ya,na,1.0E+30,1.0E+30,za);
}
/* First normalize the power spectrum
*/
pnorm=SIGMA_8/sigmac(8.0);
rm=pow(3.0*mass/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=pnorm*sigmac(rm);
nu=DELTA_CRIT/sig;
b=1+1.0/(sqrt(a)*DELTA_CRIT)*(sqrt(a)*a*nu*nu + sqrt(a)*bb*pow(a*nu*nu,1-c) -
(pow(a*nu*nu,c)/(pow(a*nu*nu,c)+bb*(1-c)*(1-c/2.))));
splint(xa,ya,za,na,log(1/sig),&fac1);
fac2 = 0.0158*pow(sig,-2.7) + 0.00251*pow(sig,2.2);
fac = 1 + fac1*fac2;
if(fac<0.01)fac=0.01;
b*=fac;
return(b);
/* This is the Seljak & Warren (2004) bias.
* There's an alpha_s in the correction term, which here I set to zero. (RUNNING.)
* See App. A of Tinker et al for a comparison of this bias with above bias.
*/
x=mass/MSTAR;
b=(0.53+0.39*pow(x,0.45)+0.13/(40*x+1) + 5.0e-4*pow(x,1.5));
b=b+log10(x)*(0.4*(OMEGA_M-0.3+SPECTRAL_INDX-1)+0.3*(SIGMA_8-0.9+HUBBLE-0.7)+0.8*0.0);
return(b);
/* This is the old Mo & White (1996) formula
*/
return(1+DELTA_CRIT/sig/sig-1/DELTA_CRIT);
}
/* Just like the halo mass function, we'll set this up such that
* you just need to interpolate.
*
* Now this has been changed to calculate the spatial-scale dependence
* of the bias factor. If you don't want the scale dep. b, then just
* input r<0.
*
* If the global flag LINEAR_PSP==0, uses the scale dependence calculated for
* for halo bias relative to the non-linear matter \xi_m(r):
*
* f^2(r) = (1.0+xi*1.17)^1.49/(1.0+xi*0.69)^2.09 --> b(r) = b0*f(r)
*
* For LINEAR_PSP==1, use scale dependence determined for the linear P(k):
*
* f(r) = 1 + exp[-(r/A)^0.7] --> where A is a parameter that we're gonna have to
* determine in more detail, but now A \approx 1
*/
double bias_interp(double m, double r)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2;
int i,n=100;
double dm,max=16.3,min=9,a,b,m1,m2,dm1,xi;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting bias for %f %f\n",OMEGA_M,SIGMA_8);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dm=(double)(max-min)/n;
for(i=1;i<=n;++i)
{
x[i]=pow(10.0,min+i*dm);
y[i]=log(bias(x[i]));
if(DELTA_HALO!=200)
{
m1 = halo_mass_conversion2(x[i]*1.001,halo_c200(x[i]*1.001),DELTA_HALO,200.0);
m2 = halo_mass_conversion2(x[i]*0.999,halo_c200(x[i]*0.999),DELTA_HALO,200.0);
dm1 = (x[i]*1.001 - x[i]*0.999)/(m1-m2);
y[i] = y[i] + log(dm1);
x[i]=log(halo_mass_conversion2(x[i],halo_c200(x[i]),DELTA_HALO,200.0));
}
else
x[i]=log(x[i]);
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
m=log(m);
splint(x,y,y2,n,m,&a);
if(r<0 || r>10)return(exp(a));
if(LINEAR_PSP)
{
b=exp(-pow(r,0.7)) + 1;
}
else
{
xi=xi_interp(r);
b=pow(1.0+xi*1.17,1.49*0.5)*pow(1.0+xi*0.69,-2.09*0.5);
}
a=exp(a)*b;
return(a);
}
/* This is the integrand which qromo or qtrap would call
* to calculate the large-scale galaxy bias.
* The integral is a number-weighted average of the halo
* bias function, integrated over the halo mass function.
*/
double func_galaxy_bias(double m)
{
return(dndM_interp(m)*N_avg(m)*bias_interp(m,-1.));
}

View file

@ -0,0 +1,155 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
double collapse_redshift(double z);
double cvir_pnorm_g1,
cvir_sigma_g1;
/* This calculates and tabulates the halo concentrations
* as a function of halo mass. Uses the "Bullock model",
* described in a little more detail below.
*/
double halo_concentration(double m)
{
static int flag=1,n,prev_cosmo=0;
static double *x,*y,*y2;
int i;
float x1,x2,cfac;
double a,dm,x3,x4;
FILE *fp;
char fname[1000];
if(flag || RESET_COSMOLOGY!=prev_cosmo)
{
MSTAR = mstar();
if(OUTPUT)
fprintf(stdout,"Calc cvir with DELTA_HALO= %f\n",DELTA_HALO);
prev_cosmo=RESET_COSMOLOGY;
n=50;
if(flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
cvir_pnorm_g1=SIGMA_8/sigmac(8.0);
flag=0;
dm=(log(HOD.M_max)-log(1.0E8))/(n-1);
for(i=1;i<=n;++i)
{
x[i]=exp((i-1)*dm+log(1.0E8));
y[i]=cvir_model(x[i]);
x[i]=log(halo_mass_conversion(x[i],&y[i],DELTA_HALO));
y[i]=log(y[i]);
//y[i] = log(10);
}
spline(x,y,n,1.0E+30,1.0E+30,y2);
}
cfac = 0.13*log10(m/1.0e12) + 0.125;
cfac = 1;
if(m>80*MSTAR) m=80*MSTAR;
m=log(m);
splint(x,y,y2,n,m,&a);
return(exp(a)*cfac);
}
/* This is the cvir model, which should reproduce the results
* of cvir3.f, which can be obtained off James Bullock's web site.
*
* Basic idea; For a halo of mass M, find the collapse redshift
* of that halo be finding the redshift at which rms mass variance
* sigma(Mf) = DELTA_CRIT (using linear growth factor), where Mf is some
* fraction of the redshift zero halo mass.
*
* cvir = k*(1+z_coll(M*f))
*
* Model params:
* - k = 3.12 - fitting parameter (taken from cvir3.f)
* - f = 0.001 - fraction of halo mass that collapsed at z_coll
*/
double cvir_model(double mass)
{
double cvir,z_coll,zbrent(),rad;
double k=3.12;
double f=0.001;
rad=pow(3.0*f*mass/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
cvir_sigma_g1=cvir_pnorm_g1*sigmac(rad);
if(collapse_redshift(0.0)<0)return(k);
z_coll=zbrent(collapse_redshift,0.0,200.0,1.0E-3);
cvir=k*(1+z_coll);
return(cvir);
}
/* This is the input function to find where sig(M)*D(z)-DELTA_CRIT = 0
* which is the redshift at which a halo of mass M collapsed.
*/
double collapse_redshift(double z)
{
double D;
D=growthfactor(z);
return(cvir_sigma_g1*D-DELTA_CRIT);
}
/* Some quantities are specific to an overdensity of 200 (i.e., the Jenkins mass
* function and the halo bias relation of Tinker et al. )
* Specfically, these are actually for FOF 0.2 halos, for which 200 is the
* current best approximation. (Although Warren et al quotes 250, which is the most recent
* value.)
*
* Therefore, the halo concentrations for Delta=200 halos need to be easily
* accessible for halo mass conversion of these quantities. The values are
* tabulates here, as opposed to the above routine which tabulates the
* concentrations for a user-specified overdensity.
*/
double halo_c200(double m)
{
static int flag=1,n,prev_cosmo=0;
static double *x,*y,*y2;
int i;
float x1,x2;
double a,dm,x3,x4;
FILE *fp;
char fname[1000];
if(flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(OUTPUT)
fprintf(stdout,"Calc cvir with DELTA_HALO= %f\n",200.0);
prev_cosmo=RESET_COSMOLOGY;
n=50;
if(flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
cvir_pnorm_g1=SIGMA_8/sigmac(8.0);
flag=0;
dm=(log(HOD.M_max)-log(1.0E8))/(n-1);
for(i=1;i<=n;++i)
{
x[i]=exp((i-1)*dm+log(1.0E8));
y[i]=cvir_model(x[i]);
x[i]=log(halo_mass_conversion(x[i],&y[i],200.0));
y[i]=log(y[i]);
}
}
m=log(m);
splint(x,y,y2,n,m,&a);
return(exp(a));
}

View file

@ -0,0 +1,100 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
double m_g3,r_g3;
double func_ng(double m);
/* The restr
*/
double restricted_number_density(double r)
{
static int flag=1;
static double *x,*y;
int i,n=50,j;
double mlimit,dlogm,logm,mmin,sum=0,t0,t1,s1,r1,r2,ng2;
r_g3=r;
ng2=GALAXY_DENSITY*GALAXY_DENSITY;
/* Calculate the maximum allowable halo mass.
*/
mlimit=log(4./3.*DELTA_HALO*RHO_CRIT*PI*r_g3*r_g3*r_g3*OMEGA_M);
mmin=log(HOD.M_low);
r1=pow(3*HOD.M_low/(4*PI*DELTA_HALO*RHO_CRIT*OMEGA_M),1.0/3.0);
/* Calculate the double integral at specified masses.
*/
dlogm=(mlimit-mmin)/(n-1);
for(i=1;i<=n;++i)
{
logm=(i-0.5)*dlogm+mmin;
m_g3=exp(logm);
r2 = pow(3*m_g3/(4*PI*DELTA_HALO*RHO_CRIT*OMEGA_M),1.0/3.0);
if(EXCLUSION==3) {
if(ellipsoidal_exclusion_probability(r1/r2,r_g3/(r1+r2))==0)break; }
else {
if(r1+r2>r_g3)break; }
s1=qtrap(func_ng,mmin,mlimit,1.0E-4);
sum+=s1*m_g3*dlogm;
if(s1==0)break;
if(sum>=ng2)break;
}
return sqrt(sum);
}
double func_ng(double m)
{
static double fac2=-1;
double s1,rv1,rv2,exfac=1,n,N;
m=exp(m);
if(fac2<0)
fac2=pow(3.0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rv1=pow(m_g3,1.0/3.0)*fac2;
rv2=pow(m,1.0/3.0)*fac2;
if(EXCLUSION==3)
{
if(0.5*(rv1+rv2)>r_g3)return(0);
if(1.5*(rv1+rv2)>r_g3)exfac=ellipsoidal_exclusion_probability(rv2/rv1,r_g3/(rv2+rv1));
}
else
{
if(rv1+rv2>r_g3)return(0);
}
n=dndM_interp(m)*dndM_interp(m_g3);
N=N_avg(m)*N_avg(m_g3);
return(exfac*n*N*m);
}
/* This is the probability that two halos do not overlap, given their
* radii and separation. Of course, for spherical halos P(x) is a step function
* at x = (r1+r2)/r_sep = 1, but for ellipsoidal halos there is a chance
* that they could be closer. In detail, P(x) changes depending on the mass
* ratio of the halos, but using tabulated values does not appear to make
* significant difference in the results for xi_2h(r). The function below is
* a fit to Monte Carlo results for a halos with a distribution of axis ratios
* which is lognormal in e_b = (1-b/a) and e_c = (1-c/a) with dispersions of 0.2
* mean <b/a>=0.9 and <c/a>=0.8 (pretty reasonable values).
*/
double ellipsoidal_exclusion_probability(double rv, double r)
{
static int flag=0,nr=101,nratio=31;
static double **xprob,*rad,*ratio,rhi,rlo,mhi,mlo,dr,dm;
float x1,x2,x3;
int i,j,im,ir;
FILE *fp;
if(rv<1)rv=1.0/rv;
r=(r-0.8)/0.29;
if(r>1)return(1.0);
if(r<0)return(0.0);
return(3*r*r-2*r*r*r);
}

View file

@ -0,0 +1,86 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "header.h"
/* This is a routine which takes a virial mass (as defined by the virial
* overdensity relation (see fitting formula of Bryan & Normax)
* and converts if to a mass of some given overdensity. This is all
* taken from the appendix of Hu & Kravtsov. 2003ApJ...584..702H
*/
/* Constants from conversion formula in Hu & Kravtsov (2003)
*/
#define a1 0.5116
#define a2 -0.4283
#define a3 -3.13E-3
#define a4 -3.52E-5
double HK_func(double x);
double halo_mass_conversion(double mvir, double *cvir1, double delta_halo)
{
double x,y,z,vx,vy,vz,x1,x2,x3,x4,omega_m,delta=180,mstar,delta_vir,delta_fof,p,f,
mp,v,mass,lambda,error,tol=1.0E-3,cprev,m_delta,delta_fac,cvir,rdelta,rvir;
cvir=*cvir1;
omega_m=OMEGA_M;
lambda=1-OMEGA_M;
mstar=MSTAR;
delta=delta_halo;
x=omega_m-1;
delta_vir=(18*PI*PI+82*x-39*x*x)/(1+x);
/* Now convert from virial mass to m_delta.
*/
f=delta/delta_vir*HK_func(1.0/cvir);
p=a2+a3*log(f)+a4*log(f)*log(f);
x1=1.0/sqrt(a1*pow(f,2*p)+0.5625)+2*f;
m_delta=mvir*(delta/delta_vir*pow(1.0/(x1*cvir),3.0));
/* Now convert the cvir to c_delta.
*/
rvir=pow(3*mvir/(4*delta_vir*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rdelta=pow(3*m_delta/(4*delta*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
*cvir1=cvir*rdelta/rvir;
return(m_delta);
}
/* This is a slight modification to the above routine-- instead of converting from
* the virial mass, it converts from a specified Delta to the other Delta.
* (so here the "_vir" quantities are any arbitrary input overdensity.)
*/
double halo_mass_conversion2(double mvir, double cvir1, double delta_vir, double delta_halo)
{
double x,y,z,vx,vy,vz,x1,x2,x3,x4,omega_m,delta=180,mstar,delta_fof,p,f,
mp,v,mass,lambda,error,tol=1.0E-3,cprev,m_delta,delta_fac,cvir,rdelta,rvir;
cvir=cvir1;
omega_m=OMEGA_M;
lambda=1-OMEGA_M;
mstar=MSTAR;
delta=delta_halo;
/* Now convert from virial mass to m_delta.
*/
f=delta/delta_vir*HK_func(1.0/cvir);
p=a2+a3*log(f)+a4*log(f)*log(f);
x1=1.0/sqrt(a1*pow(f,2*p)+0.5625)+2*f;
m_delta=mvir*(delta/delta_vir*pow(1.0/(x1*cvir),3.0));
/* Now convert the cvir to c_delta.
*/
rvir=pow(3*mvir/(4*delta_vir*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rdelta=pow(3*m_delta/(4*delta*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
return(m_delta);
}
double HK_func(double x)
{
return(x*x*x*(log(1+1.0/x)-1.0/(1+x)));
}

View file

@ -0,0 +1,338 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This is a calculation of the differential halo mass function of
* Jenkins et al 2001 (MNRAS 321, 372).
*
* Also included is the mass function from my own analysis, which is
* a variant of the Sheth-Tormen mass function (leaving all 3 parameters
* as free parameters), with a 2-parameter high-mass cutoff of the form
* suggested by Reed et al.
*
*/
void initialize_mass_function(double *a1, double *a2, double *a3, double *a4);
double halo_mass_function(double mass)
{
double sig,logm,a,slo,shi,rm,rlo,rhi,mlo,mhi,dsdM,n,nuprime,nufnu,p,A;
static int flag=0,SO180=0,SO324=0,WARREN=0,ST=0,JENKINS=0;
static double pnorm, prev_delta;
double btemp = -1;
static double
a1 = 0.325277,
a2 = 0.492785,
a3 = 0.310289,
a4 = 1.317104,
a5 = 2.425681;
/* Jenkins et al. SO 180 best-fit
*/
if(SO180)
{
JENKINS_A = 0.301;
JENKINS_B = 0.64;
JENKINS_C = 3.82;
}
if(SO324)
{
JENKINS_A = 0.316;
JENKINS_B = 0.67;
JENKINS_C = 3.82;
}
if(JENKINS) //their .2 fof function
{
JENKINS_A = 0.315;
JENKINS_B = 0.61;
JENKINS_C = 3.8;
}
/* First normalize the power spectrum
*/
pnorm=SIGMA_8/sigmac(8.0);
rm=pow(3.0*mass/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=pnorm*sigmac(rm);
logm=log10(mass);
mlo=0.99*mass;
mhi=1.01*mass;
rlo=pow(3.0*mlo/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
rhi=pow(3.0*mhi/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
slo=pnorm*sigmac(rlo);
shi=pnorm*sigmac(rhi);
dsdM=(shi-slo)/(mhi-mlo);
if(SO324)goto JENKINS_FUNCTION;
if(SO180)goto JENKINS_FUNCTION;
if(WARREN)goto WARREN_FUNCTION;
if(ST)goto ST_FUNCTION;
if(JENKINS)goto JENKINS_FUNCTION;
/* Tinker et al. (in prep) for SO 200
*/
if(DELTA_HALO != prev_delta)
{
initialize_mass_function(&a1,&a2,&a3,&a4);
prev_delta = DELTA_HALO;
// if we're using systematic errors in an MCMC, adjust parameter a1 (amplitude)
if(USE_ERRORS)
a1 *= M2N.mf_amp;
fprintf(stderr,"MF PARAMS for DELTA=%f %f %f %f %f\n",DELTA_HALO,a1,a2,a3,a4);
}
n = -a1*(pow(sig/a3,-a2)+1)*exp(-a4/sig/sig)*OMEGA_M*RHO_CRIT/mass/sig*dsdM;
return(n);
/* Jenkins et al. FOF .2 best-fit (unless SO180==1)
*/
JENKINS_FUNCTION:
a=-JENKINS_A*OMEGA_M*RHO_CRIT/mass/sig;
n=a*dsdM*exp(-pow(fabs(JENKINS_B-log(sig)),JENKINS_C));
return(n);
/* Warren et al. (calibrated only on concordance cosmology, FOF.2)
*/
WARREN_FUNCTION:
n = -0.7234*(pow(sig,-1.625)+0.2538)*exp(-1.198/sig/sig)*OMEGA_M*RHO_CRIT/mass/sig*dsdM;
return(n);
/* Need to find the derivative dlog(sig)/dlog(M)
*/
mlo=0.99*logm;
mhi=1.01*logm;
rlo=pow(3.0*pow(10.0,mlo)/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
rhi=pow(3.0*pow(10.0,mhi)/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
slo=log10(pnorm*sigmac(rlo));
shi=log10(pnorm*sigmac(rhi));
dsdM=(shi-slo)/(mhi-mlo);
ST_FUNCTION:
/* This is a bunch of Sheth-Tormen stuff.
* NB! because I'm skipping the above derivative (dlogs/dlogM), i'm using the lower
*/
nuprime=0.841*DELTA_CRIT/sig;
nufnu=0.644*(1+1.0/pow(nuprime,0.6))*(sqrt(nuprime*nuprime/2/PI))*exp(-nuprime*nuprime/2);
//n=RHO_CRIT*OMEGA_M/mass*mass*nufnu*fabs(dsdM);
n=RHO_CRIT*OMEGA_M/mass*nufnu*fabs(dsdM)/sig;
return(n);
}
/* It may be a bit costly to run the above function every time you need
* dn/dM, so here we put the values into an array and then interpolate.
*
* The currentrange of masses calculated is 10^9 to 10^16.7. The tabulation is
* done in log(M), so the spline interpolation will perform a power-law fit
* to masses outside this range.
*/
double dndM_interp(double m)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2;
int i,n=2000;
double dm,max=16.7,min=8,a,m1,m2,dm1;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting mass function for %f %f\n",OMEGA_M,SIGMA_8);
fflush(stdout);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dm=(double)(max-min)/n;
for(i=1;i<=n;++i)
{
x[i]=pow(10.0,min+i*dm);
y[i]=log(halo_mass_function(x[i]));
x[i]=log(x[i]);
continue;
/*
m1 = halo_mass_conversion2(x[i]*1.001,halo_concentration(x[i]*1.001),DELTA_HALO,200);
m2 = halo_mass_conversion2(x[i]*0.999,halo_concentration(x[i]*0.999),DELTA_HALO,200.0);
dm1 = (x[i]*1.001 - x[i]*0.999)/(m1-m2);
y[i] = y[i] + log(dm1);
x[i]=log(halo_mass_conversion2(x[i],halo_concentration(x[i]),DELTA_HALO,200.0));
printf("%e %e %e %e\n",exp(x[i]),exp(y[i]),0.1*exp(y[i]),0.1);
continue;
*/
if(DELTA_HALO!=200)
{
m1 = halo_mass_conversion2(x[i]*1.001,halo_c200(x[i]*1.001),200.0,DELTA_HALO);
m2 = halo_mass_conversion2(x[i]*0.999,halo_c200(x[i]*0.999),200.0,DELTA_HALO);
dm1 = (x[i]*1.001 - x[i]*0.999)/(m1-m2);
y[i] = y[i] + log(dm1);
x[i]=log(halo_mass_conversion2(x[i],halo_c200(x[i]),200.0,DELTA_HALO));
}
else
x[i]=log(x[i]);
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
//exit(0);
m=log(m);
splint(x,y,y2,n,m,&a);
return(exp(a));
}
/* Reads mass function in from a file and spline interpolates.
*/
double nbody_massfunction(double m)
{
static int flag=0,n;
static double *x,*y,*y2,log10_2,normhi,normlo;
float x1,x2,x3;
int i;
double a,dx;
char aa[1000];
FILE *fp;
if(!flag)
{
log10_2=log10(2.0);
flag++;
if(!(fp=fopen(Files.MassFuncFile,"r")))
endrun("ERROR opening MassFuncFile");
i=0;
n = filesize(fp);
fprintf(stderr,"Read %d lines from [%s]\n",n,Files.MassFuncFile);
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
for(i=1;i<=n;++i)
{
fscanf(fp,"%f %f",&x1,&x2);
x[i]=log(x1);
y[i]=log(x2);
fgets(aa,1000,fp);
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
fclose(fp);
fprintf(stderr,"Minimum halo mass in N-body dndM= %e\n",exp(x[1]));
normhi = exp(y[n])/halo_mass_function(exp(x[n]));
normlo = exp(y[1])/halo_mass_function(exp(x[1]));
}
m=log(m);
// if(m>x[n])return(0);
/*if(m<x[1])return(0);*/
if(m>x[n])
return(halo_mass_function(exp(m))*normhi);
if(m<x[1])
return(halo_mass_function(exp(m))*normlo);
splint(x,y,y2,n,m,&a);
/*if(m<x[1])printf("LESS %e %e %e\n",pow(10.0,m),pow(10.0,a),pow(10.0,y[1]));*/
return(exp(a));
}
void initialize_mass_function(double *a1, double *a2, double *a3, double *a4)
{
int n = 9, i;
double *x, *y, *z, at, ztemp;
x = dvector(1,n);
y = dvector(1,n);
z = dvector(1,n);
// initialize the overdensities
for(i=1;i<=9;i+=2)
x[i] = log(200*pow(2.0,(i-1.0)/2.0));
for(i=2;i<=9;i+=2)
x[i] = log(300*pow(2.0,(i-2.0)/2.0));
//first parameter
y[1] = 1.858659e-01 ;
y[2] = 1.995973e-01 ;
y[3] = 2.115659e-01 ;
y[4] = 2.184113e-01 ;
y[5] = 2.480968e-01 ;
y[6] = 2.546053e-01 ;
y[7] = 2.600000e-01 ;
y[8] = 2.600000e-01 ;
y[9] = 2.600000e-01 ;
spline(x,y,n,1.0E+30,1.0E+30,z);
splint(x,y,z,n,log(DELTA_HALO),a1);
if(DELTA_HALO>=1600) *a1 = 0.26;
//second parameter
y[1] = 1.466904e+00 ;
y[2] = 1.521782e+00 ;
y[3] = 1.559186e+00 ;
y[4] = 1.614585e+00 ;
y[5] = 1.869936e+00 ;
y[6] = 2.128056e+00 ;
y[7] = 2.301275e+00 ;
y[8] = 2.529241e+00 ;
y[9] = 2.661983e+00 ;
spline(x,y,n,1.0E+30,1.0E+30,z);
splint(x,y,z,n,log(DELTA_HALO),a2);
//third parameter
y[1] = 2.571104e+00 ;
y[2] = 2.254217e+00 ;
y[3] = 2.048674e+00 ;
y[4] = 1.869559e+00 ;
y[5] = 1.588649e+00 ;
y[6] = 1.507134e+00 ;
y[7] = 1.464374e+00 ;
y[8] = 1.436827e+00 ;
y[9] = 1.405210e+00 ;
spline(x,y,n,1.0E+30,1.0E+30,z);
splint(x,y,z,n,log(DELTA_HALO),a3);
//fourth parameter
y[1] = 1.193958e+00;
y[2] = 1.270316e+00;
y[3] = 1.335191e+00;
y[4] = 1.446266e+00;
y[5] = 1.581345e+00;
y[6] = 1.795050e+00;
y[7] = 1.965613e+00;
y[8] = 2.237466e+00;
y[9] = 2.439729e+00;
spline(x,y,n,1.0E+30,1.0E+30,z);
splint(x,y,z,n,log(DELTA_HALO),a4);
// now adjust for redshift
if(!(REDSHIFT>0))return;
ztemp = REDSHIFT;
if(REDSHIFT>3) ztemp = 3.0;
*a1 *= pow(1+ztemp,-0.14);
*a2 *= pow(1+ztemp,-0.14);
at = -pow(0.75/log10(DELTA_HALO/75),1.2);
at = pow(10.0,at);
*a3 *= pow(1+ztemp,-at);
}

View file

@ -0,0 +1,146 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This is a calculation of the differential halo mass function of
* Jenkins et al 2001 (MNRAS 321, 372).
*
* Also included is the mass function from my own analysis, which is
* a variant of the Sheth-Tormen mass function (leaving all 3 parameters
* as free parameters, with a 2-parameter high-mass cutoff of the form
* suggested by Reed et al.
*
*/
double halo_mass_function(double mass)
{
double sig,logm,a,slo,shi,rm,rlo,rhi,mlo,mhi,dsdM,n,nuprime,nufnu,p,A;
static int flag=0, prev_cosmo=-1,na=4;
static double pnorm,*xa,*ya,*za;
double fac1,fac2,fac;
static long IDUM=-555;
int i;
static double
a1 = 0.325277,
a2 = 0.492785,
a3 = 0.310289,
a4 = 1.317104,
a5 = 2.425681;
if(!flag)
{
xa=dvector(1,na);
ya=dvector(1,na);
za=dvector(1,na);
flag=1;
xa[1] = log(1/2.51);
xa[2] = log(1/1.49);
xa[3] = log(1/0.905);
xa[4] = log(1/0.501);
}
if(prev_cosmo != RESET_COSMOLOGY)
{
prev_cosmo=RESET_COSMOLOGY;
for(i=1;i<=4;++i)
ya[i] = gasdev(&IDUM);
spline(xa,ya,na,1.0E+30,1.0E+30,za);
}
/* First normalize the power spectrum
*/
pnorm=SIGMA_8/sigmac(8.0);
rm=pow(3.0*mass/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=pnorm*sigmac(rm);
logm=log10(mass);
mlo=0.99*mass;
mhi=1.01*mass;
rlo=pow(3.0*mlo/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
rhi=pow(3.0*mhi/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
slo=pnorm*sigmac(rlo);
shi=pnorm*sigmac(rhi);
dsdM=(shi-slo)/(mhi-mlo);
if(BEST_FIT)
{
n = a1*sqrt(2*a2/PI)*(1+pow(sig*sig/(a2*DELTA_CRIT*DELTA_CRIT),a3))
*DELTA_CRIT/sig*exp(-a2*DELTA_CRIT*DELTA_CRIT/(2*sig*sig))
*exp(-a4/sig/pow(fabs(cosh(2*sig)),a5));
splint(xa,ya,za,na,log(1/sig),&fac1);
fac2 = 0.00562*pow(sig,-2.9) + 0.00158*pow(sig,2.2);
fac = 1 + fac1*fac2;
if(fac<0.01)fac=0.01;
n = n*fac;
/* printf("%e %e %e %e\n",sig,n,n/fac,fac); */
n = -n*OMEGA_M*RHO_CRIT/mass/sig*dsdM;
return(n);
}
/* Jenkins et al.
*/
a=-JENKINS_A*OMEGA_M*RHO_CRIT/mass/sig;
n=a*dsdM*exp(-pow(fabs(JENKINS_B-log(sig)),JENKINS_C));
return(n);
}
/* It may be a bit costly to run the above function every time you need
* dn/dM, so here we put the values into an array and then interpolate.
*/
double dndM_interp(double m)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2;
int i,n=1000;
double dm,max=16.7,min=9,a,m1,m2,dm1;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting mass function for %f %f\n",OMEGA_M,SIGMA_8);
fflush(stdout);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dm=(double)(max-min)/n;
for(i=1;i<=n;++i)
{
x[i]=pow(10.0,min+i*dm);
y[i]=log(halo_mass_function(x[i]));
if(DELTA_HALO!=200)
{
m1 = halo_mass_conversion2(x[i]*1.001,halo_c200(x[i]*1.001),DELTA_HALO,200.0);
m2 = halo_mass_conversion2(x[i]*0.999,halo_c200(x[i]*0.999),DELTA_HALO,200.0);
dm1 = (x[i]*1.001 - x[i]*0.999)/(m1-m2);
y[i] = y[i] + log10(dm1);
x[i]=log10(halo_mass_conversion2(x[i],halo_c200(x[i]),DELTA_HALO,200.0));
}
else
x[i]=log(x[i]);
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
m=log(m);
splint(x,y,y2,n,m,&a);
return(exp(a));
}

96
c_tools/hod/header.c Normal file
View file

@ -0,0 +1,96 @@
#include <stdlib.h>
#include "header.h"
/* These are the globale variables. When needed, each is set to the
* default value. Those without defualt values are either calculated
* or set in the batfile.
*/
double GAMMA=0.2, /* Shape parameter of EBW power spectrum */
HUBBLE=0.7, /* Hubble in 100 km/s/Mpc (not realy used in code). */
SIGMA_8=0.95, /* Normalization of power spectrum */
RHO_CRIT=2.775e11, /* Critial mass density in h^2 M_sun/Mpc^3 */
SPECTRAL_INDX=1.0, /* n_s -> P(k) = k^n_s */
OMEGA_M=0.1, /* Matter density */
OMEGA_TEMP=0.3, /* For M/L minimization */
OMEGA_B=0.0, /* Baryon density */
DELTA_CRIT=1.686, /* Critical overdensity for linear collapse */
MSTAR, /* Mass scale at which sigm(M) = DELTA_CRIT */
GALAXY_DENSITY, /* Number density of galaxies (Mpc/h)^-3 */
GALAXY_DENSITY2, /* Number density of SECOND SET of galaxies (Mpc/h)^-3 (for x-corr)*/
GRAVITY, /* Newton's constant in internal units. */
BOX_SIZE, /* Size of box, if comparing to simulations. */
RESOLUTION, /* Simulations: BOX_SIZE/np^(1/3) */
R_MIN_2HALO=-1.0, /* Minimum scale of two-halo pairs, set by halo exclusion */
MASS_PER_PARTICLE, /* Simulations: mass in M_sol/h */
GALAXY_BIAS, /* Large scale bias of galaxies w.r.t linear matter distribution */
DELTA_HALO=200, /* Overdensity which defines the edge of a halo. */
VBIAS=1.0, /* Velocity bias of satellite galaxies. */
VBIAS_SLOPE=0.00, /* Slope of velocity bias relation with halo mass. */
VBIAS_MASS_THRESHOLD=0, /* Threshold mass above which there is no velocity bias. */
VBIAS_C=0.00, /* Velocity bias of central galaxies. */
CVIR_FAC=1.0, /* Ratio between galaxy and dark matter concentrations */
BIAS_A=0.707, /* parameter for halo bias function (Tinker et all 2005 App. A) */
BIAS_B=0.35, /* parameter for halo bias function (adapted from Sheth Mo Tormen) */
BIAS_C=0.8, /* parameter for halo bias function */
JENKINS_A=0.315, /* Jenkins mass function--> normalization */
JENKINS_B=0.61, /* Jenkins mass function--> constant in exponential */
JENKINS_C=3.8, /* Jenkins mass function--> exponent in exponential */
DNDM_PARAMS[10], /* Holds parameters for 5-param dndM fit */
MAXVEL=4000, /* maximum velocity in the P(vz) lookup table (set later) */
SIGV=500, /* Free parameter for Kaiser model */
BETA, /* Redshift-space distortion parameter. */
XI_MAX_RADIUS=0, /* Maximum radial value of 2-halo term */
LOCAL_DENSITY=0, /* for Hubble Bubble calculations--> change the mass function */
MASS_THRESHOLD=0, /* Mass at which you turn on change in HOD */
REDSHIFT=0, /* redshift */
DENSITY_THRESHOLD=0; /* Density at which you turn on change in HOD. */
int ITRANS=4, /* Type of transfer function to be used */
RESET_KAISER=0, /* Flag to reset tabulated Kaiser distortion quantities */
RESET_COSMOLOGY=0, /* Flag to recalculate tabulated quantities (e.g. b(M), dn/dM...) */
SOFT_CENTRAL_CUTOFF=0, /* Whether N_cen is a step function or not */
NUM_POW2MASS_BINS, /* Number of mass bins for velocity PDF calculation */
RESET_PVZ=0, /* Flag to recalculate velocity PDF table */
COVAR=1, /* Flag to use covariance matrix for wp chi^2 */
PCA=0, /* Flag to use principle component analysis for chi^2 calc */
COVARZ=0, /* Flag to use covariance matrix for xi(s,p) chi^2*/
EXCLUSION=2, /* Type of two-halo exclusion ("spherical" is default) */
FIX_PARAM=1, /* Which parameter to leave free for fixing ng (1=M_min)*/
DEPROJECTED=0, /* Fit 3-space data rather than wp(rp) */
OUTPUT=1, /* Flag to output diagnostic information */
POWELL=1, /* minimization technique 1=POWELL, 0=AMOEBA */
MCMC=0, /* Flag for doing Markov Chain analysis */
LINEAR_PSP=0, /* Flag for using linear P(k) for two-halo term. (Instead of Smith)*/
KAISER=0, /* Flag for using Kaiser linear+exponential model */
ERROR_FLAG=0, /* Global notification of problem with qromo/zbrent/etc */
BEST_FIT=0, /* Use best-fit mass function, bias from Tinker et al's analysis */
RESET_FLAG_2H=0, /* Flag to recalculate 2-halo term */
RESET_FLAG_1H=0, /* Flag to recalculate 1-halo term */
IVFLAG=0,
WP_ONLY=0, /* =1 use only wp, =0 use n(N) and M/L (+others in ml_min.c) */
GAO_EFFECT=0, /* =1 means that HOD changes in high density, =0 means lo den change.*/
N_HOD_PARAMS=9, /* number of possible parameters for HOD. for use w/ MCMC */
XCORR=0, /* flag for cross-correlation */
RESTART = 0, /* For restarting an MCMC chain (ml only) */
USE_ERRORS = 0, /* Flag for using systematic errors on massfunc, bias, etc in MCMC */
DENSITY_DEPENDENCE = 0; /* Flag for den-dep HOD. */
char RESTART_FILE[100]; /* previous output file from which to restart chain */
long IDUM_MCMC=-555; /* Random seed to start Markov Chain. */
/* These are for the parallel implementation, an ID for each
* processor and the total number of processors.
*/
int ThisTask=0,
NTask=1;
struct hod_parameters HOD,HOD2,HODt;
struct file_parameters Files;
struct perform_tasks Task;
struct workspace Work;
struct COLOR_DATA wp_color;
struct m2n_workspace M2N;

536
c_tools/hod/header.h Normal file
View file

@ -0,0 +1,536 @@
#include "nrutil.h"
#include "stdlib.h"
#include "stdio.h"
/* Function prototypes--> utility files
*/
double second(void);
double timediff(double t0,double t1);
void endrun(char *instring);
FILE *openfile(char *ff);
int filesize(FILE *fp);
void least_squares(double *x, double *y, int n, double *a, double *b);
void check_for_smoothness(double *x, double *y, int n, double r);
void read_parameter_file(char *fname);
void output_parameter_file(char *fname);
double ***d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_d3tensor(double ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
/* Function prototypes--> general control of tasks
*/
void tasks(int argc, char **argv);
/* Function prototypes--> numerical recipes
*/
double qromo(double (*func)(double), double a, double b,
double (*choose)(double(*)(double), double, double, int));
void polint(double xa[], double ya[], int n, double x, double *y, double *dy);
double midpnt(double (*func)(double), double a, double b, int n);
double midinf(double (*funk)(double), double aa, double bb, int n);
void splint(double xa[], double ya[], double y2a[], int n, double x, double *y);
void spline(double x[], double y[], int n, double yp1, double ypn, double y2[]);
double zbrent(double (*func)(double), double x1,double x2, double tol);
double qtrap(double (*func)(double), double a, double b, double EPS);
void powell(double p[], double **xi, int n, double ftol, int *iter, double *fret,
double (*func)(double []));
void amoeba(double **p, double y[], int ndim, double ftol,
double (*funk)(double []), int *nfunk);
void gaussj(double **a, int n, double **b, int m);
float gasdev(long *idum);
void jacobi(double **a, int n, double d[], double **v, int *nrot);
float ran1(long *idum);
double ran2(long *idum);
double trapzd(double (*func)(double), double a, double b, int n);
void sort2(unsigned long n, float arr[], int id[]);
/* Function prototypes--> power spectrum routines.
*/
double transfnc(double xk);
double sigmac(double rad);
double nonlinear_sigmac(double rad);
double transfunc_file(double xk);
double nonlinear_power_spectrum(double xk);
double linear_power_spectrum(double xk);
double mstar(void);
double tf_eisenstein_hu(double k);
double cobenorm(double omega_m);
double cobe_prior(double omega_m);
double sigmac_interp(double m);
double sigmac_radius_interp(double m);
/* Function prototypes--> matter correlation function routines.
*/
double xi_interp(double r);
double xi_linear_interp(double r);
double projected_xi_matter(double r);
/* Function protoypes--> outputting matter stats
*/
void output_matter_power_spectrum(void);
void output_matter_correlation_function(void);
void output_matter_variance(void);
void output_halo_concentrations(void);
void output_halo_mass_function(void);
void output_halo_correlation_function(double mass);
/* Function prototypes--> HOD functions (+related);
*/
double N_avg(double m);
double N_cen(double m);
double N_sat(double m);
double moment_ss(double m);
double func_galaxy_density(double m);
double func_satfrac(double m);
void set_HOD_params(void);
double set_low_mass(void);
double set_high_central_mass(void);
double N_cen_i(double m, int ii);
double satellite_blue_fraction(double m);
double central_blue_fraction(double m);
double func_central_density(double m);
double func_satellite_density(double m);
double number_weighted_central_mass(void);
double number_weighted_halo_mass(void);
/* Density-dependent HOD functions
*/
void dd_hod_functions(float *hmass, float *hdensity, int nhalo);
int internal_populate_simulation(float *x, float *y, float *z, float reduction_factor, int ivel,
float *vx, float *vy, float *vz);
/* Function prototypes--> HOD functions for second HOD (+related);
*/
double N_avg2(double m);
double N_cen2(double m);
double N_sat2(double m);
double moment_ss2(double m);
double func_galaxy_density2(double m);
double func_satfrac2(double m);
void set_HOD2_params(void);
double set_low_mass2(void);
double set_high_central_mass2(void);
/* Function prototypes--> halo mass function.
*/
double halo_mass_function(double mass);
double dndM_interp(double m);
/* Function prototypes--> halo bias.
*/
double bias_interp(double m, double r);
double bias(double m);
double func_galaxy_bias(double m);
/* Function prototypes--> halo profile: pair density
*/
double dFdx_ss(double x, double c_NFW);
double dFdx_cs(double x, double c_NFW);
double dFdx_ss_interp(double r, double c);
double dFdx_cs_interp(double r, double c);
double nfw_transform(double xk, double m);
/* Function prototypes--> real-space galaxy correlation function.
*/
double one_halo_real_space(double r);
double two_halo_real_space(double r);
double ellipsoidal_exclusion_probability(double rv, double r);
double restricted_number_density(double r);
double projected_xi(double r);
double projected_xi_rspace(double r);
double nbody_xi(double r);
double integrated_wp_bin(double r);
/* Function prototypes--> redshift-space galaxy correlation function.
*/
double one_halo(double rs, double rp);
double two_halo(double rs, double rp);
void xi_multipoles(void);
double small_scale_measure(double rs);
void calc_rhalf(double r[], double rhalf[], int nr);
double integrated_bin(double xlo, double ylo, double dx1, double dy1, int n);
void linlin_bins(void);
double xi2d_interp(double rs1, double rp1, double rs2, double rp2);
double xi2d_interp_polar(double rs1, double rs2, double phi1, double phi2);
/* Function prototypes--> halo pairwise velocity model
*/
double spherical_collapse_model(double delta);
double galaxy_prob_vz(double vel, double rad, double theta);
void vdelta_v4(double m0, double m1, double rad, double theta, double binsize,
double v0, int nv, double *a, double *pv, double *pt, double *pz,
double wgal[3], double sgal[4]);
void pairwise_velocity_dispersion(void);
void output_velocity_moments(int imass);
double jeans_dispersion(double mass, double rx, double v[]);
/* Function prototypes--> halo concentrations.
*/
double growthfactor(double z);
double halo_concentration(double m);
double cvir_model(double mass);
double halo_mass_conversion(double mvir, double *cvir1, double delta_halo);
double halo_mass_conversion2(double mvir, double cvir1, double delta_vir, double delta_halo);
double halo_c200(double m);
double HK_func(double x);
/* Function prototypes--> HOD fitting of correlation functions.
*/
void wp_minimization(char *fname);
void mcmc_minimization(void);
void zspace_minimization(char *fname);
double chi2_wp(double *a);
double chi2_zspace(double *a);
void fit_color_samples(void);
/* Function prototypes--> Linear+exponential model.
*/
double kaiser_distortion(double rs, double rp);
void fit_dispersion_model(void);
double linear_kaiser_distortion(double rs, double rp);
/* Function prototypes--> Jean's solution to velocity dispersions.
*/
double satellite_dispersion(double r, double rs, double rvir);
double velocity_dispersion_profile(double sig, double cvir, double rvir, double r);
/* Function prototypes--> random position/velocities of sat gals (simulation population)
*/
void populate_simulation(void);
void populate_sampled_simulation(void);
double NFW_density(double r, double rs, double ps);
double NFW_velocity(double mass, double v[], double mag);
double NFW_position(double mass, double x[]);
int poisson_deviate(double nave);
double poisson_prob(int n, double nave);
/* Definitions
*/
#define PI 3.14159265358979323846
#define TWOPI (2*PI)
#define THIRD (1.0/3.0)
#define ROOT2 1.41421356237309504880
#define RT2PI 2.50662827463100050241
#define LN_2 0.6931471805599452
#define ROOT8 2.82842712475
#define WORKBUF 1000
#define LOGE_10 2.30258509
#define c_on_H0 3000
#define mabs(A) ((A) < 0.0 ? -(A) : (A))
#define cnint(x) ((x-floor(x)) < 0.5 ? floor(x) : ceil(x))
#define muh(x) fprintf(stdout,"%d\n",x);fflush(stdout)
#define fmuh(x) fprintf(stderr,"%e\n",x)
#define square(x) (x*x)
/* Global variables
*/
extern double
GAMMA,
HUBBLE,
SIGMA_8,
RHO_CRIT,
SPECTRAL_INDX,
OMEGA_M,
OMEGA_B,
OMEGA_TEMP,
DELTA_CRIT,
MSTAR,
GALAXY_DENSITY,
GALAXY_DENSITY2,
NG_ONE_HALO,
GRAVITY,
VZ_LIMIT,
BOX_SIZE,
RESOLUTION,
R_MIN_2HALO,
MASS_PER_PARTICLE,
GALAXY_BIAS,
DELTA_HALO,
VBIAS,
VBIAS_SLOPE,
VBIAS_C,
VBIAS_MASS_THRESHOLD,
CVIR_FAC,
MAXVEL,
BIAS_A,
BIAS_B,
BIAS_C,
JENKINS_A,
JENKINS_B,
JENKINS_C,
DNDM_PARAMS[10],
SIGV,
BETA,
XI_MAX_RADIUS,
MASS_THRESHOLD,
DENSITY_THRESHOLD,
REDSHIFT,
LOCAL_DENSITY;
extern int RESET_COSMOLOGY,
RESET_KAISER,
ITRANS,
COVAR,
PCA,
COVARZ,
EXCLUSION,
SOFT_CENTRAL_CUTOFF,
NUM_POW2MASS_BINS,
FIX_PARAM,
DEPROJECTED,
OUTPUT,
POWELL,
MCMC,
BEST_FIT,
LINEAR_PSP,
KAISER,
RESET_PVZ,
ERROR_FLAG,
RESET_FLAG_2H,
RESET_FLAG_1H,
GAO_EFFECT,
IVFLAG,
WP_ONLY,
N_HOD_PARAMS,
XCORR,
RESTART,
USE_ERRORS,
DENSITY_DEPENDENCE;
extern char RESTART_FILE[100];
extern long IDUM_MCMC;
/* These are variables for the parallel implementation.
*/
extern int ThisTask,NTask;
/* HOD parameters. For definitions, look at the comments in
* hod_functions.c
*/
extern struct hod_parameters {
double M_min;
double M_max;
double M1;
double M_cut;
double M_low,M_low0;
double M_hi;
double sigma_logM;
double alpha;
double MaxCen;
double M_cen_max;
double fblue0_cen;
double sigma_fblue_cen;
double fblue0_sat;
double sigma_fblue_sat;
double blue_fraction;
int color;
int pdfc;
int pdfs;
int free[100];
int i_wp;
double M_sat_break;
double alpha1;
double M_min_loden;
double M_min_hiden;
double M_min_fac;
} HOD, HOD2, HODt;
/* Structure to keep information/data about fitting
* color-defined samples.
*/
struct COLOR_DATA {
int ON;
double ngal_red;
double ngal_blue;
double ngal_full;
int n_red;
int n_blue;
int n_full;
double *r_red,*r_blue,*r_full;
double *e_red,*e_blue,*e_full;
double *x_red,*x_blue,*x_full;
double **covar_red, **covar_blue, **covar_full;
} wp_color;
/* This is to put the work done in xi_multipoles into
* a global space.
*/
extern struct workspace {
int nrad;
int n_mono;
int n_quad;
int n_half;
int n_z;
int SDSS_bins;
double rad[WORKBUF];
double r_mono[WORKBUF];
double r_quad[WORKBUF];
double r_half[WORKBUF];
double rsigma[WORKBUF][WORKBUF];
double rpi[WORKBUF][WORKBUF];
double xi_mono[WORKBUF];
double xi_quad[WORKBUF];
double xi_half[WORKBUF];
double xi_z[WORKBUF][WORKBUF];
double data_m[WORKBUF];
double covar_m[WORKBUF][WORKBUF];
double data_q[WORKBUF];
double covar_q[WORKBUF][WORKBUF];
double data_h[WORKBUF];
double covar_h[WORKBUF][WORKBUF];
double data_z[WORKBUF][WORKBUF];
double err_m[WORKBUF];
double err_q[WORKBUF];
double err_h[WORKBUF];
double err_z[WORKBUF][WORKBUF];
double **covarz;
int n_ze;
char covarz_file[WORKBUF];
double rmlo,rmhi;
double rqlo,rqhi;
double rhlo,rhhi;
double zlo,zhi;
int ncf;
double cf[WORKBUF];
int chi2;
int imono;
int imono_covar;
int iquad;
int iquad_covar;
int ihalf;
int ihalf_covar;
int izspace;
int imodel;
int i_quad2mono;
int i_monopole;
char monofile[WORKBUF];
char monocovarfile[WORKBUF];
char quadfile[WORKBUF];
char quadcovarfile[WORKBUF];
char halffile[WORKBUF];
char halfcovarfile[WORKBUF];
char esysfile[WORKBUF];
char zfile[WORKBUF];
double absolute_error;
double percentage_error;
double eq_abs;
double em_abs;
double em_per;
double eh_per;
int use_asymptotic_values;
int iout;
int SysErrFlag;
double *psp[6];
double r_2h[6][100];
double xi_2h[6][100];
int n_2h[6];
} Work;
extern struct m2n_workspace {
int ndata;
float *mass, *m2n, *err, *radius;
int *Ngals_lo, *Ngals_hi, current_Ngals, current_bin;
char m2n_filename[100];
double *model_m2n, *model_mass;
int counts_nbins, *counts_N200;
double *ndens_N200;
// systematic errors in the modeling
// to modify things like bias, scale-bias, mass function
double bias_err, bias_amp;
double mf_err, mf_amp;
double scalebias_err, scalebias_amp;
long IDUM;
} M2N;
/* Various input files and flags on whether or not to use them.
*/
extern struct file_parameters {
char HaloFile[1000];
char HaloDensityFile[1000];
char TF_file[100];
char TwoHaloFile[100];
int i_TwoHalo;
char MassFuncFile[100];
int i_MassFunc;
char PDFTable[100];
int i_PDFTable;
char PSPFile[100];
int i_Cvir;
char CvirFile[100];
char HaloFileFormat[100];
} Files;
/* Various tasks the the program will perform
*/
extern struct perform_tasks {
int All;
int real_space_xi;
int z_space_xi;
int kaiser_xi;
int multipoles;
int r_half;
int wp_minimize;
int zspace_minimize;
int MCMC;
int HOD;
int PVD;
int populate_sim;
int matter_xi;
int matter_pk;
int sigma_r;
int cvir;
int dndM;
char root_filename[100];
} Task;
/* Workspace for w_p minimzation.
*/
struct WP {
double **covar;
int np;
int ncf;
int ncf_tot;
double pi_max;
double *r;
double *x;
double *e;
char fname_covar[100];
char fname_wp[100];
int format;
int iter;
double esys;
double *eigen;
int npca;
double ngal;
double ngal_err;
int n_wp;
double fsat_all, fsat_red, fsat_blue;
} wp;

598
c_tools/hod/hod_functions.c Normal file
View file

@ -0,0 +1,598 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This file holds several useful functions for the HOD, such as the number of
* central and satellite halos, their second moment.
*
* This also intializes the HOD parameters.
*/
/* internal routines.
*/
double fixfunc1(double m);
double fixfunc2(double m);
double func_mlow(double m);
double func_mhi(double m);
double one_halo_from_file(double m);
/*****************
* DIFFERENT HOD PARAMETERIZATIONS: (1) Central galaxies
*
* This integer HOD.pdfc controls the parameterization of the central occupation.
* (I realize 'pdf' is not the right acronym, but it's a holdover from old code.)
*
* For soft central cutoffs, the PDF is the nearest integer distribution, AKA
* Bernoulli distribution.
*
* 0 = No galaxies, just halos. (always returns 1)
* 1 = Hard cutoff at M_min. Unity above M_min. (DEFAULT)
* 2 = Soft cutoff of the form 0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM)
* 3 = Soft cutoff of the form N_cen = exp(-HOD.M_min/m)
* 4 = Hard cutoff, but N_cen -> 0 for M>M_min (i.e., blue galaxies)
* MaxCen*exp(-(lgM-lgM_min)**2/2/(sigma_logM)**2)
* NB! -> The value of N_cen(M_min) can be < 1. (It will== MaxCen)
* 5 = Hard Cutoff, Step function, but N_cen != 1, but some number < 1.
* 6 = Same as 4, but symmetric Gaussian around M_min (This is for mag bins.)
* 7 = A sqaure function. N_cen=1 for M_min <= m <= M_cen_max (for mag bin data)
* 8 = A sqaure function (like case 7) but with Gaussian cutoffs on either edge
* instead of sharp cutoffs.
*
* 9 = Magnitude bin model, but the upper mass cutoff is defined by the lower
* mass cutoff of the next-highest bin. (see function in ml_minimization.c)
*
* M_low is a parameter created to keep the integrals from having to go to M=0 for
* soft central cutoffs. N_cen(mlow) = 1.0E-3;
* If the value of sigma_logM gets above 1 or so, then M_low can be rediculously
* small, so I have placed a lower limit on M_low of 1.0E+7 Msol/h
*/
double N_cen(double m)
{
double x,f=1;
//return(one_halo_from_file(m));
if(HOD.color)
f=central_blue_fraction(m);
switch(HOD.pdfc) {
case -1:
return 0;
case 0:
return 1;
case 1:
if(m<HOD.M_min)return(0);
return(f*1.0);
break;
case 2:
return(f*HOD.MaxCen*0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM)));
break;
case 3:
return(f*exp(-HOD.M_min/m));
break;
case 4:
if(m<HOD.M_min)return(0);
x = (log10(m) - log10(HOD.M_min))/HOD.sigma_logM;
return(f*HOD.MaxCen*exp(-x*x/2));
case 5:
if(m<HOD.M_min)return(0);
return(f*HOD.MaxCen);
case 6:
x = (log10(m) - log10(HOD.M_min))/HOD.sigma_logM;
return(f*HOD.MaxCen*exp(-x*x/2));
case 7:
if(m>=HOD.M_min && m<=HOD.M_cen_max)return(f);
return(0);
case 8:
if(m>=HOD.M_min && m<=HOD.M_cen_max)return(f);
if(m<HOD.M_low)return(0);
if(m<HOD.M_min)
x = (log10(m) - log10(HOD.M_min))/HOD.sigma_logM;
else
x = (log10(m) - log10(HOD.M_cen_max))/HOD.sigma_logM;
return(f*exp(-x*x/2));
default:
endrun("Illegal value of HOD.pdfc.");
}
return 0;
}
/*****************
* DIFFERENT HOD PARAMETERIZATIONS: (1) Satellite galaxies
*
* This integer HOD.pdfs controls the parameterization of the satellite occupation.
*
* 0 = halos only, no galaxies (always returns zero)
* 1 = power law: N_sat = pow(m/HOD.M1,HOD.alpha) [cut off at M_low]
* 2 = power law with soft cutoff: N_sat = pow((m-HOD.M_cut)/HOD.M1,alpha)
* 3 = power law with exp cutoff: N_sat = pow(m/HOD.M1,alpha)*exp(-M_cut/(m-M_min))
* 4 = broken power law with exp cutoff (alpha changes at some high mass value)
* 5 = broken power law (m-mcut)/m1 parameterization
* 6 = power with alternate exp cutoff: N_sat = pow(m/M1)*exp(-M_min/m)
* 7 = from Zheng's new paper lognormal cutoff power law
* 8 = power with Conroy exp cutoff: N_sat = pow(m/M1)*exp(-M_cut/m)
*
* The PDF is always assumed to be Poisson for satellite galaxies.
*/
double N_sat(double m)
{
double m1,f=1,n,nc;
if(HOD.color)
f = satellite_blue_fraction(m);
switch(HOD.pdfs) {
case 0:
return 0;
case 1:
if(m<HOD.M_min)return(0);
return(f*pow(m/HOD.M1,HOD.alpha));
break;
case 2:
if(m<HOD.M_low || m<HOD.M_cut)return(0);
return(f*pow((m-HOD.M_cut)/HOD.M1,HOD.alpha));
break;
case 3:
if(m<HOD.M_min)return(0);
return(f*exp(-HOD.M_cut/(m-HOD.M_min))*pow(m/HOD.M1,HOD.alpha));
break;
case 4:
if(m<HOD.M_min)return(0);
if(m<HOD.M_sat_break)
return(f*exp(-HOD.M_cut/(m-HOD.M_min))*pow(m/HOD.M1,HOD.alpha));
else
{
m1 = exp(log(HOD.M_sat_break) - HOD.alpha/HOD.alpha1*log(HOD.M_sat_break/HOD.M1));
return(f*exp(-HOD.M_cut/(m-HOD.M_min))*pow(m/m1,HOD.alpha1));
}
break;
case 5:
if(m<HOD.M_low || m<HOD.M_cut)return(0);
if(m<HOD.M_sat_break)
return(f*pow((m-HOD.M_cut)/HOD.M1,HOD.alpha));
else
{
m1 = HOD.M_sat_break*pow((HOD.M_sat_break-HOD.M_cut)/HOD.M1,-HOD.alpha/HOD.alpha1);
return(f*pow(m/m1,HOD.alpha1));
}
break;
case 6:
return(pow(m/HOD.M1,HOD.alpha)*exp(-HOD.M_min/m));
case 7:
if(m<HOD.M_low || m<HOD.M_cut)return(0);
return(0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM))
*pow((m-HOD.M_cut)/HOD.M1,HOD.alpha));
break;
case 8:
n = (pow(m/HOD.M1,HOD.alpha)*exp(-HOD.M_cut/m));
if(m<HOD.M_min)
{
nc = N_cen(m);
if(n>nc)return(nc);
}
return(n);
case 9:
if(m<HOD.M_sat_break)
{
n = (pow(m/HOD.M1,HOD.alpha)*exp(-HOD.M_cut/m));
if(m<HOD.M_min)
{
nc = N_cen(m);
if(n>nc)return(nc);
}
return n;
}
m1 = (pow(HOD.M_sat_break/HOD.M1,HOD.alpha)*exp(-HOD.M_cut/HOD.M_sat_break));
n = m1*pow(m/HOD.M_sat_break,HOD.alpha1);
return n;
break;
case 10:
if(m<HOD.M_low)return(0);
return(0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM))
*pow((m)/HOD.M1,HOD.alpha));
break;
case 11:
if(m<HOD.M_low)return(0);
return(f*exp(-HOD.M_cut/m)*pow(m/HOD.M1,HOD.alpha)*
0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM)));
case 12: // Zheng et al. 2007
//if(m<HOD.M_low)return(0);
return(f*pow((m-HOD.M_cut)/HOD.M1,HOD.alpha)*
0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM)));
break;
default:
endrun("Illegal value of HOD.pdfs.");
}
return 0;
}
/* If the sample is split up by color, this function
* returns the blue fraction at a given mass for satellite galaxies.
* This function is parameterized as a log-normal.
* See equation (11) in Zehavi et al Apj 2005, 360, 1
*
* if HOD.color == 1, returns blue fraction
* if HOD.color == 2, returns red fraction
*/
double satellite_blue_fraction(double m)
{
double x;
x = log10(m) - log10(HOD.M_low0);
x=(HOD.fblue0_sat*exp(-x*x/(2*HOD.sigma_fblue_sat*HOD.sigma_fblue_sat)));
if(x>1)x=1;
if(HOD.color==2)
return(1-x);
return(x);
}
/* If the sample is split up by color, this function
* returns the blue fraction at a given mass for central galaxies.
* This function is parameterized as a log-normal.
* See equation (11) in Zehavi et al Apj 2005, 360, 1
*
* if HOD.color == 1, returns blue fraction
* if HOD.color == 2, returns red fraction
*/
double central_blue_fraction(double m)
{
double x;
x = log10(m) - log10(HOD.M_low0);
x=(HOD.fblue0_cen*exp(-x*x/(2*HOD.sigma_fblue_cen*HOD.sigma_fblue_cen)));
if(x>1)x=1;
if(HOD.color==2)
return(1-x);
return(x);
}
/* If what is needed is the total number of galaxies in a halo.
*/
double N_avg(double m)
{
return(N_cen(m)+N_sat(m));
}
/* This is the <(N_sat-1)(N_sat)> moment, which is
* for the number of pairs of satellite galaxies.
* For a Poisson distribution, <N(N-1)> = N^2
*/
double moment_ss(double m)
{
double n,x;
n=N_sat(m);
return(n*n);
// sub-poisson model from millennium run
// doesn't seem to effect -20.5 stats much
x = 0.6 + 0.4*exp(-0.1/pow(n,1.5));
return(n*n*x*x);
}
/* This is a function to set the HOD parameters until
* I get some input code or batch file set up.
*
*/
void set_HOD_params()
{
int i,j=1;
double m,error=1.0,tol=1.0E-4,prev,s1,mlo;
/* If the mass function at M_max is undefined, reset M_max
*/
//LOCAL_DENSITY = -0.2;
if(LOCAL_DENSITY!=0)
{
HOD.M_max = 1.0E16;
while(dndM_interp(HOD.M_max)<=0)
{
HOD.M_max*=0.9;
}
fprintf(stderr,"NEW M_max= %e\n",HOD.M_max);
}
if(HOD.pdfc == 2 || HOD.pdfc == 3 || HOD.pdfc == 6 || HOD.pdfc == 8 || HOD.pdfc == 9)
SOFT_CENTRAL_CUTOFF=1;
/* Error trap both the galaxy density and M_min both left unspecified.
*/
if(HOD.M_min<=0 && GALAXY_DENSITY<=0 && HOD.free[0]==0)
endrun("ERROR: Must specify either M_min or GALAXY_DENSITY");
/* If the user has specified M_min and M1, calculate the galaxy density.
*/
if(HOD.M_min>0 && HOD.M1>0)
{
HOD.M_low = -1;
if(SOFT_CENTRAL_CUTOFF)
HOD.M_low0 = HOD.M_low = exp(zbrent(func_mlow,log(HOD.M_min*1.0E-6),log(HOD.M_min*1.1),1.0E-5));
else
HOD.M_low0 = HOD.M_low = HOD.M_min;
GALAXY_DENSITY=qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt);
if(OUTPUT) {
fprintf(stdout,"M_low= %e\n",HOD.M_low);
fprintf(stdout,"ng= %e\n",GALAXY_DENSITY); }
}
/* If M_min<=0 then use the specified galaxy density to calculate M_min
*/
if(HOD.M_min<=0)
{
if(HOD.pdfc==7 && HOD.pdfc==8)
HOD.M_min=pow(10.0,zbrent(fixfunc1,8.0,log10(HOD.M_cen_max*0.99),1.0E-5));
else
HOD.M_min=pow(10.0,zbrent(fixfunc1,7.0,14.8,1.0E-5));
HOD.M_low = -1;
if(SOFT_CENTRAL_CUTOFF)
HOD.M_low = exp(zbrent(func_mlow,log(HOD.M_min)-5*HOD.sigma_logM*2.3,
log(HOD.M_min),1.0E-5));
else
HOD.M_low = HOD.M_min;
if(HOD.M_low<1.0E7)HOD.M_low=1.0E+7;
if(OUTPUT) {
fprintf(stdout,"M_min %e [ng= %e]\n",HOD.M_min,GALAXY_DENSITY);
fprintf(stdout,"M_low= %e\n",HOD.M_low); }
}
/* If M1<=0 then use the specified galaxy density to calculate M1
*/
if(HOD.M1<=0)
{
HOD.M_low = -1;
if(SOFT_CENTRAL_CUTOFF)
HOD.M_low = exp(zbrent(func_mlow,log(HOD.M_min)-5*HOD.sigma_logM*2.3,
log(HOD.M_min*1.1),1.0E-5));
else
HOD.M_low = HOD.M_min;
if(HOD.M_low<1.0E7)HOD.M_low=1.0E+7;
HOD.M1=pow(10.0,zbrent(fixfunc2,log10(HOD.M_low),15.8,1.0E-5));
if(OUTPUT) {
fprintf(stdout,"M1 %e [ng= %e]\n",HOD.M1,GALAXY_DENSITY);
fprintf(stdout,"M_min = %e M_low= %e\n",HOD.M_min,HOD.M_low); }
}
/* Set the number of halo mass bins we've got.
*/
NUM_POW2MASS_BINS=log(HOD.M_max/HOD.M_low)/LN_2+1;
if(HOD.pdfc==6)
HOD.M_hi = set_high_central_mass();
HOD.M_low0 = set_low_mass();
return;
}
/* If soft central cutoff, then put a lower limit on mass integrals
* that begins at the mass where N_cen=0.001.
*/
double func_mlow(double m)
{
/* Have a check in case the passed mass is equal to M_min, but the value of
* N_cen is < 0.001 (which might be the case for very small sigma_logM)
*/
if(fabs(exp(m)-HOD.M_min)<0.001*HOD.M_min)
if(N_cen(exp(m))<0.001)return(0);
// fprintf(stderr,"MLO %e %e %e %e %e\n",exp(m),N_cen(exp(m)),HOD.M_min,HOD.M_cen_max,HOD.M_low);
return(N_cen(exp(m))-0.001);
}
/* It is straightforward to calculate what M_low
* should be given the other parameters on N_cen.
*/
double set_low_mass()
{
double m;
if(!SOFT_CENTRAL_CUTOFF)return(HOD.M_min);
switch(HOD.pdfc){
case 8:
case 6:
m = log10(HOD.M_min) - sqrt(-2*HOD.sigma_logM*HOD.sigma_logM*log(0.001));
m = pow(10.0,m);
return(m);
case 9:
m = exp(zbrent(func_mlow,log(HOD.M_min)-5*HOD.sigma_logM*2.3,
log(HOD.M_min),1.0E-5));
return(m);
default:
m = exp(zbrent(func_mlow,log(HOD.M_min*1.0E-6),
log(HOD.M_min),1.0E-5));
return(m);
}
return(0);
}
/* If modeling magnitude bin samples, then there will be a high mass
* scale for central galaxies as well as a low mass scale. This finds
* the mass at which N_cen(m)=0.001, where m>M_min.
*/
double set_high_central_mass()
{
double m,n;
if(HOD.pdfc==7)
return(HOD.M_cen_max);
if(!(HOD.pdfc==6 || HOD.pdfc==8 || HOD.pdfc==9))
return(HOD.M_max);
m = HOD.M_min;
n = N_cen(m);
while(n>0.001)
{
m*=2;
n = N_cen(m);
if(m>HOD.M_max)return(HOD.M_max);
}
m = exp(zbrent(func_mhi,log(m/2),log(m),1.0E-5));
return(m);
}
double func_mhi(double m)
{
m=exp(m);
return(N_cen(m)-0.001);
}
/* This is a copy of the above function that can be called from any routine.
* (But this one integrates over dlogm).
*/
double func_halo_density(double m)
{
double n1;
m=exp(m);
n1=dndM_interp(m);
return(n1*m);
}
/* This is a copy of the above function that can be called from any routine.
* (But this one integrates over dlogm
*/
double func_galaxy_density(double m)
{
double n1,n2,m0;
m=exp(m);
n1=dndM_interp(m);
n2=N_avg(m);
return(n1*n2*m);
}
double func_mean_halo_mass(double m)
{
double n1,n2,m0;
m=exp(m);
n1=dndM_interp(m);
n2=N_avg(m);
return(n1*n2*m*m);
}
/* This is the equation for zbrent to solve. What value
* of M_min gives the correct galaxy density?
* For HODs that have sharp central cutoffs, use M_min as the lower
* limit of the integration. For soft cutoffs, first find M_low.
*/
double fixfunc1(double m)
{
double n,mlo;
HOD.M_min=m=pow(10.0,m);
HOD.M_low=0;
if(SOFT_CENTRAL_CUTOFF)
mlo = (zbrent(func_mlow,log(HOD.M_min)-5*HOD.sigma_logM*2.3,log(HOD.M_min),1.0E-5));
else
mlo = log(HOD.M_min);
if(exp(mlo)<1.0E7)mlo=log(1.0E+7);
n=qromo(func_galaxy_density,mlo,log(HOD.M_max),midpnt);
// fprintf(stderr,"MMIN %e %e %e %e %e %e\n",m,exp(mlo),n,GALAXY_DENSITY,N_sat(2*m),N_cen(m));
return(GALAXY_DENSITY-n);
}
/* This function is sent to zbrent to determine what M1 is based
* on the number density. Both M_min and M_low have already been specified.
*/
double fixfunc2(double m)
{
double n;
HOD.M1=m=pow(10.0,m);
n=qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt);
return(GALAXY_DENSITY-n);
}
/* This function is to be passed to qromo to integrate the number density
* of satellite galaxies.
*/
double func_satfrac(double m)
{
m=exp(m);
return(N_sat(m)*dndM_interp(m)*m);
}
/* This function is to be passed to qromo to integrate the number density
* of satellite galaxies.
*/
double func_satellite_density(double m)
{
m=exp(m);
return(N_sat(m)*dndM_interp(m)*m);
}
/* This function is to be passed to qromo to integrate the number density
* of satellite galaxies.
*/
double func_central_density(double m)
{
m=exp(m);
return(N_cen(m)*dndM_interp(m)*m);
}
/* Calculates the average mass of a halo in the HOD.
*/
double number_weighted_halo_mass()
{
double funcxx1();
return(qromo(funcxx1,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
}
double funcxx1(double m)
{
m=exp(m);
return(m*N_avg(m)*dndM_interp(m)*m);
}
/* Calculates the average mass of a halo in the HOD
* (weighted by central galaxies).
*/
double number_weighted_central_mass()
{
double funcxx2();
return(qromo(funcxx2,log(HOD.M_low),log(HOD.M_max),midpnt)/
qromo(func_central_density,log(HOD.M_low),log(HOD.M_max),midpnt));
}
double funcxx2(double m)
{
m=exp(m);
return(m*N_cen(m)*dndM_interp(m)*m);
}
double one_halo_from_file(double m)
{
static double *x, *y, *z;
static int n, flag = 1;
FILE *fp;
int i;
double a;
if(flag)
{
muh(0);
fp = openfile("ncen.dat");
muh(0);
n = filesize(fp);
x = dvector(1,n);
y = dvector(1,n);
z = dvector(1,n);
for(i=1;i<=n;++i)
fscanf(fp,"%lf %lf",&x[i],&y[i]);
spline(x,y,n,1.0E+30,1.0E+30,z);
flag = 0;
muh(0);
}
if(log10(m)<x[1])return 0;
splint(x,y,z,n,log10(m),&a);
//printf("%e %e\n",m,pow(10.0,a));
if(a>0) return 1;
return pow(10.0,a);
}

View file

@ -0,0 +1,403 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* It is not elegant to do things in this manner, but the code was
* written with auto-correlation functions in mind first, and so copy+edit for
* a second HOD was the most efficient method of modifying the code for the
* cross-correlation function.
*
* NB-- No blue/red galaxies for the second HOD.
*/
/* This file holds several useful functions for the HOD, such as the number of
* central and satellite halos, their second moment.
*
* This also intializes the HOD parameters.
*/
/* internal routines.
*/
double fixfunc1_2(double m);
double fixfunc2_2(double m);
double func_mlow2(double m);
double func_mhi2(double m);
/*****************
* DIFFERENT HOD PARAMETERIZATIONS: (1) Central galaxies
*
* This integer HOD.pdfc controls the parameterization of the central occupation.
* (I realize 'pdf' is not the right acronym, but it's a holdover from old code.)
*
* For soft central cutoffs, the PDF is the nearest integer distribution, AKA
* Bernoulli distribution.
*
* 0 = No galaxies, just halos. (always returns 1)
* 1 = Hard cutoff at M_min. Unity above M_min. (DEFAULT)
* 2 = Soft cutoff of the form 0.5*(1+erf((log10(m) - log10(HOD.M_min))/HOD.sigma_logM)
* 3 = Soft cutoff of the form N_cen = exp(-HOD.M_min/m)
* 4 = Hard cutoff, but N_cen -> 0 for M>M_min (i.e., blue galaxies)
* MaxCen*exp(-(lgM-lgM_min)**2/2/(sigma_logM)**2)
* NB! -> The value of N_cen(M_min) can be < 1. (It will== MaxCen)
* 5 = Hard Cutoff, Step function, but N_cen != 1, but some number < 1.
* 6 = Same as 4, but symmetric Gaussian around M_min (This is for mag bins.)
* 7 = A sqaure function. N_cen=1 for M_min <= m <= M_cen_max (for mag bin data)
* 8 = A sqaure function (like case 7) but with Gaussian cutoffs on either edge
* instead of sharp cutoffs.
*
* 9 = Magnitude bin model, but the upper mass cutoff is defined by the lower
* mass cutoff of the next-highest bin. (see function in ml_minimization.c)
*
* M_low is a parameter created to keep the integrals from having to go to M=0 for
* soft central cutoffs. N_cen(mlow) = 1.0E-3;
* If the value of sigma_logM gets above 1 or so, then M_low can be rediculously
* small, so I have placed a lower limit on M_low of 1.0E+7 Msol/h
*/
double N_cen2(double m)
{
double x,f=1;
switch(HOD2.pdfc) {
case 0:
return 1;
case 1:
if(m<HOD2.M_min)return(0);
return(f*1.0);
break;
case 2:
return(f*0.5*(1+erf((log10(m) - log10(HOD2.M_min))/HOD2.sigma_logM)));
break;
case 3:
return(f*exp(-HOD2.M_min/m));
break;
case 4:
if(m<HOD2.M_min)return(0);
x = (log10(m) - log10(HOD2.M_min))/HOD2.sigma_logM;
return(f*HOD2.MaxCen*exp(-x*x/2));
case 5:
if(m<HOD2.M_min)return(0);
return(f*HOD2.MaxCen);
case 6:
x = (log10(m) - log10(HOD2.M_min))/HOD2.sigma_logM;
return(f*HOD2.MaxCen*exp(-x*x/2));
case 7:
if(m>=HOD2.M_min && m<=HOD2.M_cen_max)return(f);
return(0);
case 8:
if(m>=HOD2.M_min && m<=HOD2.M_cen_max)return(f);
if(m<HOD2.M_low)return(0);
if(m<HOD2.M_min)
x = (log10(m) - log10(HOD2.M_min))/HOD2.sigma_logM;
else
x = (log10(m) - log10(HOD2.M_cen_max))/HOD2.sigma_logM;
return(f*exp(-x*x/2));
case 9:
return(f*N_cen_i(m,HOD2.i_wp));
default:
endrun("Illegal value of HOD2.pdfc.");
}
return 0;
}
/*****************
* DIFFERENT HOD PARAMETERIZATIONS: (1) Satellite galaxies
*
* This integer HOD2.pdfs controls the parameterization of the satellite occupation.
*
* 0 = halos only, no galaxies (always returns zero)
* 1 = power law: N_sat = pow(m/HOD2.M1,HOD2.alpha) [cut off at M_low]
* 2 = power law with soft cutoff: N_sat = pow((m-HOD2.M_cut)/HOD2.M1,alpha)
* 3 = power law with exp cutoff: N_sat = pow(m/HOD2.M1,alpha)*exp(-M_cut/(m-M_min))
* 4 = broken power law with exp cutoff (alpha changes at some high mass value)
* 5 = broken power law (m-mcut)/m1 parameterization
*
* The PDF is always assumed to be Poisson for satellite galaxies.
*/
double N_sat2(double m)
{
double m1,f=1;
switch(HOD2.pdfs) {
case 0:
return 0;
case 1:
if(m<HOD2.M_min)return(0);
return(f*pow(m/HOD2.M1,HOD2.alpha));
break;
case 2:
if(m<HOD2.M_low || m<HOD2.M_cut)return(0);
return(f*pow((m-HOD2.M_cut)/HOD2.M1,HOD2.alpha));
break;
case 3:
if(m<HOD2.M_min)return(0);
return(f*exp(-HOD2.M_cut/(m-HOD2.M_min))*pow(m/HOD2.M1,HOD2.alpha));
break;
case 4:
if(m<HOD2.M_min)return(0);
if(m<HOD2.M_sat_break)
return(f*exp(-HOD2.M_cut/(m-HOD2.M_min))*pow(m/HOD2.M1,HOD2.alpha));
else
{
m1 = exp(log(HOD2.M_sat_break) - HOD2.alpha/HOD2.alpha1*log(HOD2.M_sat_break/HOD2.M1));
/*
m1 = exp(log(HOD2.M_sat_break) - 1/HOD2.alpha1*
(HOD2.alpha*log(HOD2.M_sat_break/HOD2.M1) - HOD2.M_cut/(HOD2.M_sat_break-HOD2.M_min)));
*/
return(f*exp(-HOD2.M_cut/(m-HOD2.M_min))*pow(m/m1,HOD2.alpha1));
}
break;
case 5:
if(m<HOD2.M_low || m<HOD2.M_cut)return(0);
if(m<HOD2.M_sat_break)
return(f*pow((m-HOD2.M_cut)/HOD2.M1,HOD2.alpha));
else
{
m1 = HOD2.M_sat_break*pow((HOD2.M_sat_break-HOD2.M_cut)/HOD2.M1,-HOD2.alpha/HOD2.alpha1);
return(f*pow(m/m1,HOD2.alpha1));
}
break;
default:
endrun("Illegal value of HOD2.pdfs.");
}
return 0;
}
/* If what is needed is the total number of galaxies in a halo.
*/
double N_avg2(double m)
{
return(N_cen2(m)+N_sat2(m));
}
/* This is the <(N_sat-1)(N_sat)> moment, which is
* for the number of pairs of satellite galaxies.
* For a Poisson distribution, <N(N-1)> = N^2
*/
double moment_ss2(double m)
{
double n;
n=N_sat2(m);
return(n*n);
}
/* This is a function to set the HOD parameters until
* I get some input code or batch file set up.
*
*/
void set_HOD2_params()
{
int i,j=1;
double m,error=1.0,tol=1.0E-4,prev,s1,mlo;
if(HOD2.pdfc == 2 || HOD2.pdfc == 3 || HOD2.pdfc == 6 || HOD2.pdfc == 8 || HOD2.pdfc == 9)
SOFT_CENTRAL_CUTOFF=1;
/* Error trap both the galaxy density and M_min both left unspecified.
*/
if(HOD2.M_min<=0 && GALAXY_DENSITY2<=0 && HOD2.free[0]==0)
endrun("ERROR: Must specify either M_min or GALAXY_DENSITY2");
/* If the user has specified M_min and M1, calculate the galaxy density.
*/
if(HOD2.M_min>0 && HOD2.M1>0)
{
HOD2.M_low = -1;
if(SOFT_CENTRAL_CUTOFF)
HOD2.M_low = exp(zbrent(func_mlow2,log(HOD2.M_min*1.0E-6),log(HOD2.M_min*1.1),1.0E-5));
else
HOD2.M_low = HOD2.M_min;
GALAXY_DENSITY2=qromo(func_galaxy_density2,log(HOD2.M_low),log(HOD2.M_max),midpnt);
if(OUTPUT) {
fprintf(stdout,"M_low= %e\n",HOD2.M_low);
fprintf(stdout,"ng= %e\n",GALAXY_DENSITY2); }
}
/* If M_min<=0 then use the specified galaxy density to calculate M_min
*/
if(HOD2.M_min<=0)
{
if(HOD2.pdfc==7 && HOD2.pdfc==8)
HOD2.M_min=pow(10.0,zbrent(fixfunc1_2,8.0,log10(HOD2.M_cen_max*0.99),1.0E-5));
else
HOD2.M_min=pow(10.0,zbrent(fixfunc1_2,8.0,14.8,1.0E-5));
HOD2.M_low = -1;
if(SOFT_CENTRAL_CUTOFF)
HOD2.M_low = exp(zbrent(func_mlow2,log(HOD2.M_min)-5*HOD2.sigma_logM*2.3,
log(HOD2.M_min),1.0E-5));
else
HOD2.M_low = HOD2.M_min;
if(HOD2.M_low<1.0E7)HOD2.M_low=1.0E+7;
if(OUTPUT) {
fprintf(stdout,"M_min %e [ng= %e]\n",HOD2.M_min,GALAXY_DENSITY2);
fprintf(stdout,"M_low= %e\n",HOD2.M_low); }
}
/* If M1<=0 then use the specified galaxy density to calculate M1
*/
if(HOD2.M1<=0)
{
HOD2.M_low = -1;
if(SOFT_CENTRAL_CUTOFF)
HOD2.M_low = exp(zbrent(func_mlow2,log(HOD2.M_min)-5*HOD2.sigma_logM*2.3,
log(HOD2.M_min*1.1),1.0E-5));
else
HOD2.M_low = HOD2.M_min;
if(HOD2.M_low<1.0E7)HOD2.M_low=1.0E+7;
HOD2.M1=pow(10.0,zbrent(fixfunc2_2,log10(HOD2.M_low),15.8,1.0E-5));
if(OUTPUT) {
fprintf(stdout,"M1 %e [ng= %e]\n",HOD2.M1,GALAXY_DENSITY2);
fprintf(stdout,"M_min = %e M_low= %e\n",HOD2.M_min,HOD2.M_low); }
}
HOD2.M_hi = set_high_central_mass2();
return;
}
/* If soft central cutoff, then put a lower limit on mass integrals
* that begins at the mass where N_cen=0.001.
*/
double func_mlow2(double m)
{
/* Have a check in case the passed mass is equal to M_min, but the value of
* N_cen is < 0.001 (which might be the case for very small sigma_logM)
*/
if(fabs(exp(m)-HOD2.M_min)<0.001*HOD2.M_min)
if(N_cen2(exp(m))<0.001)return(0);
/* fprintf(stderr,"MLO %e %e %e %e %e\n",exp(m),N_cen(exp(m)),HOD2.M_min,HOD2.M_cen_max,HOD2.M_low); */
return(N_cen2(exp(m))-0.001);
}
/* It is straightforward to calculate what M_low
* should be given the other parameters on N_cen.
*/
double set_low_mass2()
{
double m;
if(!SOFT_CENTRAL_CUTOFF)return(HOD2.M_min);
switch(HOD2.pdfc){
case 8:
case 6:
m = log10(HOD2.M_min) - sqrt(-2*HOD2.sigma_logM*HOD2.sigma_logM*log(0.001));
m = pow(10.0,m);
return(m);
default:
m = exp(zbrent(func_mlow2,log(HOD2.M_min)-5*HOD2.sigma_logM*2.3,
log(HOD2.M_min),1.0E-5));
return(m);
}
return(0);
}
/* If modeling magnitude bin samples, then there will be a high mass
* scale for central galaxies as well as a low mass scale. This finds
* the mass at which N_cen(m)=0.001, where m>M_min.
*/
double set_high_central_mass2()
{
double m,n;
if(HOD2.pdfc==7)
return(HOD2.M_cen_max);
if(!(HOD2.pdfc==6 || HOD2.pdfc==8 || HOD2.pdfc==9))
return(HOD2.M_max);
m = HOD2.M_min;
n = N_cen(m);
while(n>0.001)
{
m*=2;
n = N_cen(m);
if(m>HOD2.M_max)return(HOD2.M_max);
}
m = exp(zbrent(func_mhi2,log(m/2),log(m),1.0E-5));
return(m);
}
double func_mhi2(double m)
{
m=exp(m);
return(N_cen2(m)-0.001);
}
/* This is a copy of the above function that can be called from any routine.
* (But this one integrates over dlogm
*/
double func_galaxy_density2(double m)
{
double n1,n2,m0;
m=exp(m);
n1=dndM_interp(m);
n2=N_avg2(m);
return(n1*n2*m);
}
/* This is the equation for zbrent to solve. What value
* of M_min gives the correct galaxy density?
* For HODs that have sharp central cutoffs, use M_min as the lower
* limit of the integration. For soft cutoffs, first find M_low.
*/
double fixfunc1_2(double m)
{
double n,mlo;
HOD2.M_min=m=pow(10.0,m);
HOD2.M_low=0;
if(SOFT_CENTRAL_CUTOFF)
mlo = (zbrent(func_mlow2,log(HOD2.M_min)-5*HOD2.sigma_logM*2.3,log(HOD2.M_min),1.0E-5));
else
mlo = log(HOD2.M_min);
if(exp(mlo)<1.0E7)mlo=log(1.0E+7);
n=qromo(func_galaxy_density,mlo,log(HOD2.M_max),midpnt);
/* fprintf(stderr,"MMIN %e %e %e %e\n",m,exp(mlo),n,GALAXY_DENSITY2); */
return(GALAXY_DENSITY2-n);
}
/* This function is sent to zbrent to determine what M1 is based
* on the number density. Both M_min and M_low have already been specified.
*/
double fixfunc2_2(double m)
{
double n;
HOD2.M1=m=pow(10.0,m);
n=qromo(func_galaxy_density,log(HOD2.M_low),log(HOD2.M_max),midpnt);
return(GALAXY_DENSITY2-n);
}
/* This function is to be passed to qromo to integrate the number density
* of satellite galaxies.
*/
double func_satfrac2(double m)
{
m=exp(m);
return(N_sat2(m)*dndM_interp(m)*m);
}
/* This function is to be passed to qromo to integrate the number density
* of satellite galaxies.
*/
double func_satellite_density2(double m)
{
m=exp(m);
return(N_sat2(m)*dndM_interp(m)*m);
}
/* This function is to be passed to qromo to integrate the number density
* of satellite galaxies.
*/
double func_central_density2(double m)
{
m=exp(m);
return(N_cen2(m)*dndM_interp(m)*m);
}

58
c_tools/hod/i3tensor_2.c Normal file
View file

@ -0,0 +1,58 @@
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#define NR_END 1
#define FREE_ARG char*
int ***i3tensor_2(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
int ***t;
/* allocate pointers to pointers to rows */
t=(int ***) malloc((size_t)((nrow+NR_END)*sizeof(int**)));
if (!t)exit(0);
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(int **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int*)));
if (!t[nrl])exit(0);
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(int *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(int)));
if (!t[nrl][ncl])exit(0);
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
void free_i3tensor(int ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh)
/* free a int i3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}
#undef NR_END
#undef FREE_ARG

788
c_tools/hod/input_params.c Normal file
View file

@ -0,0 +1,788 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "header.h"
/* This function is taken from Volker Springel's GADGET code and
* modified for the parameters used for the HOD.x code.
*/
/*
* This function parses the parameterfile in a simple way.
* Each paramater is defined by a keyword (`tag'), and can be
* either of type douple, int, or character string.
* The routine makes sure that each parameter appears
* exactly once in the parameterfile.
*/
void read_parameter_file(char *fname)
{
#define DOUBLE 1
#define STRING 2
#define INT 3
#define CHAR 4
#define LONG 4
#define MAXTAGS 300
FILE *fd,*fdout;
char buf[200],buf1[200],buf2[200],buf3[200],tempchar;
int i,j,nt,ii,nn,ctemp;
int id[MAXTAGS];
void *addr[MAXTAGS];
char tag[MAXTAGS][200];
int errorFlag=0;
int IDUM_MCMC_TEMP=-555;
nt=0;
strcpy(tag[nt],"RESTART");
addr[nt]=&RESTART;
id[nt++]=INT;
strcpy(tag[nt],"RESTART_FILE");
addr[nt]=&RESTART_FILE;
id[nt++]=STRING;
strcpy(tag[nt],"GAMMA");
addr[nt]=&GAMMA;
id[nt++]=DOUBLE;
strcpy(tag[nt],"OMEGA_M");
addr[nt]=&OMEGA_M;
id[nt++]=DOUBLE;
strcpy(tag[nt],"REDSHIFT");
addr[nt]=&REDSHIFT;
id[nt++]=DOUBLE;
strcpy(tag[nt],"OMEGA_TEMP");
addr[nt]=&OMEGA_TEMP;
id[nt++]=DOUBLE;
strcpy(tag[nt],"OMEGA_B");
addr[nt]=&OMEGA_B;
id[nt++]=DOUBLE;
strcpy(tag[nt],"SIGMA_8");
addr[nt]=&SIGMA_8;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HUBBLE");
addr[nt]=&HUBBLE;
id[nt++]=DOUBLE;
strcpy(tag[nt],"ITRANS");
addr[nt]=&ITRANS;
id[nt++]=INT;
strcpy(tag[nt],"LINEAR_PSP");
addr[nt]=&LINEAR_PSP;
id[nt++]=INT;
strcpy(tag[nt],"KAISER");
addr[nt]=&KAISER;
id[nt++]=INT;
strcpy(tag[nt],"BETA");
addr[nt]=&BETA;
id[nt++]=DOUBLE;
strcpy(tag[nt],"SIGV");
addr[nt]=&SIGV;
id[nt++]=DOUBLE;
strcpy(tag[nt],"IDUM_MCMC");
addr[nt]=&IDUM_MCMC_TEMP;
id[nt++]=INT;
strcpy(tag[nt],"SPECTRAL_INDX");
addr[nt]=&SPECTRAL_INDX;
id[nt++]=DOUBLE;
strcpy(tag[nt],"DELTA_HALO");
addr[nt]=&DELTA_HALO;
id[nt++]=DOUBLE;
strcpy(tag[nt],"BOX_SIZE");
addr[nt]=&BOX_SIZE;
id[nt++]=DOUBLE;
strcpy(tag[nt],"RESOLUTION");
addr[nt]=&RESOLUTION;
id[nt++]=DOUBLE;
strcpy(tag[nt],"VBIAS");
addr[nt]=&VBIAS;
id[nt++]=DOUBLE;
strcpy(tag[nt],"VBIAS_C");
addr[nt]=&VBIAS_C;
id[nt++]=DOUBLE;
strcpy(tag[nt],"TF_file");
addr[nt]=Files.TF_file;
id[nt++]=STRING;
strcpy(tag[nt],"M1");
addr[nt]=&HOD.M1;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_min");
addr[nt]=&HOD.M_min;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_cen_max");
addr[nt]=&HOD.M_cen_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_cut");
addr[nt]=&HOD.M_cut;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_max");
addr[nt]=&HOD.M_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"sigma_logM");
addr[nt]=&HOD.sigma_logM;
id[nt++]=DOUBLE;
HOD.MaxCen=1;
strcpy(tag[nt],"MaxCen");
addr[nt]=&HOD.MaxCen;
id[nt++]=DOUBLE;
strcpy(tag[nt],"alpha");
addr[nt]=&HOD.alpha;
id[nt++]=DOUBLE;
strcpy(tag[nt],"alpha1");
addr[nt]=&HOD.alpha1;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_sat_break");
addr[nt]=&HOD.M_sat_break;
id[nt++]=DOUBLE;
strcpy(tag[nt],"pdfc");
addr[nt]=&HOD.pdfc;
id[nt++]=INT;
strcpy(tag[nt],"pdf");
addr[nt]=&tempchar;
id[nt++]=CHAR;
strcpy(tag[nt],"pdfs");
addr[nt]=&HOD.pdfs;
id[nt++]=INT;
strcpy(tag[nt],"M_min_fac");
addr[nt]=&HOD.M_min_fac;
id[nt++]=DOUBLE;
/* Paramaters for the second HOD function
* (for x-corr)
*/
strcpy(tag[nt],"XCORR");
addr[nt]=&XCORR;
id[nt++]=INT;
XCORR=0;
strcpy(tag[nt],"GALAXY_DENSITY2");
addr[nt]=&GALAXY_DENSITY2;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.M1");
addr[nt]=&HOD2.M1;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.M_min");
addr[nt]=&HOD2.M_min;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.M_cen_max");
addr[nt]=&HOD2.M_cen_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.M_cut");
addr[nt]=&HOD2.M_cut;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.M_max");
addr[nt]=&HOD2.M_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.sigma_logM");
addr[nt]=&HOD2.sigma_logM;
id[nt++]=DOUBLE;
HOD2.MaxCen=1;
strcpy(tag[nt],"HOD2.MaxCen");
addr[nt]=&HOD2.MaxCen;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.alpha");
addr[nt]=&HOD2.alpha;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.alpha1");
addr[nt]=&HOD2.alpha1;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.M_sat_break");
addr[nt]=&HOD2.M_sat_break;
id[nt++]=DOUBLE;
strcpy(tag[nt],"HOD2.pdfc");
addr[nt]=&HOD2.pdfc;
id[nt++]=INT;
HOD2.pdfc=-1;
strcpy(tag[nt],"HOD2.pdfs");
addr[nt]=&HOD2.pdfs;
id[nt++]=INT;
HOD2.pdfs=-1;
/* Finished with HOD2 params
*/
strcpy(tag[nt],"color");
addr[nt]=&HOD.color;
id[nt++]=INT;
HOD.color=0;
strcpy(tag[nt],"fblue0_cen");
addr[nt]=&HOD.fblue0_cen;
id[nt++]=DOUBLE;
strcpy(tag[nt],"sigma_fblue_cen");
addr[nt]=&HOD.sigma_fblue_cen;
id[nt++]=DOUBLE;
strcpy(tag[nt],"fblue0_sat");
addr[nt]=&HOD.fblue0_sat;
id[nt++]=DOUBLE;
strcpy(tag[nt],"sigma_fblue_sat");
addr[nt]=&HOD.sigma_fblue_sat;
id[nt++]=DOUBLE;
strcpy(tag[nt],"GALAXY_DENSITY");
addr[nt]=&GALAXY_DENSITY;
id[nt++]=DOUBLE;
strcpy(tag[nt],"EXCLUSION");
addr[nt]=&EXCLUSION;
id[nt++]=INT;
strcpy(tag[nt],"FIX_PARAM");
addr[nt]=&FIX_PARAM;
id[nt++]=INT;
strcpy(tag[nt],"POWELL");
addr[nt]=&POWELL;
id[nt++]=INT;
strcpy(tag[nt],"OUTPUT");
addr[nt]=&OUTPUT;
id[nt++]=INT;
for(i=0;i<=16;++i)
{
sprintf(tag[nt],"free[%d]",i);
addr[nt]=&HOD.free[i];
id[nt++]=INT;
}
strcpy(tag[nt],"All");
addr[nt]=&Task.All;
id[nt++]=INT;
strcpy(tag[nt],"real_space_xi");
addr[nt]=&Task.real_space_xi;
id[nt++]=INT;
strcpy(tag[nt],"z_space_xi");
addr[nt]=&Task.z_space_xi;
id[nt++]=INT;
strcpy(tag[nt],"kaiser_xi");
addr[nt]=&Task.kaiser_xi;
id[nt++]=INT;
strcpy(tag[nt],"multipoles");
addr[nt]=&Task.multipoles;
id[nt++]=INT;
strcpy(tag[nt],"r_half");
addr[nt]=&Task.r_half;
id[nt++]=INT;
strcpy(tag[nt],"PVD");
addr[nt]=&Task.PVD;
id[nt++]=INT;
Task.PVD = 0;
strcpy(tag[nt],"cvir");
addr[nt]=&Task.cvir;
id[nt++]=INT;
Task.cvir = 0;
strcpy(tag[nt],"matter_xi");
addr[nt]=&Task.matter_xi;
id[nt++]=INT;
Task.matter_xi = 0;
strcpy(tag[nt],"matter_pk");
addr[nt]=&Task.matter_pk;
id[nt++]=INT;
Task.matter_pk = 0;
strcpy(tag[nt],"massfunc");
addr[nt]=&Task.dndM;
id[nt++]=INT;
Task.matter_pk = 0;
strcpy(tag[nt],"sigma_r");
addr[nt]=&Task.sigma_r;
id[nt++]=INT;
Task.sigma_r = 0;
strcpy(tag[nt],"wp_minimize");
addr[nt]=&Task.wp_minimize;
id[nt++]=INT;
Task.wp_minimize=0;
strcpy(tag[nt],"zspace_minimize");
addr[nt]=&Task.zspace_minimize;
id[nt++]=INT;
Task.zspace_minimize=0;
strcpy(tag[nt],"MCMC");
addr[nt]=&Task.MCMC;
id[nt++]=INT;
Task.MCMC=0;
strcpy(tag[nt],"populate_sim");
addr[nt]=&Task.populate_sim;
id[nt++]=INT;
Task.populate_sim=0;
strcpy(tag[nt],"HaloFile");
addr[nt]=&Files.HaloFile;
id[nt++]=STRING;
strcpy(tag[nt],"HaloFileFormat");
addr[nt]=&Files.HaloFileFormat;
id[nt++]=STRING;
strcpy(tag[nt],"HaloDensityFile");
addr[nt]=&Files.HaloDensityFile;
id[nt++]=STRING;
strcpy(tag[nt],"DENSITY_DEPENDENCE");
addr[nt]=&DENSITY_DEPENDENCE;
id[nt++]=INT;
strcpy(tag[nt],"DENSITY_THRESHOLD");
addr[nt]=&DENSITY_THRESHOLD;
id[nt++]=DOUBLE;
strcpy(tag[nt],"WP_ONLY");
addr[nt]=&WP_ONLY;
id[nt++]=INT;
strcpy(tag[nt],"HOD");
addr[nt]=&Task.HOD;
id[nt++]=INT;
Task.HOD=0;
strcpy(tag[nt],"COVAR");
addr[nt]=&COVAR;
id[nt++]=INT;
COVAR=1;
strcpy(tag[nt],"PCA");
addr[nt]=&PCA;
id[nt++]=INT;
PCA=0;
strcpy(tag[nt],"wp_npca");
addr[nt]=&wp.npca;
id[nt++]=INT;
wp.npca=0;
strcpy(tag[nt],"DEPROJECTED");
addr[nt]=&DEPROJECTED;
id[nt++]=INT;
strcpy(tag[nt],"fname_covar");
addr[nt]=&wp.fname_covar;
id[nt++]=STRING;
wp.pi_max=40;
strcpy(tag[nt],"pi_max");
addr[nt]=&wp.pi_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"esys");
addr[nt]=&wp.esys;
id[nt++]=DOUBLE;
strcpy(tag[nt],"fname_wp");
addr[nt]=&wp.fname_wp;
id[nt++]=STRING;
wp.format=1;
strcpy(tag[nt],"wp_format");
addr[nt]=&wp.format;
id[nt++]=INT;
wp.n_wp=9;
strcpy(tag[nt],"n_wp");
addr[nt]=&wp.n_wp;
id[nt++]=INT;
strcpy(tag[nt],"root_filename");
addr[nt]=&Task.root_filename;
id[nt++]=STRING;
strcpy(tag[nt],"CVIR_FAC");
addr[nt]=&CVIR_FAC;
id[nt++]=DOUBLE;
strcpy(tag[nt],"JENKINS_A");
addr[nt]=&JENKINS_A;
id[nt++]=DOUBLE;
strcpy(tag[nt],"JENKINS_C");
addr[nt]=&JENKINS_C;
id[nt++]=DOUBLE;
strcpy(tag[nt],"JENKINS_B");
addr[nt]=&JENKINS_B;
id[nt++]=DOUBLE;
strcpy(tag[nt],"BEST_FIT");
addr[nt]=&BEST_FIT;
id[nt++]=INT;
if((fd=fopen(fname,"r")))
{
nn=filesize(fd);
sprintf(buf,"%s","hod-usedvalues");
if(!(fdout=fopen(buf,"w")))
{
fprintf(stdout,"error opening file '%s' \n",buf);
errorFlag=1;
}
else
{
/*while(!feof(fd))*/
for(ii=1;ii<=nn;++ii)
{
fgets(buf,200,fd);
if(sscanf(buf,"%s%s%s",buf1,buf2,buf3)<2)
continue;
if(buf1[0]=='%')
continue;
for(i=0,j=-1;i<nt;i++)
if(strcmp(buf1,tag[i])==0)
{
j=i;
tag[i][0]=0;
break;
}
if(j>=0)
{
switch(id[j])
{
case DOUBLE:
*((double*)addr[j])=atof(buf2);
fprintf(fdout,"%-35s%g\n",buf1,*((double*)addr[j]));
break;
case STRING:
strcpy(addr[j],buf2);
fprintf(fdout,"%-35s%s\n",buf1,buf2);
break;
case INT:
*((int*)addr[j])=atoi(buf2);
fprintf(fdout,"%-35s%d\n",buf1,*((int*)addr[j]));
break;
case CHAR:
*((char*)addr[j])=buf2[0];
fprintf(fdout,"%-35s%c\n",buf1,*((int*)addr[j]));
break;
}
}
else
{
fprintf(stderr,"Error in file %s: Tag '%s' not allowed or multiple defined.\n",
fname,buf1);
errorFlag=1;
}
}
}
fclose(fd);
fclose(fdout);
}
else
{
fprintf(stderr,"Parameter file %s not found.\n", fname);
exit(1);
}
/* Check the params for some basic interpretation
*/
MASS_PER_PARTICLE=pow(RESOLUTION,3.0)*RHO_CRIT*OMEGA_M;
/* If minimizing data, make sure to set M_min to 0
*/
if(MCMC || Task.wp_minimize)
HOD.M_min = 0;
for(i=0;i<nt;i++)
{
if(!strcmp(tag[i],"DENSITY_DEPENDENCE"))continue;
if(!strcmp(tag[i],"DENSITY_THRESHOLD") && !DENSITY_DEPENDENCE)continue;
if(!strcmp(tag[i],"M_min_fac") && !DENSITY_DEPENDENCE)continue;
if(!strcmp(tag[i],"HaloDensityFile") && !DENSITY_DEPENDENCE)continue;
if(!strcmp(tag[i],"HOD2.M_min") && !XCORR)continue;
if(!strcmp(tag[i],"HOD2.M_max") && !XCORR)continue;
if(!strcmp(tag[i],"HOD2.MaxCen") && !(HOD2.pdfc>=4 && HOD.pdfc<=6))continue;
if(!strcmp(tag[i],"HOD2.M_cut") && HOD2.pdfs<2)continue;
if(!strcmp(tag[i],"HOD2.M1") && !XCORR)continue;
if(!strcmp(tag[i],"HOD2.M_cen_max") && HOD2.pdfc!=7)continue;
if(!strcmp(tag[i],"HOD2.sigma_logM") && (!XCORR || (HOD2.pdfc==1 || HOD2.pdfc==7)))continue;
if(!strcmp(tag[i],"HOD2.pdfs") && !XCORR)continue;
if(!strcmp(tag[i],"HOD2.pdfc") && !XCORR)continue;
if(!strcmp(tag[i],"HOD2.alpha") && !XCORR)continue;
if(!strcmp(tag[i],"HOD2.alpha1") && HOD2.pdfs!=4 && HOD2.pdfs!=5)continue;
if(!strcmp(tag[i],"HOD2.M_sat_break") && HOD2.pdfs!=4 && HOD2.pdfs!=5)continue;
if(!strcmp(tag[i],"GALAXY_DENSITY2") && !XCORR)continue;
if(!strcmp(tag[i],"XCORR"))continue;
if(!strcmp(tag[i],"alpha1"))continue;
if(!strcmp(tag[i],"M_sat_break"))continue;
if(!strcmp(tag[i],"OMEGA_TEMP"))
{
OMEGA_TEMP = OMEGA_M;
continue;
}
if(!strcmp(tag[i],"GAMMA") && ITRANS==4)
{
fprintf(stderr,"No value of GAMMA specified for ITRANS=4\n");
errorFlag=1;
}
if(!strcmp(tag[i],"HUBBLE") && ITRANS==5)
{
fprintf(stderr,"No value of HUBBLE specified for ITRANS=5\n");
errorFlag=1;
}
if(!strcmp(tag[i],"OMEGA_B") && ITRANS==5)
{
fprintf(stderr,"No value of OMEGA_B specified for ITRANS=5\n");
errorFlag=1;
}
if(!strcmp(tag[i],"GAMMA"))continue;
if(!strcmp(tag[i],"pdf"))continue;
if(!strcmp(tag[i],"WP_ONLY"))continue;
if(!strcmp(tag[i],"RESTART"))continue;
if(!strcmp(tag[i],"RESTART_FILE"))continue;
if(!strcmp(tag[i],"DEPROJECTED"))continue;
if(!strcmp(tag[i],"POWELL"))continue;
if(!strcmp(tag[i],"LINEAR_PSP"))continue;
if(!strcmp(tag[i],"BOX_SIZE"))continue;
if(!strcmp(tag[i],"RESOLUTION"))continue;
if(!strcmp(tag[i],"DELTA_HALO"))continue;
if(!strcmp(tag[i],"VBIAS"))continue;
if(!strcmp(tag[i],"COVAR"))continue;
if(!strcmp(tag[i],"VBIAS_C"))continue;
if(!strcmp(tag[i],"CVIR_FAC"))continue;
if(!strcmp(tag[i],"ITRANS"))continue;
if(!strcmp(tag[i],"IDUM_MCMC"))continue;
if(!strcmp(tag[i],"FIX_PARAM"))continue;
if(!strcmp(tag[i],"DEPROJECTED"))continue;
if(!strcmp(tag[i],"OUTPUT"))continue;
if(!strcmp(tag[i],"JENKINS_A"))continue;
if(!strcmp(tag[i],"JENKINS_B"))continue;
if(!strcmp(tag[i],"JENKINS_C"))continue;
if(!strcmp(tag[i],"BEST_FIT"))continue;
if(!strcmp(tag[i],"KAISER"))continue;
if(!strcmp(tag[i],"SIGV"))continue;
if(!strcmp(tag[i],"BETA"))continue;
if(!strcmp(tag[i],"MCMC"))continue;
if(!strcmp(tag[i],"wp_minimize"))continue;
if(!strcmp(tag[i],"wp_format"))continue;
if(!strcmp(tag[i],"n_wp"))continue;
if(!strcmp(tag[i],"wp_npca"))continue;
if(!strcmp(tag[i],"z_space_xi"))continue;
if(!strcmp(tag[i],"multipoles"))continue;
if(!strcmp(tag[i],"r_half"))continue;
if(!strcmp(tag[i],"zspace_minimize"))continue;
if(!strcmp(tag[i],"pi_max"))continue;
if(!strcmp(tag[i],"esys"))continue;
if(HOD.color)
{
if(!strcmp(tag[i],"fblue0_cen") ||
!strcmp(tag[i],"sigma_fblue_cen") ||
!strcmp(tag[i],"fblue0_sat") ||
!strcmp(tag[i],"sigma_fblue_sat"))
{
fprintf(stderr,"Parameters for color HOD not specified.\n");
exit(0);
}
continue;
}
if(!strcmp(tag[i],"color"))continue;
if(!strcmp(tag[i],"fblue0_cen"))continue;
if(!strcmp(tag[i],"sigma_fblue_cen"))continue;
if(!strcmp(tag[i],"fblue0_sat"))continue;
if(!strcmp(tag[i],"sigma_fblue_sat"))continue;
if(!strcmp(tag[i],"free[0]"))continue;
if(!strcmp(tag[i],"free[1]"))continue;
if(!strcmp(tag[i],"free[2]"))continue;
if(!strcmp(tag[i],"free[3]"))continue;
if(!strcmp(tag[i],"free[4]"))continue;
if(!strcmp(tag[i],"free[5]"))continue;
if(!strcmp(tag[i],"free[6]"))continue;
if(!strcmp(tag[i],"free[7]"))continue;
if(!strcmp(tag[i],"free[8]"))continue;
if(!strcmp(tag[i],"free[9]"))continue;
if(!strcmp(tag[i],"free[10]"))continue;
if(!strcmp(tag[i],"free[11]"))continue;
if(!strcmp(tag[i],"free[12]"))continue;
if(!strcmp(tag[i],"free[13]"))continue;
if(!strcmp(tag[i],"free[14]"))continue;
if(!strcmp(tag[i],"free[15]"))continue;
if(!strcmp(tag[i],"free[16]"))continue;
if(!strcmp(tag[i],"All"))continue;
if(!strcmp(tag[i],"massfunc"))continue;
if(!strcmp(tag[i],"populate_sim"))continue;
if(!strcmp(tag[i],"HaloFile"))continue;
if(!strcmp(tag[i],"HaloFileFormat"))continue;
if(!strcmp(tag[i],"HOD"))continue;
if(!strcmp(tag[i],"PCA"))continue;
if(!strcmp(tag[i],"PVD"))continue;
if(!strcmp(tag[i],"matter_xi"))continue;
if(!strcmp(tag[i],"matter_pk"))continue;
if(!strcmp(tag[i],"sigma_r"))continue;
if(!strcmp(tag[i],"kaiser_xi"))continue;
if(!strcmp(tag[i],"cvir"))continue;
if(!strcmp(tag[i],"TF_file"))
{
if(ITRANS==11) {
sprintf(Files.TF_file,"CMBFAST_trans.dat");
fprintf(stderr,"No transfer function file, using [%s]\n",Files.TF_file);
}
continue;
}
if(!strcmp(tag[i],"fname_covar"))
{
if(Task.wp_minimize) {
fprintf(stderr,"No filename specified for covariance matrix.\n");
errorFlag=1;
}
continue;
}
if(!strcmp(tag[i],"fname_wp"))
{
if(Task.wp_minimize) {
fprintf(stderr,"No filename specified for wp data.\n");
errorFlag=1;
}
continue;
}
if(!strcmp(tag[i],"M_cut"))
{
if(HOD.pdfs==2 || HOD.pdfs==3){
fprintf(stderr,"No value for M_cut given for pdfs= 2/3\n");
errorFlag=1;
}
continue;
}
if(!strcmp(tag[i],"M_cen_max"))
{
if(HOD.pdfc==7) {
fprintf(stderr,"No value for M_cen_max given for pdfc= 7\n");
errorFlag=1;
}
continue;
}
if(!strcmp(tag[i],"sigma_logM"))
{
if(HOD.pdfc==2){
fprintf(stderr,"No value for sigma_logM given for pdfc=2\n");
errorFlag=1;
}
continue;
}
if(!strcmp(tag[i],"MaxCen"))
{
if(HOD.pdfc==5){
fprintf(stderr,"No value for MaxCen given for pdfc=5\n");
errorFlag=1;
}
continue;
}
if(*tag[i])
{
fprintf(stderr,"Error. I miss a value for tag '%s' in parameter file '%s'.\n",
tag[i],fname);
errorFlag=1;
}
}
if(PCA==1 && COVAR==1)
{
fprintf(stderr,"EEROR: you have both PCA and COVAR set to 1.\n");
errorFlag=1;
}
IDUM_MCMC=IDUM_MCMC_TEMP;
MCMC = Task.MCMC;
if(errorFlag)
endrun("error in input_params ");
/* Other initialization stuff.
*/
MSTAR=mstar();
ctemp = HOD.color;
if(Task.wp_minimize)
HOD.color = 0;
set_HOD_params();
HOD.color = ctemp;
//if(XCORR)set_HOD2_params();
#undef DOUBLE
#undef STRING
#undef INT
#undef MAXTAGS
}

View file

@ -0,0 +1,32 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
double integrated_bin(double xlo, double ylo, double dx1, double dy1, int n)
{
int i,j;
double dx,dy,xsum=0,vol=0,x1,x2,rs,rp;
dx=dx1/n;
dy=dy1/n;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
{
rs=xlo+(i-0.5)*dx;
rp=ylo+(j-0.5)*dy;
x2=two_halo(rs,rp);
x1=one_halo(rs,rp);
xsum+=2*dy*rs*dx*(x1+x2);
}
dx=xlo+dx1;
dy=ylo+dy1;
xsum/=((dx*dx-xlo*xlo)*dy1);
return(xsum);
}

87
c_tools/hod/jacobi.c Normal file
View file

@ -0,0 +1,87 @@
#include <math.h>
#define NRANSI
#include "nrutil.h"
#define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
a[k][l]=h+s*(g-h*tau);
void jacobi(double **a, int n, double d[], double **v, int *nrot)
{
int j,iq,ip,i;
double tresh,theta,tau,t,sm,s,h,g,c,*b,*z;
b=dvector(1,n);
z=dvector(1,n);
for (ip=1;ip<=n;ip++) {
for (iq=1;iq<=n;iq++) v[ip][iq]=0.0;
v[ip][ip]=1.0;
}
for (ip=1;ip<=n;ip++) {
b[ip]=d[ip]=a[ip][ip];
z[ip]=0.0;
}
*nrot=0;
for (i=1;i<=50;i++) {
sm=0.0;
for (ip=1;ip<=n-1;ip++) {
for (iq=ip+1;iq<=n;iq++)
sm += fabs(a[ip][iq]);
}
if (sm == 0.0) {
free_dvector(z,1,n);
free_dvector(b,1,n);
return;
}
if (i < 4)
tresh=0.2*sm/(n*n);
else
tresh=0.0;
for (ip=1;ip<=n-1;ip++) {
for (iq=ip+1;iq<=n;iq++) {
g=100.0*fabs(a[ip][iq]);
if (i > 4 && (double)(fabs(d[ip])+g) == (double)fabs(d[ip])
&& (double)(fabs(d[iq])+g) == (double)fabs(d[iq]))
a[ip][iq]=0.0;
else if (fabs(a[ip][iq]) > tresh) {
h=d[iq]-d[ip];
if ((double)(fabs(h)+g) == (double)fabs(h))
t=(a[ip][iq])/h;
else {
theta=0.5*h/(a[ip][iq]);
t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
if (theta < 0.0) t = -t;
}
c=1.0/sqrt(1+t*t);
s=t*c;
tau=s/(1.0+c);
h=t*a[ip][iq];
z[ip] -= h;
z[iq] += h;
d[ip] -= h;
d[iq] += h;
a[ip][iq]=0.0;
for (j=1;j<=ip-1;j++) {
ROTATE(a,j,ip,j,iq)
}
for (j=ip+1;j<=iq-1;j++) {
ROTATE(a,ip,j,j,iq)
}
for (j=iq+1;j<=n;j++) {
ROTATE(a,ip,j,iq,j)
}
for (j=1;j<=n;j++) {
ROTATE(v,j,ip,j,iq)
}
++(*nrot);
}
}
}
for (ip=1;ip<=n;ip++) {
b[ip] += z[ip];
d[ip]=b[ip];
z[ip]=0.0;
}
}
nrerror("Too many iterations in routine jacobi");
}
#undef ROTATE
#undef NRANSI

95
c_tools/hod/jeans.c Normal file
View file

@ -0,0 +1,95 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "header.h"
double *mu_x,*mu_y,*mu_z;
int mu_n;
/* Equation (10) of vdB et al, assuming alpha = 1 (standard NFW)
*/
double func_jeans1(double x)
{
return(x/(1+x)/(1+x));
}
/* Equation (11) of vdB et al.
*/
double func_jeans2(double x)
{
double y;
splint(mu_x,mu_y,mu_z,mu_n,x,&y);
return(y/(x*x*x*(1+x)*(1+x)));
}
double jeans_dispersion(double mass, double rx, double v[])
{
int i,j,k,n,nc,nr;
double rmin,rmax,dlogr;
static double cmin,cmax,dlogc;
double rvir,rs,s1,sig,mu1,vcirc,cvir;
static long IDUM2 = -4555;
static double fac=-1;
static int prev_cosmo=-1;
if(fac<0)
{
mu_n = nc = 1000;
cmin = 0.1;
cmax = 100.0;
dlogc = (log(cmax) - log(cmin))/(nc-1);
mu_x = dvector(1,nc);
mu_y = dvector(1,nc);
mu_z = dvector(1,nc);
for(i=1;i<=nc;++i)
{
mu_x[i] = exp((i-1)*dlogc)*cmin;
mu_y[i] = qromo(func_jeans1,0,mu_x[i],midpnt);
}
spline(mu_x,mu_y,nc,1.0E+30,1.0E+30,mu_z);
fac=sqrt(4.499E-48)*3.09E19;
}
cvir = halo_concentration(mass);
rvir = pow(3*mass/(4*PI*DELTA_HALO*OMEGA_M*RHO_CRIT),THIRD);
rs = rvir/cvir;
rx = rx/rs;
vcirc = fac*fac*mass/rvir;
splint(mu_x,mu_y,mu_z,mu_n,cvir,&mu1);
s1 = qromo(func_jeans2,rx,cmax,midpnt);
sig = sqrt(cvir*vcirc/mu1*rx*(1+rx)*(1+rx)*s1);
if(isnan(sig))
sig = sqrt(vcirc/2);
for(i=0;i<3;++i)
v[i]=gasdev(&IDUM2)*sig*VBIAS;
return sig;
nr = 100;
rmin = rvir*0.01;
rmax = rvir*0.99;
dlogr = (log(rmax) - log(rmin))/(nr-1);
rs = rvir/cvir;
vcirc = fac*fac*mass/rvir;
splint(mu_x,mu_y,mu_z,mu_n,cvir,&mu1);
for(i=0;i<nr;++i)
{
rx = exp(i*dlogr)*rmin/rs;
s1 = qromo(func_jeans2,rx,cmax,midpnt);
sig = cvir/mu1*rx*(1+rx)*(1+rx)*s1*2;
printf("%f %f\n",rx*rs/rvir,sqrt(sig));
}
exit(0);
}

375
c_tools/hod/jet_pvz_temp.c Normal file
View file

@ -0,0 +1,375 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "header.h"
double delta_pdf(double delta, double r);
void vdelta_v4(double m0, double m1, double rad, double theta, double binsize,
double v0, int nv, double *a, double *pv, double *pt, double *pz,
double wgal[3], double sgal[4])
{
static double pnorm=-1,flag=0;
static double *rho,*mu,*pdelta;
static int prev_cosmo=0;
int i,j,k,nrho=75,halo_pair_only=0,use_file_coeff=0;
double dlogrho,sintheta,costheta,tan2theta,rho_min,rho_max,w,b0,
collapse_factor,rho200,ptot,v,sigv,rho0,x1,x2,x3,rvir0,rho200t,sigvt,alpha,alphat,
rvir1,rvirmax,rvir2,vfac,sr1,sr2,sr3,sr4,st1,st2,st3,st4,sz1,sz2,sz3,sz4,
gnorm1,gnorm2,gnorm3,gnorm4,vv,pmax,rcrit,sig20,sig10,sig5;
int direction,iend;
double sigz1[76],sigz2[76],sigz3[76],sigz4[76],
g1[76],g2[76],g3[76],g4[76],minp,xfit[3],yfit[3],afit,bfit;
double t0,t1,tt1,tt2;
int ii=0;
double vfac0 = 0.97; /* factor om rho200[t,r]. was 0.97 */
for(i=1;i<=nv;++i)
/* pt[i]=pv[i]=*/ pz[i]=0;
rvir0=(pow(3*m0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0) +
pow(3*m1/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0));
rvir1=pow(3*m1/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rvir2=pow(3*m0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
b0=(bias_interp(m0,-1)+bias_interp(m1,-1));
/* 0.5 comes from ellipsoidal halo exclusion.
*/
if(rad<rvir0*0.5)return;
/*if(rad<rvir0)rad=rvir0;*/
rho_min=0.01;
alpha=alphat=pow(rad/35,0.1);
rcrit=4*rvir1;
rcrit=0;
if(rad<=rcrit)
{
x1=rcrit;
x2=pow(x1/35,0.1);
x3=x1*pow(x2,-1.0/(+0.3));
alpha=alphat=pow(rad/x3,+0.3);
}
rcrit=4*rvir1;
rho200 = pow(rad/5.0/sqrt(rvir1),-4.0) + pow(rad/11.5/sqrt(rvir0),-1.3) + 0.5;
rho200t = pow(rad/7.2/sqrt(rvir1),-2.5) + pow(rad/12.6/sqrt(rvir0),-0.8) + 0.48;
rho0 = 1.41*b0 + pow(rad/9.4/rvir1,-2.2);
/* TEMP TEMP TEMP
*/
/* rho0 = 1.38*b0 + pow(rad/9.4/rvir1,-2.2); */
vfac0 = 1.01;
/* If using the bias parameters that fit Warren's sims, use:
*/
/* rho0 = 1.45*b0 + pow(rad/9.4/rvir1,-2.2); */
/* If using the bias parameters for the linear P(k), use:
*/
if(LINEAR_PSP)
rho0 = 1.28*b0 + pow(rad/9.4/rvir1,-2.2);
sintheta=sin(theta);
costheta=cos(theta);
tan2theta=sintheta*sintheta/(costheta*costheta);
if(!flag)
{
flag=1;
mu=dvector(1,nrho);
rho=dvector(1,nrho);
pdelta=dvector(1,nrho);
}
/* Determine the proper limits of the integral over rho
*/
dlogrho=log(1.0E+3/0.01)/(50-1);
pmax=0;
i=0;
for(i=1;i<=50;++i)
{
rho[i]=rho_min*exp((i-1)*dlogrho);
pdelta[i]=exp(-rho0/rho[i])*delta_pdf(rho[i]-1,rad)*rho[i];
if(pdelta[i]>pmax){ pmax=pdelta[i]; j=i; }
}
pmax*=1.0E-4;
for(i=1;i<j;++i)
if(pdelta[i]>=pmax)break;
rho_min=rho[i];
for(i=j+1;i<50;++i)
if(pdelta[i]<=pmax)break;
rho_max=rho[i];
/* Tabulate the spherical collapse model, density, and p(delta).
*/
dlogrho=log(rho_max/rho_min)/(nrho-1);
ptot=0;
for(i=1;i<=nrho;++i)
{
rho[i]=rho_min*exp((i-1)*dlogrho);
pdelta[i]=exp(-rho0/rho[i])*delta_pdf(rho[i]-1,rad)*rho[i];
ptot+=pdelta[i]*dlogrho;
if(pdelta[i]>pdelta[j])j=i;
x1=-(100*rad)*pow(OMEGA_M,0.6)*(rho[i]-1)/3;
/* If underdense region, use linear theory.
*/
if(rho[i]<=1)
{
mu[i]=x1;
continue;
}
x2=(rad)*spherical_collapse_model(rho[i]-1)*exp(-(4.5/rad/rho[i])*(4.5/rad/rho[i]));
if(x2>0)x2=0;
/* If small separation, use spherical collapse model only.
*/
if(rad<=4)
{
mu[i]=x2;
continue;
}
/* If intermediate separation, use linear combination of v_sph & v_lin.
*/
if(rad<=20)
{
w=-0.62*log(rad)+1.86;
mu[i]=w*x2 + (1-w)*x1;
continue;
}
/* In linear regime. Use linear theory.
*/
mu[i]=x1;
}
if(rad<=rcrit)
for(i=1;i<=nrho;++i)
mu[i]=mu[j];
for(i=1;i<=nrho;++i)
pdelta[i]/=ptot;
vfac=pow(OMEGA_M/0.3,0.6)*(SIGMA_8/0.8)*vfac0;
/* If Halos only, then set all the galaxy velocity dispersions
* and weights to be zero.
*/
if(!HOD.pdfs)
{
sgal[0]=sgal[1]=sgal[2]=0;
wgal[0]=wgal[1]=wgal[2]=0;
}
for(i=1;i<=nrho;++i)
{
sigv=200*pow(rho[i]/rho200,alpha)*vfac;
sigvt=200*pow(rho[i]/rho200t,alphat)*vfac;
sr1=sigv*sigv + sgal[0];
sr2=sigv*sigv + sgal[1];
sr3=sigv*sigv + sgal[2];
sr4=sigv*sigv + sgal[3];
st1=sigvt*sigvt + sgal[0];
st2=sigvt*sigvt + sgal[1];
st3=sigvt*sigvt + sgal[2];
st4=sigvt*sigvt + sgal[3];
sz1=2*(st1+tan2theta*sr1)*costheta*costheta;
sz2=2*(st2+tan2theta*sr2)*costheta*costheta;
sz3=2*(st3+tan2theta*sr3)*costheta*costheta;
sz4=2*(st4+tan2theta*sr4)*costheta*costheta;
sigz1[i]=sz1;
sigz2[i]=sz2;
sigz3[i]=sz3;
sigz4[i]=sz4;
gnorm1=wgal[0]/(RT2PI*sqrt(st1*sr1)*sqrt(1.0/(sr1) + tan2theta/(st1)));
gnorm2=wgal[1]/(RT2PI*sqrt(st2*sr2)*sqrt(1.0/(sr2) + tan2theta/(st2)));
gnorm3=wgal[2]/(RT2PI*sqrt(st3*sr3)*sqrt(1.0/(sr3) + tan2theta/(st3)));
gnorm4=(1-wgal[0]-wgal[1]-wgal[2])/
(RT2PI*sqrt(st4*sr4)*sqrt(1.0/(sr4) + tan2theta/(st4)));
g1[i]=gnorm1;
g2[i]=gnorm2;
g3[i]=gnorm3;
g4[i]=gnorm4;
}
/* Find the mode of the distribution. Start at vz=0 and work either way.
*/
for(k=1,j=nv/2;j<=nv;++j,++k)
{
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(k==2){
if(pz[j-1]>pz[j])direction=-1;
else direction=1;
break;
}
}
direction=1;
if(direction==1)iend=nv;
else iend=1;
for(k=1,j=nv/2-direction;j!=iend;j+=direction,++k)
{
if(pz[j]>0)goto SKIP1;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
SKIP1:
if(k<3)continue;
if(direction>0) {
/*printf("%d %e %e %e\n",j,pz[j],pz[j-1],pz[j-2]);*/
if(pz[j-1]>pz[j] && pz[j-1]>pz[j-2]) {
minp = pz[j-1]*0.001; break; }
} else {
/*printf("%d %e %e %e\n",j,pz[j],pz[j+1],pz[j+2]);*/
if(pz[j+1]>pz[j] && pz[j+1]>pz[j+2]) {
minp = pz[j+1]*0.001; break; }
}
}
for(j=nv/2;j<=nv;++j)
{
if(pz[j]>0)continue;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(pz[j]<=minp && nv-j>=3)break;
}
/* Now extrapolate the rest of the PVD from the last three points.
*/
for(k=0,i=j-2;i<=j;++i,++k)
{
yfit[k]=log(pz[i]);
xfit[k]=v0+(i-1)*binsize;
}
least_squares(xfit,yfit,3,&afit,&bfit);
for(i=j+1;i<=nv;++i)
pz[i] = exp(afit + bfit*(v0+(i-1)*binsize));
/* Now go from the mode to i=0
*/
for(j=nv/2-1;j>=1;--j)
{
if(pz[j]>0)continue;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(pz[j]<=minp && j>=3)break;
}
/* Now extrapolate the rest of the PVD from the last three points.
*/
for(k=2,i=j+2;i>=j;--i,--k)
{
yfit[k]=log(pz[i]);
xfit[k]=v0+(i-1)*binsize;
}
least_squares(xfit,yfit,3,&afit,&bfit);
for(i=j-1;i>0;--i)
pz[i] = exp(afit + bfit*(v0+(i-1)*binsize));
/* Do this just to get rid of any numerical roundoff errors and such.
* (It whould already be one by construction if I didn't have the
* linear extrapolation at the end of each side, but the correction
* shouldn't be much.)
*/
for(ptot=0,i=1;i<=nv;++i)
ptot+=pz[i]*binsize;
for(i=1;i<=nv;++i)
pz[i]/=ptot;
if(isnan(ptot))
{
printf("NAN ptot %f %f %f %f %f %f\n",rho200,rho200t,alpha,rho0,sr4,st4);
fflush(stdout);
for(i=1;i<=nv;++i)
pt[i]=pz[i]=pv[i]=0;
return;
}
return;
}
/* This is the standard log-normal 1-pt distribution of dark
* matter densities (non-linear) at top-hat smoothing scale r.
*/
double delta_pdf(double delta, double r)
{
static int model_prev=0;
static double pnorm=-1,rprev=0,sig0,sig1sqr;
double pnorm1;
if(pnorm<0 || RESET_COSMOLOGY!=model_prev)
{
pnorm1=SIGMA_8/sigmac(8.0);
/*printf("NORM %e %e %e\n",pnorm1,sigmac(8.0),nonlinear_sigmac(8.0));*/
pnorm=pnorm1*sigmac(80.0)/nonlinear_sigmac(80.0);
rprev=0;
/*printf("NORM %e %e %e %e %f\n",pnorm,sigmac(8.0),sigmac(80.0),nonlinear_sigmac(80.0),SIGMA_8);*/
}
if(r!=rprev)
{
sig0=pnorm*nonlinear_sigmac(r);
sig1sqr=log(1+sig0*sig0);
/*printf("NORM %f %f %e %e %e\n",r,sig0,pnorm,nonlinear_sigmac(8.0),sigmac(8.0));*/
}
rprev=r;
model_prev=RESET_COSMOLOGY;
return(1.0/(RT2PI*sqrt(sig1sqr))*exp(-pow(log((1+delta))+sig1sqr*0.5,2.0)/
(2*sig1sqr))/(1+delta));
}

View file

@ -0,0 +1,432 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "header.h"
/* Local variables for the coordinate in redshift space.
*/
double rs_g8,rp_g8;
/* Internal functions.
*/
double func_kaiser(double z);
double xi_bar(double r);
double f_xibar(double r);
double xi_prime(double r, double mu);
double xi_t(double r);
double Lpoly(double x, int i);
double f_xi2bar(double r);
double xi_harmonic(double r, int i);
double scale_dependent_dispersion(double r);
double scale_dependent_skewness(double r);
void initial_dispersion_model_values(double *a, double **pp, double *yy);
void dispersion_model_input(void);
double chi2_dispersion_model(double *a);
/* Internal variables.
*/
struct DISPERION_MODEL_STRUCT {
int n;
double **rs,**rp;
double **x,**e;
} XX;
double *rr_g8, *aa_g8;
int nparams_g8, niter_g8=0;
void fit_dispersion_model()
{
int n,niter,i,j;
double *a,**pp,*yy,FTOL=1.0E-3,chi2min,s1,dlogm,m;
FILE *fp;
char aa[1000];
fprintf(stderr,"\n\nCHI2 MINIMIZATION OF xi(SIGMA,PI) WITH DISPERSION MODEL.\n");
fprintf(stderr, "--------------------------------------------------------\n\n");
if(POWELL)
FTOL=1.0E-4;
else
FTOL=1.0E-4;
nparams_g8 = n = 8;
dispersion_model_input();
wp.ncf=n;
a=dvector(1,n);
rr_g8 = dvector(1,n);
aa_g8 = dvector(1,n);
for(i=1;i<=n;++i)
rr_g8[i] = (log(10)-log(0.1))/(n-1.)*(i-1) + log(0.1);
BETA = 0.5;
if(POWELL)
pp=dmatrix(1,n,1,n);
else
pp=dmatrix(1,n+1,1,n);
yy=dvector(1,n+1);
initial_dispersion_model_values(a,pp,yy);
if(POWELL)
{
if(OUTPUT)printf("dispersion_model> starting powell.\n");
powell(a,pp,n,FTOL,&niter,&chi2min,chi2_dispersion_model);
chi2min = chi2_dispersion_model(a);
}
else
{
if(OUTPUT)printf("dispersion_model> starting amoeba.\n");
amoeba(pp,yy,n,FTOL,chi2_dispersion_model,&niter);
for(i=1;i<=n;++i)a[i]=pp[1][i];
chi2min = chi2_dispersion_model(a);
}
}
void initial_dispersion_model_values(double *a, double **pp, double *yy)
{
static int flag=0;
int i,j;
double d[100];
if(!flag) {
for(i=1;i<=nparams_g8;++i)
a[i] = 500;
printf("INITIAL VALUES: ");
for(i=1;i<=wp.ncf;++i)printf("%e ",a[i]);
printf("\n");
}
flag++;
/* Make the starting stepsize 10% of the initial values.
*/
for(i=1;i<=wp.ncf;++i)
d[i]=a[i]*0.1/flag;
if(POWELL)
{
for(i=1;i<=wp.ncf;++i)
{
for(j=1;j<=wp.ncf;++j)
{
pp[i][j]=0;
if(i==j)pp[i][j]+=d[j];
}
}
}
else
{
for(j=1;j<=wp.ncf;++j)
pp[1][j]=a[j];
yy[1]=chi2_dispersion_model(a);
for(i=1;i<=wp.ncf;++i)
{
a[i]+=d[i];
if(i>1)a[i-1]-=d[i-1];
yy[i+1]=chi2_dispersion_model(a);
for(j=1;j<=wp.ncf;++j)
pp[i+1][j]=a[j];
}
a[wp.ncf]-=d[wp.ncf];
}
}
void dispersion_model_input()
{
FILE *fp;
int i,j;
fp = openfile("xi2d.data");
XX.n = (int)sqrt(filesize(fp)*0.99)+1;
XX.rs = dmatrix(1,XX.n,1,XX.n);
XX.rp = dmatrix(1,XX.n,1,XX.n);
XX.x = dmatrix(1,XX.n,1,XX.n);
XX.e = dmatrix(1,XX.n,1,XX.n);
for(i=1;i<=XX.n;++i)
for(j=1;j<=XX.n;++j)
fscanf(fp,"%lf %lf %lf %lf",&XX.rs[i][j],&XX.rp[i][j],&XX.x[i][j],&XX.e[i][j]);
fclose(fp);
}
double chi2_dispersion_model(double *a)
{
int i,j;
double xx,r,chi2=0;
for(i=1;i<=nparams_g8;++i)
{
aa_g8[i] = a[i];
if(a[i]<=0)return(1.0E7);
}
for(i=2;i<=XX.n;++i)
for(j=2;j<=XX.n;++j)
{
xx = kaiser_distortion(XX.rs[i][j],XX.rp[i][j]);
/* printf("%f %f %f %f %f\n",XX.rs[i][j],XX.rp[i][j],XX.x[i][j],xx,xx); */
chi2 += (xx-XX.x[i][j])*(xx-XX.x[i][j])/(XX.e[i][j]*XX.e[i][j]);
}
niter_g8++;
printf("ITER %d %e ",niter_g8,chi2);
for(i=1;i<=nparams_g8;++i)
printf("%e ",a[i]);
printf("\n");
fflush(stdout);
if(niter_g8%100==0)
{
for(i=1;i<=100;++i)
{
r = exp((log(40)-log(0.1))/(100-1.)*(i-1) + log(0.1));
xx = scale_dependent_dispersion(r);
printf("PVD %d %f %f\n",niter_g8,r,xx);
}
fflush(stdout);
}
return(chi2);
}
double kaiser_distortion(double rs, double rp)
{
double s1,rlim=60,rr;
static int prev=-1;
if(prev==-1 || prev!=RESET_COSMOLOGY)
{
prev=RESET_COSMOLOGY;
/*
BETA = pow(OMEGA_M,0.6)/qromo(func_galaxy_bias,HOD.M_low,HOD.M_max,midpnt)*
GALAXY_DENSITY;
*/
printf("kaiser> BETA= %f SIGV= %f\n",BETA,SIGV);
}
rs_g8=rs;
rp_g8=rp;
rr=sqrt(rs*rs+rp*rp);
/* if(rr*1.5>10)rlim=rr*5.5; */
/* s1=qromo(func_kaiser,-rlim,rlim,midpnt); */
s1=qtrap(func_kaiser,-rlim,rlim,1.0E-3);
return(s1-1);
}
double linear_kaiser_distortion(double r, double z)
{
double mu;
mu= sqrt(1 - z/r*z/r);
mu = z/r;
return xi_prime(r,mu);
}
double func_kaiser(double z)
{
double r,mu,v,x,sigv;
r=sqrt(z*z+rs_g8*rs_g8);
mu=z/r;
v=(rp_g8-z)*100.0;
sigv = scale_dependent_dispersion(r);
/*
if(v*z<0)
sigv*=scale_dependent_skewness(r);
*/
/*
x=(1+one_halo_real_space(r)+two_halo_real_space(r))*
exp(-ROOT2*fabs(v)/sigv)/ROOT2/sigv*100.0;
*/
x=(1+xi_prime(r,mu)+one_halo_real_space(r))*exp(-ROOT2*fabs(v)/sigv)/ROOT2/sigv*100.0;
return(x);
}
double scale_dependent_skewness(double r)
{
return 1.5;
}
double scale_dependent_dispersion(double r)
{
static int niter=-1,flag=0;
static double *z,*x,*y;
double a;
int i;
if(niter!=niter_g8)
{
niter = niter_g8;
if(!flag)
{
flag++;
x=dvector(1,nparams_g8+1);
y=dvector(1,nparams_g8+1);
z=dvector(1,nparams_g8+1);
y[1] = 0;
x[1] = log(0.01);
for(i=2;i<=nparams_g8+1;++i)
x[i] = rr_g8[i-1];
}
for(i=2;i<=nparams_g8+1;++i)
y[i] = aa_g8[i-1];
spline(x,y,nparams_g8+1,1.0E+30,1.0E+30,z);
}
r=log(r);
if(r>rr_g8[nparams_g8])return(aa_g8[nparams_g8]);
splint(x,y,z,nparams_g8+1,r,&a);
return(a);
}
/* This function tabulates the spherically averaged correlation function.
* Equation (A7) in Madgwick et al.
*/
double xi_bar(double r)
{
static int flag=0,prev=-1;
static double *x,*y,*y2;
int n=100,i;
static double rmin,rmax,lgr,a;
if(!flag || prev!=RESET_KAISER)
{
if(OUTPUT>1)
printf("Tabulating xi_bar...\n");
prev=RESET_KAISER;
if(!flag)
{
x=malloc(n*sizeof(double));
x--;
y=malloc(n*sizeof(double));
y--;
y2=malloc(n*sizeof(double));
y2--;
}
flag=1;
rmin=-1.9;
rmin=log10(R_MIN_2HALO);
rmax=log10(80.0);
for(i=1;i<=n;++i)
{
lgr=(rmax-rmin)*(i-1.0)/(n-1.0)+rmin;
x[i]=pow(10.0,lgr);
y[i]=qtrap(f_xibar,0.0,x[i],1.0E-4)*3/(x[i]*x[i]*x[i]);
//printf("XIBAR %f %e\n",x[i],y[i]);
}
spline(x,y,n,1.0E30,1.0E30,y2);
}
if(r<x[1])return(-1);
splint(x,y,y2,n,r,&a);
//if(a<xi_t(r))return(xi_t(r));
return(a);
}
double f_xibar(double r)
{
double x;
x=two_halo_real_space(r);
/* x=one_halo_real_space(r)+two_halo_real_space(r); */
return(x*r*r);
}
/* This function tabulates the xi(r)*r^4 dr function.
* Equation (A8)
*/
double xi_2bar(double r)
{
static int flag=0,prev=-1;
static double *x,*y,*y2,rmin;
int n=100,i;
double rmax,lgr,a;
if(!flag || prev!=RESET_KAISER)
{
if(OUTPUT>1)
printf("Tabulating xi_2bar...\n");
prev=RESET_KAISER;
if(!flag)
{
x=malloc(n*sizeof(double));
x--;
y=malloc(n*sizeof(double));
y--;
y2=malloc(n*sizeof(double));
y2--;
}
flag=1;
rmin=-1.9;
rmin = log10(R_MIN_2HALO);
rmax=log10(80.0);
for(i=1;i<=n;++i)
{
lgr=(rmax-rmin)*(i-1.0)/(n-1.0)+rmin;
x[i]=pow(10.0,lgr);
y[i]=qtrap(f_xi2bar,0.0,x[i],1.0E-4)*5/(x[i]*x[i]*x[i]*x[i]*x[i]);
//printf("XI2BAR %f %e\n",x[i],y[i]);
}
spline(x,y,n,1.0E30,1.0E30,y2);
}
if(r<x[1])return(-1);
splint(x,y,y2,n,r,&a);
// if(a<xi_t(r))return(xi_t(r));
return(a);
}
double f_xi2bar(double r)
{
double x;
x=two_halo_real_space(r);
/* x=one_halo_real_space(r)+two_halo_real_space(r); */
return(x*r*r*r*r);
}
/* These are Legendre polynomials
*/
double Lpoly(double x, int i)
{
switch(i) {
case 0: return(1.0);
case 2: return(0.5*(3*x*x-1));
case 4: return((35*x*x*x*x-30*x*x+3)/8.0);
/*case 4: return((384*x*x*x*x+1152*x*x*(x*x-1)+144*(x*x-1)*(x*x-1))/(16.*24.));*/
default: return(0.0);
}
}
double xi_harmonic(double r, int i)
{
switch(i){
case 0: return((1+2.*BETA/3.+BETA*BETA/5.)*xi_t(r));
case 2: return((4.*BETA/3.+4.*BETA*BETA/7.)*(xi_t(r)-xi_bar(r)));
case 4: return(8.*BETA*BETA/35.*(xi_t(r)+2.5*xi_bar(r)-3.5*xi_2bar(r)));
default: return(0);
}
}
double xi_prime(double r, double mu)
{
double x0,x2,x4;
x0=xi_harmonic(r,0)*Lpoly(mu,0);
x2=xi_harmonic(r,2)*Lpoly(mu,2);
x4=xi_harmonic(r,4)*Lpoly(mu,4);
return(x0+x2+x4);
}
double xi_t(double r)
{
return(two_halo_real_space(r));
return(one_halo_real_space(r)+two_halo_real_space(r));
}

View file

@ -0,0 +1,22 @@
#include "header.h"
/* Just a little ditty to do a least squares fit to the arrays given
* (assuming no errors).
*/
void least_squares(double *x, double *y, int n, double *a, double *b)
{
int i,j;
double delta,sx=0,sy=0,sxx=0,sxy=0,syy=0;
for(i=0;i<n;++i)
{
sx+=x[i];
sy+=y[i];
sxx+=x[i]*x[i];
syy+=y[i]*y[i];
sxy+=x[i]*y[i];
}
delta=n*sxx-sx*sx;
*a=(sxx*sy-sx*sxy)/delta;
*b=(n*sxy-sx*sy)/delta;
}

60
c_tools/hod/linlin_bins.c Normal file
View file

@ -0,0 +1,60 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
void linlin_bins()
{
FILE *fp,*fp2;
char fname[100];
int nsize_rpi,nsize_rsig,i,j;
double rp,rs,r,dx1,dx2,dx3,dx4,dx5,rslo,rshi,drs,binsize_rpi=2;
float x1;
nsize_rpi=15;
nsize_rsig=15;
binsize_rpi=2.0;
sprintf(fname,"%s.linlin",Task.root_filename);
fp=fopen(fname,"w");
rshi=0;
for(i=1;i<=nsize_rsig;++i)
{
rslo=rshi;
rshi=rslo+binsize_rpi;
drs=rshi-rslo;
rs=0.5*(rshi+rslo);
for(j=1;j<=nsize_rpi;++j)
{
rp=(j-0.5)*binsize_rpi;
r=sqrt(rs*rs+rp*rp);
if(!KAISER)
{
dx4=two_halo(rs,rp);
dx1=one_halo(rs,rp);
}
else
{
dx1=0;
dx4=0;
}
/*
dx5=integrated_bin(rslo,(j-1)*binsize_rpi,drs,binsize_rpi,10);
*/
dx5=xi2d_interp(rslo,(j-1)*binsize_rpi,rslo+drs,j*binsize_rpi);
fprintf(fp,"%e %e %e %e %e\n",rs,rp,dx5,dx1,dx4);
fprintf(stdout,"%e %e %e %e %e\n",rs,rp,dx5,dx1,dx4);
fflush(stdout);
fflush(fp);
}
}
fclose(fp);
}

38
c_tools/hod/linmin.c Normal file
View file

@ -0,0 +1,38 @@
#define NRANSI
#include "nrutil.h"
#define TOL 2.0e-4
int ncom;
double *pcom,*xicom,(*nrfunc)(double []);
void linmin(double p[], double xi[], int n, double *fret, double (*func)(double []))
{
double brent(double ax, double bx, double cx,
double (*f)(double), double tol, double *xmin);
double f1dim(double x);
void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb,
double *fc, double (*func)(double));
int j;
double xx,xmin,fx,fb,fa,bx,ax;
ncom=n;
pcom=dvector(1,n);
xicom=dvector(1,n);
nrfunc=func;
for (j=1;j<=n;j++) {
pcom[j]=p[j];
xicom[j]=xi[j];
}
ax=0.0;
xx=1.0;
mnbrak(&ax,&xx,&bx,&fa,&fx,&fb,f1dim);
*fret=brent(ax,xx,bx,f1dim,TOL,&xmin);
for (j=1;j<=n;j++) {
xi[j] *= xmin;
p[j] += xi[j];
}
free_dvector(xicom,1,n);
free_dvector(pcom,1,n);
}
#undef TOL
#undef NRANSI

1083
c_tools/hod/m2n_mcmc.c Normal file

File diff suppressed because it is too large Load diff

1047
c_tools/hod/m2n_mcmc_new.c Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

109
c_tools/hod/main.c Normal file
View file

@ -0,0 +1,109 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* test file routines.
*/
void test(int argc, char **argv);
void chi2_grid(int argc, char **argv);
void fit_scale_bias(int argc, char **argv);
void aspen_breakout(void);
void populate_simulation_clf(void);
int main(int argc, char **argv)
{
double s1;
int i;
#ifdef PARALLEL
printf("STARTING>>>\n");
fflush(stdout);
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
MPI_Comm_size(MPI_COMM_WORLD, &NTask);
printf("TASK %d reporting for duty.\n",ThisTask);
fflush(stdout);
#endif
OUTPUT=0;
for(i=1;i<=99;++i)
HOD.free[i]=0;
wp.esys=0;
Work.chi2=0;
Work.imodel=1;
USE_ERRORS = 0;
ITRANS=4;
HUBBLE=0.7;
BEST_FIT = 0;
HOD.M_sat_break = 1.0e14;
HOD.alpha1 = 1.0;
if(argc==1)
endrun("./HOD.x hod.bat_file > output");
read_parameter_file(argv[1]);
/* If there's no cross-correlation function,
* set the second number density equal to the first
*/
if(!XCORR)
GALAXY_DENSITY2 = GALAXY_DENSITY;
/* Initialize the non-linear power spectrum.
*/
nonlinear_sigmac(8.0);
sigmac_interp(1.0E13);
sigmac_radius_interp(1.0);
if(argc>2)
IDUM_MCMC=atoi(argv[2]);
// if(MCMC)m2n_mcmc();
/* Get the galaxy bias factor
*/
s1=qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt);
GALAXY_BIAS=s1/GALAXY_DENSITY;
if(OUTPUT)
fprintf(stdout,"Galaxy Bias bg= %f\n",GALAXY_BIAS);
/* Get the galaxy satellite fraction
*/
s1=qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/
GALAXY_DENSITY;
if(OUTPUT)
fprintf(stdout,"fsat %e\n",s1);
/* Mean halo mass.
*/
if(OUTPUT)
fprintf(stdout,"M_eff %e\n",number_weighted_halo_mass());
/* Set up BETA for wp integration.
*/
BETA = pow(OMEGA_M,0.6)/GALAXY_BIAS;
if(OUTPUT)
printf("BETA = %f\n",BETA);
/* Check for extra commands:
* arg==999 goes to the test program, superceding tasks.
* arg<0 supercedes the MCMC random number in the batfile.
*/
if(argc>2)
{
if(atoi(argv[2])==999)
test(argc,argv);
}
tasks(argc,argv);
}

69
c_tools/hod/mass2number.c Normal file
View file

@ -0,0 +1,69 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
int g31_number;
double poisson_prob(int n, double nave);
double func1_m2n(double m);
double func2_m2n(double m);
void mass2number()
{
int i,j,k,n;
double s1,s2,mbar;
char fname[1000];
FILE *fp;
sprintf(fname,"%s.M2N",Task.root_filename);
fp = fopen(fname,"w");
for(i=2;i<=10;++i)
{
g31_number = i;
s1 = qromo(func1_m2n,log(HOD.M_low),log(HOD.M_max),midpnt);
s2 = qromo(func2_m2n,log(HOD.M_low),log(HOD.M_max),midpnt);
mbar = s1/s2;
fprintf(fp,"%d %e %e\n",i,mbar,mbar/i);
}
for(i=20;i<=150;i+=10)
{
g31_number = i;
s1 = qromo(func1_m2n,log(HOD.M_low),log(HOD.M_max),midpnt);
s2 = qromo(func2_m2n,log(HOD.M_low),log(HOD.M_max),midpnt);
mbar = s1/s2;
fprintf(fp,"%d %e %e\n",i,mbar,mbar/i);
}
fclose(fp);
}
double func1_m2n(double m)
{
double ncen,nsat,x;
m = exp(m);
ncen = N_cen(m);
nsat = N_sat(m);
x = poisson_prob(g31_number-1,nsat);
// printf("%e %e %e %e %e\n",m,ncen,nsat,poisson_prob(g31_number-1,nsat));
if(isnan(x))x = 0;
return ncen*x*m*m*dndM_interp(m);
}
double func2_m2n(double m)
{
double ncen,nsat,x;
m = exp(m);
ncen = N_cen(m);
nsat = N_sat(m);
x = poisson_prob(g31_number-1,nsat);
if(isnan(x))x = 0;
return ncen*x*m*dndM_interp(m);
}

469
c_tools/hod/mcmc.c Normal file
View file

@ -0,0 +1,469 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* External functions from wp_minimization.c
*/
void wp_input(void);
double mcmc_initialize(double *a, double **cov1, double *avg1, double *start_dev);
/* Internal functions.
*/
double chi2_wp_wrapper(double *a);
int USE_IWEIGHT = 0;
/******************************************************************
*
* HOD.free[] also controls which variables will be held constant/vary
* during MCMC minimization. Since this routine will also so z-space
* minimization if requested, indices>6 are cosmological.
*
* i variable
* --- --------
* [1] -> M_min
* [2] -> M1
* [3] -> alpha
* [4] -> M_cut
* [5] -> sigmaM
* [6] -> CVIR_FAC
* [7] -> MaxCen (or M_cen_max)
* [8] -> M_sat_break
* [9] -> alpha1
*
* [10]-> OMEGA_M
* [11]-> SIGMA_8
* [12]-> VBIAS
* [13]-> VBIAS_C
* [14]-> GAMMA
* [15]-> SPECTRAL_INDX
*
* [0] -> The galaxy_density will be considered data with errors on it,
* and therefore no variable will be fixed by the galaxy density.
*
*/
void mcmc_minimization()
{
double stepfac=1;
double error=1,tolerance=0,**cov1,**tmp,*a,*avg1,chi2,chi2prev,
**evect,*eval,*aprev,*atemp,**tmp1,*opar,x1,fsat,**chain,*start_dev,*eval_prev;
int n,i,j,k,nrot,niter=0,count=0,imax_chain=100000,NSTEP=50,NSTEP_MAX=10000,convergence=0;
long IDUM=-555;
int *pcheck,pcnt,ptot=20,firstflag=1,*iweight,total_weight,icvir;
double t0,tprev,temp,chi2a,chi2b;
FILE *fpmcmc;
char fname[1000];
sprintf(fname,"%s.MCMC",Task.root_filename);
fpmcmc = fopen(fname,"w");
opar=dvector(1,100);
MCMC=Task.MCMC;
pcheck=calloc(ptot,sizeof(int));
wp_input();
Work.imodel=2;
Work.chi2=1;
OUTPUT=0;
srand48(32498793);
/* Find the number of free parameters in the minimization
* for the real-space correlation function.
*/
for(n=0,i=1;i<100;++i)
{
n+=HOD.free[i];
if(OUTPUT)
printf("mcmc_min> free[%i] = %d\n",i,HOD.free[i]);
}
wp.ncf=n;
/* Find out which free parameter is for CVIR_FAC
*/
j=0;
if(HOD.free[6])
for(i=0;i<6;++i)
if(HOD.free[i])j++;
icvir=j+1;
if(HOD.free[0])
{
wp.ngal = GALAXY_DENSITY;
wp.ngal_err = 0.1*wp.ngal;
FIX_PARAM = 0;
}
if(OUTPUT)
printf("mcmc_min> %d free parameters\n",n);
a=dvector(1,n);
start_dev=dvector(1,n);
aprev=dvector(1,n);
atemp=dvector(1,n);
cov1=dmatrix(1,n,1,n);
avg1=dvector(1,n);
tmp=dmatrix(1,n,1,n);
tmp1=dmatrix(1,n,1,1);
evect=dmatrix(1,n,1,n);
eval=dvector(1,n);
eval_prev=dvector(1,n);
chain=dmatrix(1,imax_chain,1,n);
iweight = ivector(1,imax_chain);
for(i=1;i<=imax_chain;++i)
iweight[i] = 0;
IDUM=IDUM_MCMC;
chi2prev=mcmc_initialize(a,cov1,avg1,start_dev);
niter++;
for(i=1;i<=n;++i)
{
aprev[i] = a[i];
chain[1][i] = a[i];
}
pcnt=0;
pcheck[pcnt]=1;
stepfac=1;
while(niter<NSTEP)
{
pcnt++;
if(pcnt==ptot)
{
for(j=i=0;i<ptot;++i)j+=pcheck[i];
stepfac = stepfac*pow(0.9,5-j);
if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
pcnt=0;
}
/* stepfac=0.7; */
for(i=1;i<=n;++i)
a[i] = (1+gasdev(&IDUM)*start_dev[i]*stepfac)*aprev[i];
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
if(HOD.free[++i])GAMMA = a[++j];
if(HOD.free[++i])SPECTRAL_INDX = a[++j];
}
if(VBIAS_C<0)continue;
/* Hard-wire CVIR variation
*/
if(HOD.free[6])
CVIR_FAC = a[icvir];
chi2=chi2_wp_wrapper(a);
pcheck[pcnt]=1;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
{
if(USE_IWEIGHT)
iweight[niter+1]++;
pcheck[pcnt]=0;
continue;
}
niter++;
iweight[niter]++;
for(i=1;i<=n;++i)
chain[niter][i]=a[i];
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
if(!ThisTask){
fprintf(fpmcmc,"%d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(fpmcmc);
}
}
stepfac=1.6/sqrt(n);
pcnt=-1;
t0 = second();
NSTEP = niter;
while(niter<imax_chain)
{
stepfac=1.6/sqrt(n);
if(convergence)goto SKIP_MATRIX;
for(j=1;j<=n;++j)
{
avg1[j]=0;
for(k=1;k<=n;++k)
cov1[j][k]=0;
}
total_weight = 0;
for(i=1;i<=niter;++i)
{
for(j=1;j<=n;++j)
{
avg1[j]+=chain[i][j]*iweight[i];
for(k=1;k<=n;++k)
cov1[j][k]+=chain[i][j]*chain[i][k]*iweight[i];
}
total_weight+=iweight[i];
}
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
tmp[i][j] = cov1[i][j]/total_weight - avg1[i]*avg1[j]/(total_weight*total_weight);
jacobi(tmp,n,eval,evect,&nrot);
gaussj(evect,n,tmp1,1);
SKIP_MATRIX:
for(i=1;i<=n;++i)
atemp[i] = gasdev(&IDUM)*sqrt(eval[i])*stepfac;
for(i=1;i<=n;++i)
for(a[i]=0,j=1;j<=n;++j)
a[i] += atemp[j]*evect[j][i];
for(i=1;i<=n;++i)
a[i] += aprev[i];
/* We seem to be having a problem with this.
* So, broadcast the model params from the root processor.
*/
#ifdef PARALLEL
MPI_Bcast(&a[1],n,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD);
#endif
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
if(HOD.free[++i])GAMMA = a[++j];
if(HOD.free[++i])SPECTRAL_INDX = a[++j];
/* if(HOD.free[++i])SIGV = a[++j]; */
}
if(VBIAS_C<0)continue;
/* Hard-wire CVIR variation
*/
if(HOD.free[6])
CVIR_FAC = a[icvir];
chi2=chi2_wp_wrapper(a);
tprev = t0;
t0 = second();
++count;
pcheck[pcnt]=0;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
{
if(USE_IWEIGHT)
iweight[niter+1]++;
continue;
}
pcheck[pcnt]=1;
niter++;
if(!convergence)NSTEP = niter;
iweight[niter]++;
if(niter%NSTEP_MAX==0 && !convergence && niter>NSTEP_MAX)
{
convergence = 1;
for(i=1;i<=n;++i)
{
x1=fabs(eval[i]-eval_prev[i])/eval_prev[i];
if(x1>0.01)convergence = 0;
printf("CONVERGENCE CHECK %d %d %e %e %e\n",niter/NSTEP_MAX,i,x1,eval[i],eval_prev[i]);
}
for(i=1;i<=n;++i)
eval_prev[i] = eval[i];
convergence = 0;
if(convergence)
printf("CONVERGENCE ACCOMPLISHED %d %d \n",niter,count);
}
if(niter==NSTEP_MAX)
{
for(i=1;i<=n;++i)
eval_prev[i] = eval[i];
}
for(i=1;i<=n;++i)
chain[niter][i]=a[i];
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
if(!ThisTask) {
fprintf(fpmcmc,"%d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(fpmcmc);
}
}
}
double chi2_wp_wrapper(double *a)
{
static int flag=1;
static double *b;
int i,j;
if(flag)
{
b=dvector(1,100);
flag=0;
}
for(j=0,i=1;i<=N_HOD_PARAMS;++i) {
if(HOD.free[i] && i!=5) {
if(a[++j]<=0) { printf("NEG %d %d %e\n",i,j,a[j]); return(1.0E7); } }
if(HOD.free[i] && i==5) {
++j; }
}
i=0;j=0;
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_min */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M1 */
if(HOD.free[++i]){j++;b[j]=a[j];} /* alpha */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_cut */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* sigma_logM */
if(HOD.free[++i]){j++;b[j]=a[j];} /* cvir_fac */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* MaxCen */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_sat_break */
if(HOD.free[++i]){j++;b[j]=a[j];} /* alpha1 */
return(chi2_wp(b));
}
double mcmc_initialize(double *a, double **cov1, double *avg1, double *start_dev)
{
int i,j=0;
double x1,x2,omega_m;
long IDUM = -556;
omega_m = 1;
if(MCMC>1)
omega_m = OMEGA_M;
i=0;j=0;
if(HOD.free[++i]){ a[++j]=log10(HOD.M_min/omega_m);start_dev[j]=0.001; }
if(HOD.free[++i]){ a[++j]=log10(HOD.M1/omega_m);start_dev[j]=0.001; } //.0005
if(HOD.free[++i]){ a[++j]=HOD.alpha;start_dev[j]=0.03; } //.005
if(HOD.free[++i]){ a[++j]=log10(HOD.M_cut/omega_m);start_dev[j]=0.01; } //.001
if(HOD.free[++i]){ a[++j]=log10(HOD.sigma_logM);start_dev[j]=0.01; }
if(HOD.free[++i]){ a[++j]=CVIR_FAC;start_dev[j]=0.02; }
if(HOD.pdfc==7) {
if(HOD.free[++i])a[++j]=log10(HOD.M_cen_max/omega_m); start_dev[j]=0.001; }
else {
if(HOD.free[++i])a[++j]=HOD.MaxCen; start_dev[j]=0.02; }
if(HOD.free[++i]){ a[++j]=log10(HOD.M_sat_break/omega_m);start_dev[j]=0.001; }
if(HOD.free[++i]){ a[++j]=HOD.alpha1;start_dev[j]=0.02; }
if(MCMC>1)
{
if(HOD.free[++i])a[++j]=OMEGA_M;
if(HOD.free[++i])a[++j]=SIGMA_8;
if(HOD.free[++i])a[++j]=VBIAS;
if(HOD.free[++i])a[++j]=VBIAS_C;
if(HOD.free[++i])a[++j]=GAMMA;
if(HOD.free[++i])a[++j]=SPECTRAL_INDX;
}
if(!ThisTask)
{
printf("INITIAL VALUES: ");
for(i=1;i<=wp.ncf;++i)printf("%e ",a[i]);
printf("\n");
}
for(i=1;i<=wp.ncf;++i)
{
avg1[i]=a[i];
for(j=1;j<=wp.ncf;++j)
cov1[i][j]=a[i]*a[j];
}
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i]){ OMEGA_M = a[++j]; start_dev[j] = 0.01; }
if(HOD.free[++i]){ SIGMA_8 = a[++j]; start_dev[j] = 0.01; }
if(HOD.free[++i]){ VBIAS = a[++j]; start_dev[j] = 0.01; }
if(HOD.free[++i]){ VBIAS_C = a[++j]; start_dev[j] = 0.02; }
if(HOD.free[++i]){ GAMMA = a[++j]; start_dev[j] = 0.015; }
if(HOD.free[++i]){ SPECTRAL_INDX = a[++j]; start_dev[j] = 0.02; }
}
x1=chi2_wp_wrapper(a);
x2=0;
if(!ThisTask) {
printf("TRY 0 ");
for(i=1;i<=wp.ncf;++i)
printf("%.4e ",a[i]);
printf("%e\n",x1+x2);fflush(stdout);
printf("INITIAL CHI2: %e %e\n",x1,x2);
fflush(stdout);
}
return(x1+x2);
}

539
c_tools/hod/mcmc_color.c Normal file
View file

@ -0,0 +1,539 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* External functions from wp_minimization.c
*/
void wp_input(void);
void wp_color_input(void);
double chi2_wp_color(double *a);
double chi2_wp_color_wrapper(double *a);
/* inteernal functions
*/
double mcmc_color_initialize(double *a, double **cov1, double *avg1, double *start_dev);
void mcmc_color_minimization()
{
double stepfac=1;
double error=1,tolerance=0,**cov1,**tmp,*a,*avg1,chi2,chi2prev,
**evect,*eval,*aprev,*atemp,**tmp1,*opar,x1,fsat,**chain,*start_dev,*eval_prev;
int n,i,j,k,nrot,niter=0,count=0,imax_chain=100000,NSTEP=50,NSTEP_MAX=10000,convergence=0;
long IDUM=-555;
int *pcheck,pcnt,ptot=20,firstflag=1,*iweight,total_weight;
double t0,tprev,temp,chi2a,chi2b;
opar=dvector(1,100);
MCMC=Task.MCMC;
pcheck=calloc(ptot,sizeof(int));
Work.imodel=2;
Work.chi2=1;
OUTPUT=1;
fprintf(stderr,"\n\nMCMC OF W_P(R_P) COLOR DATA..........\n");
fprintf(stderr, "--------------------------------------------\n\n");
HOD.blue_fraction = 0.5857; /* <- Millenium fraction (sloan);; SDSS fraction -> 0.565; */
HOD.blue_fraction = 0.6555; /* <- Millenium fraction (B-V>0.8) */
HOD.blue_fraction = 0.565; /* SDSS -19,-20 */
HOD.blue_fraction = 0.492; /* SDSS -20,-21 */
HOD.blue_fraction = 0.379; /* SDSS -21 */
wp_color.ON = 1;
wp_color_input();
srand48(32498793);
/* Find the number of free parameters in the minimization
* for the real-space correlation function.
*/
for(n=0,i=1;i<12;++i)
{
n+=HOD.free[i];
/* if(i>N_HOD_PARAMS && HOD.free[i])MCMC=3;*/
if(OUTPUT)
printf("mcmc_min> free[%i] = %d\n",i,HOD.free[i]);
}
// add 3 parameters for the color stuff
n+=3;
wp.ncf=n;
if(HOD.free[0])
{
wp.ngal = GALAXY_DENSITY;
wp.ngal_err = 0.1*wp.ngal;
FIX_PARAM = 0;
}
if(OUTPUT)
printf("mcmc_min> %d free parameters\n",n);
a=dvector(1,n);
start_dev=dvector(1,n);
aprev=dvector(1,n);
atemp=dvector(1,n);
cov1=dmatrix(1,n,1,n);
avg1=dvector(1,n);
tmp=dmatrix(1,n,1,n);
tmp1=dmatrix(1,n,1,1);
evect=dmatrix(1,n,1,n);
eval=dvector(1,n);
eval_prev=dvector(1,n);
chain=dmatrix(1,imax_chain,1,n);
iweight = ivector(1,imax_chain);
for(i=1;i<=imax_chain;++i)
iweight[i] = 0;
IDUM=IDUM_MCMC;
//chi2prev=mcmc_initialize(a,cov1,avg1,start_dev);
chi2prev=mcmc_color_initialize(a,cov1,avg1,start_dev);
//initial_color_values(a,pp,yy);
niter++;
for(i=1;i<=n;++i)
{
aprev[i] = a[i];
chain[1][i] = a[i];
}
pcnt=0;
pcheck[pcnt]=1;
stepfac=1;
while(niter<NSTEP)
{
pcnt++;
if(pcnt==ptot)
{
for(j=i=0;i<ptot;++i)j+=pcheck[i];
stepfac = stepfac*pow(0.9,5-j);
if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
pcnt=0;
}
/* stepfac=0.7; */
for(i=1;i<=n;++i)
a[i] = (1+gasdev(&IDUM)*start_dev[i]*stepfac)*aprev[i];
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
if(HOD.free[++i])GAMMA = a[++j];
if(HOD.free[++i])SPECTRAL_INDX = a[++j];
/* if(HOD.free[++i])SIGV = a[++j]; */
}
if(VBIAS_C<0)continue;
/* Hard-wire CVIR variation
*/
if(HOD.free[6])
CVIR_FAC = a[3];
chi2=chi2_wp_color_wrapper(a);
if(!ThisTask){
printf("TRY %d ",++count);
for(i=1;i<=n;++i)
printf("%.4e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
}
pcheck[pcnt]=1;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
{
/* This for loop puts the prev element in the chain is
* the current trial point is rejected.
*/
/* For the initialization, don't use this: we need
* separate elements for estimating the covariance matrix.
*/
/*
for(i=1;i<=n;++i)
a[i] = aprev[i];
chi2 = chi2prev;
*/
pcheck[pcnt]=0;
continue;
}
niter++;
iweight[niter]++;
for(i=1;i<=n;++i)
chain[niter][i]=a[i];
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
if(!ThisTask){
printf("ACCEPT %d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
number_weighted_central_mass(),
qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
printf("FSAT %d %e %e %e %e\n",niter,HOD.M_min,wp.fsat_red,wp.fsat_blue,wp.fsat_all);
}
}
RESTART_POINT:
stepfac=1.6/sqrt(n);
pcnt=-1;
t0 = second();
NSTEP = niter;
while(niter<imax_chain)
{
pcnt++;
if(pcnt==ptot)
{
for(j=i=0;i<ptot;++i)j+=pcheck[i];
//stepfac=1.6/sqrt(n);
//stepfac=0.6/sqrt(n);
// stepfac = stepfac*pow(0.9,6-j);
stepfac = 0.25;
stepfac = 0.5;
stepfac=1.6/sqrt(n);
if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
pcnt=0;
}
stepfac=1.6/sqrt(n);
//stepfac = 0;
if(convergence)goto SKIP_MATRIX;
// if(niter>NSTEP_MAX && niter%NSTEP_MAX!=0)goto SKIP_MATRIX;
for(j=1;j<=n;++j)
{
avg1[j]=0;
for(k=1;k<=n;++k)
cov1[j][k]=0;
}
total_weight = 0;
for(i=1;i<=niter;++i)
{
for(j=1;j<=n;++j)
{
avg1[j]+=chain[i][j]*iweight[i];
for(k=1;k<=n;++k)
cov1[j][k]+=chain[i][j]*chain[i][k]*iweight[i];
}
total_weight+=iweight[i];
}
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
tmp[i][j] = cov1[i][j]/total_weight - avg1[i]*avg1[j]/(total_weight*total_weight);
jacobi(tmp,n,eval,evect,&nrot);
gaussj(evect,n,tmp1,1);
SKIP_MATRIX:
if(RESTART==4)convergence = 1;
if(RESTART && count==0)stepfac=0;
for(i=1;i<=n;++i)
atemp[i] = gasdev(&IDUM)*sqrt(eval[i])*stepfac;
for(i=1;i<=n;++i)
for(a[i]=0,j=1;j<=n;++j)
a[i] += atemp[j]*evect[j][i];
for(i=1;i<=n;++i)
a[i] += aprev[i];
/* We seem to be having a problem with this.
* So, broadcast the model params from the root processor.
*/
#ifdef PARALLEL
MPI_Bcast(&a[1],n,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD);
#endif
// CHeck that the chi2 for the last point in the restart chain
// is recovered.
/*
if(RESTART && !count)
for(i=1;i<=n;++i)
a[i] = aprev[i];
*/
if(RESTART==5)
{
j = count+1;
if(j>4000)exit(0);
for(i=1;i<=n;++i)
a[i] = chain[j][i];
}
/*
if(!ThisTask)
for(i=1;i<=n;++i)
{
printf("COV %d %d %e ",count,i,sqrt(eval[i]));
for(j=1;j<=n;++j)
printf("%e ",evect[j][i]);
printf("\n");
}
*/
/* Using only variances
*/
//for(i=1;i<=n;++i)
// a[i] = aprev[i] + gasdev(&IDUM)*sqrt(tmp[i][i])*stepfac;
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
if(HOD.free[++i])GAMMA = a[++j];
if(HOD.free[++i])SPECTRAL_INDX = a[++j];
/* if(HOD.free[++i])SIGV = a[++j]; */
}
if(VBIAS_C<0)continue;
/* Hard-wire CVIR variation
*/
if(HOD.free[6])
CVIR_FAC = a[3];
chi2=chi2_wp_color_wrapper(a);
tprev = t0;
t0 = second();
++count;
if(!ThisTask) {
printf("TRY %d ",count);
for(i=1;i<=n;++i)
printf("%.4e ",a[i]);
if(RESTART==2) {
printf("%e %e %.2f\n",chi2,chi2/(1+exp(-count/100.0)),
timediff(tprev,t0));fflush(stdout); }
else {
printf("%e %.2f\n",chi2,
timediff(tprev,t0));fflush(stdout); }
}
if(0) {
printf("CPU%02d %d ",ThisTask,count);
for(i=1;i<=n;++i)
printf("%.4e ",a[i]);
if(RESTART==2) {
printf("%e %e %.2f\n",chi2,chi2/(1+exp(-count/100.0)),
timediff(tprev,t0));fflush(stdout); }
else {
printf("%e %.2f\n",chi2,
timediff(tprev,t0));fflush(stdout); }
}
pcheck[pcnt]=0;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
{
/*
for(i=1;i<=n;++i)
a[i] = aprev[i];
chi2 = chi2prev;
*/
continue;
}
pcheck[pcnt]=1;
// if(NSTEP<NSTEP_MAX)NSTEP++;
niter++;
if(!convergence)NSTEP = niter;
iweight[niter]++;
if(niter%NSTEP_MAX==0 && !convergence && niter>NSTEP_MAX)
{
convergence = 1;
for(i=1;i<=n;++i)
{
x1=fabs(eval[i]-eval_prev[i])/eval_prev[i];
if(x1>0.01)convergence = 0;
printf("CONVERGENCE CHECK %d %d %e %e %e\n",niter/NSTEP_MAX,i,x1,eval[i],eval_prev[i]);
}
for(i=1;i<=n;++i)
eval_prev[i] = eval[i];
convergence = 0;
if(convergence)
printf("CONVERGENCE ACCOMPLISHED %d %d \n",niter,count);
}
if(niter==NSTEP_MAX)
{
for(i=1;i<=n;++i)
eval_prev[i] = eval[i];
}
for(i=1;i<=n;++i)
chain[niter][i]=a[i];
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
if(!ThisTask) {
printf("ACCEPT %d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
printf("FSAT %d %e %e %e %e\n",niter,HOD.M_min,wp.fsat_red,wp.fsat_blue,wp.fsat_all);
if(MCMC==1)
{
printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
number_weighted_central_mass(),
qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
}
}
}
}
double chi2_wp_color_wrapper(double *a)
{
static int flag=1;
static double *b;
int i,j;
if(flag)
{
b=dvector(1,100);
flag=0;
}
for(j=0,i=1;i<=N_HOD_PARAMS;++i) {
if(HOD.free[i] && i!=5) {
if(a[++j]<=0) { printf("NEG %d %d %e\n",i,j,a[j]); return(1.0E7); } }
if(HOD.free[i] && i==5) {
++j; }
}
i=0;j=0;
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_min */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M1 */
if(HOD.free[++i]){j++;b[j]=a[j];} /* alpha */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_cut */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* sigma_logM */
if(HOD.free[++i]){j++;b[j]=a[j];} /* cvir_fac */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* MaxCen */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_sat_break */
if(HOD.free[++i]){j++;b[j]=a[j];} /* alpha1 */
// now the 3 color params
++j;
b[j] = a[j];
++j;
b[j] = a[j];
++j;
b[j] = a[j];
muh(1);
return(chi2_wp_color(b));
}
double mcmc_color_initialize(double *a, double **cov1, double *avg1, double *start_dev)
{
int i,j=0;
double x1,x2,omega_m;
long IDUM = -556;
i=0;j=0;
if(HOD.free[++i]){ a[++j]=log10(HOD.M_min); start_dev[j]=0.001; }
if(HOD.free[++i]){ a[++j]=log10(HOD.M1); start_dev[j] = 0.001; }
if(HOD.free[++i]){ a[++j]=HOD.alpha; start_dev[j] = 0.03; }
if(HOD.free[++i]){ a[++j]=log10(HOD.M_cut); start_dev[j] = 0.01; }
if(HOD.free[++i]){ a[++j]=log10(HOD.sigma_logM); start_dev[j] = 0.01; }
if(HOD.free[++i]){ a[++j]=CVIR_FAC; start_dev[j] = 0.02; }
if(HOD.pdfc>=7){
if(HOD.free[++i]){ a[++j]=log10(HOD.M_cen_max); start_dev[j] = 0.001; }}
else {
if(HOD.free[++i]) { a[++j]=log10(HOD.MaxCen); start_dev[j] = 0.001; }}
a[++j] = HOD.fblue0_sat;
start_dev[j] = 0.01;
a[++j] = HOD.sigma_fblue_sat;
start_dev[j] = 0.01;
a[++j] = HOD.sigma_fblue_cen;
start_dev[j] = 0.01;
if(!ThisTask)
{
printf("INITIAL VALUES: ");
for(i=1;i<=wp.ncf;++i)printf("%e ",a[i]);
printf("\n");
}
for(i=1;i<=wp.ncf;++i)
{
avg1[i]=a[i];
for(j=1;j<=wp.ncf;++j)
cov1[i][j]=a[i]*a[j];
}
x1=chi2_wp_color_wrapper(a);
x2 = 0;
if(!ThisTask) {
printf("TRY 0 ");
for(i=1;i<=wp.ncf;++i)
printf("%.4e ",a[i]);
printf("%e\n",x1+x2);fflush(stdout);
printf("INITIAL CHI2: %e %e\n",x1,x2);
fflush(stdout);
}
return(x1+x2);
}

632
c_tools/hod/mcmc_exp.c Normal file
View file

@ -0,0 +1,632 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* External functions from wp_minimization.c
*/
void wp_input(void);
double mcmc_initialize(double *a, double **cov1, double *avg1, double *start_dev);
/* Internal functions.
*/
double chi2_wp_wrapper(double *a);
void mcmc_restart2(double *start_dev, int np);
int mcmc_restart3(double **chain, int n, double *chi2_prev, int *iweight);
int USE_IWEIGHT = 0;
/******************************************************************
*
* HOD.free[] also controls which variables will be held constant/vary
* during MCMC minimization. Since this routine will also so z-space
* minimization if requested, indices>6 are cosmological.
*
* i variable
* --- --------
* [1] -> M_min
* [2] -> M1
* [3] -> alpha
* [4] -> M_cut
* [5] -> sigmaM
* [6] -> CVIR_FAC
* [7] -> MaxCen (or M_cen_max)
* [8] -> M_sat_break
* [9] -> alpha1
*
* [10]-> OMEGA_M
* [11]-> SIGMA_8
* [12]-> VBIAS
* [13]-> VBIAS_C
* [14]-> GAMMA
* [15]-> SPECTRAL_INDX
*
* [0] -> The galaxy_density will be considered data with errors on it,
* and therefore no variable will be fixed by the galaxy density.
*
*/
void mcmc_minimization()
{
double stepfac=1;
double error=1,tolerance=0,**cov1,**tmp,*a,*avg1,chi2,chi2prev,
**evect,*eval,*aprev,*atemp,**tmp1,*opar,x1,fsat,**chain,*start_dev,*eval_prev;
int n,i,j,k,nrot,niter=0,count=0,imax_chain=100000,NSTEP=150,NSTEP_MAX=1000,convergence=0;
long IDUM=-555;
int *pcheck,pcnt,ptot=20,firstflag=1,*iweight,total_weight;
double t0,tprev,temp;
opar=dvector(1,100);
MCMC=Task.MCMC;
pcheck=calloc(ptot,sizeof(int));
if(MCMC>1 && !COVAR)
wp.esys=0.05;
if(!ThisTask)printf("ESYS %f %d\n",wp.esys,MCMC);
wp_input();
Work.imodel=2;
Work.chi2=1;
/*
OUTPUT=0;
*/
srand48(32498793);
/* Find the number of free parameters in the minimization
* for the real-space correlation function.
*/
for(n=0,i=1;i<100;++i)
{
n+=HOD.free[i];
/* if(i>N_HOD_PARAMS && HOD.free[i])MCMC=3;*/
if(OUTPUT)
printf("mcmc_min> free[%i] = %d\n",i,HOD.free[i]);
}
wp.ncf=n;
if(HOD.free[0])
{
wp.ngal = GALAXY_DENSITY;
wp.ngal_err = 0.1*wp.ngal;
FIX_PARAM = 0;
}
if(OUTPUT)
printf("mcmc_min> %d free parameters\n",n);
a=dvector(1,n);
start_dev=dvector(1,n);
aprev=dvector(1,n);
atemp=dvector(1,n);
cov1=dmatrix(1,n,1,n);
avg1=dvector(1,n);
tmp=dmatrix(1,n,1,n);
tmp1=dmatrix(1,n,1,1);
evect=dmatrix(1,n,1,n);
eval=dvector(1,n);
eval_prev=dvector(1,n);
chain=dmatrix(1,imax_chain,1,n);
iweight = ivector(1,imax_chain);
for(i=1;i<=imax_chain;++i)
iweight[i] = 0;
IDUM=IDUM_MCMC;
if(RESTART)
{
niter = mcmc_restart3(chain,n,&chi2prev,iweight);
if(niter < NSTEP)
{
if(ThisTask==0)
fprintf(stderr,"Not enough points in restart chain: %d<=%d\n",niter,NSTEP);
exit(0);
}
for(i=1;i<=n;++i)
aprev[i] = chain[niter][i];
goto RESTART_POINT;
}
chi2prev=mcmc_initialize(a,cov1,avg1,start_dev);
niter++;
for(i=1;i<=n;++i)
{
aprev[i] = a[i];
chain[1][i] = a[i];
}
pcnt=0;
pcheck[pcnt]=1;
if(RESTART==2)
{
mcmc_restart2(start_dev,n);
}
stepfac=1;
while(niter<NSTEP)
{
pcnt++;
if(pcnt==ptot)
{
for(j=i=0;i<ptot;++i)j+=pcheck[i];
stepfac = stepfac*pow(0.9,5-j);
if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
pcnt=0;
}
/* stepfac=0.7; */
for(i=1;i<=n;++i)
a[i] = (1+gasdev(&IDUM)*start_dev[i]*stepfac)*aprev[i];
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
if(HOD.free[++i])GAMMA = a[++j];
if(HOD.free[++i])SPECTRAL_INDX = a[++j];
/* if(HOD.free[++i])SIGV = a[++j]; */
}
if(VBIAS_C<0)continue;
/* Hard-wire CVIR variation
*/
if(HOD.free[6])
CVIR_FAC = a[3];
/* Draw random value of cvir from prior.
*/
/* if(CVIR_FAC<0.3 || CVIR_FAC>1.2)continue; */
/* CVIR_FAC = 0.9*drand48()+0.3; */
/* GAMMA = gasdev(&IDUM)*0.02 + 0.15; */
chi2=chi2_wp_wrapper(a);
if(MCMC>2 && chi2<1.0E7)chi2+=chi2_zspace(a);
if(!ThisTask){
printf("TRY %d ",++count);
for(i=1;i<=n;++i)
printf("%.4e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
}
pcheck[pcnt]=1;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
{
/* This for loop puts the prev element in the chain is
* the current trial point is rejected.
*/
/* For the initialization, don't use this: we need
* separate elements for estimating the covariance matrix.
*/
/*
for(i=1;i<=n;++i)
a[i] = aprev[i];
chi2 = chi2prev;
*/
if(USE_IWEIGHT)
iweight[niter+1]++;
pcheck[pcnt]=0;
continue;
}
niter++;
iweight[niter]++;
for(i=1;i<=n;++i)
chain[niter][i]=a[i];
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
if(!ThisTask){
printf("ACCEPT %d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
number_weighted_central_mass(),
qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
printf("FSAT %d %e %e %e %e\n",niter,fsat,HOD.M_min,HOD.sigma_logM,CVIR_FAC);
}
}
RESTART_POINT:
stepfac=1.6/sqrt(n);
pcnt=-1;
t0 = second();
NSTEP = niter;
while(niter<imax_chain)
{
pcnt++;
if(pcnt==ptot)
{
for(j=i=0;i<ptot;++i)j+=pcheck[i];
//stepfac=1.6/sqrt(n);
//stepfac=0.6/sqrt(n);
// stepfac = stepfac*pow(0.9,6-j);
stepfac = 0.25;
stepfac = 0.5;
stepfac=1.6/sqrt(n);
if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
pcnt=0;
}
//stepfac = 0;
if(convergence)goto SKIP_MATRIX;
// if(niter>NSTEP_MAX && niter%NSTEP_MAX!=0)goto SKIP_MATRIX;
for(j=1;j<=n;++j)
{
avg1[j]=0;
for(k=1;k<=n;++k)
cov1[j][k]=0;
}
total_weight = 0;
for(i=1;i<=niter;++i)
{
for(j=1;j<=n;++j)
{
avg1[j]+=chain[i][j]*iweight[i];
for(k=1;k<=n;++k)
cov1[j][k]+=chain[i][j]*chain[i][k]*iweight[i];
}
total_weight+=iweight[i];
}
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
tmp[i][j] = cov1[i][j]/total_weight - avg1[i]*avg1[j]/(total_weight*total_weight);
jacobi(tmp,n,eval,evect,&nrot);
gaussj(evect,n,tmp1,1);
SKIP_MATRIX:
if(RESTART==4)convergence = 1;
for(i=1;i<=n;++i)
atemp[i] = gasdev(&IDUM)*sqrt(eval[i])*stepfac;
for(i=1;i<=n;++i)
for(a[i]=0,j=1;j<=n;++j)
a[i] += atemp[j]*evect[j][i];
for(i=1;i<=n;++i)
a[i] += aprev[i];
if(!ThisTask)
for(i=1;i<=n;++i)
{
printf("COV %d %d %e ",count,i,sqrt(eval[i]));
for(j=1;j<=n;++j)
printf("%e ",evect[j][i]);
printf("\n");
}
/* Using only variances
*/
//for(i=1;i<=n;++i)
// a[i] = aprev[i] + gasdev(&IDUM)*sqrt(tmp[i][i])*stepfac;
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
if(HOD.free[++i])GAMMA = a[++j];
if(HOD.free[++i])SPECTRAL_INDX = a[++j];
/* if(HOD.free[++i])SIGV = a[++j]; */
}
if(VBIAS_C<0)continue;
/* Hard-wire CVIR variation
*/
if(HOD.free[6])
CVIR_FAC = a[3];
/* Draw random value of cvir from prior.
*/
/* CVIR_FAC = a[n]; */
/* if(CVIR_FAC<0.3 || CVIR_FAC>1.2)continue; */
/* CVIR_FAC = 0.7*drand48()+0.3; */
/* GAMMA = gasdev(&IDUM)*0.02 + 0.15; */
// printf("GAMMA %d %f %f\n",count+1,GAMMA,CVIR_FAC);
chi2=chi2_wp_wrapper(a);
if(MCMC>2 && chi2<1.0E7)chi2+=chi2_zspace(a);
tprev = t0;
t0 = second();
if(!ThisTask) {
printf("TRY %d ",++count);
for(i=1;i<=n;++i)
printf("%.4e ",a[i]);
printf("%e %.2f\n",chi2,timediff(tprev,t0));fflush(stdout);
}
pcheck[pcnt]=0;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
{
/*
for(i=1;i<=n;++i)
a[i] = aprev[i];
chi2 = chi2prev;
*/
if(USE_IWEIGHT)
iweight[niter+1]++;
continue;
}
pcheck[pcnt]=1;
// if(NSTEP<NSTEP_MAX)NSTEP++;
niter++;
if(!convergence)NSTEP = niter;
iweight[niter]++;
if(niter%NSTEP_MAX==0 && !convergence && niter>NSTEP_MAX)
{
convergence = 1;
for(i=1;i<=n;++i)
{
x1=fabs(eval[i]-eval_prev[i])/eval_prev[i];
if(x1>0.01)convergence = 0;
printf("CONVERGENCE CHECK %d %d %e %e %e\n",niter/NSTEP_MAX,i,x1,eval[i],eval_prev[i]);
}
for(i=1;i<=n;++i)
eval_prev[i] = eval[i];
convergence = 0;
if(convergence)
printf("CONVERGENCE ACCOMPLISHED %d %d \n",niter,count);
}
if(niter==NSTEP_MAX)
{
for(i=1;i<=n;++i)
eval_prev[i] = eval[i];
}
for(i=1;i<=n;++i)
chain[niter][i]=a[i];
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
if(!ThisTask) {
printf("ACCEPT %d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
number_weighted_central_mass(),
qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
printf("FSAT %d %e %e %e %e\n",niter,fsat,HOD.M_min,HOD.sigma_logM,CVIR_FAC);
}
}
}
double chi2_wp_wrapper(double *a)
{
static int flag=1;
static double *b;
int i,j;
if(flag)
{
b=dvector(1,100);
flag=0;
}
for(j=0,i=1;i<=N_HOD_PARAMS;++i) {
if(HOD.free[i] && i!=5) {
if(a[++j]<=0) { printf("NEG %d %d %e\n",i,j,a[j]); return(1.0E7); } }
if(HOD.free[i] && i==5) {
++j; }
}
i=0;j=0;
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_min */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M1 */
if(HOD.free[++i]){j++;b[j]=a[j];} /* alpha */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_cut */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* sigma_logM */
if(HOD.free[++i]){j++;b[j]=a[j];} /* cvir_fac */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* MaxCen */
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);} /* M_sat_break */
if(HOD.free[++i]){j++;b[j]=a[j];} /* alpha1 */
return(chi2_wp(b));
}
double mcmc_initialize(double *a, double **cov1, double *avg1, double *start_dev)
{
int i,j=0;
double x1,x2;
long IDUM = -556;
i=0;j=0;
if(HOD.free[++i]){ a[++j]=log10(HOD.M_min);start_dev[j]=0.001; }
if(HOD.free[++i]){ a[++j]=log10(HOD.M1);start_dev[j]=0.001; } //.0005
if(HOD.free[++i]){ a[++j]=HOD.alpha;start_dev[j]=0.03; } //.005
if(HOD.free[++i]){ a[++j]=log10(HOD.M_cut);start_dev[j]=0.01; } //.001
if(HOD.free[++i]){ a[++j]=log10(HOD.sigma_logM);start_dev[j]=0.01; }
if(HOD.free[++i]){ a[++j]=CVIR_FAC;start_dev[j]=0.02; }
if(HOD.pdfc==7) {
if(HOD.free[++i])a[++j]=log10(HOD.M_cen_max); start_dev[j]=0.001; }
else {
if(HOD.free[++i])a[++j]=HOD.MaxCen; start_dev[j]=0.02; }
if(HOD.free[++i]){ a[++j]=log10(HOD.M_sat_break);start_dev[j]=0.001; }
if(HOD.free[++i]){ a[++j]=HOD.alpha1;start_dev[j]=0.02; }
if(MCMC>1)
{
if(HOD.free[++i])a[++j]=OMEGA_M;
if(HOD.free[++i])a[++j]=SIGMA_8;
if(HOD.free[++i])a[++j]=VBIAS;
if(HOD.free[++i])a[++j]=VBIAS_C;
if(HOD.free[++i])a[++j]=GAMMA;
if(HOD.free[++i])a[++j]=SPECTRAL_INDX;
}
printf("INITIAL VALUES: ");
for(i=1;i<=wp.ncf;++i)printf("%e ",a[i]);
printf("\n");
for(i=1;i<=wp.ncf;++i)
{
avg1[i]=a[i];
for(j=1;j<=wp.ncf;++j)
cov1[i][j]=a[i]*a[j];
}
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
i=N_HOD_PARAMS;
if(HOD.free[++i]){ OMEGA_M = a[++j]; start_dev[j] = 0.01; }
if(HOD.free[++i]){ SIGMA_8 = a[++j]; start_dev[j] = 0.01; }
if(HOD.free[++i]){ VBIAS = a[++j]; start_dev[j] = 0.01; }
if(HOD.free[++i]){ VBIAS_C = a[++j]; start_dev[j] = 0.02; }
if(HOD.free[++i]){ GAMMA = a[++j]; start_dev[j] = 0.015; }
if(HOD.free[++i]){ SPECTRAL_INDX = a[++j]; start_dev[j] = 0.02; }
}
x1=chi2_wp_wrapper(a);
if(MCMC>2)
x2=chi2_zspace(a);
else
x2=0;
if(!ThisTask) {
printf("TRY 0 ");
for(i=1;i<=wp.ncf;++i)
printf("%.4e ",a[i]);
printf("%e\n",x1+x2);fflush(stdout);
printf("INITIAL CHI2: %e %e\n",x1,x2);
fflush(stdout);
}
return(x1+x2);
}
/* This is to look at a chain and get the variances in each parameter.
*/
void mcmc_restart2(double *start_dev, int np)
{
int n,i,j,k,i1,i2;
FILE *fp;
char aa[100];
float xbar[10],xsqr[10],x;
fp = openfile(RESTART_FILE);
n = filesize(fp);
for(i=0;i<np;++i)
xbar[i] = xsqr[i] = 0;
for(i=1;i<=n;++i)
{
fscanf(fp,"%s %d %d",aa,&i1,&i2);
for(j=0;j<np;++j)
{
fscanf(fp,"%f",&x);
xbar[j] += x;
xsqr[j] += x*x;
}
fgets(aa,100,fp);
}
for(i=0;i<np;++i)
{
xbar[i]/=n;
xsqr[i]/=n;
xsqr[i] = sqrt(xsqr[i] - xbar[i]*xbar[i]);
start_dev[i+1] = xsqr[i];
if(!ThisTask)
fprintf(stdout,"RESTART_DEV %f %f\n",xbar[i],xsqr[i]);
}
}
int mcmc_restart3(double **chain, int n, double *chi2_prev, int *iweight)
{
FILE *fp;
char aa[100];
int niter,i,j,i1,i2,iprev;
double x,*a,chi2;
fp = openfile(RESTART_FILE);
niter = filesize(fp);
a = dvector(1,n);
fscanf(fp,"%s %d %d",aa,&i1,&i2);
rewind(fp);
iprev = i2 - 1;
for(i=1;i<=niter;++i)
{
fscanf(fp,"%s %d %d",aa,&i1,&i2);
if(USE_IWEIGHT)
iweight[i] = i2 - iprev;
else
iweight[i] = 1;
iprev = i2;
for(j=1;j<=n;++j)
fscanf(fp,"%lf",&chain[i][j]);
fscanf(fp,"%lf",&x);
}
*chi2_prev = 20000*x; // set it to automatically take the first element
//*chi2_prev = x;
/* Normalize all the masses by OMEGA_M
*/
for(i=1;i<=niter;++i)
{
chain[i][1] -= log10(chain[i][4]);
chain[i][3] -= log10(chain[i][4]);
}
return niter;
}

View file

@ -0,0 +1,425 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* External functions from wp_minimization.c
*/
void wp_input(void);
double mcmc_initialize(double *a, double **cov1, double *avg1);
/* Internal functions.
*/
void choose_bias_fit(void);
double chi2_wp_wrapper(double *);
void choose_dndM_fit(void);
/******************************************************************
*
* HOD.free[] also controls which variables will be held constant/vary
* during MCMC minimization. Since this routine will also so z-space
* minimization if requested, indices>6 are cosmological.
*
* i variable
* --- --------
* [1] -> M_min
* [2] -> M1
* [3] -> alpha
* [4] -> M_cut
* [5] -> sigmaM
* [6] -> CVIR_FAC
* [7] -> OMEGA_M
* [8] -> SIGMA_8
* [9] -> VBIAS
*
*/
void mcmc_minimization()
{
int EJENK=1,EBIAS=0;
double stepfac=1;
double error=1,tolerance=0,**cov1,**tmp,*a,*avg1,chi2,chi2prev,
**evect,*eval,*aprev,*atemp,**tmp1;
int n,i,j,nrot,niter=0,count=0;
long IDUM=-555;
float original_jenkins_a,
original_jenkins_b,
original_jenkins_c;
int *pcheck,pcnt,ptot=10;
original_jenkins_a=JENKINS_A;
original_jenkins_b=JENKINS_B;
original_jenkins_c=JENKINS_C;
pcheck=calloc(ptot,sizeof(int));
if(MCMC>1)
wp.esys=0.08;
wp_input();
Work.imodel=2;
Work.chi2=1;
MCMC=Task.MCMC;
OUTPUT=0;
srand48(32498793);
/* Find the number of free parameters in the minimization
* for the real-space correlation function.
*/
for(n=0,i=1;i<=10;++i)
{
n+=HOD.free[i];
if(OUTPUT)
printf("mcmc_min> free[%i] = %d\n",i,HOD.free[i]);
}
wp.ncf=n;
if(OUTPUT)
printf("mcmc_min> %d free parameters\n",n);
a=dvector(1,n);
aprev=dvector(1,n);
atemp=dvector(1,n);
cov1=dmatrix(1,n,1,n);
avg1=dvector(1,n);
tmp=dmatrix(1,n,1,n);
tmp1=dmatrix(1,n,1,1);
evect=dmatrix(1,n,1,n);
eval=dvector(1,n);
chi2prev=mcmc_initialize(a,cov1,avg1);
niter++;
for(i=1;i<=n;++i)
aprev[i] = a[i];
IDUM=IDUM_MCMC;
pcnt=0;
pcheck[pcnt]=1;
stepfac=1;
while(niter<10)
{
pcnt++;
if(pcnt==ptot)
{
for(j=i=0;i<ptot;++i)j+=pcheck[i];
stepfac = stepfac*pow(0.9,5-j);
printf("STEPFAC %f %d %d\n",stepfac,j,count);
pcnt=0;
}
for(i=1;i<=n;++i)
a[i] = (1+gasdev(&IDUM)*0.004*stepfac)*aprev[i];
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=6;++i)if(HOD.free[i])j++;
i=6;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
}
/* Take the parameters of the Jenkins
* mass function from Gaussian distributions.
*/
/*
RESET_COSMOLOGY++;
if(EJENK)
choose_dndM_fit();
if(EBIAS)
choose_bias_fit();
*/
chi2=chi2_wp_wrapper(a);
if(MCMC>1)chi2+=chi2_zspace(a);
printf("TRY %d ",++count);
for(i=1;i<=n;++i)
printf("%.4e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
pcheck[pcnt]=0;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
continue;
pcheck[pcnt]=1;
niter++;
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
printf("ACCEPT %d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
}
stepfac=1.0;
pcnt=-1;
while(error>tolerance)
{
pcnt++;
if(pcnt==ptot)
{
for(j=i=0;i<ptot;++i)j+=pcheck[i];
stepfac = stepfac*pow(0.9,5-j);
printf("STEPFAC %f %d %d\n",stepfac,j,count);
pcnt=0;
}
stepfac=1;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
tmp[i][j] = cov1[i][j]/niter - avg1[i]*avg1[j]/niter/niter;
jacobi(tmp,n,eval,evect,&nrot);
gaussj(evect,n,tmp1,1);
for(i=1;i<=n;++i)
atemp[i] = gasdev(&IDUM)*sqrt(eval[i])*stepfac;
for(i=1;i<=n;++i)
for(a[i]=0,j=1;j<=n;++j)
a[i] += atemp[j]*evect[j][i];
for(i=1;i<=n;++i)
a[i] += aprev[i];
printf("BOO %d %f %f\n",niter,a[1],a[2]);
fflush(stdout);
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=6;++i)if(HOD.free[i])j++;
i=6;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
}
/* Take the parameters of the Jenkins
* mass function from Gaussian distributions.
*/
RESET_COSMOLOGY++;
if(EJENK)
{
/*
JENKINS_A = original_jenkins_a*(1+gasdev(&IDUM)*sqrt(3.919662e-07));
JENKINS_B = original_jenkins_b*(1+gasdev(&IDUM)*sqrt(9.265636e-06));
JENKINS_C = original_jenkins_c*(1+gasdev(&IDUM)*sqrt(2.365370e-03));
choose_dndM_fit();
*/
}
if(EBIAS)
choose_bias_fit();
chi2=chi2_wp_wrapper(a);
if(MCMC>1)chi2+=chi2_zspace(a);
printf("TRY %d ",++count);
for(i=1;i<=n;++i)
printf("%.4e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
pcheck[pcnt]=0;
if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
continue;
pcheck[pcnt]=1;
niter++;
for(i=1;i<=n;++i)
avg1[i] += a[i];
for(i=1;i<=n;++i)
aprev[i] = a[i];
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
cov1[i][j] += a[i]*a[j];
chi2prev=chi2;
printf("ACCEPT %d %d ",niter,count);
for(i=1;i<=n;++i)
printf("%e ",a[i]);
printf("%e\n",chi2);fflush(stdout);
}
}
double chi2_wp_wrapper(double *a)
{
static int flag=1;
static double *b;
int i,j;
if(flag)
{
b=dvector(1,100);
flag=0;
}
for(j=0,i=1;i<=6;++i)
if(HOD.free[i])
if(a[++j]<=0)return(1.0E7);
i=0;j=0;
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);}
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);}
if(HOD.free[++i]){j++;b[j]=a[j];}
if(HOD.free[++i]){j++;b[j]=pow(10.0,a[j]);}
if(HOD.free[++i]){j++;b[j]=a[j];}
if(HOD.free[++i]){j++;b[j]=a[j];}
return(chi2_wp(b));
}
double mcmc_initialize(double *a, double **cov1, double *avg1)
{
int i,j=0;
double x1,x2;
long IDUM = -556;
i=0;j=0;
if(HOD.free[++i])a[++j]=log10(HOD.M_min);
if(HOD.free[++i])a[++j]=log10(HOD.M1);
if(HOD.free[++i])a[++j]=HOD.alpha;
if(HOD.free[++i])a[++j]=log10(HOD.M_cut);
if(HOD.free[++i])a[++j]=HOD.sigma_logM;
if(HOD.free[++i])a[++j]=CVIR_FAC;
if(MCMC>1)
{
if(HOD.free[++i])a[++j]=OMEGA_M;
if(HOD.free[++i])a[++j]=SIGMA_8;
if(HOD.free[++i])a[++j]=VBIAS;
if(HOD.free[++i])a[++j]=VBIAS_C;
}
printf("INITIAL VALUES: ");
for(i=1;i<=wp.ncf;++i)printf("%e ",a[i]);
printf("\n");
for(i=1;i<=wp.ncf;++i)
{
avg1[i]=a[i];
for(j=1;j<=wp.ncf;++j)
cov1[i][j]=a[i]*a[j];
}
if(MCMC>1)
{
RESET_COSMOLOGY++;
j=0;
for(i=1;i<=6;++i)if(HOD.free[i])j++;
i=6;
if(HOD.free[++i])OMEGA_M = a[++j];
if(HOD.free[++i])SIGMA_8 = a[++j];
if(HOD.free[++i])VBIAS = a[++j];
if(HOD.free[++i])VBIAS_C = a[++j];
}
x1=chi2_wp_wrapper(a);
if(MCMC>1)
x2=chi2_zspace(a);
else
x2=0;
printf("TRY 0 ");
for(i=1;i<=wp.ncf;++i)
printf("%.4e ",a[i]);
printf("%e\n",x1+x2);fflush(stdout);
printf("INITIAL CHI2: %e %e\n",x1,x2);
fflush(stdout);
return(x1+x2);
}
void choose_bias_fit()
{
static long IDUM1=-444;
static int flag=1,n;
static float *a,*b,*c;
FILE *fp;
int i;
char string[1000];
if(flag)
{
flag=0;
fp=openfile("/home/tinker/TABLES/bias_errors.dat");
n=filesize(fp);
a=vector(1,n);
b=vector(1,n);
c=vector(1,n);
for(i=1;i<=n;++i)
{
fscanf(fp,"%f %f %f",&a[i],&b[i],&c[i]);
fgets(string,1000,fp);
}
}
i=(int)(ran1(&IDUM1)*n) + 1;
BIAS_A = a[i];
BIAS_B = b[i];
BIAS_C = c[i];
/*
printf("BIAS %f %f %f\n",a[i],b[i],c[i]);
*/
}
void choose_dndM_fit()
{
static long IDUM1=-444;
static int flag=1,n;
static float *a,*b,*c,*d,*e;
FILE *fp;
int i;
char string[1000];
if(flag)
{
flag=0;
fp=openfile("/home/tinker/TABLES/dndM_errors.dat");
n=filesize(fp);
a=vector(1,n);
b=vector(1,n);
c=vector(1,n);
d=vector(1,n);
e=vector(1,n);
for(i=1;i<=n;++i)
{
fscanf(fp,"%f %f %f %f %f",&a[i],&b[i],&c[i],&d[i],&e[i]);
fgets(string,1000,fp);
}
}
i=(int)(ran1(&IDUM1)*n) + 1;
DNDM_PARAMS[1] = a[i];
DNDM_PARAMS[2] = b[i];
DNDM_PARAMS[3] = c[i];
DNDM_PARAMS[4] = d[i];
DNDM_PARAMS[5] = e[i];
}

91
c_tools/hod/meshlink2.c Normal file
View file

@ -0,0 +1,91 @@
/* PROGRAM MESHLINK2
--- meshlink2(np,nmesh,smin,smax,rmax,x,y,z,meshparts,meshstart)
--- creates a linked list for efficient neighbor searching.
--- tag particles according to their mesh
--- adapted from DHW's linklist.c
--- version2 has all arrays pushed to the end
* np = number of particles
* x,y,z = arrays of particle coordinates.
* smin,smax = particles are located in a box running from
(smin,smin,smin) to (smax,smax,smax).
* rmax = max. radius of a mesh. All neighbors closer than
rmax. are included in a mesh.- to determine size of mesh
* meshparts = on return, pointer to particle link list.
* meshstart = on return, pointer to array of pointers to the
first particle in each mesh.
* nmesh = on return,dimension of mesh array in each dimension.
Notes: 09/09/96
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define sqr(x) ((x)*(x))
#define max(A,B) ((A) > (B) ? (A) : (B))
#define min(A,B) ((A) < (B) ? (A) : (B))
#define mabs(A) ((A) < 0.0 ? -(A) : (A))
#define pi 3.1415926535898
#define ind(a,b,c) (a)*n*n+(b)*n+(c)
#define ALLOC3D(type,dim0,dim1,dim2) \
(type***)a3alloc((unsigned)dim0,(unsigned)dim1,(unsigned)dim2,(unsigned)sizeof(type))
#define NLATMAX 600 /* maximum lattice dimension */
int ***i3tensor_2(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
/*
void meshlink2(np1,nmesh,smin,smax,rmax,x1,y1,z1,meshparts,meshstart,meshfac)
int np1;
float smin,smax,rmax;
float *x1,*y1,*z1;
int **meshparts,****meshstart;
int *nmesh;
int meshfac;
*/
void meshlink2(int np1,int *nmesh,float smin,float smax,float rmax,float *x1,float *y1,float *z1,
int **meshparts,int ****meshstart,int meshfac)
{
int nlatt;
int i,j,k;
int ix,iy,iz;
float sinv;
nlatt=(int)((smax-smin)/rmax);
if (nlatt>NLATMAX) nlatt=NLATMAX ;
/*
*meshstart=ALLOC3D(int,nlatt,nlatt,nlatt);
*/
fprintf(stderr,"nlatt= %d %f %f %f\n",nlatt,smin,smax,rmax);
*meshstart=(int ***)i3tensor_2(0,nlatt-1,0,nlatt-1,0,nlatt-1);
fprintf(stderr,"done here\n");
*meshparts=(int *)calloc(np1,sizeof(int));
fprintf(stderr,"done here\n");
for(i=0;i<np1;i++)(*meshparts)[i]=-1;
for(i=0;i<nlatt;i++)
for(j=0;j<nlatt;j++)
for(k=0;k<nlatt;k++)
(*meshstart)[i][j][k]=-1;
sinv=1./(smax-smin);
for(i=0;i<np1;i++){
ix=(int)(nlatt*(x1[i]-smin)*sinv);
iy=(int)(nlatt*(y1[i]-smin)*sinv);
iz=(int)(nlatt*(z1[i]-smin)*sinv);
if (ix==nlatt) ix=nlatt-1;
if (iy==nlatt) iy=nlatt-1;
if (iz==nlatt) iz=nlatt-1;
(*meshparts)[i]=(*meshstart)[ix][iy][iz];
(*meshstart)[ix][iy][iz]=i;
}
*nmesh=nlatt;
fprintf(stderr,"Done with meshlink. nlatt=%d\n",nlatt);
}

29
c_tools/hod/midinf.c Normal file
View file

@ -0,0 +1,29 @@
#define FUNC(x) ((*funk)(1.0/(x))/((x)*(x)))
double midinf(double (*funk)(double), double aa, double bb, int n)
{
double x,tnm,sum,del,ddel,b,a;
static double s;
int it,j;
b=1.0/aa;
a=1.0/bb;
if (n == 1) {
return (s=(b-a)*FUNC(0.5*(a+b)));
} else {
for(it=1,j=1;j<n-1;j++) it *= 3;
tnm=it;
del=(b-a)/(3.0*tnm);
ddel=del+del;
x=a+0.5*del;
sum=0.0;
for (j=1;j<=it;j++) {
sum += FUNC(x);
x += ddel;
sum += FUNC(x);
x += del;
}
return (s=(s+(b-a)*sum/tnm)/3.0);
}
}
#undef FUNC

28
c_tools/hod/midpnt.c Normal file
View file

@ -0,0 +1,28 @@
#define FUNC(x) ((*func)(x))
double midpnt(double (*func)(double), double a, double b, int n)
{
double x,tnm,sum,del,ddel;
static double s;
int it,j;
if (n == 1) {
return (s=(b-a)*FUNC(0.5*(a+b)));
} else {
for(it=1,j=1;j<n-1;j++) it *= 3;
tnm=it;
del=(b-a)/(3.0*tnm);
ddel=del+del;
x=a+0.5*del;
sum=0.0;
for (j=1;j<=it;j++) {
sum += FUNC(x);
x += ddel;
sum += FUNC(x);
x += del;
}
s=(s+(b-a)*sum/tnm)/3.0;
return s;
}
}
#undef FUNC

64
c_tools/hod/mnbrak.c Normal file
View file

@ -0,0 +1,64 @@
#include <math.h>
#define NRANSI
#include "nrutil.h"
#define GOLD 1.618034
#define GLIMIT 100.0
#define TINY 1.0e-20
#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc,
double (*func)(double))
{
double ulim,u,r,q,fu,dum;
*fa=(*func)(*ax);
*fb=(*func)(*bx);
if (*fb > *fa) {
SHFT(dum,*ax,*bx,dum)
SHFT(dum,*fb,*fa,dum)
}
*cx=(*bx)+GOLD*(*bx-*ax);
*fc=(*func)(*cx);
while (*fb > *fc) {
r=(*bx-*ax)*(*fb-*fc);
q=(*bx-*cx)*(*fb-*fa);
u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/
(2.0*SIGN(FMAX(fabs(q-r),TINY),q-r));
ulim=(*bx)+GLIMIT*(*cx-*bx);
if ((*bx-u)*(u-*cx) > 0.0) {
fu=(*func)(u);
if (fu < *fc) {
*ax=(*bx);
*bx=u;
*fa=(*fb);
*fb=fu;
return;
} else if (fu > *fb) {
*cx=u;
*fc=fu;
return;
}
u=(*cx)+GOLD*(*cx-*bx);
fu=(*func)(u);
} else if ((*cx-u)*(u-ulim) > 0.0) {
fu=(*func)(u);
if (fu < *fc) {
SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx))
SHFT(*fb,*fc,fu,(*func)(u))
}
} else if ((u-ulim)*(ulim-*cx) >= 0.0) {
u=ulim;
fu=(*func)(u);
} else {
u=(*cx)+GOLD*(*cx-*bx);
fu=(*func)(u);
}
SHFT(*ax,*bx,*cx,u)
SHFT(*fa,*fb,*fc,fu)
}
}
#undef GOLD
#undef GLIMIT
#undef TINY
#undef SHFT
#undef NRANSI

39
c_tools/hod/mstar.c Normal file
View file

@ -0,0 +1,39 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "header.h"
/* This function calculates M_star (non-linear mass scale) for the given
* cosmological paramters.
*/
double sigma_Mmdelta_c(double lnM);
double pnorm1;
double mstar()
{
double sig,lnMmin,lnMmax,M_star;
sig=sigmac(8.0);
pnorm1 = SIGMA_8/sig;
lnMmin=log(1e7);
lnMmax=log(1e18);
M_star=zbrent(sigma_Mmdelta_c,lnMmin,lnMmax,1e-5);
M_star=exp(M_star);
if(!ThisTask)
fprintf(stderr,"M_star = %e h^{-1}M_sol\n",M_star);
return(M_star);
}
/*** solve for M_* ***/
double sigma_Mmdelta_c(double lnM)
{
double sig,M,rm;
M=exp(lnM);
rm=pow(3.0*M/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=pnorm1*sigmac(rm);
return sig-DELTA_CRIT;
}

432
c_tools/hod/nbody_xi.c Normal file
View file

@ -0,0 +1,432 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "header.h"
#define NBINLOOKUP 10000
/* Loocal functions.
*/
void nbody_covar(double *rad, double *xi, int nr);
/* External functions.
*/
void nbrsfind2(float smin,float smax,float rmax,int nmesh,float xpos,float ypos,float zpos,
int *nbrmax,int *indx,float *rsqr,float *x,float *y,float *z,
int *meshparts,int ***meshstart,int ip);
void meshlink2(int np1,int *nmesh,float smin,float smax,float rmax,float *x1,float *y1,float *z1,
int **meshparts,int ****meshstart,int meshfac);
void free_i3tensor(int ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
double nbody_xi(double r)
{
static int flag=1,n=30;
static double *x,*y,*y2;
double a;
int i;
if(flag || RESET_FLAG_1H)
{
if(flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=0;
if(OUTPUT)
printf("Calculating nbody xi(r)...\n");
nbody_covar(x,y,n);
if(OUTPUT)
printf("finished\n");
for(i=1;i<=n;++i)
y[i]=log(y[i]);
spline(x,y,n,1.0E+30,1.0E+30,y2);
RESET_FLAG_1H=0;
}
r=log(r);
splint(x,y,y2,n,r,&a);
return(exp(a));
}
void nbody_covar(double *rad, double *xi, int nr)
{
float rmax,rmin,lrstep,binfac,rcube,weight0,fac,rlow,density,weightrandom,vol,r;
int ibin,kbin,nbin,i,j,k,*binlookup,*npair,ngal,ngal_temp;
float *rupp,*rsqr,reduction_factor,*vxt,*vyt,*vzt;
int *meshparts, ***meshstart,nmesh,meshfac,nbrmax,*indx;
double *rbar,galden;
static float *xg,*yg,*zg,*xt,*yt,*zt;
static int flag = 1;
rmin=0.1;
rmax=30.0;
nbin=nr;
rcube=BOX_SIZE;
if(flag) {
galden = GALAXY_DENSITY;
if(HOD.color == 1) galden = wp_color.ngal_blue;
if(HOD.color == 2) galden = wp_color.ngal_red;
ngal = galden*rcube*rcube*rcube*2;
reduction_factor = 1;
if(galden > 0.005)reduction_factor = 0.2;
if(wp_color.ON)reduction_factor = 0.5;
xg = malloc(reduction_factor*ngal*sizeof(float));
yg = malloc(reduction_factor*ngal*sizeof(float));
zg = malloc(reduction_factor*ngal*sizeof(float));
xt = malloc(ngal*sizeof(float));
yt = malloc(ngal*sizeof(float));
zt = malloc(ngal*sizeof(float));
flag = 1;
}
printf("Starting population...\n");
ngal = internal_populate_simulation(xt,yt,zt,1.0,0,vxt,vyt,vzt);
printf("Done. [%d] galaxies [%.0f]\n",ngal,galden*rcube*rcube*rcube);
fflush(stdout);
ngal_temp=0;
for(i=0;i<ngal;++i)
{
if(drand48()>reduction_factor)continue;
xg[ngal_temp] = xt[i];
yg[ngal_temp] = yt[i];
zg[ngal_temp] = zt[i];
ngal_temp++;
}
ngal = ngal_temp;
indx=malloc(ngal*sizeof(int));
rsqr=malloc(ngal*sizeof(float));
/***********************
* initializing the logarithmic bins
*/
rupp = (float *) calloc(nbin+1,sizeof(float)) ;
lrstep=log(rmax/rmin)/(float)(nbin-1) ;
binlookup=(int *)calloc(NBINLOOKUP+2,sizeof(int)) ;
ibin=0 ;
for (i=0;i<=NBINLOOKUP;i++) {
r=rmax*i/NBINLOOKUP ;
if (r>0) {
kbin=(int)floor(log(r/rmin)/lrstep+1.0) ;
}
else {
kbin=0 ;
}
if (kbin<0) kbin=0 ;
if (kbin>ibin) {
rupp[ibin]=r ;
ibin=kbin ;
}
binlookup[i]=kbin ;
}
binlookup[NBINLOOKUP+1]=nbin ;
rupp[nbin-1]=rmax ;
rupp[nbin]=rmax ;
binfac=NBINLOOKUP/rmax ;
rbar=calloc(nbin,sizeof(double));
npair=calloc(nbin,sizeof(int));
nmesh=0;
meshlink2(ngal,&nmesh,0.0,rcube,rmax,xg,yg,zg,&meshparts,&meshstart,meshfac);
for(i=0;i<ngal;++i)
{
nbrmax=ngal;
nbrsfind2(0.0,rcube,rmax,nmesh,xg[i],yg[i],zg[i],&nbrmax,indx,rsqr,xg,yg,zg,
meshparts,meshstart,i);
for(j=0;j<nbrmax;++j)
{
r=sqrt(rsqr[j]) ;
kbin=binlookup[(int)(binfac*r)] ;
if(kbin>=nbin)continue;
npair[kbin]++;
rbar[kbin]+=r;
}
}
density=ngal/(rcube*rcube*rcube) ;
rlow=0;
for (kbin=0;kbin<nbin;kbin++) {
weight0=(float) npair[kbin];
if (weight0>0.0) {
fac=1./weight0 ;
rbar[kbin] *= fac ;
}
else { /* avoid errors in empty bins */
rbar[kbin]=(rupp[kbin]+rlow)*0.5;
}
/* compute xi, dividing summed weight by that expected for a random set */
vol=4.*PI/3.*(rupp[kbin]*rupp[kbin]*rupp[kbin]-rlow*rlow*rlow) ;
weightrandom=ngal*density*vol ;
rad[kbin+1]=log(rbar[kbin]);
xi[kbin+1]=weight0/weightrandom-1 ;
rlow=rupp[kbin] ;
if(OUTPUT>1)
{
fprintf(stdout,"nbody_xi> %f %f %.0f\n",rbar[kbin],xi[kbin+1],weight0);
fflush(stdout);
}
}
free(indx);
free(rsqr);
free(rupp);
free(binlookup);
free(npair);
free(rbar);
free_i3tensor(meshstart,0,nmesh-1,0,nmesh-1,0,nmesh-1);
}
int internal_populate_simulation(float *x, float *y, float *z, float reduction_factor, int ivel,
float *vx, float *vy, float *vz)
{
FILE *fp,*fpa[9],*fp2,*fpb[9],*fpc[9],*fps[9];
int i,j,k,n,imass,n1,j_start=0,i1,galcnt[1000],halocnt[1000],imag;
double mass,xg[3],vg[3],nsat,nc[10],ncen,mlo,mag,err1,err2,r,high_density_f0,low_density_f0;
char aa[1000],fname[100];
float x1,xh[3],vh[3],vgf[3];
long IDUM = -445, IDUM3 = -445;
float **galarr;
int *galid,id1=0,id2=0,j1,ii,*indx;
float dx,dy,dz,dr,drh,rv1,rv2,rmin,rmax,temp1,temp2,fac,sigma;
float **haloarr,**temp_pos,*temp_den,**temp_vel;
int ngal,nsati[9],ALL_FILES=0,TRACK_GALAXIES=0;
static int
flag = 1,
nhalo,
SO_FILE = 0;
FILE *fp3;
static float
**halo_pos,
**halo_vel,
*hdensity,
*halo_mass;
if(flag){
fp = openfile(Files.HaloFile);
nhalo = filesize(fp);
if(DENSITY_DEPENDENCE)
{
fp2 = openfile(Files.HaloDensityFile);
if(nhalo != filesize(fp2))
{
fprintf(stderr,"ERROR: filesize mismatch with [%s] and [%s]\n",
Files.HaloFile, Files.HaloDensityFile);
exit(0);
}
}
halo_pos = matrix(1,nhalo,0,2);
halo_mass = vector(1,nhalo);
temp_pos = matrix(1,nhalo,0,2);
halo_vel = matrix(1,nhalo,0,2);
temp_vel = matrix(1,nhalo,0,2);
indx = ivector(1,nhalo);
fprintf(stderr,"HERE %d halos\n",nhalo);
if(DENSITY_DEPENDENCE)
{
temp_den = vector(1,nhalo);
hdensity = vector(1,nhalo);
}
for(i=1;i<=nhalo;++i)
{
if(DENSITY_DEPENDENCE)
fscanf(fp2,"%f",&temp_den[i]);
if(SO_FILE)
{
fscanf(fp,"%d %lf %f %f %f %f %f %f %f %f",
&j,&mass,&x1,&x1,&xh[0],&xh[1],&xh[2],&vh[0],&vh[1],&vh[2]);
halo_mass[i] = -mass;
}
else
{
fscanf(fp,"%d %d %e %e %e %e %e %e %e",
&j,&imass,&xh[0],&xh[1],&xh[2],&x1,&vh[0],&vh[1],&vh[2]);
mass=imass*RHO_CRIT*OMEGA_M*pow(RESOLUTION,3.0);
halo_mass[i]= - imass*RHO_CRIT*OMEGA_M*pow(RESOLUTION,3.0);
}
for(j=0;j<3;++j) {
temp_pos[i][j] = xh[j];
temp_vel[i][j] = vh[j]; }
indx[i] = i;
}
sort2(nhalo,halo_mass,indx);
for(i=1;i<=nhalo;++i)
{
halo_mass[i] *= -1;
for(j=0;j<3;++j) {
halo_pos[i][j] = temp_pos[indx[i]][j];
halo_vel[i][j] = temp_vel[indx[i]][j]; }
if(DENSITY_DEPENDENCE)
hdensity[i] = temp_den[indx[i]];
}
free_matrix(temp_pos,1,nhalo,0,2);
free_matrix(temp_vel,1,nhalo,0,2);
free_ivector(indx,1,nhalo);
flag = 0;
fclose(fp);
if(DENSITY_DEPENDENCE)
fclose(fp2);
}
if(wp_color.ON)
{
temp1 = HOD.M_min;
temp2 = HOD.M_low;
}
HOD.M_min = 0;
set_HOD_params();
if(DENSITY_DEPENDENCE)
dd_hod_functions(halo_mass,hdensity,nhalo);
if(wp_color.ON)
{
HOD.M_min = temp1;
HOD.M_low = temp2;
fprintf(stderr,"true M_min = %e\n",HOD.M_min);
}
HOD.M_low = set_low_mass();
mlo = HOD.M_low;
if(HOD.M_min_fac<0)
mlo *= HOD.M_min_fac;
high_density_f0 = HOD.fblue0_cen;
low_density_f0 = (1 - HOD.M_min_fac*(1-HOD.fblue0_cen));
fac=sqrt(4.499E-48)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19;
fprintf(stderr,"%e %e %e\n",HOD.M_min,HOD.M_low,halo_mass[1]);
sprintf(fname,"%s.mock_halo",Task.root_filename);
fp2 = fopen(fname,"w");
for(ii=1;ii<=nhalo;++ii)
{
// printf("%d\n",ii);
//fflush(stdout);
mass=halo_mass[ii];
if(mass<mlo)break;
if(ran2(&IDUM)>reduction_factor)continue;
for(i=0;i<3;++i)
{
xh[i] = halo_pos[ii][i];
if(xh[i]<0)xh[i]+=BOX_SIZE;
if(xh[i]>BOX_SIZE)xh[i]-=BOX_SIZE;
if(ivel)
vh[i] = halo_vel[ii][i];
}
nsat = N_sat(mass);
if(nsat>250)
n1 = gasdev(&IDUM3)*sqrt(nsat) + nsat;
else
n1 = poisson_deviate(nsat);
for(i=1;i<=n1;++i)
{
r = NFW_position(mass,xg);
for(k=0;k<3;++k)
{
xg[k]+=xh[k];
if(xg[k]<0)xg[k]+=BOX_SIZE;
if(xg[k]>BOX_SIZE)xg[k]-=BOX_SIZE;
}
if(ivel) {
NFW_velocity(mass,vg,mag);
vx[id2] = vg[0]+vh[0];
vy[id2] = vg[1]+vh[1];
vz[id2] = vg[2]+vh[2];
}
x[id2] = xg[0];
y[id2] = xg[1];
z[id2] = xg[2];
id2++;
fprintf(fp2,"%d\n",ii);
}
if(DENSITY_DEPENDENCE && !wp_color.ON)
{
// printf("%e %e\n",mass,hdensity[ii]);
HOD.M_min=HOD.M_min_hiden;
if(hdensity[ii]<DENSITY_THRESHOLD)
HOD.M_min=HOD.M_min*HOD.M_min_fac;
}
if(DENSITY_DEPENDENCE && wp_color.ON && HOD.color == 2)
{
if(hdensity[ii]<DENSITY_THRESHOLD)
HOD.fblue0_cen = low_density_f0;
else
HOD.fblue0_cen = high_density_f0;
}
if(DENSITY_DEPENDENCE && wp_color.ON && HOD.color == 1)
{
if(hdensity[ii]<DENSITY_THRESHOLD)
HOD.fblue0_cen = low_density_f0;
else
HOD.fblue0_cen = high_density_f0;
}
ncen=N_cen(mass);
if(ran2(&IDUM)>ncen)continue;
sigma=fac*pow(mass,1.0/3.0)/sqrt(2.0);
x[id2] = xh[0];
y[id2] = xh[1];
z[id2] = xh[2];
if(ivel) {
vx[id2] = vh[0] + gasdev(&IDUM)*VBIAS_C*sigma;
vy[id2] = vh[1] + gasdev(&IDUM)*VBIAS_C*sigma;
vz[id2] = vh[2] + gasdev(&IDUM)*VBIAS_C*sigma;
}
id2++;
fprintf(fp2,"%d\n",ii);
}
fclose(fp2);
muh(999);
// ivel = 1;
if(ivel) {
sprintf(aa,"%s.mock",Task.root_filename);
fp = fopen(aa,"w");
for(i=0;i<id2;++i)
fprintf(fp,"%e %e %e %e %e %e\n",x[i],y[i],z[i],vx[i],vy[i],vz[i]);
// fprintf(fp,"%e %e %e\n",x[i],y[i],z[i]);
fclose(fp);
}
return id2;
}

139
c_tools/hod/nbrsfind2.c Normal file
View file

@ -0,0 +1,139 @@
/* PROGRAM NBRSFIND2
--- nbrsfind2(smin,smax,rmax,nmesh,xpos,ypos,zpos,nbrmax,indx,rsqr,x,y,z,meshparts,meshstart)
--- nbrsfind2(x,y,z,smin,smax,rmax,meshparts,meshstart,nmesh,xpos,ypos,zpos,indx,rsqr,nbrmax)
--- find all neighbours of a particle within a radius rmax.
--- adapted from DHW's rfind.c
--- version2 has all arrays pushed to the end
* x,y,z = arrays of particle coordinates.
* smin,smax = particles are located in a box running from
(smin,smin,smin) to (smax,smax,smax).
* rmax = max. radius within which to search for neighbors.
* meshparts = particle link list produced by `meshlink'
* meshstart = lattice pointer array produced by `meshlink'
* nmesh = dimension of mesh array in each dimension.
* xpos,ypos,zpos = coordinates defining center of search.
* indx = on return, contains list of particles within rmax of
center. allocate as (int *)calloc(nbrmax,sizeof(int))
* rmax = on return, rsqr[i] is the squared distance of particle
indx[i]. allocate as (float *)calloc(nbrmax,sizeof(float)).
* nbrmax = on input: dimension of indx[] and rsqr[],
for error checking on return: number of particles within rmax
Notes: 09/10/96 - assumes periodic boundary condition.
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define sqr(x) ((x)*(x))
#define max(A,B) ((A) > (B) ? (A) : (B))
#define min(A,B) ((A) < (B) ? (A) : (B))
#define mabs(A) ((A) < 0.0 ? -(A) : (A))
#define pi 3.1415926535898
/*
void nbrsfind2(smin,smax,rmax,nmesh,xpos,ypos,zpos,nbrmax,indx,rsqr,x,y,z,meshparts,meshstart)
float smin,smax,rmax;
float *x,*y,*z;
int *meshparts,***meshstart;
int nmesh;
float xpos,ypos,zpos;
int *indx;
float *rsqr;
int *nbrmax;
*/
void nbrsfind2(float smin,float smax,float rmax,int nmesh,float xpos,float ypos,float zpos,
int *nbrmax,int *indx,float *rsqr,float *x,float *y,float *z,
int *meshparts,int ***meshstart,int ip)
{
int i,j,k,ir;
int ix,iy,iz,
iix,iiy,iiz,
iiix,iiiy,iiiz,
nbr,p;
float rmax2,r2,side,side2,sinv,dx,dy,dz;
side=(smax-smin);
side2=side/2.;
sinv=1./side;
/* printf("nbrsfind2> %f %f %f %f %f %f %d %d\n",smin,smax,rmax,xpos,ypos,zpos,nmesh,*nbrmax);
*/
/* ix=(int)(nmesh*(xpos-smin)*sinv);
iy=(int)(nmesh*(ypos-smin)*sinv);
iz=(int)(nmesh*(zpos-smin)*sinv);
if (ix>=nmesh||iy>=nmesh||iz>=nmesh ||ix<0||iy<0||iz<0){
fprintf(stderr,"nbrsfind2> error in position or lattice parameters\n");
fprintf(stderr,"nbrsfind2> nmesh, ix, iy, iz = %d %d %d %d\n",nmesh,ix,iy,iz) ;
exit(-1) ;
}
*/
ix=(int)(nmesh*(xpos-smin)*sinv);
if(ix>=nmesh)
{
fprintf(stderr,"meshlink> Warning: Particle at x = %f ix = %d\n",xpos,ix);
ix=ix-1;
}
iy=(int)(nmesh*(ypos-smin)*sinv);
if(iy>=nmesh)
{
fprintf(stderr,"meshlink> Warning: Particle at y = %f iy = %d\n",ypos,iy);
iy=iy-1;
}
iz=(int)(nmesh*(zpos-smin)*sinv);
if(iz>=nmesh)
{
fprintf(stderr,"meshlink> Warning: Particle at z = %f iz = %d\n",zpos,iz);
iz=iz-1;
}
rmax2=rmax*rmax;
nbr=0;
ir=(int)(nmesh*rmax*sinv)+1;
for(iix=-ir;iix<=ir;iix++)
for(iiy=-ir;iiy<=ir;iiy++)
for(iiz=-ir;iiz<=ir;iiz++){
iiix=(ix+iix+nmesh)%nmesh ;
iiiy=(iy+iiy+nmesh)%nmesh ;
iiiz=(iz+iiz+nmesh)%nmesh ;
p=meshstart[iiix][iiiy][iiiz] ;
while(p>=0){
dx=mabs(xpos-x[p]) ;
dy=mabs(ypos-y[p]) ;
dz=mabs(zpos-z[p]) ;
if (dx>side2) dx=side-dx ;
if (dy>side2) dy=side-dy ;
if (dz>side2) dz=side-dz ;
r2=dx*dx+dy*dy+dz*dz ;
if(r2<=rmax2) {
indx[nbr]=p;
rsqr[nbr]=r2;
nbr++;
}
if(nbr>*nbrmax){
fprintf(stderr,"nbrsfind2>too many particles in indx list\n");
fprintf(stderr,"nbrsfind2>reset nbrmax and try again\n");
fprintf(stderr,"nbr = %d\n",nbr);
exit(-1) ;
}
p=meshparts[p];
}
}
*nbrmax=nbr;
}

View file

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "header.h"
void cisi(double x, double *ci, double *si);
/* The Fourier transform of the NFW profile.
* Inputs are wavenumber and halo mass.
* NB! -> Function assumes that profile of satellite GALAXIES is
* desired, therefore uses CVIR_FAC
*/
double nfw_transform(double xk, double m)
{
double c,rvir,kappa1,kappa2,f,y,ci1,ci2,si1,si2;
c=halo_concentration(m)*CVIR_FAC;
rvir=pow(3.0*m/(4.0*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
kappa1=xk*rvir/c;
kappa2=kappa1*(1.0+c);
f=log(1.0+c)-c/(1.0+c);
f=1.0/f;
cisi(kappa1,&ci1,&si1);
cisi(kappa2,&ci2,&si2);
y=-sin(kappa1*c)/kappa2;
y=y+sin(kappa1)*(si2-si1)+cos(kappa1)*(ci2-ci1);
y=f*y;
return(y);
}

View file

@ -0,0 +1,204 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This is my implementation of the Halo Model fitting function
* described in Appendix C of Smith, Peacock, et al. 2003 MNRAS 341, 1311
*
* Comparison to Smith et al. program halofit.f output is successful.
*/
/* Internal functions
*/
double func_nl(double r);
void tabulate_pk_nl(double *kk, double *pknl, int nk);
/* This returns the linear power
* Delta = 4pi*k^3 P(k)/(2pi)^3
*/
double linear_power_spectrum(double xk)
{
static double *kk,*pknl,*y2,pnorm=-1,ahi,bhi;
static int flag=1,nk=1000,prev_cosmology=0;
double a,psp,x1[4],y1[4];
int i;
if(pnorm<0 || prev_cosmology!=RESET_COSMOLOGY)
{
pnorm=SIGMA_8/sigmac(8.0);
pnorm*=pnorm;
prev_cosmology=RESET_COSMOLOGY;
}
if(ITRANS>0)
psp=pow(xk,SPECTRAL_INDX)*pow(transfnc(xk),2.);
else
psp=pow(xk,SPECTRAL_INDX);
psp=psp*pnorm*xk*xk*xk/(2*PI*PI);
return(psp);
}
double nonlinear_power_spectrum(double xk)
{
static double *kk,*pknl,*y2,pnorm=-1,ahi,bhi;
static int flag=1,nk=1000,prev_cosmology=0;
double a,psp,x1[4],y1[4],xklog;
int i;
if(flag || RESET_COSMOLOGY!=prev_cosmology)
{
prev_cosmology=RESET_COSMOLOGY;
pnorm=SIGMA_8/sigmac(8.0);
flag=0;
kk=dvector(1,nk);
pknl=dvector(1,nk);
y2=dvector(1,nk);
tabulate_pk_nl(kk,pknl,nk);
spline(kk,pknl,nk,1.0E+30,1.0E+30,y2);
/* This takes the last four points in the power spectrum at high k
* and fits a power law to them for extrapolation.
*/
for(i=0;i<4;++i)
{
x1[i]=(kk[nk-3+i]);
y1[i]=(pknl[nk-3+i]);
}
least_squares(x1,y1,4,&ahi,&bhi);
}
xklog=log(xk);
/* If xk is less than the smallest k value tabulates, return linear power.
*/
if(xklog<kk[1])
return(linear_power_spectrum(xk));
/* If xk larger than highest k, return extrapolation.
*/
if(xklog>kk[nk])
return((exp((ahi+bhi*xklog))));
splint(kk,pknl,y2,nk,xklog,&a);
return(exp(a));
}
void tabulate_pk_nl(double *kk, double *pknl, int nk)
{
double r_nl,pnorm,DeltaQ,DeltaLin,DeltaH,psp,neff,s1,s2,n1,n2,ncurve,
lnk_lo,lnk_hi,dlnk,xk1,y,xk,fy;
double an,bn,cn,f1b,f2b,f3b,alpha,beta,gamma,nu,mu;
int i,j,n=10000;
/* First normalize the linear power spectrum.
*/
pnorm=SIGMA_8/sigmac(8.0);
/* Calculate the non-linear scale.
*/
r_nl = exp(zbrent(func_nl,log(0.01),log(10.0),1.0E-4));
if(OUTPUT)
fprintf(stdout,"R_NL= %f\n",r_nl);
/* Calculate the effective spectral index at the non-linear scale.
*/
s1=pnorm*sigmac(-r_nl*0.999);
s2=pnorm*sigmac(-r_nl*1.001);
neff=-(3+2*(s2-s1)/0.002);
if(OUTPUT)
fprintf(stderr,"neff= %f\n",neff);
/* Spectral curvature.
*/
lnk_hi=10.0;
lnk_lo=-10.0;
dlnk=(lnk_hi-lnk_lo)/n;
s1=0;
for(i=1;i<=n;++i)
{
xk1=exp(lnk_lo+(i-0.5)*dlnk);
y=xk1*r_nl;
DeltaLin=linear_power_spectrum(xk1);
s1+=DeltaLin*y*y*(1-y*y)*exp(-y*y)*dlnk;
}
ncurve=(3+neff)*(3+neff)+4*s1;
if(OUTPUT)
fprintf(stderr,"ncurve= %f\n",ncurve);
/* Coefficients of the model.
*/
an=pow(10.0,1.4861 + 1.8369*neff + 1.6762*neff*neff + 0.7940*neff*neff*neff +
0.1670*pow(neff,4.0) - 0.6202*ncurve);
bn=pow(10.0,0.9463 + 0.9466*neff + 0.3084*neff*neff - 0.9400*ncurve);
cn= pow(10.0,-0.2807 + 0.6669*neff + 0.3214*neff*neff - 0.0793*ncurve);
gamma = 0.8649 + 0.2989*neff + 0.1631*ncurve;
alpha = 1.3884 + 0.3700*neff - 0.1452*neff*neff;
beta = 0.8291 + 0.9854*neff + 0.3401*neff*neff;
mu = pow(10.0,-3.5442 + 0.1908*neff);
nu = pow(10.0, 0.9589 + 1.2857*neff);
/* Testing the parameter dependence.
* TESTING TESTING
*/
/*
alpha *= 0.3;
beta *= 0.3;
*/
/* Omega-dependent functions (FLAT LAMBDA COSMOLOGY)
*/
f1b = pow(OMEGA_M,-0.0307);
f2b = pow(OMEGA_M,-0.0585);
f3b = pow(OMEGA_M,+0.0743);
/* Tabulate the power spectrum
*/
lnk_lo=log(0.001);
lnk_hi=log(1000.0);
dlnk=(lnk_hi-lnk_lo)/(nk-1);
for(i=1;i<=nk;++i)
{
xk=exp(lnk_lo+(i-1)*dlnk);
y=xk*r_nl;
fy=y/4.0 + y*y/8.0;
/* TEST */
/* fy*=1.2; */
DeltaLin=linear_power_spectrum(xk);
DeltaQ = DeltaLin*pow(1+DeltaLin,beta)/(1+alpha*DeltaLin)*exp(-fy);
DeltaH = an*pow(y,3*f1b)/(1+bn*pow(y,f2b)+pow(cn*f3b*y,3-gamma));
DeltaH*= 1.0/(1+mu/y+nu/(y*y));
kk[i]=log(xk);
pknl[i]=log(DeltaQ + DeltaH);
}
}
/* This is a function to find the non-linear scale. Similar to M_star,
* but here we're using a Guassian smoothing window rather than top hat.
* (And we're finding the scale at which the variance = 1, not 1.686).
*/
double func_nl(double r)
{
static int prev_cosmology=0;
double sig;
static double pnorm=-1;
if(pnorm<0 || RESET_COSMOLOGY!=prev_cosmology)
pnorm=SIGMA_8/sigmac(8.0);
prev_cosmology=RESET_COSMOLOGY;
r=exp(r);
sig=pnorm*sigmac(-r);
return sig-1.0;
}

293
c_tools/hod/nrutil.c Normal file
View file

@ -0,0 +1,293 @@
/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
utility file nrutil.c. Do not confuse this file with the same-named
file nrutil.c that is supplied in the 'misc' subdirectory.
*That* file is the one from the book, and contains both ANSI and
traditional K&R versions, along with #ifdef macros to select the
correct version. *This* file contains only ANSI C. */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#define NR_END 1
#define FREE_ARG char*
void nrerror(char error_text[])
/* Numerical Recipes standard error handler */
{
fprintf(stderr,"Numerical Recipes run-time error...\n");
fprintf(stderr,"%s\n",error_text);
fprintf(stderr,"...now exiting to system...\n");
exit(1);
}
float *vector(long nl, long nh)
/* allocate a float vector with subscript range v[nl..nh] */
{
float *v;
v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
if (!v) nrerror("allocation failure in vector()");
return v-nl+NR_END;
}
int *ivector(long nl, long nh)
/* allocate an int vector with subscript range v[nl..nh] */
{
int *v;
v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
if (!v) nrerror("allocation failure in ivector()");
return v-nl+NR_END;
}
unsigned char *cvector(long nl, long nh)
/* allocate an unsigned char vector with subscript range v[nl..nh] */
{
unsigned char *v;
v=(unsigned char *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(unsigned char)));
if (!v) nrerror("allocation failure in cvector()");
return v-nl+NR_END;
}
unsigned long *lvector(long nl, long nh)
/* allocate an unsigned long vector with subscript range v[nl..nh] */
{
unsigned long *v;
v=(unsigned long *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(long)));
if (!v) nrerror("allocation failure in lvector()");
return v-nl+NR_END;
}
double *dvector(long nl, long nh)
/* allocate a double vector with subscript range v[nl..nh] */
{
double *v;
v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double)));
if (!v) nrerror("allocation failure in dvector()");
return v-nl+NR_END;
}
float **matrix(long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
double **dmatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
double **m;
/* allocate pointers to rows */
m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
int **imatrix(long nrl, long nrh, long ncl, long nch)
/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */
{
long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
int **m;
/* allocate pointers to rows */
m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*)));
if (!m) nrerror("allocation failure 1 in matrix()");
m += NR_END;
m -= nrl;
/* allocate rows and set pointers to them */
m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int)));
if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
m[nrl] += NR_END;
m[nrl] -= ncl;
for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
long newrl, long newcl)
/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */
{
long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl;
float **m;
/* allocate array of pointers to rows */
m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in submatrix()");
m += NR_END;
m -= newrl;
/* set pointers to rows */
for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix
declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1
and ncol=nch-ncl+1. The routine should be called with the address
&a[0][0] as the first argument. */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*)));
if (!m) nrerror("allocation failure in convert_matrix()");
m += NR_END;
m -= nrl;
/* set pointers to rows */
m[nrl]=a-ncl;
for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol;
/* return pointer to array of pointers to rows */
return m;
}
float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
float ***t;
/* allocate pointers to pointers to rows */
t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(float *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
void free_vector(float *v, long nl, long nh)
/* free a float vector allocated with vector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_ivector(int *v, long nl, long nh)
/* free an int vector allocated with ivector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_cvector(unsigned char *v, long nl, long nh)
/* free an unsigned char vector allocated with cvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_lvector(unsigned long *v, long nl, long nh)
/* free an unsigned long vector allocated with lvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_dvector(double *v, long nl, long nh)
/* free a double vector allocated with dvector() */
{
free((FREE_ARG) (v+nl-NR_END));
}
void free_matrix(float **m, long nrl, long nrh, long ncl, long nch)
/* free a float matrix allocated by matrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch)
/* free a double matrix allocated by dmatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch)
/* free an int matrix allocated by imatrix() */
{
free((FREE_ARG) (m[nrl]+ncl-NR_END));
free((FREE_ARG) (m+nrl-NR_END));
}
void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch)
/* free a submatrix allocated by submatrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch)
/* free a matrix allocated by convert_matrix() */
{
free((FREE_ARG) (b+nrl-NR_END));
}
void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh)
/* free a float f3tensor allocated by f3tensor() */
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}

77
c_tools/hod/nrutil.h Normal file
View file

@ -0,0 +1,77 @@
/* CAUTION: This is the ANSI C (only) version of the Numerical Recipes
utility file nrutil.h. Do not confuse this file with the same-named
file nrutil.h that is supplied in the 'misc' subdirectory.
*That* file is the one from the book, and contains both ANSI and
traditional K&R versions, along with #ifdef macros to select the
correct version. *This* file contains only ANSI C. */
#ifndef _NR_UTILS_H_
#define _NR_UTILS_H_
static float sqrarg;
#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
static double dsqrarg;
#define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg)
static double dmaxarg1,dmaxarg2;
#define DMAX(a,b) (dmaxarg1=(a),dmaxarg2=(b),(dmaxarg1) > (dmaxarg2) ?\
(dmaxarg1) : (dmaxarg2))
static double dminarg1,dminarg2;
#define DMIN(a,b) (dminarg1=(a),dminarg2=(b),(dminarg1) < (dminarg2) ?\
(dminarg1) : (dminarg2))
static float maxarg1,maxarg2;
#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
(maxarg1) : (maxarg2))
static float minarg1,minarg2;
#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\
(minarg1) : (minarg2))
static long lmaxarg1,lmaxarg2;
#define LMAX(a,b) (lmaxarg1=(a),lmaxarg2=(b),(lmaxarg1) > (lmaxarg2) ?\
(lmaxarg1) : (lmaxarg2))
static long lminarg1,lminarg2;
#define LMIN(a,b) (lminarg1=(a),lminarg2=(b),(lminarg1) < (lminarg2) ?\
(lminarg1) : (lminarg2))
static int imaxarg1,imaxarg2;
#define IMAX(a,b) (imaxarg1=(a),imaxarg2=(b),(imaxarg1) > (imaxarg2) ?\
(imaxarg1) : (imaxarg2))
static int iminarg1,iminarg2;
#define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ?\
(iminarg1) : (iminarg2))
#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
void nrerror(char error_text[]);
float *vector(long nl, long nh);
int *ivector(long nl, long nh);
unsigned char *cvector(long nl, long nh);
unsigned long *lvector(long nl, long nh);
double *dvector(long nl, long nh);
float **matrix(long nrl, long nrh, long ncl, long nch);
double **dmatrix(long nrl, long nrh, long ncl, long nch);
int **imatrix(long nrl, long nrh, long ncl, long nch);
float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch,
long newrl, long newcl);
float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch);
float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
void free_vector(float *v, long nl, long nh);
void free_ivector(int *v, long nl, long nh);
void free_cvector(unsigned char *v, long nl, long nh);
void free_lvector(unsigned long *v, long nl, long nh);
void free_dvector(double *v, long nl, long nh);
void free_matrix(float **m, long nrl, long nrh, long ncl, long nch);
void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch);
void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch);
void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch);
void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
#endif /* _NR_UTILS_H_ */

376
c_tools/hod/old.c Normal file
View file

@ -0,0 +1,376 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "header.h"
double delta_pdf(double delta, double r);
void vdelta_v4(double m0, double m1, double rad, double theta, double binsize,
double v0, int nv, double *a, double *pv, double *pt, double *pz,
double wgal[3], double sgal[4])
{
static double pnorm=-1,flag=0;
static double *rho,*mu,*pdelta;
static int prev_cosmo=0;
int i,j,k,nrho=75,halo_pair_only=0,use_file_coeff=0;
double dlogrho,sintheta,costheta,tan2theta,rho_min,rho_max,w,b0,
collapse_factor,rho200,ptot,v,sigv,rho0,x1,x2,x3,rvir0,rho200t,sigvt,alpha,alphat,
rvir1,rvirmax,rvir2,vfac,sr1,sr2,sr3,sr4,st1,st2,st3,st4,sz1,sz2,sz3,sz4,
gnorm1,gnorm2,gnorm3,gnorm4,vv,pmax,rcrit,sig20,sig10,sig5;
int direction,iend;
double sigz1[76],sigz2[76],sigz3[76],sigz4[76],
g1[76],g2[76],g3[76],g4[76],minp,xfit[3],yfit[3],afit,bfit;
double t0,t1,tt1,tt2;
int ii=0;
double vfac0 = 0.97; /* factor om rho200[t,r]. was 0.97 */
for(i=1;i<=nv;++i)
/* pt[i]=pv[i]=*/ pz[i]=0;
rvir0=(pow(3*m0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0) +
pow(3*m1/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0));
rvir1=pow(3*m1/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rvir2=pow(3*m0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
b0=(bias_interp(m0,-1)+bias_interp(m1,-1));
/* 0.5 comes from ellipsoidal halo exclusion.
*/
if(rad<rvir0*0.5)return;
/*if(rad<rvir0)rad=rvir0;*/
rho_min=0.01;
alpha=alphat=pow(rad/35,0.1);
rcrit=4*rvir1;
rcrit=0;
if(rad<=rcrit)
{
x1=rcrit;
x2=pow(x1/35,0.1);
x3=x1*pow(x2,-1.0/(+0.3));
alpha=alphat=pow(rad/x3,+0.3);
}
rcrit=4*rvir1;
rho200 = pow(rad/5.0/sqrt(rvir1),-4.0) + pow(rad/11.5/sqrt(rvir0),-1.3) + 0.5;
rho200t = pow(rad/7.2/sqrt(rvir1),-2.5) + pow(rad/12.6/sqrt(rvir0),-0.8) + 0.48;
rho0 = 1.41*b0 + pow(rad/9.4/rvir1,-2.2);
/* TEMP TEMP TEMP
*/
/* rho0 = 1.38*b0 + pow(rad/9.4/rvir1,-2.2); */
vfac0 = 1.01;
/* If using the bias parameters that fit Warren's sims, use:
*/
rho0 = 1.43*b0 + pow(rad/9.4/rvir1,-2.2);
vfac0 = 0.95;
/* If using the bias parameters for the linear P(k), use:
*/
if(LINEAR_PSP)
rho0 = 1.28*b0 + pow(rad/9.4/rvir1,-2.2);
sintheta=sin(theta);
costheta=cos(theta);
tan2theta=sintheta*sintheta/(costheta*costheta);
if(!flag)
{
flag=1;
mu=dvector(1,nrho);
rho=dvector(1,nrho);
pdelta=dvector(1,nrho);
}
/* Determine the proper limits of the integral over rho
*/
dlogrho=log(1.0E+3/0.01)/(50-1);
pmax=0;
i=0;
for(i=1;i<=50;++i)
{
rho[i]=rho_min*exp((i-1)*dlogrho);
pdelta[i]=exp(-rho0/rho[i])*delta_pdf(rho[i]-1,rad)*rho[i];
if(pdelta[i]>pmax){ pmax=pdelta[i]; j=i; }
}
pmax*=1.0E-4;
for(i=1;i<j;++i)
if(pdelta[i]>=pmax)break;
rho_min=rho[i];
for(i=j+1;i<50;++i)
if(pdelta[i]<=pmax)break;
rho_max=rho[i];
/* Tabulate the spherical collapse model, density, and p(delta).
*/
dlogrho=log(rho_max/rho_min)/(nrho-1);
ptot=0;
for(i=1;i<=nrho;++i)
{
rho[i]=rho_min*exp((i-1)*dlogrho);
pdelta[i]=exp(-rho0/rho[i])*delta_pdf(rho[i]-1,rad)*rho[i];
ptot+=pdelta[i]*dlogrho;
if(pdelta[i]>pdelta[j])j=i;
x1=-(100*rad)*pow(OMEGA_M,0.6)*(rho[i]-1)/3;
/* If underdense region, use linear theory.
*/
if(rho[i]<=1)
{
mu[i]=x1;
continue;
}
x2=(rad)*spherical_collapse_model(rho[i]-1)*exp(-(4.5/rad/rho[i])*(4.5/rad/rho[i]));
if(x2>0)x2=0;
/* If small separation, use spherical collapse model only.
*/
if(rad<=4)
{
mu[i]=x2;
continue;
}
/* If intermediate separation, use linear combination of v_sph & v_lin.
*/
if(rad<=20)
{
w=-0.62*log(rad)+1.86;
mu[i]=w*x2 + (1-w)*x1;
continue;
}
/* In linear regime. Use linear theory.
*/
mu[i]=x1;
}
if(rad<=rcrit)
for(i=1;i<=nrho;++i)
mu[i]=mu[j];
for(i=1;i<=nrho;++i)
pdelta[i]/=ptot;
vfac=pow(OMEGA_M/0.3,0.6)*(SIGMA_8/0.8)*vfac0;
/* If Halos only, then set all the galaxy velocity dispersions
* and weights to be zero.
*/
if(!HOD.pdfs)
{
sgal[0]=sgal[1]=sgal[2]=0;
wgal[0]=wgal[1]=wgal[2]=0;
}
for(i=1;i<=nrho;++i)
{
sigv=200*pow(rho[i]/rho200,alpha)*vfac;
sigvt=200*pow(rho[i]/rho200t,alphat)*vfac;
sr1=sigv*sigv + sgal[0];
sr2=sigv*sigv + sgal[1];
sr3=sigv*sigv + sgal[2];
sr4=sigv*sigv + sgal[3];
st1=sigvt*sigvt + sgal[0];
st2=sigvt*sigvt + sgal[1];
st3=sigvt*sigvt + sgal[2];
st4=sigvt*sigvt + sgal[3];
sz1=2*(st1+tan2theta*sr1)*costheta*costheta;
sz2=2*(st2+tan2theta*sr2)*costheta*costheta;
sz3=2*(st3+tan2theta*sr3)*costheta*costheta;
sz4=2*(st4+tan2theta*sr4)*costheta*costheta;
sigz1[i]=sz1;
sigz2[i]=sz2;
sigz3[i]=sz3;
sigz4[i]=sz4;
gnorm1=wgal[0]/(RT2PI*sqrt(st1*sr1)*sqrt(1.0/(sr1) + tan2theta/(st1)));
gnorm2=wgal[1]/(RT2PI*sqrt(st2*sr2)*sqrt(1.0/(sr2) + tan2theta/(st2)));
gnorm3=wgal[2]/(RT2PI*sqrt(st3*sr3)*sqrt(1.0/(sr3) + tan2theta/(st3)));
gnorm4=(1-wgal[0]-wgal[1]-wgal[2])/
(RT2PI*sqrt(st4*sr4)*sqrt(1.0/(sr4) + tan2theta/(st4)));
g1[i]=gnorm1;
g2[i]=gnorm2;
g3[i]=gnorm3;
g4[i]=gnorm4;
}
/* Find the mode of the distribution. Start at vz=0 and work either way.
*/
for(k=1,j=nv/2;j<=nv;++j,++k)
{
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(k==2){
if(pz[j-1]>pz[j])direction=-1;
else direction=1;
break;
}
}
direction=1;
if(direction==1)iend=nv;
else iend=1;
for(k=1,j=nv/2-direction;j!=iend;j+=direction,++k)
{
if(pz[j]>0)goto SKIP1;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
SKIP1:
if(k<3)continue;
if(direction>0) {
/*printf("%d %e %e %e\n",j,pz[j],pz[j-1],pz[j-2]);*/
if(pz[j-1]>pz[j] && pz[j-1]>pz[j-2]) {
minp = pz[j-1]*0.001; break; }
} else {
/*printf("%d %e %e %e\n",j,pz[j],pz[j+1],pz[j+2]);*/
if(pz[j+1]>pz[j] && pz[j+1]>pz[j+2]) {
minp = pz[j+1]*0.001; break; }
}
}
for(j=nv/2;j<=nv;++j)
{
if(pz[j]>0)continue;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(pz[j]<=minp && nv-j>=3)break;
}
/* Now extrapolate the rest of the PVD from the last three points.
*/
for(k=0,i=j-2;i<=j;++i,++k)
{
yfit[k]=log(pz[i]);
xfit[k]=v0+(i-1)*binsize;
}
least_squares(xfit,yfit,3,&afit,&bfit);
for(i=j+1;i<=nv;++i)
pz[i] = exp(afit + bfit*(v0+(i-1)*binsize));
/* Now go from the mode to i=0
*/
for(j=nv/2-1;j>=1;--j)
{
if(pz[j]>0)continue;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(pz[j]<=minp && j>=3)break;
}
/* Now extrapolate the rest of the PVD from the last three points.
*/
for(k=2,i=j+2;i>=j;--i,--k)
{
yfit[k]=log(pz[i]);
xfit[k]=v0+(i-1)*binsize;
}
least_squares(xfit,yfit,3,&afit,&bfit);
for(i=j-1;i>0;--i)
pz[i] = exp(afit + bfit*(v0+(i-1)*binsize));
/* Do this just to get rid of any numerical roundoff errors and such.
* (It whould already be one by construction if I didn't have the
* linear extrapolation at the end of each side, but the correction
* shouldn't be much.)
*/
for(ptot=0,i=1;i<=nv;++i)
ptot+=pz[i]*binsize;
for(i=1;i<=nv;++i)
pz[i]/=ptot;
if(isnan(ptot))
{
printf("NAN ptot %f %f %f %f %f %f\n",rho200,rho200t,alpha,rho0,sr4,st4);
fflush(stdout);
for(i=1;i<=nv;++i)
pt[i]=pz[i]=pv[i]=0;
return;
}
return;
}
/* This is the standard log-normal 1-pt distribution of dark
* matter densities (non-linear) at top-hat smoothing scale r.
*/
double delta_pdf(double delta, double r)
{
static int model_prev=0;
static double pnorm=-1,rprev=0,sig0,sig1sqr;
double pnorm1;
if(pnorm<0 || RESET_COSMOLOGY!=model_prev)
{
pnorm1=SIGMA_8/sigmac(8.0);
/*printf("NORM %e %e %e\n",pnorm1,sigmac(8.0),nonlinear_sigmac(8.0));*/
pnorm=pnorm1*sigmac(80.0)/nonlinear_sigmac(80.0);
rprev=0;
/*printf("NORM %e %e %e %e %f\n",pnorm,sigmac(8.0),sigmac(80.0),nonlinear_sigmac(80.0),SIGMA_8);*/
}
if(r!=rprev)
{
sig0=pnorm*nonlinear_sigmac(r);
sig1sqr=log(1+sig0*sig0);
/*printf("NORM %f %f %e %e %e\n",r,sig0,pnorm,nonlinear_sigmac(8.0),sigmac(8.0));*/
}
rprev=r;
model_prev=RESET_COSMOLOGY;
return(1.0/(RT2PI*sqrt(sig1sqr))*exp(-pow(log((1+delta))+sig1sqr*0.5,2.0)/
(2*sig1sqr))/(1+delta));
}

View file

@ -0,0 +1,231 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* These routines control the real-space one-halo term.
* For specifics, see:
*
* Berlind, A.\ A., \& Weinberg, D.\ H.\ 2002, \apj, 575, 587
* Zheng, Z. 2003, \apj, 610, 61
* Tinker, Weinberg, Zheng, Zehavi 2005 Apj 631 (App B)
*
*/
/* Local functions.
*/
void calc_real_space_one_halo(double *r, double *xi, int n);
double func1(double m);
double func1cs(double m);
double func1satsat(double m);
double func1_xcorr(double m);
double one_halo_ss(double r);
double one_halo_cs(double r);
double *xi_cs_g2,*xi_ss_g2,*xi_rad_g2;
/* These are the local globals to use during the qromo integration
*/
double r_g2;
/* This function tabulates the one-halo real-space term for spline interpolation.
* If the requested radius is out-of-bounds of the tabulated function, a value of
* zero is returned.
*/
double one_halo_real_space(double r)
{
static int flag=0;
static double *x,*y,*y2;
int i,n=100;
double a;
if(!HOD.pdfs)return(0);
if(!flag || RESET_FLAG_1H)
{
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
RESET_FLAG_1H=0;
calc_real_space_one_halo(x,y,n);
spline(x,y,n,2.0E+30,2.0E+30,y2);
}
if(r>x[n])return(0);
if(r<x[1])return(0);
splint(x,y,y2,n,r,&a);
return(a);
}
/* Here we calculate the one-halo real space term
* logarithmically spaced in r. The minimum value of r = 0.01 Mpc/h. The maximum
* value of r is set to be approximately twice the virial radius of M_max.
*
* Only halos with virial radii greater than 1/2 the separation
* contribute to the 1-halo term.
* Terminate integrations when r>2*R_vir(M_max).
*/
void calc_real_space_one_halo(double *r, double *xi, int n)
{
static int ncnt=0;
double fac,s1,rhi=1,rlo=-2,dr,mlo,x1,x2;
int i,j;
FILE *fp;
char fname[100];
ncnt++;
rlo=log(0.01);
rhi=log(1.9*pow(3*HOD.M_max/(4*PI*DELTA_HALO*RHO_CRIT*OMEGA_M),1.0/3.0));
dr=(rhi-rlo)/(n-1);
if(OUTPUT>1)
printf("calc_one_halo> starting...\n");
if(!XCORR)
GALAXY_DENSITY2 = GALAXY_DENSITY;
for(i=1;i<=n;++i)
{
r_g2=r[i]=exp((i-1)*dr + rlo);
fac=1.0/(2*PI*r_g2*r_g2*GALAXY_DENSITY*GALAXY_DENSITY2);
mlo = 4./3.*PI*RHO_CRIT*DELTA_HALO*OMEGA_M*pow(r[i]*.5,3.0);
if(mlo<HOD.M_low)
mlo = HOD.M_low;
if(XCORR)
s1=fac*qromo(func1_xcorr,log(mlo),log(HOD.M_max),midpnt)*0.5;
else
s1=fac*qromo(func1,log(mlo),log(HOD.M_max),midpnt);
xi[i]=s1;
if(OUTPUT>1)
printf("calc_one_halo> %f %e %e\n",r[i],s1,fac);
continue;
}
}
/* This is the function passed to qromo in the above routine.
* It is the number density of
* galaxy pairs in halos of mass m at separation r_g2.
* See Equation (11) from Berlind & Weinberg.
*/
double func1(double m)
{
double N,n,fac2,rvir,f_ss,f_cs,cvir,x,rfof,ncen,nsat;
m=exp(m);
cvir=halo_concentration(m)*CVIR_FAC;
n=dndM_interp(m);
nsat=N_sat(m);
ncen=N_cen(m);
rvir=2*pow(3.0*m/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
/* Break up the contribution of pairs into
* central-satellite (cs) and satellite-satellite (ss) pairs.
*/
f_ss=dFdx_ss(r_g2/rvir,cvir)*moment_ss(m)*0.5;
f_cs=dFdx_cs(r_g2/rvir,cvir)*nsat*ncen;
x=n*(f_ss+f_cs)/rvir*m;
return(x);
}
double func1satsat(double m)
{
double N,n,fac2,rvir,f_ss,f_cs,cvir,x,rfof,ncen,nsat;
m=exp(m);
cvir=halo_concentration(m)*CVIR_FAC;
n=dndM_interp(m);
nsat=N_sat(m);
ncen=N_cen(m);
rvir=2*pow(3.0*m/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
/* Break up the contribution of pairs into
* central-satellite (cs) and satellite-satellite (ss) pairs.
*/
f_ss=dFdx_ss(r_g2/rvir,cvir)*moment_ss(m)*0.5;
x=n*(f_ss)/rvir*m;
return(x);
}
double func1cs(double m)
{
double N,n,fac2,rvir,f_ss,f_cs,cvir,x,rfof,ncen,nsat;
m=exp(m);
cvir=halo_concentration(m)*CVIR_FAC;
n=dndM_interp(m);
nsat=N_sat(m);
ncen=N_cen(m);
rvir=2*pow(3.0*m/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
/* Break up the contribution of pairs into
* central-satellite (cs) and satellite-satellite (ss) pairs.
*/
f_cs=dFdx_cs(r_g2/rvir,cvir)*nsat*ncen;
x=n*(f_cs)/rvir*m;
return(x);
}
/* Same as above, only now we're calculating the number of pairs
* in the cross-correlation.
*
* NB! -- We're assuming that the satellite galaxy profiles
* of both HODs are the same.
*/
double func1_xcorr(double m)
{
double N,n,fac2,rvir,f_ss=0,f_cs=0,cvir,x,rfof,ncen1,nsat1,ncen2,nsat2;
m=exp(m);
cvir=halo_concentration(m)*CVIR_FAC;
n=dndM_interp(m);
nsat1=N_sat(m);
ncen1=N_cen(m);
nsat2=N_sat2(m);
ncen2=N_cen2(m);
rvir=2*pow(3.0*m/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
/* Break up the contribution of pairs into
* central-satellite (cs) and satellite-satellite (ss) pairs.
* But for x-corr, we have c1-s2, c2-s1, s1-s2.
*/
f_ss=dFdx_ss(r_g2/rvir,cvir)*nsat1*nsat2;
f_cs=dFdx_cs(r_g2/rvir,cvir)*(nsat1*ncen2 + nsat2*ncen1);
x=n*(f_ss+f_cs)/rvir*m;
return(x);
}
/* The public version doesn't currently support cross-correlations.
*/
double N_sat2(double m)
{
return 0;
}
double N_cen2(double m)
{
return 0;
}

349
c_tools/hod/output_params.c Normal file
View file

@ -0,0 +1,349 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "header.h"
/* This function is taken from Volker Springel's GADGET code and
* modified for the parameters used for the HOD.x code.
*/
/* Ths is the same as intput_params.c, but it is called after
* model fitting to data, and uses the new values whenever
* applicable.
*/
/*
* This function parses the parameterfile in a simple way.
* Each paramater is defined by a keyword (`tag'), and can be
* either of type douple, int, or character string.
* The routine makes sure that each parameter appears
* exactly once in the parameterfile.
*/
void output_parameter_file(char *fname)
{
#define DOUBLE 1
#define STRING 2
#define INT 3
#define CHAR 4
#define LONG 4
#define MAXTAGS 300
FILE *fd,*fdout;
char buf[200],buf1[200],buf2[200],buf3[200];
int i,j,nt;
int id[MAXTAGS];
void *addr[MAXTAGS];
char tag[MAXTAGS][200];
int errorFlag=0;
int IDUM_MCMC_TEMP=-555;
nt=0;
strcpy(tag[nt],"GAMMA");
addr[nt]=&GAMMA;
id[nt++]=DOUBLE;
strcpy(tag[nt],"OMEGA_M");
addr[nt]=&OMEGA_M;
id[nt++]=DOUBLE;
strcpy(tag[nt],"SIGMA_8");
addr[nt]=&SIGMA_8;
id[nt++]=DOUBLE;
strcpy(tag[nt],"RHO_CRIT");
addr[nt]=&RHO_CRIT;
id[nt++]=DOUBLE;
strcpy(tag[nt],"ITRANS");
addr[nt]=&ITRANS;
id[nt++]=INT;
strcpy(tag[nt],"LINEAR_PSP");
addr[nt]=&LINEAR_PSP;
id[nt++]=INT;
strcpy(tag[nt],"KAISER");
addr[nt]=&KAISER;
id[nt++]=INT;
strcpy(tag[nt],"BETA");
addr[nt]=&BETA;
id[nt++]=DOUBLE;
strcpy(tag[nt],"SIGV");
addr[nt]=&SIGV;
id[nt++]=DOUBLE;
strcpy(tag[nt],"IDUM_MCMC");
addr[nt]=&IDUM_MCMC_TEMP;
id[nt++]=INT;
strcpy(tag[nt],"SPECTRAL_INDX");
addr[nt]=&SPECTRAL_INDX;
id[nt++]=DOUBLE;
strcpy(tag[nt],"DELTA_CRIT");
addr[nt]=&DELTA_CRIT;
id[nt++]=DOUBLE;
strcpy(tag[nt],"DELTA_HALO");
addr[nt]=&DELTA_HALO;
id[nt++]=DOUBLE;
strcpy(tag[nt],"BOX_SIZE");
addr[nt]=&BOX_SIZE;
id[nt++]=DOUBLE;
strcpy(tag[nt],"RESOLUTION");
addr[nt]=&RESOLUTION;
id[nt++]=DOUBLE;
strcpy(tag[nt],"VBIAS");
addr[nt]=&VBIAS;
id[nt++]=DOUBLE;
strcpy(tag[nt],"VBIAS_C");
addr[nt]=&VBIAS_C;
id[nt++]=DOUBLE;
strcpy(tag[nt],"TF_file");
addr[nt]=Files.TF_file;
id[nt++]=STRING;
strcpy(tag[nt],"M1");
addr[nt]=&HOD.M1;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_min");
addr[nt]=&HOD.M_min;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_cen_max");
addr[nt]=&HOD.M_cen_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_cut");
addr[nt]=&HOD.M_cut;
id[nt++]=DOUBLE;
strcpy(tag[nt],"M_max");
addr[nt]=&HOD.M_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"sigma_logM");
addr[nt]=&HOD.sigma_logM;
id[nt++]=DOUBLE;
strcpy(tag[nt],"MaxCen");
addr[nt]=&HOD.MaxCen;
id[nt++]=DOUBLE;
strcpy(tag[nt],"alpha");
addr[nt]=&HOD.alpha;
id[nt++]=DOUBLE;
strcpy(tag[nt],"pdfc");
addr[nt]=&HOD.pdfc;
id[nt++]=INT;
strcpy(tag[nt],"pdfs");
addr[nt]=&HOD.pdfs;
id[nt++]=INT;
strcpy(tag[nt],"GALAXY_DENSITY");
addr[nt]=&GALAXY_DENSITY;
id[nt++]=DOUBLE;
strcpy(tag[nt],"EXCLUSION");
addr[nt]=&EXCLUSION;
id[nt++]=INT;
strcpy(tag[nt],"FIX_PARAM");
addr[nt]=&FIX_PARAM;
id[nt++]=INT;
strcpy(tag[nt],"POWELL");
addr[nt]=&POWELL;
id[nt++]=INT;
strcpy(tag[nt],"OUTPUT");
addr[nt]=&OUTPUT;
id[nt++]=INT;
for(i=1;i<=11;++i)
{
sprintf(tag[nt],"free[%d]",i);
addr[nt]=&HOD.free[i];
id[nt++]=INT;
}
strcpy(tag[nt],"All");
addr[nt]=&Task.All;
id[nt++]=INT;
strcpy(tag[nt],"real_space_xi");
addr[nt]=&Task.real_space_xi;
id[nt++]=INT;
strcpy(tag[nt],"z_space_xi");
addr[nt]=&Task.z_space_xi;
id[nt++]=INT;
strcpy(tag[nt],"kaiser_xi");
addr[nt]=&Task.kaiser_xi;
id[nt++]=INT;
strcpy(tag[nt],"multipoles");
addr[nt]=&Task.multipoles;
id[nt++]=INT;
strcpy(tag[nt],"r_half");
addr[nt]=&Task.r_half;
id[nt++]=INT;
strcpy(tag[nt],"wp_minimize");
addr[nt]=&Task.wp_minimize;
id[nt++]=INT;
Task.wp_minimize=0;
strcpy(tag[nt],"zspace_minimize");
addr[nt]=&Task.zspace_minimize;
id[nt++]=INT;
Task.zspace_minimize=0;
strcpy(tag[nt],"MCMC");
addr[nt]=&Task.MCMC;
id[nt++]=INT;
Task.MCMC=0;
strcpy(tag[nt],"COVAR");
addr[nt]=&COVAR;
id[nt++]=INT;
COVAR=1;
strcpy(tag[nt],"DEPROJECTED");
addr[nt]=&DEPROJECTED;
id[nt++]=INT;
strcpy(tag[nt],"fname_covar");
addr[nt]=&wp.fname_covar;
id[nt++]=STRING;
strcpy(tag[nt],"pi_max");
addr[nt]=&wp.pi_max;
id[nt++]=DOUBLE;
strcpy(tag[nt],"esys");
addr[nt]=&wp.esys;
id[nt++]=DOUBLE;
strcpy(tag[nt],"fname_wp");
addr[nt]=&wp.fname_wp;
id[nt++]=STRING;
strcpy(tag[nt],"wp_format");
addr[nt]=&wp.format;
id[nt++]=INT;
strcpy(tag[nt],"root_filename");
addr[nt]=&Task.root_filename;
id[nt++]=STRING;
strcpy(tag[nt],"CVIR_FAC");
addr[nt]=&CVIR_FAC;
id[nt++]=DOUBLE;
strcpy(tag[nt],"JENKINS_A");
addr[nt]=&JENKINS_A;
id[nt++]=DOUBLE;
strcpy(tag[nt],"JENKINS_C");
addr[nt]=&JENKINS_C;
id[nt++]=DOUBLE;
strcpy(tag[nt],"JENKINS_B");
addr[nt]=&JENKINS_B;
id[nt++]=DOUBLE;
strcpy(tag[nt],"BEST_FIT");
addr[nt]=&BEST_FIT;
id[nt++]=INT;
if((fd=fopen(fname,"r")))
{
sprintf(buf,"%s.new",fname);
if(!(fdout=fopen(buf,"w")))
{
fprintf(stdout,"error opening file '%s' \n",buf);
errorFlag=1;
}
else
{
while(!feof(fd))
{
fgets(buf,200,fd);
if(sscanf(buf,"%s%s%s",buf1,buf2,buf3)<2)
continue;
if(buf1[0]=='%')
continue;
for(i=0,j=-1;i<nt;i++)
if(strcmp(buf1,tag[i])==0)
{
j=i;
tag[i][0]=0;
break;
}
if(j>=0)
{
switch(id[j])
{
case DOUBLE:
if(!((double)atof(buf2)!=*((double*)addr[j])))
*((double*)addr[j])=atof(buf2);
fprintf(fdout,"%-35s%g\n",buf1,*((double*)addr[j]));
break;
case STRING:
strcpy(addr[j],buf2);
fprintf(fdout,"%-35s%s\n",buf1,buf2);
break;
case INT:
if(!(atoi(buf2)!=*((int*)addr[j])))
*((int*)addr[j])=atoi(buf2);
fprintf(fdout,"%-35s%d\n",buf1,*((int*)addr[j]));
break;
case CHAR:
if(!(buf2[0]!=*((char*)addr[j])))
*((char*)addr[j])=buf2[0];
fprintf(fdout,"%-35s%c\n",buf1,*((int*)addr[j]));
break;
}
}
}
}
}
else
{
fprintf(stderr,"Parameter file %s not found.\n", fname);
exit(1);
}
fprintf(fdout,"\n\n");
fclose(fd);
fclose(fdout);
#undef DOUBLE
#undef STRING
#undef INT
#undef MAXTAGS
}

175
c_tools/hod/pair_density.c Normal file
View file

@ -0,0 +1,175 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
double m_g3,r_g3,*x_g3,*y_g3,*z_g3;
double n_g3;
int flag_g3=0;
double func_ng(double m);
double func_ng2(double m);
/* The restr
*/
double restricted_number_density(double r)
{
static int flag=1;
static double *x,*y,*y2;
int i,n=50,j;
double mlimit,dlogm,logm,mmin,sum=0,t0,t1,s1,s2,s3,m,r1,r2,ng2,rlim,rmin,rmax;
if(flag)
{
n_g3 = n;
x_g3=dvector(1,n);
y_g3=dvector(1,n);
z_g3=dvector(1,n);
flag=0;
}
/* Reset the static variables in this function.
*/
func_ng2(-1);
r_g3=r;
ng2=GALAXY_DENSITY*GALAXY_DENSITY;
/* Calculate the maximum allowable halo mass, which had
* rvir = r_g3 - rvir(M_low).
*/
r1=pow(3.*HOD.M_low/(4.*PI*DELTA_HALO*RHO_CRIT*OMEGA_M),1.0/3.0);
rlim = r_g3 - r1;
mlimit=log(4./3.*DELTA_HALO*RHO_CRIT*PI*rlim*rlim*rlim*OMEGA_M);
if(mlimit>log(HOD.M_max))mlimit=log(HOD.M_max);
mmin=log(HOD.M_low);
if(HOD.color==2)
{
dlogm=(mlimit-mmin)/(n-1);
m = mmin;
for(i=1;i<=n;++i)
{
if(N_avg(exp(m))>0)break;
m += dlogm;
}
mmin = m;
r1=pow(3.*exp(mmin)/(4.*PI*DELTA_HALO*RHO_CRIT*OMEGA_M),1.0/3.0);
rlim = r_g3 - r1;
mlimit=log(4./3.*DELTA_HALO*RHO_CRIT*PI*rlim*rlim*rlim*OMEGA_M);
}
if(EXCLUSION==2) {
dlogm=(mlimit-mmin)/(n-1);
x_g3[1] = mmin;
y_g3[1] = qromo(func_galaxy_density,mmin,mmin+dlogm,midpnt);
for(i=2;i<=n;++i)
{
x_g3[i] = i*dlogm+mmin;
y_g3[i] = y_g3[i-1] + qromo(func_galaxy_density,(i-1)*dlogm+mmin,mmin+i*dlogm,midpnt);
}
spline(x_g3,y_g3,n,1.0E+30,1.0E+30,z_g3);
s1 = qromo(func_ng2,mmin,mlimit,midpnt);
return(sqrt(s1));
}
/* Calculate the double integral at specified masses.
*/
dlogm=(mlimit-mmin)/(n-1);
for(i=1;i<=n;++i)
{
logm=(i-0.5)*dlogm+mmin;
m_g3=exp(logm);
r2 = pow(3*m_g3/(4*PI*DELTA_HALO*RHO_CRIT*OMEGA_M),1.0/3.0);
if(EXCLUSION==3) {
if(ellipsoidal_exclusion_probability(r1/r2,r_g3/(r1+r2))==0)break; }
else {
if(r1+r2>r_g3)break; }
s1=qtrap(func_ng,mmin,mlimit,1.0E-4);
sum+=s1*m_g3*dlogm;
if(s1==0)break;
if(sum>=ng2)break;
}
return sqrt(sum);
}
double func_ng2(double m)
{
static double fac2=-1,fac1=-1;
double s1,rv1,n,N,m1,mx;
if(m<0)
{
fac1=fac2=-1;
return(0);
}
m1=exp(m);
if(fac2<0)
fac2=pow(3.0/(4.*PI*DELTA_HALO*RHO_CRIT*OMEGA_M),1.0/3.0);
if(fac1<0)
fac1=4./3.*PI*RHO_CRIT*DELTA_HALO*OMEGA_M;
rv1 = r_g3 - pow(m1,1.0/3.0)*fac2;
rv1 = rv1;
mx = fac1*rv1*rv1*rv1;
n=dndM_interp(m1);
N=N_avg(m1);
splint(x_g3,y_g3,z_g3,n_g3,log(mx),&s1);
return(n*N*s1*m1);
}
double func_ng(double m)
{
static double fac2=-1;
double s1,rv1,rv2,exfac=1,n,N;
m=exp(m);
if(fac2<0)
fac2=pow(3.0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rv1=pow(m_g3,1.0/3.0)*fac2;
rv2=pow(m,1.0/3.0)*fac2;
if(EXCLUSION==3)
{
if(0.5*(rv1+rv2)>r_g3)return(0);
if(1.5*(rv1+rv2)>r_g3)exfac=ellipsoidal_exclusion_probability(rv2/rv1,r_g3/(rv2+rv1));
}
else
{
if(rv1+rv2>r_g3)return(0);
}
n=dndM_interp(m)*dndM_interp(m_g3);
N=N_avg(m)*N_avg(m_g3);
return(exfac*n*N*m);
}
/* This is the probability that two halos do not overlap, given their
* radii and separation. Of course, for spherical halos P(x) is a step function
* at x = (r1+r2)/r_sep = 1, but for ellipsoidal halos there is a chance
* that they could be closer. In detail, P(x) changes depending on the mass
* ratio of the halos, but using tabulated values does not appear to make
* significant difference in the results for xi_2h(r). The function below is
* a fit to Monte Carlo results for a halos with a distribution of axis ratios
* which is lognormal in e_b = (1-b/a) and e_c = (1-c/a) with dispersions of 0.2
* mean <b/a>=0.9 and <c/a>=0.8 (pretty reasonable values).
*/
double ellipsoidal_exclusion_probability(double rv, double r)
{
static int flag=0,nr=101,nratio=31;
static double **xprob,*rad,*ratio,rhi,rlo,mhi,mlo,dr,dm;
float x1,x2,x3;
int i,j,im,ir;
FILE *fp;
if(rv<1)rv=1.0/rv;
r=(r-0.8)/0.29;
if(r>1)return(1.0);
if(r<0)return(0.0);
return(3*r*r-2*r*r*r);
}

39
c_tools/hod/polint.c Normal file
View file

@ -0,0 +1,39 @@
#include <math.h>
#include <stdio.h>
#define NRANSI
#include "nrutil.h"
void polint(double xa[], double ya[], int n, double x, double *y, double *dy)
{
int i,m,ns=1;
double den,dif,dift,ho,hp,w;
double *c,*d;
dif=fabs(x-xa[1]);
c=dvector(1,n);
d=dvector(1,n);
for (i=1;i<=n;i++) {
if ( (dift=fabs(x-xa[i])) < dif) {
ns=i;
dif=dift;
}
c[i]=ya[i];
d[i]=ya[i];
}
*y=ya[ns--];
for (m=1;m<n;m++) {
for (i=1;i<=n-m;i++) {
ho=xa[i]-x;
hp=xa[i+m]-x;
w=c[i+1]-d[i];
if ( (den=ho-hp) == 0.0) nrerror("Error in routine polint");
den=w/den;
d[i]=hp*den;
c[i]=ho*den;
}
*y += (*dy=(2*ns < (n-m) ? c[ns+1] : d[ns--]));
}
free_dvector(d,1,n);
free_dvector(c,1,n);
}
#undef NRANSI

View file

@ -0,0 +1,702 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "header.h"
#define NBINLOOKUP 10000
/* This function reads in a halo file and creates a mock galaxy distribution
* by populating the dark matter halos with galaxies with the currently specified
* HOD functions.
*
* The format of the halo file needs to be in ASCII:
* col 1 - halo ID (not used)
* col 2 - number of particles in halo
* cols 3-5 - x,y,z position of halo, in Mpc/h
* col 6 - space velocity of halo (not used)
* cols 7-9 - vx,vy,vz velocity of halo, in km/s
*
* The values of RESOLUTION, BOX_SIZE, OMEGA_M from the batch file are used
* to convert particle number into mass, and to box-wrap galaxies.
* If you want another file format, by all means edit.
*
* Output: mock galaxies are printed to [root].mock
* in format: x,y,z [Mpc/h] vz,vy,vz [km/s]
*
* Output: HOD calculated from populated halos (for cross-checking with true HOD)
* [root].binned_HOD in format: bin id, log10(mass), <N_gal>, N_halo
*
* Satellite positions are chosen from a random sampling of the NFW profile
* for the mass of the halo being populated. If CVIR_FAC is specified, then that value
* will be used to adjust the NFW profile. Satellite velocities are chosen
* from a Gaussin distribution with width = to virial dispersion of halo (plus
* halo center-of-mass).
*
* NB-- If you are using the code to calculate M_min from a desired space density,
* be sure that the linear matter power spectrum is the same as that used in the
* simulation, or else the space densities won't match. [Mass function is used for this
* purpose].
*
*/
double NFW_central_velocity(double mass, double v[], double mag);
void calc_nbody_two_halo(float **gal, int *id, int ngal);
double *g21_rad, *g21_xi;
int g21_nrad;
/* External functions.
*/
void nbrsfind2(float smin,float smax,float rmax,int nmesh,float xpos,float ypos,float zpos,
int *nbrmax,int *indx,float *rsqr,float *x,float *y,float *z,
int *meshparts,int ***meshstart,int ip);
void meshlink2(int np1,int *nmesh,float smin,float smax,float rmax,float *x1,float *y1,float *z1,
int **meshparts,int ****meshstart,int meshfac);
void free_i3tensor(int ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh);
void populate_simulation()
{
FILE *fp,*fpa[9],*fp2,*fpb[9],*fpc[9],*fps[9],*fpt;
int i,j,k,n,imass,n1,j_start=0,i1,galcnt[1000],halocnt[1000],imag;
double mass,xg[3],vg[3],nsat,nc[10],ncen,mlo,mag,err1,err2,r,fac,sigv;
char aa[1000];
float x1,xh[3],vh[3],vgf[3];
long IDUM3 = -445;
float **galarr;
int *galid,id1=0,id2=0,j1;
float dx,dy,dz,dr,drh,rv1,rv2,rmin,rmax;
float **haloarr;
int ngal,nsati[9],ALL_FILES=0,TRACK_GALAXIES=0,WARREN_MASS_CORRECTION=0,haloid;
int nadded;
FILE *fpBuh;
char buhFile[1000];
nadded = 0;
float *xt,*yt,*zt,*vxt,*vyt,*vzt;
int SO_FILE = 1,
JEANS_DISPERSION = 0;
// if(RESOLUTION > 1.6)
// WARREN_MASS_CORRECTION = 1;
TRACK_GALAXIES=1;
// srand48(IDUM_MCMC);
galarr = matrix(1,1000000000,0,5);
haloarr = matrix(1,1000000000,0,6);
galid = ivector(1,1000000000);
fp=openfile(Files.HaloFile);
sprintf(aa,"%s.mock",Task.root_filename);
fp2 = fopen(aa,"w");
sprintf(aa,"%s.mock_halo",Task.root_filename);
fpt = fopen(aa,"w");
sprintf(buhFile,"%s.buh",Task.root_filename);
fpBuh = fopen(buhFile,"w");
fprintf(fp2, "%f\n", BOX_SIZE);
fprintf(fp2, "%f\n", OMEGA_M);
fprintf(fp2, "%f\n", HUBBLE);
fprintf(fp2, "%f\n", REDSHIFT);
fprintf(fp2, "%d\n", RESOLUTION*RESOLUTION*RESOLUTION);
for(i=0;i<1000;++i)
halocnt[i]=0;
for(i=0;i<1000;++i)
galcnt[i]=0;
set_HOD_params();
mlo = HOD.M_low;
printf("MLO %e %e %f\n",mlo,HOD.M_min,HOD.sigma_logM);
printf("BOX_SIZE %f\n",BOX_SIZE);
fflush(stdout);
int numHalos = 0;
printf("FORMAT IS %s\n", Files.HaloFileFormat);
printf("FILE IS %s\n", Files.HaloFile);
int numLines = 0;
int dummy = 0;
char* dummyString[200];
while(!feof(fp))
{
numLines++;
if(SO_FILE)
{
if (strcmp(Files.HaloFileFormat, "multidark") == 0) {
fscanf(fp,"%f,%f,%f,%f,%f,%f,%lf,%lf,%f,%f,%f,%f",
&xh[0],&xh[1],&xh[2],&vh[0],&vh[1],&vh[2],&mass,&x1,&x1,&x1,&x1,&x1);
} else if (strcmp(Files.HaloFileFormat, "lanl") == 0 ||
strcmp(Files.HaloFileFormat, "sdf") == 0) {
fscanf(fp,"%lf %f %f %f %f %f %f\n",
&mass, &xh[0],&xh[1],&xh[2],&vh[0],&vh[1],&vh[2]);
} else if (strcmp(Files.HaloFileFormat, "fnl") == 0) {
if (numLines <= 1) {
fscanf(fp, "%s %s %s %s %s %s %s %s %s\n", dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString);
continue;
}
fscanf(fp,"%d %f %f %f %f %f %f %lf\n",
&dummy, &xh[0],&xh[1],&xh[2],&vh[0],&vh[1],&vh[2],&mass);
} else if (strcmp(Files.HaloFileFormat, "ahf") == 0) {
if (numLines <= 1) {
fscanf(fp,"%s\n", dummyString);
continue;
} else if (numLines <= 2) {
fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString,
dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString,
dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString,
dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString,
dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString,
dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString,
dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString, dummyString
);
continue;
}
fscanf(fp,"%d %d %d %lf %d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
&dummy, &dummy, &dummy, &mass, &dummy, &xh[0], &xh[1], &xh[2], &vh[0], &vh[1], &vh[2],
&x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1,
&x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1,
&x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1,
&x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1,
&x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1,
&x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1, &x1
);
xh[0] /= 1000.;
xh[1] /= 1000.;
xh[2] /= 1000.;
} else {
printf("Unsupported format: %s!\n", Files.HaloFileFormat);
exit(-1);
}
//if (numHalos < 10) {
// printf("READ %e %e %e %e\n", mass, xh[0], xh[1], xh[2]);
//}
//&mass,&x1,&x1,&xh[0],&xh[1],&xh[2],&vh[0],&vh[1],&vh[2]);
//fscanf(fp,"%d %lf %f %f %f %f %f %f %f %f",
// &i,&mass,&x1,&x1,&xh[0],&xh[1],&xh[2],&vh[0],&vh[1],&vh[2]);
/*
fac=sqrt(4.499E-48)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19;
sigv=fac*pow(mass,1.0/3.0)/sqrt(2.0);
printf("%e %e %f\n",mass,sigv,VBIAS);
if(i==2)
one_halo(1,1);
*/
haloid = numHalos;
numHalos++;
}
else
{
fscanf(fp,"%d %d %e %e %e %e %e %e %e",
&i,&imass,&xh[0],&xh[1],&xh[2],&x1,&vh[0],&vh[1],&vh[2]);
mass=imass*RHO_CRIT*OMEGA_M*pow(RESOLUTION,3.0);
}
haloid = i;
if(mass>HOD.M_max)continue;
if(WARREN_MASS_CORRECTION)
mass = imass*(1-pow(imass,-0.6))*RHO_CRIT*OMEGA_M*pow(RESOLUTION,3.0);
if(mass<mlo)continue;
for(i=0;i<3;++i)
{
if(xh[i]<0)xh[i]+=BOX_SIZE;
if(xh[i]>BOX_SIZE)xh[i]-=BOX_SIZE;
}
i1 = (int)(log10(mass)/0.1);
halocnt[i1]++;
ncen=N_cen(mass);
if(drand48()>ncen)goto SATELLITES;
if(VBIAS_C>0)
{
NFW_central_velocity(mass,vg,mag);
for(i=0;i<3;++i)
vh[i]+=vg[i];
}
fprintf(fp2,"%d %e %e %e %e %e %e %e\n",nadded,xh[0],xh[1],xh[2],vh[2],vh[1],vh[0], mass);
nadded++;
//fprintf(fp2,"%e %e %e %e %e %e\n",xh[0],xh[1],xh[2],vh[0],vh[1],vh[2]);
fprintf(fpt,"%d\n",haloid);
// THis mocks up the ~22 columns of the MR mocks
// fprintf(fpt,"%d %d %d %e %e %e 0.0 0.0 0.0 %e %e %e 0.0 0.0 0.0 0.0 0.0 0.0 %e 0.0 0.0\n",
// 0,0,0,xh[0],xh[1],xh[2],vh[0],vh[1],vh[2],log10(mass));
if(VBIAS_C>0)
{
for(i=0;i<3;++i)
vh[i]-=vg[i];
}
galcnt[i1]++;
if(TRACK_GALAXIES)
{
id2++;
galid[id2] = haloid;
galarr[id2][0] = xh[0];
galarr[id2][1] = xh[1];
galarr[id2][2] = xh[2];
galarr[id2][3] = vh[0];
galarr[id2][4] = vh[1];
galarr[id2][5] = vh[2];
}
if(TRACK_GALAXIES)
{
id1++;
haloarr[id1][0] = xh[0];
haloarr[id1][1] = xh[1];
haloarr[id1][2] = xh[2];
haloarr[id1][3] = vh[0];
haloarr[id1][4] = vh[1];
haloarr[id1][5] = vh[2];
haloarr[id1][6] = mass;
}
SATELLITES:
nsat = N_sat(mass);
if(nsat>250)
n1 = gasdev(&IDUM3)*sqrt(nsat) + nsat;
else
n1 = poisson_deviate(nsat);
///*
if(nsat>=1)
fprintf(fpBuh,"%d %f %e %d %e %f\n",haloid,nsat,mass,n1,HOD.M1,pow(mass/HOD.M1,HOD.alpha));
//fprintf(stdout,"BUH %d %f %e %d %e %f\n",haloid,nsat,mass,n1,HOD.M1,pow(mass/HOD.M1,HOD.alpha));
// */
for(i=1;i<=n1;++i)
{
r = NFW_position(mass,xg);
if(JEANS_DISPERSION)
jeans_dispersion(mass,r,vg);
else
NFW_velocity(mass,vg,mag);
for(k=0;k<3;++k)
{
xg[k]+=xh[k];
if(xg[k]<0)xg[k]+=BOX_SIZE;
if(xg[k]>BOX_SIZE)xg[k]-=BOX_SIZE;
vg[k]+=vh[k];
/* vg[k] = vgf[k]; */
/*
vg[k] = gasdev(&IDUM3)*500;
vg[k] = non_gaussian_velocity();
*/
}
fprintf(fp2,"%d %e %e %e %e %e %e %e\n",i, xg[0],xg[1],xg[2],vg[2],vg[1],vg[0],mass);
//fprintf(fp2,"%e %e %e %e %e %e\n",xg[0],xg[1],xg[2],vg[0],vg[1],vg[2]);
fprintf(fpt,"%d\n",haloid);
// fprintf(fpt,"%d %d %d %e %e %e 0.0 0.0 0.0 %e %e %e 0.0 0.0 0.0 0.0 0.0 0.0 %e 0.0 0.0\n",1,1,1,xg[0],xg[1],xg[2],vg[0],vg[1],vg[2],log10(mass));
if(TRACK_GALAXIES)
{
id2++;
galid[id2] = haloid;
galarr[id2][0] = xg[0];
galarr[id2][1] = xg[1];
galarr[id2][2] = xg[2];
galarr[id2][3] = vg[0];
galarr[id2][4] = vg[1];
galarr[id2][5] = vg[2];
}
/* Bin up the galaxies by halo mass to check the HOD
*/
galcnt[i1]++;
}
if(feof(fp))break;
}
fprintf(fp2, "-99 -99 -99 -99 -99 -99 -99 -99\n"); // signals end of particle list
fclose(fp2);
fclose(fpt);
fclose(fpBuh);
printf("GALAXY DENSITY %e\n", GALAXY_DENSITY);
/* output the binned HOD
*/
sprintf(aa,"%s.binned_HOD",Task.root_filename);
fp2=fopen(aa,"w");
for(i=0;i<1000;++i)
if(galcnt[i]>0)
fprintf(fp2,"%d %f %f %d %d\n",
i,(i+0.5)*0.1,(float)galcnt[i]/halocnt[i],galcnt[i],halocnt[i]);
fclose(fp2);
/* Calculate the two-halo term
*/
if(TRACK_GALAXIES)
{
fprintf(stderr,"Calling nbody_2halo...\n");
calc_nbody_two_halo(galarr,galid,id2);
}
return ;
/* Track the close pairs - for Non-Tinkers, don't worry about this.
*/
rmin = 1.5;
rmax = 2.5;
for(i=1;i<=id2;++i)
for(j=i+1;j<=id2;++j)
{
if(galid[i]==galid[j])continue;
dx = galarr[i][0] - galarr[j][0];
if(dx>BOX_SIZE/2)dx = BOX_SIZE-dx;
if(dx>rmax)continue;
dy = galarr[i][1] - galarr[j][1];
if(dy>BOX_SIZE/2)dy = BOX_SIZE-dy;
if(dy>rmax)continue;
dz = galarr[i][2] - galarr[j][2];
if(dz>BOX_SIZE/2)dz = BOX_SIZE-dz;
if(dz>rmax)continue;
dr = sqrt(dx*dx+dy*dy+dz*dz);
if(dr<rmin || dr>rmax)continue;
i1 = galid[i];
j1 = galid[j];
dx = haloarr[i1][0] - haloarr[j1][0];
if(dx>BOX_SIZE/2)dx = BOX_SIZE-dx;
dy = haloarr[i1][1] - haloarr[j1][1];
if(dy>BOX_SIZE/2)dy = BOX_SIZE-dy;
dz = haloarr[i1][2] - haloarr[j1][2];
if(dz>BOX_SIZE/2)dz = BOX_SIZE-dz;
drh = sqrt(dx*dx+dy*dy+dz*dz);
rv1 = pow(3*haloarr[i1][6]/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rv2 = pow(3*haloarr[j1][6]/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
if(dr < rv1+rv2)
{
dx = galarr[i][3] - galarr[j][3];
dy = galarr[i][4] - galarr[j][4];
dz = galarr[i][5] - galarr[j][5];
printf("%e %e %e %e %e %e %e\n",dr,rv1+rv2,haloarr[i1][6],haloarr[j1][6],dx,dy,dz);
fflush(stdout);
}
}
exit(0);
}
/* Generate a random integer based on a Poisson distribution
* with mean given as input.
*/
int poisson_deviate(double nave)
{
static int flag=0;
double p,pp;
int n;
p=0;
pp=1;
while(p<pp)
{
if(nave<1)
n=(int)(drand48()*20);
else
n=(int)(drand48()*30*nave);
p=poisson_prob(n,nave);
pp=drand48();
}
return(n);
}
/* Poisson probability of n given n_average
*/
double poisson_prob(int n, double nave)
{
int i;
double fac=1;
if(n>0)
for(i=1;i<=n;++i)
fac*=nave/i;
return((float)(fac*exp(-nave)));
}
/* Randomy generates a position away from the origin with
* a probability given by the NFW profile for a halo of the input
* mass (and including the CVIR_FAC)
*/
double NFW_position(double mass, double x[])
{
double r,pr,max_p,costheta,sintheta,phi1,signs,rvir,rs,cvir;
cvir=halo_concentration(mass)*CVIR_FAC;
rvir=pow(3*mass/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rs=rvir/cvir;
max_p=NFW_density(rs,rs,1.0)*rs*rs*4.0*PI;
for(;;) {
r=drand48()*rvir;
pr=NFW_density(r,rs,1.0)*r*r*4.0*PI/max_p;
if(drand48()<=pr)
{
costheta=2.*(drand48()-.5);
sintheta=sqrt(1.-costheta*costheta);
signs=2.*(drand48()-.5);
costheta=signs*costheta/fabs(signs);
phi1=2.0*PI*drand48();
x[0]=r*sintheta*cos(phi1);
x[1]=r*sintheta*sin(phi1);
x[2]=r*costheta;
return r;
}
}
}
/* This is the NFW density profile
*/
double NFW_density(double r, double rs, double ps)
{
return(ps*rs/(r*(1+r/rs)*(1+r/rs)));
}
/* This sets the velocity to be isotropic Gaussian.
*/
double NFW_velocity(double mass, double v[], double mag)
{
static long IDUM2=-455;
static double fac = -1;
double sigv,vbias=1;
int i;
if(fac<0)
fac=sqrt(4.499E-48)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19;
sigv=fac*pow(mass,1.0/3.0)/sqrt(2.0);
for(i=0;i<3;++i)
v[i]=gasdev(&IDUM2)*sigv*VBIAS;
return(0);
}
/* This sets the velocity to be isotropic Gaussian.
*/
double NFW_central_velocity(double mass, double v[], double mag)
{
static long IDUM2=-455;
static double fac = -1;
double sigv,vbias=1;
int i;
if(fac<0)
fac=sqrt(4.499E-48)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19;
sigv=fac*pow(mass,1.0/3.0)/sqrt(2.0);
for(i=0;i<3;++i)
v[i]=gasdev(&IDUM2)*sigv*VBIAS_C;
return(0);
}
/* This is the routine where we tabulate the 2-halo term and
* interpolate as needed.
*/
double nbody_two_halo(double r)
{
static int flag=1,n=30;
static double *x,*y,*y2;
double a;
int i;
if(flag || RESET_FLAG_1H)
{
populate_simulation();
if(flag)
{
n = g21_nrad;
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=0;
for(i=1;i<=n;++i)
{
x[i] = g21_rad[i];
y[i] = g21_xi[i];
}
/*
if(OUTPUT)
printf("Calculating nbody xi(r)...\n");
calc_nbody_two_halo(x,y,n);
if(OUTPUT)
printf("finished\n");
for(i=1;i<=n;++i)
y[i]=log(y[i]);
*/
spline(x,y,n,1.0E+30,1.0E+30,y2);
RESET_FLAG_1H=0;
}
// r=log(r);
if(r<0.2)return(-1);
splint(x,y,y2,n,r,&a);
return(a);
// return(exp(a));
}
/* This is the two-halo term.
*/
void calc_nbody_two_halo(float **gal, int *id, int ngal)
{
float rmax,rmin,lrstep,binfac,rcube,weight0,fac,rlow,density,weightrandom,vol,r;
int ibin,kbin,nbin,i,j,k,*binlookup,*npair,ngal_temp;
float *rupp,*rsqr,reduction_factor,*vxt,*vyt,*vzt;
int *meshparts, ***meshstart,nmesh,meshfac,nbrmax,*indx;
double *rbar,galden;
float *xg,*yg,*zg,*xt,*yt,*zt;
static float *rad, *xi;
static int nr, flag = 0;
char fname[100];
FILE *fp;
sprintf(fname,"%s.nbody_2halo",Task.root_filename);
fp = fopen(fname,"w");
rmax = 30;
rmin = 0.1;
nbin = nr = 20;
rad = vector(1,nr);
xi = vector(1,nr);
g21_rad = dvector(1,nr);
g21_xi = dvector(1,nr);
g21_nrad = nr;
xg = malloc(ngal*sizeof(float));
yg = malloc(ngal*sizeof(float));
zg = malloc(ngal*sizeof(float));
ngal_temp=0;
for(i=1;i<=ngal;++i)
{
xg[ngal_temp] = gal[i][0];
yg[ngal_temp] = gal[i][1];
zg[ngal_temp] = gal[i][2];
ngal_temp++;
}
ngal = ngal_temp;
indx=malloc(ngal*sizeof(int));
rsqr=malloc(ngal*sizeof(float));
/***********************
* initializing the logarithmic bins
*/
rupp = (float *) calloc(nbin+1,sizeof(float)) ;
lrstep=log(rmax/rmin)/(float)(nbin-1) ;
binlookup=(int *)calloc(NBINLOOKUP+2,sizeof(int)) ;
ibin=0 ;
for (i=0;i<=NBINLOOKUP;i++) {
r=rmax*i/NBINLOOKUP ;
if (r>0) {
kbin=(int)floor(log(r/rmin)/lrstep+1.0) ;
}
else {
kbin=0 ;
}
if (kbin<0) kbin=0 ;
if (kbin>ibin) {
rupp[ibin]=r ;
ibin=kbin ;
}
binlookup[i]=kbin ;
}
binlookup[NBINLOOKUP+1]=nbin ;
rupp[nbin-1]=rmax ;
rupp[nbin]=rmax ;
binfac=NBINLOOKUP/rmax ;
rbar=calloc(nbin,sizeof(double));
npair=calloc(nbin,sizeof(int));
rcube = BOX_SIZE;
nmesh=0;
printf("STARTING MESHLINK\n");
printf("PARAMETERS: %e %e %e\n", 0.0, rcube, rmax);
meshlink2(ngal,&nmesh,0.0,rcube,rmax,xg,yg,zg,&meshparts,&meshstart,meshfac);
printf("DONE WITH MESHLINK\n");
for(i=0;i<ngal;++i)
{
nbrmax=ngal;
nbrsfind2(0.0,rcube,rmax,nmesh,xg[i],yg[i],zg[i],&nbrmax,indx,rsqr,xg,yg,zg,
meshparts,meshstart,i);
for(j=0;j<nbrmax;++j)
{
k = indx[j];
// if gals in same halo, skip
if(id[i+1]==id[k+1])continue;
r=sqrt(rsqr[j]) ;
kbin=binlookup[(int)(binfac*r)] ;
if(kbin>=nbin)continue;
npair[kbin]++;
rbar[kbin]+=r;
}
}
density=ngal/(rcube*rcube*rcube) ;
rlow=0;
for (kbin=0;kbin<nbin;kbin++) {
weight0=(float) npair[kbin];
if (weight0>0.0) {
fac=1./weight0 ;
rbar[kbin] *= fac ;
}
else { /* avoid errors in empty bins */
rbar[kbin]=(rupp[kbin]+rlow)*0.5;
}
/* compute xi, dividing summed weight by that expected for a random set */
vol=4.*PI/3.*(rupp[kbin]*rupp[kbin]*rupp[kbin]-rlow*rlow*rlow) ;
weightrandom=ngal*density*vol ;
g21_rad[kbin+1] = rad[kbin+1]=log(rbar[kbin]);
g21_xi[kbin+1] = xi[kbin+1]=weight0/weightrandom-1 ;
rlow=rupp[kbin] ;
fprintf(fp,"%e %e %.0f\n",rbar[kbin],xi[kbin+1],weight0);
if(OUTPUT>1)
{
fprintf(stdout,"nbody_xi> %f %f %.0f\n",rbar[kbin],xi[kbin+1],weight0);
fflush(stdout);
}
}
fclose(fp);
free(indx);
free(rsqr);
free(rupp);
free(binlookup);
free(npair);
free(rbar);
free_i3tensor(meshstart,0,nmesh-1,0,nmesh-1,0,nmesh-1);
}

58
c_tools/hod/powell.c Normal file
View file

@ -0,0 +1,58 @@
#include <math.h>
#define NRANSI
#include "nrutil.h"
#define ITMAX 200
void powell(double p[], double **xi, int n, double ftol, int *iter, double *fret,
double (*func)(double []))
{
void linmin(double p[], double xi[], int n, double *fret,
double (*func)(double []));
int i,ibig,j;
double del,fp,fptt,t,*pt,*ptt,*xit;
pt=dvector(1,n);
ptt=dvector(1,n);
xit=dvector(1,n);
*fret=(*func)(p);
for (j=1;j<=n;j++) pt[j]=p[j];
for (*iter=1;;++(*iter)) {
fp=(*fret);
ibig=0;
del=0.0;
for (i=1;i<=n;i++) {
for (j=1;j<=n;j++) xit[j]=xi[j][i];
fptt=(*fret);
linmin(p,xit,n,fret,func);
if (fabs(fptt-(*fret)) > del) {
del=fabs(fptt-(*fret));
ibig=i;
}
}
if (2.0*fabs(fp-(*fret)) <= ftol*(fabs(fp)+fabs(*fret))) {
free_dvector(xit,1,n);
free_dvector(ptt,1,n);
free_dvector(pt,1,n);
return;
}
if (*iter == ITMAX) nrerror("powell exceeding maximum iterations.");
for (j=1;j<=n;j++) {
ptt[j]=2.0*p[j]-pt[j];
xit[j]=p[j]-pt[j];
pt[j]=p[j];
}
fptt=(*func)(ptt);
if (fptt < fp) {
t=2.0*(fp-2.0*(*fret)+fptt)*SQR(fp-(*fret)-del)-del*SQR(fp-fptt);
if (t < 0.0) {
linmin(p,xit,n,fret,func);
for (j=1;j<=n;j++) {
xi[j][ibig]=xi[j][n];
xi[j][n]=xit[j];
}
}
}
}
}
#undef ITMAX
#undef NRANSI

214
c_tools/hod/powspec.c Normal file
View file

@ -0,0 +1,214 @@
#include "header.h"
double sig8; // value of sigma_8
double rho; // current density of universe (solar mass/Mpc^3)
double G0; // present day density cst
double Gl; // Cosmological Constant densty
double H0; // Hubble cst km/s.MPc
double pow_n; // Scalar spectral index
double bfrac; // Baryon fraction of total density
double Gamma; // P(k) parameter - normally unused
double pow_norm; // power spectrum normalisation
double NB_density; // Nbody density being modelled
int pow_spec_type=2; // choice of power spectrum
// set up rho and power spectrum normalisation
void nm_power_eh()
{
double r, mass, sigmasq;
rho = 3.*G0*(3.236e-20*H0)*(3.236e-20*H0)/(8.*pi*G_cst*M_sun/(Mpc*Mpc*Mpc));
fprintf(stderr,"h=%g, rho=%g\n",H0/100.,rho);
r = 8.0;
mass = 4./3.*pi*r*r*r*rho;
pow_norm=1.;
sigmasq=qmidinf(Sigth_eh,1.0,1.e40,r)/(2.*pi*pi);
pow_norm=(sig8*sig8)/sigmasq;
fprintf(stderr,"r=%g, mass=%g, sig8=%g, nor=%g\n",r,mass,sig8, pow_norm);
}
// Sigmasq no filter : return D^2(k)
double Sig_eh(double lnk) {
double k;
k = pow(10.,lnk);
return k*k*k*Pk(k)/(2.*pi*pi);
}
// Sigmasq for a top hat filter - integrate 0..infinity
double Sigth_eh( double kplus1, double R )
{
double k, x, W;
k = kplus1-1.0;
x = k*R;
W = 3.*(sin(x) - x*cos(x))/(x*x*x);
return W*W*k*k*Pk(k);
}
// Power spectrum
float Pk(float k)
{
float pn=0.0;
float q, tf, tfsq=0.0;
float tk_eh(float);
if(k==0.) return 0.;
switch(pow_spec_type) {
// BBKS
case 1:
q = k/Gamma;
tf = log(1.+2.34*q)/(2.34*q);
tfsq = tf*tf/sqrt(1.0+q*(3.89+q*(259.21+q*(162.77+q*2027.17))));
pn = pow_norm*pow(k,pow_n)*tfsq;
break;
// Eisenstein & Hu
case 2:
tf = tk_eh(k);
tfsq = tf*tf;
pn = pow_norm*pow(k,pow_n)*tfsq;
break;
// Power law k^(pow_n)
case 3:
tfsq = 1.0;
pn = pow_norm*pow(k,pow_n)*tfsq;
break;
// DEFW P(k)
case 4:
q = k/Gamma;
tf = pow(1.+pow(6.4*q+pow(3.0*q,1.5)+pow(1.7*q,2.),1.13),(-1./1.13));
tfsq = tf*tf;
pn = pow_norm*pow(k,pow_n)*tfsq;
break;
// baryonic fit
// case 5:
// pn = sin(fit_phi+k/fit_kc);
// pn = pow_norm*(1.+fit_a*k+fit_b*k*k)*pn*pn;
// break;
// Eisenstein & Hu + non-linear approximation
case 6:
tf = tk_eh(k);
tfsq = tf*tf;
pn = pow_norm*pow(k,pow_n)*tfsq;
if(k>0.2) pn = exp( 2.0*(1.+log(k)-log(0.2))*log(pn) );
break;
// Eisenstein & Hu + shot noise
case 7:
tf = tk_eh(k);
tfsq = tf*tf;
pn = pow_norm*pow(k,pow_n)*tfsq;
if(k<=(2.*2.*pi*pow(NB_density,1./3.))) pn += 1.0/NB_density;
break;
}
return pn;
}
// Transfer function of Eisenstein & Hu 1998
// (Equation numbers refer to this paper)
float tk_eh(float k)
{
float rk,e,thet,thetsq,thetpf,b1,b2,zd,ze,rd,re,rke,s,rks,q,y,g;
float ab,a1,a2,ac,bc,f,c1,c2,tc,bb,bn,ss,tb,tk_eh;
float h,hsq,om_mhsq,om_b,om_m;
// set up cosmology
h = H0/100.0;
om_m = G0;
om_b = bfrac*om_m;
// convert k to Mpc^-1 rather than hMpc^-1
rk=k*h;
hsq=h*h;
om_mhsq=om_m*hsq;
// constants
e=exp(1.);
thet=2.728/2.7;
thetsq=thet*thet;
thetpf=thetsq*thetsq;
// Equation 4 - redshift of drag epoch
b1=0.313*pow(om_mhsq,-0.419)*(1.+0.607*pow(om_mhsq,0.674));
b2=0.238*pow(om_mhsq,0.223);
zd=1291.*(1.+b1*pow(om_b*hsq,b2))*pow(om_mhsq,0.251)
/(1.+0.659*pow(om_mhsq,0.828));
// Equation 2 - redshift of matter-radiation equality
ze=2.50e4*om_mhsq/thetpf;
// value of R=(ratio of baryon-photon momentum density) at drag epoch
rd=31500.*om_b*hsq/(thetpf*zd);
// value of R=(ratio of baryon-photon momentum density) at epoch of matter-radiation equality
re=31500.*om_b*hsq/(thetpf*ze);
// Equation 3 - scale of ptcle horizon at matter-radiation equality
rke=7.46e-2*om_mhsq/(thetsq);
// Equation 6 - sound horizon at drag epoch
s=(2./3./rke)*sqrt(6./re)*log((sqrt(1.+rd)+sqrt(rd+re))/(1.+sqrt(re)));
// Equation 7 - silk damping scale
rks=1.6*pow(om_b*hsq,0.52)*pow(om_mhsq,0.73)*(1.+pow(10.4*om_mhsq,-0.95));
// Equation 10 - define q
q=rk/13.41/rke;
// Equations 11 - CDM transfer function fits
a1=pow(46.9*om_mhsq,0.670)*(1.+pow(32.1*om_mhsq,-0.532));
a2=pow(12.0*om_mhsq,0.424)*(1.+pow(45.0*om_mhsq,-0.582));
ac=pow(a1,(-om_b/om_m))*pow(a2,pow(-(om_b/om_m),3.));
// Equations 12 - CDM transfer function fits
b1=0.944/(1.+pow(458.*om_mhsq,-0.708));
b2=pow(0.395*om_mhsq,-0.0266);
bc=1./(1.+b1*(pow(1.-om_b/om_m,b2)-1.));
// Equation 18
f=1./(1.+pow(rk*s/5.4,4.));
// Equation 20
c1=14.2 + 386./(1.+69.9*pow(q,1.08));
c2=14.2/ac + 386./(1.+69.9*pow(q,1.08));
// Equation 17 - CDM transfer function
tc=f*log(e+1.8*bc*q)/(log(e+1.8*bc*q)+c1*q*q) +
(1.-f)*log(e+1.8*bc*q)/(log(e+1.8*bc*q)+c2*q*q);
// Equation 15
y=(1.+ze)/(1.+zd);
g=y*(-6.*sqrt(1.+y)+(2.+3.*y)*log((sqrt(1.+y)+1.)/(sqrt(1.+y)-1.)));
// Equation 14
ab=g*2.07*rke*s/pow(1.+rd,0.75);
// Equation 23
bn=8.41*pow(om_mhsq,0.435);
// Equation 22
ss=s/pow(1.+pow(bn/rk/s,3.),1./3.);
// Equation 24
bb=0.5+(om_b/om_m) + (3.-2.*om_b/om_m)*sqrt(pow(17.2*om_mhsq,2.)+1.);
// Equations 19 & 21
tb=log(e+1.8*q)/(log(e+1.8*q)+c1*q*q)/(1+pow(rk*s/5.2,2.));
tb=(tb+ab*exp(-pow(rk/rks,1.4))/(1.+pow(bb/rk/s,3.)))*sin(rk*ss)/rk/ss;
// Equation 8
tk_eh=(om_b/om_m)*tb+(1.-om_b/om_m)*tc;
return tk_eh;
}

34
c_tools/hod/qromo.c Normal file
View file

@ -0,0 +1,34 @@
#include <math.h>
#include <stdio.h>
#include "header.h"
#define EPS 1.0e-6
#define JMAX 14
#define JMAXP (JMAX+1)
#define K 5
double qromo(double (*func)(double), double a, double b,
double (*choose)(double(*)(double), double, double, int))
{
void polint(double xa[], double ya[], int n, double x, double *y, double *dy);
void nrerror(char error_text[]);
int j;
double ss,dss,h[JMAXP+1],s[JMAXP+1];
h[1]=1.0;
for (j=1;j<=JMAX;j++) {
s[j]=(*choose)(func,a,b,j);
if (j >= K) {
polint(&h[j-K],&s[j-K],K,0.0,&ss,&dss);
if (fabs(dss) < EPS*fabs(ss)) return ss;
}
s[j+1]=s[j];
h[j+1]=h[j]/9.0;
}
printf("ERROR: Too many steps in routing qromo\n");
ERROR_FLAG=1;
return ss;
}
#undef EPS
#undef JMAX
#undef JMAXP
#undef K

20
c_tools/hod/qtrap.c Normal file
View file

@ -0,0 +1,20 @@
#include <math.h>
#include <stdio.h>
#define JMAX 20
double qtrap(double (*func)(double), double a, double b, double EPS)
{
double trapzd(double (*func)(double), double a, double b, int n);
/*void nrerror(char error_text[]);*/
int j;
double s,olds,t1,t2;
olds = -1.0e30;
for (j=1;j<=JMAX;j++) {
s=trapzd(func,a,b,j);
if (fabs(s-olds) < EPS*fabs(olds)) return s;
olds=s;
}
return s;
}
#undef JMAX

47
c_tools/hod/ran1.c Normal file
View file

@ -0,0 +1,47 @@
#define IA 16807
#define IM 2147483647
#define AM (1.0/IM)
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float ran1(long *idum)
{
int j;
long k;
static long iy=0;
static long iv[NTAB];
float temp;
if (*idum <= 0 || !iy) {
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
for (j=NTAB+7;j>=0;j--) {
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-IR*k;
if (*idum < 0) *idum += IM;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ;
*idum=IA*(*idum-k*IQ)-IR*k;
if (*idum < 0) *idum += IM;
j=iy/NDIV;
iy=iv[j];
iv[j] = *idum;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
#undef IA
#undef IM
#undef AM
#undef IQ
#undef IR
#undef NTAB
#undef NDIV
#undef EPS
#undef RNMX

63
c_tools/hod/ran2.c Normal file
View file

@ -0,0 +1,63 @@
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
double ran2(long *idum)
{
int j;
long k;
static long idum2=123456789;
static long iy=0;
static long iv[NTAB];
double temp;
if (*idum <= 0) {
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
idum2=(*idum);
for (j=NTAB+7;j>=0;j--) {
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
k=idum2/IQ2;
idum2=IA2*(idum2-k*IQ2)-k*IR2;
if (idum2 < 0) idum2 += IM2;
j=iy/NDIV;
iy=iv[j]-idum2;
iv[j] = *idum;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
#undef IM1
#undef IM2
#undef AM
#undef IMM1
#undef IA1
#undef IA2
#undef IQ1
#undef IQ2
#undef IR1
#undef IR2
#undef NTAB
#undef NDIV
#undef EPS
#undef RNMX

173
c_tools/hod/sigmac.c Normal file
View file

@ -0,0 +1,173 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/*
* sigmac calls qromo to evaluate the integral
int_0^infty P_s(k) 4 pi k^2 dk / (2pi)^3
where P_s(k) is the power spectrum smoothed through a gaussian
window of radius rgaus and a top hat window of radius rth.
The power spectrum is a power law of index xindx, multiplied by
the square of the CDM transfer function if itrans = 1.
If the smoothing radius [rad] is positive, a top-hat window
function is used.
If [rad<0], a gaussian window function is used.
*/
double rad1;
double func_sigmac(double xk);
double func_sigmac_nl(double xk);
double sigmac_interp(double m)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2, pnorm;
int i,n=100;
double dlogm,max=5.e16,min=1.0e7,a,b,m1,m2,dm1,xi,power,rm,sig,b1,b2,mass;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting bias for %f %f\n",OMEGA_M,SIGMA_8);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dlogm = (log(max) - log(min))/(n-1);
pnorm=SIGMA_8/sigmac(8.0);
for(i=1;i<=n;++i)
{
m = exp((i-1)*dlogm)*min;
rm=pow(3.0*m/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=log(pnorm*sigmac(rm));
x[i] = log(m);
y[i] = sig;
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
m=log(m);
splint(x,y,y2,n,m,&a);
return exp(a);
}
double sigmac_radius_interp(double m)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2, pnorm;
int i,n=100;
double dlogm,max=80.0,min=0.1,a,b,m1,m2,dm1,xi,power,rm,sig,b1,b2,mass;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting bias for %f %f\n",OMEGA_M,SIGMA_8);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dlogm = (log(max) - log(min))/(n-1);
pnorm=SIGMA_8/sigmac(8.0);
for(i=1;i<=n;++i)
{
rm = exp((i-1)*dlogm)*min;
sig=log(pnorm*sigmac(rm));
x[i] = log(rm);
y[i] = sig;
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
m=log(m);
splint(x,y,y2,n,m,&a);
return exp(a);
}
double sigmac(double rad)
{
double xk1,s1=1,s2=0,sigma0;
rad1=rad;
xk1 = 1./(2.*PI*mabs(rad));
s1=qromo(func_sigmac,0.0,xk1,midpnt);
s2=qromo(func_sigmac,xk1,1.e20,midinf);
sigma0=sqrt((s1+s2)*(4*PI)/pow(2*PI,3.0));
return sigma0;
}
double func_sigmac(double xk)
{
double xkr,w,psp;
if(rad1>0)
{
xkr = xk*rad1;
w = 3*(sin(xkr)-xkr*cos(xkr))/(xkr*xkr*xkr);
w = w*w;
}
else
{
xkr = -rad1*xk;
w = exp(-xkr*xkr);
}
if(ITRANS>0)
psp=pow(xk,SPECTRAL_INDX)*pow(transfnc(xk),2.0);
else
psp=pow(xk,SPECTRAL_INDX);
psp=psp*w*xk*xk;
return(psp);
}
/* Same as above, but no instead of using the linear
* theory power spectrum, use the non-linear P(k)
*/
double nonlinear_sigmac(double rad)
{
double xk1,s1=1,s2=0,sigma0;
rad1=rad;
xk1 = 1./(2.*PI*mabs(rad));
s1=qromo(func_sigmac_nl,0.0,xk1,midpnt);
s2=qromo(func_sigmac_nl,xk1,1.e20,midinf);
sigma0=sqrt((s1+s2));
return sigma0;
}
double func_sigmac_nl(double xk)
{
double xkr,w,psp;
if(rad1>0)
{
xkr = xk*rad1;
w = 3*(sin(xkr)-xkr*cos(xkr))/(xkr*xkr*xkr);
w = w*w;
}
else
{
xkr = -rad1*xk;
w = exp(-xkr*xkr);
}
psp=nonlinear_power_spectrum(xk);
psp=psp*w/xk;
return(psp);
}

81
c_tools/hod/sort2.c Normal file
View file

@ -0,0 +1,81 @@
#define NRANSI
#include "nrutil.h"
#define SWAP(a,b) temp=(a);(a)=(b);(b)=temp;
#define iSWAP(a,b) itemp=(a);(a)=(b);(b)=itemp;
#define M 7
#define NSTACK 50
void sort2(unsigned long n, float arr[], int id[])
{
unsigned long i,ir=n,j,k,l=1;
int jstack=0,*istack;
float a,temp,temp_Id;
int temp_m,itemp;
istack=ivector(1,NSTACK);
for (;;) {
if (ir-l < M) {
for (j=l+1;j<=ir;j++) {
a=arr[j];
temp_m=id[j];
for (i=j-1;i>=1;i--) {
if (arr[i] <= a) break;
arr[i+1]=arr[i];
id[i+1]=id[i];
}
arr[i+1]=a;
id[i+1]=temp_m;
}
if (jstack == 0) break;
ir=istack[jstack--];
l=istack[jstack--];
} else {
k=(l+ir) >> 1;
SWAP(arr[k],arr[l+1]);
iSWAP(id[k],id[l+1]);
if (arr[l+1] > arr[ir]) {
SWAP(arr[l+1],arr[ir]);
iSWAP(id[l+1],id[ir]);
}
if (arr[l] > arr[ir]) {
SWAP(arr[l],arr[ir]);
iSWAP(id[l],id[ir]);
}
if (arr[l+1] > arr[l]) {
SWAP(arr[l+1],arr[l]);
iSWAP(id[l+1],id[l]);
}
i=l+1;
j=ir;
a=arr[l];
temp_m=id[l];
for (;;) {
do i++; while (arr[i] < a);
do j--; while (arr[j] > a);
if (j < i) break;
SWAP(arr[i],arr[j]);
iSWAP(id[i],id[j]);
}
arr[l]=arr[j];
id[l]=id[j];
arr[j]=a;
id[j]=temp_m;
jstack += 2;
if (jstack > NSTACK) nrerror("NSTACK too small in sort.");
if (ir-i+1 >= j-l) {
istack[jstack]=ir;
istack[jstack-1]=i;
ir=j-1;
} else {
istack[jstack]=j-1;
istack[jstack-1]=l;
l=i;
}
}
}
free_ivector(istack,1,NSTACK);
}
#undef M
#undef NSTACK
#undef SWAP
#undef NRANSI

13
c_tools/hod/splie2.c Normal file
View file

@ -0,0 +1,13 @@
#include <stdlib.h>
#include <stdio.h>
void splie2(double x1a[], double x2a[], double **ya, int m, int n, double **y2a)
{
void spline(double x[], double y[], int n, double yp1,
double ypn, double y2[]);
int j;
for (j=1;j<=m;j++)
{
spline(x2a,ya[j],n,1.0e30,1.0e30,y2a[j]);
}
}

23
c_tools/hod/splin2.c Normal file
View file

@ -0,0 +1,23 @@
#define NRANSI
#include "nrutil.h"
void splin2(double x1a[], double x2a[], double **ya, double **y2a, int m, int n,
double x1, double x2, double *y)
{
void spline(double x[], double y[], int n, double yp1,
double ypn, double y2[]);
void splint(double xa[], double ya[], double y2a[], int n,
double x, double *y);
int j;
double *ytmp,*yytmp;
ytmp=dvector(1,n);
yytmp=dvector(1,n);
for (j=1;j<=m;j++)
splint(x2a,ya[j],y2a[j],n,x2,&yytmp[j]);
spline(x1a,yytmp,m,1.0e30,1.0e30,ytmp);
splint(x1a,yytmp,ytmp,m,x1,y);
free_dvector(yytmp,1,n);
free_dvector(ytmp,1,n);
}
#undef NRANSI

38
c_tools/hod/spline.c Normal file
View file

@ -0,0 +1,38 @@
#define NRANSI
#include <stdio.h>
#include <stdlib.h>
#include "nrutil.h"
void spline(double x[], double y[], int n, double yp1, double ypn, double y2[])
{
int i,k;
double p,qn,sig,un,*u;
u=dvector(1,n-1);
if (yp1 > 0.99e30)
y2[1]=u[1]=0.0;
else {
y2[1] = -0.5;
u[1]=(3.0/(x[2]-x[1]))*((y[2]-y[1])/(x[2]-x[1])-yp1);
}
for (i=2;i<=n-1;i++) {
sig=(x[i]-x[i-1])/(x[i+1]-x[i-1]);
p=sig*y2[i-1]+2.0;
y2[i]=(sig-1.0)/p;
u[i]=(y[i+1]-y[i])/(x[i+1]-x[i]) - (y[i]-y[i-1])/(x[i]-x[i-1]);
u[i]=(6.0*u[i]/(x[i+1]-x[i-1])-sig*u[i-1])/p;
}
if (ypn > 0.99e30)
qn=un=0.0;
else {
qn=0.5;
un=(3.0/(x[n]-x[n-1]))*(ypn-(y[n]-y[n-1])/(x[n]-x[n-1]));
}
y2[n]=(un-qn*u[n-1])/(qn*y2[n-1]+1.0);
for (k=n-1;k>=1;k--)
{
y2[k]=y2[k]*y2[k+1]+u[k];
}
free_dvector(u,1,n-1);
}
#undef NRANSI

36
c_tools/hod/splint.c Normal file
View file

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void splint(double xa[], double ya[], double y2a[], int n, double x, double *y)
{
void nrerror(char error_text[]);
int klo,khi,k,i;
double h,b,a;
klo=1;
khi=n;
while (khi-klo > 1) {
k=(khi+klo) >> 1;
if (xa[k] > x) khi=k;
else klo=k;
}
h=xa[khi]-xa[klo];
if(h == 0.0) {
printf("BADXA %d %f\n",n,x);
fflush(stdout);
}
if (h == 0.0) nrerror("Bad xa input to routine splint");
a=(xa[khi]-x)/h;
b=(x-xa[klo])/h;
*y=a*ya[klo]+b*ya[khi]+((a*a*a-a)*y2a[klo]+(b*b*b-b)*y2a[khi])*(h*h)/6.0;
if(isnan(*y))
{
/*
fprintf(stdout,"NAN %e %e %d %e %e %e %e %e %e\n",a,b,n,x,ya[klo],ya[khi],
y2a[khi],y2a[klo],h);
for(i=1;i<=n;++i)
printf("NAN %d %e %e %e %e\n",i,xa[i],ya[i],y2a[i],x);
*/
*y=0;
}
}

170
c_tools/hod/tasks.c Normal file
View file

@ -0,0 +1,170 @@
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/***********************************************************************
* This is the main function for controlling the activities of the code.
* If you ask for any sort of minimization or MCMC analysis, the code is
* redirected to another routine, but once finished will complete the rest
* of the tasks checked off (so if you want to minimize and then print out
* related statistics, the code will do that automatically if you ask it).
*
*
* Each task generates an output file using the "root_filename" in the hod.bat
* file and tacking on an extension at the end:
*
* [filename].r_space --> real space correlation function
* [filename].HOD --> prints out the mean N(M)
*
* See the full list below.
*/
void tasks(int argc, char **argv)
{
int i,j,nsize,ix,iy,nr,i1,i2,n;
float x1,x2,x3,x4,x5,x6,err,npairs;
double r,rs,rp,dx1,dx2,dx3,dx4,dx5,**xi2d,*xx2d,*yy2d,**xi2d_data,**xi2d_kaiser,
xi0_m,xi2_m,xi0_k,xi2_k,xi0_d,xi2_d,xi_r,rlo,rhi,rr[50],rhalf[50],dr,
rphi,rshi,rslo,rplo,dlogm,m,sig;
FILE *fp,*fp2,*fp1;
char fname[100];
/* This is for chi^2 minimization of data for the projected correlation
* function.
*/
if(Task.wp_minimize && !HOD.color)
wp_minimization(argv[1]);
/* This is for Monte-Carlo Markov Chain exploration of the posterior
* distribution of the parameters, either real-space or redshift-space,
* depending on what MCMC is set to.
*/
if(Task.MCMC)
mcmc_minimization();
/* This is to output the shape of the mean occupation function and the
* scatter about the mean.
* File columns are:
* 1 - halo mass (M_sol/h)
* 2 - N_cen(M)
* 3 - N_sat(M)
* 4 - N_tot(M)
* 5 - <N(N-1)>
* 6 - ratio of scatter to Poisson scatter (often called "alpha")
*/
if(Task.HOD || Task.All)
{
sprintf(fname,"%s.HOD",Task.root_filename);
fp=fopen(fname,"w");
dlogm=(log(HOD.M_max)-log(HOD.M_low))/99;
for(i=1;i<=100;++i)
{
m=exp((i-1)*dlogm)*HOD.M_low;
sig = N_sat(m)*N_sat(m) + N_cen(m)*(1-N_cen(m));
fprintf(fp,"%e %e %e %e %e %e\n",
m,N_cen(m),N_sat(m),N_avg(m),sig,sig/(N_avg(m)*N_avg(m)));
}
fclose(fp);
}
/* This sets in motion the calculation and tabulation of the real-space
* correlation function and outputs it to a file.
* File columns are:
* 1 - radius (Mpc/h)
* 2 - one-halo term (real-space)
* 3 - two-halo term (real-space)
* 4 - full xi(r)
* 5 - projected correlation function (1st column is now r_p)
* 6 - projected correlation function without z-space correction
*/
if(Task.real_space_xi || Task.All)
{
fprintf(stderr,"\n\nCALCULATING REAL-SPACE CORRELATION FUNCTION.\n");
fprintf(stderr, "--------------------------------------------\n\n");
sprintf(fname,"%s.r_space",Task.root_filename);
fp=fopen(fname,"w");
dr=(log(70.0)-log(0.01))/49.0;
for(i=0;i<50;++i)
{
r=exp(i*dr+log(0.01));
x1=one_halo_real_space(r);
x2=two_halo_real_space(r);
x3=projected_xi(r);
x4 = projected_xi_rspace(r);
fprintf(fp,"%f %e %e %e %e %e\n",r,x1,x2,x1+x2,x3,x4);
fflush(fp);
}
fclose(fp);
}
/* This takes a halofile from a simulation and populates the halos
* with galaxies according the HOD specified in the batch file.
*/
if(Task.populate_sim==1)
populate_simulation();
if(!ThisTask)
OUTPUT=1;
/* Output the linear and non-linear dark matter power spectrum.
* Non-linear P(k) calculated using Smith et al.
*
* Format of file [root].matter_pk
* 1 - k [h/Mpc]
* 2 - linear P(k) [Mpc/h]^3
* 3 - non-linear P(k) [Mpc/h]^3
*/
if(Task.matter_pk)
output_matter_power_spectrum();
/* Output the linear and non-linear dark matter power spectrum.
* Non-linear xi(r) is Fourier transform of Smith et al (above)
*
* Format of file [root].matter_pk
* 1 - r [Mpc/h]
* 2 - linear xi(r)
* 3 - non-linear xi(r)
*/
if(Task.matter_xi)
output_matter_correlation_function();
/* Output the matter variance as a function of scale.
*
* Format of file [root].sigma_r
* 1 - r [Mpc/h]
* 2 - sigma(r) [linear]
* 3 - sigma(r) [non-linear, using Smith]
* 4 - mass [M_sol/h] mass = (4/3)*PI*r^3*rho_bar
*/
if(Task.sigma_r)
output_matter_variance();
/* Output the halo concentrations using Bullock et al (2001) model
*
* Format of file [root].civr
* 1 - mass [Msol/h] --> mass specified by DELTA_HALO (input file).
* 2 - halo concentration. (for the specified halo definition)
*/
if(Task.cvir)
output_halo_concentrations();
/* Output the halo mass function using the results of Tinker et al (2008)
*
* Format of the file [root].massfunc
* 1 - mass [Msol/h]
* 2 - dn/dM [Mph/c]^-3 (the differential mass function).
*/
if(Task.dndM)
output_halo_mass_function();
endrun("finished with tasks");
}

5
c_tools/hod/test.c Normal file
View file

@ -0,0 +1,5 @@
#include "header.h"
void test(int argc, char **argv)
{
}

View file

@ -0,0 +1,140 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "header.h"
// Transfer function of Eisenstein & Hu 1998
// (Equation numbers refer to this paper)
double calc_tf_eh(double k);
double tf_eisenstein_hu(double k)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2;
int n=1000,i;
double a,rlo=1.0E-4,rhi=1.0E+4,dlogr,klo;
double xi_linear_int();
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dlogr = (log(rhi)-log(rlo))/(n-1);
for(i=1;i<=n;++i)
{
x[i] = exp((i-1)*dlogr)*rlo;
y[i] = log(calc_tf_eh(x[i]));
//printf("TK %e %e %e %e %e\n",x[i],exp(y[i]),exp(y[i]),exp(y[i]),exp(y[i]));
x[i] = log(x[i]);
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
splint(x,y,y2,n,log(k),&a);
return(exp(a));
}
double calc_tf_eh(double k)
{
double rk,e,thet,thetsq,thetpf,b1,b2,zd,ze,rd,re,rke,s,rks,q,y,g;
double ab,a1,a2,ac,bc,f,c1,c2,tc,bb,bn,ss,tb,tk_eh;
double h,hsq,om_mhsq,om_b,om_m;
// set up cosmology
h = HUBBLE;
om_m = OMEGA_M;
om_b = OMEGA_B;
// convert k to Mpc^-1 rather than hMpc^-1
rk=k*h;
hsq=h*h;
om_mhsq=om_m*hsq;
// constants
e=exp(1.);
thet=2.728/2.7;
thetsq=thet*thet;
thetpf=thetsq*thetsq;
// Equation 4 - redshift of drag epoch
b1=0.313*pow(om_mhsq,-0.419)*(1.+0.607*pow(om_mhsq,0.674));
b2=0.238*pow(om_mhsq,0.223);
zd=1291.*(1.+b1*pow(om_b*hsq,b2))*pow(om_mhsq,0.251)
/(1.+0.659*pow(om_mhsq,0.828));
// Equation 2 - redshift of matter-radiation equality
ze=2.50e4*om_mhsq/thetpf;
// value of R=(ratio of baryon-photon momentum density) at drag epoch
rd=31500.*om_b*hsq/(thetpf*zd);
// value of R=(ratio of baryon-photon momentum density) at epoch of matter-radiation equality
re=31500.*om_b*hsq/(thetpf*ze);
// Equation 3 - scale of ptcle horizon at matter-radiation equality
rke=7.46e-2*om_mhsq/(thetsq);
// Equation 6 - sound horizon at drag epoch
s=(2./3./rke)*sqrt(6./re)*log((sqrt(1.+rd)+sqrt(rd+re))/(1.+sqrt(re)));
// Equation 7 - silk damping scale
rks=1.6*pow(om_b*hsq,0.52)*pow(om_mhsq,0.73)*(1.+pow(10.4*om_mhsq,-0.95));
// Equation 10 - define q
q=rk/13.41/rke;
// Equations 11 - CDM transfer function fits
a1=pow(46.9*om_mhsq,0.670)*(1.+pow(32.1*om_mhsq,-0.532));
a2=pow(12.0*om_mhsq,0.424)*(1.+pow(45.0*om_mhsq,-0.582));
ac=pow(a1,(-om_b/om_m))*pow(a2,pow(-(om_b/om_m),3.));
// Equations 12 - CDM transfer function fits
b1=0.944/(1.+pow(458.*om_mhsq,-0.708));
b2=pow(0.395*om_mhsq,-0.0266);
bc=1./(1.+b1*(pow(1.-om_b/om_m,b2)-1.));
// Equation 18
f=1./(1.+pow(rk*s/5.4,4.));
// Equation 20
c1=14.2 + 386./(1.+69.9*pow(q,1.08));
c2=14.2/ac + 386./(1.+69.9*pow(q,1.08));
// Equation 17 - CDM transfer function
tc=f*log(e+1.8*bc*q)/(log(e+1.8*bc*q)+c1*q*q) +
(1.-f)*log(e+1.8*bc*q)/(log(e+1.8*bc*q)+c2*q*q);
// Equation 15
y=(1.+ze)/(1.+zd);
g=y*(-6.*sqrt(1.+y)+(2.+3.*y)*log((sqrt(1.+y)+1.)/(sqrt(1.+y)-1.)));
// Equation 14
ab=g*2.07*rke*s/pow(1.+rd,0.75);
// Equation 23
bn=8.41*pow(om_mhsq,0.435);
// Equation 22
ss=s/pow(1.+pow(bn/rk/s,3.),1./3.);
// Equation 24
bb=0.5+(om_b/om_m) + (3.-2.*om_b/om_m)*sqrt(pow(17.2*om_mhsq,2.)+1.);
// Equations 19 & 21
tb=log(e+1.8*q)/(log(e+1.8*q)+c1*q*q)/(1+pow(rk*s/5.2,2.));
tb=(tb+ab*exp(-pow(rk/rks,1.4))/(1.+pow(bb/rk/s,3.)))*sin(rk*ss)/rk/ss;
// Equation 8
tk_eh=(om_b/om_m)*tb+(1.-om_b/om_m)*tc;
return tk_eh;
}

70
c_tools/hod/transfnc.c Normal file
View file

@ -0,0 +1,70 @@
/* PROGRAM TRANSFERFUNCTION
--- transfnc(xk)
--- compute the transfer function T(k) of the power spectrum
--- T(k) defined as P(k) = k^{xindx}*T^{2}(k)
* itrans=type of transfer function
0 -> no change (returns 1)
4 -> Efstathiou, Bond & White transfer function with Gamma as
specified (eqn. 7)
5 -> Eisnstein & Hu
11 -> read in TF from file (usually CMBFAST)
NOTE: xk is in h/Mpc and is defined as k=2pi/lambda (not k=1/lambda)
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "header.h"
/* EBW CDM parameters */
#define aa 6.4
#define bb 3.0
#define cc 1.7
#define xnu 1.13
#define twopi 6.283185
#define xnuinv -0.884956
double transfnc(double xk)
{
double transf;
double q,t1,t2;
if(xk==0.)
{
transf=1.;
return (double)transf;
}
switch(ITRANS)
{
case 0:
transf=1.;
break;
case 4:
q = xk/GAMMA;
t1=aa*q+pow((bb*q),1.5)+(cc*q)*(cc*q);
t2=pow(t1,xnu);
transf=pow((1.+t2),xnuinv);
break;
case 5:
transf = tf_eisenstein_hu(xk);
break;
case 11:
transf = transfunc_file(xk);
break;
default:
fprintf(stderr,"transfnc> Unrecognized transfer function %d \n",ITRANS);
exit(-1);
break;
}
return (double)transf;
}

View file

@ -0,0 +1,59 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This routine reads in a transfer function from a file.
* - col 1 = k [h/Mpc]
* - col 2 = T(k)
* other columns not used.
*
* The TF is considered to be un-normalized, and will normalize all values
* by the entry in the first line.
*
* The TF is stored in arrays an spline interpolation is used at all k values.
* The interpolation is in log(k)/log(TF) to preserve the power-law dependence
* of T(k) on k outside the k-range of the file.
*/
double transfunc_file(double xk)
{
static double *x,*y,*y2;
static int flag=1,n;
int i;
double t,x0;
FILE *fp;
char a[1000];
float x1,x2;
if(flag)
{
flag=0;
fp=openfile(Files.TF_file);
n=filesize(fp);
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
for(i=1;i<=n;++i)
{
fscanf(fp,"%f %f",&x1,&x2);
x[i]=x1;
y[i]=x2;
if(i==1)x0=y[i];
fgets(a,1000,fp);
y[i]/=x0;
x[i]=log(x[i]);
y[i]=log(y[i]);
}
fclose(fp);
spline(x,y,n,1.0E+30,1.0E+30,y2);
}
xk=log(xk);
splint(x,y,y2,n,xk,&t);
return(exp(t));
}

89
c_tools/hod/trapzd.c Normal file
View file

@ -0,0 +1,89 @@
#define FUNC(x) ((*func)(x))
double trapzd(double (*func)(double), double a, double b, int n)
{
double x,tnm,sum,del;
static double s;
int it,j;
if (n == 1) {
return (s=0.5*(b-a)*(FUNC(a)+FUNC(b)));
} else {
for (it=1,j=1;j<n-1;j++) it <<= 1;
tnm=it;
del=(b-a)/tnm;
x=a+0.5*del;
for (sum=0.0,j=1;j<=it;j++,x+=del) sum += FUNC(x);
s=0.5*(s+(b-a)*sum/tnm);
return s;
}
}
#undef FUNC
#define FUNC(x) ((*func)(x))
double trapzd2(double (*func)(double), double a, double b, int n)
{
double x,tnm,sum,del;
static double s;
int it,j;
if (n == 1) {
return (s=0.5*(b-a)*(FUNC(a)+FUNC(b)));
} else {
for (it=1,j=1;j<n-1;j++) it <<= 1;
tnm=it;
del=(b-a)/tnm;
x=a+0.5*del;
for (sum=0.0,j=1;j<=it;j++,x+=del) sum += FUNC(x);
s=0.5*(s+(b-a)*sum/tnm);
return s;
}
}
#undef FUNC
#define FUNC(x) ((*func)(x))
double trapzd3(double (*func)(double), double a, double b, int n)
{
double x,tnm,sum,del;
static double s;
int it,j;
if (n == 1) {
return (s=0.5*(b-a)*(FUNC(a)+FUNC(b)));
} else {
for (it=1,j=1;j<n-1;j++) it <<= 1;
tnm=it;
del=(b-a)/tnm;
x=a+0.5*del;
for (sum=0.0,j=1;j<=it;j++,x+=del) sum += FUNC(x);
s=0.5*(s+(b-a)*sum/tnm);
return s;
}
}
#undef FUNC
#define FUNC(x) ((*func)(x))
double trapzd4(double (*func)(double), double a, double b, int n)
{
double x,tnm,sum,del;
static double s;
int it,j;
if (n == 1) {
return (s=0.5*(b-a)*(FUNC(a)+FUNC(b)));
} else {
for (it=1,j=1;j<n-1;j++) it <<= 1;
tnm=it;
del=(b-a)/tnm;
x=a+0.5*del;
for (sum=0.0,j=1;j<=it;j++,x+=del) sum += FUNC(x);
s=0.5*(s+(b-a)*sum/tnm);
return s;
}
}
#undef FUNC

View file

@ -0,0 +1,511 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "header.h"
/* This is the two-halo term of the correlation function in both real space.
* This is solved in Fourier space and requires the
* non-linear power spectrum P_nl(k), which is from the model of Smith et al.
* (see Smith et al, astro-ph/0207664).
*
* For specifics see Berlind & Weinberg (2002), Zheng (2003), Tinker et al (2005)
*
*/
/* Internal functions.
*/
double func2(double m);
double func2_cen(double m);
double func2_sat(double m);
double func5(double xk);
double func_mlimit(double m);
void calc_real_space_two_halo(double *r, double *xi, int *n);
double HOD2_two_halo_real_space(double r);
/* the restricted number density.
*/
double NG_MINUS2;
/* Globals needed for the qromo functions.
*/
double r_g1,
k1;
/* Global checkflag to stop doing the restricted
* number density.
*/
int checkflag;
/* This tabulates the two-halo real-space term for future
* spline interpolation.
*/
double two_halo_real_space(double r)
{
static int flag=0,n=45;
static double *x,*y,*y2;
int i;
double max=16,min=9,a,rvir_min;
float x1,x2;
FILE *fp;
// if(r<25)
// return(nbody_two_halo(r));
if(!flag || RESET_FLAG_2H)
{
if(!LINEAR_PSP)
nonlinear_sigmac(8.0);
n=30;
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
RESET_FLAG_2H=0;
flag=1;
if(OUTPUT>1)
fprintf(stdout,"Calculating real-space two-halo term...\n");
calc_real_space_two_halo(x,y,&n);
if(!HOD.color==2)
check_for_smoothness(x,y,n,1.5);
XI_MAX_RADIUS=x[n];
if(XCORR)
for(i=1;i<=n;++i)
{
a = HOD2_two_halo_real_space(x[i]);
y[i] = a*y[i];
if(y[i]<0)y[i]=-1;
else y[i] = sqrt(y[i]);
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
}
if(r<R_MIN_2HALO)return(-1);
if(r>XI_MAX_RADIUS)return(-1);
splint(x,y,y2,n,r,&a);
/* This check is against the spline interpolation, which
* sometimes has (smoothness) problems with the sharp truncation of xi_2h
* at small separations.
*/
if(a<-1)return(-1);
return(a);
}
void calc_real_space_two_halo(double *r, double *xi, int *nn)
{
double xtemp[200],rtemp[200];
double mlimit,s2,rlo,rhi=90,dr,klo,tolerance=1.0e-7,s1;
int i,j,imin=0,n;
double t0,t1,t2,t1s=0,t2s=0;
n=*nn;
/* Set the minimum separation of two-halo pairs.
*/
if(HOD.color)
{
while(N_avg(HOD.M_low)<0.001)
HOD.M_low*=1.01;
}
rlo = 2.2*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
if(EXCLUSION==3)
rlo = rlo/1.3;
if(EXCLUSION==4)
rlo = rlo/2.1;
R_MIN_2HALO = rlo;
rlo = log(rlo);
dr=(log(rhi)-rlo)/(n-1);
checkflag=0;
for(i=1;i<=n;++i)
{
r_g1=r[i]=exp(rlo+dr*(i-1));
if(r_g1>30)
{
GALAXY_BIAS = qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
xi[i]=xi_interp(r_g1)*GALAXY_BIAS*GALAXY_BIAS;
continue;
}
/* Fourier transform. If BOX_SIZE specified, then truncate
* transform at that k. If no box, take integral to k=0.
*/
klo = 0;
if(BOX_SIZE)klo=1/BOX_SIZE;
j=16;
s1 = qromo(func5,klo,j*TWOPI/r_g1,midpnt);
s2 = s1;
klo = j*TWOPI/r_g1;
while(fabs(s1)>tolerance*s2) {
j+=16;
s1 = qromo(func5,klo,j*TWOPI/r_g1,midpnt);
s2 += s1;
klo = j*TWOPI/r_g1;
}
/* Divide the integral by the restricted number density.
* (This is calculated in the pk_gg_2h function.)
*/
s2=s2/NG_MINUS2;
/* Correction factor b/c we haven't been
* including all halos.
*/
xi[i]=(NG_MINUS2/GALAXY_DENSITY/GALAXY_DENSITY)*(1+s2)-1;
if(isnan(xi[i]))xi[i]=-1;
if(xi[i]==-1)imin=i;
if(OUTPUT>1)
printf("calc_2halo> %f %f %d\n",r[i],xi[i],checkflag);
//printf("calc_2halo> %f %f %d\n",r[i],xi[i],checkflag);
}
/* Eliminate all entries which have xi=-1
* (to eliminate a "wavy" spline fit at small r
*/
for(j=0,i=imin+1;i<=n;++i)
{
j++;
xtemp[j]=xi[i];
rtemp[j]=r[i];
}
n=j;
for(i=1;i<=n;++i)
{
r[i]=rtemp[i];
xi[i]=xtemp[i];
}
*nn=n;
R_MIN_2HALO=r[1];
/*printf("calc_2halo> %d %d %f\n",imin,n,r[1]);*/
}
/* This calculates and tabulates the galaxy power spectrum. This is done
* by taking the galaxy-number-weighted halo bias (with scale-dependent
* halo bias and extended structure of halos taken into account) and multiplying
* it by the non-linear matter power spectrum.
*
* The galaxy-number-weighted average is an integral over the halo mass function
* (see Equations B10 & B12 in Appendix B of Tinker et al.) over all allowed halo
* pairs.
*
* The allowed number of halo pairs is controlled by the type of halo exclusion used:
* EXCLUSION = 1 --> only halos with Rvir < r/2
* EXCLUSION = 2 --> only halo PAIRS with R1+R2 < r ("spherical eclusion")
* EXCLUSION = 3 --> same as 3
* EXCLUSION = 4 --> only halos with Rvir < r
*
* 1 and 4 are fast b/c the integral is separable, calculated once and squared. Can drastically
* underestimate the number of small-sep pairs.
*
* for 2/3, I've incorporated the approximation in Tinker etal 2005 called the n_g-matched
* method, where instead of actually doing the double integral over halo_mass_1 and halo_mass_2,
* i calculate the number density of that type of exclusion, and calculate the effective
* radius for the 1/4-type exlcusion-- ie, halos with Rvir < [x]*r where 0.5<[x]<1.0.
*/
double psp_gg_2h(double k, double r)
{
static double rp=-1,*x,*y,*y2;
static int flag=0;
int n=60,i;
double a,dk,klo=-3,khi=3,xk,s1,s2,mhi,mlo,mhi1,mlo1;
double t1,t0,ttot1,ttot2;
/* The fourier transform is done at each r, so tabulate the power spectrum
* at all k for a given r. If r has changed, re-tabulate.
*/
if(rp!=r)
{
mlo=HOD.M_low;
if(!flag)
{
flag=1;
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
dk=(khi-klo)/n;
switch(EXCLUSION) {
case 1:
mhi=4./3.*DELTA_HALO*RHO_CRIT*PI*r*r*r*OMEGA_M*0.125;
if(mhi>HOD.M_max)mhi=HOD.M_max;
NG_MINUS2 = qromo(func_galaxy_density,log(mlo),log(mhi),midpnt);
NG_MINUS2*=NG_MINUS2;
for(i=n;i>=1;--i)
{
xk=pow(10.0,klo+dk*i);
k1=xk;
if(nfw_transform(xk,mhi)<0.999)
a=qromo(func2,log(mlo),log(mhi),midpnt);
x[i]=log(xk);
if(LINEAR_PSP)
y[i]=log(linear_power_spectrum(xk)*a*a);
else
y[i]=log(nonlinear_power_spectrum(xk)*a*a);
}
break;
case 2:
case 3:
if(!checkflag)
s2=restricted_number_density(r);
else
s2=GALAXY_DENSITY;
mhi=4./3.*DELTA_HALO*RHO_CRIT*PI*r*r*r*OMEGA_M*0.125;
if(s2>=GALAXY_DENSITY || mhi>HOD.M_max)
{
s2=GALAXY_DENSITY;
mhi=log(HOD.M_max);
checkflag=1;
}
else
{
mhi=0;
NG_MINUS2=s2;
if(N_avg(HOD.M_low*1.001)>0)
{
if(qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_low*1.0001),midpnt)
>NG_MINUS2)mhi=log(HOD.M_low*1.0001);
}
if(qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max*4.0),midpnt)
<NG_MINUS2)mhi=log(HOD.M_max);
if(!mhi)
mhi=zbrent(func_mlimit,log(HOD.M_low*1.0001),log(HOD.M_max*4.0),1.0E-4);
if(mhi>log(HOD.M_max))mhi=log(HOD.M_max);
}
NG_MINUS2=s2*s2;
for(i=n;i>=1;--i)
{
xk=pow(10.0,klo+dk*i);
k1=xk;
if(nfw_transform(xk,exp(mhi))<0.999) {
if(HOD.pdfc==7)/* || HOD.pdfc==6 || HOD.pdfc==9 || HOD.pdfc==8)*/
{
a = qromo(func2_cen,log(HOD.M_low),log(HOD.M_cen_max),midpnt);
a += qromo(func2_sat,log(HOD.M_low),log(HOD.M_max),midpnt);
}
else {
MAG_21_CHECK:
a=qromo(func2,log(mlo),mhi,midpnt);
}
}
x[i]=log(xk);
if(LINEAR_PSP)
y[i]=log(linear_power_spectrum(xk)*a*a);
else
y[i]=log(nonlinear_power_spectrum(xk)*a*a);
}
break;
case 4: // where max halo mass is M(R=r) rather than M(R=r/2)
mhi=4./3.*DELTA_HALO*RHO_CRIT*PI*r*r*r*OMEGA_M;
if(mhi>HOD.M_max)mhi=HOD.M_max;
NG_MINUS2 = qromo(func_galaxy_density,log(mlo),log(mhi),midpnt);
NG_MINUS2*=NG_MINUS2;
for(i=n;i>=1;--i)
{
xk=pow(10.0,klo+dk*i);
k1=xk;
if(nfw_transform(xk,mhi)<0.999)
a=qromo(func2,log(mlo),log(mhi),midpnt);
x[i]=log(xk);
if(LINEAR_PSP)
y[i]=log(linear_power_spectrum(xk)*a*a);
else
y[i]=log(nonlinear_power_spectrum(xk)*a*a);
}
break;
default:
endrun("Error: invalid choice of EXCLUSION");
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
rp=r;
}
k=log(k);
splint(x,y,y2,n,k,&a);
return(exp(a));
}
/* The routine called by qromo for the integral in Zheng's Eq [7]
*/
double func2(double m)
{
double n,N,b,yg,x,Ncen,Nsat;
m=exp(m);
n=dndM_interp(m);
b=bias_interp(m,r_g1);
Ncen=N_cen(m);
Nsat=N_sat(m);
yg=nfw_transform(k1,m);
x = n*(Ncen + Nsat*yg)*b*m;
return(x);
}
/* The routine called by qromo for the integral in Zheng's Eq [7]
* FOR CENTRAL GALAXIES ONLY: This means no Fourier transform of NFW profile.
*/
double func2_cen(double m)
{
double n,N,b,yg,x;
m=exp(m);
n=dndM_interp(m);
b=bias_interp(m,r_g1);
N=N_cen(m);
x=n*N*b*m;
return(x);
}
/* The routine called by qromo for the integral in Zheng's Eq [7]
* FOR SATELLITE GALAXIES ONLY.
*/
double func2_sat(double m)
{
double n,N,b,yg,x;
m=exp(m);
n=dndM_interp(m);
b=bias_interp(m,r_g1);
N=N_sat(m);
yg=nfw_transform(k1,m);
x=n*N*b*yg*m;
return(x);
}
/* This is the integrand of the Fourier transform
* of the two-halo power spectrum to correlation function
*/
double func5(double xk)
{
double psp1;
double xk1,xk2,x3;
if(xk==0)return(0);
psp1=psp_gg_2h(xk,r_g1);
xk1=r_g1*xk;
psp1*=sin(xk1)/xk1/xk;
return(psp1);
}
/* This is the function sent to zbrent to calculate the halo mass
* which gives the matched restricted number density.
*/
double func_mlimit(double m)
{
double s1;
if(N_avg(exp(m))>0)
s1=qromo(func_galaxy_density,log(HOD.M_low),m,midpnt);
else
s1=0;
return(s1-NG_MINUS2);
}
/* This tabulates the two-halo real-space term
* for the second HOD function for future
* spline interpolation.
*/
double HOD2_two_halo_real_space(double r)
{
static int flag=0,n=45;
static double *x,*y,*y2;
int i;
double max=16,min=9,a,rvir_min,galtemp;
float x1,x2;
FILE *fp;
if(!flag || RESET_FLAG_2H)
{
/* Switch HODs temporarily
*/
HODt.M_min = HOD.M_min;
HODt.M_low = HOD.M_low;
HODt.M1 = HOD.M1;
HODt.alpha = HOD.alpha;
HODt.M_cen_max = HOD.M_cen_max;
HODt.sigma_logM = HOD.sigma_logM;
HODt.M_max = HOD.M_max;
HODt.pdfc = HOD.pdfc;
HODt.pdfs = HOD.pdfs;
galtemp = GALAXY_DENSITY;
HOD.M_min = HOD2.M_min;
HOD.M_low = HOD2.M_low;
HOD.M1 = HOD2.M1;
HOD.alpha = HOD2.alpha;
HOD.M_cen_max = HOD2.M_cen_max;
HOD.sigma_logM = HOD2.sigma_logM;
HOD.M_max = HOD2.M_max;
HOD.pdfc = HOD2.pdfc;
HOD.pdfs = HOD2.pdfs;
GALAXY_DENSITY = GALAXY_DENSITY2;
set_HOD_params();
if(!LINEAR_PSP)
nonlinear_sigmac(8.0);
n=30;
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
RESET_FLAG_2H=0;
flag=1;
if(OUTPUT)
fprintf(stdout,"Calculating HOD2 real-space two-halo term...\n");
calc_real_space_two_halo(x,y,&n);
check_for_smoothness(x,y,n,1.5);
XI_MAX_RADIUS=x[n];
spline(x,y,n,2.0E+30,2.0E+30,y2);
/* Switch HODs back
*/
HOD.M_min = HODt.M_min;
HOD.M_low = HODt.M_low;
HOD.M1 = HODt.M1;
HOD.alpha = HODt.alpha;
HOD.M_cen_max = HODt.M_cen_max;
HOD.sigma_logM = HODt.sigma_logM;
HOD.M_max = HODt.M_max;
HOD.pdfc = HODt.pdfc;
HOD.pdfs = HODt.pdfs;
GALAXY_DENSITY = galtemp;
set_HOD_params();
}
if(r>XI_MAX_RADIUS)return(-1);
if(r<R_MIN_2HALO)return(-1);
splint(x,y,y2,n,r,&a);
/* This check is against the spline interpolation, which
* sometimes has (smoothness) problems with the sharp truncation of xi_2h
* at small separations.
*/
if(a<-1)return(-1);
return(a);
}

142
c_tools/hod/utility.c Normal file
View file

@ -0,0 +1,142 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "header.h"
#ifdef PARALLEL
#include <mpi.h>
#endif
#define NR_END 1
#define FREE_ARG char*
/* returns the number of cpu-ticks in seconds that
* have elapsed. (or the wall-clock time)
*/
double second(void)
{
return ((double)((unsigned int)clock()))/CLOCKS_PER_SEC;
/* note: on AIX and presumably many other 32bit systems,
* clock() has only a resolution of 10ms=0.01sec
*/
}
/* returns the time difference between two measurements
* obtained with second(). The routine takes care of the
* possible overflow of the tick counter on 32bit systems.
*/
double timediff(double t0,double t1)
{
double dt;
dt=t1-t0;
if(dt<0) /* overflow has occured */
{
dt=t1 + pow(2,32)/CLOCKS_PER_SEC - t0;
}
return dt;
}
void endrun(char *instring)
{
fprintf(stderr,"endrun> %s\n",instring);
fflush(stderr);
/*
fprintf(stdout,"endrun> %s\n",instring);
fflush(stdout);
*/
#ifdef PARALLEL
MPI_Abort(MPI_COMM_WORLD, 0);
#endif
exit(0);
}
/* This takes a file and reads the number of lines in it,
* rewinds the file and returns the lines.
*/
int filesize(FILE *fp)
{
int i=-1;
char a[1000];
while(!feof(fp))
{
i++;
fgets(a,1000,fp);
}
rewind(fp);
return(i);
}
/* This opens a file and has an error trap
* if the file does not exist.
*/
FILE *openfile(char *ff)
{
FILE *fp;
if(!(fp=fopen(ff,"r")))
{
fprintf(stderr,"ERROR opening [%s]\n",ff);
exit(0);
}
return(fp);
}
/* This is for allocating a 3-dimensional array of doubles, adapted from
* the numerical recipes f3tensor routine.
*/
double ***d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
/* allocate a double 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */
{
long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
double ***t;
/* allocate pointers to pointers to rows */
t=(double ***) malloc((size_t)((nrow+NR_END)*sizeof(double**)));
if (!t) nrerror("allocation failure 1 in f3tensor()");
t += NR_END;
t -= nrl;
/* allocate pointers to rows and set pointers to them */
t[nrl]=(double **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double*)));
if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()");
t[nrl] += NR_END;
t[nrl] -= ncl;
/* allocate rows and set pointers to them */
t[nrl][ncl]=(double *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(double)));
if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()");
t[nrl][ncl] += NR_END;
t[nrl][ncl] -= ndl;
for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
for(i=nrl+1;i<=nrh;i++) {
t[i]=t[i-1]+ncol;
t[i][ncl]=t[i-1][ncl]+ncol*ndep;
for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
}
/* return pointer to array of pointers to rows */
return t;
}
/* Free the memory allocated by d3tensor (see above)
*/
void free_d3tensor(double ***t, long nrl, long nrh, long ncl, long nch,
long ndl, long ndh)
{
free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END));
free((FREE_ARG) (t[nrl]+ncl-NR_END));
free((FREE_ARG) (t+nrl-NR_END));
}

View file

@ -0,0 +1,745 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#ifdef PARALLEL
#include <mpi.h>
#endif
#include "header.h"
/* This is a series of routines to calculate the projected correlation
* function from the real-space one (HOD calculation) and then chi2
* minimize the parameters based on the SDSS data.
*/
int FIT_WITH_COSMO = 0,
FIRST_CALL = 0;
double rp_g1;
double func_wp(double z);
double func_wp_rspace(double z);
double func_wp_matter(double z);
double chi2_wp(double *a);
void wp_input(void);
void initial_wp_values(double *a, double **pp, double *yy);
/* This integrates the calculated real-space correlation function
* along the line-of-sight to get the projected correlation function (wp(rp).
* The value passed if the projected separation.
*
* In most SDSS work, the maximum line of sight separation considered when
* claculating wp is pi=40 Mpc/h, which is the default, but can be set
* in the parameter file if desired.
*
* NB! - note that this routine uses a correction for redshift space distortions.
*/
double projected_xi(double r)
{
double x,zmax;
rp_g1=r*r;
two_halo_real_space(1.0);
zmax=sqrt(XI_MAX_RADIUS*XI_MAX_RADIUS-rp_g1);
if(zmax>wp.pi_max)zmax=wp.pi_max;
zmax = wp.pi_max;
x=2*qromo(func_wp,log(0.001),log(zmax),midpnt);
return(x);
}
/* Same as above, but it projects the real-space correlation function
* directly, with no correction for redshift-space effects.
*/
double projected_xi_rspace(double r)
{
double x,zmax;
rp_g1=r*r;
two_halo_real_space(1.0);
zmax=sqrt(XI_MAX_RADIUS*XI_MAX_RADIUS-rp_g1);
if(zmax>wp.pi_max)zmax=wp.pi_max;
zmax = wp.pi_max;
x=2*qromo(func_wp_rspace,log(0.001),log(zmax),midpnt);
return(x);
}
/* Same as above but for matter.
* I've set the maximum line-of-sight separation to be 50 Mpc/h,
* which should be good for visual comparison purposes.
*/
double projected_xi_matter(double r)
{
double x,zmax;
rp_g1=r*r;
zmax=50.0;
x=2*qtrap(func_wp_matter,log(0.001),log(zmax),1.0E-3);
return(x);
}
/* Function called from qromo/qtrap to get xi->wp
* Note that the two-halo term has the linear Kaiser distortion correction.
*/
double func_wp(double z)
{
double r;
z=exp(z);
r=sqrt(rp_g1 + z*z);
return(z*(one_halo_real_space(r)+linear_kaiser_distortion(r,z)));
}
/* Function called from qromo/qtrap to get xi->wpm but without
* correction for redshift-space distortions in the two-halo term
*/
double func_wp_rspace(double z)
{
double r;
z=exp(z);
r=sqrt(rp_g1 + z*z);
return(z*(one_halo_real_space(r)+two_halo_real_space(r)));
}
/* Function called from qromo/qtrap to get xi->wp (dark matter)
*/
double func_wp_matter(double z)
{
double r;
z=exp(z);
r=sqrt(rp_g1 + z*z);
return(z*(xi_interp(r)));
}
/********************************************************************
* Below is the actual minimization of the wp data.
* Relevant variables: [default]
*
* COVAR -> [1]=use covariance matrixl; 0=diagonal error bars
* DEPROJECTED -> [1]=we're fitting a real-space xi(r) [0]= fitting wp(rp)
*
* HOD.free[] is a vector which holds 1/0 as to whether or not a parameter is going
* to be help constant during the chi^2 minimization. 1==vary 0==constant. The default
* on any will be [0].
*
* i variable
* --- --------
* [1] -> M_min
* [2] -> M1
* [3] -> alpha
* [4] -> M_cut
* [5] -> sigmaM
* [6] -> CVIR_FAC
* [7] -> MaxCen (M_cen_max)
*
* Currently I have no checks on whether the values of this vector line
* up correctly with the specific HOD pdfs, so double-check hod.bat files.
*
* Once the code is finished, it will output the values of the HOD parameters
* to a file called [filename].fit (+ the bias, satellite fraction, and chi^2).
* Then it outputs the mean <N>_M to a file called [filename].HOD.
* Then it will go through all the TASKS asked for in the hod.bat file.
*/
void wp_minimization(char *fname)
{
int n,niter,i,j;
double *a,**pp,*yy,FTOL=1.0E-3,chi2min,s1,dlogm,m;
FILE *fp;
char aa[1000];
fprintf(stderr,"\n\nCHI2 MINIMIZATION OF W_P(R_P) DATA..........\n");
fprintf(stderr, "--------------------------------------------\n\n");
OUTPUT = 0;
FIRST_CALL = 1;
if(POWELL)
FTOL=1.0E-3;
else
FTOL=1.0E-4;
for(n=0,i=1;i<=N_HOD_PARAMS;++i)
{
n+=HOD.free[i];
if(!OUTPUT)continue;
printf("wp_min> free[%i] = %d\n",i,HOD.free[i]);
}
if(XCORR)n*=2;
if(OUTPUT)printf("wp_min> Number of free parameters: %d\n",n);
printf("FNAME %s\n",Task.root_filename);
wp_input();
wp.ncf=n;
a=dvector(1,n);
if(POWELL)
pp=dmatrix(1,n,1,n);
else
pp=dmatrix(1,n+1,1,n);
yy=dvector(1,n+1);
initial_wp_values(a,pp,yy);
printf("IVALS %e %e %e %e\n",a[1],a[2],a[3],a[4]);
if(POWELL)
{
if(OUTPUT)printf("wp_min> starting powell.\n");
powell(a,pp,n,FTOL,&niter,&chi2min,chi2_wp);
chi2min = chi2_wp(a);
}
else
{
if(OUTPUT)printf("wp_min> starting amoeba.\n");
amoeba(pp,yy,n,FTOL,chi2_wp,&niter);
for(i=1;i<=n;++i)a[i]=pp[1][i];
chi2min = chi2_wp(a);
}
s1=qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt);
GALAXY_BIAS=s1/GALAXY_DENSITY;
printf("POWELL %e %e ",chi2min,HOD.M_min);
for(i=1;i<=n;++i)printf("%e ",a[i]);
printf(" %f\n",GALAXY_BIAS);
/* These outputs are for easy cut & paste into
* another batch file.
*/
//output_parameter_file(fname);
/* Output the fit and the HOD curve.
*/
printf("FNAME2 %s\n",Task.root_filename);
sprintf(aa,"%s.fit",Task.root_filename);
fp=fopen(aa,"w");
fprintf(fp,"%e %e ",chi2min,HOD.M_min);
for(i=1;i<=n;++i)fprintf(fp,"%e ",a[i]);
fprintf(fp," %f\n",GALAXY_BIAS);
fclose(fp);
sprintf(aa,"%s.HOD",Task.root_filename);
fp=fopen(aa,"w");
dlogm=(log(HOD.M_max)-log(HOD.M_low))/99;
for(i=1;i<=100;++i)
{
m=exp((i-1)*dlogm)*HOD.M_low;
fprintf(fp,"%e %e %e %e\n",m,N_cen(m),N_sat(m),N_avg(m));
}
fclose(fp);
fprintf(stderr,"here\n");
free_dvector(a,1,n);
if(POWELL)
free_dmatrix(pp,1,n,1,n);
else
free_dmatrix(pp,1,n+1,1,n);
free_dvector(yy,1,n+1);
fprintf(stderr,"here\n");
free_dvector(wp.r,1,wp.np);
free_dvector(wp.x,1,wp.np);
free_dvector(wp.e,1,wp.np);
if(COVAR)
free_dmatrix(wp.covar,1,wp.np,1,wp.np);
fprintf(stderr,"done in wp_min\n");
}
double integrated_wp_bin(double r)
{
return(projected_xi(r)*r);
}
double integrated_xi_bin(double r)
{
//return((1+one_halo_real_space(r))*r*r);
return((one_halo_real_space(r)+two_halo_real_space(r))*r*r);
}
double chi2_wp(double *a)
{
static int flag=1,niter=0,ichi=-1;
static double *x,mmin_prev=0,t0=-1,t1,sig_prev=0,chi2_prev,chi2_array[10];
double **tmp,**tmp2,chi2,x1,ta1,ta2,dt1h,dt2h,par_chi,chi2ngal;
int i,j,k,ncf_hod;
double rlo,rhi,rmin,rmax,dlogr,integrated_wp_bin();
if(FIRST_CALL)
{
flag = 1;
FIRST_CALL = 0;
}
t0 = clock();
if(HOD.free[1])FIX_PARAM = 0;
wp.iter=niter;
for(j=0,i=1;i<=N_HOD_PARAMS;++i)
if(HOD.free[i])
if(a[++j]<=0) { printf("%d %e\n",j,a[j]); return(1.0E7); }
ncf_hod = j;
RESET_FLAG_1H=1;
RESET_FLAG_2H=1;
RESET_KAISER++;
i=0;j=0;
if(HOD.free[++i])HOD.M_min=a[++j];
if(HOD.free[++i])HOD.M1=a[++j];
if(HOD.free[++i])HOD.alpha=a[++j];
if(HOD.free[++i])HOD.M_cut=a[++j];
if(HOD.free[++i])HOD.sigma_logM=a[++j];
if(HOD.pdfc!=9) {
if(HOD.free[++i])CVIR_FAC=a[++j];
if(HOD.pdfc>=7) {
if(HOD.free[++i])HOD.M_cen_max=a[++j]; }
else {
if(HOD.free[++i])HOD.MaxCen=a[++j]; }
}
if(HOD.free[++i])HOD.M_sat_break=a[++j];
if(HOD.free[++i])HOD.alpha1=a[++j];
if(XCORR) {
i=0;
if(HOD.free[++i])HOD2.M_min=a[++j];
if(HOD.free[++i])HOD2.M1=a[++j];
if(HOD.free[++i])HOD2.alpha=a[++j];
if(HOD.free[++i])HOD2.M_cut=a[++j];
if(HOD.free[++i])HOD2.sigma_logM=a[++j];
if(HOD2.pdfc!=9) {
if(HOD.free[++i])CVIR_FAC=a[++j];
if(HOD2.pdfc>=7) {
if(HOD2.free[++i])HOD2.M_cen_max=a[++j]; }
else {
if(HOD2.free[++i])HOD2.MaxCen=a[++j]; }
}
}
if(!ThisTask) {
printf("START %d ",niter);
for(i=1;i<=ncf_hod;++i)printf("%e ",a[i]);
printf("\n");
}
if(HOD.pdfs==2 && HOD.M_cut<1.0e7)return(1.0e7);
if(HOD.pdfs==2 && HOD.M_cut>1.0e15)return(1.0e7);
/* if(HOD.M_min>HOD.M_max)return(1.0e7); */
/* I've noticed some problems when sigma_logM gets to be
* unresonably high or low, so I've put some limits on the
* values they can have when doing mag-bin fitting.
*/
if(HOD.pdfc==6) {
if(HOD.sigma_logM<0.07)return(1.0e7);
if(HOD.sigma_logM>1.2)return(1.0e7);
}
if(HOD.pdfc==2 || HOD.pdfc==9) {
if(HOD.sigma_logM>1.8)return(1.0e7);
if(HOD.sigma_logM<0.05)return(1.0e7);
}
if(HOD.M1>1.0e17)return(1.0e7);
if(FIX_PARAM==2)
{
HOD.M1=HOD.M_low;
x1=qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt);
if(x1<GALAXY_DENSITY)return(1.0e7);
HOD.M1=pow(10.0,14.8);
x1=qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt);
if(x1>GALAXY_DENSITY)return(1.0e7);
HOD.M1=0;
}
/* Check the make sure these are reasonable parameters
* (Assuming that M_min is NOT a FREE parameter but is
* calculated from the GALAXY_DENSITY.)
*/
if(FIX_PARAM==1 && !HOD.color)
{
HOD.M_min=pow(10.0,8.0);
HOD.M_low=set_low_mass();
if(HOD.M_low<1.0e8)HOD.M_low=1.0e8;
x1=qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt);
// fprintf(stderr,"PC1 %e %e\n",x1,GALAXY_DENSITY);
if(x1<GALAXY_DENSITY) {
fprintf(stdout,"PCHECK %e %e %e\n",x1,GALAXY_DENSITY,HOD.M_low);
return(1.0e7); }
HOD.M_min=pow(10.0,14.8);
if(HOD.pdfc==7 && HOD.pdfc==8)
HOD.M_min=HOD.M_cen_max*0.99;
HOD.M_low=set_low_mass();
x1=qromo(func_galaxy_density,log(HOD.M_low),log(HOD.M_max),midpnt);
/* fprintf(stderr,"PC2 %e %e %e %e\n",HOD.M_min,HOD.M_low,x1,GALAXY_DENSITY); */
if(x1>GALAXY_DENSITY) {
fprintf(stdout,"PCHECK %e %e\n",x1,GALAXY_DENSITY);
return(1.0e7); }
HOD.M_min=0;
}
if(ERROR_FLAG)
{
ERROR_FLAG=0;
return(1e7);
}
if(HOD.free[0] || HOD.free[1])
GALAXY_DENSITY=0;
if(!HOD.color)
set_HOD_params();
/*
if(XCORR)
set_HOD2_params();
*/
if(HOD.free[0])
{
chi2ngal = (GALAXY_DENSITY-wp.ngal)*(GALAXY_DENSITY-wp.ngal)/wp.ngal_err/wp.ngal_err;
if(chi2ngal>1.0E3)return(chi2ngal);
}
if(ERROR_FLAG)
{
ERROR_FLAG=0;
return(1e7);
}
/* if(HOD.pdfs==3 && HOD.M_cut<HOD.M_low)return(1.1e7); */
if(HOD.M_min>HOD.M1)return(1.0e7);
/* if(HOD.pdfs==3)if(HOD.M_cut<HOD.M_min*0.9)return(1.2e7); */
mmin_prev=HOD.M_min;
sig_prev=HOD.sigma_logM;
if(HOD.color>=niter)
flag = 1;
if(flag && COVAR)
{
// printf("INVERTING COVARIANCE MATRIX\n");
flag=0;
tmp=dmatrix(1,wp.np,1,1);
tmp2=dmatrix(1,wp.np,1,wp.np);
for(i=1;i<=wp.np;++i)
for(j=1;j<=wp.np;++j)
tmp2[i][j]=wp.covar[i][j];
gaussj(tmp2,wp.np,tmp,1);
for(i=1;i<=wp.np;++i)
for(j=1;j<=wp.np;++j)
wp.covar[i][j]=tmp2[i][j];
free_dmatrix(tmp,1,wp.np,1,1);
free_dmatrix(tmp2,1,wp.np,1,wp.np);
x=dvector(1,wp.np);
}
if(!COVAR)
x=dvector(1,wp.np);
rmax = wp.r[wp.np];
rmin = wp.r[1];
dlogr = (log(rmax)-log(rmin))/(wp.np-1);
BETA = pow(OMEGA_M,0.6)/qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt)*
GALAXY_DENSITY;
if(OUTPUT)
printf("BETA = %f\n",BETA);
rlo = exp(log(rmin) - 0.5*dlogr);
for(i=1;i<=wp.np;++i)
{
rhi = exp(dlogr)*rlo;
if(DEPROJECTED)
x[i]=one_halo_real_space(wp.r[i])+two_halo_real_space(wp.r[i]);
else
{
x[i]=projected_xi(wp.r[i]);
if(wp.format==3)
x[i]/=wp.r[i];
}
if(OUTPUT && !ThisTask)
printf("WP%d %f %e %e %e %e\n",niter+1,wp.r[i],wp.x[i],x[i],rlo,rhi);
rlo=rhi;
}
if(ERROR_FLAG)
{
ERROR_FLAG=0;
return(1e7);
}
chi2=0;
if(COVAR)
{
for(i=1;i<=wp.np;++i)
for(j=1;j<=wp.np;++j)
{
x1=(x[i]-wp.x[i])*(x[j]-wp.x[j])*wp.covar[i][j];
chi2+=x1;
}
}
else
{
if(!PCA)
{
for(i=1;i<=wp.np;++i)
{
x1=(x[i]-wp.x[i])*(x[i]-wp.x[i])/
(wp.e[i]*wp.e[i] + wp.esys*wp.esys*x[i]*x[i]);
chi2+=x1;
}
}
else
{
chi2=0;
for(i=1;i<=wp.npca;++i)
{
par_chi=0;
for(j=1;j<=wp.np;++j)
par_chi+=wp.covar[j][i]*(x[j]-wp.x[j])/wp.e[j];
chi2+=par_chi*par_chi/wp.eigen[i];
}
}
}
/*
* From Peder Norberg's instructions for use of PCA:
do i=1,npca
par_chi=0.d0
do j=1,npoints
par_chi=par_chi+pca(j,i)*(xi_teo(j)-xi_data(j))/err_data(j)
enddo
chi2=chi2+(par_chi**2)/ev(i) ! (****)
enddo
*/
/* Add in the error on the galaxy density
*/
if(HOD.free[0])
chi2+=chi2ngal;
t1 = clock();
t0 = difftime(t1,t0)/CLOCKS_PER_SEC;
niter++;
if(!ThisTask){
printf("ITER %7d %e ",niter,chi2);
for(i=1;i<=ncf_hod;++i)printf("%e ",a[i]);
printf(" %.2f\n",t0);
fflush(stdout);
if(HOD.free[0])
printf("NGAL %e %e %e\n",chi2ngal,
GALAXY_DENSITY,wp.ngal);
}
chi2_prev=chi2;
chi2_array[ichi]=chi2;
ichi++;
if(ichi==10)ichi=0;
fflush(stdout);
return(chi2);
}
void initial_wp_values(double *a, double **pp, double *yy)
{
static int flag=1;
int i,j;
double d[100];
if(flag) {
i=0;j=0;
if(HOD.free[++i])a[++j]=HOD.M_min;
if(HOD.free[++i])a[++j]=HOD.M1;
if(HOD.free[++i])a[++j]=HOD.alpha;
if(HOD.free[++i])a[++j]=HOD.M_cut;
if(HOD.free[++i])a[++j]=HOD.sigma_logM;
if(HOD.free[++i])a[++j]=CVIR_FAC;
if(HOD.pdfc>=7){
if(HOD.free[++i])a[++j]=HOD.M_cen_max; }
else {
if(HOD.free[++i])a[++j]=HOD.MaxCen; }
if(HOD.free[++i])a[++j]=HOD.M_sat_break;
if(HOD.free[++i])a[++j]=HOD.alpha1;
if(XCORR){
i=0;
if(HOD.free[++i])a[++j]=HOD2.M_min;
if(HOD.free[++i])a[++j]=HOD2.M1;
if(HOD.free[++i])a[++j]=HOD2.alpha;
if(HOD.free[++i])a[++j]=HOD2.M_cut;
if(HOD.free[++i])a[++j]=HOD2.sigma_logM;
if(HOD.free[++i])a[++j]=CVIR_FAC;
if(HOD2.pdfc>=7){
if(HOD.free[++i])a[++j]=HOD2.M_cen_max; }
else {
if(HOD.free[++i])a[++j]=HOD2.MaxCen; }
}
printf("INITIAL VALUES: ");
for(i=1;i<=wp.ncf;++i)printf("%e ",a[i]);
printf("\n");
}
//flag++;
/* Make the starting stepsize 10% of the initial values.
*/
for(i=1;i<=wp.ncf;++i)
d[i]=a[i]*0.25/flag;
if(POWELL)
{
for(i=1;i<=wp.ncf;++i)
{
for(j=1;j<=wp.ncf;++j)
{
pp[i][j]=0;
if(i==j)pp[i][j]+=d[j];
}
}
}
else
{
for(j=1;j<=wp.ncf;++j)
pp[1][j]=a[j];
yy[1]=chi2_wp(a);
for(i=1;i<=wp.ncf;++i)
{
a[i]+=d[i];
if(i>1)a[i-1]-=d[i-1];
yy[i+1]=chi2_wp(a);
for(j=1;j<=wp.ncf;++j)
pp[i+1][j]=a[j];
}
a[wp.ncf]-=d[wp.ncf];
}
}
/* This routine reads in the wp data and covariance matrix from
* the filenames specified.
*
* FILE FORMATS:
*
* - fname_wp -> r xi e_xi
* - fname_covar -> (i=1,np)(j=1,np) read(covar[i][j])
*
*/
void wp_input()
{
float x1,x2,x3;
FILE *fp;
int i,j,n;
char a[1000];
if(!(fp=fopen(wp.fname_wp,"r")))
{
fprintf(stdout,"ERROR opening [%s]\n",wp.fname_wp);
endrun("error in wp_input");
}
wp.np=filesize(fp);
/* [wp.format==2] means that there are two header lines at
* the top of the file.
*/
if(wp.format==2)
{
wp.np-=2;
fgets(a,1000,fp);
fgets(a,1000,fp);
}
/* [wp.format==3] means that there is one header lines at
* the top of the file.
*/
if(wp.format==3)
{
wp.np-=1;
fgets(a,1000,fp);
}
wp.r=dvector(1,wp.np);
wp.x=dvector(1,wp.np);
wp.e=dvector(1,wp.np);
if(PCA)
{
wp.eigen=dvector(1,wp.np);
wp.covar=dmatrix(1,wp.np,1,wp.np);
}
/* Read in the projected correlation function data.
* Standard format [wp.format==1] is linear r, linear wp, linear err.
* [wp.format==2] is log10 r, log10 wp, linear err.
* NB! Peder's format is to list the inner edge of the bin, so we're adding 0.1 to each number.
*/
for(i=1;i<=wp.np;++i)
{
fscanf(fp,"%f %f %f",&x1,&x2,&x3);
wp.r[i]=x1;
wp.x[i]=x2;
wp.e[i]=x3;
if(wp.format==2){
wp.r[i] = pow(10.0,wp.r[i]+0.1);
wp.x[i] = pow(10.0,wp.x[i])*wp.r[i];
wp.e[i] = wp.e[i]*wp.r[i];
}
if(wp.format==3){
fscanf(fp,"%f",&x3);
wp.e[i]=x3;
wp.r[i] = pow(10.0,wp.r[i]+0.1);
// wp.x[i] = wp.x[i]*wp.r[i];
// wp.e[i] = wp.e[i]*wp.r[i];
}
if(wp.format==3 && PCA) {
fscanf(fp,"%lf",&wp.eigen[i]);
for(j=1;j<=wp.np;++j)
fscanf(fp,"%lf",&wp.covar[j][i]);
if(wp.npca==0)
wp.npca = wp.np;
}
// if(wp.format==3 && !PCA)
fgets(a,1000,fp);
}
fclose(fp);
fprintf(stderr,"Done reading %d lines from [%s]\n",wp.np,wp.fname_wp);
if(!COVAR || PCA)
return;
/*
if(wp.format==1)
{
Work.SDSS_bins=1;
for(i=1;i<=40;++i)
Work.rad[i] = i-0.5;
}
*/
if(!(fp=fopen(wp.fname_covar,"r")))
{
fprintf(stdout,"ERROR opening [%s]\n",wp.fname_covar);
endrun("error in wp_input");
}
wp.covar=dmatrix(1,wp.np,1,wp.np);
for(i=1;i<=wp.np;++i)
for(j=1;j<=wp.np;++j)
{
fscanf(fp,"%lf",&(wp.covar[i][j]));
/* printf("COVAR %d %d %e\n",i,j,wp.covar[i][j]); */
}
fclose(fp);
if(!ThisTask)
fprintf(stdout,"Done reading %d lines from [%s]\n",wp.np,wp.fname_covar);
}

180
c_tools/hod/xi_matter.c Normal file
View file

@ -0,0 +1,180 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/* This calculates and tabulates both the linear and non-linear
* matter correlation function.
*
* If the parameter BOX_SIZE is set, then the lower limits of the
* Fourier transform in 1/BOX_SIZE, else it starts at k=0.
*
* The integral (Smith etal 2003 MNRAS.341.1311S Eq [4]) to transform:
*
* Int_0^\infty Delta(k) sin(rk)/rk/k dk
*
* This integral sometimes gives qromo problems when calculating xi(r) at large r.
* Therefore, we cut off the integral at k = 10^3, which has negligible effect on the
* correlation function at the relevent scales.
*/
double r_g4;
double xi_int(double xk);
/* Calculates and tabulates the non-linear matter correlation function.
* Since this is only really needed for the scale-dependence of the bias,
* which is basically 1 at scales r>~8 Mpc/h, I won't calculate this much
* past that value.
*/
double xi_interp(double r)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2;
int n=30,i,j;
double a,xi_int(),rhi=95,rlo=0.1,dlogr,klo,s1,s2,tolerance=1.0e-6;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dlogr = (log(rhi)-log(rlo))/(n-1);
for(i=1;i<=n;++i)
{
klo = 0;
if(BOX_SIZE>0)klo = 1/BOX_SIZE;
r_g4 = x[i] = exp((i-1)*dlogr)*rlo;
j=1;
s1 = qromo(xi_int,klo,j/r_g4,midpnt);
s2 = s1;
klo = j/r_g4;
while(mabs(s1)>tolerance*mabs(s2)) {
j+=16;
s1 = qromo(xi_int,klo,j/r_g4,midpnt);
s2 += s1;
klo = j/r_g4;
}
y[i]=s2;
}
check_for_smoothness(x,y,n,0);
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
splint(x,y,y2,n,r,&a);
return(a);
}
/* This is the integrand of Smith et al Eq. [4]
*/
double xi_int(double xk)
{
double xk1,xk2,psp;
if(xk==0)return(0);
/* power spectrum at xk
*/
psp=nonlinear_power_spectrum(xk);
/* Integrand of Fourier transform
*/
xk1=r_g4*xk;
psp*=sin(xk1)/xk1/xk;
return psp;
}
double xi_linear_interp(double r)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2;
int n=100,i;
double a,rlo=0.1,rhi=150,dlogr,klo;
double xi_linear_int();
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dlogr = (log(rhi)-log(rlo))/(n-1);
klo = 0;
if(BOX_SIZE>0)klo = 1/BOX_SIZE;
for(i=1;i<=n;++i)
{
r_g4 = x[i] = exp((i-1)*dlogr)*rlo;
y[i] = qromo(xi_linear_int,klo,1.0/r_g4,midpnt)+
qromo(xi_linear_int,1.0/r_g4,1.0E+3,midpnt);
}
check_for_smoothness(x,y,n,0);
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
splint(x,y,y2,n,r,&a);
return(a);
}
double xi_linear_int(xk)
double xk;
{
double psp;
double xk1,xk2;
/* power spectrum at xk
*/
psp=linear_power_spectrum(xk);
/* Now take Fourier transform
*/
xk1=r_g4*xk;
psp*=sin(xk1)/xk1/xk;
return psp;
}
/* Sometimes one or two of the correlation function values will
* totally crap out, [a side-effect of qromo] so here we check for that and if
* we find it then we interpolate the values in log-space.
*/
void check_for_smoothness(double *x, double *y, int n, double r)
{
int i,flag,flag2=0;
double m,b,new;
for(i=2;i<n;++i)
{
flag=0;
if(y[i]>0)flag2=1;
if(y[i]<0 && !flag2)continue;
if(x[i]<r)continue;
if(fabs(y[i]/y[i-1])>3.0 && fabs(y[i]/y[i+1])>3.0)flag=1;
if(fabs(y[i]/y[i-1])<0.2 && fabs(y[i]/y[i+1])<0.2)flag=1;
if(y[i]<0 && (y[i-1]>=0 && y[i+1]>=0))flag=1;
if(y[i+1]<0)flag=0;
if(!flag)continue;
m=(log(y[i+1])-log(y[i-1]))/(log(x[i+1])-log(x[i-1]));
b=log(y[i+1])-m*log(x[i+1]);
new=m*log(x[i])+b;
fprintf(stderr,"SMOOTHING: %e %e %e r= %f new=%e\n",y[i-1],y[i],y[i+1],x[i],exp(new));
y[i]=exp(new);
}
}

76
c_tools/hod/zbrent.c Normal file
View file

@ -0,0 +1,76 @@
#include <math.h>
#include "header.h"
#define ITMAX 100
#define EPS 3.0e-8
double zbrent(double (*func)(double), double x1,double x2, double tol)
{
int iter;
double a=x1,b=x2,c,d,e,min1,min2;
double fa=(*func)(a),fb=(*func)(b),fc,p,q,r,s,tol1,xm;
void nrerror();
if (fb*fa > 0.0)
{
printf("ERROR: Root must be bracketed in ZBRENT\n");
ERROR_FLAG=1;
return (x1+x2)/2;
}
fc=fb;
for (iter=1;iter<=ITMAX;iter++) {
if (fb*fc > 0.0) {
c=a;
fc=fa;
e=d=b-a;
}
if (fabs(fc) < fabs(fb)) {
a=b;
b=c;
c=a;
fa=fb;
fb=fc;
fc=fa;
}
tol1=2.0*EPS*fabs(b)+0.5*tol;
xm=0.5*(c-b);
if (fabs(xm) <= tol1 || fb == 0.0) return b;
if (fabs(e) >= tol1 && fabs(fa) > fabs(fb)) {
s=fb/fa;
if (a == c) {
p=2.0*xm*s;
q=1.0-s;
} else {
q=fa/fc;
r=fb/fc;
p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
q=(q-1.0)*(r-1.0)*(s-1.0);
}
if (p > 0.0) q = -q;
p=fabs(p);
min1=3.0*xm*q-fabs(tol1*q);
min2=fabs(e*q);
if (2.0*p < (min1 < min2 ? min1 : min2)) {
e=d;
d=p/q;
} else {
d=xm;
e=d;
}
} else {
d=xm;
e=d;
}
a=b;
fa=fb;
if (fabs(d) > tol1)
b += d;
else
b += (xm > 0.0 ? fabs(tol1) : -fabs(tol1));
fb=(*func)(b);
}
nrerror("Maximum number of iterations exceeded in ZBRENT");
return(0);
}
#undef ITMAX
#undef EPS

View file

@ -94,24 +94,24 @@ bool loadParticleInfo(ParticleInfo& info,
offset = info.ranges[0][0];
// TEST PMS NON-COBIC BOXES
mul = 1.0;
//mul = info.ranges[0][1] - info.ranges[0][0];
//mul = 1.0;
mul = info.ranges[0][1] - info.ranges[0][0];
f.beginCheckpoint();
for (int i = 0; i < numpart; i++)
info.particles[i].x = mul*f.readReal32();
f.endCheckpoint();
offset = info.ranges[1][0];
mul = 1.0;
//mul = info.ranges[1][1] - info.ranges[1][0];
//mul = 1.0;
mul = info.ranges[1][1] - info.ranges[1][0];
f.beginCheckpoint();
for (int i = 0; i < numpart; i++)
info.particles[i].y = mul*f.readReal32();
f.endCheckpoint();
offset = info.ranges[2][0];
mul = 1.0;
//mul = info.ranges[2][1] - info.ranges[2][0];
//mul = 1.0;
mul = info.ranges[2][1] - info.ranges[2][0];
f.beginCheckpoint();
for (int i = 0; i < numpart; i++)
info.particles[i].z = mul*f.readReal32();

View file

@ -831,7 +831,8 @@ if (args.hod or args.all) and haloFileBase != "":
sampleName = getSampleName(prefix+"hod_"+thisHod['name'], redshift, False)
tempFile = "./hod.out_"+sampleName
os.system(hodPath+" "+parFileName+">& " + tempFile)
HOD_PATH = "@CMAKE_BINARY_DIR@/c_tools/hod/hod"
os.system(HOD_PATH+" "+parFileName+">& " + tempFile)
for line in open(tempFile):
if "MLO" in line:
print " (minimum halo mass = ", line.split()[1], ")"

View file

@ -624,6 +624,9 @@ def launchStack(sample, stack, binPath, thisDataPortion=None, logDir=None,
# periodicLine += "z"
# periodicLine += "' "
launchDir = os.getcwd()
os.chdir(voidDir)
conf="""
desc %s
partzone %s
@ -690,6 +693,8 @@ def launchStack(sample, stack, binPath, thisDataPortion=None, logDir=None,
fp.write("doExtraction\n")
fp.close()
jobString = " "+runSuffix+":"
if not (continueRun and jobSuccessful(logFile, "Done!\n")):
#cmd = "%s --configFile=%s &> %s" % \
# (binPath, parmFile, logFile)
@ -701,13 +706,13 @@ def launchStack(sample, stack, binPath, thisDataPortion=None, logDir=None,
log.close()
if jobSuccessful(logFile, "Done!\n"):
print "done"
print jobString, "Stacking voids done"
else:
print "FAILED!"
print jobString, "Stacking voids FAILED!"
exit(-1)
else:
print "already done!"
print jobString, "Stacking voids already done!"
if os.access(parmFile, os.F_OK): os.unlink(parmFile)
return
@ -739,7 +744,7 @@ def launchStack(sample, stack, binPath, thisDataPortion=None, logDir=None,
os.unlink(voidDir+"/NOVOID")
if (numVoids == "0"):
print " No voids found; skipping!"
print jobString, "No voids found; skipping!"
fp = open(voidDir+"/NOVOID", "w")
fp.write("no voids found\n")
fp.close()
@ -750,7 +755,7 @@ def launchStack(sample, stack, binPath, thisDataPortion=None, logDir=None,
if "EMPTY STACK" in line:
emptyStack = True
if emptyStack:
print " Stack is empty; skipping!"
print jobString, "Stack is empty; skipping!"
fp = open(voidDir+"/NOVOID", "w")
fp.write("empty stack\n")
fp.close()
@ -817,30 +822,32 @@ def launchStack(sample, stack, binPath, thisDataPortion=None, logDir=None,
fp.write(str(normalization)+"\n")
fp.close()
os.system("mv %s %s" % ("tree.data", treeFile))
os.system("mv %s %s" % ("void_indexes.txt", voidDir+"/"))
os.system("mv %s %s" % ("posx.nc", voidDir+"/"))
os.system("mv %s %s" % ("posy.nc", voidDir+"/"))
os.system("mv %s %s" % ("posz.nc", voidDir+"/"))
os.system("mv %s %s" % ("z_void_indexes.txt", voidDir+"/"))
os.system("mv %s %s" % ("z_posx.nc", voidDir+"/"))
os.system("mv %s %s" % ("z_posy.nc", voidDir+"/"))
os.system("mv %s %s" % ("z_posz.nc", voidDir+"/"))
os.system("mv %s %s" % ("redshifts.nc", voidDir+"/"))
os.system("mv %s %s" % ("indexes.nc", voidDir+"/"))
os.system("mv %s %s" % ("kdtree_stackvoids.dat", voidDir+"/"))
os.system("mv %s %s" % ("centers.txt", voidDir+"/"))
os.system("mv %s %s" % ("z_centers.txt", voidDir+"/"))
os.system("mv %s %s" % ("sky_positions.txt", voidDir+"/"))
os.system("mv %s %s" % ("check.txt", voidDir+"/"))
os.system("mv %s %s" % ("tracer.txt", voidDir+"/"))
os.system("mv %s %s" % ("normalizations.txt", voidDir+"/"))
os.system("mv %s %s" % ("boundaryDistances.txt", voidDir+"/"))
#os.system("mv %s %s" % ("tree.data", treeFile))
#os.system("mv %s %s" % ("void_indexes.txt", voidDir+"/"))
#os.system("mv %s %s" % ("posx.nc", voidDir+"/"))
#os.system("mv %s %s" % ("posy.nc", voidDir+"/"))
#os.system("mv %s %s" % ("posz.nc", voidDir+"/"))
#os.system("mv %s %s" % ("z_void_indexes.txt", voidDir+"/"))
#os.system("mv %s %s" % ("z_posx.nc", voidDir+"/"))
#os.system("mv %s %s" % ("z_posy.nc", voidDir+"/"))
#os.system("mv %s %s" % ("z_posz.nc", voidDir+"/"))
#os.system("mv %s %s" % ("redshifts.nc", voidDir+"/"))
#os.system("mv %s %s" % ("indexes.nc", voidDir+"/"))
#os.system("mv %s %s" % ("kdtree_stackvoids.dat", voidDir+"/"))
#os.system("mv %s %s" % ("centers.txt", voidDir+"/"))
#os.system("mv %s %s" % ("z_centers.txt", voidDir+"/"))
#os.system("mv %s %s" % ("sky_positions.txt", voidDir+"/"))
#os.system("mv %s %s" % ("check.txt", voidDir+"/"))
#os.system("mv %s %s" % ("tracer.txt", voidDir+"/"))
#os.system("mv %s %s" % ("normalizations.txt", voidDir+"/"))
#os.system("mv %s %s" % ("boundaryDistances.txt", voidDir+"/"))
if os.access(idListFile, os.F_OK): os.unlink(idListFile)
if os.access(parmFile, os.F_OK): os.unlink(parmFile)
os.chdir(launchDir)
return
# -----------------------------------------------------------------------------
@ -851,6 +858,7 @@ def launchCombine(sample, stack, voidDir=None, logFile=None,
runSuffix = getStackSuffix(stack.zMin, stack.zMax, stack.rMin,
stack.rMax, thisDataPortion)
jobString = " "+runSuffix+":"
sys.stdout = open(logFile, 'w')
sys.stderr = open(logFile, 'a')
@ -1076,21 +1084,26 @@ def launchCombine(sample, stack, voidDir=None, logFile=None,
sys.stderr = sys.__stderr__
if jobSuccessful(logFile, "Done!\n"):
print "done"
print jobString, "Combining stacks done"
else:
print "FAILED!"
print jobString, "Combining stacks FAILED!"
exit(-1)
#else:
# print "already done!"
# -----------------------------------------------------------------------------
def launchProfile(sample, stack, voidDir=None, logFile=None, continueRun=None):
def launchProfile(sample, stack, voidDir=None, logFile=None, continueRun=None,
thisDataPortion=None):
sampleName = sample.fullName
runSuffix = getStackSuffix(stack.zMin, stack.zMax, stack.rMin,
stack.rMax, thisDataPortion)
jobString = " "+runSuffix+":"
if os.access(voidDir+"/NOVOID", os.F_OK):
print "no stack here; skipping!"
print jobString, "Profile no stack here; skipping!"
return
numVoids = open(voidDir+"/num_voids.txt", "r").readline()
@ -1129,13 +1142,13 @@ def launchProfile(sample, stack, voidDir=None, logFile=None, continueRun=None):
sys.stderr = sys.__stderr__
if jobSuccessful(logFile, "Done!\n"):
print "done", numVoids
print jobString, "Profiling stacks done, (N_v=", numVoids,")"
else:
print "FAILED!"
print jobString, "Profiling stacks FAILED!"
exit(-1)
else:
print "already done!"
print jobString, "Profiling stacks already done!"
# -----------------------------------------------------------------------------
@ -1147,14 +1160,16 @@ def launchFit(sample, stack, logFile=None, voidDir=None, figDir=None,
runSuffix = getStackSuffix(stack.zMin, stack.zMax, stack.rMin,
stack.rMax, thisDataPortion)
jobString = " "+runSuffix+":"
if not (continueRun and jobSuccessful(logFile, "Done!\n")):
if os.access(voidDir+"/NOVOID", os.F_OK):
print "no voids here; skipping!"
print jobString, "Fitting no voids here; skipping!"
return
numVoids = int(open(voidDir+"/num_voids.txt", "r").readline())
if numVoids < 10:
print "not enough voids to fit; skipping!"
print jobString, "Fitting not enough voids to fit; skipping!"
fp = open(voidDir+"/NOFIT", "w")
fp.write("not enough voids: %d \n" % numVoids)
fp.close()
@ -1165,18 +1180,18 @@ def launchFit(sample, stack, logFile=None, voidDir=None, figDir=None,
# return
if sample.partOfCombo or not sample.includeInHubble:
print "sample not needed for further analysis; skipping!"
print jobString, "Fitting sample not needed for further analysis; skipping!"
fp = open(voidDir+"/NOFIT", "w")
fp.write("sample not needed for hubble\n")
fp.close()
return
if not stack.includeInHubble:
print "radius not needed for further analysis; skipping!"
print jobString, "Fitting radius not needed for further analysis; skipping!"
return
if not stack.includeInHubble:
print "redshift not needed for further analysis; skipping!"
print jobString, "Fitting redshift not needed for further analysis; skipping!"
return
if os.access(figDir+"/stackedVoid_"+sampleName+"_"+\
@ -1241,9 +1256,9 @@ def launchFit(sample, stack, logFile=None, voidDir=None, figDir=None,
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
if jobSuccessful(logFile, "Done!\n"):
print "done (", ntries, " tries)"
print jobString, "Fitting done (", ntries, " tries)"
else:
print "FAILED!"
print jobString, "Fitting FAILED!"
exit(-1)
# record the measured stretch
@ -1255,14 +1270,14 @@ def launchFit(sample, stack, logFile=None, voidDir=None, figDir=None,
if os.access(voidDir+"/NOFIT", os.F_OK):
os.unlink(voidDir+"/NOFIT")
if ntries > maxtries:
print " No reliable fit found; skipping!"
print jobString, " No reliable fit found; skipping!"
fp = open(voidDir+"/NOFIT", "w")
fp.write("bad ellipticity fit\n")
fp.close()
return
else:
print "already done!"
print jobString, "already done!"
# -----------------------------------------------------------------------------