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