KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sample_sampler.h
Go to the documentation of this file.
1 /* $Id: sample_sampler.h 18278 2014-11-25 01:42:10Z ksimek $ */
2 /* =========================================================================== *
3  |
4  | Copyright (c) 1994-2010 by Kobus Barnard (author)
5  |
6  | Personal and educational use of this code is granted, provided that this
7  | header is kept intact, and that the authorship is not misrepresented, that
8  | its use is acknowledged in publications, and relevant papers are cited.
9  |
10  | For other use contact the author (kobus AT cs DOT arizona DOT edu).
11  |
12  | Please note that the code in this file has not necessarily been adequately
13  | tested. Naturally, there is no guarantee of performance, support, or fitness
14  | for any particular task. Nonetheless, I am interested in hearing about
15  | problems that you encounter.
16  |
17  | Author: Kyle Simek, Ernesto Brau
18  * =========================================================================== */
19 
20 #ifndef SAMPLE_SAMPLER_H_INCLUDED
21 #define SAMPLE_SAMPLER_H_INCLUDED
22 
23 #include "sample_cpp/sample_step.h"
24 #include "sample_cpp/sample_base.h"
26 
27 #include <boost/lambda/lambda.hpp>
28 #include <boost/function.hpp>
29 #include <l_cpp/l_index.h>
30 #include <vector>
31 
46 template<typename Model>
48 {
49 private:
50  typedef boost::function0<void> Callback;
51 public:
52  typedef typename Sampler_step<Model>::Type Step;
53  typedef Model Model_type;
54  //typedef typename Sampler_callback<Model>::Type Callback;
55 
61  const Model& initial_state,
62  double initial_log_target) :
63  m_cur_model(initial_state),
64  m_cur_log_target(initial_log_target)
65  {}
66 
68 
81  virtual void run(int num_iterations);
82 
86  Model& current_state()
87  {
88  return m_cur_model;
89  }
90 
94  const Model& current_state() const
95  {
96  return m_cur_model;
97  }
98 
103  double current_log_target() const
104  {
105  return m_cur_log_target;
106  }
107 
108  template <class Recorder>
109  void add_recorder(Recorder r)
110  {
112  m_record.add(r);
113  }
114 
115  template <class Recorder>
116  void add_recorder(Recorder* r)
117  {
119  m_record.add(r);
120  }
121 
122  template <class Callback>
123  void add_record_callback(Callback cb)
124  {
126  }
127 
128  //virtual const char* get_type() const{ return "Abstract_sampler"; }
129 
130 // template <class Recorder>
131 // Recorder& get_recorder(size_t i)
132 // {
133 // BOOST_CONCEPT_ASSERT((ModelRecorder<Recorder>));
134 // return m_record.get_recorder<Recorder>(i);
135 // }
136 
137  template <class Recorder>
138  const Recorder& get_recorder(size_t i) const
139  {
141  return m_record.template get_recorder<Recorder>(i);
142  }
143 
148  void if_accept(const Callback& cb)
149  {
150  using namespace boost::lambda;
151  if(m_if_accept.empty())
152  m_if_accept = cb;
153  else
154  // comma operator of boost::lambda chains two functions together
155  m_if_accept = (m_if_accept , cb);
156  }
157 
162  void if_reject(const Callback& cb)
163  {
164  using namespace boost::lambda;
165  if(m_if_reject.empty())
166  m_if_reject = cb;
167  else
168  // comma operator of boost::lambda chains two functions together
169  m_if_reject = (m_if_reject , cb);
170  }
171 
183  void on_accept(const Callback& cb)
184  {
185  using namespace boost::lambda;
186  if(m_on_accept.empty())
187  m_on_accept = cb;
188  else
189  // comma operator of boost::lambda chains two functions together
190  m_on_accept = (m_on_accept , cb);
191  }
192 
204  void on_reject(const Callback& cb)
205  {
206  using namespace boost::lambda;
207  if(m_on_reject.empty())
208  m_on_reject = cb;
209  else
210  // comma operator of boost::lambda chains two functions together
211  m_on_reject = (m_on_reject , cb);
212  }
213 
214 protected:
215 
219  virtual const Step& choose_step() const = 0;
220 
221 private:
222  Model m_cur_model;
223  double m_cur_log_target;
225  //Callback pre_callback;
226  //Callback post_callback;
227 
228  // one-off callbacks (cleared every iteration)
229  Callback m_if_accept;
230  Callback m_if_reject;
231 
232  // persistent callbacks (called every iteration)
233  Callback m_on_accept;
234  Callback m_on_reject;
235 };
236 
237 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
238 
239 template<typename Model>
240 void Abstract_sampler<Model>::run(int num_iterations)
241 {
242  for(int i = 1; i <= num_iterations; i++)
243  {
244  const Step& step = choose_step();
245  Step_log<Model> log = step(m_cur_model, m_cur_log_target);
246  m_cur_log_target = log[0].lt;
247  m_record(m_cur_model, log);
248 
249  if(log.back().accept)
250  {
251  if(!m_on_accept.empty())
252  m_on_accept();
253  if(!m_if_accept.empty())
254  m_if_accept();
255  }
256  else
257  {
258  if(!m_on_reject.empty())
259  m_on_reject();
260  if(!m_if_reject.empty())
261  m_if_reject();
262  }
263 
264  // clear non-persisitent callbacks
265  m_if_accept.clear();
266  m_if_reject.clear();
267  }
268 };
269 
270 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
271 
280 template<typename Model>
282 {
283 protected:
285  {
286  void operator()(const void*) const{}
287  };
288 public:
290 
291  //typedef typename Sampler_callback<Model>::Type Callback;
292  //
294 
295 
297 
303  const Model& initial_state,
304  double initial_log_target) :
305  Parent(initial_state, initial_log_target),
306  m_steps(),
307  m_step_callbacks(),
308  m_name(),
309  m_probabilities()
310  {}
311 
319  template <class StepType>
321  const StepType& st,
322  const Model& initial_state,
323  double initial_log_target) :
324  Parent(initial_state, initial_log_target),
325  m_steps(),
326  m_step_callbacks(),
327  m_name(),
328  m_probabilities()
329  {
330  add_step(st, 1.0);
331  }
332 
341  const std::vector<Step>& step_list,
342  const std::vector<double>& prob_list,
343  const Model& initial_state,
344  double initial_log_target) :
345  Parent(initial_state, initial_log_target),
346  m_steps(),
347  m_step_callbacks(),
348  m_name(),
349  m_probabilities()
350  {
351  assert(step_list.size() == prob_list.size());
352  for(size_t i = 0; i < step_list.size(); ++i)
353  {
354  add_step(step_list[i], prob_list[i]);
355  }
356  }
357 
363  template <class StepType>
364  void add_step(const StepType& step, double prob, const std::string& name = "")
365  {
366  BOOST_CONCEPT_ASSERT((boost::CopyConstructible<StepType>));
367 
368  boost::shared_ptr<StepType> tmp(new StepType(step));
369  add_step(tmp, prob, name);
370  }
371 
372 
378  template <class StepType>
379  void add_step(StepType* step, double prob, const std::string& name = "")
380  {
381  BOOST_CONCEPT_ASSERT((boost::CopyConstructible<StepType>));
382 
383  add_step(boost::shared_ptr<StepType>(step, null_deleter()), prob, name);
384  }
385 
391  template <class StepType>
392  void add_step(const boost::shared_ptr<StepType>& step, double prob, const std::string& name = "")
393  {
394  m_steps.push_back(step);
395  m_step_callbacks.push_back(boost::ref(*step));
396  m_name.push_back(name);
397  m_probabilities.push_back(prob);
398  }
399 
403  template <class StepType>
404  const StepType& get_step(size_t i) const
405  {
406  return *boost::any_cast<boost::shared_ptr<StepType> >(m_steps.at(i));
407  }
408 
409  //virtual const char* get_type() const
410  //{ return "Multi_step_sampler"; }
411 
412 protected:
413  virtual const Step& choose_step() const
414  {
415  assert(m_steps.size() > 0);
416  std::vector<size_t> indices = kjb::Index_range(0, m_steps.size() - 1).expand();
417 
418  // TODO: make this object a member to avoid constructing every time
420  indices,
421  m_probabilities);
422  size_t s = kjb::sample(P);
423  return m_step_callbacks[s];
424  }
425 
426 private:
427  std::vector<boost::any> m_steps;
428  std::vector<Step> m_step_callbacks;
429  std::vector<std::string> m_name;
430  std::vector<double> m_probabilities;
431 };
432 
433 
443 template<typename Model>
445 {
446 public:
448 
450 
452 
453 
463  const Step& step,
464  const Model& initial_state,
465  double initial_log_target) :
466  Parent(initial_state, initial_log_target),
467  m_step(step)
468  {}
469 
470 protected:
471 
476  virtual const Step& choose_step() const
477  {
478  return m_step;
479  }
480 
481 private:
482  Step m_step;
483 };
484 
485 #endif /*SAMPLE_SAMPLER_H_INCLUDED */
486 
Multi_step_sampler(const std::vector< Step > &step_list, const std::vector< double > &prob_list, const Model &initial_state, double initial_log_target)
Definition: sample_sampler.h:340
void add_record_callback(Callback cb)
Definition: sample_sampler.h:123
Sampler_step< Model >::Type Step
Definition: sample_sampler.h:52
Definition: sample_concept.h:123
const Model & current_state() const
Definition: sample_sampler.h:94
Definition: sample_recorder.h:501
Abstract_sampler< Model >::Step Step
Definition: sample_sampler.h:293
Multi_step_sampler(const StepType &st, const Model &initial_state, double initial_log_target)
Definition: sample_sampler.h:320
void add_step(const StepType &step, double prob, const std::string &name="")
Add a new step with associated probability. This does NOT make sure probabilities add up to 1...
Definition: sample_sampler.h:364
void add_recorder(Recorder r)
Definition: sample_sampler.h:109
Definition: sample_sampler.h:444
Multi_step_sampler(const Model &initial_state, double initial_log_target)
Definition: sample_sampler.h:302
void if_reject(const Callback &cb)
Definition: sample_sampler.h:162
Model & current_state()
Definition: sample_sampler.h:86
void add_step(StepType *step, double prob, const std::string &name="")
Add a new step with associated probability. This does NOT make sure probabilities add up to 1...
Definition: sample_sampler.h:379
const Recorder & get_recorder(size_t i) const
Definition: sample_sampler.h:138
r
Definition: APPgetLargeConnectedEdges.m:127
Definition: sample_base.h:160
BOOST_CONCEPT_ASSERT((BaseModel< Model >))
Vector sample(const MV_gaussian_distribution &dist)
Sample from a multivariate normal distribution.
Definition: prob_sample.cpp:42
virtual const Step & choose_step() const
Chooses a sampler step. Pure virtual method, should be overwritten.
Definition: sample_sampler.h:413
void if_accept(const Callback &cb)
Definition: sample_sampler.h:148
Abstract_sampler< Model > Parent
Definition: sample_sampler.h:289
Definition: sample_sampler.h:47
Abstract_sampler< Model >::Step Step
Definition: sample_sampler.h:449
Single_step_sampler(const Step &step, const Model &initial_state, double initial_log_target)
Constructs an object of this type from a MH step.
Definition: sample_sampler.h:462
void on_accept(const Callback &cb)
Definition: sample_sampler.h:183
void operator()(const void *) const
Definition: sample_sampler.h:286
Model Model_type
Definition: sample_sampler.h:53
Definition: sample_recorder.h:960
void on_reject(const Callback &cb)
Definition: sample_sampler.h:204
double current_log_target() const
Definition: sample_sampler.h:103
Abstract_sampler(const Model &initial_state, double initial_log_target)
Definition: sample_sampler.h:60
void add_step(const boost::shared_ptr< StepType > &step, double prob, const std::string &name="")
Add a new step with associated probability. This does NOT make sure probabilities add up to 1...
Definition: sample_sampler.h:392
Abstract_sampler< Model > Parent
Definition: sample_sampler.h:447
virtual const Step & choose_step() const
Returns the step given in the constructor.
Definition: sample_sampler.h:476
Definition: l_index.h:65
Definition: sample_sampler.h:281
if lambda(1, 1)>0 conf
const StepType & get_step(size_t i) const
Definition: sample_sampler.h:404
boost::function2< Step_log< Model >, Model &, double > Type
Definition: sample_base.h:228
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
virtual void run(int num_iterations)
Runs the sampler. This function runs the sampler for the indicated number of iterations. At each iteration it chooses a sampler step using choose_step() and invokes it using its operator(). The best model is saved and returned.
Definition: sample_sampler.h:240
Definition: sample_sampler.h:284
virtual const Step & choose_step() const =0
Chooses a sampler step. Pure virtual method, should be overwritten.
Definition: sample_concept.h:41
void add_recorder(Recorder *r)
Definition: sample_sampler.h:116