gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
fixed_same_as.hpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
10 //
16 
17 #ifndef FIXED_SAME_AS_PRIOR_HPP
18 #define FIXED_SAME_AS_PRIOR_HPP
19 
20 #include <algorithm>
21 
23 
24 
25 namespace Gambit
26 {
27  namespace Priors
28  {
30  class FixedPrior : public BasePrior
31  {
32  private:
33  std::vector<double> value;
34  mutable int iter;
35 
36  public:
37  FixedPrior(const std::vector<std::string>& param, const Options& options) : BasePrior(param), iter(0)
38  {
39  if (options.hasKey("fixed_value"))
40  {
41  if (options.getNode("fixed_value").IsScalar())
42  {
43  value.push_back(options.getValue<double>("fixed_value"));
44  }
45  else if (options.getNode("fixed_value").IsSequence())
46  {
47  value = options.getValue<std::vector<double>>("fixed_value");
48  }
49  else
50  {
51  scan_err << "fixed_value input for parameter " << param_names[0] << " is neither scalar nor sequence" << scan_end;
52  }
53  }
54  else
55  {
56  scan_err << "Did not give fixed_value for parameter " << param_names[0] << "..." << scan_end;
57  }
58  }
59 
60  FixedPrior(const std::string& param, const Options& options) : BasePrior(param), iter(0)
61  {
62  if (options.getNode().IsScalar())
63  {
64  value.push_back(options.getValue<double>());
65  }
66  else if (options.getNode().IsSequence())
67  {
68  value = options.getValue<std::vector<double>>();
69  }
70  else
71  {
72  scan_err << "fixed_value input for parameter " << param_names[0] << " is neither scalar nor sequence" << scan_end;
73  }
74  }
75 
76  FixedPrior(const std::string &name, double value) : BasePrior(name), value(1, value), iter(0) {}
77 
78  std::vector<std::string> getShownParameters() const {return std::vector<std::string>();}
79 
80  void transform(const std::vector<double> &, std::unordered_map<std::string, double> &outputMap) const
81  {
82  for (auto it = param_names.begin(), end = param_names.end(); it != end; it++)
83  {
84  outputMap[*it] = value[iter];
85  }
86 
87  iter = (iter + 1)%value.size();
88  }
89 
90  std::vector<double> inverse_transform(const std::unordered_map<std::string, double> &physical) const override
91  {
92  const double rtol = 1e-4;
93  for (int i = 0, n = this->size(); i < n; i++)
94  {
95  const double a = physical.at(param_names[i]);
96  const double b = value[i];
97  const double rdiff = std::abs(a - b) / std::max(std::abs(a), std::abs(b));
98  if (rdiff > rtol)
99  {
100  throw std::runtime_error("no inverse as physical does not match fixed value");
101  }
102  }
103  // arbitrary as every value of unit hypercube maps to the same fixed parameter
104  std::vector<double> u(this->size(), 0.5);
105  return u;
106  }
107  };
108 
110  class MultiPriors : public BasePrior
111  {
112  private:
113  std::string name;
114  std::vector<double> scale, shift;
115 
116  public:
117  MultiPriors(const std::vector<std::string>& param, const Options& options) :
118  BasePrior(param), scale(param.size(), 1.0), shift(param.size(), 0.0)
119  {
120  if (options.hasKey("same_as"))
121  {
122  name = options.getValue<std::string>("same_as");
123  }
124  else
125  {
126  std::stringstream err;
127  scan_err << "Did not give same_as parameters for parameter " << name << scan_end;
128  }
129 
130  if (options.hasKey("scale"))
131  {
132  scale = options.getValue<std::vector<double>>("scale");
133  }
134 
135  if (options.hasKey("shift"))
136  {
137  shift = options.getValue<std::vector<double>>("shift");
138  }
139  }
140 
141  MultiPriors(std::string name_in, std::unordered_map<std::string, std::pair<double, double> > &map_in)
142  {
143  std::string::size_type pos_old = 0;
144  std::string::size_type pos = name_in.find("+");
145  while (pos != std::string::npos)
146  {
147  std::string p_name = name_in.substr(pos_old, (pos-pos_old));
148  param_names.push_back(p_name);
149  if (map_in.find(p_name) == map_in.end())
150  {
151  scale.push_back(1.0);
152  shift.push_back(0.0);
153  }
154  else
155  {
156  scale.push_back(map_in[p_name].first);
157  shift.push_back(map_in[p_name].second);
158  }
159  pos_old = pos + 1;
160  pos = name_in.find("+", pos_old);
161  }
162 
163  name = name_in.substr(pos_old);
164  param_names.push_back(name_in);
165  }
166 
167  std::vector<std::string> getShownParameters() const {return std::vector<std::string>();}
168 
169  void transform (const std::vector<double> &, std::unordered_map<std::string, double> &outputMap) const
170  {
171  double value = outputMap[name];
172 
173  auto it1 = scale.begin(), it2 = shift.begin();
174  for (auto it = param_names.begin(), end = param_names.end(); it != end; ++it, ++it1, ++it2)
175  {
176  outputMap[*it] = (*it1)*value + *it2;
177  }
178  }
179 
180  std::vector<double> inverse_transform(const std::unordered_map<std::string, double> &physical) const override
181  {
182  const double rtol = 1e-4;
183  for (int i = 0, n = this->size(); i < n; i++)
184  {
185  const double a = physical.at(param_names[i]);
186  const double b = scale[i] * physical.at(name) + shift[i];
187  const double rdiff = std::abs(a - b) / std::max(std::abs(a), std::abs(b));
188  if (rdiff > rtol)
189  {
190  throw std::runtime_error("no inverse as physical does not match same as value");
191  }
192  }
193  // arbitrary as every value of unit hypercube maps to the same fixed parameter
194  std::vector<double> u(this->size(), 0.5);
195  return u;
196  }
197 
198  };
199 
200  LOAD_PRIOR(fixed_value, FixedPrior)
201  LOAD_PRIOR(same_as, MultiPriors)
202  }
203 }
204 
205 #endif
Abstract base class for priors.
Definition: base_prior.hpp:40
void transform(const std::vector< double > &, std::unordered_map< std::string, double > &outputMap) const
Transform from unit hypercube to parameter.
std::vector< double > value
std::vector< std::string > getShownParameters() const
std::vector< std::string > param_names
Definition: base_prior.hpp:46
std::vector< std::string > getShownParameters() const
FixedPrior(const std::vector< std::string > &param, const Options &options)
Prior object construction routines.
FixedPrior(const std::string &param, const Options &options)
START_MODEL b
Definition: demo.hpp:270
bool hasKey(const args &... keys) const
Getters for key/value pairs (which is all the options node should contain)
TYPE getValue(const args &... keys) const
unsigned int size() const
Definition: base_prior.hpp:77
#define scan_err
Defined to macros to output errors in the form: scan_err << "error" << scan_end; scan_warn << "warnin...
A parameter that is fixed to a different parameter.
FixedPrior(const std::string &name, double value)
A fixed parameter.
std::vector< double > inverse_transform(const std::unordered_map< std::string, double > &physical) const override
Transform from parameter back to unit hypercube.
RangePrior1D< flatprior > LOAD_PRIOR(cos, RangePrior1D< cosprior >) LOAD_PRIOR(sin
std::vector< double > inverse_transform(const std::unordered_map< std::string, double > &physical) const override
Transform from parameter back to unit hypercube.
MultiPriors(const std::vector< std::string > &param, const Options &options)
#define scan_end
MultiPriors(std::string name_in, std::unordered_map< std::string, std::pair< double, double > > &map_in)
void transform(const std::vector< double > &, std::unordered_map< std::string, double > &outputMap) const
Transform from unit hypercube to parameter.
TODO: see if we can use this one:
Definition: Analysis.hpp:33
A small wrapper object for &#39;options&#39; nodes.
std::vector< double > shift
YAML::Node getNode(const args &... keys) const
Retrieve raw YAML node.