OpenGM  2.3.x
Discrete Graphical Model Library
gibbs.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_GIBBS_HXX
3 #define OPENGM_GIBBS_HXX
4 
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 #include <iomanip>
9 #include <cstdlib>
10 #include <cmath>
11 #include <typeinfo>
12 
13 #include "opengm/opengm.hxx"
23 
24 namespace opengm {
25 
27 namespace detail_gibbs {
28 
29  template<class OPERATOR, class ACCUMULATOR, class PROBABILITY>
30  struct ValuePairToProbability;
31 
32  template<class PROBABILITY>
33  struct ValuePairToProbability<Multiplier, Maximizer, PROBABILITY>
34  {
35  typedef PROBABILITY ProbabilityType;
36  template<class T>
37  static ProbabilityType convert(const T newValue, const T oldValue)
38  { return static_cast<ProbabilityType>(newValue) / static_cast<ProbabilityType>(oldValue); }
39  };
40 
41  template<class PROBABILITY>
42  struct ValuePairToProbability<Adder, Minimizer, PROBABILITY>
43  {
44  typedef PROBABILITY ProbabilityType;
45  template<class T>
46  static ProbabilityType convert(const T newValue, const T oldValue)
47  { return static_cast<ProbabilityType>(std::exp(oldValue - newValue)); }
48  };
49 }
51 
55 template<class GIBBS>
57 public:
58  typedef GIBBS GibbsType;
59  typedef typename GibbsType::ValueType ValueType;
60  typedef typename GibbsType::GraphicalModelType GraphicalModelType;
61  typedef typename GraphicalModelType::IndependentFactorType IndependentFactorType;
62 
63  // construction
65  GibbsMarginalVisitor(const GraphicalModelType&);
66  void assign(const GraphicalModelType&);
67 
68  // manipulation
69  template<class VariableIndexIterator>
70  size_t addMarginal(VariableIndexIterator, VariableIndexIterator);
71  size_t addMarginal(const size_t);
72  void operator()(const GibbsType&, const ValueType, const ValueType, const size_t, const bool, const bool);
73 
74  // query
75  void begin(const GibbsType&, const ValueType, const ValueType) const {}
76  void end(const GibbsType&, const ValueType, const ValueType) const {}
77  size_t numberOfSamples() const;
78  size_t numberOfAcceptedSamples() const;
79  size_t numberOfRejectedSamples() const;
80  size_t numberOfMarginals() const;
81  const IndependentFactorType& marginal(const size_t) const;
82 
83 private:
84  const GraphicalModelType* gm_;
85  size_t numberOfSamples_;
86  size_t numberOfAcceptedSamples_;
87  size_t numberOfRejectedSamples_;
88  std::vector<IndependentFactorType> marginals_;
89  std::vector<size_t> stateCache_;
90 
91 };
92 
94 template<class GM, class ACC>
95 class Gibbs
96 : public Inference<GM, ACC> {
97 public:
98  typedef ACC AccumulationType;
99  typedef GM GraphicalModelType;
105  typedef double ProbabilityType;
106 
107  class Parameter {
108  public:
110 
112  const size_t maxNumberOfSamplingSteps = 1e5,
113  const size_t numberOfBurnInSteps = 1e5,
114  const bool useTemp=false,
115  const ValueType tmin=0.0001,
116  const ValueType tmax=1,
117  const IndexType periods=10,
118  const VariableProposal variableProposal = RANDOM,
119  const std::vector<size_t>& startPoint = std::vector<size_t>()
120  )
121  : maxNumberOfSamplingSteps_(maxNumberOfSamplingSteps),
122  numberOfBurnInSteps_(numberOfBurnInSteps),
123  variableProposal_(variableProposal),
124  startPoint_(startPoint),
125  useTemp_(useTemp),
126  tempMin_(tmin),
127  tempMax_(tmax),
128  periods_(periods){
130  }
131  bool useTemp_;
134  size_t periods_;
139  std::vector<size_t> startPoint_;
140 
141 
142  };
143 
144  Gibbs(const GraphicalModelType&, const Parameter& param = Parameter());
145  std::string name() const;
146  const GraphicalModelType& graphicalModel() const;
147  void reset();
149  template<class VISITOR>
150  InferenceTermination infer(VISITOR&);
151  void setStartingPoint(typename std::vector<LabelType>::const_iterator);
152  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
153 
154  LabelType markovState(const size_t) const;
155  ValueType markovValue() const;
156  LabelType currentBestState(const size_t) const;
157  ValueType currentBestValue() const;
158 
159 private:
160  ValueType cosTemp(const ValueType arg,const ValueType periode,const ValueType min,const ValueType max)const{
161  return static_cast<ValueType>(((std::cos(arg/periode)+1.0)/2.0)*(max-min))+min;
162  //if(v<
163  }
164 
165  ValueType getTemperature(const size_t step)const{
166  return cosTemp(
167  static_cast<ValueType>(step),
168  parameter_.p_,
169  parameter_.tempMin_,
170  parameter_.tempMax_
171  );
172  }
173  Parameter parameter_;
174  const GraphicalModelType& gm_;
175  MovemakerType movemaker_;
176  std::vector<size_t> currentBestState_;
177  ValueType currentBestValue_;
178  bool inInference_;
179 };
180 
181 template<class GM, class ACC>
182 inline
184 (
185  const GraphicalModelType& gm,
186  const Parameter& parameter
187 )
188 : parameter_(parameter),
189  gm_(gm),
190  movemaker_(gm),
191  currentBestState_(gm.numberOfVariables()),
192  currentBestValue_()
193 {
194  inInference_=false;
195  ACC::ineutral(currentBestValue_);
196  if(parameter.startPoint_.size() != 0) {
197  if(parameter.startPoint_.size() == gm.numberOfVariables()) {
198  movemaker_.initialize(parameter.startPoint_.begin());
199  currentBestState_ = parameter.startPoint_;
200  currentBestValue_ = movemaker_.value();
201  }
202  else {
203  throw RuntimeError("parameter.startPoint_.size() is neither zero nor equal to the number of variables.");
204  }
205  }
206 }
207 
208 template<class GM, class ACC>
209 inline void
211  if(parameter_.startPoint_.size() != 0) {
212  if(parameter_.startPoint_.size() == gm_.numberOfVariables()) {
213  movemaker_.initialize(parameter_.startPoint_.begin());
214  currentBestState_ = parameter_.startPoint_;
215  currentBestValue_ = movemaker_.value();
216  }
217  else {
218  throw RuntimeError("parameter.startPoint_.size() is neither zero nor equal to the number of variables.");
219  }
220  }
221  else {
222  movemaker_.reset();
223  std::fill(currentBestState_.begin(), currentBestState_.end(), 0);
224  }
225 }
226 
227 template<class GM, class ACC>
228 inline void
230 (
231  typename std::vector<typename Gibbs<GM, ACC>::LabelType>::const_iterator begin
232 ) {
233  try{
234  movemaker_.initialize(begin);
235 
236  for(IndexType vi=0;vi<static_cast<IndexType>(gm_.numberOfVariables());++vi ){
237  currentBestState_[vi]=movemaker_.state(vi);
238  }
239  currentBestValue_ = movemaker_.value();
240 
241  }
242  catch(...) {
243  throw RuntimeError("unsuitable starting point");
244  }
245 }
246 
247 template<class GM, class ACC>
248 inline std::string
250 {
251  return "Gibbs";
252 }
253 
254 template<class GM, class ACC>
255 inline const typename Gibbs<GM, ACC>::GraphicalModelType&
257 {
258  return gm_;
259 }
260 
261 template<class GM, class ACC>
264 {
265  EmptyVisitorType visitor;
266  return infer(visitor);
267 }
268 
269 template<class GM, class ACC>
270 template<class VISITOR>
272  VISITOR& visitor
273 ) {
274  inInference_=true;
275  visitor.begin(*this);
276  opengm::RandomUniform<size_t> randomVariable(0, gm_.numberOfVariables());
277  opengm::RandomUniform<ProbabilityType> randomProb(0, 1);
278 
279  if(parameter_.useTemp_==false){
280  for(size_t iteration = 0; iteration < parameter_.maxNumberOfSamplingSteps_ + parameter_.numberOfBurnInSteps_; ++iteration) {
281  // select variable
282  size_t variableIndex = 0;
283  if(this->parameter_.variableProposal_ == Parameter::RANDOM) {
284  variableIndex = randomVariable();
285  }
286  else if(this->parameter_.variableProposal_ == Parameter::CYCLIC) {
287  variableIndex < gm_.numberOfVariables() - 1 ? ++variableIndex : variableIndex = 0;
288  }
289 
290  // draw label
291  opengm::RandomUniform<size_t> randomLabel(0, gm_.numberOfLabels(variableIndex));
292  const size_t label = randomLabel();
293 
294  // move
295  const bool burningIn = (iteration < parameter_.numberOfBurnInSteps_);
296  if(label != movemaker_.state(variableIndex)) {
297  const ValueType oldValue = movemaker_.value();
298  const ValueType newValue = movemaker_.valueAfterMove(&variableIndex, &variableIndex + 1, &label);
299  if(AccumulationType::bop(newValue, oldValue)) {
300  movemaker_.move(&variableIndex, &variableIndex + 1, &label);
301  if(AccumulationType::bop(newValue, currentBestValue_) && newValue != currentBestValue_) {
302  currentBestValue_ = newValue;
303  for(size_t k = 0; k < currentBestState_.size(); ++k) {
304  currentBestState_[k] = movemaker_.state(k);
305  }
306  }
307  visitor(*this);
308  //visitor(*this, newValue, currentBestValue_, iteration, true, burningIn);
309  }
310  else {
311  const ProbabilityType pFlip =
312  detail_gibbs::ValuePairToProbability<
313  OperatorType, AccumulationType, ProbabilityType
314  >::convert(newValue, oldValue);
315  if(randomProb() < pFlip) {
316  movemaker_.move(&variableIndex, &variableIndex + 1, &label);
317  visitor(*this);
318  //visitor(*this, newValue, currentBestValue_, iteration, true, burningIn);
319  }
320  else {
321  visitor(*this);
322  // visitor(*this, newValue, currentBestValue_, iteration, false, burningIn);
323  }
324  }
325  ++iteration;
326  }
327  }
328  }
329  else {
330  for(size_t iteration = 0; iteration < parameter_.maxNumberOfSamplingSteps_ + parameter_.numberOfBurnInSteps_; ++iteration) {
331  // select variable
332  size_t variableIndex = 0;
333  if(this->parameter_.variableProposal_ == Parameter::RANDOM) {
334  variableIndex = randomVariable();
335  }
336  else if(this->parameter_.variableProposal_ == Parameter::CYCLIC) {
337  variableIndex < gm_.numberOfVariables() - 1 ? ++variableIndex : variableIndex = 0;
338  }
339 
340  // draw label
341  opengm::RandomUniform<size_t> randomLabel(0, gm_.numberOfLabels(variableIndex));
342  const size_t label = randomLabel();
343 
344  // move
345  const bool burningIn = (iteration < parameter_.numberOfBurnInSteps_);
346  if(label != movemaker_.state(variableIndex)) {
347  const ValueType oldValue = movemaker_.value();
348  const ValueType newValue = movemaker_.valueAfterMove(&variableIndex, &variableIndex + 1, &label);
349  if(AccumulationType::bop(newValue, oldValue)) {
350  movemaker_.move(&variableIndex, &variableIndex + 1, &label);
351  if(AccumulationType::bop(newValue, currentBestValue_) && newValue != currentBestValue_) {
352  currentBestValue_ = newValue;
353  for(size_t k = 0; k < currentBestState_.size(); ++k) {
354  currentBestState_[k] = movemaker_.state(k);
355  }
356  }
357  visitor(*this);
358  //visitor(*this, newValue, currentBestValue_, iteration, true, burningIn);
359  }
360  else {
361  const ProbabilityType pFlip =
362  detail_gibbs::ValuePairToProbability<
363  OperatorType, AccumulationType, ProbabilityType
364  >::convert(newValue, oldValue);
365  if(randomProb() < pFlip*this->getTemperature(iteration)){
366  //std::cout<<"temp="<<this->getTemperature(iteration)<<"\n";
367  movemaker_.move(&variableIndex, &variableIndex + 1, &label);
368  visitor(*this);
369  //visitor(*this, newValue, currentBestValue_, iteration, true, burningIn);
370  }
371  else {
372  //std::cout<<"temp="<<this->getTemperature(iteration)<<"\n";
373  visitor(*this);
374  //visitor(*this, newValue, currentBestValue_, iteration, false, burningIn);
375  }
376  }
377  ++iteration;
378  }
379  }
380  }
381  //visitor.end(*this, currentBestValue_, currentBestValue_);
382  visitor.end(*this);
383  inInference_=false;
384  return NORMAL;
385 }
386 
387 template<class GM, class ACC>
390 (
391  std::vector<LabelType>& x,
392  const size_t N
393 ) const {
394  if(N == 1) {
395  x.resize(gm_.numberOfVariables());
396  for(size_t j = 0; j < x.size(); ++j) {
397  if(!inInference_)
398  x[j] = currentBestState_[j];
399  else{
400  x[j] = movemaker_.state(j);
401  }
402  }
403  return NORMAL;
404  }
405  else {
406  return UNKNOWN;
407  }
408 }
409 
410 template<class GM, class ACC>
411 inline typename Gibbs<GM, ACC>::LabelType
413 (
414  const size_t j
415 ) const
416 {
417  OPENGM_ASSERT(j < gm_.numberOfVariables());
418  return movemaker_.state(j);
419 }
420 
421 template<class GM, class ACC>
422 inline typename Gibbs<GM, ACC>::ValueType
424 {
425  return movemaker_.value();
426 }
427 
428 template<class GM, class ACC>
429 inline typename Gibbs<GM, ACC>::LabelType
431 (
432  const size_t j
433 ) const
434 {
435  OPENGM_ASSERT(j < gm_.numberOfVariables());
436  return currentBestState_[j];
437 }
438 
439 template<class GM, class ACC>
440 inline typename Gibbs<GM, ACC>::ValueType
442 {
443  return currentBestValue_;
444 }
445 
446 template<class GIBBS>
447 inline
449 : gm_(NULL),
450  numberOfSamples_(0),
451  numberOfAcceptedSamples_(0),
452  numberOfRejectedSamples_(0),
453  marginals_(),
454  stateCache_()
455 {}
456 
457 template<class GIBBS>
458 inline
461 )
462 : gm_(&gm),
463  numberOfSamples_(0),
464  numberOfAcceptedSamples_(0),
465  numberOfRejectedSamples_(0),
466  marginals_(),
467  stateCache_()
468 {}
469 
470 template<class GIBBS>
471 inline void
474 )
475 {
476  gm_ = &gm;
477 }
478 
479 template<class GIBBS>
480 inline void
482  const typename GibbsMarginalVisitor<GIBBS>::GibbsType& gibbs,
483  const typename GibbsMarginalVisitor<GIBBS>::ValueType currentValue,
484  const typename GibbsMarginalVisitor<GIBBS>::ValueType bestValue,
485  const size_t iteration,
486  const bool accepted,
487  const bool burningIn
488 ) {
489  if(!burningIn) {
490  ++numberOfSamples_;
491  if(accepted) {
492  ++numberOfAcceptedSamples_;
493  }
494  else {
495  ++numberOfRejectedSamples_;
496  }
497  for(size_t j = 0; j < marginals_.size(); ++j) {
498  for(size_t k = 0; k < marginals_[j].numberOfVariables(); ++k) {
499  stateCache_[k] = gibbs.markovState(marginals_[j].variableIndex(k));
500  }
501  ++marginals_[j](stateCache_.begin());
502  }
503  }
504 }
505 
506 template<class GIBBS>
507 template<class VariableIndexIterator>
508 inline size_t
510  VariableIndexIterator begin,
511  VariableIndexIterator end
512 ) {
513  marginals_.push_back(IndependentFactorType(*gm_, begin, end));
514  if(marginals_.back().numberOfVariables() > stateCache_.size()) {
515  stateCache_.resize(marginals_.back().numberOfVariables());
516  }
517  return marginals_.size() - 1;
518 }
519 
520 template<class GIBBS>
521 inline size_t
523  const size_t variableIndex
524 ) {
525  size_t variableIndices[] = {variableIndex};
526  return addMarginal(variableIndices, variableIndices + 1);
527 }
528 
529 template<class GIBBS>
530 inline size_t
532  return numberOfSamples_;
533 }
534 
535 template<class GIBBS>
536 inline size_t
538  return numberOfAcceptedSamples_;
539 }
540 
541 template<class GIBBS>
542 inline size_t
544  return numberOfRejectedSamples_;
545 }
546 
547 template<class GIBBS>
548 inline size_t
550  return marginals_.size();
551 }
552 
553 template<class GIBBS>
556  const size_t setIndex
557 ) const {
558  return marginals_[setIndex];
559 }
560 
561 } // namespace opengm
562 
563 #endif // #ifndef OPENGM_GIBBS_HXX
VariableProposal variableProposal_
Definition: gibbs.hxx:138
size_t numberOfAcceptedSamples() const
Definition: gibbs.hxx:537
The OpenGM namespace.
Definition: config.hxx:43
size_t numberOfMarginals() const
Definition: gibbs.hxx:549
double ProbabilityType
Definition: gibbs.hxx:105
void operator()(const GibbsType &, const ValueType, const ValueType, const size_t, const bool, const bool)
Definition: gibbs.hxx:481
visitors::EmptyVisitor< Gibbs< GM, ACC > > EmptyVisitorType
Definition: gibbs.hxx:103
GraphicalModelType::IndependentFactorType IndependentFactorType
Definition: gibbs.hxx:61
size_t addMarginal(VariableIndexIterator, VariableIndexIterator)
Definition: gibbs.hxx:509
void reset()
Definition: gibbs.hxx:210
ACC AccumulationType
Definition: gibbs.hxx:98
GibbsType::ValueType ValueType
Definition: gibbs.hxx:59
std::string name() const
Definition: gibbs.hxx:249
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Definition: gibbs.hxx:390
GibbsType::GraphicalModelType GraphicalModelType
Definition: gibbs.hxx:60
InferenceTermination infer()
Definition: gibbs.hxx:263
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
GraphicalModelType::OperatorType OperatorType
Definition: inference.hxx:42
size_t maxNumberOfSamplingSteps_
Definition: gibbs.hxx:136
LabelType markovState(const size_t) const
Definition: gibbs.hxx:413
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:40
Movemaker< GraphicalModelType > MovemakerType
Definition: gibbs.hxx:101
const GraphicalModelType & graphicalModel() const
Definition: gibbs.hxx:256
ValueType markovValue() const
Definition: gibbs.hxx:423
size_t numberOfSamples() const
Definition: gibbs.hxx:531
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:41
visitors::VerboseVisitor< Gibbs< GM, ACC > > VerboseVisitorType
Definition: gibbs.hxx:102
Inference algorithm interface.
Definition: inference.hxx:34
std::vector< size_t > startPoint_
Definition: gibbs.hxx:139
GM GraphicalModelType
Definition: gibbs.hxx:99
ValueType currentBestValue() const
Definition: gibbs.hxx:441
LabelType currentBestState(const size_t) const
Definition: gibbs.hxx:431
size_t numberOfRejectedSamples() const
Definition: gibbs.hxx:543
Gibbs(const GraphicalModelType &, const Parameter &param=Parameter())
Definition: gibbs.hxx:184
visitors::TimingVisitor< Gibbs< GM, ACC > > TimingVisitorType
Definition: gibbs.hxx:104
const IndependentFactorType & marginal(const size_t) const
Definition: gibbs.hxx:555
void end(const GibbsType &, const ValueType, const ValueType) const
Definition: gibbs.hxx:76
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:39
Gibbs sampling.
Definition: gibbs.hxx:95
Parameter(const size_t maxNumberOfSamplingSteps=1e5, const size_t numberOfBurnInSteps=1e5, const bool useTemp=false, const ValueType tmin=0.0001, const ValueType tmax=1, const IndexType periods=10, const VariableProposal variableProposal=RANDOM, const std::vector< size_t > &startPoint=std::vector< size_t >())
Definition: gibbs.hxx:111
void begin(const GibbsType &, const ValueType, const ValueType) const
Definition: gibbs.hxx:75
OpenGM runtime error.
Definition: opengm.hxx:100
void assign(const GraphicalModelType &)
Definition: gibbs.hxx:472
OPENGM_GM_TYPE_TYPEDEFS
Definition: gibbs.hxx:100
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
Definition: gibbs.hxx:230
InferenceTermination
Definition: inference.hxx:24
Visitor for the Gibbs sampler to compute arbitrary marginal probabilities.
Definition: gibbs.hxx:56