OpenGM  2.3.x
Discrete Graphical Model Library
fusion_mover.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_AUX_FUSION_MOVER_HXX
2 #define OPENGM_AUX_FUSION_MOVER_HXX
3 
4 
5 
6 
7 #include "opengm/opengm.hxx"
14 
16 #include "opengm/inference/fix-fusion/fusion-move.hpp"
17 
19 
20 #ifdef WITH_CPLEX
22 #endif
23 #ifdef WITH_QPBO
24 #include "QPBO.h"
27 #endif
28 
29 
30 
31 namespace opengm
32 {
33 
34 
35 
36 
37 template<class GM>
39  : public FunctionBase<FuseViewFunction<GM>, typename GM::ValueType, typename GM::IndexType, typename GM::LabelType>
40 {
41 public:
42  typedef typename GM::ValueType ValueType;
43  typedef ValueType value_type;
44  typedef typename GM::FactorType FactorType;
45  typedef typename GM::OperatorType OperatorType;
46  typedef typename GM::IndexType IndexType;
47  typedef typename GM::LabelType LabelType;
48 
50 
52  const FactorType &factor,
53  const std::vector<LabelType> &argA,
54  const std::vector<LabelType> &argB
55  )
56  : factor_(&factor),
57  argA_(&argA),
58  argB_(&argB),
59  iteratorBuffer_(factor.numberOfVariables())
60  {
61 
62  }
63 
64 
65 
66  template<class Iterator>
67  ValueType operator()(Iterator begin)const
68  {
69  for (IndexType i = 0; i < iteratorBuffer_.size(); ++i)
70  {
71  OPENGM_CHECK_OP(begin[i], < , 2, "");
72  if (begin[i] == 0)
73  {
74  iteratorBuffer_[i] = argA_->operator[](factor_->variableIndex(i));
75  }
76  else
77  {
78  iteratorBuffer_[i] = argB_->operator[](factor_->variableIndex(i));
79  }
80  }
81  return factor_->operator()(iteratorBuffer_.begin());
82  }
83 
84  IndexType shape(const IndexType)const
85  {
86  return 2;
87  }
88 
89  IndexType dimension()const
90  {
91  return iteratorBuffer_.size();
92  }
93 
94  IndexType size()const
95  {
96  return std::pow(2, iteratorBuffer_.size());
97  }
98 private:
99  FactorType const *factor_;
100  std::vector<LabelType> const *argA_;
101  std::vector<LabelType> const *argB_;
102  mutable std::vector<LabelType> iteratorBuffer_;
103 };
104 
105 
106 template<class GM>
108  : public FunctionBase<FuseViewFixFunction<GM>, typename GM::ValueType, typename GM::IndexType, typename GM::LabelType>
109 {
110 public:
111  typedef typename GM::ValueType ValueType;
112  typedef ValueType value_type;
113  typedef typename GM::FactorType FactorType;
114  typedef typename GM::OperatorType OperatorType;
115  typedef typename GM::IndexType IndexType;
116  typedef typename GM::LabelType LabelType;
117 
119 
121  const FactorType &factor,
122  const std::vector<LabelType> &argA,
123  const std::vector<LabelType> &argB
124  )
125  : factor_(&factor),
126  argA_(&argA),
127  argB_(&argB),
128  notFixedPos_(),
129  iteratorBuffer_(factor.numberOfVariables())
130  {
131  for (IndexType v = 0; v < factor.numberOfVariables(); ++v)
132  {
133  const IndexType vi = factor.variableIndex(v);
134  if (argA[vi] != argB[vi])
135  {
136  notFixedPos_.push_back(v);
137  }
138  else
139  {
140  iteratorBuffer_[v] = argA[vi];
141  }
142  }
143  }
144 
145 
146 
147  template<class Iterator>
148  ValueType operator()(Iterator begin)const
149  {
150  for (IndexType i = 0; i < notFixedPos_.size(); ++i)
151  {
152  const IndexType nfp = notFixedPos_[i];
153  OPENGM_CHECK_OP(begin[i], < , 2, "");
154  if (begin[i] == 0)
155  {
156  iteratorBuffer_[nfp] = argA_->operator[](factor_->variableIndex(nfp));
157  }
158  else
159  {
160  iteratorBuffer_[nfp] = argB_->operator[](factor_->variableIndex(nfp));
161  }
162  }
163  return factor_->operator()(iteratorBuffer_.begin());
164  }
165 
166  IndexType shape(const IndexType)const
167  {
168  return 2;
169  }
170 
171  IndexType dimension()const
172  {
173  return notFixedPos_.size();
174  }
175 
176  IndexType size()const
177  {
178  return std::pow(2, notFixedPos_.size());
179  }
180 private:
181  FactorType const *factor_;
182  std::vector<LabelType> const *argA_;
183  std::vector<LabelType> const *argB_;
184  std::vector<IndexType> notFixedPos_;
185  mutable std::vector<LabelType> iteratorBuffer_;
186 };
187 
188 template<class MODEL_TYPE>
190 {
191 
192  typedef typename MODEL_TYPE::SpaceType SpaceType;
193 
194 
195  void createModel(const UInt64Type nVar)
196  {
197  model_ = new MODEL_TYPE(SpaceType(nVar, 2));
198  }
199  void freeModel()
200  {
201  delete model_;
202  }
203 
204  template<class F, class ITER>
205  void addFactor(const F &f, ITER viBegin, ITER viEnd)
206  {
207  model_->addFactor(model_->addFunction(f), viBegin, viEnd);
208  }
209 
210  MODEL_TYPE *model_;
211 };
212 
213 
214 template<class MODEL_TYPE>
216 {
217 
219  {
220  c00_[0] = 0;
221  c00_[1] = 0;
222 
223  c11_[0] = 1;
224  c11_[1] = 1;
225 
226  c01_[0] = 0;
227  c01_[1] = 1;
228 
229  c10_[0] = 1;
230  c10_[1] = 0;
231  }
232 
233  void createModel(const UInt64Type nVar)
234  {
235  model_ = new MODEL_TYPE(nVar, 0);
236  model_->AddNode(nVar);
237  }
238  void freeModel()
239  {
240  delete model_;
241  }
242 
243  template<class F, class ITER>
244  void addFactor(const F &f, ITER viBegin, ITER viEnd)
245  {
246  OPENGM_CHECK_OP(f.dimension(), <= , 2, "wrong order for QPBO");
247 
248  if (f.dimension() == 1)
249  {
250  model_->AddUnaryTerm(*viBegin, f(c00_), f(c11_));
251  }
252  else
253  {
254  model_->AddPairwiseTerm(
255  viBegin[0], viBegin[1],
256  f(c00_),
257  f(c01_),
258  f(c10_),
259  f(c11_)
260  );
261  }
262  }
263 
264  MODEL_TYPE *model_;
269 };
270 
271 template<class MODEL_TYPE>
273 {
274 
275  Ad3ModelProxy(const typename MODEL_TYPE::Parameter param)
276  : param_(param)
277  {
278  }
279 
280  void createModel(const UInt64Type nVar)
281  {
282  model_ = new MODEL_TYPE(nVar, 2, param_, true);
283  }
284  void freeModel()
285  {
286  delete model_;
287  }
288 
289  template<class F, class ITER>
290  void addFactor(const F &f, ITER viBegin, ITER viEnd)
291  {
292  model_->addFactor(viBegin, viEnd, f);
293  }
294 
295  MODEL_TYPE *model_;
296  typename MODEL_TYPE::Parameter param_;
297 };
298 
299 
300 
301 template<class GM, class ACC>
303 public:
304 
305  typedef GM GraphicalModelType;
306  typedef ACC AccumulationType;
308 
309 
310  // function types
312 
315 
317 
318  // sub gm
320  typedef typename meta::TypeListGenerator< FuseViewingFunction, FuseViewingFixingFunction, ArrayFunction >::type SubFunctionTypeList;
322 public:
323 
324  FusionMover(const GM &gm);
325 
326  void setup(
327  const std::vector<LabelType> &argA,
328  const std::vector<LabelType> &argB,
329  std::vector<LabelType> &resultArg,
330  const ValueType valueA,
331  const ValueType valueB
332  );
333 
334 
335  IndexType numberOfFusionMoveVariable()const
336  {
337  return nLocalVar_;
338  }
339 
340  template<class SOLVER>
341  ValueType fuse(
342  const typename SOLVER::Parameter &param,
343  const bool warmStart = false
344  );
345 
346 
347  template<class SOLVER>
348  ValueType fuseAd3(
349  const typename SOLVER::Parameter &param
350  );
351 
352  template<class SOLVER>
353  ValueType fuseQpbo(
354  );
355 
356 
357  template<class SOLVER>
358  ValueType fuseFixQpbo(
359  );
360 
361  ValueType valueResult()const
362  {
363  return valueResult_;
364  }
365  ValueType valueA()const
366  {
367  return valueA_;
368  }
369  ValueType valueB()const
370  {
371  return valueB_;
372  }
373 
374 private:
375  template<class MODEL_PROXY>
376  void fillSubModel(MODEL_PROXY &modelProy);
377 
378  // needed for higher fix order reduction
379  static const size_t maxOrder_ = 9;
380  // graphical model to fuse states from
381  const GraphicalModelType &gm_;
382 
383  std::vector<LabelType> const *argA_;
384  std::vector<LabelType> const *argB_;
385  std::vector<LabelType> const *argBest_;
386  std::vector<LabelType> *argResult_;
387 
388  ValueType valueA_;
389  ValueType valueB_;
390  ValueType valueBest_;
391  ValueType valueResult_;
392 
393  LabelType bestLabel_;
394 
395 
396  std::vector<LabelType> subSpace_;
397  std::vector<IndexType> localToGlobalVi_;
398  std::vector<IndexType> globalToLocalVi_;
399  IndexType nLocalVar_;
400 
401 
402 };
403 
404 template<class GM, class ACC>
406 
407 public:
408  typedef GM GraphicalModelType;
409  typedef ACC AccumulationType;
411 
412 
415 
416 
417  #ifdef WITH_QPBO
418  typedef kolmogorov::qpbo::QPBO<double> QpboSubInf;
419  //typedef opengm::external::QPBO<SubGmType> QPBOSubInf;
420  typedef opengm::HQPBO<SubGmType,AccumulationType> HQPBOSubInf;
421  typedef typename ReducedInferenceHelper<SubGmType>::InfGmType ReducedGmType;
422  #endif
423  #ifdef WITH_CPLEX
425  #endif
426 
428 
429 
430  typedef std::vector<LabelType> LabelVector;
431 
437  };
438 
439  struct Parameter{
441  const FusionSolver fusionSolver=DefaulFusion,
442  const size_t maxSubgraphSize = 2,
443  const bool reducedInf = false,
444  const bool tentacles = false,
445  const bool connectedComponents = false,
446  const double fusionTimeLimit = 100.0
447  )
448  :
449  fusionSolver_(fusionSolver),
450  maxSubgraphSize_(maxSubgraphSize),
451  reducedInf_(reducedInf),
452  connectedComponents_(connectedComponents),
453  tentacles_(tentacles),
454  fusionTimeLimit_(fusionTimeLimit)
455  {
456 
457  }
464  };
465 
466  HlFusionMover(const GM & gm, const Parameter & param)
467  : gm_(gm),
468  param_(param),
469  fusionMover_(gm),
470  factorOrder_(gm.factorOrder()) {
471 
472  // set default fusion mover
473  if(param_.fusionSolver_==DefaulFusion){
475  #ifdef WITH_QPBO
476  param_.fusionSolver_ = QpboFusion;
477  #endif
478  }
479 
480 
481  // check
482  if(param_.fusionSolver_ == QpboFusion){
483  #ifndef WITH_QPBO
484  throw RuntimeError("WITH_QPBO need to be enabled for QpboFusion");
485  #endif
486  }
487  if(param_.fusionSolver_ == CplexFuison){
488  #ifndef WITH_CPLEX
489  throw RuntimeError("WITH_CPLEX need to be enabled for CplexFusion");
490  #endif
491  }
492  if(param_.reducedInf_){
493  #ifndef WITH_QPBO
494  throw RuntimeError("WITH_QPBO need to be enabled for reducedInference");
495  #endif
496  }
497 
498  }
499 
500 
501  bool fuse(const LabelVector & argA, const LabelVector argB, LabelVector & argRes,
502  const ValueType valA, const ValueType valB,ValueType & valRes){
503 
504  fusionMover_.setup(argA, argB, argRes, valA, valB);
505 
506 
507 
508  if(fusionMover_.numberOfFusionMoveVariable()>0){
509  if(param_.fusionSolver_ == QpboFusion){
510  #ifdef WITH_QPBO
511  if(factorOrder_<=2){
512  valRes = fusionMover_. template fuseQpbo<QpboSubInf> ();
513  }
514  else{
515  typename HQPBOSubInf::Parameter subInfParam;
516  valRes = fusionMover_. template fuse<HQPBOSubInf> (subInfParam,true);
517  }
518  #endif
519  }
520  else if(param_.fusionSolver_ == CplexFuison){
521  #ifdef WITH_CPLEX
522  // with reduced inference
523  if(param_.reducedInf_){
524  #ifdef WITH_QPBO
527  typename _CplexSubInf::Parameter _subInfParam;
528  _subInfParam.integerConstraint_ = true;
529  _subInfParam.numberOfThreads_ = 1;
530  _subInfParam.timeLimit_ = param_.fusionTimeLimit_;
531  typename CplexReducedSubInf::Parameter subInfParam(true,param_.tentacles_,param_.connectedComponents_,_subInfParam);
532  valRes = fusionMover_. template fuse<CplexReducedSubInf> (subInfParam,true);
533  #endif
534  }
535  // without reduced inference
536  else{
537  typename CplexSubInf::Parameter p;
538  p.integerConstraint_ = true;
539  p.numberOfThreads_ = 1;
540  p.timeLimit_ = param_.fusionTimeLimit_;
541  valRes = fusionMover_. template fuse<CplexSubInf> (p,true);
542  }
543  #endif
544  }
545  else if(param_.fusionSolver_ == LazyFlipperFusion){
546  if(param_.reducedInf_){
547  #ifdef WITH_QPBO
550  typename _LfSubInf::Parameter _subInfParam;
551  _subInfParam.maxSubgraphSize_= param_.maxSubgraphSize_;
552  typename LfReducedSubInf::Parameter subInfParam(true,param_.tentacles_,param_.connectedComponents_,_subInfParam);
553  valRes = fusionMover_. template fuse<LfReducedSubInf> (subInfParam,true);
554  #endif
555  }
556  else{
557  const typename LazyFlipperSubInf::Parameter fuseInfParam(param_.maxSubgraphSize_);
558  valRes = fusionMover_. template fuse<LazyFlipperSubInf> (fuseInfParam, true);
559  }
560  }
561  else{
562  throw RuntimeError("Unknown Fusion Type! Maybe caused by missing linking!");
563  }
564  return true;
565  }
566  else{
567  return false;
568  }
569  }
570 
571 private:
572  const GraphicalModelType & gm_;
573  Parameter param_;
574  FusionMoverType fusionMover_;
575  size_t factorOrder_;
576 };
577 
578 
579 
580 
581 /*
582 template<class GM, class ACC>
583 class MultiFusion{
584 
585 public:
586  typedef GM GraphicalModelType;
587  typedef ACC AccumulationType;
588  OPENGM_GM_TYPE_TYPEDEFS;
589 
590  typedef HlFusionMover<GraphicalModelType, AccumulationType> Fuse2;
591  typedef typename Fuse2::Parameter Fuse2Parameter;
592  typedef std::vector<LabelType> LabelVector;
593  enum MultiFusionMode{
594  Default,
595  PairwiseBest
596  };
597 
598 
599  struct Parameter{
600  Parameter(
601  const Fuse2Parameter & fuse2Param = Fuse2Parameter()
602  )
603  :
604  fuse2Param_(fuse2Param_){
605 
606  }
607 
608  Fuse2Parameter fuse2Param_;
609  };
610 
611  HlFusionMover<GM, ACC> fuse2_;
612 
613 
614  ValueType pairwiseFusion( const std::vector<LabelVector> & args
615  LabelVector & argRes){
616 
617  std::vector<LabelVector> * argsPtr = const_cast< const std::vector<LabelVector> * >(&args);
618  return pairwiseFusionImpl(*argsPtr, argRes,true);
619 
620  }
621 
622 private:
623  ValueType pairwiseFusionImpl( std::vector<LabelVector> & args
624  LabelVector & argRes,
625  bool first=true
626  ){
627 
628 
629  std::vector<LabelVector> improvedArgs;
630  size_t nInputs = args.size();
631 
632  size_t bestInputIndex=0;
633  ValueType bestInputVal = gm_.evalulate(args[0].begin(), args[0].end());
634  LabelVector argRes;
635  for(size_t i = 0; i<nInputs; ++i){
636 
637  const ValueType valA = gm_.evalulate(args[i].begin(), args[i].end());
638  if(ACC::bop(valA,bestInputVal)){
639  bestInputIndex = i;
640  bestInputVal = valA;
641  }
642  for(size_t j = i+1; j<nInputs; ++j){
643  const ValueType valB = gm_.evalulate(args[j].begin(), args[j].end());
644  const ValueType valRes = fuse2(args[i], args[j], argRes);
645  if(ACC::bop(valRes, valA) || ACC::bop(valRes, valB)){
646  improvedArgs.push_back(argRes);
647  }
648  }
649  }
650  if(improvedArgs.size()==0){
651  argRes = args[bestInputIndex];
652  return bestInputVal;
653  }
654  else if(improvedArgs.size()==1){
655  argRes = improvedArgs;
656  return gm_.evalulate(improvedArgs.begin(), improvedArgs.end());
657  }
658  else{
659  if(first==false)
660  args.clear();
661  return this->pairwiseFusionImpl(improvedArgs, argRes, first=false)
662  }
663  }
664 
665  const GM & gm_;
666  Fuse2 fuse2_;
667 
668 };
669 */
670 
671 template<class GM, class ACC>
673  :
674  gm_(gm),
675  subSpace_(gm.numberOfVariables(), 2),
676  localToGlobalVi_(gm.numberOfVariables()),
677  globalToLocalVi_(gm.numberOfVariables()),
678  nLocalVar_(0)
679 {
680 
681 }
682 
683 
684 template<class GM, class ACC>
686  const std::vector<typename FusionMover<GM, ACC>::LabelType> &argA,
687  const std::vector<typename FusionMover<GM, ACC>::LabelType> &argB,
688  std::vector<typename FusionMover<GM, ACC>::LabelType> &resultArg,
689  const typename FusionMover<GM, ACC>::ValueType valueA,
690  const typename FusionMover<GM, ACC>::ValueType valueB
691 )
692 {
693  nLocalVar_ = 0;
694  for (IndexType vi = 0; vi < gm_.numberOfVariables(); ++vi)
695  {
696  if (argA[vi] != argB[vi])
697  {
698  localToGlobalVi_[nLocalVar_] = vi;
699  globalToLocalVi_[vi] = nLocalVar_;
700  ++nLocalVar_;
701  }
702  }
703  std::copy(argA.begin(), argA.end(), resultArg.begin());
704 
705  // store pointers
706  argA_ = &argA;
707  argB_ = &argB;
708  argResult_ = &resultArg;
709 
710  valueA_ = valueA;
711  valueB_ = valueB;
712 
713  if (ACC::bop(valueA, valueB))
714  {
715  argBest_ = argA_;
716  valueBest_ = valueA;
717  bestLabel_ = 0;
718  }
719  else
720  {
721  argBest_ = argB_;
722  valueBest_ = valueB;
723  bestLabel_ = 1;
724  }
725 }
726 
727 
728 template<class GM, class ACC>
729 template<class MODEL_PROXY>
730 void FusionMover<GM, ACC>::fillSubModel(MODEL_PROXY &modelProxy)
731 {
732 
733 
734  OPENGM_CHECK_OP(nLocalVar_, > , 0, "nothing to fuse");
735 
736  modelProxy.createModel(nLocalVar_);
737  std::set<IndexType> addedFactors;
738  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
739  {
740 
741  const IndexType vi = localToGlobalVi_[lvi];
742  const IndexType nFacVi = gm_.numberOfFactors(vi);
743 
744  for (IndexType f = 0; f < nFacVi; ++f)
745  {
746  const IndexType fi = gm_.factorOfVariable(vi, f);
747  const IndexType fOrder = gm_.numberOfVariables(fi);
748 
749  // first order
750  if (fOrder == 1)
751  {
752  OPENGM_CHECK_OP( localToGlobalVi_[lvi], == , gm_[fi].variableIndex(0), "internal error");
753  OPENGM_CHECK_OP( globalToLocalVi_[gm_[fi].variableIndex(0)], == , lvi, "internal error");
754 
755  const IndexType vis[] = {lvi};
756  const IndexType globalVi = localToGlobalVi_[lvi];
757 
758  ArrayFunction f(subSpace_.begin(), subSpace_.begin() + 1);
759 
760 
761  const LabelType c[] = { (*argA_)[globalVi], (*argB_)[globalVi] };
762  f(0) = gm_[fi](c );
763  f(1) = gm_[fi](c + 1);
764 
765  //subGm_.addFactor(subGm_.addFunction(f),vis,vis+1);
766 
767  modelProxy.addFactor(f, vis, vis + 1);
768  }
769 
770  // high order
771  else if ( addedFactors.find(fi) == addedFactors.end() )
772  {
773  addedFactors.insert(fi);
774  IndexType fixedVar = 0;
775  IndexType notFixedVar = 0;
776 
777  for (IndexType vf = 0; vf < fOrder; ++vf)
778  {
779  const IndexType viFactor = gm_[fi].variableIndex(vf);
780  if ((*argA_)[viFactor] != (*argB_)[viFactor])
781  {
782  notFixedVar += 1;
783  }
784  else
785  {
786  fixedVar += 1;
787  }
788  }
789  OPENGM_CHECK_OP(notFixedVar, > , 0, "internal error");
790 
791 
792  if (fixedVar == 0)
793  {
794  OPENGM_CHECK_OP(notFixedVar, == , fOrder, "interal error")
795 
796  //std::cout<<"no fixations \n";
797 
798  // get local vis
799  std::vector<IndexType> lvis(fOrder);
800  for (IndexType vf = 0; vf < fOrder; ++vf)
801  {
802  lvis[vf] = globalToLocalVi_[gm_[fi].variableIndex(vf)];
803  }
804 
805  //std::cout<<"construct view\n";
806  FuseViewingFunction f(gm_[fi], *argA_, *argB_);
807 
808 
809 
810  //std::cout<<"add view\n";
811  //subGm_.addFactor(subGm_.addFunction(f),lvis.begin(),lvis.end());
812  modelProxy.addFactor(f, lvis.begin(), lvis.end());
813  //std::cout<<"done \n";
814 
815  }
816  else
817  {
818  OPENGM_CHECK_OP(notFixedVar + fixedVar, == , fOrder, "interal error")
819 
820  //std::cout<<"fixedVar "<<fixedVar<<"\n";
821  //std::cout<<"notFixedVar "<<notFixedVar<<"\n";
822 
823  // get local vis
824  std::vector<IndexType> lvis;
825  lvis.reserve(notFixedVar);
826  for (IndexType vf = 0; vf < fOrder; ++vf)
827  {
828  const IndexType gvi = gm_[fi].variableIndex(vf);
829  if ((*argA_)[gvi] != (*argB_)[gvi])
830  {
831  lvis.push_back(globalToLocalVi_[gvi]);
832  }
833  }
834  OPENGM_CHECK_OP(lvis.size(), == , notFixedVar, "internal error");
835 
836 
837  //std::cout<<"construct fix view\n";
838  FuseViewingFixingFunction f(gm_[fi], *argA_, *argB_);
839  //std::cout<<"add fix view\n";
840  modelProxy.addFactor(f, lvis.begin(), lvis.end());
841  //subGm_.addFactor(subGm_.addFunction(f),lvis.begin(),lvis.end());
842  //std::cout<<"done \n";
843 
844  }
845  }
846  }
847  }
848 }
849 
850 
851 
852 
853 template<class GM, class ACC>
854 template<class SOLVER>
855 typename FusionMover<GM, ACC>::ValueType
857  const typename SOLVER::Parameter &param,
858  const bool warmStart
859 )
860 {
861  //std::cout<<"fill sub gm ... "<<std::flush;
862  NativeModelProxy<SubGmType> modelProxy;
863  this->fillSubModel(modelProxy);
864  //std::cout<<"done!"<<std::endl;
865 
866 
867 
868  //std::cout<<"solve sub problem ... "<<std::flush;
869  SOLVER solver(*(modelProxy.model_), param);
870  std::vector<LabelType> localArg(nLocalVar_);
871  if (warmStart)
872  {
873  std::fill( localArg.begin(), localArg.end(),bestLabel_);
874  solver.setStartingPoint(localArg.begin());
875  }
876 
877  if(solver.infer()!=UNKNOWN){
878  solver.arg(localArg);
879  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
880  {
881  const IndexType globalVi = localToGlobalVi_[lvi];
882  const LabelType l = localArg[lvi];
883  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
884  }
885  valueResult_ = gm_.evaluate(*argResult_);
886  if (AccumulationType::bop(valueBest_, valueResult_))
887  {
888  valueResult_ = valueBest_;
889  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
890  }
891  }
892  else{
893  valueResult_ = valueBest_;
894  }
895  modelProxy.freeModel();
896  //std::cout<<"done!"<<std::endl;
897  return valueResult_;
898 }
899 
900 template<class GM, class ACC>
901 template<class SOLVER>
904  const typename SOLVER::Parameter &param
905 )
906 {
907  //std::cout<<"fill sub gm\n";
908  Ad3ModelProxy<SOLVER> modelProxy(param);
909  this->fillSubModel(modelProxy);
910 
911 
912 
913  std::vector<LabelType> localArg(nLocalVar_);
914  modelProxy.model_->infer();
915  modelProxy.model_->arg(localArg);
916 
917  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
918  {
919  const IndexType globalVi = localToGlobalVi_[lvi];
920  const LabelType l = localArg[lvi];
921  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
922  }
923  valueResult_ = gm_.evaluate(*argResult_);
924 
925  if (AccumulationType::bop(valueBest_, valueResult_))
926  {
927  valueResult_ = valueBest_;
928  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
929  }
930 
931  modelProxy.freeModel();
932  return valueResult_;
933 }
934 
935 
936 template<class GM, class ACC>
937 template<class SOLVER>
940 )
941 {
942  //std::cout<<"fill qbpo -2 order model\n";
943  QpboModelProxy<SOLVER> modelProxy;
944  this->fillSubModel(modelProxy);
945  //std::cout<<"done\n";
946 
947  modelProxy.model_->MergeParallelEdges();
948 
949  // set label for qpbo improvement
950  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
951  {
952  const IndexType globalVi = localToGlobalVi_[lvi];
953  modelProxy.model_->SetLabel(lvi, bestLabel_);
954  }
955 
956  // do qpbo improvment
957  srand( 42 );
958  modelProxy.model_->Improve();
959 
960  // get result arg
961  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
962  {
963  const IndexType globalVi = localToGlobalVi_[lvi];
964  const LabelType l = modelProxy.model_->GetLabel(lvi);
965  if (l == 0 || l == 1)
966  {
967  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
968  }
969  else
970  {
971  (*argResult_)[globalVi] = (*argBest_)[globalVi];
972  }
973  }
974  valueResult_ = gm_.evaluate(*argResult_);
975  if (AccumulationType::bop(valueBest_, valueResult_))
976  {
977  valueResult_ = valueBest_;
978  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
979  }
980  modelProxy.freeModel();
981  return valueResult_;
982 }
983 
984 
985 template<class GM, class ACC>
986 template<class SOLVER>
989 
990 )
991 {
992 
993  //std::cout<<"fill native for qbpo fix reduction model\n";
994  NativeModelProxy<SubGmType> modelProxy;
995  this->fillSubModel(modelProxy);
996 
997  const SubGmType &subGm = *(modelProxy.model_);
998 
999  // DO MOVE
1000  unsigned int maxNumAssignments = 1 << maxOrder_;
1001  std::vector<ValueType> coeffs(maxNumAssignments);
1002  std::vector<LabelType> cliqueLabels(maxOrder_);
1003 
1004  HigherOrderEnergy<ValueType, maxOrder_> hoe;
1005  hoe.AddVars(subGm.numberOfVariables());
1006  for (IndexType f = 0; f < subGm.numberOfFactors(); ++f)
1007  {
1008  IndexType size = subGm[f].numberOfVariables();
1009  if (size == 0)
1010  {
1011  continue;
1012  }
1013  else if (size == 1)
1014  {
1015  IndexType var = subGm[f].variableIndex(0);
1016 
1017  const LabelType lla[] = {0};
1018  const LabelType llb[] = {1};
1019 
1020 
1021  ValueType e0 = subGm[f](lla);
1022  ValueType e1 = subGm[f](llb);
1023  hoe.AddUnaryTerm(var, e1 - e0);
1024  }
1025  else
1026  {
1027 
1028  // unsigned int numAssignments = std::pow(2,size);
1029  unsigned int numAssignments = 1 << size;
1030 
1031 
1032  // -- // ValueType coeffs[numAssignments];
1033  for (unsigned int subset = 1; subset < numAssignments; ++subset)
1034  {
1035  coeffs[subset] = 0;
1036  }
1037  // For each boolean assignment, get the clique energy at the
1038  // corresponding labeling
1039  // -- // LabelType cliqueLabels[size];
1040  for (unsigned int assignment = 0; assignment < numAssignments; ++assignment)
1041  {
1042  for (unsigned int i = 0; i < size; ++i)
1043  {
1044  //if ( assignment%2 == (std::pow(2,i))%2 )
1045  if (assignment & (1 << i))
1046  {
1047  cliqueLabels[i] = 0;
1048  }
1049  else
1050  {
1051  cliqueLabels[i] = 1;
1052  }
1053  }
1054  ValueType energy = subGm[f](cliqueLabels.begin());
1055  for (unsigned int subset = 1; subset < numAssignments; ++subset)
1056  {
1057  // if (assigment%2 != subset%2)
1058  if (assignment & ~subset)
1059  {
1060  continue;
1061  }
1062  //(assigment%2 == subset%2)
1063  else
1064  {
1065  int parity = 0;
1066  for (unsigned int b = 0; b < size; ++b)
1067  {
1068  parity ^= (((assignment ^ subset) & (1 << b)) != 0);
1069  }
1070  coeffs[subset] += parity ? -energy : energy;
1071  }
1072  }
1073  }
1074  typename HigherOrderEnergy<ValueType, maxOrder_> ::VarId vars[maxOrder_];
1075  for (unsigned int subset = 1; subset < numAssignments; ++subset)
1076  {
1077  int degree = 0;
1078  for (unsigned int b = 0; b < size; ++b)
1079  {
1080  if (subset & (1 << b))
1081  {
1082  vars[degree++] = subGm[f].variableIndex(b);
1083  }
1084  }
1085  std::sort(vars, vars + degree);
1086  hoe.AddTerm(coeffs[subset], degree, vars);
1087  }
1088  }
1089  }
1090  SOLVER qr(subGm.numberOfVariables(), 0);
1091  hoe.ToQuadratic(qr);
1092  qr.Solve();
1093  IndexType numberOfChangedVariables = 0;
1094 
1095 
1096  // get result arg
1097  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
1098  {
1099  const IndexType globalVi = localToGlobalVi_[lvi];
1100  const LabelType l = qr.GetLabel(lvi);
1101  if (l == 0 || l == 1)
1102  {
1103  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
1104  }
1105  else
1106  {
1107  (*argResult_)[globalVi] = (*argBest_)[globalVi];
1108  }
1109  }
1110  valueResult_ = gm_.evaluate(*argResult_);
1111  if (AccumulationType::bop(valueBest_, valueResult_))
1112  {
1113  valueResult_ = valueBest_;
1114  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
1115  }
1116  modelProxy.freeModel();
1117  return valueResult_;
1118 }
1119 
1120 
1121 
1122 }
1123 
1124 #endif //OPENGM_AUX_FUSION_MOVER_HXX
ValueType fuseAd3(const typename SOLVER::Parameter &param)
Parameter(const FusionSolver fusionSolver=DefaulFusion, const size_t maxSubgraphSize=2, const bool reducedInf=false, const bool tentacles=false, const bool connectedComponents=false, const double fusionTimeLimit=100.0)
The OpenGM namespace.
Definition: config.hxx:43
ValueType valueB() const
Fallback implementation of member functions of OpenGM functions.
ValueType valueA() const
FusionMover< GraphicalModelType, AccumulationType > FusionMoverType
ViewFixVariablesFunction< GM > FixFunction
GM::OperatorType OperatorType
IndexType shape(const IndexType) const
Ad3ModelProxy(const typename MODEL_TYPE::Parameter param)
Discrete space in which all variables have the same number of labels.
ValueType operator()(Iterator begin) const
FuseViewFunction(const FactorType &factor, const std::vector< LabelType > &argA, const std::vector< LabelType > &argB)
STL namespace.
FusionMoverType::SubGmType SubGmType
ExplicitFunction< ValueType, IndexType, LabelType > ArrayFunction
void createModel(const UInt64Type nVar)
void addFactor(const F &f, ITER viBegin, ITER viEnd)
FusionMover(const GM &gm)
IndexType numberOfFusionMoveVariable() const
ValueType valueResult() const
FuseViewFunction< GM > FuseViewingFunction
GM::FactorType FactorType
detail_types::UInt64Type UInt64Type
uint64
Definition: config.hxx:300
meta::TypeListGenerator< FuseViewingFunction, FuseViewingFixingFunction, ArrayFunction >::type SubFunctionTypeList
ValueType fuseFixQpbo()
GraphicalModel< ValueType, typename GM::OperatorType, SubFunctionTypeList, SubSpaceType > SubGmType
MODEL_TYPE::SpaceType SpaceType
ValueType operator()(Iterator begin) const
opengm::SimpleDiscreteSpace< IndexType, LabelType > SubSpaceType
Optimization by Linear Programming (LP) or Integer LP using IBM ILOG CPLEX http://www.ilog.com/products/cplex/.
Definition: lpcplex.hxx:38
FuseViewFixFunction(const FactorType &factor, const std::vector< LabelType > &argA, const std::vector< LabelType > &argB)
bool fuse(const LabelVector &argA, const LabelVector argB, LabelVector &argRes, const ValueType valA, const ValueType valB, ValueType &valRes)
FuseViewFixFunction< GM > FuseViewingFixingFunction
IndexType dimension() const
HQPBO Algorithm .
Definition: hqpbo.hxx:22
void setup(const std::vector< LabelType > &argA, const std::vector< LabelType > &argB, std::vector< LabelType > &resultArg, const ValueType valueA, const ValueType valueB)
IndexType size() const
std::vector< LabelType > LabelVector
HlFusionMover(const GM &gm, const Parameter &param)
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Definition: submodel2.hxx:24
GM::OperatorType OperatorType
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
IndexType numberOfVariables() const
A generalization of ICM B. Andres, J. H. Kappes, U. Koethe and Hamprecht F. A., The Lazy Flipper: MA...
MODEL_TYPE::Parameter param_
void addFactor(const F &f, ITER viBegin, ITER viEnd)
ValueType fuse(const typename SOLVER::Parameter &param, const bool warmStart=false)
[class reducedinference] Reduced Inference Implementation of the reduction techniques proposed in J...
void addFactor(const F &f, ITER viBegin, ITER viEnd)
IndexType numberOfFactors() const
OpenGM runtime error.
Definition: opengm.hxx:100
opengm::LazyFlipper< SubGmType, AccumulationType > LazyFlipperSubInf
void createModel(const UInt64Type nVar)
void createModel(const UInt64Type nVar)
IndexType shape(const IndexType) const
IndexType dimension() const