OpenGM  2.3.x
Discrete Graphical Model Library
reducedinference.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_REDUCEDINFERENCE_HXX
3 #define OPENGM_REDUCEDINFERENCE_HXX
4 
5 #include <vector>
6 #include <set>
7 #include <map>
8 #include <string>
9 #include <iostream>
10 
11 #include "opengm/opengm.hxx"
16 
19 #include "opengm/inference/fix-fusion/fusion-move.hpp"
21 
25 
30 
31 namespace opengm {
32  template<class GM>
34  {
35  public:
36  typedef typename GM::ValueType ValueType;
37  typedef typename GM::LabelType LabelType;
38  typedef typename GM::IndexType IndexType;
39  typedef typename GM::OperatorType OperatorType;
41 
42  typedef typename meta::TypeListGenerator< ViewFixVariablesFunction<GM>,
48  };
49 
73  template<class GM, class ACC, class INF>
74  class ReducedInference : public Inference<GM, ACC>
75  {
76  public:
77  typedef ACC AccumulationType;
78  typedef GM GmType;
79  typedef GM GraphicalModelType;
80  typedef INF InfType;
85 
86 
87  template<class _GM>
88  struct RebindGm{
90  typedef typename INF:: template RebindGm<RebindedInfGmType>::type RebindedInf;
92  };
93 
94  template<class _GM,class _ACC>
99  };
100 
101 
102  class Parameter
103  {
104  public:
105  typename INF::Parameter subParameter_;
107  bool Tentacle_;
109 
110 
111  template<class P>
112  Parameter(const P & p)
113  : subParameter_(p.subParameter_),
114  Persistency_(p.Persistency_),
115  Tentacle_(p.Tentacle_),
116  ConnectedComponents_(p.ConnectedComponents_)
117  {
118  }
119 
121  const bool Persistency=false,
122  const bool Tentacle=false,
123  const bool ConnectedComponents=false,
124  typename INF::Parameter subParameter = typename INF::Parameter()
125  )
126  :
127  Persistency_(Persistency),
128  Tentacle_(Tentacle),
129  ConnectedComponents_(ConnectedComponents),
130  subParameter_(subParameter)
131  {
132 
133  };
134  };
135 
136  ReducedInference(const GmType&, const Parameter & = Parameter() );
137  std::string name() const;
138  const GmType& graphicalModel() const;
140  typename GM::ValueType bound() const;
141  template<class VisitorType>
142  InferenceTermination infer(VisitorType&);
143  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const ;
144  typename GM::ValueType value() const;
145 
146  private:
147  //typedef typename ReducedInferenceHelper<GM>::InfGmType GM2;
148  //typedef external::QPBO<GM> QPBO;
149 
151  //typedef disjoint_set<IndexType> Set;
152  //typedef opengm::DynamicProgramming<GM2,AccumulationType> dynP;
153  //typedef modelTrees<GM2> MT;
154 
155 
156  const GmType& gm_;
157 
158  Parameter param_;
159  ValueType bound_;
160  ValueType value_;
161 
162  std::vector<LabelType> state_;
163 
164  void getPartialOptimalityByQPBO(std::vector<LabelType>&, std::vector<bool>&);
165  void getPartialOptimalityByFixsHOQPBO(std::vector<LabelType>&, std::vector<bool>&);
166  void getPartialOptimalityByKovtunsMethod(std::vector<LabelType>&, std::vector<bool>&);
167  void getPartialOptimalityByMQPBO(std::vector<LabelType>&, std::vector<bool>&);
168  void getPartialOptimalityByAutoSelection(std::vector<LabelType>&, std::vector<bool>&);
169  void setPartialOptimality(std::vector<LabelType>&, std::vector<bool>&);
170 
171  void subinf(const typename ReducedInferenceHelper<GM>::InfGmType&,const bool,std::vector<LabelType>&, typename GM::ValueType&, typename GM::ValueType&);
172 
173  //std::vector<bool> variableOpt_;
174  //std::vector<bool> factorOpt_;
175  //ValueType const_;
176  //std::vector<IndexType> model2gm_;
177 
178  //void updateFactorOpt(std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >&);
179  //void getConnectComp(std::vector< std::vector<IndexType> >&, std::vector<GM2>&, std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >&, bool );
180  //void getTentacle(std::vector< std::vector<IndexType> >&, std::vector<IndexType>&, std::vector< std::vector<ValueType> >&, std::vector< std::vector<std::vector<LabelType> > >&, std::vector< std::vector<IndexType> >&, std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >& );
181  //void getRoots(std::vector< std::vector<IndexType> >&, std::vector<IndexType>& );
182  //void getTentacleCC(std::vector< std::vector<IndexType> >&, std::vector<IndexType>&, std::vector< std::vector<ValueType> >&, std::vector< std::vector<std::vector<LabelType> > >&, std::vector< std::vector<IndexType> >&, std::vector<GM2>&, GM2&);
183 
184  };
186 
187 
188  template<class GM, class ACC, class INF>
190  (
191  const GmType& gm,
192  const Parameter& parameter
193  )
194  : gm_( gm ),
195  param_(parameter)
196  {
197 
198  ACC::ineutral(bound_);
199  OperatorType::neutral(value_);
200  state_.resize(gm.numberOfVariables(),0);
201 
202  //variableOpt_.resize(gm_.numberOfVariables(),false);
203  //factorOpt_.resize(gm.numberOfFactors(),false);
204  //const_ = 0;
205  }
206 
207  template<class GM, class ACC, class INF>
208  void ReducedInference<GM,ACC,INF>::getPartialOptimalityByAutoSelection(std::vector<LabelType>& arg, std::vector<bool>& opt)
209  {
210  bool binary = true;
211  bool potts = true;
212  IndexType order = 0;
213 
214  for(IndexType j = 0; j < gm_.numberOfVariables(); ++j) {
215  if(gm_.numberOfLabels(j) != 2) {
216  binary = false;
217  }
218  }
219 
220  for(IndexType j = 0; j < gm_.numberOfFactors(); ++j) {
221  if(potts && gm_[j].numberOfVariables() >1 && (gm_[j].numberOfVariables() > 3 || !gm_[j].isPotts() ) )
222  potts=false;
223  if(gm_[j].numberOfVariables() > order) {
224  order = gm_[j].numberOfVariables();
225  }
226  }
227 
228  if(binary){
229  if(order<=2)
230  getPartialOptimalityByQPBO(arg,opt);
231  else
232  getPartialOptimalityByFixsHOQPBO(arg,opt);
233  }
234  else{
235  if(potts)
236  getPartialOptimalityByKovtunsMethod(arg,opt);
237  else if(order<=2)
238  getPartialOptimalityByMQPBO(arg,opt);
239  else
240  throw RuntimeError("This implementation of Reduced Inference supports no higher order multi-label problems.");
241  }
242  }
243 
244  template<class GM, class ACC, class INF>
245  void ReducedInference<GM,ACC,INF>::getPartialOptimalityByQPBO(std::vector<LabelType>& arg, std::vector<bool>& opt)
246  {
247  typedef external::QPBO<GM> QPBO;
248  typename QPBO::Parameter paraQPBO;
249  paraQPBO.strongPersistency_=false;
250  QPBO qpbo(gm_,paraQPBO);
251  qpbo.infer();
252  qpbo.arg(arg);
253  qpbo.partialOptimality(opt);
254  bound_=qpbo.bound();
255  }
256  template<class GM, class ACC, class INF>
257  void ReducedInference<GM,ACC,INF>::getPartialOptimalityByFixsHOQPBO(std::vector<LabelType>& arg, std::vector<bool>& opt)
258  {
259  const size_t maxOrder = 10;
260  ValueType constV = 0;
261  HigherOrderEnergy<ValueType, maxOrder> hoe;
262  hoe.AddVars(gm_.numberOfVariables());
263  for(IndexType f=0; f<gm_.numberOfFactors(); ++f){
264  IndexType size = gm_[f].numberOfVariables();
265  const LabelType l0 = 0;
266  const LabelType l1 = 1;
267  if (size == 0) {
268  constV += gm_[f](&l0);
269  continue;
270  } else if (size == 1) {
271  IndexType var = gm_[f].variableIndex(0);
272  const ValueType e0 = gm_[f](&l0);
273  const ValueType e1 = gm_[f](&l1);
274  hoe.AddUnaryTerm(var, e1 - e0);
275  } else {
276  unsigned int numAssignments = 1 << size;
277  AutoDeleteArray<ValueType> coeffs_array(new ValueType[numAssignments]);
278  ValueType * coeffs = coeffs_array.get();
279  for (unsigned int subset = 1; subset < numAssignments; ++subset) {
280  coeffs[subset] = 0;
281  }
282  // For each boolean assignment, get the clique energy at the
283  // corresponding labeling
284  AutoDeleteArray<LabelType> cliqueLabels_array(new LabelType[size]);
285  LabelType * cliqueLabels = cliqueLabels_array.get();
286  for(unsigned int assignment = 0; assignment < numAssignments; ++assignment){
287  for (unsigned int i = 0; i < size; ++i) {
288  if (assignment & (1 << i)) {
289  cliqueLabels[i] = l1;
290  } else {
291  cliqueLabels[i] = l0;
292  }
293  }
294  ValueType energy = gm_[f](cliqueLabels);
295  for (unsigned int subset = 1; subset < numAssignments; ++subset){
296  if (assignment & ~subset) {
297  continue;
298  } else {
299  int parity = 0;
300  for (unsigned int b = 0; b < size; ++b) {
301  parity ^= (((assignment ^ subset) & (1 << b)) != 0);
302  }
303  coeffs[subset] += parity ? -energy : energy;
304  }
305  }
306  }
307  typename HigherOrderEnergy<ValueType, maxOrder> ::VarId vars[maxOrder];
308  for (unsigned int subset = 1; subset < numAssignments; ++subset) {
309  int degree = 0;
310  for (unsigned int b = 0; b < size; ++b) {
311  if (subset & (1 << b)) {
312  vars[degree++] = gm_[f].variableIndex(b);
313  }
314  }
315  std::sort(vars, vars+degree);
316  hoe.AddTerm(coeffs[subset], degree, vars);
317  }
318  }
319  }
320  kolmogorov::qpbo::QPBO<ValueType> qr(gm_.numberOfVariables(), 0);
321  hoe.ToQuadratic(qr);
322  qr.Solve();
323 
324  for (IndexType i = 0; i < gm_.numberOfVariables(); ++i) {
325  int label = qr.GetLabel(i);
326  if(label == 0 ){
327  arg[i] = 0;
328  opt[i] = true;
329  }
330  else if(label == 1){
331  arg[i] = 1;
332  opt[i] = true;
333  }
334  else{
335  arg[i] = 0;
336  opt[i] = false;
337  }
338  }
339  bound_ = constV + 0.5 * qr.ComputeTwiceLowerBound();
340  }
341 
342  template<class GM, class ACC, class INF>
343  void ReducedInference<GM,ACC,INF>::getPartialOptimalityByMQPBO(std::vector<LabelType>& arg, std::vector<bool>& opt)
344  {
345  typedef opengm::MQPBO<GM,ACC> MQPBOType;
346  typename MQPBOType::Parameter mqpboPara;
347  mqpboPara.useKovtunsMethod_ = false;
348  mqpboPara.strongPersistency_ = true;
349  mqpboPara.rounds_ = 10;
350  mqpboPara.permutationType_ = MQPBOType::RANDOM;
351  MQPBOType mqpbo(gm_,mqpboPara);
352  mqpbo.infer();
353  arg.resize(gm_.numberOfVariables(),0);
354  opt.resize(gm_.numberOfVariables(),false);
355  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
356  opt[var] = mqpbo.partialOptimality(var,arg[var]);
357  }
358  }
359 
360  template<class GM, class ACC, class INF>
361  void ReducedInference<GM,ACC,INF>::getPartialOptimalityByKovtunsMethod(std::vector<LabelType>& arg, std::vector<bool>& opt)
362  {
363  typedef opengm::MQPBO<GM,ACC> MQPBOType;
364  typename MQPBOType::Parameter mqpboPara;
365  mqpboPara.strongPersistency_ = true;
366  MQPBOType mqpbo(gm_,mqpboPara);
367  mqpbo.infer();
368  arg.resize(gm_.numberOfVariables(),0);
369  opt.resize(gm_.numberOfVariables(),false);
370  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
371  opt[var] = mqpbo.partialOptimality(var,arg[var]);
372  }
373  }
374 
375 
376  template<class GM, class ACC, class INF>
377  inline std::string
379  {
380  return "ReducedInference";
381  }
382 
383  template<class GM, class ACC, class INF>
384  inline const typename ReducedInference<GM,ACC,INF>::GmType&
386  {
387  return gm_;
388  }
389 
390  template<class GM, class ACC, class INF>
391  inline InferenceTermination
393  {
394  EmptyVisitorType v;
395  return infer(v);
396  }
397 
398 
399  template<class GM, class ACC, class INF>
400  template<class VisitorType>
402  (
403  VisitorType& visitor
404  )
405  {
406  visitor.begin(*this);
407 
409 
410  // Find persistency
411  size_t numFixedVars = 0;
412  if(param_.Persistency_ == true){
413  std::vector<bool> opt(gm_.numberOfVariables(),false);
414  std::vector<LabelType> arg(gm_.numberOfVariables(),0);
415  getPartialOptimalityByAutoSelection(arg,opt);
416  for(IndexType i=0; i<gm_.numberOfVariables(); ++i){
417  if(opt[i]){
418  ++numFixedVars;
419  gmm.fixVariable(i, arg[i]);
420  }
421  }
422  }
423 
424  //std::cout << numFixedVars <<" of " <<gm_.numberOfVariables() << " are fixed."<<std::endl;
425 
426  if(numFixedVars == gm_.numberOfVariables()){
427  gmm.lock();
428  std::vector<LabelType> arg(0);
429  gmm.modifiedState2OriginalState(arg, state_);
430  bound_ = value();
431  //visitor(*this);
432  visitor.end(*this);
433  return NORMAL;
434  }
435 
436  if(param_.Tentacle_ == true){
437  //std::cout << " Search for tentacles." <<std::endl;
438  gmm.template lockAndTentacelElimination<ACC>();
439  }
440  else{
441  gmm.lock();
442  }
443 
444  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ) {
445  visitor.end(*this);
446  return NORMAL;
447  }
448 
449 
450  //ValueType sv, v;
451  ValueType sb, b, v;
452  OperatorType::neutral(sb);
453  //OperatorType::neutral(sv);
454 
455  // CONNTECTED COMPONENTS INFERENCE
456  if(param_.ConnectedComponents_ == true){
458  std::vector<std::vector<LabelType> > args(gmm.numberOfSubmodels(),std::vector<LabelType>() );
459  for(size_t i=0; i<gmm.numberOfSubmodels(); ++i){
460  args[i].resize(gmm.getModifiedSubModel(i).numberOfVariables());
461  }
462  for(size_t i=0; i<gmm.numberOfSubmodels(); ++i){
464  subinf(agm, param_.Tentacle_, args[i],v,b);
465  //OperatorType::op(v,sv);
466  OperatorType::op(b,sb);
467  //gmm.modifiedSubStates2OriginalState(args, state_);
468  //visitor(*this,value(),bound(),"numberOfComp",i);
469  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ) {
470  visitor.end(*this);
471  return NORMAL;
472  }
473  }
474  bound_= sb;
475  gmm.modifiedSubStates2OriginalState(args, state_);
476  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ) {
477  visitor.end(*this);
478  return NORMAL;
479  }
480  //gmm.modifiedSubStates2OriginalState(args, state_);
481 
482  }
483  else{
484  //size_t i=0;
485  std::vector<LabelType> arg;
486  gmm.buildModifiedModel();
488  subinf(agm, param_.Tentacle_, arg,v,b);
489  gmm.modifiedState2OriginalState(arg, state_);
490  //visitor(*this,value(),bound(),"numberOfComp",i);
491  //gmm.modifiedState2OriginalState(arg, state_);
492  bound_=b;
493  }
494  //value_=gm_.evaluate(state_);
495  visitor.end(*this);
496  return NORMAL;
497  }
498 
499 
500  template<class GM, class ACC, class INF>
502  (
503  const typename ReducedInferenceHelper<GM>::InfGmType& agm,
504  const bool tentacleElimination,
505  std::vector<LabelType>& arg,
506  typename GM::ValueType& value,
507  typename GM::ValueType& bound
508  )
509  {
510  //std::cout << "solve model with "<<agm.numberOfVariables()<<" and "<<agm.numberOfFactors()<<" factors."<<std::endl;
511  InfType inf(agm, param_.subParameter_);
512  inf.infer();
513  arg.resize(agm.numberOfVariables());
514  inf.arg(arg);
515  value = inf.value();
516  bound = inf.bound();
517  }
518 
519 
520  template<class GM, class ACC, class INF>
521  typename GM::ValueType ReducedInference<GM,ACC,INF>::bound() const {
522  return bound_;
523  }
524 
525  template<class GM, class ACC, class INF>
526  typename GM::ValueType ReducedInference<GM,ACC,INF>::value() const {
527  return gm_.evaluate(state_);
528  }
529 
530  template<class GM, class ACC, class INF>
531  inline InferenceTermination
533  (
534  std::vector<LabelType>& x,
535  const size_t N
536  ) const
537  {
538  if(N==1){
539  x.resize(gm_.numberOfVariables());
540  for(size_t i=0; i<x.size(); ++i){
541  x[i] = state_[i];
542  }
543  return NORMAL;
544  }
545  else {
546  return UNKNOWN;
547  }
548  }
549 } // namespace opengm
550 
551 #endif // #ifndef OPENGM_ReducedInference_HXX
552 
Constant function.
Definition: constant.hxx:20
std::string name() const
The OpenGM namespace.
Definition: config.hxx:43
Discrete space in which variables can have differently many labels.
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Parameter(const bool Persistency=false, const bool Tentacle=false, const bool ConnectedComponents=false, typename INF::Parameter subParameter=typename INF::Parameter())
void buildModifiedModel()
build modified model
ReducedInference(const GmType &, const Parameter &=Parameter())
[class reducedinference]
void infer(const typename INF::GraphicalModelType &gm, const typename INF::Parameter &param, std::vector< typename INF::LabelType > &conf)
Definition: inference.hxx:34
InferenceTermination infer()
visitors::VerboseVisitor< ReducedInference< GM, ACC, INF > > VerboseVisitorType
void fixVariable(const typename GM::IndexType, const typename GM::LabelType)
fix label for variable
GM::ValueType bound() const
return a bound on the solution
virtual ValueType bound() const
return a bound on the solution
Definition: inference.hxx:423
[class mqpbo] Multilabel QPBO (MQPBO) Implements the algorithms described in i) Ivan Kovtun: Partial ...
Definition: mqpbo.hxx:37
void modifiedState2OriginalState(const std::vector< LabelType > &, std::vector< LabelType > &) const
transforming label of the modified to the labeling of the original problem
ReducedInference< _GM, _ACC, RebindedInf > type
GraphicalModel< ValueType, OperatorType, FunctionTypeList, SpaceType > InfGmType
void buildModifiedSubModels()
build modified sub-models
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:49
reference to a Factor of a GraphicalModel
Definition: view.hxx:13
visitors::EmptyVisitor< ReducedInference< GM, ACC, INF > > EmptyVisitorType
const MGM & getModifiedModel() const
return the modified graphical model
double partialOptimality(std::vector< bool > &) const
Definition: qpbo.hxx:170
ReducedInferenceHelper< _GM >::InfGmType RebindedInfGmType
ReducedInference< _GM, ACC, RebindedInf > type
INF::template RebindGmAndAcc< RebindedInfGmType, _ACC >::type RebindedInf
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:50
QPBO Algorithm.
QPBO Algorithm C. Rother, V. Kolmogorov, V. Lempitsky, and M. Szummer, "Optimizing binary MRFs via e...
Definition: qpbo.hxx:19
Inference algorithm interface.
Definition: inference.hxx:43
visitors::TimingVisitor< ReducedInference< GM, ACC, INF > > TimingVisitorType
void modifiedSubStates2OriginalState(const std::vector< std::vector< LabelType > > &, std::vector< LabelType > &) const
transforming label of the modified subproblems to the labeling of the original problem ...
IndexType numberOfVariables() const
DiscreteSpace< IndexType, LabelType > SpaceType
GM::ValueType value() const
return the solution (value)
InferenceTermination infer()
Definition: qpbo.hxx:126
ReducedInferenceHelper< _GM >::InfGmType RebindedInfGmType
INF::template RebindGm< RebindedInfGmType >::type RebindedInf
const GmType & graphicalModel() const
const MGM & getModifiedSubModel(size_t) const
return the i-th modified sub graphical model
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:48
meta::TypeListGenerator< ViewFixVariablesFunction< GM >, ViewFunction< GM >, ConstantFunction< ValueType, IndexType, LabelType >, ExplicitFunction< ValueType, IndexType, LabelType > >::type FunctionTypeList
size_t numberOfSubmodels() const
return the number of submodels
[class reducedinference] Reduced Inference Implementation of the reduction techniques proposed in J...
OpenGM runtime error.
Definition: opengm.hxx:100
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
Definition: qpbo.hxx:145
InferenceTermination
Definition: inference.hxx:24