Merge branch 'master' of bitbucket.org:cosmicvoids/void_identification

This commit is contained in:
Guilhem Lavaux 2014-01-26 09:27:16 +01:00
commit dc7eb577fe
113 changed files with 22392 additions and 171 deletions

4
README
View file

@ -6,13 +6,13 @@
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
This is VIDE. The Void IDEntifier pipeline. This is VIDE, the Void IDentification and Examination pipeline.
License/Copyright information License/Copyright information
----------------------------- -----------------------------
Copyright (C) 2010-2013 Guilhem Lavaux, 2011-2013 Paul M. Sutter. Copyright (C) 2010-2013 Guilhem Lavaux, 2011-2013 P.M. Sutter.
This software is put under the GNU Public License. Please see LICENSE This software is put under the GNU Public License. Please see LICENSE
for further information. for further information.

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]; offset = info.ranges[0][0];
// TEST PMS NON-COBIC BOXES // TEST PMS NON-COBIC BOXES
mul = 1.0; //mul = 1.0;
//mul = info.ranges[0][1] - info.ranges[0][0]; mul = info.ranges[0][1] - info.ranges[0][0];
f.beginCheckpoint(); f.beginCheckpoint();
for (int i = 0; i < numpart; i++) for (int i = 0; i < numpart; i++)
info.particles[i].x = mul*f.readReal32(); info.particles[i].x = mul*f.readReal32();
f.endCheckpoint(); f.endCheckpoint();
offset = info.ranges[1][0]; offset = info.ranges[1][0];
mul = 1.0; //mul = 1.0;
//mul = info.ranges[1][1] - info.ranges[1][0]; mul = info.ranges[1][1] - info.ranges[1][0];
f.beginCheckpoint(); f.beginCheckpoint();
for (int i = 0; i < numpart; i++) for (int i = 0; i < numpart; i++)
info.particles[i].y = mul*f.readReal32(); info.particles[i].y = mul*f.readReal32();
f.endCheckpoint(); f.endCheckpoint();
offset = info.ranges[2][0]; offset = info.ranges[2][0];
mul = 1.0; //mul = 1.0;
//mul = info.ranges[2][1] - info.ranges[2][0]; mul = info.ranges[2][1] - info.ranges[2][0];
f.beginCheckpoint(); f.beginCheckpoint();
for (int i = 0; i < numpart; i++) for (int i = 0; i < numpart; i++)
info.particles[i].z = mul*f.readReal32(); info.particles[i].z = mul*f.readReal32();

View file

@ -115,7 +115,7 @@ void loadData(const string& fname, NYU_VData & data)
} }
void generateGalaxiesInCube(NYU_VData& data, ParticleData& output_data, void generateGalaxiesInCube(NYU_VData& data, ParticleData& output_data,
bool useLCDM) bool useComoving)
{ {
double d2r = M_PI/180; double d2r = M_PI/180;
@ -163,7 +163,7 @@ void generateGalaxiesInCube(NYU_VData& data, ParticleData& output_data,
double ra = data[i].ra*d2r, dec = data[i].dec*d2r; double ra = data[i].ra*d2r, dec = data[i].dec*d2r;
Position& p = output_data.pos[i]; Position& p = output_data.pos[i];
if (useLCDM) { if (useComoving) {
//double pos = gsl_interp_eval(interp, redshifts, dL, data[i].cz, acc); //double pos = gsl_interp_eval(interp, redshifts, dL, data[i].cz, acc);
gsl_integration_qng(&expanF, 1.e-6, data[i].cz/LIGHT_SPEED, gsl_integration_qng(&expanF, 1.e-6, data[i].cz/LIGHT_SPEED,
1.e-6, 1.e-6,
@ -587,7 +587,7 @@ int main(int argc, char **argv)
// We compute a cube holding all the galaxies + the survey surface mask // We compute a cube holding all the galaxies + the survey surface mask
cout << "Placing galaxies..." << endl; cout << "Placing galaxies..." << endl;
generateGalaxiesInCube(data, output_data, args_info.useLCDM_flag); generateGalaxiesInCube(data, output_data, args_info.useComoving_flag);
generateSurfaceMask(args_info, mask, pixel_list, full_mask_list, generateSurfaceMask(args_info, mask, pixel_list, full_mask_list,
data, output_data); data, output_data);

View file

@ -14,4 +14,4 @@ option "zMax" - "Maximum redshift of data" double required
option "output" - "Filename of particle datafile" string required option "output" - "Filename of particle datafile" string required
option "params" - "Output parameters of the datacube" string required option "params" - "Output parameters of the datacube" string required
option "useLCDM" - "Convert to real space using LCDM cosmology" flag off option "useComoving" - "Convert to real space using LCDM cosmology" flag off

View file

@ -116,6 +116,11 @@ void metricTransform(SimuData *data, int axis, bool reshift, bool pecvel, double
baseComovingDistance = LIGHT_SPEED/100.* gslIntegrate(e_computer, 0, z0, 1e-3); baseComovingDistance = LIGHT_SPEED/100.* gslIntegrate(e_computer, 0, z0, 1e-3);
cout << "Comoving distance = " << baseComovingDistance << " Mpc/h" << endl; cout << "Comoving distance = " << baseComovingDistance << " Mpc/h" << endl;
if (cosmo_flag) cout << "Will place particles on a lightcone..." << endl;
float minZ = 1.e99;
float maxZ = 0;
for (uint32_t i = 0; i < data->NumPart; i++) for (uint32_t i = 0; i < data->NumPart; i++)
{ {
float& x = data->Pos[x0][i]; float& x = data->Pos[x0][i];
@ -148,8 +153,11 @@ void metricTransform(SimuData *data, int axis, bool reshift, bool pecvel, double
cout << "The offending value is z=" << reduced_red << endl; cout << "The offending value is z=" << reduced_red << endl;
abort(); abort();
} }
if (z > maxZ) maxZ = z;
if (z < minZ) minZ = z;
} }
printf("Range of z: %.2f - %.2f\n", minZ, maxZ);
} }
// slightly perturb particle positions // slightly perturb particle positions

Some files were not shown because too many files have changed in this diff Show more