/*** Initialize 2D spline ***/ void Spline::init(double *dom1, double *dom2, double **f, int n1, int n2) { int i, j; // Clear previous settings if existent: if (dim!=0) dealloc(); // Set variables and allocate memory: dim = 2; N1 = n1; N2 = n2; x1 = vector<double>(splOffset, N1+splOffset-1); x2 = vector<double>(splOffset, N2+splOffset-1); f1d = NULL; f2d = matrix<double>(splOffset, N1+splOffset-1, splOffset, N2+splOffset-1); d2fdx2 = NULL; d2fdxdy = matrix<double>(splOffset, N1+splOffset-1, splOffset, N2+splOffset-1); // Copy function sampled point to internal arrays: for (i=splOffset; i<N1+splOffset; i++) x1[i] = dom1[i]; for (j=splOffset; j<N2+splOffset; j++) x2[j] = dom2[j]; for (i=splOffset; i<N1+splOffset; i++) for (j=splOffset; j<N2+splOffset; j++){ f2d[i][j] = f[i][j]; } // Compute second derivatives that are needed for Spline: splie2(x1, x2, f2d, N1, N2, d2fdxdy); }
// Will use the Cov[i][j][l] tensor, you have to specify the field index and // the multipole l, and the code loops over redshifts. void Spline::init(const FZdatabase & fieldlist, double ***Cov, int field, int lpos) { int i, j, z1, z2; // Clear previous settings if existent: if (dim!=0) dealloc(); // Set variables and allocate memory: dim = 2; N1 = fieldlist.Nz4f(field); N2 = fieldlist.Nz4f(field); x1 = vector<double>(splOffset, N1+splOffset-1); x2 = vector<double>(splOffset, N2+splOffset-1); f1d = NULL; f2d = matrix<double>(splOffset, N1+splOffset-1, splOffset, N2+splOffset-1); d2fdx2 = NULL; d2fdxdy = matrix<double>(splOffset, N1+splOffset-1, splOffset, N2+splOffset-1); // Copy function sampled point to internal arrays: for (z1=0; z1<N1; z1++) { fieldlist.fFixedIndex(field, z1, &i); // Will use the mean redshift in the bin as point where Cov was sampled: x1[splOffset+z1] = (fieldlist.zmin(i)+fieldlist.zmax(i))/2.0; x2[splOffset+z1] = x1[splOffset+z1]; } for (z1=splOffset; z1<N1+splOffset; z1++) { fieldlist.fFixedIndex(field, z1, &i); for (z2=splOffset; z2<N2+splOffset; z2++) { fieldlist.fFixedIndex(field, z2, &j); f2d[z1][z2] = Cov[i][j][lpos]; } } // Compute second derivatives that are needed for Spline: splie2(x1, x2, f2d, N1, N2, d2fdxdy); }
int main(void) { int i,j; float x1x2,*x1,*x2,**y,**y2; x1=vector(1,N); x2=vector(1,N); y=matrix(1,M,1,N); y2=matrix(1,M,1,N); for (i=1;i<=M;i++) x1[i]=0.2*i; for (i=1;i<=N;i++) x2[i]=0.2*i; for (i=1;i<=M;i++) for (j=1;j<=N;j++) { x1x2=x1[i]*x2[j]; y[i][j]=x1x2*x1x2; } splie2(x1,x2,y,M,N,y2); printf("\nsecond derivatives from SPLIE2\n"); printf("natural spline assumed\n"); for (i=1;i<=5;i++) { for (j=1;j<=5;j++) printf("%12.6f",y2[i][j]); printf("\n"); } printf("\nactual second derivatives\n"); for (i=1;i<=5;i++) { for (j=1;j<=5;j++) printf("%12.6f",2.0*x1[i]*x1[i]); printf("\n"); } free_matrix(y2,1,M,1,N); free_matrix(y,1,M,1,N); free_vector(x2,1,N); free_vector(x1,1,N); return 0; }
double xi2d_interp(double rs1, double rp1, double rs2, double rp2) { static double **xi2d,rmax,rmin,*rsig,*rpi,**yy2d; static int flag=1,n,prev; int i,j,ng=20; double dx,dy,dlogr,xsum,rs,rp,x; if(flag || prev!=RESET_COSMOLOGY) { two_halo(1,1); prev=RESET_COSMOLOGY; n=35; if(flag) { xi2d=dmatrix(1,n,1,n); yy2d=dmatrix(1,n,1,n); rsig=dvector(1,n); rpi=dvector(1,n); } flag=0; rmax=log(40.5); rmin=log(0.05); dlogr = (rmax-rmin)/(n-1); for(i=1;i<=n;++i) rsig[i]=rpi[i]=exp((i-1)*dlogr+rmin); calc_xi2d(xi2d,n,rmax,rmin); splie2(rsig,rpi,xi2d,n,n,yy2d); } if(rs2<0 && rp2<0) { splin2(rsig,rpi,xi2d,yy2d,n,n,(rs1),(rp1),&x); return(x); } dx=(rs2-rs1)/ng; dy=(rp2-rp1)/ng; xsum=0; for(i=1;i<=ng;++i) for(j=1;j<=ng;++j) { rs=rs1+(i-0.5)*dx; rp=rp1+(j-0.5)*dy; splin2(rsig,rpi,xi2d,yy2d,n,n,(rs),(rp),&x); xsum+=2*dy*rs*dx*(x); } xsum/=((rs2*rs2-rs1*rs1)*(rp2-rp1)); return(xsum); }
/* The angular grid here is set such that * it's only used for the small-r SDSS multipoles, i<=3, or r<~ 1 Mpc/h */ double xi2d_interp_polar(double rs1, double rs2, double phi1, double phi2) { static double **xi2d,rmax,rmin,*rsig,*rpi,**yy2d; static int flag=1,n,prev; int i,j,ng=20; double dx,dy,dlogr,xsum,rs,rp,x,vsum,dr,dphi,phi,r; if(flag || prev!=RESET_COSMOLOGY) { two_halo(1,1); prev=RESET_COSMOLOGY; n=15; if(flag) { xi2d=dmatrix(1,n,1,n); yy2d=dmatrix(1,n,1,n); rsig=dvector(1,n); rpi=dvector(1,n); } flag=0; rmax=log(2.5); rmin=log(0.05); dlogr = (rmax-rmin)/(n-1); for(i=1;i<=n;++i) rsig[i]=rpi[i]=exp((i-1)*dlogr+rmin); calc_xi2d(xi2d,n,rmax,rmin); splie2(rsig,rpi,xi2d,n,n,yy2d); } rs1 = log(rs1); rs2 = log(rs2); dr=(rs2-rs1)/ng; dphi=(phi2-phi1)/ng; xsum=vsum=0; for(i=1;i<=ng;++i) for(j=1;j<=ng;++j) { r=exp(rs1+(i-0.5)*dr); phi=phi1+(j-0.5)*dphi; rp = r*sin(phi); rs = r*cos(phi); splin2(rsig,rpi,xi2d,yy2d,n,n,(rs),(rp),&x); xsum+=sin(phi)*r*r*r*(x); vsum+=r*r*r*sin(phi); } xsum/=vsum; return(xsum); }