OpenGM  2.3.x
Discrete Graphical Model Library
alphaexpansion.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_ALPHAEXPANSION_HXX
3 #define OPENGM_ALPHAEXPANSION_HXX
4 
7 
8 namespace opengm {
9 
12 template<class GM, class INF>
14 : public Inference<GM, typename INF::AccumulationType>
15 {
16 public:
17  typedef GM GraphicalModelType;
18  typedef INF InferenceType;
19  typedef typename INF::AccumulationType AccumulationType;
24 
25  template<class _GM>
26  struct RebindGm{
27  typedef typename INF:: template RebindGm<_GM>::type RebindedInf;
29  };
30 
31  template<class _GM,class _ACC>
33  typedef typename INF:: template RebindGmAndAcc<_GM,_ACC>::type RebindedInf;
35  };
36 
37  struct Parameter {
38  typedef typename InferenceType::Parameter InferenceParameter;
39  enum LabelingIntitialType {DEFAULT_LABEL, RANDOM_LABEL, LOCALOPT_LABEL, EXPLICIT_LABEL};
40  enum OrderType {DEFAULT_ORDER, RANDOM_ORDER, EXPLICIT_ORDER};
41 
42  Parameter
43  (
44  const size_t maxNumberOfSteps = 1000,
45  const InferenceParameter& para = InferenceParameter()
46  )
47  : parameter_(para),
48  maxNumberOfSteps_(maxNumberOfSteps),
49  labelInitialType_(DEFAULT_LABEL),
50  orderType_(DEFAULT_ORDER),
51  randSeedOrder_(0),
52  randSeedLabel_(0),
53  labelOrder_(),
54  label_()
55  {}
56 
57  template<class P>
58  Parameter
59  (
60  const P & p
61  )
62  : parameter_(p.parameter_),
63  maxNumberOfSteps_(p.maxNumberOfSteps_),
64  labelInitialType_(p.labelInitialType_),
65  orderType_(p.orderType_),
66  randSeedOrder_(p.randSeedOrder_),
67  randSeedLabel_(p.randSeedLabel_),
68  labelOrder_(p.labelOrder_),
69  label_(p.labelOrder_)
70  {}
71 
72  InferenceParameter parameter_;
76  unsigned int randSeedOrder_;
77  unsigned int randSeedLabel_;
78  std::vector<LabelType> labelOrder_;
79  std::vector<LabelType> label_;
80  };
81 
82  AlphaExpansion(const GraphicalModelType&, Parameter para = Parameter());
83 
84  std::string name() const;
85  const GraphicalModelType& graphicalModel() const;
86  template<class StateIterator>
87  void setState(StateIterator, StateIterator);
89  void reset();
90  template<class Visitor>
91  InferenceTermination infer(Visitor& visitor);
92  void setStartingPoint(typename std::vector<LabelType>::const_iterator);
93  InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
94 
95 private:
96  const GraphicalModelType& gm_;
97  Parameter parameter_;
98  std::vector<LabelType> label_;
99  std::vector<LabelType> labelList_;
100  size_t maxState_;
101  size_t alpha_;
102  size_t counter_;
103  void incrementAlpha();
104  void setLabelOrder(std::vector<LabelType>& l);
105  void setLabelOrderRandom(unsigned int);
106  void setInitialLabel(std::vector<LabelType>& l);
107  void setInitialLabelLocalOptimal();
108  void setInitialLabelRandom(unsigned int);
109  void addUnary(INF&, const size_t var, const ValueType v0, const ValueType v1);
110  void addPairwise(INF&, const size_t var1, const size_t var2, const ValueType v0, const ValueType v1, const ValueType v2, const ValueType v3);
111 };
112 
113 template<class GM, class INF>
114 inline std::string
116 {
117  return "Alpha-Expansion";
118 }
119 
120 template<class GM, class INF>
121 inline const typename AlphaExpansion<GM, INF>::GraphicalModelType&
123 {
124  return gm_;
125 }
126 
127 template<class GM, class INF>
128 template<class StateIterator>
129 inline void
131 (
132  StateIterator begin,
133  StateIterator end
134 )
135 {
136  label_.assign(begin, end);
137 }
138 
139 template<class GM, class INF>
140 inline void
142 (
143  typename std::vector<typename AlphaExpansion<GM,INF>::LabelType>::const_iterator begin
144 ) {
145  try{
146  label_.assign(begin, begin+gm_.numberOfVariables());
147  }
148  catch(...) {
149  throw RuntimeError("unsuitable starting point");
150  }
151 }
152 
153 template<class GM, class INF>
154 inline
156 (
157  const GraphicalModelType& gm,
158  Parameter para
159 )
160 : gm_(gm),
161  parameter_(para),
162  maxState_(0)
163 {
164  for(size_t j=0; j<gm_.numberOfFactors(); ++j) {
165  if(gm_[j].numberOfVariables() > 2) {
166  throw RuntimeError("This implementation of Alpha-Expansion supports only factors of order <= 2.");
167  }
168  }
169  for(size_t i=0; i<gm_.numberOfVariables(); ++i) {
170  size_t numSt = gm_.numberOfLabels(i);
171  if(numSt > maxState_) {
172  maxState_ = numSt;
173  }
174  }
175 
176  if(parameter_.labelInitialType_ == Parameter::RANDOM_LABEL) {
177  setInitialLabelRandom(parameter_.randSeedLabel_);
178  }
179  else if(parameter_.labelInitialType_ == Parameter::LOCALOPT_LABEL) {
180  setInitialLabelLocalOptimal();
181  }
182  else if(parameter_.labelInitialType_ == Parameter::EXPLICIT_LABEL) {
183  setInitialLabel(parameter_.label_);
184  }
185  else{
186  label_.resize(gm_.numberOfVariables(), 0);
187  }
188 
189 
190  if(parameter_.orderType_ == Parameter::RANDOM_ORDER) {
191  setLabelOrderRandom(parameter_.randSeedOrder_);
192  }
193  else if(parameter_.orderType_ == Parameter::EXPLICIT_ORDER) {
194  setLabelOrder(parameter_.labelOrder_);
195  }
196  else{
197  labelList_.resize(maxState_);
198  for(size_t i=0; i<maxState_; ++i)
199  labelList_[i] = i;
200  }
201 
202  counter_ = 0;
203  alpha_ = labelList_[counter_];
204 }
205 
206 // reset assumes that the structure of
207 // the graphical model has not changed
208 template<class GM, class INF>
209 inline void
211  if(parameter_.labelInitialType_ == Parameter::RANDOM_LABEL) {
212  setInitialLabelRandom(parameter_.randSeedLabel_);
213  }
214  else if(parameter_.labelInitialType_ == Parameter::LOCALOPT_LABEL) {
215  setInitialLabelLocalOptimal();
216  }
217  else if(parameter_.labelInitialType_ == Parameter::EXPLICIT_LABEL) {
218  setInitialLabel(parameter_.label_);
219  }
220  else{
221  std::fill(label_.begin(),label_.end(),0);
222  }
223 
224 
225  if(parameter_.orderType_ == Parameter::RANDOM_ORDER) {
226  setLabelOrderRandom(parameter_.randSeedOrder_);
227  }
228  else if(parameter_.orderType_ == Parameter::EXPLICIT_ORDER) {
229  setLabelOrder(parameter_.labelOrder_);
230  }
231  else{
232  for(size_t i=0; i<maxState_; ++i)
233  labelList_[i] = i;
234  }
235  counter_ = 0;
236  alpha_ = labelList_[counter_];
237 }
238 
239 template<class GM, class INF>
240 inline void
242 (
243  INF& inf,
244  const size_t var1,
245  const ValueType v0,
246  const ValueType v1
247 ) {
248  const size_t shape[] = {2};
249  size_t vars[] = {var1};
250  opengm::IndependentFactor<ValueType,IndexType,LabelType> fac(vars, vars+1, shape, shape+1);
251  fac(0) = v0;
252  fac(1) = v1;
253  inf.addFactor(fac);
254 }
255 
256 template<class GM, class INF>
257 inline void
259 (
260  INF& inf,
261  const size_t var1,
262  const size_t var2,
263  const ValueType v0,
264  const ValueType v1,
265  const ValueType v2,
266  const ValueType v3
267 ) {
268  const LabelType shape[] = {2, 2};
269  const IndexType vars[] = {var1, var2};
270  opengm::IndependentFactor<ValueType,IndexType,LabelType> fac(vars, vars+2, shape, shape+2);
271  fac(0, 0) = v0;
272  fac(0, 1) = v1;
273  fac(1, 0) = v2;
274  fac(1, 1) = v3;
275  inf.addFactor(fac);
276 }
277 
278 template<class GM, class INF>
281 {
282  EmptyVisitorType visitor;
283  return infer(visitor);
284 }
285 
286 template<class GM, class INF>
287 template<class Visitor>
290 (
291  Visitor& visitor
292 )
293 {
294  bool exitInf = false;
295  size_t it = 0;
296  size_t countUnchanged = 0;
297  size_t numberOfVariables = gm_.numberOfVariables();
298  std::vector<size_t> variable2Node(numberOfVariables);
299  ValueType energy = gm_.evaluate(label_);
300  visitor.begin(*this);
301  LabelType vecA[1];
302  LabelType vecX[1];
303  LabelType vecAA[2];
304  LabelType vecAX[2];
305  LabelType vecXA[2];
306  LabelType vecXX[2];
307  while(it++ < parameter_.maxNumberOfSteps_ && countUnchanged < maxState_ && exitInf == false) {
308  size_t numberOfAuxiliaryNodes = 0;
309  for(size_t k=0 ; k<gm_.numberOfFactors(); ++k) {
310  const FactorType& factor = gm_[k];
311  if(factor.numberOfVariables() == 2) {
312  size_t var1 = factor.variableIndex(0);
313  size_t var2 = factor.variableIndex(1);
314  if(label_[var1] != label_[var2] && label_[var1] != alpha_ && label_[var2] != alpha_ ) {
315  ++numberOfAuxiliaryNodes;
316  }
317  }
318  }
319  std::vector<size_t> numFacDim(4, 0);
320  INF inf(numberOfVariables + numberOfAuxiliaryNodes, numFacDim, parameter_.parameter_);
321  size_t varX = numberOfVariables;
322  size_t countAlphas = 0;
323  for (size_t k=0 ; k<gm_.numberOfVariables(); ++k) {
324  if (label_[k] == alpha_ ) {
325  addUnary(inf, k, 0, std::numeric_limits<ValueType>::infinity());
326  ++countAlphas;
327  }
328  }
329  if(countAlphas < gm_.numberOfVariables()) {
330  for (size_t k=0 ; k<gm_.numberOfFactors(); ++k) {
331  const FactorType& factor = gm_[k];
332  if(factor.numberOfVariables() == 1) {
333  size_t var = factor.variableIndex(0);
334  vecA[0] = alpha_;
335  vecX[0] = label_[var];
336  if (label_[var] != alpha_ ) {
337  addUnary(inf, var, factor(vecA), factor(vecX));
338  }
339  }
340  else if (factor.numberOfVariables() == 2) {
341  size_t var1 = factor.variableIndex(0);
342  size_t var2 = factor.variableIndex(1);
343  std::vector<IndexType> vars(2); vars[0]=var1;vars[1]=var2;
344  vecAA[0] = vecAA[1] = alpha_;
345  vecAX[0] = alpha_; vecAX[1] = label_[var2];
346  vecXA[0] = label_[var1]; vecXA[1] = alpha_;
347  vecXX[0] = label_[var1]; vecXX[1] = label_[var2];
348  if(label_[var1]==alpha_ && label_[var2]==alpha_) {
349  continue;
350  }
351  else if(label_[var1]==alpha_) {
352  addUnary(inf, var2, factor(vecAA), factor(vecAX));
353  }
354  else if(label_[var2]==alpha_) {
355  addUnary(inf, var1, factor(vecAA), factor(vecXA));
356  }
357  else if(label_[var1]==label_[var2]) {
358  addPairwise(inf, var1, var2, factor(vecAA), factor(vecAX), factor(vecXA), factor(vecXX));
359  }
360  else{
361  OPENGM_ASSERT(varX < numberOfVariables + numberOfAuxiliaryNodes);
362  addPairwise(inf, var1, varX, 0, factor(vecAX), 0, 0);
363  addPairwise(inf, var2, varX, 0, factor(vecXA), 0, 0);
364  addUnary(inf, varX, factor(vecAA), factor(vecXX));
365  ++varX;
366  }
367  }
368  }
369  std::vector<LabelType> state;
370  inf.infer();
371  inf.arg(state);
372  OPENGM_ASSERT(state.size() == numberOfVariables + numberOfAuxiliaryNodes);
373  for(size_t var=0; var<numberOfVariables ; ++var) {
374  if (label_[var] != alpha_ && state[var]==0) {
375  label_[var] = alpha_;
376  }
377  OPENGM_ASSERT(label_[var] < gm_.numberOfLabels(var));
378  }
379  }
380  OPENGM_ASSERT(gm_.numberOfVariables() == label_.size());
381  ValueType energy2 = gm_.evaluate(label_);
382  //visitor(*this,energy2,energy,alpha_);
383  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ){
384  exitInf=true;
385  }
386  // OPENGM_ASSERT(!AccumulationType::ibop(energy2, energy));
387  if(AccumulationType::bop(energy2, energy)) {
388  energy=energy2;
389  countUnchanged = 0;
390  }
391  else{
392  ++countUnchanged;
393  }
394  incrementAlpha();
395  OPENGM_ASSERT(alpha_ < maxState_);
396  }
397  visitor.end(*this);
398  return NORMAL;
399 }
400 
401 template<class GM, class INF>
404 (
405  std::vector<LabelType>& arg,
406  const size_t n
407 ) const
408 {
409  if(n > 1) {
410  return UNKNOWN;
411  }
412  else {
413  OPENGM_ASSERT(label_.size() == gm_.numberOfVariables());
414  arg.resize(label_.size());
415  for(size_t i=0; i<label_.size(); ++i) {
416  arg[i] = label_[i];
417  }
418  return NORMAL;
419  }
420 }
421 
422 template<class GM, class INF>
423 inline void
425 (
426  std::vector<LabelType>& l
427 ) {
428  if(l.size() == maxState_) {
429  labelList_=l;
430  }
431 }
432 
433 template<class GM, class INF>
434 inline void
436 (
437  unsigned int seed
438 ) {
439  srand(seed);
440  labelList_.resize(maxState_);
441  for (size_t i=0; i<maxState_;++i) {
442  labelList_[i]=i;
443  }
444  random_shuffle(labelList_.begin(), labelList_.end());
445 }
446 
447 template<class GM, class INF>
448 inline void
450 (
451  std::vector<LabelType>& l
452 ) {
453  label_.resize(gm_.numberOfVariables());
454  if(l.size() == label_.size()) {
455  for(size_t i=0; i<l.size();++i) {
456  if(l[i]>=gm_.numberOfLabels(i)) return;
457  }
458  for(size_t i=0; i<l.size();++i) {
459  label_[i] = l[i];
460  }
461  }
462 }
463 
464 template<class GM, class INF>
465 inline void
467  label_.resize(gm_.numberOfVariables(), 0);
468  std::vector<size_t> accVec;
469  for(size_t i=0; i<gm_.numberOfFactors();++i) {
470  if(gm_[i].numberOfVariables()==1) {
471  std::vector<size_t> state(1, 0);
472  ValueType value = gm_[i](state.begin());
473  for(state[0]=1; state[0]<gm_.numberOfLabels(i); ++state[0]) {
474  if(AccumulationType::bop(gm_[i](state.begin()), value)) {
475  value = gm_[i](state.begin());
476  label_[i] = state[0];
477  }
478  }
479  }
480  }
481 }
482 
483 template<class GM, class INF>
484 inline void
486 (
487  unsigned int seed
488 ) {
489  srand(seed);
490  label_.resize(gm_.numberOfVariables());
491  for(size_t i=0; i<gm_.numberOfVariables();++i) {
492  label_[i] = rand() % gm_.numberOfLabels(i);
493  }
494 }
495 
496 template<class GM, class INF>
497 inline void
499  counter_ = (counter_+1) % maxState_;
500  alpha_ = labelList_[counter_];
501 }
502 
503 } // namespace opengm
504 
505 #endif // #ifndef OPENGM_ALPHAEXPANSION_HXX
The OpenGM namespace.
Definition: config.hxx:43
Factor (with corresponding function and variable indices), independent of a GraphicalModel.
visitors::VerboseVisitor< AlphaExpansion< GM, INF > > VerboseVisitorType
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
virtual ValueType value() const
return the solution (value)
Definition: inference.hxx:401
InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
INF::AccumulationType AccumulationType
std::vector< LabelType > labelOrder_
InferenceType::Parameter InferenceParameter
visitors::TimingVisitor< AlphaExpansion< GM, INF > > TimingVisitorType
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
AlphaExpansion< _GM, RebindedInf > type
INF::template RebindGmAndAcc< _GM, _ACC >::type RebindedInf
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:49
GraphicalModelType::FactorType FactorType
Definition: inference.hxx:52
AlphaExpansion(const GraphicalModelType &, Parameter para=Parameter())
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:50
Inference algorithm interface.
Definition: inference.hxx:43
Alpha-Expansion Algorithm.
std::string name() const
visitors::EmptyVisitor< AlphaExpansion< GM, INF > > EmptyVisitorType
InferenceTermination infer()
const GraphicalModelType & graphicalModel() const
void setState(StateIterator, StateIterator)
std::vector< LabelType > label_
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:48
LabelingIntitialType labelInitialType_
INF::template RebindGm< _GM >::type RebindedInf
OpenGM runtime error.
Definition: opengm.hxx:100
AlphaExpansion< _GM, RebindedInf > type
InferenceTermination
Definition: inference.hxx:24