CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
SuperSampleCovariance.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Copyright (C) 2021 by Federico Marulli and Giorgio Lesci *
3  * federico.marulli3@unibo.it *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public *
16  * License along with this program; if not, write to the Free *
17  * Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ********************************************************************/
20 
34 #include "SuperSampleCovariance.h"
35 
36 
37 // ======================================================================================
38 
39 
40 cbl::cosmology::SuperSampleCovariance::SuperSampleCovariance (cbl::cosmology::Cosmology cosm, const std::vector<cbl::cosmology::CosmologicalParameter> cosmo_param, const std::vector<double> redshift_edges, const double area, const std::string method_Pk, const double delta_z, const double precision, const bool NL, const bool store_output)
41 {
42  m_cosmo = std::make_shared<cosmology::Cosmology>(cosm);
43  m_cosmo->set_unit(false); // force physical units
44 
45  m_cosmo_param = cosmo_param;
46  m_method_Pk = method_Pk;
47  m_NL = NL;
48  m_store_output = store_output;
49 
50  m_nbins = (int)(redshift_edges.size()-1);
51  m_area = area * pow(cbl::par::pi/180,2);
52  m_precision = precision;
53 
54  m_compute_topHat_window(delta_z, redshift_edges);
55 
56  if (m_nbins != (int)(m_response_func.size()))
57  cbl::ErrorCBL("Different number of redshift bins and input models!","set_SSC","SuperSampleCovariance");
58 }
59 
60 
61 // ======================================================================================
62 
63 
64 cbl::cosmology::SuperSampleCovariance::SuperSampleCovariance (cbl::cosmology::Cosmology cosm, const std::vector<cbl::cosmology::CosmologicalParameter> cosmo_param, const double area, const std::vector<double> W_mean, const std::vector<double> W_std, const std::string method_Pk, const double delta_z, const double precision, const bool NL, const bool store_output)
65 {
66  m_cosmo = std::make_shared<cosmology::Cosmology>(cosm);
67  m_cosmo->set_unit(false); // force physical units
68 
69  m_cosmo_param = cosmo_param;
70  m_method_Pk = method_Pk;
71  m_NL = NL;
72  m_store_output = store_output;
73 
74  m_nbins = (int)(W_mean.size());
75  m_area = area * pow(cbl::par::pi/180,2);
76  m_precision = precision;
77 
78  m_compute_gaussian_window(delta_z, W_mean, W_std);
79 
80  if (m_nbins != (int)(m_response_func.size()))
81  cbl::ErrorCBL("Different number of redshift bins and input models!","set_SSC","SuperSampleCovariance");
82 }
83 
84 
85 // ======================================================================================
86 
87 
88 void cbl::cosmology::SuperSampleCovariance::m_compute_topHat_window (const double delta_z, const std::vector<double> redshift_edges)
89 {
90  m_nsteps = (int)((redshift_edges[redshift_edges.size()-1]-redshift_edges[0])/delta_z + 1);
91  if (m_nsteps < m_nbins)
92  cbl::ErrorCBL("m_nsteps can not be lower than the number of redshift bins!","m_compute_topHat_window","SuperSampleCovariance");
93 
94  m_redshifts.resize(m_nsteps);
95  m_windows.resize(m_nbins);
96 
97  for (int i=0; i<m_nbins; i++) {
98  m_windows[i].resize(m_nsteps);
99  double iter = redshift_edges[0]-delta_z;
100  double Delta_z = redshift_edges[i+1] - redshift_edges[i];
101  for (int j=0; j<m_nsteps; j++) {
102  iter += delta_z;
103  m_redshifts[j] = iter;
104  if ((iter>redshift_edges[i]) && (iter<=redshift_edges[i+1]))
105  m_windows[i][j] = 1/Delta_z;
106  }
107  }
108 }
109 
110 
111 // ======================================================================================
112 
113 
114 void cbl::cosmology::SuperSampleCovariance::m_compute_gaussian_window (const double delta_z, const std::vector<double> W_mean, const std::vector<double> W_std)
115 {
116  double max_z = W_mean[W_mean.size()-1]+3.5*W_std[W_mean.size()-1];
117  double min_z = W_mean[0]-3.5*W_std[0];
118 
119  m_nsteps = (int)((max_z - min_z) / delta_z + 1);
120  m_redshifts.resize(m_nsteps);
121  m_windows.resize(m_nbins);
122 
123  for (int i=0; i<m_nbins; i++) {
124  m_windows[i].resize(m_nsteps);
125  double iter = min_z - delta_z;
126  for (int j=0; j<m_nsteps; j++) {
127  iter += delta_z;
128  m_redshifts[j] = iter;
129  m_windows[i][j] = exp( - (m_redshifts[j] - W_mean[i]) * (m_redshifts[j] - W_mean[i]) / (2*W_std[i]*W_std[i]) ) / sqrt(2*cbl::par::pi*W_std[i]*W_std[i]);
130  }
131  }
132 }
133 
134 
135 // ======================================================================================
136 
137 
139 {
140  // Compute comoving distances, volumes, growth factor
141  std::vector<double> comov_dist(m_nsteps), dV(m_nsteps), growthf(m_nsteps);
142  for (int i=0; i<m_nsteps; i++){
143  comov_dist[i] = cosmo.D_C(m_redshifts[i]);
144  dV[i] = comov_dist[i] * comov_dist[i] * cosmo.D_H() * cosmo.EE_inv(m_redshifts[i]); // D_H()*EE_inv(z) is the D_C normalized derivative
145  growthf[i] = cosmo.DN(m_redshifts[i]); // normalized scale-independent growth factor
146  }
147 
148  // Compute normalizations
149  std::vector<double> Inorm(m_nbins);
150  std::vector<std::vector<double>> integrand (m_nbins,std::vector<double>(m_nsteps));
151  for (int i=0; i<m_nbins; i++){
152  for (int s=0; s<m_nsteps; s++){
153  integrand[i][s] = dV[s] * m_windows[i][s] * m_windows[i][s] / 1.e10;
154  }
155  cbl::glob::FuncGrid integ(m_redshifts, integrand[i], "Spline");
156  Inorm[i] = integ.integrate_cquad(m_redshifts[0], m_redshifts[m_redshifts.size()-1]) * 1.e10;
157  }
158 
159  // Compute U(k)
160  const double h = cosmo.hh();
161  const double keq = 0.02/h; // Equality matter radiation in 1/Mpc (more or less)
162  const double klogwidth = 10; // Factor of width of the integration range. 10 seems ok
163  double max_comov_dist = comov_dist[comov_dist.size()-1];
164  double min_comov_dist = comov_dist[0];
165 
166  double kmin = 0;
167  double kmax = 0;
168  if (keq<(1./max_comov_dist))
169  kmin = keq/klogwidth;
170  else
171  kmin = (1./max_comov_dist)/klogwidth;
172  if (keq>(1./min_comov_dist))
173  kmax = keq*klogwidth;
174  else
175  kmax = min_comov_dist*klogwidth;
176 
177  const double nk = pow(2,m_precision); // m_precision=10 seems to be enough. Increase to test precision, reduce to speed up.
178  const double logkmin = log(kmin);
179  const double logkmax = log(kmax);
180  std::vector<double> logk(nk);
181  std::vector<double> kk(nk);
182  for (size_t i=0; i<logk.size(); i++) {
183  logk[i]=logkmin+i*(logkmax-logkmin)/(nk-1);
184  kk[i]=exp(logk[i]);
185  }
186 
187  std::vector<double> Pk_new = cosmo.Pk_matter(kk, "EisensteinHu", m_NL, 0., m_store_output, "test", -1, 1.e-4, 100., 1.e-2, cbl::par::defaultString, false);
188  std::vector<std::vector<double>> Uarr(m_nbins, std::vector<double>(logk.size()));
189  std::vector<double> kr(m_nsteps);
190  std::vector<std::vector<double>> integrand2(m_nbins, std::vector<double>(m_nsteps));
191  for (int i=0; i<m_nbins; i++) {
192  for (size_t j=0; j<logk.size(); j++) {
193  for (size_t s=0; s<m_redshifts.size(); s++) {
194  kr[s] = kk[j]*comov_dist[s];
195  integrand2[i][s] = dV[s] * m_windows[i][s] * m_windows[i][s] * growthf[s] * sin(kr[s]) / kr[s] / 1.e10;
196  }
197  cbl::glob::FuncGrid integ(m_redshifts, integrand2[i], "Spline");
198  Uarr[i][j] = integ.integrate_cquad(m_redshifts[0], m_redshifts[m_redshifts.size()-1]) * 1.e10;
199  }
200  }
201 
202  // Compute S_ij
203  std::vector<std::vector<double>> Cl_zero(m_nbins,std::vector<double>(m_nbins));
204  std::vector<std::vector<double>> U1(m_nbins, std::vector<double>(logk.size()));
205  std::vector<std::vector<double>> U2(m_nbins, std::vector<double>(logk.size()));
206  std::vector<std::vector<double>> integrand3(m_nbins, std::vector<double>(logk.size()));
207  for (int i=0; i<m_nbins; i++){
208  for (size_t j=0; j<logk.size(); j++){
209  U1[i][j] = Uarr[i][j]/Inorm[i];
210  }
211  for (int k=i; k<m_nbins; k++){
212  for (size_t j=0; j<logk.size(); j++){
213  U2[k][j] = Uarr[k][j]/Inorm[k];
214  integrand3[k][j] = kk[j] * kk[j] * Pk_new[j] * U1[i][j] * U2[k][j] * 1.e10;
215  }
216  cbl::glob::FuncGrid integ(kk, integrand3[k], "Spline");
217  Cl_zero[i][k] = 2/cbl::par::pi * integ.integrate_cquad(kk[0], kk[kk.size()-1]) / 1.e10;
218  }
219  }
220 
221  // Fill by symmetry
222  for (int i=0; i<m_nbins; i++){
223  for (int j=0; j<m_nbins; j++){
224  Cl_zero[i][j] = Cl_zero[std::min(i,j)][std::max(i,j)];
225  }
226  }
227  std::vector<std::vector<double>> Sij(m_nbins, std::vector<double>(m_nbins));
228  for (int i=0; i<m_nbins; i++){
229  for (int j=0; j<m_nbins; j++){
230  Sij[i][j] = Cl_zero[i][j] / m_area; // S_ij is given by dividing Cl_zero/4pi by the fraction of the sky, i.e. Area(steradians)/4pi
231  }
232  }
233 
234  return Sij;
235 }
236 
237 
238 // ======================================================================================
239 
240 
241 std::vector<std::vector<double>> cbl::cosmology::SuperSampleCovariance::operator () (std::vector<double> &parameter) const
242 {
243  // Redefine the cosmology
244  cbl::cosmology::Cosmology cosmo = *m_cosmo;
245 
246  // Set the cosmological parameters
247  for (size_t i=0; i<m_cosmo_param.size(); ++i)
248  cosmo.set_parameter(m_cosmo_param[i], parameter[i]);
249 
250  std::vector<std::vector<double>> Sij = m_compute_Sij(cosmo);
251 
252  return Sij;
253 }
254 
255 
256 // ======================================================================================
257 
258 
260 {
261  return m_windows;
262 }
263 
264 
265 
266 // ======================================================================================
267 
268 
269 void cbl::cosmology::SuperSampleCovariance::write_window_function (const std::string dir, const std::string file)
270 {
271  // Create the directory
272  std::string mkdir = "mkdir -p "+dir; if (system(mkdir.c_str())) {}
273 
274  // Write on file
275  std::string file_out = dir+file;
276  std::ofstream fout(file_out.c_str());
277 
278  int precision = 6;
279 
280  fout << "### [1] i # [2] j # [3] window[i][j] # [4] redshift " << std::endl;
281 
282  for (size_t i=0; i<m_windows.size(); ++i)
283  for (size_t j=0; j<m_windows[i].size(); ++j)
284  fout << setiosflags(std::ios::fixed) << std::setprecision(precision) << std::setw(15) << std::right << i
285  << " " << setiosflags(std::ios::fixed) << std::setprecision(precision) << std::setw(15) << std::right << j
286  << " " << setiosflags(std::ios::fixed) << std::setprecision(precision) << std::setw(15) << std::right << m_windows[i][j]
287  << " " << setiosflags(std::ios::fixed) << std::setprecision(precision) << std::setw(15) << std::right << m_redshifts[j] << std::endl;
288 
289  fout.close(); std::cout << std::endl; coutCBL << "I wrote the file: " << file_out << std::endl;
290 }
291 
292 
293 // ======================================================================================
294 
295 
296 void cbl::cosmology::SuperSampleCovariance::write_Sij (const std::string dir, const std::string file)
297 {
298  // Compute S_ij using the cosmology given in input to set_SSC
299  std::vector<std::vector<double>> Sij = m_compute_Sij(*m_cosmo);
300 
301  // Create the directory
302  std::string mkdir = "mkdir -p "+dir; if (system(mkdir.c_str())) {}
303 
304  // Write on file
305  std::string file_out = dir+file;
306  std::ofstream fout(file_out.c_str());
307 
308  int precision = 15;
309 
310  fout << "### [1] i # [2] j # [3] S_ij " << std::endl;
311 
312  for (size_t i=0; i<Sij.size(); ++i)
313  for (size_t j=0; j<Sij[i].size(); ++j)
314  fout << setiosflags(std::ios::fixed) << std::setprecision(precision) << std::setw(15) << std::right << i
315  << " " << setiosflags(std::ios::fixed) << std::setprecision(precision) << std::setw(15) << std::right << j
316  << " " << setiosflags(std::ios::fixed) << std::setprecision(precision) << std::setw(15) << std::right << Sij[i][j] << std::endl;
317 
318  fout.close(); std::cout << std::endl; coutCBL << "I wrote the file: " << file_out << std::endl;
319 }
320 
321 
322 // ======================================================================================
323 
324 
326 {
327  return m_nbins;
328 }
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class SuperSampleCovariance.
The class Cosmology.
Definition: Cosmology.h:277
double DN(const double redshift, const double redshift_norm=0., const double prec=1.e-4) const
the normalised amplitude of the growing mode at a given redshift,
Definition: Cosmology.cpp:691
void set_parameter(const CosmologicalParameter parameter, const double value)
set the value of one cosmological paramter
Definition: Cosmology.cpp:424
double hh() const
get the private member Cosmology::m_hh
Definition: Cosmology.h:1191
double D_H() const
get the private member Cosmology::m_D_H
Definition: Cosmology.h:1205
std::vector< double > Pk_matter(const std::vector< double > kk, const std::string method_Pk, const bool NL, const double redshift, const bool store_output=true, const std::string output_root="test", const int norm=-1, const double k_min=0.001, const double k_max=100., const double prec=1.e-2, const std::string file_par=par::defaultString, const bool unit1=false)
the dark matter power spectrum
Definition: PkXi.cpp:1331
double EE_inv(const double redshift=0.) const
inverse of the auxiliary function used to compute the Hubble function integrand of the comoving dista...
Definition: Cosmology.h:1910
double D_C(const double redshift) const
the comoving line-of-sight distance at a given redshift
Definition: Cosmology.cpp:741
std::vector< std::shared_ptr< statistics::Model > > m_response_func
pointer to the response function of the probe
void m_compute_topHat_window(const double delta_z, const std::vector< double > redshift_edges)
compute the top-hat window functions in the redshift bins
std::vector< std::vector< double > > operator()(std::vector< double > &parameter) const
get
void m_compute_gaussian_window(const double delta_z, const std::vector< double > W_mean, const std::vector< double > W_std)
compute the Gaussian window functions in the redshift bins
int Sij_dimension()
return the dimension of the Sij matrix
std::vector< std::vector< double > > m_compute_Sij(cbl::cosmology::Cosmology cosmo) const
compute the S_ij matrix
void write_window_function(const std::string dir, const std::string file)
write the window functions on file
double m_area
survey area in steradians
std::shared_ptr< cosmology::Cosmology > m_cosmo
pointer to the Cosmology object
std::vector< cbl::cosmology::CosmologicalParameter > m_cosmo_param
names of the cosmological parameters
void write_Sij(const std::string dir, const std::string file)
Write the matrix on file.
std::vector< std::vector< double > > get_window_function()
return the window functions
std::string m_method_Pk
method used to compute the power spectrum
double m_precision
precision of the array
bool m_NL
linear o non-linear power-spectrum
SuperSampleCovariance(cbl::cosmology::Cosmology cosm, const std::vector< cbl::cosmology::CosmologicalParameter > cosmo_param, const std::vector< double > redshift_edges, const double area, const std::string method_Pk="EisensteinHu", const double delta_z=0.001, const double precision=10, const bool NL=false, const bool store_output=false)
Default constructor, used to compute the matrix, assuming top-hat window functions....
The class FuncGrid.
Definition: FuncGrid.h:55
double integrate_cquad(const double a, const double b, const double rel_err=1.e-2, const double abs_err=1.e-6, const int nevals=100)
compute the definite integral with GSL cquad method
Definition: FuncGrid.cpp:198
static const std::string defaultString
default std::string value
Definition: Constants.h:336
static const double pi
: the ratio of a circle's circumference to its diameter
Definition: Constants.h:199
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
Definition: Kernel.h:780