gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
toy_mcmc.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
10 //
16 
17 #ifdef WITH_MPI
19 #include "mpi.h"
21 #endif
22 
23 #include <vector>
24 #include <string>
25 #include <cmath>
26 #include <iostream>
27 #include <map>
28 #include <sstream>
29 
32 
33 scanner_plugin(toy_mcmc, version(1, 0, 0))
34 {
35  void hiFunc(){std::cout << "This is the GAMBIT toy MCMC. Don't run serious scans with this." << std::endl;}
36 
37  int N, ma, rank, numtasks;
38  like_ptr LogLike;
39 
41  {
42  hiFunc();
43 
44  N = get_inifile_value<int>("point_number", 1000);
45  LogLike = get_purpose(get_inifile_value<std::string>("like"));
46  ma = get_dimension();
47 
48  if (N <= 0)
49  scan_err << "You need to choose at least 2 points" << scan_end;
50 
51 #ifdef WITH_MPI
52  MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
53  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
54 #else
55  numtasks = 1;
56  rank = 0;
57 #endif
58  }
59 
60  /*Define main module function. Can input and return any types or type (exp. cannot return void).*/
61  int plugin_main (void)
62  {
63 
64  double ans, chisq, chisqnext;
65  int mult = 1, count = 0, total = 1;
66  unsigned long long int id;
67  std::vector<double> a(ma);
68 
69  Gambit::Options txt_options;
70  txt_options.setValue("synchronised",false);
71  get_printer().new_stream("txt", txt_options);
72  Gambit::Scanner::printer *out_stream = get_printer().get_stream("txt");
73  out_stream->reset();
74 
75  for (auto &&val : a)
76  val = Gambit::Random::draw();
77 
78  std::cout << "Metropolis Hastings Algorthm Started" << std::endl; // << "tpoints = " << "\n\taccept ratio = " << std::endl;
79 
80  chisq = -LogLike(a);
81  id = LogLike->getPtID();
82 #ifdef WITH_MPI
83  if (numtasks > 1)
84  {
85  int countsofar = 0, idnext;
86  MPI_Status stat;
87  std::vector<unsigned long long int> buffer_ids(N);
88  std::vector<double> buffer_chisqs(N);
89 
90  do
91  {
92  int countsofarnext = N-count;
93  if (countsofarnext < numtasks)
94  countsofarnext = numtasks;
95 
96  if (countsofarnext != countsofar)
97  {
98  countsofar = countsofarnext;
99  buffer_ids.resize(countsofar);
100  buffer_chisqs.resize(countsofar);
101  }
102 
103  total += countsofar;
104  for (int i = rank, end = countsofar; i < end; i+=numtasks)
105  {
106  for (auto &&val : a)
107  {
108  val = Gambit::Random::draw();
109  }
110 
111  buffer_chisqs[i] = -LogLike(a);
112  buffer_ids[i] = LogLike->getPtID();
113  }
114 
115  if (rank == 0)
116  {
117  for (int i = 0, end = countsofar; i < end; i++)
118  {
119  int tag = i%numtasks;
120  if (tag != 0)
121  {
122  MPI_Recv (&buffer_ids[i], 1, MPI_UNSIGNED_LONG_LONG, tag, tag, MPI_COMM_WORLD, &stat);
123  MPI_Recv (&buffer_chisqs[i], 1, MPI_DOUBLE, tag, tag, MPI_COMM_WORLD, &stat);
124  }
125  }
126 
127  for (auto &&iter : zip(buffer_ids, buffer_chisqs))
128  {
129  boost::tie(idnext, chisqnext) = iter;
130  ans = chisqnext - chisq;
131  if ((ans <= 0.0)||(-std::log(Gambit::Random::draw()) >= ans))
132  {
133  out_stream->print(mult, "mult", rank, id);
134  id = idnext;
135  chisq = chisqnext;
136  mult = 1;
137  count++;
138  }
139  else
140  {
141  mult++;
142  }
143  }
144 
145  std::cout << "points = " << count << "; accept ratio = " << (double)count/(double)total << std::endl;
146  }
147  else
148  {
149  for (int i = rank, end = countsofar; i < end; i+=numtasks)
150  {
151  MPI_Send (&buffer_ids[i], 1, MPI_UNSIGNED_LONG_LONG, 0, rank, MPI_COMM_WORLD);
152  MPI_Send (&buffer_chisqs[i], 1, MPI_DOUBLE, 0, rank, MPI_COMM_WORLD);
153  }
154  }
155  }
156  while(count < N);
157  } else
158 #endif
159  do
160  {
161  total++;
162 
163  for (auto &&val : a)
164  {
165  val = Gambit::Random::draw();
166  }
167 
168  chisqnext = -LogLike(a);
169 
170  ans = chisqnext - chisq;
171  if ((ans <= 0.0)||(-std::log(Gambit::Random::draw()) >= ans))
172  //if (true)
173  {
174  out_stream->print(mult, "mult", rank, id);
175  id = LogLike->getPtID();
176  chisq = chisqnext;
177  mult = 1;
178  count++;
179  // cout << "\033[2A\tpoints = " << count << "\n\taccept ratio = " << " \033[15D" << (double)count/(double)total << endl;
180  std::cout << "points = " << count << "; accept ratio = " << (double)count/(double)total << std::endl;
181  }
182  else
183  {
184  mult++;
185  }
186  }
187  while(count < N);
188 
189  return 0;
190  }
191 }
192 
void print(T const &in, const std::string &label, const int vertexID, const uint rank, const ulong pointID)
DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry double
#define plugin_constructor
Runs when the plugin is loaded.
auto zip(const T &... containers) -> boost::iterator_range< boost::zip_iterator< decltype(boost::make_tuple(std::begin(containers)...))>>
Use for combine container in a range loop: for (auto &&x : zip(a, b)){...}.
static double draw()
Draw a single uniform random deviate from the interval (0,1) using the chosen RNG engine...
#define scan_err
Defined to macros to output errors in the form: scan_err << "error" << scan_end; scan_warn << "warnin...
#define plugin_main(...)
Declaration of the main function which will be ran by the interface.
virtual void reset(bool force=false)=0
Function to signal to the printer to write buffer contents to disk.
A threadsafe interface to the STL random number generators.
Simple header file for turning compiler warnings back on after having included one of the begin_ignor...
Pragma directives to suppress compiler warnings coming from including MPI library headers...
#define scan_end
declaration for scanner module
void setValue(const KEYTYPE &key, const VALTYPE &val)
Basic setter, for adding extra options.
scanner_plugin(toy_mcmc, version(1, 0, 0))
Definition: toy_mcmc.cpp:33
A small wrapper object for &#39;options&#39; nodes.