gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
flat_log.hpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
21 
22 #ifndef PRIOR_DEFS_HPP
23 #define PRIOR_DEFS_HPP
24 
25 #include <cmath>
27 
32 
33 
34  // let us imagine that the user wants to specify something like this in the inifile:
35  // log; M0; lower=x; upper=y
36  // log; M12; lower=x; upper=y
37  // flat; A0; lower=x; upper=y
38 
39  // or something worse;
40  // log; p1; lower=x; upper=y
41  // custom2D; p2,p3; lower1=x2; lower2=x2; upper1=x1; upper2=x2; extrapar=z
42 
43  // (where custom2D is a 2D prior over p2 and p3, with some specified ranges,
44  // but also an extra parameter which controls some aspect of the prior shape
45 
46  // Need to create the appropriate prior objects based on this information.
47  // Will have to communicate to the primary parameter object to get the correct
48  // ordering of parameters.
49 
50  // Lets make some fake structure to hold this information, to be replaced by
51  // output of the yaml file parser.
52  // Ahh ok I have added a proposal to gambit.yaml for the sort of thing we need.
53  // Looks like, for every prior object we want to create, there should be 3 things:
54  // prior name (string, identifies factory function to use)
55  // parameters list (strings, identifes parameters to associate with this prior)
56  // ranges (optional but common; pair of doubles to supply to priors)
57  // options (set of key,value pairs for any custom input needed to fancy priors)
58  // e.g. an entry in the yaml file might look like this:
59  // custom2D:
60  // parameters: A0, Mstop
61  // options:
62  // lower1: -1000
63  // upper1: 1000
64  // correlation: 0.5
65 
66  // We need a factory system of some kind.
67  // Factory functions need to be able to pass a variety of arguments to the
68  // constructors of the priors, sometimes doubles, but also other prior objects!
69  // CHANGE: ok, I think it is safe to treat the "composite" prior class as
70  // special, and used only for putting all the individual priors together
71  // (if number of sub-priors > 1). This prior is not accessible to the user
72  // directly. All user accessible priors can take only the wrapped YAML::Node object
73  // as an argument.
74 
75  // All priors (except for CompositePrior) take their options as an Options object
76  // (which wraps a YAML::Node object). They have to extract the options they need
77  // from this structure. The options present there are passed directly from the inifile,
78 
80  // Whenever you add a new prior, you need to add an entry here in order to
81  // have it accessible via the inifile (by whatever name you specify here).
82 
83 namespace Gambit
84 {
85  namespace Priors
86  {
87  // ------------------1D prior function library------------------------
88  // If you add anything here, don't forget to declare it in the header as well!
89 
90  // Simple single parameter priors.
91  // In all cases input x is a variate from the unit uniform distribution [0,1].
92 
93  // 'flat' prior
94  // Transforms x to a sample from the uniform interval [a,b].
95 
96  struct flatprior
97  {
98  static double limits(double x) {return x;}
99  static double inv(double x) {return x;}
100  static double prior (double) {return 0;}
101  };
102 
103  struct logprior
104  {
105  static double limits(double x) {return std::log(x);}
106  static double inv(double x) {return std::exp(x);}
107  static double prior(double x){return -std::log(x);}
108  };
109 
110  struct sinprior
111  {
112  static double limits(double x) {return std::cos(x);}
113  static double inv(double x) {return std::acos(x);}
114  static double prior(double x){return std::log(std::sin(x));}
115  };
116 
117  struct cosprior
118  {
119  static double limits(double x) {return std::sin(x);}
120  static double inv(double x) {return std::asin(x);}
121  static double prior(double x){return std::log(std::cos(x));}
122  };
123 
124  struct tanprior
125  {
126  inline static double SQR(double x){return x*x;}
127  static double limits(double x) {return 1.0/SQR(std::cos(x));}
128  static double inv(double x) {return std::acos(1.0/std::sqrt(x));}
129  static double prior(double x){return std::log(std::tan(x));}
130  };
131 
132  struct cotprior
133  {
134  inline static double SQR(double x){return x*x;}
135  static double limits(double x) {return 1.0/SQR(std::sin(x));}
136  static double inv(double x) {return std::asin(1.0/std::sqrt(x));}
137  static double prior(double x){return -std::log(std::tan(x));}
138  };
139 
140  struct arccosprior
141  {
142  inline static double SQR(double x){return x*x;}
143  static double limits(double x) {return std::acos(x);}
144  static double inv(double x) {return std::cos(x);}
145  static double prior(double x) { return 1.0/std::sqrt(1-SQR(x));}
146  };
147 
149  // See factory function map to see how to use this class to quickly create new priors of this kind
150  template <class T>
151  class RangePrior1D : public BasePrior
152  {
153  private:
154  // Name of the parameter that this prior is supposed to transform
155  std::string &myparameter;
156  // Ranges for parameters
157  double lower;
158  double upper;
159  double scale;
160  double shift;
161  double scale_out;
162  double shift_out;
163 
164  public:
165 
166  // Constructor
167  RangePrior1D(const std::vector<std::string>& param, const Options& options) : BasePrior(param, 1), myparameter(param_names[0]), scale(1.0), shift(0.0), scale_out(1.0), shift_out(0.0)
168  {
169  // Read the entries we need from the options
170  if ( not options.hasKey("range") )
171  {
172  scan_err << "Error! No 'range' keyword found in options supplied for building RangePrior1D prior (i.e. some instance of this, probably 'flat' or 'log')" << scan_end;
173  }
174  std::pair<double, double> range = options.getValue< std::pair<double, double> >("range");
175  if (range.first > range.second)
176  {
177  double temp = range.first;
178  range.first = range.second;
179  range.second = temp;
180  }
181 
182  if (param.size()!=1)
183  {
184  scan_err << "Invalid input to some prior derived from RangePrior1D (in constructor): 'myparameters' must be a vector of size 1! (has size=" << param.size() << ")" << scan_end;
185  }
186 
187  if (options.hasKey("scale"))
188  {
189  if (options.getValue<std::string>("scale") == "degrees")
190  {
191  scale = 0.0174532925199;
192  }
193  else
194  {
195  scale = options.getValue<double>("scale");
196  }
197  }
198 
199  if (options.hasKey("shift"))
200  {
201  shift = options.getValue<double>("shift");
202  }
203 
204  // If the user has specifically set output_scaled_values = false, then remove any scale and shift before outputting.
205  if (options.hasKey("output_scaled_values") and not options.getValue<bool>("output_scaled_values"))
206  {
207  scale_out = scale;
208  shift_out = shift;
209  }
210 
211  lower = T::limits(range.first*scale + shift);
212  upper = T::limits(range.second*scale + shift);
213  }
214 
215  // Transformation from unit interval to specified range
216  // (need to use vectors to be compatible with BasePrior virtual function)
217  void transform(const std::vector<double> &unitpars, std::unordered_map<std::string,double> &output) const
218  {
219  output[myparameter] = (T::inv(unitpars[0]*(upper-lower) + lower)-shift_out)/scale_out;
220  }
221 
222  std::vector<double> inverse_transform(const std::unordered_map<std::string, double> &physical) const override
223  {
224  const double p = physical.at(myparameter);
225  const double x = T::limits(scale_out * p + shift_out);
226  const double u = (x - lower) / (upper - lower);
227  return {u};
228  }
229 
230  double operator()(const std::vector<double> &vec) const {return T::prior(vec[0]*scale+shift)*scale;}
231  };
232 
240  }
241 }
242 
243 #endif
static double limits(double x)
Definition: flat_log.hpp:112
static double SQR(double x)
Definition: flat_log.hpp:126
static double prior(double x)
Definition: flat_log.hpp:129
Abstract base class for priors.
Definition: base_prior.hpp:40
static double limits(double x)
Definition: flat_log.hpp:127
static double inv(double x)
Definition: flat_log.hpp:120
static double prior(double x)
Definition: flat_log.hpp:137
static double prior(double x)
Definition: flat_log.hpp:114
static double prior(double x)
Definition: flat_log.hpp:145
static double inv(double x)
Definition: flat_log.hpp:144
static double prior(double)
Definition: flat_log.hpp:100
Prior object construction routines.
static double inv(double x)
Definition: flat_log.hpp:136
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
static double inv(double x)
Definition: flat_log.hpp:99
#define scan_err
Defined to macros to output errors in the form: scan_err << "error" << scan_end; scan_warn << "warnin...
void transform(const std::vector< double > &unitpars, std::unordered_map< std::string, double > &output) const
Transform from unit hypercube to parameter.
Definition: flat_log.hpp:217
static double limits(double x)
Definition: flat_log.hpp:98
static double SQR(double x)
Definition: flat_log.hpp:134
RangePrior1D(const std::vector< std::string > &param, const Options &options)
Definition: flat_log.hpp:167
static double limits(double x)
Definition: flat_log.hpp:119
std::vector< double > inverse_transform(const std::unordered_map< std::string, double > &physical) const override
Transform from parameter back to unit hypercube.
Definition: flat_log.hpp:222
Template class for 1d priors which need only a "range" option in their constructor.
Definition: flat_log.hpp:151
static double limits(double x)
Definition: flat_log.hpp:143
RangePrior1D< flatprior > LOAD_PRIOR(cos, RangePrior1D< cosprior >) LOAD_PRIOR(sin
static double inv(double x)
Definition: flat_log.hpp:106
#define scan_end
static double prior(double x)
Definition: flat_log.hpp:121
static double limits(double x)
Definition: flat_log.hpp:135
double operator()(const std::vector< double > &vec) const
Log of PDF density.
Definition: flat_log.hpp:230
static double SQR(double x)
Definition: flat_log.hpp:142
std::vector< T > vec(std::vector< T > vector)
Definition: daFunk.hpp:142
static double limits(double x)
Definition: flat_log.hpp:105
static double inv(double x)
Definition: flat_log.hpp:128
const T SQR(const T a)
TODO: see if we can use this one:
Definition: Analysis.hpp:33
A small wrapper object for &#39;options&#39; nodes.
static double inv(double x)
Definition: flat_log.hpp:113
static double prior(double x)
Definition: flat_log.hpp:107