CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
CombinedPosterior.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Copyright (C) 2014 by Federico Marulli and Alfonso Veropalumbo *
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 
33 #include "FITSwrapper.h"
34 #include "PosteriorParameters.h"
35 #include "Sampler.h"
36 #include "CombinedPosterior.h"
37 #include "ChainMesh.h"
38 
39 using namespace std;
40 
41 using namespace cbl;
42 
43 
44 // ============================================================================================
45 
46 
47 cbl::statistics::CombinedPosterior::CombinedPosterior (const std::vector<std::shared_ptr<Posterior>> posteriors, std::vector<std::string> repeated_par, const std::vector<std::vector<std::vector<int>>> common_repeated_par)
48 {
49  m_posteriors = posteriors;
50  m_Nposteriors = m_posteriors.size();
51  std::vector<bool> is_from_chain(m_Nposteriors);
52 
53  for(int N=0; N<m_Nposteriors; N++)
54  if(m_posteriors[N]->m_get_seed() != -1) is_from_chain[N] = true;
55  else is_from_chain[N] = false;
56 
57  if(std::find(is_from_chain.begin(), is_from_chain.end(), false) == is_from_chain.end()) { // All false
58  m_set_parameters_priors(m_posteriors, repeated_par, common_repeated_par);
59  m_set_independent_probes();
60  }
61 
62  else if (std::find(is_from_chain.begin(), is_from_chain.end(), true) == is_from_chain.end()) // All true
63  {
64  impsampling = true;
65  for(int N=1; N<m_Nposteriors; N++)
66  if(m_posteriors[N]->get_Nparameters()!=m_posteriors[0]->get_Nparameters())
67  ErrorCBL("Different number of parameters for the combination", "CombinedPosterior", "CombinedPosterior.cpp");
68  m_Nparameters = m_posteriors[0]->get_Nparameters();
69  m_model_parameters = m_posteriors[0]->get_model_parameters();
70  }
71 
72  // at least one is false
73  else
74  ErrorCBL("Different kind of Posterior objects given as input!", "CombinedPosterior", "CombinedPosterior.cpp");
75 }
76 
77 
78 // ============================================================================================
79 
80 
81 cbl::statistics::CombinedPosterior::CombinedPosterior (const std::vector<std::vector<std::shared_ptr<Posterior>>> posteriors, const std::vector<std::shared_ptr<data::CovarianceMatrix>> covariance, const std::vector<cbl::statistics::LikelihoodType> likelihood_types, const std::vector<std::string> repeated_par, const std::vector<std::vector<std::vector<int>>> common_repeated_par, const std::vector<std::shared_ptr<cbl::cosmology::SuperSampleCovariance>> SSC)
82 {
83  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
84  // Check the likelihood types and the covariance matrices
85  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
86 
87  int N_userdefined = 0;
88  std::vector<bool> userdefined;
89  for (size_t i=0; i<posteriors.size(); i++) {
90  int dataset_length = 0;
91 
92  switch (likelihood_types[i])
93  {
94 
95  case (LikelihoodType::_Poissonian_): case (LikelihoodType::_Gaussian_Covariance_):
96  for (size_t j=0; j<posteriors[i].size(); j++)
97  dataset_length += posteriors[i][j]->get_m_data()->xx().size();
98  if (dataset_length != (int)(covariance[i]->operator()().size()))
99  ErrorCBL("Dataset with index "+cbl::conv(i, cbl::par::fINT)+": The dimension of the covariance matrix does not match the length of the data vector!", "CombinedPosterior", "CombinedPosterior.cpp");
100  userdefined.emplace_back(false);
101  break;
102 
103  case (LikelihoodType::_UserDefined_):
104  if (posteriors[i].size() != 1)
105  ErrorCBL("If the likelihood type is _UserDefined_, you must provide one Posterior object. You provided "+cbl::conv((int)(posteriors.size()), cbl::par::fINT)+" Posterior objects in posteriors["+cbl::conv(i, cbl::par::fINT)+"].", "CombinedPosterior", "CombinedPosterior.cpp");
106 
107  userdefined.emplace_back(true);
108  N_userdefined ++;
109  break;
110 
111  default:
112  ErrorCBL("Wrong likelihood type declaration for the set of variables with index "+cbl::conv(i, cbl::par::fINT)+". Choose among: _Gaussian_Covariance_, _Poissonian_, _UserDefined_", "CombinedPosterior", "CombinedPosterior.cpp");
113  break;
114 
115  }
116  }
117 
118  if (N_userdefined > 0) {
119  bool userdefined_started = false;
120  for (size_t i=0; i<userdefined.size(); i++) {
121  if (userdefined[i] == true)
122  userdefined_started = true;
123  else if (userdefined[i] == false && userdefined_started == true)
124  ErrorCBL("You must sort the posteriors elements so that the sets of probes described by UserDefined likelihoods are the last elements in the vector!", "CombinedPosterior", "CombinedPosterior.cpp");
125  else
126  continue;
127  }
128  if (covariance.size() != likelihood_types.size()-N_userdefined)
129  ErrorCBL("If a set of probes is described by a UserDefined likelihood, you can't give in input a CovarianceMatrix object, in this constructor, related to that set of probes!\nThe number of required CovarianceMatrix objects is "+cbl::conv((int)(likelihood_types.size()-N_userdefined), cbl::par::fINT)+", i.e. the number of non-UserDefined likelihoods.", "CombinedPosterior", "CombinedPosterior.cpp");
130  }
131  if (posteriors.size() != likelihood_types.size() && N_userdefined == 0)
132  ErrorCBL("The number of sets of dependent posteriors must match the number of likelihood types!", "CombinedPosterior", "CombinedPosterior.cpp");
133 
134  if (posteriors.size() != covariance.size()+N_userdefined)
135  ErrorCBL("The number of sets of dependent posteriors must match the number of covariance matrices!", "CombinedPosterior", "CombinedPosterior.cpp");
136 
137  if (SSC.size() != 0 && SSC.size() != posteriors.size())
138  ErrorCBL("The length of SSC must be either 0 or equal to number of sets of posteriors!", "CombinedPosterior", "CombinedPosterior.cpp");
139 
140 
141  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
142  // Set the core variables
143  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
144 
145  m_Nposteriors = posteriors.size();
146 
147  m_parameter_indexes.resize(m_Nposteriors);
148  m_use_grid.resize(m_Nposteriors);
149  m_likelihood_inputs.resize(m_Nposteriors);
150  m_log_likelihood_functions.resize(m_Nposteriors);
151  m_likelihood_functions.resize(m_Nposteriors);
152  m_log_likelihood_functions_grid.resize(m_Nposteriors);
153  m_likelihood_functions_grid.resize(m_Nposteriors);
154 
155 
156  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
157  // Set parameters and priors
158  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
159 
160  std::vector<std::shared_ptr<Posterior>> dummy_posteriors;
161  for (size_t i=0; i<posteriors.size(); i++)
162  for (size_t j=0; j<posteriors[i].size(); j++)
163  dummy_posteriors.emplace_back(posteriors[i][j]);
164 
165  m_set_parameters_priors(dummy_posteriors, repeated_par, common_repeated_par);
166 
167  m_parameter_indexes2.resize(dummy_posteriors.size());
168 
169 
170  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
171  // Set the models and the likelihood functions
172  // »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
173 
174  int name_idx = 0;
175  for (size_t i=0; i<posteriors.size(); i++) {
176  auto inputs = make_shared<STR_DependentProbes_data_model>(m_data_model);
177 
178  switch (likelihood_types[i])
179  {
180 
181  case (LikelihoodType::_Gaussian_Covariance_): case (LikelihoodType::_Poissonian_):
182 
183  inputs->models.resize(posteriors[i].size(), NULL);
184  if (SSC.size() != 0) {
185  if (SSC[i] != NULL) {
186  inputs->responses.resize(posteriors[i].size(), NULL);
187  }
188  }
189  inputs->xx.resize(posteriors[i].size());
190  inputs->par_indexes.resize(posteriors[i].size());
191  for (size_t j=0; j<posteriors[i].size(); j++) {
192  if (posteriors[i][j]->get_m_model()->dimension() != Dim::_1D_)
193  ErrorCBL("The model dimension of the statistically dependent probes must be 1!", "CombinedPosterior", "CombinedPosterior.cpp");
194  inputs->models[j] = posteriors[i][j]->get_m_model();
195  if (SSC.size() != 0) {
196  if (SSC[i] != NULL) {
197  inputs->responses[j] = posteriors[i][j]->get_response_function();
198  inputs->Sij = SSC[i];
199  }
200  }
201  m_models.emplace_back(posteriors[i][j]->get_m_model()); // Used only for writing the models at percentiles
202  m_datasets.emplace_back(posteriors[i][j]->get_m_data()); // Used only for writing the models at percentiles
203  inputs->xx[j] = posteriors[i][j]->get_m_data()->xx();
204  for (size_t k=0; k<posteriors[i][j]->get_model_parameters()->name().size(); k++)
205  for(int rr=0; rr<m_Nparameters; rr++)
206  if (m_parameter_names[name_idx][k] == m_model_parameters->name(rr)) {
207  inputs->par_indexes[j].emplace_back(rr);
208  m_parameter_indexes2[name_idx].emplace_back(rr);
209  }
210  for (size_t k=0; k<posteriors[i][j]->get_m_data()->xx().size(); k++)
211  inputs->flat_data.emplace_back(posteriors[i][j]->get_m_data()->data(k));
212  name_idx ++;
213  }
214  inputs->covariance = covariance[i];
215  inputs->cosmoPar_indexes = m_cosmoPar_indexes;
216 
217  for (size_t j=0; j<m_model_parameters->nparameters(); j++)
218  m_parameter_indexes[i].emplace_back(j);
219 
220  break;
221 
222  case (LikelihoodType::_UserDefined_):
223 
224  for (size_t k=0; k<m_parameter_names[name_idx].size(); k++)
225  for(int j=0; j<m_Nparameters; j++)
226  if (m_parameter_names[name_idx][k] == m_model_parameters->name(j)) {
227  m_parameter_indexes[i].emplace_back(j);
228  m_parameter_indexes2[name_idx].emplace_back(j);
229  }
230  name_idx ++;
231 
232  break;
233 
234  default:
235  break;
236  }
237 
238  switch (likelihood_types[i])
239  {
240  case (LikelihoodType::_Gaussian_Covariance_):
241  if (SSC.size() != 0) {
242  if (SSC[i] != NULL) {
243  ErrorCBL("The super-sample covariance in the Gaussian likelihood case is not available yet!", "CombinedPosterior", "CombinedPosterior.cpp");
244  } else {
245  m_log_likelihood_functions[i] = &LogLikelihood_Gaussian_combined;
246  }
247  } else
248  m_log_likelihood_functions[i] = &LogLikelihood_Gaussian_combined;
249  m_likelihood_inputs[i] = inputs;
250  break;
251 
252  case (LikelihoodType::_Poissonian_):
253  if (SSC.size() != 0) {
254  if (SSC[i] != NULL) {
255  m_log_likelihood_functions[i] = &LogLikelihood_Poissonian_SSC_combined;
256  } else {
257  m_log_likelihood_functions[i] = &LogLikelihood_Poissonian_combined;
258  }
259  } else
260  m_log_likelihood_functions[i] = &LogLikelihood_Poissonian_combined;
261  m_likelihood_inputs[i] = inputs;
262  break;
263 
264  case (LikelihoodType::_UserDefined_):
265  WarningMsgCBL("The likelihood type is UserDefined. Note that the user must set the natural logarithm of the likelihood.", "CombinedPosterior", "CombinedPosterior.cpp");
266  m_log_likelihood_functions[i] = posteriors[i][0]->get_m_log_likelihood_function();
267  m_likelihood_inputs[i] = posteriors[i][0]->get_m_likelihood_inputs();
268  break;
269 
270  default:
271  break;
272  }
273 
274  m_likelihood_functions[i] = [&] (vector<double> &par, const shared_ptr<void> input) { return exp(m_log_likelihood_functions[i](par, input)); };
275  m_use_grid[i] = false;
276  m_log_likelihood_functions_grid[i] = NULL;
277  m_likelihood_functions_grid[i] = NULL;
278  }
279 
280  m_set_seed(321);
281 
282 }
283 
284 
285 // ============================================================================================
286 
287 
288 void cbl::statistics::CombinedPosterior::m_check_repeated_par (int dummy_Nposteriors, std::vector<std::shared_ptr<Posterior>> posteriors, std::vector<std::string> repeated_par)
289 {
290  std::vector<bool> at_least_one (repeated_par.size(), false);
291  for (int i=0; i<dummy_Nposteriors; i++) {
292  std::vector<std::string> names = posteriors[i]->get_model_parameters()->name();
293  for (size_t j=0; j<repeated_par.size(); j++) {
294  if (std::count(names.begin(), names.end(), repeated_par[j]))
295  at_least_one[j] = true;
296  else
297  continue;
298  }
299  }
300  for (size_t j=0; j<repeated_par.size(); j++)
301  if (at_least_one[j] == false)
302  ErrorCBL("Wrong parameter name declaration in repeated_par! The parameter \""+repeated_par[j]+"\" does not exist or is not set.", "m_check_repeated_par", "CombinedPosterior.cpp");
303 }
304 
305 
306 // ============================================================================================
307 
308 
309 void cbl::statistics::CombinedPosterior::m_check_common_repeated_par (int dummy_Nposteriors, std::vector<std::shared_ptr<Posterior>> posteriors, std::vector<std::string> repeated_par, std::vector<std::vector<std::vector<int>>> common_repeated_par)
310 {
311  if (common_repeated_par.size() != repeated_par.size())
312  ErrorCBL("The size of common_repeated_par must match the size of repeated_par!", "m_check_common_repeated_par", "CombinedPosterior.cpp");
313  for (size_t cc=0; cc<common_repeated_par.size(); cc++) {
314  std::vector<int> indexes;
315  for (size_t dd=0; dd<common_repeated_par[cc].size(); dd++) {
316  if (common_repeated_par[cc][dd].size() < 2)
317  ErrorCBL("Error in common_repeated_par["+cbl::conv(cc, cbl::par::fINT)+"]["+cbl::conv(dd, cbl::par::fINT)+"]: the vectors must have dimension > 1!", "m_set_parameters_priors", "CombinedPosterior.cpp");
318  for (size_t ee=0; ee<common_repeated_par[cc][dd].size(); ee++) {
319  if (common_repeated_par[cc][dd][ee] > (int)(dummy_Nposteriors-1) || common_repeated_par[cc][dd][ee] < 0)
320  ErrorCBL("Error in common_repeated_par["+cbl::conv(cc, cbl::par::fINT)+"]["+cbl::conv(dd, cbl::par::fINT)+"]: the index "+cbl::conv(common_repeated_par[cc][dd][ee], cbl::par::fINT)+" does not correspond to any probe given in input!", "m_check_common_repeated_par", "CombinedPosterior.cpp");
321  std::vector<std::string> names = posteriors[common_repeated_par[cc][dd][ee]]->get_model_parameters()->name();
322  if (std::count(names.begin(), names.end(), repeated_par[cc]) == false)
323  ErrorCBL("Error in common_repeated_par: the parameter "+repeated_par[cc]+" is not set for the probe with index "+cbl::conv(common_repeated_par[cc][dd][ee], cbl::par::fINT)+"!", "m_check_common_repeated_par", "CombinedPosterior.cpp");
324  else
325  indexes.emplace_back(common_repeated_par[cc][dd][ee]);
326  }
327  }
328  if (cbl::different_elements(indexes).size() != indexes.size())
329  ErrorCBL("Posterior index declared multiple times in common_repeated_par["+cbl::conv(cc, cbl::par::fINT)+"]!", "m_check_common_repeated_par", "CombinedPosterior.cpp");
330  }
331 }
332 
333 
334 // ============================================================================================
335 
336 
337 void cbl::statistics::CombinedPosterior::m_add_prior (bool par_is_repeated, std::vector<std::shared_ptr<Posterior>> posteriors, const int N, const int k, std::vector<std::shared_ptr<cbl::statistics::PriorDistribution>> &prior_distributions)
338 {
339  switch (posteriors[N]->get_model_parameters()->type(k)) {
341  prior_distributions.emplace_back(posteriors[N]->get_model_parameters()->prior_distribution(k));
342  break;
344  break;
346  if (par_is_repeated)
347  ErrorCBL("For the moment, the code can manage only Base and Derived parameters (in the case of repeated parameters)!", "m_add_prior", "CombinedPosterior.cpp");
348  else
349  prior_distributions.emplace_back(posteriors[N]->get_model_parameters()->prior_distribution(k));
350  break;
351  }
352 }
353 
354 
355 // ============================================================================================
356 
357 
358 void cbl::statistics::CombinedPosterior::m_set_common_repeated_par (std::vector<std::shared_ptr<Posterior>> posteriors, const bool is_in_parnames, const int N, const int k, const std::vector<std::string> repeated_par, const std::vector<std::vector<std::vector<int>>> common_repeated_par, std::vector<std::shared_ptr<cbl::statistics::PriorDistribution>> &prior_distributions, std::vector<std::string> &parameter_names, std::vector<std::string> &original_names, std::vector<ParameterType> &parameter_types)
359 {
360  auto itr = std::find(repeated_par.begin(), repeated_par.end(), posteriors[N]->get_model_parameters()->name(k));
361  int the_i = std::distance(repeated_par.begin(), itr);
362  if (common_repeated_par[the_i].size() == 0) {
363  if (is_in_parnames == false)
364  original_names.emplace_back(posteriors[N]->get_model_parameters()->name(k));
365  m_parameter_names[N].emplace_back(posteriors[N]->get_model_parameters()->name(k)+"_Posterior_"+cbl::conv(N+1, cbl::par::fINT));
366  parameter_names.emplace_back(posteriors[N]->get_model_parameters()->name(k)+"_Posterior_"+cbl::conv(N+1, cbl::par::fINT));
367  parameter_types.emplace_back(posteriors[N]->get_model_parameters()->type(k));
368  m_add_prior(true, posteriors, N, k, prior_distributions);
369  } else {
370  for (size_t dd=0; dd<common_repeated_par[the_i].size(); dd++) {
371  std::string posterior_name = "_Posterior_";
372  if (std::count(common_repeated_par[the_i][dd].begin(), common_repeated_par[the_i][dd].end(), N)) {
373  for (size_t ee=0; ee<common_repeated_par[the_i][dd].size(); ee++) {
374  if (ee == common_repeated_par[the_i][dd].size()-1)
375  posterior_name += cbl::conv(common_repeated_par[the_i][dd][ee]+1, cbl::par::fINT);
376  else
377  posterior_name += cbl::conv(common_repeated_par[the_i][dd][ee]+1, cbl::par::fINT)+"_";
378  }
379  m_parameter_names[N].emplace_back(posteriors[N]->get_model_parameters()->name(k)+posterior_name);
380  if (N == common_repeated_par[the_i][dd][0] && std::count(common_repeated_par[the_i][dd].begin(), common_repeated_par[the_i][dd].end(), 0) == false) {
381  if (is_in_parnames == false)
382  original_names.emplace_back(posteriors[N]->get_model_parameters()->name(k));
383  parameter_names.emplace_back(posteriors[N]->get_model_parameters()->name(k)+posterior_name);
384  parameter_types.emplace_back(posteriors[N]->get_model_parameters()->type(k));
385  m_add_prior(true, posteriors, N, k, prior_distributions);
386  }
387  } else if ( std::count(common_repeated_par[the_i][dd].begin(), common_repeated_par[the_i][dd].end(), N) == false ) {
388  bool N_in_one = false;
389  for (size_t new_dd=0; new_dd<common_repeated_par[the_i].size(); new_dd++)
390  if (std::count(common_repeated_par[the_i][new_dd].begin(), common_repeated_par[the_i][new_dd].end(), N))
391  N_in_one = true;
392  if (N_in_one == false && dd == 0) {
393  if (is_in_parnames == false)
394  original_names.emplace_back(posteriors[N]->get_model_parameters()->name(k));
395  m_parameter_names[N].emplace_back(posteriors[N]->get_model_parameters()->name(k)+"_Posterior_"+cbl::conv(N+1, cbl::par::fINT));
396  parameter_names.emplace_back(posteriors[N]->get_model_parameters()->name(k)+"_Posterior_"+cbl::conv(N+1, cbl::par::fINT));
397  parameter_types.emplace_back(posteriors[N]->get_model_parameters()->type(k));
398  m_add_prior(true, posteriors, N, k, prior_distributions);
399  } else
400  continue;
401  }
402  }
403  }
404 }
405 
406 
407 // ============================================================================================
408 
409 
410 void cbl::statistics::CombinedPosterior::m_set_repeated_par (std::vector<std::shared_ptr<Posterior>> posteriors, const bool is_in_parnames, const int N, const int k, const std::vector<std::string> repeated_par, const std::vector<std::vector<std::vector<int>>> common_repeated_par, std::vector<std::shared_ptr<cbl::statistics::PriorDistribution>> &prior_distributions, std::vector<std::string> &parameter_names, std::vector<std::string> &original_names, std::vector<ParameterType> &parameter_types)
411 {
412  // First, check if there are common repeated parameters
413  if (common_repeated_par.size() > 0) {
414  m_set_common_repeated_par(posteriors, is_in_parnames, N, k, repeated_par, common_repeated_par, prior_distributions, parameter_names, original_names, parameter_types);
415  }
416  else {
417  if (is_in_parnames == false)
418  original_names.emplace_back(posteriors[N]->get_model_parameters()->name(k));
419  m_parameter_names[N].emplace_back(posteriors[N]->get_model_parameters()->name(k)+"_Posterior_"+cbl::conv(N+1, cbl::par::fINT));
420  parameter_names.emplace_back(posteriors[N]->get_model_parameters()->name(k)+"_Posterior_"+cbl::conv(N+1, cbl::par::fINT));
421  parameter_types.emplace_back(posteriors[N]->get_model_parameters()->type(k));
422  m_add_prior(true, posteriors, N, k, prior_distributions);
423  }
424 }
425 
426 
427 // ============================================================================================
428 
429 
430 void cbl::statistics::CombinedPosterior::m_set_parameters_priors (std::vector<std::shared_ptr<Posterior>> posteriors, std::vector<std::string> repeated_par, const std::vector<std::vector<std::vector<int>>> common_repeated_par)
431 {
432  const int dummy_Nposteriors = (int)(posteriors.size());
433 
434  // Check repeated_par
435  if (repeated_par.size() > 0)
436  m_check_repeated_par(dummy_Nposteriors, posteriors, repeated_par);
437 
438  // Check common_repeated_par
439  if (common_repeated_par.size() > 0)
440  m_check_common_repeated_par(dummy_Nposteriors, posteriors, repeated_par, common_repeated_par);
441 
442  // Set the parameter types, names and priors, starting from the first Posterior object
443  std::vector<ParameterType> parameter_types = posteriors[0]->get_model_parameters()->type();
444  std::vector<std::string> parameter_names = posteriors[0]->get_model_parameters()->name();
445 
446  std::vector<std::shared_ptr<cbl::statistics::PriorDistribution>> prior_distributions;
447  for (size_t k=0; k<parameter_types.size(); k++)
448  m_add_prior(false, posteriors, 0, k, prior_distributions);
449 
450  std::vector<std::string> original_names = parameter_names;
451 
452  m_parameter_names.resize(posteriors.size());
453  m_parameter_names[0] = parameter_names;
454 
455  // If the number Posterior objects is >1, set the other parameters
456  if (dummy_Nposteriors > 1) {
457  for (int N=1; N<dummy_Nposteriors; N++) {
458  for (size_t k=0; k<posteriors[N]->get_model_parameters()->name().size(); k++) {
459 
460  const bool is_in_parnames = std::count(original_names.begin(), original_names.end(), posteriors[N]->get_model_parameters()->name(k));
461  const bool is_repeated = std::count(repeated_par.begin(), repeated_par.end(), posteriors[N]->get_model_parameters()->name(k));
462 
463  if (is_in_parnames && is_repeated == false) {
464  m_parameter_names[N].emplace_back(posteriors[N]->get_model_parameters()->name(k));
465  }
466  else if (is_in_parnames == false && is_repeated == false) {
467  original_names.emplace_back(posteriors[N]->get_model_parameters()->name(k));
468 
469  m_parameter_names[N].emplace_back(posteriors[N]->get_model_parameters()->name(k));
470  parameter_names.emplace_back(posteriors[N]->get_model_parameters()->name(k));
471  parameter_types.emplace_back(posteriors[N]->get_model_parameters()->type(k));
472  m_add_prior(false, posteriors, N, k, prior_distributions);
473  }
474  else if (is_repeated) {
475  m_set_repeated_par(posteriors, is_in_parnames, N, k, repeated_par, common_repeated_par, prior_distributions, parameter_names, original_names, parameter_types);
476  }
477  }
478  }
479  }
480 
481  m_Nparameters = (int)(parameter_types.size());
482 
483 
484  // Rename the parameters of the first probe, if necessary
485  if (repeated_par.size() > 0) {
486  if (common_repeated_par.size() > 0) {
487  for (size_t i=0; i<posteriors[0]->get_model_parameters()->name().size(); i++) {
488  if (std::count(repeated_par.begin(), repeated_par.end(), posteriors[0]->get_model_parameters()->name(i))) {
489  auto itr = std::find(repeated_par.begin(), repeated_par.end(), posteriors[0]->get_model_parameters()->name(i));
490  int the_i = std::distance(repeated_par.begin(), itr);
491  if (common_repeated_par[the_i].size() > 0) {
492  for (size_t jj=0; jj<common_repeated_par[the_i].size(); jj++) {
493  if (common_repeated_par[the_i][jj].size() > 0) {
494  if (std::count(common_repeated_par[the_i][jj].begin(), common_repeated_par[the_i][jj].end(), 0)) {
495  parameter_names[i] += "_Posterior_";
496  m_parameter_names[0][i] += "_Posterior_";
497  for (size_t dd=0; dd<common_repeated_par[the_i][jj].size(); dd++) {
498  if (dd == common_repeated_par[the_i][jj].size()-1) {
499  parameter_names[i] += cbl::conv(common_repeated_par[the_i][jj][dd]+1, cbl::par::fINT);
500  m_parameter_names[0][i] += cbl::conv(common_repeated_par[the_i][jj][dd]+1, cbl::par::fINT);
501  } else {
502  parameter_names[i] += cbl::conv(common_repeated_par[the_i][jj][dd]+1, cbl::par::fINT)+"_";
503  m_parameter_names[0][i] += cbl::conv(common_repeated_par[the_i][jj][dd]+1, cbl::par::fINT)+"_";
504  }
505  }
506  } else if (std::count(common_repeated_par[the_i][jj].begin(), common_repeated_par[the_i][jj].end(), 0) == false) {
507  bool zero_in_one = false;
508  for (size_t new_jj=0; new_jj<common_repeated_par[the_i].size(); new_jj++)
509  if (std::count(common_repeated_par[the_i][new_jj].begin(), common_repeated_par[the_i][new_jj].end(), 0))
510  zero_in_one = true;
511  if (zero_in_one == false && jj == 0) {
512  parameter_names[i] += "_Posterior_1";
513  m_parameter_names[0][i] += "_Posterior_1";
514  } else
515  continue;
516  }
517  } else if (common_repeated_par[the_i][jj].size() == 0) {
518  parameter_names[i] += "_Posterior_1";
519  m_parameter_names[0][i] += "_Posterior_1";
520  }
521  }
522  } else {
523  parameter_names[i] += "_Posterior_1";
524  m_parameter_names[0][i] += "_Posterior_1";
525  }
526  }
527  }
528  } else if (common_repeated_par.size() == 0) {
529  for (size_t i=0; i<posteriors[0]->get_model_parameters()->name().size(); i++)
530  if (std::count(repeated_par.begin(), repeated_par.end(), posteriors[0]->get_model_parameters()->name(i))) {
531  parameter_names[i] += "_Posterior_1";
532  m_parameter_names[0][i] += "_Posterior_1";
533  }
534  }
535  }
536 
537  // Set m_model_parameters
538  cbl::statistics::PosteriorParameters posterior_par (m_Nparameters, prior_distributions, parameter_types, parameter_names);
539  m_model_parameters = std::make_shared<PosteriorParameters>(posterior_par);
540 
541  // Print the parameters for each probe on screen
542  std::cout<<std::endl;
543  for (size_t i=0; i<m_parameter_names.size(); i++) {
544  coutCBL<<"For the probe "<<i+1<<" (with internal index "<<i<<"), the following parameters are set:\n";
545  for (size_t j=0; j<m_parameter_names[i].size(); j++) {
546  if (j == m_parameter_names[i].size()-1)
547  std::cout<<m_parameter_names[i][j]<<std::endl<<std::endl;
548  else if (j==0)
549  coutCBL<<m_parameter_names[i][j]<<", ";
550  else
551  std::cout<<m_parameter_names[i][j]<<", ";
552  }
553  }
554  coutCBL<<"Thus the guess vector should be sorted in this way:\n";
555  for (size_t j=0; j<parameter_names.size(); j++)
556  if (j == parameter_names.size()-1)
557  std::cout<<parameter_names[j]<<std::endl<<std::endl;
558  else if (j==0)
559  coutCBL<<parameter_names[j]<<", ";
560  else
561  std::cout<<parameter_names[j]<<", ";
562 
563 
564  // Find the indexes of the cosmological parameters, if any.
565  // This is useful for the super-sample covariance.
566  std::vector<std::string> cosmoNames = cbl::cosmology::CosmologicalParameterNames();
567  for (size_t i=0; i<parameter_names.size(); i++)
568  if (std::count(cosmoNames.begin(), cosmoNames.end(), parameter_names[i]))
569  m_cosmoPar_indexes.emplace_back(i);
570 
571  // Check if any cosmological parameter is repeated
572  for (size_t i=0; i<repeated_par.size(); i++)
573  if (std::count(cosmoNames.begin(), cosmoNames.end(), repeated_par[i]))
574  ErrorCBL("You cannot have more than one posterior for a cosmological parameter ("+repeated_par[i]+" in this case)!", "m_set_parameters_priors", "CombinedPosterior.cpp");
575 }
576 
577 
578 // ============================================================================================
579 
580 
582 {
583  m_use_grid.resize(m_Nposteriors);
584  m_models.resize(m_Nposteriors);
585  m_datasets.resize(m_Nposteriors);
586  m_likelihood_inputs.resize(m_Nposteriors);
587  m_log_likelihood_functions_grid.resize(m_Nposteriors);
588  m_log_likelihood_functions.resize(m_Nposteriors);
589  m_likelihood_functions.resize(m_Nposteriors);
590  m_likelihood_functions_grid.resize(m_Nposteriors);
591 
592  for(int N=0; N<m_Nposteriors; N++) {
593  m_use_grid[N] = m_posteriors[N]->get_m_use_grid();
594  m_models[N] = m_posteriors[N]->get_m_model();
595  m_datasets[N] = m_posteriors[N]->get_m_data();
596  m_likelihood_inputs[N] = m_posteriors[N]->get_m_likelihood_inputs();
597  m_log_likelihood_functions_grid[N] = m_posteriors[N]->get_m_log_likelihood_function_grid();
598  m_log_likelihood_functions[N] = m_posteriors[N]->get_m_log_likelihood_function();
599  m_likelihood_functions[N] = m_posteriors[N]->get_m_likelihood_function();
600  m_likelihood_functions_grid[N] = m_posteriors[N]->get_m_likelihood_function_grid();
601  }
602 
603  m_seed = m_posteriors[0]->m_get_seed();
604  m_set_seed(m_seed);
605 
606  // Set the parameter indexes
607  m_parameter_indexes.resize(m_Nposteriors);
608  m_parameter_indexes2.resize(m_Nposteriors);
609  for(int N=0; N<m_Nposteriors; N++) {
610  for (size_t k=0; k<m_parameter_names[N].size(); k++) {
611  for(int j=0; j<m_Nparameters; j++) {
612  if (m_parameter_names[N][k] == m_model_parameters->name(j)) {
613  m_parameter_indexes[N].emplace_back(j);
614  m_parameter_indexes2[N].emplace_back(j);
615  }
616  }
617  }
618  }
619 
620 }
621 
622 
623 // ============================================================================================
624 
625 
626 void cbl::statistics::CombinedPosterior::set_parameters (const std::vector<std::vector<double>> parametersA, const std::vector<std::vector<double>> parametersB)
627 {
628  std::vector<std::vector<double>> parameters (m_Nparameters);
629  for(int N=0; N<m_Nparameters; N++){
630  parameters[N].insert(parameters[N].end(), parametersA[N].begin(), parametersA[N].end());
631  parameters[N].insert(parameters[N].end(), parametersB[N].begin(), parametersB[N].end());
632  }
633  m_parameters = parameters;
634  parameters.clear();
635 }
636 
637 
638 // ============================================================================================
639 
640 
641 void cbl::statistics::CombinedPosterior::set_log_posterior (const std::vector<double> logpostA, const std::vector<double> logpostB)
642 {
643  m_log_posterior.reserve(logpostA.size() + logpostB.size()); // preallocate memory
644  m_log_posterior.insert(m_log_posterior.end(), logpostA.begin(), logpostA.end());
645  m_log_posterior.insert(m_log_posterior.end(), logpostB.begin(), logpostB.end());
646 }
647 
648 
649 // ============================================================================================
650 
651 void cbl::statistics::CombinedPosterior::set_weight (const std::vector<double> weightsA, const std::vector<double> weightsB)
652 {
653 
654  m_weight.reserve(weightsA.size() + weightsB.size()); // preallocate memory
655  m_weight.insert(m_weight.end(), weightsA.begin(), weightsA.end());
656  m_weight.insert(m_weight.end(), weightsB.begin(), weightsB.end());
657 
658 }
659 
660 // ============================================================================================
661 
662 void cbl::statistics::CombinedPosterior::importance_sampling (const int distNum, const double cell_size, const double rMAX, const double cut_sigma)
663 {
664  std::vector<std::vector<double>> parametersA = m_posteriors[0]->get_parameters();
665  std::vector<std::vector<double>> parametersB = m_posteriors[1]->get_parameters();
666  std::vector<double> logpostA = m_posteriors[0]->get_log_posterior();
667  std::vector<double> logpostB = m_posteriors[1]->get_log_posterior();
668 
669  set_parameters(parametersA, parametersB);
670  set_log_posterior(logpostA, logpostB);
671 
672  // initialize the Chain Mesh for interpolation
673  cbl::chainmesh::ChainMesh chmesh(cell_size, m_Nparameters);
674 
675  // interpolate using chainmesh
676  std::vector<double> logpostA_interpolated = chmesh.interpolate(parametersA, logpostA, parametersB, distNum, rMAX);
677  std::vector<double> logpostB_interpolated = chmesh.interpolate(parametersB, logpostB, parametersA, distNum, rMAX);
678 
679  // compute shifts
680 
681  double shift_A = *max_element(logpostA.begin(), logpostA.end()) - *max_element(logpostB_interpolated.begin(), logpostB_interpolated.end());
682  double shift_B = *max_element(logpostB.begin(), logpostB.end()) - *max_element(logpostA_interpolated.begin(), logpostA_interpolated.end());
683 
684  // compute m_weight
685 
686  std::vector<double> weights_A(logpostA.size());
687  std::vector<double> weights_B(logpostB.size());
688 
689  for(size_t ii=0; ii<logpostA.size(); ii++) weights_A[ii] = exp(logpostB_interpolated[ii] - logpostA[ii] + shift_A);
690  for(size_t ii=0; ii<logpostB.size(); ii++) weights_B[ii] = exp(logpostA_interpolated[ii] - logpostB[ii] + shift_B);
691 
692  // cut weights distribution if cut_sigma!=-1
693  if(cut_sigma>0)
694  {
695  const double mean_A = cbl::Average(weights_A);
696  const double mean_B = cbl::Average(weights_B);
697  const double sigma_A = cbl::Sigma(weights_A);
698  const double sigma_B = cbl::Sigma(weights_B);
699 
700  for(size_t ii=0; ii<weights_A.size(); ii++)
701  if(weights_A[ii]>mean_A+cut_sigma*sigma_A) weights_A[ii] = mean_A;
702  for(size_t ii=0; ii<weights_B.size(); ii++)
703  if(weights_B[ii]>mean_B+cut_sigma*sigma_B) weights_B[ii] = mean_B;
704  }
705 
706  set_weight(weights_A, weights_B);
707 }
708 
709 
710 // ============================================================================================
711 
712 
713 void cbl::statistics::CombinedPosterior::importance_sampling (const std::string output_path, const std::string model_nameA, const std::string model_nameB, const std::vector<double> start, const int chain_size, const int nwalkers, const int burn_in, const int thin)
714 {
715  if(m_Nposteriors != 2) ErrorCBL("You can't do importance sampling for a number of probes > 2", "importance_sampling", "CombinedPosterior.cpp");
716 
717  impsampling = true;
718  std::vector<std::string> modelnames(m_Nposteriors);
719  modelnames[0] = model_nameA;
720  modelnames[1] = model_nameB;
721 
722  std::string file_AB = model_nameA+"_post_"+model_nameB;
723  std::string file_BA = model_nameB+"_post_"+model_nameA;
724 
725  for(int N=0; N<m_Nposteriors; N++){
726  m_posteriors[N]->initialize_chains(chain_size, nwalkers, 1.e-5, start);
727  coutCBL << "Sampling the posterior distribution for " << modelnames[N] << endl << endl;
728  m_posteriors[N]->sample_stretch_move(2);
729  m_posteriors[N]->write_results(output_path, modelnames[N], burn_in, thin);
730  cout << endl;
731  }
732 
733  coutCBL << "Doing importance sampling for " << modelnames[0] << "_post_" << modelnames[1] << ".." << endl;
734  m_posteriors[0]->importance_sampling(output_path, modelnames[1]+"_chain.dat");
735  m_posteriors[0]->write_results(output_path, file_AB);
736  cout << endl;
737  coutCBL << "Doing importance sampling for " << modelnames[1] << "_post_" << modelnames[0] << ".." << endl;
738  m_posteriors[1]->importance_sampling(output_path, modelnames[0]+"_chain.dat");
739  m_posteriors[1]->write_results(output_path, file_BA);
740 
741  std::vector<std::vector<double>> chainA;
742  std::vector<std::vector<double>> chainB;
743 
744  chainA = read(output_path, file_AB+"_chain.dat");
745  chainB = read(output_path, file_BA+"_chain.dat");
746 
747  std::vector<std::vector<double>> parametersA (m_Nparameters, std::vector<double> (chainA.size()));
748  std::vector<std::vector<double>> parametersB (m_Nparameters, std::vector<double> (chainB.size()));
749  std::vector<double> weightsAB = m_posteriors[0]->weight();
750  std::vector<double> weightsBA = m_posteriors[1]->weight();
751 
752  for(int N=1; N<m_Nparameters+1; N++){
753  for(size_t ii=0; ii<chainA.size(); ii++){
754  parametersA[N-1][ii] = chainA[ii][N];
755  parametersB[N-1][ii] = chainB[ii][N];
756  }
757  }
758 
759  set_log_posterior(m_posteriors[0]->get_log_posterior(), m_posteriors[1]->get_log_posterior());
760  set_parameters(parametersA, parametersB);
761  set_weight(weightsAB, weightsBA);
762 }
763 
764 
765 // ============================================================================================
766 
767 
768 void cbl::statistics::CombinedPosterior::initialize_chains (const int chain_size, const int n_walkers, const double radius, const std::vector<double> start, const unsigned int max_iter, const double tol, const double epsilon)
769 {
770  maximize(start, max_iter, tol, epsilon);
771  m_model_parameters->set_chain(chain_size, n_walkers);
772  m_model_parameters->initialize_chain_ball_bestfit(radius, m_generate_seed());
773 }
774 
775 
776 // ============================================================================================
777 
778 
779 void cbl::statistics::CombinedPosterior::initialize_chains (const int chain_size, const int n_walkers)
780 {
781  m_model_parameters->set_chain(chain_size, n_walkers);
782  m_model_parameters->initialize_chain_from_prior();
783 }
784 
785 
786 // ============================================================================================
787 
788 
789 void cbl::statistics::CombinedPosterior::initialize_chains (const int chain_size, const int n_walkers, const std::string input_dir, const std::string input_file, const int seed)
790 {
791  m_set_seed(seed);
792 
793  m_model_parameters->set_chain(chain_size, n_walkers);
794 
795  string last_step_file = input_dir+input_file+"_LastStep";
796  string get_last_step = "tail -n "+conv(n_walkers, par::fINT)+" "+input_dir+input_file+" > "+last_step_file;
797  if (system(get_last_step.c_str())) {}
798 
799  ifstream fin(last_step_file);
800  string line;
801 
802  vector<vector<double>> chain_value;
803 
804  while (getline(fin, line))
805  {
806  stringstream ss(line);
807  double NUM;
808  vector<double> ll, params;
809 
810  while (ss>>NUM) ll.push_back(NUM);
811  for (size_t i=1; i<ll.size()-4; i++)
812  params.push_back(ll[i]);
813 
814  chain_value.push_back(params);
815  }
816  fin.clear(); fin.close();
817 
818  string rm_last_step = "rm -r "+last_step_file;
819  if (system(rm_last_step.c_str())) {}
820 
821  checkDim(chain_value, n_walkers, m_model_parameters->nparameters(), "chain_from_LastStep_file");
822  chain_value = cbl::transpose(chain_value);
823 
824  for (size_t pp=0; pp<m_model_parameters->nparameters(); pp++)
825  for (int ww=0; ww<n_walkers; ww++)
826  m_model_parameters->set_chain_value(pp, 0, ww, chain_value[pp][ww]);
827 }
828 
829 
830 // ============================================================================================
831 
832 
833 void cbl::statistics::CombinedPosterior::sample_stretch_move (const double aa, const bool parallel, const std::string outputFile, const int start, const int thin, const int nbins)
834 {
835  if (parallel && outputFile!=cbl::par::defaultString)
836  WarningMsgCBL("no run-time output available for parallel stretch-move algorithm: this option will be ignored!", "sample_stretch_move", "Posterior.cpp");
837 
838  coutCBL << "Sampling the posterior..." << endl;
839 
840  const int seed = m_generate_seed();
841  const int nparameters = m_model_parameters->nparameters();
842  const int nparameters_free = m_model_parameters->nparameters_free();
843  const int chain_size = m_model_parameters->chain_size();
844  const int n_walkers = m_model_parameters->chain_nwalkers();
845 
846  vector<vector<double>> Start(n_walkers, vector<double>(nparameters, 0));
847 
848  for (int i=0; i<nparameters; i++)
849  for (int j=0; j<n_walkers; j++)
850  Start[j][i] = m_model_parameters->chain_value(i, 0, j);
851 
852  auto posterior = [this] (vector<double> &pp) { return log(pp); };
853 
854  cbl::statistics::Sampler sampler(nparameters, nparameters_free, posterior);
855  if (parallel)
856  sampler.sample_stretch_move_parallel(chain_size, n_walkers, Start, seed, aa);
857  else
858  sampler.sample_stretch_move(chain_size, n_walkers, Start, seed, aa, outputFile);
859 
860  vector<vector<double>> chain_values;
861 
862  sampler.get_chain_function_acceptance(chain_values, m_log_posterior, m_acceptance);
863 
864  m_model_parameters->set_chain_values(chain_values, n_walkers);
865  m_model_parameters->set_bestfit_values(start, thin, nbins, m_generate_seed());
866  m_weight.erase(m_weight.begin(), m_weight.end());
867  m_weight.resize(m_log_posterior.size(), 1.);
868 
869  // Set the chain values also for each Model
870  for (size_t i=0; i<m_models.size(); i++) {
871  vector<vector<double>> probe_chain_values;
872  probe_chain_values.resize(m_parameter_indexes2[i].size());
873  for (size_t j=0; j<m_parameter_indexes2[i].size(); j++)
874  probe_chain_values[j] = chain_values[m_parameter_indexes2[i][j]];
875  m_models[i]->parameters()->set_chain_values(probe_chain_values, n_walkers);
876  m_models[i]->parameters()->set_bestfit_values(start, thin, nbins, m_generate_seed());
877  }
878 
879 }
880 
881 
882 // ============================================================================================
883 
884 
885 double cbl::statistics::CombinedPosterior::operator () (std::vector<double> &pp) const
886 {
887  pp = m_model_parameters->full_parameter(pp);
888  double prior = m_model_parameters->prior()->operator()(pp);
889 
890  double val = 1.;
891 
892  for(int N=0; N<m_Nposteriors; N++)
893  {
894  if(prior<=0)
895  {
896  val = 0.;
897  break;
898  }
899  std::vector<double> pp_single (m_parameter_indexes.size(), 0);
900  for (size_t ii=0; ii<pp_single.size(); ii++)
901  pp_single[ii] = pp[m_parameter_indexes[N][ii]];
902  val *= (m_use_grid[N]) ? m_likelihood_functions_grid[N](pp_single, m_likelihood_inputs[N]) : m_likelihood_functions[N](pp_single, m_likelihood_inputs[N]);
903  for (size_t ii=0; ii<pp_single.size(); ii++)
904  pp[m_parameter_indexes[N][ii]] = pp_single[ii]; // this is necessary in presence of derived parameters
905  }
906 
907  return val*prior;
908 }
909 
910 
911 // ============================================================================================
912 
913 
914 double cbl::statistics::CombinedPosterior::log (std::vector<double> &pp) const
915 {
916  pp = m_model_parameters->full_parameter(pp);
917 
918  const double logprior = m_model_parameters->prior()->log(pp);
919 
920  double val = 0.;
921 
922  for(int N=0; N<m_Nposteriors; N++)
923  {
924  if (logprior>par::defaultDouble) {
925  std::vector<double> pp_single (m_parameter_indexes[N].size(), 0);
926  for (size_t ii=0; ii<pp_single.size(); ii++)
927  pp_single[ii] = pp[m_parameter_indexes[N][ii]];
928  val += (m_use_grid[N]) ? m_log_likelihood_functions_grid[N](pp_single, m_likelihood_inputs[N]) : m_log_likelihood_functions[N](pp_single, m_likelihood_inputs[N]);
929  for (size_t ii=0; ii<pp_single.size(); ii++)
930  pp[m_parameter_indexes[N][ii]] = pp_single[ii]; // this is necessary in presence of derived parameters
931  }
932  else
933  {
934  val = par::defaultDouble;
935  break;
936  }
937  }
938 
939  return val+logprior;
940 }
941 
942 
943 // ============================================================================================
944 
945 
946 void cbl::statistics::CombinedPosterior::maximize (const std::vector<double> start, const unsigned int max_iter, const double tol, const double epsilon)
947 {
948  vector<double> starting_par;
949 
950  unsigned int npar = m_model_parameters->nparameters();
951  unsigned int npar_free = m_model_parameters->nparameters_free();
952 
953  if (start.size()==npar_free)
954  starting_par = start;
955  else if (start.size()==npar)
956  for (size_t i=0; i<npar_free; i++)
957  starting_par.push_back(start[m_model_parameters->free_parameter()[i]]);
958  else
959  ErrorCBL("check your inputs: start.size()="+conv(start.size(), par::fINT)+" must be equal to either npar_free="+conv(npar_free, par::fINT)+" or npar="+conv(npar, par::fINT)+"!", "maximize", "CombinedPosterior.cpp");
960 
961  function<double(vector<double> &)> post = [this](vector<double> &pp) { return -this->log(pp); };
962 
963 
964  // extra check on epsilon
965 
966  function<bool(vector<double> &)> checkWrong = [&] (vector<double> &pp)
967  {
968  bool ch = true;
969  if (post(pp)<-par::defaultDouble)
970  ch = false;
971  return ch;
972  };
973 
974  vector<double> par = starting_par;
975  if (checkWrong(par))
976  ErrorCBL("The starting position is outside the prior range: the first input parameter must be changed!", "maximize", "CombinedPosterior.cpp");
977 
978  // loop on simplex side
979  for (size_t i=0; i<npar_free; i++) {
980  par = starting_par;
981  par[i] += epsilon;
982  if (checkWrong(par))
983  ErrorCBL("The simplex side is outside prior range: the epsilon parameter or the starting position must be changed.", "maximize", "CombinedPosterior.cpp");
984  }
985 
986  // everything is fine up to here... let's go
987  coutCBL << "Maximizing the posterior..." << endl;
988  vector<double> result = cbl::wrapper::gsl::GSL_minimize_nD(post, starting_par, {}, max_iter, tol, epsilon);
989  // check if the result is inside the prior ranges
990 
991  if(m_model_parameters->prior()->log(result)<=par::defaultDouble)
992  ErrorCBL("the maximization ended with parameter values out of the priors: check your inputs or change the epsilon value!", "maximize", "CombinedPosterior.cpp");
993 
994  coutCBL << "Done!" << endl << endl;
995 
996  m_model_parameters->set_bestfit_values(result);
997  m_model_parameters->write_bestfit_info();
998 
999  coutCBL << "log(posterior) = " << post(result) << endl << endl;
1000 
1001 }
1002 
1003 
1004 // ============================================================================================
1005 
1006 
1007 void cbl::statistics::CombinedPosterior::show_results (const int start, const int thin, const int nbins, const bool show_mode, const int ns, const int nb)
1008 {
1009  if(!impsampling) Posterior::show_results(start, thin, nbins, show_mode, ns, nb);
1010  else{
1011  for (int i=0; i<m_Nparameters; i++){
1012  coutCBL << "Parameter: " << par::col_yellow << this->parameters()->name(i) << par::col_default << endl;
1013  coutCBL << "Weighted Average: " << cbl::Average(m_parameters[i], m_weight) << endl;
1014  coutCBL << "Standard Deviation: " << cbl::Sigma(m_parameters[i], m_weight) << endl << endl;
1015  }
1016  }
1017 }
1018 // ============================================================================================
1019 
1020 
1021 void cbl::statistics::CombinedPosterior::write_results (const string output_dir, const string root_file, const int start, const int thin, const int nbins, const bool fits, const bool compute_mode, const int ns, const int nb)
1022 {
1023  if(!impsampling){
1024  const string extension = (fits) ? "_chain.fits" : "_chain.dat";
1025  write_chain(output_dir, root_file+extension, start, thin, fits);
1026  m_model_parameters->write_results(output_dir, root_file, start, thin, nbins, m_generate_seed(), compute_mode, ns, nb, weight(start, thin));
1027  }
1028  else {
1029  string file = output_dir+root_file+"_chain.dat";
1030  ofstream fout(file.c_str()); checkIO(fout, file);
1031 
1032  fout << "# step" << setw(25);
1033  for (int k=0; k<m_Nparameters; k++){
1034  fout << this->parameters()->name(k) << setw(25);
1035  }
1036  fout << "log(Posterior)" << setw(25) << "Weight" << endl;
1037 
1038  fout << std::fixed;
1039  fout << setprecision(7);
1040 
1041  for(size_t ii=0; ii<m_weight.size(); ii++)
1042  {
1043  fout << ii;
1044  for(int N=0; N<m_Nparameters; N++){
1045  fout << setw(25) << std::fixed << m_parameters[N][ii];
1046  }
1047  fout << setw(25) << std::fixed << m_log_posterior[ii] << setw(25) << std::scientific << m_weight[ii] << endl;
1048  }
1049  fout.clear(); fout.close();
1050 
1051  coutCBL << "I wrote the file: " << file << endl;
1052  }
1053 }
1054 
1055 
1056 // ============================================================================================
1057 
1058 
1059 void cbl::statistics::CombinedPosterior::write_chain (const string output_dir, const string output_file, const int start, const int thin, const bool is_FITS_format, const int prec, const int ww)
1060 {
1061  if (is_FITS_format)
1062  write_chain_fits(output_dir, output_file, start, thin);
1063  else
1064  write_chain_ascii(output_dir, output_file, start, thin, prec, ww);
1065 }
1066 
1067 
1068 // ============================================================================================
1069 
1070 
1071 void cbl::statistics::CombinedPosterior::write_chain_ascii (const string output_dir, const string output_file, const int start, const int thin, const int prec, const int ww)
1072 {
1073  const int nparameters = m_model_parameters->nparameters();
1074  const int chain_size = m_model_parameters->chain_size();
1075  const int n_walkers = m_model_parameters->chain_nwalkers();
1076 
1077  checkDim(m_log_posterior, n_walkers*chain_size, "m_log_posterior", false);
1078 
1079  string MK = "mkdir -p "+output_dir;
1080  if (system(MK.c_str())) {}
1081 
1082  string file = output_dir+output_file;
1083 
1084  ofstream fout(file.c_str()); checkIO(fout, file);
1085  fout.precision(10);
1086 
1087  fout << "# step ";
1088  for (int k=0; k<nparameters; k++)
1089  fout << m_model_parameters->name(k) << " ";
1090  fout << " log(Likelihood) log(Prior) log(Posterior) Weight" << endl;
1091 
1092  int nn = 0;
1093 
1094  for (int j=start; j<chain_size; j+=thin) {
1095  for (int i=0; i<n_walkers; i++) {
1096  fout << setw(6) << nn++ << " ";
1097 
1098  vector<double> pp(nparameters);
1099 
1100  for (int k=0; k<nparameters; k++) {
1101  pp[k] = m_model_parameters->chain_value(k, j, i);
1102  cbl::Print(m_model_parameters->chain_value(k, j, i), prec, ww, "", " ", false, fout);
1103  }
1104 
1105  double pr = m_model_parameters->prior()->log(pp);
1106  cbl::Print(m_log_posterior[j*n_walkers+i]-pr, prec, ww, "", " ", false, fout);
1107  cbl::Print(pr, prec, ww, "", " ", false, fout);
1108 
1109  cbl::Print(m_log_posterior[j*n_walkers+i], prec, ww, "", " ", false, fout);
1110  cbl::Print(m_weight[j*n_walkers+i], prec, ww, "", "\n", false, fout);
1111  }
1112  }
1113 
1114  fout.clear(); fout.close();
1115 
1116  coutCBL << "I wrote the file: " << file << endl;
1117 }
1118 
1119 
1120 // ============================================================================================
1121 
1122 
1123 void cbl::statistics::CombinedPosterior::write_chain_fits (const string output_dir, const string output_file, const int start, const int thin)
1124 {
1125  const int nparameters = m_model_parameters->nparameters();
1126  const int chain_size = m_model_parameters->chain_size();
1127  const int n_walkers = m_model_parameters->chain_nwalkers();
1128 
1129  checkDim(m_log_posterior, n_walkers*chain_size, "m_log_posterior", false);
1130 
1131  string MK = "mkdir -p "+output_dir;
1132  if (system(MK.c_str())) {}
1133 
1134  vector<string> names;
1135  names.push_back("Step");
1136  for (int k=0; k<nparameters; k++)
1137  names.emplace_back(m_model_parameters->name(k));
1138 
1139  names.push_back("Log(Likelihood)");
1140  names.push_back("Log(Prior)");
1141  names.push_back("Log(Posterior)");
1142  names.push_back("Weight");
1143 
1144  vector<vector<double>> value(nparameters+5);
1145 
1146  int n = 0;
1147  for (int j=start; j<chain_size; j+=thin)
1148  for (int i=0; i<n_walkers; i++) {
1149  value[0].emplace_back(n);
1150  vector<double> pp(nparameters);
1151  for (int k=0; k<nparameters; k++) {
1152  value[k+1].emplace_back(m_model_parameters->chain_value(k, j, i));
1153  pp[k] = m_model_parameters->chain_value(k, j, i);
1154  }
1155 
1156 
1157  double lpr = m_model_parameters->prior()->log(pp);
1158  value[nparameters+1].emplace_back(m_log_posterior[j*n_walkers+i]-lpr);
1159  value[nparameters+2].emplace_back(lpr);
1160 
1161  value[nparameters+3].emplace_back(m_log_posterior[j*n_walkers+i]);
1162  value[nparameters+4].emplace_back(m_weight[j*n_walkers+i]);
1163  n ++;
1164  }
1165 
1166  cbl::wrapper::ccfits::write_table_fits(output_dir, output_file, names, value);
1167 
1168 }
1169 
1170 
1171 // ============================================================================================
1172 
1173 
1174 void cbl::statistics::CombinedPosterior::write_model_from_chain (const std::string output_dir, const std::string output_file, const int start, const int thin, const std::vector<double> xx, const std::vector<double> yy)
1175 {
1176  for(size_t N=0; N<m_models.size(); N++) {
1177 
1178  switch (m_models[N]->dimension()) {
1179 
1180  case Dim::_1D_:
1181  {
1182  vector<double> xvec = (xx.size() > 0) ? xx : m_datasets[N]->xx();
1183  m_models[N]->write_from_chains(output_dir, std::to_string(N)+"_"+output_file, xvec, start, thin);
1184  }
1185  break;
1186 
1187  case Dim::_2D_:
1188  {
1189  vector<double> xvec = (xx.size() > 0) ? xx : m_datasets[N]->xx();
1190  vector<double> yvec = (yy.size() > 0) ? yy : m_datasets[N]->yy();
1191  m_models[N]->write_from_chains(output_dir, std::to_string(N)+"_"+output_file, xvec, yvec, start, thin);
1192  }
1193  break;
1194 
1195  default:
1196  ErrorCBL("the input dimension must be Dim::_1D_ or Dim::_2D_ !", "write_model_from_chain", "CombinedPosterior.cpp");
1197 
1198  }
1199  }
1200 }
1201 
1202 
1203 // ============================================================================================
1204 
1205 
1206 void cbl::statistics::CombinedPosterior::write_maximization_results (const std::string dir_output, const std::string file)
1207 {
1208  coutCBL << "Writing results of posterior maximization on " << dir_output+file << endl;
1209  vector<double> bestFitValues = m_model_parameters->bestfit_value();
1210  string name = LikelihoodTypeNames ()[static_cast<int>(m_likelihood_type)];
1211  double posteriorValue = this->log(bestFitValues);
1212 
1213  string mkdir = "mkdir -p "+dir_output;
1214  if (system(mkdir.c_str())) {}
1215 
1216  ofstream fout(dir_output+file);
1217 
1218  fout << "#Parameters information" << endl;
1219  fout << "number of parameters = " << bestFitValues.size() << endl;
1220 
1221  for (size_t i=0; i<bestFitValues.size(); i++) {
1222  fout << "par" << i+1 << "_name = " << m_model_parameters->name(i) << endl;
1223  fout << "par" << i+1 << "_status = " << m_model_parameters->status(i) << endl;
1224  fout << "par" << i+1 << "_bestfit_value = " << bestFitValues[i] << endl;
1225  }
1226 
1227  fout << "#Likelihood information" << endl;
1228  fout << "likelihoodType = " << name << endl;
1229  fout << "logPosteriorValue = " << posteriorValue << endl;
1230 
1231  fout.clear(); fout.close();
1232  coutCBL << "I wrote the file " << dir_output+file << endl;
1233 }
1234 
1235 
1236 // ============================================================================================
1237 
1238 
1239 std::vector<std::vector<double>> cbl::statistics::CombinedPosterior::read (const std::string path, const std::string filename)
1240 {
1241  std::vector< std::vector<double>> table;
1242  std::fstream ifs;
1243 
1244  ifs.open(path+filename);
1245 
1246  while (true)
1247  {
1248  std::string line;
1249  double buf;
1250  getline(ifs, line);
1251 
1252  std::stringstream ss(line, std::ios_base::out|std::ios_base::in|std::ios_base::binary);
1253 
1254  if (!ifs)
1255  // mainly catch EOF
1256  break;
1257 
1258  if (line[0] == '#' || line.empty())
1259  // catch empty lines or comment lines
1260  continue;
1261 
1262  std::vector<double> row;
1263 
1264  while (ss >> buf)
1265  row.push_back(buf);
1266 
1267  table.push_back(row);
1268  }
1269 
1270  ifs.close();
1271 
1272  return table;
1273 }
1274 
1275 
1276 // ============================================================================================
1277 
1278 
1279 double cbl::statistics::LogLikelihood_Gaussian_combined (std::vector<double> &likelihood_parameter, const std::shared_ptr<void> fixed_parameter)
1280 {
1281  // ----- extract the parameters -----
1282  shared_ptr<statistics::STR_DependentProbes_data_model> pp = static_pointer_cast<statistics::STR_DependentProbes_data_model>(fixed_parameter);
1283 
1284  // ----- compute the model values -----
1285  vector<double> computed_model;
1286  for (size_t i=0; i<pp->models.size(); i++) {
1287 
1288  std::vector<double> single_par ((int)(pp->par_indexes[i].size()));
1289 
1290  for (size_t jj=0; jj<single_par.size(); jj++)
1291  single_par[jj] = likelihood_parameter[pp->par_indexes[i][jj]];
1292 
1293  std::vector<double> single_probe_model = pp->models[i]->operator()(pp->xx[i], single_par);
1294 
1295  // Update the derived parameters, if present
1296  for (size_t jj=0; jj<single_par.size(); jj++)
1297  likelihood_parameter[pp->par_indexes[i][jj]] = single_par[jj];
1298 
1299  // Fill the vector containing all the model values
1300  for (size_t kk=0; kk<single_probe_model.size(); kk++)
1301  computed_model.emplace_back(single_probe_model[kk]);
1302 
1303  }
1304 
1305  // ----- compute the difference between model and data at each bin -----
1306  vector<double> diff(pp->flat_data.size(), 0);
1307  for (size_t i=0; i<pp->flat_data.size(); i++)
1308  diff[i] = pp->flat_data[i]-computed_model[i];
1309 
1310  // ----- define the inverse covariance matrix -----
1311  data::CovarianceMatrix cov = *pp->covariance;
1312  std::vector<std::vector<double>> inverse_covariance = cov.precision();
1313 
1314  // ----- estimate the Gaussian log-likelihood -----
1315  double LogLikelihood = 0.;
1316  for (size_t i=0; i<pp->flat_data.size(); i++)
1317  for (size_t j=0; j<pp->flat_data.size(); j++)
1318  LogLikelihood += diff[i]*inverse_covariance[i][j]*diff[j];
1319 
1320  return -0.5*LogLikelihood - log(sqrt(pow(2*cbl::par::pi, computed_model.size()) * cov.determinant()));
1321 }
1322 
1323 
1324 // ============================================================================================
1325 
1326 
1327 double cbl::statistics::LogLikelihood_Poissonian_combined (std::vector<double> &likelihood_parameter, const std::shared_ptr<void> fixed_parameter)
1328 {
1329  // ----- extract the parameters -----
1330  shared_ptr<statistics::STR_DependentProbes_data_model> pp = static_pointer_cast<statistics::STR_DependentProbes_data_model>(fixed_parameter);
1331 
1332  // ----- compute the model values -----
1333  vector<double> computed_model;
1334  for (size_t i=0; i<pp->models.size(); i++) {
1335 
1336  std::vector<double> single_par ((int)(pp->par_indexes[i].size()));
1337 
1338  for (size_t jj=0; jj<single_par.size(); jj++)
1339  single_par[jj] = likelihood_parameter[pp->par_indexes[i][jj]];
1340  std::vector<double> single_probe_model = pp->models[i]->operator()(pp->xx[i], single_par);
1341 
1342  // Update the derived parameters, if present
1343  for (size_t jj=0; jj<single_par.size(); jj++)
1344  likelihood_parameter[pp->par_indexes[i][jj]] = single_par[jj];
1345 
1346  // Fill the vector containing all the model values
1347  for (size_t kk=0; kk<single_probe_model.size(); kk++)
1348  computed_model.emplace_back(single_probe_model[kk]);
1349 
1350  }
1351 
1352  // ----- estimate the Poissonian log-likelihood -----
1353  double LogLikelihood = 0.;
1354  for (size_t i=0; i<pp->flat_data.size(); i++)
1355  LogLikelihood += pp->flat_data[i]*cbl::Ln(computed_model[i],1.e-50)-computed_model[i]-gsl_sf_lnfact(int(pp->flat_data[i]));
1356 
1357  return LogLikelihood;
1358 }
1359 
1360 
1361 // ============================================================================================
1362 
1363 
1364 double cbl::statistics::LogLikelihood_Poissonian_SSC_combined (std::vector<double> &likelihood_parameter, const std::shared_ptr<void> fixed_parameter)
1365 {
1366  // ----- extract the parameters -----
1367  shared_ptr<statistics::STR_DependentProbes_data_model> pp = static_pointer_cast<statistics::STR_DependentProbes_data_model>(fixed_parameter);
1368 
1369  // ----- define the covariance matrix -----
1370  data::CovarianceMatrix cov = *pp->covariance;
1371 
1372  // ----- define the Sij matrix for the super-sample covariance -----
1373  std::vector<double> cosmoPar (pp->cosmoPar_indexes.size(), 0.);
1374  for (size_t i=0; i<cosmoPar.size(); i++)
1375  cosmoPar[i] = likelihood_parameter[pp->cosmoPar_indexes[i]];
1376 
1377  std::vector<std::vector<double>> Sij = pp->Sij->operator()(cosmoPar);
1378  vector<vector<double>> invSij; cbl::invert_matrix(Sij, invSij);
1379  const double detSij = cbl::determinant_matrix(Sij);
1380 
1381  // ----- for the super-sample covariance, extract the values of delta_b, i.e. the background matter contrast variation -----
1382  srand(time(0));
1383  std::vector<double> delta_b (pp->models.size(), 0.);
1384  for (size_t i=0; i<pp->models.size(); i++) {
1385  cbl::random::NormalRandomNumbers extraction (0, sqrt(Sij[i][i]), rand(), -sqrt(Sij[i][i]), sqrt(Sij[i][i]));
1386  delta_b[i] = extraction();
1387  }
1388 
1389  // ----- compute the model values -----
1390  vector<double> computed_model, computed_response;
1391  vector<double> delta_b_index;
1392  for (size_t i=0; i<pp->models.size(); i++) {
1393 
1394  std::vector<double> single_par ((int)(pp->par_indexes[i].size()));
1395 
1396  for (size_t jj=0; jj<single_par.size(); jj++)
1397  single_par[jj] = likelihood_parameter[pp->par_indexes[i][jj]];
1398 
1399  std::vector<double> single_probe_model = pp->models[i]->operator()(pp->xx[i], single_par);
1400 
1401  // Update the derived parameters, if present
1402  for (size_t jj=0; jj<single_par.size(); jj++)
1403  likelihood_parameter[pp->par_indexes[i][jj]] = single_par[jj];
1404 
1405  // Compute the response function
1406  std::vector<double> single_probe_response = pp->responses[i]->operator()(pp->xx[i], single_par);
1407 
1408  // Fill the vectors containing all the model values
1409  for (size_t kk=0; kk<single_probe_model.size(); kk++) {
1410  computed_model.emplace_back(single_probe_model[kk]);
1411  computed_response.emplace_back(single_probe_response[kk]);
1412  delta_b_index.emplace_back(i);
1413  }
1414 
1415  }
1416 
1417  // ----- estimate the log-likelihood -----
1418  double LogLikelihood = 0.;
1419 
1420  for (size_t i=0; i<pp->flat_data.size(); i++)
1421  LogLikelihood += pp->flat_data[i]*cbl::Ln(computed_model[i]+delta_b[delta_b_index[i]]*computed_response[i],1.e-50)-(computed_model[i]+delta_b[delta_b_index[i]]*computed_response[i])-gsl_sf_lnfact(int(pp->flat_data[i]));
1422 
1423  for (size_t i=0; i<delta_b.size(); i++)
1424  for (size_t j=0; j<delta_b.size(); j++)
1425  LogLikelihood += -0.5 * delta_b[i]*invSij[i][j]*delta_b[j];
1426 
1427  LogLikelihood = LogLikelihood - log( sqrt(detSij*pow(2.*cbl::par::pi, delta_b.size())) );
1428 
1429  return LogLikelihood;
1430 }
Implementation of the chain-mesh data structure.
The class CombinedPosterior.
class FITSwrapper that wrap CCfits routines to manage FITS files
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class PosteriorParameters.
The class Sampler.
The class ChainMesh.
Definition: ChainMesh.h:60
double interpolate(std::vector< double > xi, const int distNum)
N-dim interpolation of a set of N coordinates on a normalised grid (see normalize)
Definition: ChainMesh.cpp:387
The class CovarianceMatrix.
double precision(const int i, const int j) const
get the value of the precision matrix at index i,j
The class NormalRandomNumbers.
void importance_sampling(const int distNum, const double cell_size, const double rMAX, const double cut_sigma=-1)
do the importance sampling for two Posterior objects, which has been read externally
void m_add_prior(bool par_is_repeated, std::vector< std::shared_ptr< Posterior >> posteriors, const int N, const int k, std::vector< std::shared_ptr< cbl::statistics::PriorDistribution >> &prior_distributions)
add a prior
void m_set_parameters_priors(std::vector< std::shared_ptr< Posterior >> posteriors, std::vector< std::string > repeated_par={}, const std::vector< std::vector< std::vector< int >>> common_repeated_par={})
set the parameters and the priors
void show_results(const int start, const int thin, const int nbins=50, const bool show_mode=false, const int ns=-1, const int nb=-1)
show the results of the MCMC combination on the screen.
void write_results(const std::string output_dir, const std::string root_file, const int start=0, const int thin=1, const int nbins=50, const bool fits=false, const bool compute_mode=false, const int ns=-1, const int nb=-1)
store the results of the MCMC sampling to file
void m_set_independent_probes()
set all the internal variables needed for modelling independent probes
void maximize(const std::vector< double > start, const std::vector< std::vector< double >> parameter_limits, const unsigned int max_iter=10000, const double tol=1.e-6, const double epsilon=1.e-3)
function that maximizes the posterior, finds the best-fit parameters and store them in the model
void sample_stretch_move(const double aa=2, const bool parallel=true, const std::string outputFile=par::defaultString, const int start=0, const int thin=1, const int nbins=50)
sample the posterior using the stretch-move sampler (Foreman-Mackey et al. 2012)
std::vector< std::vector< double > > read(const std::string path, const std::string filename)
read an entire 2d table data (MCMC chain) of unknown dimension
double log(std::vector< double > &pp) const
evaluate the logarithm of the un-normalized posterior as the sum of all the logarithm of the un-norma...
void m_set_repeated_par(std::vector< std::shared_ptr< Posterior >> posteriors, const bool is_in_parnames, const int N, const int k, const std::vector< std::string > repeated_par, const std::vector< std::vector< std::vector< int >>> common_repeated_par, std::vector< std::shared_ptr< cbl::statistics::PriorDistribution >> &prior_distributions, std::vector< std::string > &parameter_names, std::vector< std::string > &original_names, std::vector< ParameterType > &parameter_types)
set a repeated parameter
void m_set_common_repeated_par(std::vector< std::shared_ptr< Posterior >> posteriors, const bool is_in_parnames, const int N, const int k, const std::vector< std::string > repeated_par, const std::vector< std::vector< std::vector< int >>> common_repeated_par, std::vector< std::shared_ptr< cbl::statistics::PriorDistribution >> &prior_distributions, std::vector< std::string > &parameter_names, std::vector< std::string > &original_names, std::vector< ParameterType > &parameter_types)
set a common repeated parameter
void m_check_repeated_par(int dummy_Nposteriors, std::vector< std::shared_ptr< Posterior >> posteriors, const std::vector< std::string > repeated_par)
check the repeated parameters
void set_log_posterior(const std::vector< double > logpostA, const std::vector< double > logpostB)
set the internal values of m_log_posterior as the concatenation of the logposterior vectors of two co...
void write_model_from_chain(const std::string output_dir, const std::string output_file, const int start, const int thin, const std::vector< double > xx={}, const std::vector< double > yy={})
write the model computing 16th, 50th and 84th percentiles from the MCMC
CombinedPosterior()=default
default constructor
void set_weight(const std::vector< double > weightsA, const std::vector< double > weightsB)
set the internal values of m_weight as the concatenation of the weights vectors of two MCMC chains
void write_chain(const std::string output_dir, const std::string output_file, const int start=0, const int thin=1, const bool is_FITS_format=false, const int prec=5, const int ww=14)
write the chains obtained after the MCMC sampling
void write_chain_ascii(const std::string output_dir, const std::string output_file, const int start=0, const int thin=1, const int prec=5, const int ww=14)
write the chains obtained after the MCMC sampling on an ascii file
void m_check_common_repeated_par(int dummy_Nposteriors, std::vector< std::shared_ptr< Posterior >> posteriors, std::vector< std::string > repeated_par, std::vector< std::vector< std::vector< int >>> common_repeated_par)
check the common repeated parameters
void set_parameters(const std::vector< std::vector< double >> parametersA, const std::vector< std::vector< double >> parametersB)
set the internal values of m_parameters as the concatenation of the parameters vectors of two cosmolo...
void write_maximization_results(const std::string dir_output, const std::string file)
write maximization results on a file
void write_chain_fits(const std::string output_dir, const std::string output_file, const int start=0, const int thin=1)
write the chains obtained after the MCMC sampling on a FITS file
double operator()(std::vector< double > &pp) const
evaluate the un-normalized posterior as the product of the un-normalized entry posteriors....
void initialize_chains(const int chain_size, const int n_walkers, const double radius, const std::vector< double > start, const unsigned int max_iter=10000, const double tol=1.e-6, const double epsilon=1.e-3)
initialize the chains in a ball around the posterior best-fit parameter values
The class PosteriorParameters.
The class Sampler.
Definition: Sampler.h:115
void sample_stretch_move(const int chain_size, const int nwalkers, const std::vector< std::vector< double >> start, const int seed=4241, const double aa=2, const std::string outputFile=cbl::par::defaultString)
sample the input function using the stretch-move algorithm on n-dimensional parameter space
Definition: Sampler.cpp:133
void get_chain_function_acceptance(std::vector< std::vector< double >> &chains, std::vector< double > &function, std::vector< double > &acceptance, const int start=0, const int thin=1)
get the chain values and the function
Definition: Sampler.cpp:411
void sample_stretch_move_parallel(const int chain_size, const int nwalkers, const std::vector< std::vector< double >> start, const int seed=4241, const double aa=2)
sample the input function using the stretch-move algorithm on n-dimensional parameter space - paralle...
Definition: Sampler.cpp:396
static const std::string col_default
default colour (used when printing something on the screen)
Definition: Constants.h:297
static const std::string col_yellow
yellow colour (used when printing something on the screen)
Definition: Constants.h:315
static const char fINT[]
conversion symbol for: int -> std::string
Definition: Constants.h:121
static const std::string defaultString
default std::string value
Definition: Constants.h:336
static const double defaultDouble
default double value
Definition: Constants.h:348
static const double pi
: the ratio of a circle's circumference to its diameter
Definition: Constants.h:199
static const double ee
e: the Euler's constant, defined as
Definition: Constants.h:202
static const double cc
: the speed of light in vacuum (the value is exact) [km/sec]
Definition: Constants.h:221
std::vector< std::string > CosmologicalParameterNames()
return a vector containing the CosmologicalParameter names
Definition: Cosmology.h:209
double LogLikelihood_Poissonian_combined(std::vector< double > &likelihood_parameter, const std::shared_ptr< void > input)
Poissonian log-likelihood.
double LogLikelihood_Gaussian_combined(std::vector< double > &likelihood_parameter, const std::shared_ptr< void > input)
Gaussian log-likelihood.
@ _Derived_
derived parameter
@ _Correlated_
correlated parameters
std::vector< std::string > LikelihoodTypeNames()
return a vector containing the LikelihoodType names
double LogLikelihood_Poissonian_SSC_combined(std::vector< double > &likelihood_parameter, const std::shared_ptr< void > input)
Poissonian log-likelihood with super-sample covariance.
void write_table_fits(const std::string output_dir, const std::string file_fits, const std::vector< std::string > column_names, const std::vector< std::vector< double >> table, const std::vector< std::string > column_units={})
function that writes a table on a fits file
Definition: FITSwrapper.cpp:88
std::vector< double > GSL_minimize_nD(FunctionDoubleVector func, const std::vector< double > start, const std::vector< std::vector< double >> ranges, const unsigned int max_iter=1000, const double tol=1.e-6, const double epsilon=0.1)
minimize the provided function using GSL procedure
Definition: GSLwrapper.cpp:497
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
std::string conv(const T val, const char *fact)
convert a number to a std::string
Definition: Kernel.h:903
void Print(const T value, const int prec, const int ww, const std::string header="", const std::string end="\n", const bool use_coutCBL=true, std::ostream &stream=std::cout, const std::string colour=cbl::par::col_default)
function to print values with a proper homegenised format
Definition: Kernel.h:1142
double Average(const std::vector< double > vect)
the average of a std::vector
Definition: Func.cpp:870
std::vector< T > different_elements(const std::vector< T > vect_input)
get the unique elements of a std::vector
Definition: Kernel.h:1349
void checkDim(const std::vector< T > vect, const int val, const std::string vector, bool equal=true)
check if the dimension of a std::vector is equal/lower than an input value
Definition: Kernel.h:1532
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
Definition: Kernel.cpp:160
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
void invert_matrix(const std::vector< std::vector< double >> mat, std::vector< std::vector< double >> &mat_inv, const double prec=1.e-10, const int Nres=-1)
function to invert a matrix
Definition: Func.cpp:673
T Ln(const T val, const double fact=0.9)
natural logarithm
Definition: Kernel.h:937
std::vector< std::vector< T > > transpose(std::vector< std::vector< T >> matrix)
transpose a matrix
Definition: Kernel.h:1729
double Sigma(const std::vector< double > vect)
the standard deviation of a std::vector
Definition: Func.cpp:925
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
Definition: Kernel.h:747
double determinant_matrix(const std::vector< std::vector< double >> mat)
compute the determinant of a matrix
Definition: Func.cpp:648