CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
CombinedDistribution.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Copyright (C) 2020 by Sofia Contarini *
3  * *
4  * This program is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU General Public License as *
6  * published by the Free Software Foundation; either version 2 of *
7  * the License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU General Public *
15  * License along with this program; if not, write to the Free *
16  * Software Foundation, Inc., *
17  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18  ********************************************************************/
19 
33 #include "CombinedDistribution.h"
34 
35 
36 // ======================================================================================
37 
38 
39 cbl::glob::CombinedDistribution::CombinedDistribution (const DistributionType distributionType, const std::vector<double> meanVec, const std::vector<std::vector<double>> covMat, const std::vector<double> xMinVec, const std::vector<double> xMaxVec, const int seed)
40 {
41  if (distributionType!=glob::DistributionType::_Gaussian_)
42  ErrorCBL("this constructor only allows DistributionType::_Gaussian_!", "CombinedDistribution", "CombinedDistribution.cpp");
43 
44  m_xMinVec = xMinVec;
45  m_xMaxVec = xMaxVec;
46  std::vector<double> sigmaVec = cbl::wrapper::eigen::EigenToVector(cbl::wrapper::eigen::MatrixToEigen(covMat).diagonal().array().sqrt());
47 
48  glob::STR_multivariateGaussian parameters;
49  parameters.MeanVec = cbl::wrapper::eigen::VectorToEigen(meanVec);
50  parameters.CovMat = cbl::wrapper::eigen::MatrixToEigen(covMat);
51 
52  m_inputs = std::make_shared<glob::STR_multivariateGaussian>(parameters);
53  m_Func = &multivariateGaussian;
54 
55  m_distributionVec.erase(m_distributionVec.begin(), m_distributionVec.end());
56  m_distributionVec.resize(meanVec.size(), NULL);
57 
58  for (size_t i=0; i<meanVec.size(); i++)
59  m_distributionVec[i] = std::make_shared<cbl::glob::Distribution>(cbl::glob::Distribution(cbl::glob::DistributionType::_Gaussian_, {meanVec[i], sigmaVec[i]}, xMinVec[i], xMaxVec[i], seed+i));
60 
61 }
62 
63 // ======================================================================================
64 
65 
66 cbl::glob::CombinedDistribution::CombinedDistribution (const std::string filename, const std::string path, const std::vector<int> columns_to_read, const int skip_nlines, const int type_data, const bool normalize, const int distNum, const double rMAX, const double cell_size)
67 {
68  int nparams = columns_to_read.size()-1;
69  std::vector<std::vector<double>> all_data = cbl::read_file(filename, path, columns_to_read, skip_nlines);
70  std::vector<double> posterior;
71 
72  switch (type_data) {
73  case 0:
74  coutCBL << "Reading log(Posterior) distribution as column number " << columns_to_read[nparams] << std::endl;
75  posterior = all_data[nparams];
76  if (cbl::Min(posterior)<log(DBL_MIN)) ErrorCBL("please select a valid higher log(Posterior) values!", "CombinedDistribution", "CombinedDistribution.cpp");
77  for (size_t i=0; i<posterior.size(); i++) posterior[i] = exp(posterior[i]);
78  break;
79 
80  case 1:
81  coutCBL << "Reading Posterior distribution as column number " << columns_to_read[nparams] << std::endl;
82  posterior = all_data[nparams+1];
83  if (cbl::Min(posterior)<0.) ErrorCBL("please select a valid positive Posterior values!", "CombinedDistribution", "CombinedDistribution.cpp");
84  break;
85 
86  case 2:
87  coutCBL << "Reading Chi2 distribution as column number " << columns_to_read[nparams] << std::endl;
88  posterior = all_data[nparams];
89  if (cbl::Min(posterior)<-2.*log(DBL_MIN)) ErrorCBL("please select a valid higher log(Posterior) values!", "CombinedDistribution", "CombinedDistribution.cpp");
90  for (size_t i=0; i<posterior.size(); i++) posterior[i] = exp(-0.5*posterior[i]);
91  break;
92 
93  default:
94  ErrorCBL("please select a valid type_data!", "CombinedDistribution", "CombinedDistribution.cpp");
95  }
96 
97  if (normalize) {
98  const double Min_post = cbl::Min(posterior);
99  const double Max_post = cbl::Max(posterior);
100  const double Norm = fabs(Max_post-Min_post);
101  for (size_t i=0; i<posterior.size(); i++) posterior[i] = (posterior[i]-Min_post)/Norm;
102  }
103 
104  m_xMinVec.erase(m_xMinVec.begin(), m_xMinVec.end());
105  m_xMaxVec.erase(m_xMaxVec.begin(), m_xMaxVec.end());
106  m_xMinVec.resize(nparams);
107  m_xMaxVec.resize(nparams);
108 
109  std::vector<std::vector<double>> data(nparams);
110  for (int i=0; i<nparams; i++) {
111  data[i] = all_data[i];
112  m_xMinVec[i] = cbl::Min(data[i])*0.99;
113  m_xMaxVec[i] = cbl::Max(data[i])*1.01;
114  }
115 
116  cbl::chainmesh::ChainMesh chMesh(cell_size, nparams);
117  chMesh.normalize(data, posterior, rMAX);
118 
119  glob::STR_chainMeshInterpolate parameters;
120  parameters.ChainMesh = chMesh;
121  parameters.DistNum = distNum;
122 
123  m_inputs = std::make_shared<glob::STR_chainMeshInterpolate>(parameters);
124  m_Func = &chainMeshInterpolate;
125 
126  m_distributionVec.erase(m_distributionVec.begin(), m_distributionVec.end());
127  m_distributionVec.resize(nparams, NULL);
128 
129  for (int i=0; i<nparams; i++)
130  m_distributionVec[i] = std::make_shared<cbl::glob::Distribution>(cbl::glob::Distribution(cbl::glob::DistributionType::_Uniform_, m_xMinVec[i], m_xMaxVec[i]));
131 
132 }
133 
134 // ======================================================================================
135 
136 
137 double cbl::glob::CombinedDistribution::operator[] (std::vector<double> xx)
138 {
139  double fact = m_Func(xx, m_inputs);
140 
141  if (fact==0.) fact = DBL_MIN;
142 
143  else if (!std::isfinite(fact)) {
144  fact = DBL_MIN;
145  WarningMsgCBL("inf or nan values encountered", "operator[]", "CombinedDistribution.cpp");
146  }
147 
148  return fact;
149 }
The class CombinedDistribution.
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class ChainMesh.
Definition: ChainMesh.h:60
The class CombinedDistribution.
Definition: Distribution.h:124
DistributionType
the distribution type
Definition: Distribution.h:51
@ _Uniform_
Identity function.
@ _Gaussian_
Gaussian function.
Eigen::MatrixXd MatrixToEigen(const std::vector< std::vector< double >> mat)
convert a std::vector<std::vector<double>> to an Eigen::MatrixXd object
Eigen::MatrixXd VectorToEigen(const std::vector< double > vec)
convert a std::vector<double> to an Eigen::MatrixXd object
std::vector< double > EigenToVector(const Eigen::MatrixXd vec)
convert an Eigen::MatrixXd to a std::vector<double>
T Min(const std::vector< T > vect)
minimum element of a std::vector
Definition: Kernel.h:1324
double multivariateGaussian(std::vector< double > xx, std::shared_ptr< void > pars)
the multivariate Gaussian function
Definition: Func.cpp:79
std::vector< std::vector< double > > read_file(const std::string file_name, const std::string path_name, const std::vector< int > column_data, const int skip_nlines=0)
read a data from a file ASCII
Definition: Kernel.cpp:410
double chainMeshInterpolate(std::vector< double > xx, std::shared_ptr< void > pars)
a multidimension interpolator
Definition: Func.cpp:68
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
T Max(const std::vector< T > vect)
maximum element of a std::vector
Definition: Kernel.h:1336
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
Definition: Kernel.h:747