OpenGM  2.3.x
Discrete Graphical Model Library
cgc.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_CGC_HXX
3 #define OPENGM_CGC_HXX
4 
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 #include <fstream>
9 
10 #include <boost/format.hpp>
11 #include <boost/unordered_set.hpp>
12 
13 #include "opengm/opengm.hxx"
18 
19 
22 
23 
24 
25 namespace opengm {
26 
27 namespace detail_gcg{
28 
34  template<class GM,class LABELS_ITER>
35  typename GM::IndexType getCCFromLabels(
36  const GM & gm,
37  LABELS_ITER labels
38  ){
39  typedef typename GM::IndexType IndexType;
40  typedef typename GM::LabelType LabelType;
41 
42  // merge with UFD
43  opengm::Partition<IndexType> ufd(gm.numberOfVariables());
44  for(IndexType vi=0;vi<gm.numberOfVariables();++vi){
45  const LabelType label=labels[vi];
46  const IndexType numFacVar = static_cast<IndexType>(gm.numberOfFactors(vi));
47  for(IndexType f=0;f<numFacVar;++f){
48  const IndexType fi = gm.factorOfVariable(vi,f);
49  const IndexType numVarFac = gm[fi].numberOfVariables();
50  for(size_t v=0;v<numVarFac;++v){
51  const IndexType vi2=gm[fi].variableIndex(v);
52  const LabelType label2=labels[vi2];
53  if(vi!=vi2 && label==label2){
54  ufd.merge(vi,vi2);
55  }
56  }
57  }
58  }
59  std::map<IndexType,IndexType> repLabeling;
60  ufd.representativeLabeling(repLabeling);
61  const size_t numberOfCCs=ufd.numberOfSets();
62 
63  for(IndexType vi=0;vi<gm.numberOfVariables();++vi){
64  IndexType findVi=ufd.find(vi);
65  IndexType denseRelabling=repLabeling[findVi];
66  labels[vi]=denseRelabling;
67  }
68  return numberOfCCs;
69  }
70 
78  template<class CT,class C,class FP,class F>
79  void findFirst(
80  const CT & toFind,
81  const C & container,
82  FP & position,
83  F & found
84  ){
85  typedef typename CT::value_type ToFindType;
86  typedef typename FP::value_type ResultTypePosition;
87  // fill map with positions of values to find
88  typedef std::map<ToFindType,size_t> MapType;
89  typedef typename MapType::const_iterator MapIter;
90  MapType toFindPosition;
91  for(size_t i=0;i<toFind.size();++i){
92  toFindPosition.insert(std::pair<ToFindType,size_t>(toFind[i],i));
93  found[i]=false;
94  }
95 
96  // find values
97  size_t numFound=0;
98  for(size_t i=0;i<container.size();++i){
99  const ToFindType value = container[i];
100  MapIter findVal=toFindPosition.find(value);
101 
102  if( findVal!=toFindPosition.end()){
103  const size_t posInToFind = findVal->second;
104  if(found[posInToFind]==false){
105  position[posInToFind]=static_cast<ResultTypePosition>(i);
106  found[posInToFind]=true;
107  numFound+=1;
108  }
109  if(numFound==toFind.size()){
110  break;
111  }
112  }
113  }
114  }
115 }
116 
117 
120 template<class GM, class ACC>
121 class CGC : public Inference<GM, ACC>
122 {
123 public:
124 
125  typedef ACC AccumulationType;
126  typedef GM GraphicalModelType;
131 
132  typedef std::pair<int,ValueType> IVPairType;
134 
136 
137  class Parameter {
138  public:
140  const bool planar = true,
141  const size_t maxIterations = 1,
142  const bool useBookkeeping = true,
143  const double threshold = 0.0,
144  const bool startFromThreshold = true,
145  const bool doCutMove = true,
146  const bool doGlueCutMove = true
147  ):
148  planar_(planar),
149  maxIterations_(maxIterations),
150  useBookkeeping_(useBookkeeping),
151  threshold_(threshold),
153  doCutMove_(doCutMove),
155  {}
156 
157  bool planar_;
160  double threshold_;
164 
165 
166 
167  };
168 
169  CGC(const GraphicalModelType&, const Parameter& param = Parameter());
170  std::string name() const;
171  const GraphicalModelType& graphicalModel() const;
172  void reset();
173 
174  ValueType bound() const {
175  return bound_+energyOffset_;
176  }
177  ValueType value() const {
178  return value_+energyOffset_;
179  }
180  ValueType calcBound(){ return 0; }
181 
183  template<class VisitorType>
184  InferenceTermination infer(VisitorType&);
185  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
186 
187  void setStartingPoint(typename std::vector<LabelType>::const_iterator);
188 
189  ValueType evalPrimal() const;
190  ValueType evalPrimal2(const std::vector<LabelType>&) const;
191 
192 
193  ~CGC(){
194  delete submodel_;
195  }
196 
197 
198  private:
199  bool inRecursive2Coloring()const{
200  return inRecursive2Coloring_;
201  }
202  bool inGreedy2Coloring()const{
203  return inGreedy2Coloring_;
204  }
205 
206  void findActiveFactors(std::vector<IndexType> activeFactors){
207  activeFactors.clear();
208  for(IndexType fi=0;fi<numDualVar_;++fi){
209  if(argDual_[fi]!=0)
210  activeFactors.push_back(fi);
211  }
212  }
213 
214  LabelType setStartingPointFromArgPrimal(const bool fillQ);
215 
216  void primalToDual();
217  ValueType evalDual()const;
218 
219  template<class VISITOR>
220  void recursive2Coloring(VISITOR & visitor);
221 
222  template<class VISITOR>
223  void greedy2ColoringPlanar(VISITOR & visitor);
224 
225 
226  const GraphicalModelType& gmRaw_;
227 
228  PottsGmType gm_;
229 
230  Parameter param_;
231 
232  std::vector<ValueType> lambdas_;
233 
234  SubmodelCGC<PottsGmType> * submodel_;
235 
236  // redundant data for easy readability
237  IndexType numVar_;
238  IndexType numDualVar_;
239 
240  // current value and naive bound
241  ValueType value_;
242  ValueType bound_;
243 
244  // current primal and dual arg
245  // and the current max Color in arg Primal
246  std::vector<LabelType> argPrimal_;
247  std::vector<LabelType> argDual_;
248  IndexType maxColor_;
249 
250  // deque for recursive 2 coloring
251  std::deque<IndexType> toSplit_;
252 
253  // current state of the alg.
254  bool inRecursive2Coloring_;
255  bool inGreedy2Coloring_;
256 
257  ValueType energyOffset_;
258 
259 
260  std::vector<unsigned char> dirtyFactors_;
261 
262  std::string log_;
263 
264  bool timeout_;
265 };
266 
267 
268 
269 template<class GM, class ACC>
270 inline
272 (
273  const GraphicalModelType& gm,
274  const Parameter& parameter
275 )
276 : gmRaw_(gm),
277  gm_(gm.space()),
278  param_(parameter),
279  //lambdas_(gm.numberOfFactors()),
280  //submodel_(gm,3,1),
281  numVar_(gm.numberOfVariables()),
282  //numDualVar_(gm.numberOfFactors()),
283  value_(0),
284  bound_(0),
285  argPrimal_(gm.numberOfVariables(),0),
286  //argDual_(gm.numberOfFactors(),0),
287  toSplit_(),
288  inRecursive2Coloring_(false),
289  inGreedy2Coloring_(false),
290  energyOffset_(0),
291  timeout_(false)
292  //dirtyFactors_(gm_.numberOfFactors(),1))
293 {
295  // find all double edges
297 
298  typedef std::map<UInt64Type,ValueType> MapType;
299  MapType factorMap;
300 
301  LabelType lAA[]={0,0};
302  LabelType lAB[]={0,1};
303 
304  for(IndexType fi=0;fi<gm.numberOfFactors();++fi){
305 
306  const ValueType o = gm[fi].operator()(lAA);
307  const ValueType l = gm[fi].operator()(lAB)-o;
308  energyOffset_ += o;
309 
310  const UInt64Type key = gm[fi].variableIndex(0)*gm.numberOfVariables() + gm[fi].variableIndex(1);
311 
312  if(factorMap.find(key)==factorMap.end() ){
313  // factor is not yet added
314  factorMap[key]=l;
315  }
316  else{
317  factorMap[key]+=l;
318  }
319 
320  }
321 
322  // iterate over map to add all non-double edge factors to gm_
323  for(typename MapType::const_iterator iter=factorMap.begin(); iter!=factorMap.end(); ++iter){
324  const UInt64Type key = iter->first;
325  const ValueType lambda = iter->second;
326 
327  const UInt64Type v0 = key/gm.numberOfVariables();
328  const UInt64Type v1 = key - v0*gm.numberOfVariables();
329  const UInt64Type vis[2]={v0,v1};
330 
331  PfType f(gm.numberOfLabels(v0),gm.numberOfLabels(v1),0.0,lambda);
332  gm_.addFactor( gm_.addFunction(f) ,vis,vis+2);
333  }
334 
335  numDualVar_=gm_.numberOfFactors();
336  argDual_.resize(numDualVar_);
337  dirtyFactors_.resize(numDualVar_);
338  lambdas_.resize(numDualVar_);
339 
340  // gm_ is set up
341  //lambdas_(gm.numberOfFactors()),
342  //submodel_ = new SubmodelCGC<PottsGmType>(gm_,3,1,false);
343  submodel_ = new SubmodelCGC<PottsGmType>(gm_,0,0,false);
344 
345  // set up lambdas
346  for(IndexType f=0;f<numDualVar_;++f){
347 
348  OPENGM_CHECK(gm_[f].isPotts(), "all factors need to be potts factors");
349  OPENGM_CHECK_OP(gm_[f].numberOfVariables(),==,2, "all factors need to 2. order");
350 
351  const ValueType o = gm_[f].operator()(lAA);
352  energyOffset_ += o;
353 
354  const ValueType lambda=gm_[f].operator()(lAB) - o;
355  if(lambda<0.0){
356  bound_ +=lambda;
357  }
358  lambdas_[f]=lambda;
359  }
360 }
361 
362 
363 
364 
365 template<class GM, class ACC>
366 template<class VisitorType>
368 (
369  VisitorType& visitor
370 )
371 {
372  timeout_ = false;
373  //std::cout << boost::format("CGC: infer for %d primary, %d dual variables\n") % gm_.numberOfVariables() % gm_.numberOfFactors();
374  visitor.begin(*this);
375  if(param_.startFromThreshold_)
376  startFromThreshold(gm_,lambdas_,argPrimal_, 0);
377  for(IndexType f=0;f<numDualVar_;++f){
378  const IndexType v1=gm_[f].variableIndex(0);
379  const IndexType v2=gm_[f].variableIndex(1);
380  }
381 
382  ValueType valA = 0.0;
383  ValueType valB = 0.0;
384  for(size_t i=0;i<param_.maxIterations_;++i){
385  if(!timeout_ && param_.doCutMove_ && ( value_<valA || i==0)){
386  //std::cout<<"rec 2 coloring\n";
387  this->recursive2Coloring(visitor);
388  valA=value_;
389  }
390  if(!timeout_ && param_.doGlueCutMove_ && (value_<valB || i==0)){
391  //std::cout<<"greedy 2 coloring\n";
392  this->greedy2ColoringPlanar(visitor);
393  valB=value_;
394  }
395  if(timeout_)
396  break;
397  }
398  visitor.end(*this);
399  return NORMAL;
400 }
401 
402 
403 
404 template<class GM, class ACC>
405 template<class VISITOR>
406 void
407 CGC<GM, ACC>::recursive2Coloring(VISITOR & visitor){
408  // set mode
409  inRecursive2Coloring_=true;
410  inGreedy2Coloring_=false;
411 
412  // set starting point will set up all invariants
413  const LabelType numCCsStart=this->setStartingPointFromArgPrimal(true);
414 
415 
416 
417  // while there are subsets to cut in deque
418  while(!toSplit_.empty()){
419 
420 
421  // get an example variable of an cc and
422  // the "color" of all variables which are in cc
423  const LabelType exampleVariableInCC = toSplit_.front();
424  toSplit_.pop_front();
425  const LabelType ccColor = argPrimal_[exampleVariableInCC];
426 
427  // infer cc / all variables which have ccColor
428  // the result of inference is writte in self.argPrimal via call by reference
429  IVPairType res = submodel_->inferSubset(argPrimal_,ccColor,exampleVariableInCC,maxColor_+1,toSplit_,param_.planar_, false /*debug*/);
430  const int numCCArg = res.first;
431  const ValueType value2Coloring = res.second;
432 
433  // the 2 coloring on the cc can split the cc in "numCCArg" connected comps
434  // and if numCCArg is 1 this means cc can't be splitted any more
435  // otherwise we need to add an exampe var for each result cc to the deque
436  if(numCCArg>1){
437  // increment the maximum color which is in arg Primal
438  maxColor_ += numCCArg+1;
439  // update current best value
440  value_ += value2Coloring;
441  if(visitor(*this)!=0){
442  timeout_ = true;
443  break;
444  }
445  }
446  }
447 
448 
449  // set mode
450  inRecursive2Coloring_=false;
451  inGreedy2Coloring_=false;
452  // set starting point will set up all invariants
453  const LabelType numCCsEnd=this->setStartingPointFromArgPrimal(false);
454 }
455 
456 
457 template<class GM, class ACC>
458 template<class VISITOR>
459 void
460 CGC<GM, ACC>::greedy2ColoringPlanar(VISITOR & visitor){
461  // set mode
462  inRecursive2Coloring_=false;
463  inGreedy2Coloring_=true;
464 
465 
466 
467  //while there are some improvements
468  bool changes=true;
469 
470  //std::vector<bool> dirtyFactors(gm_.numberOfFactors(),true);
471 
472 
473  //std::fill(dirtyFactors_.begin(),dirtyFactors_.end(),true );
474 
475  for(IndexType fi=0;fi<dirtyFactors_.size();++fi){
476  if(dirtyFactors_[fi]!=2)
477  dirtyFactors_[fi]=1;
478  }
479 
480 
481  while(changes && timeout_==false){
482  changes=false;
483 
484  // set starting point will set up all invariants
485  const LabelType numCCsStart=this->setStartingPointFromArgPrimal(false);
486  if (numCCsStart==1){
487  break;
488  }
489 
490  // find one factor between each cc
491  typedef opengm::UInt64Type KeyType;
492  typedef std::map< opengm::UInt64Type , IndexType > MapType;
493  typedef typename MapType::const_iterator MapIter;
494  MapType factorCCs;
495  for(IndexType fi=0;fi<numDualVar_;++fi){
496  const LabelType c0 = argPrimal_[ gm_[fi].variableIndex(0) ];
497  const LabelType c1 = argPrimal_[ gm_[fi].variableIndex(1) ];
498  const KeyType cA = static_cast<KeyType>(std::min(c0,c1));
499  const KeyType cB = static_cast<KeyType>(std::max(c0,c1));
500 
501  const KeyType key = cA + cB*static_cast<KeyType>(maxColor_+1);
502  factorCCs[key]=fi;
503  }
504 
505  // get 2 adj. connect comp , merge them and try to
506  // reoptimize them with colorings
507  for(MapIter iter=factorCCs.begin();iter!=factorCCs.end();++iter){
508  const IndexType fi = iter->second;
509  if(param_.useBookkeeping_==false || dirtyFactors_[fi] == 1 ){
510 
511  //std::cout<<" fi dirty ? "<<bool(dirtyFactors[fi])<<" \n";
512  const LabelType c0 = argPrimal_[ gm_[fi].variableIndex(0) ];
513  const LabelType c1 = argPrimal_[ gm_[fi].variableIndex(1) ];
514 
515  // infer by merging and resplitting
516  if(c0!=c1){
517  //std::cout<<"infer 2 subsets \n\n";
518  IVPairType res = submodel_->infer2Subsets(
519  argPrimal_,c0,c1,
520  gm_[fi].variableIndex(0),gm_[fi].variableIndex(1),
521  maxColor_+1,
522  param_.planar_
523  );
524  const int numCCArg = res.first;
525  const ValueType value2Coloring = res.second;
526  /*
527  if(numCCArg==-1):
528  print " one var problem"
529 
530  print " no improvement"
531  elif(numCCArg==-3):
532  print " OPT CUT"
533  */
534  if(numCCArg==0){
535  //std::cout<<"zeros ccs\n";
536  OPENGM_CHECK(false,"internal error");
537  }
538  // no improvment
539  else if(numCCArg==-2){
540  //std::cout<<" NO improvement\n\n\n";
541  if(param_.useBookkeeping_)
542  submodel_->updateDirtyness(dirtyFactors_,false);
543  //submodel_->cleanInsideAndBorder();
544  }
545  else if(numCCArg>=1){
546  //OPENGM_CHECK_OP(value2Coloring,<=,0.0,"internal error");
547  //if(numCCArg==1){
548  //OPENGM_CHECK_OP(argPrimal_[gm_[fi].variableIndex(0)],==,argPrimal_[gm_[fi].variableIndex(1)], "internal error");
549  //}
550  changes=true;
551  maxColor_+=numCCArg+1;
552  value_+=value2Coloring;
553  if(param_.useBookkeeping_){
554  submodel_->updateDirtyness(dirtyFactors_,true);
555  //submodel_->cleanInsideAndBorder();
556  }
557 
558  if(visitor(*this)!=0){
559  timeout_ = true;
560  break;
561  }
562  }
563  submodel_->cleanInsideAndBorder();
564  } // if still active
565  } // if dirty
566  else{
567  }
568  } // for all factors
569  } // while changes...
570 
571  inRecursive2Coloring_=false;
572  inGreedy2Coloring_=false;
573  // set starting point will set up all invariants
574  const LabelType numCCsEnd=this->setStartingPointFromArgPrimal(false);
575 }
576 
577 
578 
579 template<class GM, class ACC>
580 inline void
582 
583 }
584 
585 template<class GM, class ACC>
586 inline void
588 (
589  typename std::vector<typename CGC<GM,ACC>::LabelType>::const_iterator begin
590 ) {
591  std::copy(begin,begin+numVar_,argPrimal_.begin());
592  const LabelType numCC=this->setStartingPointFromArgPrimal(true);
593 }
594 
595 template<class GM, class ACC>
596 inline typename CGC<GM,ACC>::LabelType
598 
599  // get a connected componet labeling from starting point
600  IndexType numCC = detail_gcg::getCCFromLabels(gm_,argPrimal_.begin());
601 
602 
603  //this has set returns the following:
604  // # argPrimal_[primal variable index / vi] = "color" in [0, numCC]
605  this->primalToDual();
606  value_ = evalPrimal();
607  maxColor_ = numCC-1;
608 
609  if(fillQ){
610  // fill deque with example variables for each connected componet
611  std::vector<LabelType> toFind(numCC);
612  std::vector<bool> found(numCC,false);
613  std::vector<IndexType> foundPosition(numCC);
614  for(LabelType c=0;c<numCC;++c){
615  toFind[c]=c;
616  }
617  detail_gcg::findFirst(toFind,argPrimal_,foundPosition,found);
618  toSplit_.clear();
619  for(IndexType c=0;c<numCC;++c){
620  toSplit_.push_back(foundPosition[c]);
621  }
622  }
623  return numCC;
624 }
625 
626 template<class GM, class ACC>
627 inline std::string
629 {
630  return "CGC";
631 }
632 
633 template<class GM, class ACC>
634 inline const typename CGC<GM, ACC>::GraphicalModelType&
636 {
637  return gmRaw_;
638 }
639 
640 template<class GM, class ACC>
643 {
644  EmptyVisitorType v;
645  return infer(v);
646 }
647 
648 
649 
650 
651 template<class GM, class ACC>
654 (
655  std::vector<LabelType>& x,
656  const size_t N
657 ) const
658 {
659  if(N==1) {
660  x.resize(gm_.numberOfVariables());
661  for(size_t j=0; j<x.size(); ++j) {
662  x[j] = argPrimal_[j];
663  }
664  return NORMAL;
665  }
666  else {
667  return UNKNOWN;
668  }
669 }
670 
671 
672 template<class GM, class ACC>
673 inline void
675  for(IndexType f=0;f<numDualVar_;++f){
676  const IndexType v1=gm_[f].variableIndex(0);
677  const IndexType v2=gm_[f].variableIndex(1);
678  argDual_[f] = argPrimal_[v1]==argPrimal_[v2] ? 0 :1 ;
679  }
680 }
681 
682 
683 template<class GM, class ACC>
684 inline typename CGC<GM, ACC>::ValueType
686  const std::vector<typename CGC<GM, ACC>::LabelType> & argP
687 )const{
688  ValueType value = 0.0;
689  for(IndexType f=0;f<numDualVar_;++f){
690  const IndexType v1=gm_[f].variableIndex(0);
691  const IndexType v2=gm_[f].variableIndex(1);
692  if(argP[v1]!=argP[v2])
693  value+=lambdas_[f];
694  }
695  return value;
696 }
697 
698 
699 template<class GM, class ACC>
700 inline typename CGC<GM, ACC>::ValueType
702  ValueType value = 0.0;
703  for(IndexType f=0;f<numDualVar_;++f){
704  const IndexType v1=gm_[f].variableIndex(0);
705  const IndexType v2=gm_[f].variableIndex(1);
706  if(argPrimal_[v1]!=argPrimal_[v2])
707  value+=lambdas_[f];
708  }
709  return value;
710 }
711 
712 
713 template<class GM, class ACC>
714 inline typename CGC<GM, ACC>::ValueType
716  ValueType value = 0.0;
717  for(IndexType f=0;f<numDualVar_;++f){
718  if(argDual_[f]!=0)
719  value+=lambdas_[f];
720  }
721  return value;
722 }
723 
724 
725 
726 } // namespace opengm
727 
728 #endif // #ifndef OPENGM_CGC_HXX
729 
730 // kate: space-indent on; indent-width 3; replace-tabs on; indent-mode cstyle; remove-trailing-space; replace-trailing-spaces-save;
The OpenGM namespace.
Definition: config.hxx:43
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Definition: cgc.hxx:654
const GraphicalModelType & graphicalModel() const
Definition: cgc.hxx:635
Parameter(const bool planar=true, const size_t maxIterations=1, const bool useBookkeeping=true, const double threshold=0.0, const bool startFromThreshold=true, const bool doCutMove=true, const bool doGlueCutMove=true)
Definition: cgc.hxx:139
void findFirst(const CT &toFind, const C &container, FP &position, F &found)
Definition: cgc.hxx:79
CGC(const GraphicalModelType &, const Parameter &param=Parameter())
Definition: cgc.hxx:272
ValueType evalPrimal() const
Definition: cgc.hxx:701
void merge(value_type, value_type)
Merge two sets.
Definition: partition.hxx:147
visitors::VerboseVisitor< CGC< GM, ACC > > VerboseVisitorType
Definition: cgc.hxx:128
size_t maxIterations_
Definition: cgc.hxx:158
OPENGM_GM_TYPE_TYPEDEFS
Definition: cgc.hxx:127
detail_types::UInt64Type UInt64Type
uint64
Definition: config.hxx:300
ValueType value() const
return the solution (value)
Definition: cgc.hxx:177
Experimental Multicut.
Definition: cgc.hxx:121
ValueType evalPrimal2(const std::vector< LabelType > &) const
Definition: cgc.hxx:685
PottsFunction< ValueType, IndexType, LabelType > PfType
Definition: cgc.hxx:133
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:40
ACC AccumulationType
Definition: cgc.hxx:125
void reset()
Definition: cgc.hxx:581
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
Definition: cgc.hxx:588
bool startFromThreshold_
Definition: cgc.hxx:161
visitors::EmptyVisitor< CGC< GM, ACC > > EmptyVisitorType
Definition: cgc.hxx:129
GM::IndexType getCCFromLabels(const GM &gm, LABELS_ITER labels)
Definition: cgc.hxx:35
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:41
Inference algorithm interface.
Definition: inference.hxx:34
std::string name() const
Definition: cgc.hxx:628
GM GraphicalModelType
Definition: cgc.hxx:126
visitors::TimingVisitor< CGC< GM, ACC > > TimingVisitorType
Definition: cgc.hxx:130
InferenceTermination infer()
Definition: cgc.hxx:642
GraphicalModel< ValueType, Adder, PfType, typename GM::SpaceType > PottsGmType
Definition: cgc.hxx:135
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Definition: submodel2.hxx:24
Potts function for two variables.
Definition: potts.hxx:19
ValueType calcBound()
Definition: cgc.hxx:180
Disjoint set data structure with path compression.
Definition: partition.hxx:13
#define OPENGM_CHECK(B, TXT)
Definition: submodel2.hxx:28
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:39
std::pair< int, ValueType > IVPairType
Definition: cgc.hxx:132
void startFromThreshold(const GM &gm, std::vector< typename GM::ValueType > &lambdas, std::vector< typename GM::LabelType > &resultArg, const typename GM::ValueType threshold=0.0)
ValueType bound() const
return a bound on the solution
Definition: cgc.hxx:174
InferenceTermination
Definition: inference.hxx:24