gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
lognormal.hpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
24 
25 #ifndef __PRIOR_LOGNORMAL_HPP__
26 #define __PRIOR_LOGNORMAL_HPP__
27 
28 #include <algorithm>
29 #include <cmath>
30 #include <numeric>
31 #include <string>
32 #include <unordered_map>
33 #include <vector>
34 
38 
39 #include <boost/math/special_functions/erf.hpp>
40 
41 namespace Gambit
42 {
43  namespace Priors
44  {
55  class LogNormal : public BasePrior
56  {
57  private:
58  std::vector <double> mu;
59  double base{10.};
60  mutable Cholesky col;
61 
62  public:
63  // Constructor defined in LogNormal.cpp
64  LogNormal(const std::vector<std::string>&, const Options&);
65 
66  // Transformation from unit interval to the Log-Normal
67  void transform(const std::vector <double> &unitpars, std::unordered_map<std::string, double> &outputMap) const
68  {
69  std::vector<double> vec(unitpars.size());
70 
71  auto v_it = vec.begin();
72  for (auto elem_it = unitpars.begin(), elem_end = unitpars.end(); elem_it != elem_end; elem_it++, v_it++)
73  {
74  *v_it = M_SQRT2 * boost::math::erf_inv(2. * (*elem_it) - 1.);
75  }
76 
77  col.ElMult(vec);
78 
79  v_it = vec.begin();
80  auto m_it = mu.begin();
81  for (auto str_it = param_names.begin(), str_end = param_names.end(); str_it != str_end; str_it++)
82  {
83  outputMap[*str_it] = std::pow(base, *(v_it++) + *(m_it++));
84  }
85  }
86 
87  std::vector<double> inverse_transform(const std::unordered_map<std::string, double> &physical) const override
88  {
89  // undo exponentiation
90  std::vector<double> log_physical;
91  for (int i = 0, n = this->size(); i < n; i++)
92  {
93  log_physical.push_back(std::log(physical.at(param_names[i])) / std::log(base));
94  }
95 
96  // subtract mean
97  std::vector<double> central;
98  for (int i = 0, n = this->size(); i < n; i++)
99  {
100  central.push_back(log_physical[i] - mu[i]);
101  }
102 
103  // invert rotation by Cholesky matrix
104  std::vector<double> rotated = col.invElMult(central);
105 
106  // now diagonal; invert Gaussian CDF
107  std::vector<double> u;
108  for (const auto& v : rotated)
109  {
110  u.push_back(0.5 * (boost::math::erf(v / M_SQRT2) + 1.));
111  }
112  return u;
113  }
114 
115  double operator()(const std::vector<double> &vec) const
116  {
117  static double norm = 0.5 * std::log(2. * M_PI * std::pow(col.DetSqrt(), 2));
118  std::vector<double> log_vec;
119  for (const auto& v : vec)
120  {
121  log_vec.push_back(std::log(v) / std::log(base));
122  }
123  const double log_prod = std::accumulate(log_vec.begin(), log_vec.end(), 0.);
124  return -0.5 * col.Square(log_vec, mu) - norm - log_prod;
125  }
126  };
127 
128  LOAD_PRIOR(lognormal, LogNormal)
129 
130  } // namespace Priors
131 } // namespace Gambit
132 
133 #endif // __PRIOR_LOGNORMAL_HPP__
Abstract base class for priors.
Definition: base_prior.hpp:40
declaration for scanner module
LogNormal(const std::vector< std::string > &, const Options &)
Definition: lognormal.cpp:32
std::vector< std::string > param_names
Definition: base_prior.hpp:46
double Square(const std::vector< double > &y, const std::vector< double > &y0)
Definition: cholesky.hpp:106
Prior object construction routines.
Declarations for the YAML options class.
unsigned int size() const
Definition: base_prior.hpp:77
double operator()(const std::vector< double > &vec) const
Log of PDF density.
Definition: lognormal.hpp:115
Multi-dimensional Log-Normal prior.
Definition: lognormal.hpp:55
void transform(const std::vector< double > &unitpars, std::unordered_map< std::string, double > &outputMap) const
Transform from unit hypercube to parameter.
Definition: lognormal.hpp:67
double DetSqrt()
Definition: cholesky.hpp:127
std::vector< double > invElMult(const std::vector< double > &y) const
x = L^-1 y where L is the lower-diagonal Cholesky matrix
Definition: cholesky.hpp:91
RangePrior1D< flatprior > LOAD_PRIOR(cos, RangePrior1D< cosprior >) LOAD_PRIOR(sin
double pow(const double &a)
Outputs a^i.
void ElMult(std::vector< double > &y) const
Definition: cholesky.hpp:69
std::vector< double > mu
Definition: lognormal.hpp:58
std::vector< double > inverse_transform(const std::unordered_map< std::string, double > &physical) const override
Transform from parameter back to unit hypercube.
Definition: lognormal.hpp:87
std::vector< T > vec(std::vector< T > vector)
Definition: daFunk.hpp:142
TODO: see if we can use this one:
Definition: Analysis.hpp:33
A small wrapper object for &#39;options&#39; nodes.