CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
PosteriorParameters.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 
34 #include "PosteriorParameters.h"
35 
36 using namespace std;
37 
38 using namespace cbl;
39 using namespace statistics;
40 
41 
42 // ============================================================================================
43 
44 
46 {
47  string stat;
48 
49  switch (m_parameter_type[p]) {
50  case statistics::ParameterType::_Base_:
51  if (m_parameter_prior[p]->distributionType()==cbl::glob::DistributionType::_Constant_)
52  stat = "FIXED";
53  else
54  stat = "FREE";
55  break;
56 
57  case statistics::ParameterType::_Correlated_:
58  stat = "FREE";
59  break;
60 
61  case statistics::ParameterType::_Derived_:
62  stat = "OUTPUT";
63  break;
64 
65  default:
66  ErrorCBL("no such kind of parameter!", "status", "PosteriorParameters.cpp");
67  }
68 
69  return stat;
70 }
71 
72 
73 // ============================================================================================
74 
75 
77 {
78  vector<string> stat;
79  for (size_t i=0; i<m_nparameters; i++) {
80  switch (m_parameter_type[i]) {
81  case statistics::ParameterType::_Base_:
82  if (m_parameter_prior[i]->distributionType()==cbl::glob::DistributionType::_Constant_)
83  stat.push_back("FIXED");
84  else
85  stat.push_back("FREE");
86  break;
87 
88  case statistics::ParameterType::_Correlated_:
89  stat.push_back("FREE");
90  break;
91 
92  case statistics::ParameterType::_Derived_:
93  stat.push_back("OUTPUT");
94  break;
95 
96  default:
97  ErrorCBL("no such kind of parameter!", "status", "PosteriorParameters.cpp");
98  }
99  }
100  return stat;
101 }
102 // ============================================================================================
103 
104 
105 std::vector<double> cbl::statistics::PosteriorParameters::full_parameter (const std::vector<double> parameter_value) const
106 {
107  if (parameter_value.size()==m_nparameters_free) {
108  vector<double> all_parameters(m_nparameters, 0);
109 
110  for (size_t i=0; i<m_nparameters_free; i++)
111  all_parameters[m_free_parameter[i]] = parameter_value[i];
112 
113  for (size_t i=0; i<m_nparameters_fixed; i++)
114  all_parameters[m_fixed_parameter[i]] = m_parameter_prior[m_fixed_parameter[i]]->sample();
115 
116  for (size_t i=0; i<m_nparameters_derived; i++)
117  all_parameters[m_derived_parameter[i]] = 0.;
118 
119  return all_parameters;
120  }
121  else if (parameter_value.size() == m_nparameters) {
122  vector<double> all_parameters = parameter_value;
123 
124  for (size_t i=0; i<m_nparameters_fixed; i++)
125  all_parameters[m_fixed_parameter[i]] = m_parameter_prior[m_fixed_parameter[i]]->sample();
126 
127  return all_parameters;
128  }
129  else
130  ErrorCBL("the vector of free parameters has the wrong size!", "full_parameter", "PosteriorParameters.cpp");
131 
132  vector<double> vv;
133  return vv;
134 }
135 
136 
137 // ============================================================================================
138 
139 
141 {
142  m_nparameters_free = 0;
143  m_nparameters_fixed = 0;
144  m_nparameters_base = 0;
145  m_nparameters_correlated = 0;
146  m_nparameters_derived = 0;
147 
148  m_base_parameter.erase(m_base_parameter.begin(), m_base_parameter.end());
149  m_fixed_parameter.erase(m_fixed_parameter.begin(), m_fixed_parameter.end());
150  m_free_parameter.erase(m_free_parameter.begin(), m_free_parameter.end());
151  m_derived_parameter.erase(m_derived_parameter.begin(), m_derived_parameter.end());
152 
153  for (size_t i=0; i<m_nparameters; i++) {
154  switch (m_parameter_type[i]) {
155  case statistics::ParameterType::_Base_:
156  if (m_parameter_prior[i] != NULL) {
157  if (m_parameter_prior[i]->distributionType()==glob::DistributionType::_Constant_) {
158  m_nparameters_fixed ++;
159  m_fixed_parameter.push_back(i);
160  }
161  else {
162  m_nparameters_free ++;
163  m_free_parameter.push_back(i);
164  }
165  m_nparameters_base ++;
166  m_base_parameter.push_back(i);
167  }
168  break;
169 
170  case statistics::ParameterType::_Correlated_:
171  m_nparameters_free ++;
172  m_free_parameter.push_back(i);
173  m_nparameters_correlated ++;
174  m_nparameters_base ++;
175  m_base_parameter.push_back(i);
176  break;
177 
178  case statistics::ParameterType::_Derived_:
179  m_nparameters_derived ++;
180  m_derived_parameter.push_back(i);
181  break;
182 
183  default:
184  ErrorCBL("no such kind of parameter!", "m_set_parameter_type", "PosteriorParameters.cpp");
185  }
186  }
187 }
188 
189 
190 // ============================================================================================
191 
192 
193 cbl::statistics::PosteriorParameters::PosteriorParameters (const size_t nparameters, const std::vector<std::shared_ptr<PriorDistribution>> priorDistribution, std::vector<ParameterType> parameterTypes, std::vector<std::string> parameterNames)
194 {
195  set_parameters(nparameters, priorDistribution, parameterTypes, parameterNames);
196 }
197 
198 
199 // ============================================================================================
200 
201 
202 void cbl::statistics::PosteriorParameters::set_parameters (const size_t nparameters, const std::vector<std::shared_ptr<PriorDistribution>> priorDistribution, std::vector<ParameterType> parameterTypes, std::vector<std::string> parameterNames)
203 {
204  // check parameterTypes size
205 
206  if (nparameters==0)
207  ErrorCBL("nparameters must be >0!", "set_parameters", "PosteriorParameters.cpp");
208 
209  if ((parameterTypes.size()!=nparameters) && (parameterTypes.size()!=0))
210  ErrorCBL("the size of parameterTypes is incorrect!", "set_parameters", "PosteriorParameters.cpp");
211 
212  if ((parameterNames.size()!=nparameters) && (parameterNames.size()!=0))
213  ErrorCBL("the size of parameterNames is incorrect!", "set_parameters", "PosteriorParameters.cpp");
214 
215 
216  if ((parameterTypes.size()==nparameters) && (parameterNames.size()==nparameters)) {
217  m_nparameters = nparameters;
218  m_parameter_type = parameterTypes;
219  m_parameter_name = parameterNames;
220  }
221  else if ((parameterTypes.size()==0) && (parameterNames.size()==0)) {
222  m_nparameters = nparameters;
223  vector<ParameterType> pTypes(m_nparameters);
224  vector<string> pNames(m_nparameters);
225  for (size_t i=0; i<m_nparameters; i++) {
226  pTypes[i] = ParameterType::_Base_;
227  pNames[i] = "par_"+conv(i+1, par::fINT);
228  }
229  m_parameter_type = pTypes;
230  m_parameter_name = pNames;
231  }
232  else if ((parameterTypes.size()==nparameters) && (parameterNames.size()==0)) {
233  m_nparameters = nparameters;
234  vector<string> pNames(m_nparameters);
235  for (size_t i=0; i<m_nparameters; i++)
236  pNames[i] = "par_"+conv(i+1, par::fINT);
237 
238  m_parameter_type = parameterTypes;
239  m_parameter_name = pNames;
240  }
241  else if ((parameterTypes.size()==0) && (parameterNames.size()==0)) {
242  m_nparameters = nparameters;
243  vector<ParameterType> pTypes(m_nparameters);
244  for (size_t i=0; i<m_nparameters; i++)
245  pTypes[i] = ParameterType::_Base_;
246 
247  m_parameter_type = pTypes;
248  m_parameter_name = parameterNames;
249  }
250 
251  ModelParameters::m_set_parameter_type();
252  m_parameter_bestfit_value.erase(m_parameter_bestfit_value.begin(), m_parameter_bestfit_value.end());
253 
254  set_prior_distribution(priorDistribution);
255 }
256 
257 
258 // ============================================================================================
259 
260 
262 {
263  vector<vector<double>> values;
264 
265  for (size_t i=0; i<m_nparameters; i++)
266  values.push_back(parameter_chain_values(i, start, thin));
267 
268  covariance_matrix (transpose(values), m_parameter_covariance);
269 }
270 
271 
272 // ============================================================================================
273 
274 
275 double cbl::statistics::PosteriorParameters::parameter_covariance (const int i, const int j) const
276 {
277  return m_parameter_covariance[i][j];
278 }
279 
280 
281 // ============================================================================================
282 
283 
284 std::vector<std::vector<double>> cbl::statistics::PosteriorParameters::parameter_covariance () const
285 {
286  return m_parameter_covariance;
287 }
288 
289 
290 // ============================================================================================
291 
292 
293 void cbl::statistics::PosteriorParameters::set_prior_distribution (const int p, const std::shared_ptr<PriorDistribution> priorDistribution)
294 {
295  switch (m_parameter_type[p]) {
296 
297  case statistics::ParameterType::_Base_:
298  m_parameter_prior[p] = priorDistribution;
299  break;
300 
301  case statistics::ParameterType::_Correlated_:
302  m_parameter_prior[p] = priorDistribution;
303  break;
304 
305  case statistics::ParameterType::_Derived_:
306  m_parameter_prior[p] = NULL;
307  WarningMsgCBL(m_parameter_name[p]+" is a derived parameter!", "set_prior_distribution", "PosteriorParameters.cpp");
308  break;
309 
310  default:
311  ErrorCBL("no such kind of parameter!", "set_prior_distribution", "PosteriorParameters.cpp");
312  }
313 }
314 
315 
316 // ============================================================================================
317 
318 
319 void cbl::statistics::PosteriorParameters::set_prior_distribution (const std::vector<std::shared_ptr<PriorDistribution>> priorDistribution)
320 {
321  size_t priorSize = priorDistribution.size();
322  size_t diff = priorSize-m_nparameters_base+m_nparameters_correlated;
323 
324  m_parameter_prior.erase(m_parameter_prior.begin(), m_parameter_prior.end());
325  m_parameter_prior.resize(m_nparameters, NULL);
326  m_correlated_parameter_prior.erase(m_correlated_parameter_prior.begin(), m_correlated_parameter_prior.end());
327  m_correlated_parameter_prior.resize(diff, NULL);
328  m_multipriors.erase(m_multipriors.begin(), m_multipriors.end());
329  m_multipriors.resize(diff, 0);
330 
331  if (m_nparameters_correlated==0 and diff>0)
332  ErrorCBL ("The size of the prior vector is incorrect!", "set_prior_distribution", "PosteriorParameters.cpp");
333 
334  else if (m_nparameters_correlated>0) {
335  WarningMsgCBL("I'm assuming that the correlated parameters have been included as last, with "+conv(diff, par::fINT)+" multidimensional prior(s)!", "set_prior_distribution", "PosteriorParameters.cpp");
336 
337  for (size_t i=diff; i --> 0;) {
338  m_correlated_parameter_prior[i] = priorDistribution[i+priorSize-diff];
339  m_multipriors[i] = priorDistribution[i+priorSize-diff]->get_size_distribution();
340  }
341  }
342 
343  size_t index_corr = 0;
344  size_t nset_prior = 0;
345 
346  for (size_t p=0; p<m_nparameters_base; p++) {
347 
348  if (m_parameter_type[m_base_parameter[p]]==statistics::ParameterType::_Correlated_) {
349 
350  if (index_corr>(m_multipriors[nset_prior]-1)) {
351  nset_prior++;
352  index_corr = 0;
353  }
354 
355  std::shared_ptr<cbl::glob::Distribution> Distr = priorDistribution[nset_prior+m_nparameters_base-m_nparameters_correlated]->get_distribution(index_corr);
356  PriorDistribution priorDistr;
357  if (Distr->distributionType()==cbl::glob::DistributionType::_Gaussian_)
358  priorDistr = PriorDistribution(cbl::glob::DistributionType::_Gaussian_, {Distr->get_mean(), Distr->get_sigma()}, Distr->xmin(), Distr->xmax(), Distr->get_seed());
359  else priorDistr = PriorDistribution(cbl::glob::DistributionType::_Uniform_, Distr->xmin(), Distr->xmax(), Distr->get_seed());
360 
361  set_prior_distribution(m_base_parameter[p], std::make_shared<PriorDistribution>(priorDistr));
362  index_corr++;
363  }
364 
365  else set_prior_distribution(m_base_parameter[p], priorDistribution[p]);
366  }
367 
368  m_set_parameter_type();
369 }
370 
371 
372 // ============================================================================================
373 
374 
375 void cbl::statistics::PosteriorParameters::set_prior_distribution_seed (const std::shared_ptr<random::UniformRandomNumbers_Int> ran_generator)
376 {
377  for (size_t i=0; i<m_nparameters_base; i++)
378  m_parameter_prior[m_base_parameter[i]]->set_seed(ran_generator->operator()());
379 }
380 
381 
382 // ============================================================================================
383 
384 
385 std::shared_ptr<cbl::statistics::Prior> cbl::statistics::PosteriorParameters::prior () const
386 {
387  auto prior_function = [&] (const vector<double> parameters, const shared_ptr<void> prior_inputs)
388  {
389  (void)prior_inputs;
390  double prior_value = 1;
391 
392  vector<double> new_pars = parameters;
393  int n_erased_elem = 0;
394  for (size_t i=0; i<m_nparameters_derived; i++) {
395  new_pars.erase(new_pars.begin()+m_derived_parameter[i]-n_erased_elem);
396  n_erased_elem ++;
397  }
398 
399  int idx = 0;
400  for (size_t i=0; i<m_nparameters_base-m_nparameters_correlated; i++){
401  prior_value *= m_parameter_prior[m_base_parameter[i]]->operator()(new_pars[idx]);
402  idx ++;
403  }
404 
405  int add_previous = 0;
406  for (size_t i=0; i<m_multipriors.size(); i++) {
407  int start = m_nparameters_base - m_nparameters_correlated + add_previous;
408  add_previous += m_multipriors[i];
409  vector<double> correlated_parameters(new_pars.begin()+start, new_pars.begin()+start+m_multipriors[i]);
410  prior_value *= m_correlated_parameter_prior[i]->operator[](correlated_parameters);
411  }
412 
413  return prior_value;
414  };
415 
416  shared_ptr<void> prior_function_inputs = NULL;
417 
418  return make_shared<Prior>(prior_function, prior_function_inputs);
419 
420 }
421 
422 
423 // ============================================================================================
424 
425 
427 {
428  if (m_parameter_bestfit_value.size()==0)
429  ErrorCBL("the best-fit values have not been computed!", "bestfit_value", "PosteriorParameters.cpp");
430 
431  return m_parameter_bestfit_value[p];
432 }
433 
434 // ============================================================================================
435 
436 
438 {
439  if (m_parameter_bestfit_value.size()==0)
440  ErrorCBL("the best-fit values have not been computed!", "bestfit_value", "PosteriorParameters.cpp");
441 
442  return m_parameter_bestfit_value;
443 }
444 
445 
446 // ============================================================================================
447 
448 
449 void cbl::statistics::PosteriorParameters::set_bestfit_values (const std::vector<double> bestfit_value)
450 {
451  if (bestfit_value.size()!=m_nparameters)
452  ErrorCBL("the size of the input vector is incorrect!", "set_bestfit_values", "PosteriorParameters.cpp");
453 
454  m_parameter_bestfit_value.erase(m_parameter_bestfit_value.begin(), m_parameter_bestfit_value.end());
455 
456  for (size_t i=0; i<m_nparameters; i++)
457  m_parameter_bestfit_value.push_back(bestfit_value[i]);
458 }
459 
460 
461 // ============================================================================================
462 
463 
464 void cbl::statistics::PosteriorParameters::set_bestfit_values (const int start, const int thin, const int nbins, const int seed)
465 {
466  set_posterior_distribution(start, thin, nbins, seed);
467  set_parameter_covariance(start, thin);
468 
469  vector<double> bestfit_parameter;
470 
471  for (size_t i=0; i<m_nparameters; i++) {
472 
473  auto posterior = m_posterior_distribution[i];
474 
475  switch (m_parameter_type[i]) {
476 
477  case statistics::ParameterType::_Base_:
478  if (m_parameter_prior[i]->distributionType()==glob::DistributionType::_Constant_)
479  bestfit_parameter.emplace_back(m_parameter_prior[i]->sample());
480  else
481  bestfit_parameter.emplace_back(posterior->median());
482  break;
483 
484  case statistics::ParameterType::_Correlated_:
485  bestfit_parameter.emplace_back(posterior->median());
486  break;
487 
488  case statistics::ParameterType::_Derived_:
489  bestfit_parameter.emplace_back(posterior->median());
490  break;
491 
492  default:
493  ErrorCBL("no such kind of parameter!", "set_bestfit_values", "PosteriorParameters.cpp");
494  }
495  }
496 
497  set_bestfit_values(bestfit_parameter);
498 }
499 
500 
501 // ============================================================================================
502 
503 
505 {
506  if (m_parameter_bestfit_value.size()==m_nparameters) {
507  for (size_t i=0; i<m_nparameters; i++) {
508 
509  switch (m_parameter_type[i]) {
510  case statistics::ParameterType::_Base_:
511  if (m_parameter_prior[i]->distributionType()==glob::DistributionType::_Constant_)
512  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_purple << "FIXED" << endl;
513  else
514  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_green << "FREE" << endl;
515  break;
516 
517  case statistics::ParameterType::_Correlated_:
518  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_green << "FREE" << endl;
519  break;
520 
521  case statistics::ParameterType::_Derived_:
522  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_bred << "OUTPUT" << endl;
523  break;
524 
525  default:
526  ErrorCBL("no such kind of parameter!", "write_bestfit_info", "PosteriorParameters.cpp");
527  }
528 
529  Print(m_parameter_bestfit_value[i], 5, 10, "value = ", "\n", true, std::cout);
530  }
531  }
532 
533  else
534  ErrorCBL("the best-fit values have not been computed!", "write_bestfit_info", "PosteriorParameters.cpp");
535 }
536 
537 
538 // ============================================================================================
539 
540 
541 void cbl::statistics::PosteriorParameters::set_chain (const size_t size, const size_t nwalkers)
542 {
543  m_chain_size = size;
544  m_chain_nwalkers = nwalkers;
545  reset_chain();
546 }
547 
548 
549 // ============================================================================================
550 
551 
553 {
554  m_chain_value.erase(m_chain_value.begin(), m_chain_value.end());
555  m_chain_value.resize(m_nparameters, vector<double>(m_chain_size*m_chain_nwalkers, 0));
556 }
557 
558 
559 // ============================================================================================
560 
561 
563 {
564  vector<vector<double>> values = m_chain_value;
565  size_t old_size = m_chain_size;
566 
567  m_chain_size += append;
568 
569  reset();
570 
571  for (size_t i=0; i<old_size; i++)
572  for (size_t j=0; j<m_chain_nwalkers; j++)
573  for (size_t p=0; p<m_nparameters; p++)
574  set_chain_value(p, i, j, values[p][i*m_chain_nwalkers+j]);
575 }
576 
577 
578 // ============================================================================================
579 
580 
581 std::vector<double> cbl::statistics::PosteriorParameters::chain_value_parameter (const int pos, const int ww) const
582 {
583  vector<double> vv(m_nparameters, 0);
584  for (size_t i=0; i<m_nparameters; i++)
585  vv[i] = chain_value(i, pos, ww);
586  return vv;
587 }
588 
589 // ============================================================================================
590 
591 
592 std::vector<double> cbl::statistics::PosteriorParameters::parameter_chain_values (const int param, const int start, const int thin) const
593 {
594  vector<double> values;
595 
596  for (size_t i=start; i<m_chain_size; i+=thin)
597  for (size_t j=0; j<m_chain_nwalkers; j++)
598  values.push_back(chain_value(param, i, j));
599 
600  return values;
601 }
602 
603 
604 // ============================================================================================
605 
606 
607 void cbl::statistics::PosteriorParameters::set_chain_values (const std::vector<std::vector<double>> values, const int nwalkers)
608 {
609  int size = values[0].size()/nwalkers;
610 
611  if (values[0].size()%nwalkers!=0)
612  ErrorCBL("the size of the input values or the number of walkers is incorrect!", "set_chain_values", "PosteriorParameters.cpp");
613 
614  set_chain(size, nwalkers);
615 
616  for (size_t p=0; p<m_nparameters; p++)
617  for (size_t i=0; i<m_chain_size; i++)
618  for (size_t j=0; j<m_chain_nwalkers; j++)
619  set_chain_value(p, i, j, values[p][i*m_chain_nwalkers+j]);
620 }
621 
622 
623 // ============================================================================================
624 
625 
626 void cbl::statistics::PosteriorParameters::set_chain_values (const std::vector<std::vector<std::vector<double>>> values)
627 {
628  vector<vector<double>> flatten_val;
629 
630  int nwalkers = values[0][0].size();
631 
632  for (size_t i=0; i<values.size(); i++) {
633  vector<double> vv;
634  for (size_t j=0; j<values[0].size(); j++) {
635  checkDim(values[i][j], nwalkers, "values["+conv(i, par::fINT)+"]"+"["+conv(j, par::fINT)+"]");
636  for (size_t k=0; k<values[i][j].size(); k++)
637  vv.push_back(values[i][j][k]);
638  }
639  flatten_val.push_back(vv);
640  }
641 
642  set_chain_values(flatten_val, nwalkers);
643 }
644 
645 
646 // ============================================================================================
647 
648 
649 void cbl::statistics::PosteriorParameters::initialize_chain (const std::vector<std::vector<double>> values)
650 {
651  for (size_t j=0; j<values[0].size(); j++) {
652  vector<double> val;
653  for (size_t i=0; i<values.size(); i++)
654  val.emplace_back(values[i][j]);
655 
656  val = full_parameter(val);
657  for (size_t i=0; i<val.size(); i++)
658  set_chain_value(i, 0, j, val[i]);
659  }
660 }
661 
662 
663 // ============================================================================================
664 
665 
667 {
668  std::vector<std::vector<double>> values(m_nparameters, std::vector<double>(m_chain_nwalkers, 0));
669 
670  for (size_t i=0; i<m_nparameters_base; i++) {
671  const int index = m_base_parameter[i];
672  for (size_t j=0; j<m_chain_nwalkers; j++) {
673  values[index][j] = m_parameter_prior[index]->sample();
674  }
675  }
676  initialize_chain(values);
677 }
678 
679 
680 // ============================================================================================
681 
682 
683 void cbl::statistics::PosteriorParameters::initialize_chain_ball (const std::vector<double> center, const double radius, const double seed)
684 {
685  vector<vector<double>> value(m_nparameters, vector<double>(m_chain_nwalkers, 0));
686 
687  // verify if the number of given parameters is fine and, in case
688  // only the free parameters are given in inputs, fill the empy
689  // elements
690  vector<double> cen = full_parameter(center);
691 
692  cbl::random::UniformRandomNumbers ran(-radius, radius, seed);
693 
694  for (size_t i=0; i<m_nparameters_free; i++) {
695  int index = m_free_parameter[i];
696 
697  if (cen[index]+radius<m_parameter_prior[index]->xmin() or cen[index]-radius>m_parameter_prior[index]->xmax())
698  ErrorCBL("Wrong parameter range!", "initialize_chain_ball", "PosteriorParameters.cpp");
699 
700  for (size_t j=0; j<m_chain_nwalkers; j++) {
701  double val = ran()+cen[index];
702  while (!m_parameter_prior[index]->isIncluded(val))
703  val = ran()+cen[index];
704  value[index][j] = val;
705  }
706  }
707  initialize_chain(value);
708 }
709 
710 
711 // ============================================================================================
712 
713 
714 void cbl::statistics::PosteriorParameters::initialize_chain_ball_bestfit (const double radius, const double seed)
715 {
716  initialize_chain_ball(bestfit_value(), radius, seed);
717 }
718 
719 
720 // ============================================================================================
721 
722 
723 void cbl::statistics::PosteriorParameters::set_posterior_distribution (const int start, const int thin, const int nbins, const int seed, const vector<double> weight)
724 {
725  m_posterior_distribution.erase(m_posterior_distribution.begin(), m_posterior_distribution.end());
726  m_posterior_distribution.resize(m_nparameters);
727 
728  for (size_t i=0; i<m_nparameters_base; i++) {
729  const int index = m_base_parameter[i];
730  if (m_parameter_prior[index]->distributionType()==glob::DistributionType::_Constant_)
731  m_posterior_distribution[index] = make_shared<PosteriorDistribution>(PosteriorDistribution(glob::DistributionType::_Constant_, m_parameter_prior[index]->sample()));
732  else
733  m_posterior_distribution[index] = make_shared<PosteriorDistribution>(PosteriorDistribution(glob::DistributionType::_Discrete_, parameter_chain_values(index, start, thin), weight, nbins, "Spline", seed));
734  }
735 
736  for (size_t i=0; i<m_nparameters_derived; i++) {
737  const int index = m_derived_parameter[i];
738  m_posterior_distribution[index] = make_shared<PosteriorDistribution>(PosteriorDistribution(glob::DistributionType::_Discrete_, parameter_chain_values(index, start, thin), weight, nbins, "Spline", seed));
739  }
740 }
741 
742 
743 // ============================================================================================
744 
745 
746 void cbl::statistics::PosteriorParameters::show_results (const int start, const int thin, const int nbins, const int seed, const bool show_mode, const int ns, const int nb, const vector<double> weight)
747 {
748  set_posterior_distribution(start, thin, nbins, seed, weight);
749  set_parameter_covariance(start, thin);
750 
751  const int dp = cout.precision(); cout.precision(4);
752  cout << endl;
753 
754  // correction for covariance matrix uncertainties (Percival et al. 2014)
755  double corr = 1.;
756  if (ns>0 && nb>0) {
757  const double AA = 2./double((ns-nb-1.)*(ns-nb-4.));
758  const double BB = (ns-nb-2.)/double((ns-nb-1.)*(ns-nb-4.));
759  corr = sqrt((1.+BB*(nb-m_nparameters))/(1.+AA+BB*(m_nparameters-1.)));
760  }
761 
762  for (size_t i=0; i<m_nparameters; i++) {
763 
764  switch (m_parameter_type[i]) {
765 
766  case statistics::ParameterType::_Base_:
767  if (m_parameter_prior[i]->distributionType()==glob::DistributionType::_Constant_) {
768  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_purple << "FIXED" << endl;
769  Print(m_parameter_prior[i]->sample(), 5, 10, "value =", "\n", true, std::cout);
770  }
771  else {
772  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_green << "FREE" << endl;
773 
774  auto posterior = m_posterior_distribution[i];
775  const double std = posterior->std()*corr;
776  const double std_diff = (posterior->std()*(corr-1.))*0.5;
777 
778  Print(posterior->mean(), 5, 10, "Posterior mean = ", "\n", true, std::cout);
779  Print(std, 5, 10, "Posterior standard deviation = ", "\n", true, std::cout);
780  Print(posterior->median(), 5, 10, "Posterior median = ", "\n", true, std::cout);
781  Print((posterior->median()-posterior->percentile(16))-std_diff, 5, 10, "Posterior 16th percentile = ", "\n", true, std::cout);
782  Print((posterior->percentile(84)-posterior->median())+std_diff, 5, 10, "Posterior 84th percentile = ", "\n", true, std::cout);
783  if (show_mode) Print(posterior->mode(), 5, 10, "Posterior mode = ", "\n", true, std::cout);
784  cout << endl;
785  }
786  break;
787 
788  case statistics::ParameterType::_Correlated_:
789  {
790  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_green << "FREE" << endl;
791 
792  auto posterior = m_posterior_distribution[i];
793  const double std = posterior->std()*corr;
794  const double std_diff = (posterior->std()*(corr-1.))*0.5;
795 
796  Print(posterior->mean(), 5, 10, "Posterior mean = ", "\n", true, std::cout);
797  Print(std, 5, 10, "Posterior standard deviation = ", "\n", true, std::cout);
798  Print(posterior->median(), 5, 10, "Posterior median = ", "\n", true, std::cout);
799  Print((posterior->median()-posterior->percentile(16))-std_diff, 5, 10, "Posterior 16th percentile = ", "\n", true, std::cout);
800  Print((posterior->percentile(84)-posterior->median())+std_diff, 5, 10, "Posterior 84th percentile = ", "\n", true, std::cout);
801  if (show_mode) Print(posterior->mode(), 5, 10, "Posterior mode = ", "\n", true, std::cout);
802  cout << endl;
803  break;
804  }
805 
806  case statistics::ParameterType::_Derived_:
807  {
808  auto posterior = m_posterior_distribution[i];
809  const double std = posterior->std()*corr;
810  const double std_diff = (posterior->std()*(corr-1.))*0.5;
811  coutCBL << "Parameter: " << par::col_yellow << m_parameter_name[i] << par::col_default << " --> status: " << par::col_bred << "OUTPUT" << endl;
812  Print(posterior->mean(), 5, 10, "Posterior mean = ", "\n", true, std::cout);
813  Print(std, 5, 10, "Posterior standard deviation = ", "\n", true, std::cout);
814  Print(posterior->median(), 5, 10, "Posterior median = ", "\n", true, std::cout);
815  Print((posterior->median()-posterior->percentile(16))-std_diff, 5, 10, "Posterior 16th percentile = ", "\n", true, std::cout);
816  Print((posterior->percentile(84)-posterior->median())+std_diff, 5, 10, "Posterior 84th percentile = ", "\n", true, std::cout);
817  if (show_mode) Print(posterior->mode(), 5, 10, "Posterior mode = ", "\n", true, std::cout);
818  cout << endl;
819  break;
820  }
821 
822  default:
823  ErrorCBL("no such kind of parameter!", "show_results", "PosteriorParameters.cpp");
824  }
825  }
826 
827  cout.precision(dp);
828 }
829 
830 
831 // ============================================================================================
832 
833 
834 void cbl::statistics::PosteriorParameters::write_results (const string dir, const string file, const int start, const int thin, const int nbins, const int seed, const bool compute_mode, const int ns, const int nb, const vector<double> weight)
835 {
836  set_posterior_distribution(start, thin, nbins, seed, weight);
837  set_parameter_covariance(start, thin);
838 
839  const string mkdir = "mkdir -p "+dir; if (system(mkdir.c_str())) {}
840 
841  const string file_parameters = dir+file+"_parameters.dat";
842  const string file_covariance = dir+file+"_covariance.dat";
843 
844 
845  // correction for covariance matrix uncertainties (Percival et al. 2014)
846 
847  double corr = 1.;
848  if (ns>0 && nb>0) {
849  const double AA = 2./double((ns-nb-1.)*(ns-nb-4.));
850  const double BB = (ns-nb-2.)/double((ns-nb-1.)*(ns-nb-4.));
851  corr = sqrt((1.+BB*(nb-m_nparameters))/(1.+AA+BB*(m_nparameters-1.)));
852  }
853 
854  ofstream fout(file_parameters.c_str());
855 
856  if (compute_mode)
857  fout << "### Parameter # status # Posterior mean # Posterior standard deviation # Posterior median # Posterior 16th percentile # Posterior 84th percentile # Posterior mode ###" << endl << endl;
858  else
859  fout << "### Parameter # status # Posterior mean # Posterior standard deviation # Posterior median # Posterior 16th percentile # Posterior 84th percentile ###" << endl;
860 
861  for (size_t i=0; i<m_nparameters; i++) {
862  auto posterior = m_posterior_distribution[i];
863 
864  if (m_parameter_type[i]==statistics::ParameterType::_Base_ && m_parameter_prior[i]->distributionType()==glob::DistributionType::_Constant_) {
865  fout << m_parameter_name[i] << " FIXED " << m_parameter_prior[i]->sample() << " 0 0 0 0 0";
866  if (compute_mode)
867  fout << "0";
868  }
869  else {
870 
871  const double std = posterior->std()*corr;
872  const double std_diff = (posterior->std()*(corr-1.))*0.5;
873  fout << m_parameter_name[i] << " FREE " << posterior->mean() << " " << std << " " << posterior->median() << " " << (posterior->median()-posterior->percentile(16))-std_diff << " " << (posterior->percentile(84)-posterior->median())+std_diff;
874  if (compute_mode)
875  fout << " " << posterior->mode() << endl;
876  }
877  fout << endl;
878  }
879 
880  fout.clear(); fout.close(); coutCBL << "I wrote the file: " << file_parameters << endl;
881 
882 
883  fout.open(file_covariance.c_str());
884  for (size_t i=0; i<m_nparameters; i++) {
885  for (size_t j=0; j<m_nparameters; j++)
886  fout << i << " " << j << " " << m_parameter_covariance[i][j] << endl;
887  fout << endl;
888  }
889 
890  fout.clear(); fout.close(); coutCBL << "I wrote the file: " << file_covariance << endl;
891 
892 }
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class PosteriorParameters.
The class UniformRandomNumbers.
The class PosteriorDistribution.
void set_parameters(const size_t nparameters, const std::vector< std::shared_ptr< PriorDistribution >> priorDistributions, std::vector< ParameterType > parameterTypes, std::vector< std::string > parameterNames) override
set the parameter
void initialize_chain_ball_bestfit(const double radius, const double seed)
initialize the chain values around bestfit values
void write_results(const std::string dir, const std::string file, const int start, const int thin, const int nbins, const int seed=34121, const bool compute_mode=false, const int ns=-1, const int nb=-1, const std::vector< double > weight={})
store the results to file
void reset_chain()
reset the chain using m_size and m_nwalkers
void initialize_chain(const std::vector< std::vector< double >> values)
initialize the chain values
void set_prior_distribution(const int p, const std::shared_ptr< PriorDistribution > priorDistribution)
set the prior distribution for the p-th parameter
std::vector< double > parameter_chain_values(const int param, const int start=0, const int thin=1) const
return all the chain values for a parameter
void set_chain(const size_t size, const size_t nwalkers)
set the chain
std::vector< double > full_parameter(const std::vector< double > parameter_value) const override
return all the model parameters
void set_prior_distribution_seed(const std::shared_ptr< random::UniformRandomNumbers_Int > ran_generator)
set the prior distributions for the parameters
void set_bestfit_values(const std::vector< double > bestfit_value)
set the protected member m_bestfit_value
void show_results(const int start, const int thin, const int nbins, const int seed=34121, const bool show_mode=false, const int ns=-1, const int nb=-1, const std::vector< double > weight={})
show the results on the standard output
std::vector< std::string > status() const
return all the model parameter status
std::vector< double > chain_value_parameter(const int pos, const int ww) const
return the private member m_values at the pp-th step for the ww-th step for all the parameters
void expand_chain(const int append)
expand the already existing chain
std::shared_ptr< Prior > prior() const
get the prior function
PosteriorParameters()=default
default constructor
std::vector< double > bestfit_value() const
get the protected member m_parameter_bestfit_value
void set_posterior_distribution(const int start, const int thin, const int nbins, const int seed=34121, const std::vector< double > weight={})
set the posterior distribution from the chains
void set_chain_values(const std::vector< std::vector< double >> values, const int nwalkers)
set the chain values
void initialize_chain_from_prior()
initialize the chain values random sampling the parameter priors
void set_parameter_covariance(const int start=0, const int thin=1)
set the internal method m_parameter_covariance
void m_set_parameter_type() override
private member to set the parameter types
void initialize_chain_ball(const std::vector< double > center, const double radius, const double seed)
initialize the chain values
std::vector< std::vector< double > > parameter_covariance() const
return the protected member m_parameter_covariance
The class PriorDistribution.
static const std::string col_green
green colour (used when printing something on the screen)
Definition: Constants.h:309
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 std::string col_bred
bold high intensty red colour (used when printing something on the screen)
Definition: Constants.h:303
static const std::string col_purple
purple colour (used when printing something on the screen)
Definition: Constants.h:318
static const char fINT[]
conversion symbol for: int -> std::string
Definition: Constants.h:121
@ _Constant_
Constant function.
@ _Uniform_
Identity function.
@ _Gaussian_
Gaussian function.
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
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
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
std::vector< std::vector< T > > transpose(std::vector< std::vector< T >> matrix)
transpose a matrix
Definition: Kernel.h:1729
void covariance_matrix(const std::vector< std::vector< double >> mat, std::vector< std::vector< double >> &cov, const bool JK=false)
compute the covariance matrix from an input dataset
Definition: Func.cpp:761
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
Definition: Kernel.h:747