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_;
265  UInt64Type c00_[2];
266  UInt64Type c11_[2];
267  UInt64Type c01_[2];
268  UInt64Type c10_[2];
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 
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 
362  {
363  return valueResult_;
364  }
366  {
367  return valueA_;
368  }
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 
409  template<class _GM>
410  struct RebindGm{
412  };
413 
414  template<class _GM,class _ACC>
417  };
418 
419 
420  typedef GM GraphicalModelType;
421  typedef ACC AccumulationType;
423 
424 
427 
428 
429  #ifdef WITH_QPBO
430  typedef kolmogorov::qpbo::QPBO<double> QpboSubInf;
431  //typedef opengm::external::QPBO<SubGmType> QPBOSubInf;
432  typedef opengm::HQPBO<SubGmType,AccumulationType> HQPBOSubInf;
433  typedef typename ReducedInferenceHelper<SubGmType>::InfGmType ReducedGmType;
434  #endif
435  #ifdef WITH_CPLEX
437  #endif
438 
440 
441 
442  typedef std::vector<LabelType> LabelVector;
443 
448  CplexFuison
449  };
450 
451  struct Parameter{
453  const FusionSolver fusionSolver=DefaulFusion,
454  const size_t maxSubgraphSize = 2,
455  const bool reducedInf = false,
456  const bool tentacles = false,
457  const bool connectedComponents = false,
458  const double fusionTimeLimit = 100.0
459  )
460  :
461  fusionSolver_(fusionSolver),
462  maxSubgraphSize_(maxSubgraphSize),
463  reducedInf_(reducedInf),
464  connectedComponents_(connectedComponents),
465  tentacles_(tentacles),
466  fusionTimeLimit_(fusionTimeLimit)
467  {
468 
469  }
470 
471  template<class P>
472  Parameter(const P & p)
473  :
474  fusionSolver_(p.fusionSolver_),
475  maxSubgraphSize_(p.maxSubgraphSize_),
476  reducedInf_(p.reducedInf_),
477  connectedComponents_(p.connectedComponents_),
478  tentacles_(p.tentacles_),
479  fusionTimeLimit_(p.fusionTimeLimit_)
480  {
481 
482  }
483 
484 
491  };
492 
493  HlFusionMover(const GM & gm, const Parameter & param)
494  : gm_(gm),
495  param_(param),
496  fusionMover_(gm),
497  factorOrder_(gm.factorOrder()) {
498 
499  // set default fusion mover
500  if(param_.fusionSolver_==DefaulFusion){
501  param_.fusionSolver_= LazyFlipperFusion;
502  #ifdef WITH_QPBO
503  param_.fusionSolver_ = QpboFusion;
504  #endif
505  }
506 
507 
508  // check
509  if(param_.fusionSolver_ == QpboFusion){
510  #ifndef WITH_QPBO
511  throw RuntimeError("WITH_QPBO need to be enabled for QpboFusion");
512  #endif
513  }
514  if(param_.fusionSolver_ == CplexFuison){
515  #ifndef WITH_CPLEX
516  throw RuntimeError("WITH_CPLEX need to be enabled for CplexFusion");
517  #endif
518  }
519  if(param_.reducedInf_){
520  #ifndef WITH_QPBO
521  throw RuntimeError("WITH_QPBO need to be enabled for reducedInference");
522  #endif
523  }
524 
525  }
526 
527 
528  bool fuse(const LabelVector & argA, const LabelVector argB, LabelVector & argRes,
529  const ValueType valA, const ValueType valB,ValueType & valRes){
530 
531  fusionMover_.setup(argA, argB, argRes, valA, valB);
532 
533 
534 
535  if(fusionMover_.numberOfFusionMoveVariable()>0){
536  if(param_.fusionSolver_ == QpboFusion){
537  #ifdef WITH_QPBO
538  if(factorOrder_<=2){
539  valRes = fusionMover_. template fuseQpbo<QpboSubInf> ();
540  }
541  else{
542  typename HQPBOSubInf::Parameter subInfParam;
543  valRes = fusionMover_. template fuse<HQPBOSubInf> (subInfParam,true);
544  }
545  #endif
546  }
547  else if(param_.fusionSolver_ == CplexFuison){
548  #ifdef WITH_CPLEX
549  // with reduced inference
550  if(param_.reducedInf_){
551  #ifdef WITH_QPBO
554  typename _CplexSubInf::Parameter _subInfParam;
555  _subInfParam.integerConstraint_ = true;
556  _subInfParam.numberOfThreads_ = 1;
557  _subInfParam.timeLimit_ = param_.fusionTimeLimit_;
558  typename CplexReducedSubInf::Parameter subInfParam(true,param_.tentacles_,param_.connectedComponents_,_subInfParam);
559  valRes = fusionMover_. template fuse<CplexReducedSubInf> (subInfParam,true);
560  #endif
561  }
562  // without reduced inference
563  else{
564  typename CplexSubInf::Parameter p;
565  p.integerConstraint_ = true;
566  p.numberOfThreads_ = 1;
567  p.timeLimit_ = param_.fusionTimeLimit_;
568  valRes = fusionMover_. template fuse<CplexSubInf> (p,true);
569  }
570  #endif
571  }
572  else if(param_.fusionSolver_ == LazyFlipperFusion){
573  if(param_.reducedInf_){
574  #ifdef WITH_QPBO
577  typename _LfSubInf::Parameter _subInfParam;
578  _subInfParam.maxSubgraphSize_= param_.maxSubgraphSize_;
579  typename LfReducedSubInf::Parameter subInfParam(true,param_.tentacles_,param_.connectedComponents_,_subInfParam);
580  valRes = fusionMover_. template fuse<LfReducedSubInf> (subInfParam,true);
581  #endif
582  }
583  else{
584  const typename LazyFlipperSubInf::Parameter fuseInfParam(param_.maxSubgraphSize_);
585  valRes = fusionMover_. template fuse<LazyFlipperSubInf> (fuseInfParam, true);
586  }
587  }
588  else{
589  throw RuntimeError("Unknown Fusion Type! Maybe caused by missing linking!");
590  }
591  return true;
592  }
593  else{
594  return false;
595  }
596  }
597 
598 private:
599  const GraphicalModelType & gm_;
600  Parameter param_;
601  FusionMoverType fusionMover_;
602  size_t factorOrder_;
603 };
604 
605 
606 
607 
608 /*
609 template<class GM, class ACC>
610 class MultiFusion{
611 
612 public:
613  typedef GM GraphicalModelType;
614  typedef ACC AccumulationType;
615  OPENGM_GM_TYPE_TYPEDEFS;
616 
617  typedef HlFusionMover<GraphicalModelType, AccumulationType> Fuse2;
618  typedef typename Fuse2::Parameter Fuse2Parameter;
619  typedef std::vector<LabelType> LabelVector;
620  enum MultiFusionMode{
621  Default,
622  PairwiseBest
623  };
624 
625 
626  struct Parameter{
627  Parameter(
628  const Fuse2Parameter & fuse2Param = Fuse2Parameter()
629  )
630  :
631  fuse2Param_(fuse2Param_){
632 
633  }
634 
635  Fuse2Parameter fuse2Param_;
636  };
637 
638  HlFusionMover<GM, ACC> fuse2_;
639 
640 
641  ValueType pairwiseFusion( const std::vector<LabelVector> & args
642  LabelVector & argRes){
643 
644  std::vector<LabelVector> * argsPtr = const_cast< const std::vector<LabelVector> * >(&args);
645  return pairwiseFusionImpl(*argsPtr, argRes,true);
646 
647  }
648 
649 private:
650  ValueType pairwiseFusionImpl( std::vector<LabelVector> & args
651  LabelVector & argRes,
652  bool first=true
653  ){
654 
655 
656  std::vector<LabelVector> improvedArgs;
657  size_t nInputs = args.size();
658 
659  size_t bestInputIndex=0;
660  ValueType bestInputVal = gm_.evalulate(args[0].begin(), args[0].end());
661  LabelVector argRes;
662  for(size_t i = 0; i<nInputs; ++i){
663 
664  const ValueType valA = gm_.evalulate(args[i].begin(), args[i].end());
665  if(ACC::bop(valA,bestInputVal)){
666  bestInputIndex = i;
667  bestInputVal = valA;
668  }
669  for(size_t j = i+1; j<nInputs; ++j){
670  const ValueType valB = gm_.evalulate(args[j].begin(), args[j].end());
671  const ValueType valRes = fuse2(args[i], args[j], argRes);
672  if(ACC::bop(valRes, valA) || ACC::bop(valRes, valB)){
673  improvedArgs.push_back(argRes);
674  }
675  }
676  }
677  if(improvedArgs.size()==0){
678  argRes = args[bestInputIndex];
679  return bestInputVal;
680  }
681  else if(improvedArgs.size()==1){
682  argRes = improvedArgs;
683  return gm_.evalulate(improvedArgs.begin(), improvedArgs.end());
684  }
685  else{
686  if(first==false)
687  args.clear();
688  return this->pairwiseFusionImpl(improvedArgs, argRes, first=false)
689  }
690  }
691 
692  const GM & gm_;
693  Fuse2 fuse2_;
694 
695 };
696 */
697 
698 template<class GM, class ACC>
700  :
701  gm_(gm),
702  subSpace_(gm.numberOfVariables(), 2),
703  localToGlobalVi_(gm.numberOfVariables()),
704  globalToLocalVi_(gm.numberOfVariables()),
705  nLocalVar_(0)
706 {
707 
708 }
709 
710 
711 template<class GM, class ACC>
713  const std::vector<typename FusionMover<GM, ACC>::LabelType> &argA,
714  const std::vector<typename FusionMover<GM, ACC>::LabelType> &argB,
715  std::vector<typename FusionMover<GM, ACC>::LabelType> &resultArg,
716  const typename FusionMover<GM, ACC>::ValueType valueA,
717  const typename FusionMover<GM, ACC>::ValueType valueB
718 )
719 {
720  nLocalVar_ = 0;
721  for (IndexType vi = 0; vi < gm_.numberOfVariables(); ++vi)
722  {
723  if (argA[vi] != argB[vi])
724  {
725  localToGlobalVi_[nLocalVar_] = vi;
726  globalToLocalVi_[vi] = nLocalVar_;
727  ++nLocalVar_;
728  }
729  }
730  std::copy(argA.begin(), argA.end(), resultArg.begin());
731 
732  // store pointers
733  argA_ = &argA;
734  argB_ = &argB;
735  argResult_ = &resultArg;
736 
737  valueA_ = valueA;
738  valueB_ = valueB;
739 
740  if (ACC::bop(valueA, valueB))
741  {
742  argBest_ = argA_;
743  valueBest_ = valueA;
744  bestLabel_ = 0;
745  }
746  else
747  {
748  argBest_ = argB_;
749  valueBest_ = valueB;
750  bestLabel_ = 1;
751  }
752 }
753 
754 
755 template<class GM, class ACC>
756 template<class MODEL_PROXY>
757 void FusionMover<GM, ACC>::fillSubModel(MODEL_PROXY &modelProxy)
758 {
759 
760 
761  OPENGM_CHECK_OP(nLocalVar_, > , 0, "nothing to fuse");
762 
763  modelProxy.createModel(nLocalVar_);
764  std::set<IndexType> addedFactors;
765  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
766  {
767 
768  const IndexType vi = localToGlobalVi_[lvi];
769  const IndexType nFacVi = gm_.numberOfFactors(vi);
770 
771  for (IndexType f = 0; f < nFacVi; ++f)
772  {
773  const IndexType fi = gm_.factorOfVariable(vi, f);
774  const IndexType fOrder = gm_.numberOfVariables(fi);
775 
776  // first order
777  if (fOrder == 1)
778  {
779  OPENGM_CHECK_OP( localToGlobalVi_[lvi], == , gm_[fi].variableIndex(0), "internal error");
780  OPENGM_CHECK_OP( globalToLocalVi_[gm_[fi].variableIndex(0)], == , lvi, "internal error");
781 
782  const IndexType vis[] = {lvi};
783  const IndexType globalVi = localToGlobalVi_[lvi];
784 
785  ArrayFunction f(subSpace_.begin(), subSpace_.begin() + 1);
786 
787 
788  const LabelType c[] = { (*argA_)[globalVi], (*argB_)[globalVi] };
789  f(0) = gm_[fi](c );
790  f(1) = gm_[fi](c + 1);
791 
792  //subGm_.addFactor(subGm_.addFunction(f),vis,vis+1);
793 
794  modelProxy.addFactor(f, vis, vis + 1);
795  }
796 
797  // high order
798  else if ( addedFactors.find(fi) == addedFactors.end() )
799  {
800  addedFactors.insert(fi);
801  IndexType fixedVar = 0;
802  IndexType notFixedVar = 0;
803 
804  for (IndexType vf = 0; vf < fOrder; ++vf)
805  {
806  const IndexType viFactor = gm_[fi].variableIndex(vf);
807  if ((*argA_)[viFactor] != (*argB_)[viFactor])
808  {
809  notFixedVar += 1;
810  }
811  else
812  {
813  fixedVar += 1;
814  }
815  }
816  OPENGM_CHECK_OP(notFixedVar, > , 0, "internal error");
817 
818 
819  if (fixedVar == 0)
820  {
821  OPENGM_CHECK_OP(notFixedVar, == , fOrder, "interal error")
822 
823  //std::cout<<"no fixations \n";
824 
825  // get local vis
826  std::vector<IndexType> lvis(fOrder);
827  for (IndexType vf = 0; vf < fOrder; ++vf)
828  {
829  lvis[vf] = globalToLocalVi_[gm_[fi].variableIndex(vf)];
830  }
831 
832  //std::cout<<"construct view\n";
833  FuseViewingFunction f(gm_[fi], *argA_, *argB_);
834 
835 
836 
837  //std::cout<<"add view\n";
838  //subGm_.addFactor(subGm_.addFunction(f),lvis.begin(),lvis.end());
839  modelProxy.addFactor(f, lvis.begin(), lvis.end());
840  //std::cout<<"done \n";
841 
842  }
843  else
844  {
845  OPENGM_CHECK_OP(notFixedVar + fixedVar, == , fOrder, "interal error")
846 
847  //std::cout<<"fixedVar "<<fixedVar<<"\n";
848  //std::cout<<"notFixedVar "<<notFixedVar<<"\n";
849 
850  // get local vis
851  std::vector<IndexType> lvis;
852  lvis.reserve(notFixedVar);
853  for (IndexType vf = 0; vf < fOrder; ++vf)
854  {
855  const IndexType gvi = gm_[fi].variableIndex(vf);
856  if ((*argA_)[gvi] != (*argB_)[gvi])
857  {
858  lvis.push_back(globalToLocalVi_[gvi]);
859  }
860  }
861  OPENGM_CHECK_OP(lvis.size(), == , notFixedVar, "internal error");
862 
863 
864  //std::cout<<"construct fix view\n";
865  FuseViewingFixingFunction f(gm_[fi], *argA_, *argB_);
866  //std::cout<<"add fix view\n";
867  modelProxy.addFactor(f, lvis.begin(), lvis.end());
868  //subGm_.addFactor(subGm_.addFunction(f),lvis.begin(),lvis.end());
869  //std::cout<<"done \n";
870 
871  }
872  }
873  }
874  }
875 }
876 
877 
878 
879 
880 template<class GM, class ACC>
881 template<class SOLVER>
884  const typename SOLVER::Parameter &param,
885  const bool warmStart
886 )
887 {
888  //std::cout<<"fill sub gm ... "<<std::flush;
889  NativeModelProxy<SubGmType> modelProxy;
890  this->fillSubModel(modelProxy);
891  //std::cout<<"done!"<<std::endl;
892 
893 
894 
895  //std::cout<<"solve sub problem ... "<<std::flush;
896  SOLVER solver(*(modelProxy.model_), param);
897  std::vector<LabelType> localArg(nLocalVar_);
898  if (warmStart)
899  {
900  std::fill( localArg.begin(), localArg.end(),bestLabel_);
901  solver.setStartingPoint(localArg.begin());
902  }
903 
904  if(solver.infer()!=UNKNOWN){
905  solver.arg(localArg);
906  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
907  {
908  const IndexType globalVi = localToGlobalVi_[lvi];
909  const LabelType l = localArg[lvi];
910  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
911  }
912  valueResult_ = gm_.evaluate(*argResult_);
913  if (AccumulationType::bop(valueBest_, valueResult_))
914  {
915  valueResult_ = valueBest_;
916  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
917  }
918  }
919  else{
920  valueResult_ = valueBest_;
921  }
922  modelProxy.freeModel();
923  //std::cout<<"done!"<<std::endl;
924  return valueResult_;
925 }
926 
927 template<class GM, class ACC>
928 template<class SOLVER>
931  const typename SOLVER::Parameter &param
932 )
933 {
934  //std::cout<<"fill sub gm\n";
935  Ad3ModelProxy<SOLVER> modelProxy(param);
936  this->fillSubModel(modelProxy);
937 
938 
939 
940  std::vector<LabelType> localArg(nLocalVar_);
941  modelProxy.model_->infer();
942  modelProxy.model_->arg(localArg);
943 
944  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
945  {
946  const IndexType globalVi = localToGlobalVi_[lvi];
947  const LabelType l = localArg[lvi];
948  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
949  }
950  valueResult_ = gm_.evaluate(*argResult_);
951 
952  if (AccumulationType::bop(valueBest_, valueResult_))
953  {
954  valueResult_ = valueBest_;
955  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
956  }
957 
958  modelProxy.freeModel();
959  return valueResult_;
960 }
961 
962 
963 template<class GM, class ACC>
964 template<class SOLVER>
967 )
968 {
969  //std::cout<<"fill qbpo -2 order model\n";
970  QpboModelProxy<SOLVER> modelProxy;
971  this->fillSubModel(modelProxy);
972  //std::cout<<"done\n";
973 
974  modelProxy.model_->MergeParallelEdges();
975 
976  // set label for qpbo improvement
977  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
978  {
979  const IndexType globalVi = localToGlobalVi_[lvi];
980  modelProxy.model_->SetLabel(lvi, bestLabel_);
981  }
982 
983  // do qpbo improvment
984  srand( 42 );
985  modelProxy.model_->Improve();
986 
987  // get result arg
988  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
989  {
990  const IndexType globalVi = localToGlobalVi_[lvi];
991  const LabelType l = modelProxy.model_->GetLabel(lvi);
992  if (l == 0 || l == 1)
993  {
994  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
995  }
996  else
997  {
998  (*argResult_)[globalVi] = (*argBest_)[globalVi];
999  }
1000  }
1001  valueResult_ = gm_.evaluate(*argResult_);
1002  if (AccumulationType::bop(valueBest_, valueResult_))
1003  {
1004  valueResult_ = valueBest_;
1005  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
1006  }
1007  modelProxy.freeModel();
1008  return valueResult_;
1009 }
1010 
1011 
1012 template<class GM, class ACC>
1013 template<class SOLVER>
1016 
1017 )
1018 {
1019 
1020  //std::cout<<"fill native for qbpo fix reduction model\n";
1021  NativeModelProxy<SubGmType> modelProxy;
1022  this->fillSubModel(modelProxy);
1023 
1024  const SubGmType &subGm = *(modelProxy.model_);
1025 
1026  // DO MOVE
1027  unsigned int maxNumAssignments = 1 << maxOrder_;
1028  std::vector<ValueType> coeffs(maxNumAssignments);
1029  std::vector<LabelType> cliqueLabels(maxOrder_);
1030 
1031  HigherOrderEnergy<ValueType, maxOrder_> hoe;
1032  hoe.AddVars(subGm.numberOfVariables());
1033  for (IndexType f = 0; f < subGm.numberOfFactors(); ++f)
1034  {
1035  IndexType size = subGm[f].numberOfVariables();
1036  if (size == 0)
1037  {
1038  continue;
1039  }
1040  else if (size == 1)
1041  {
1042  IndexType var = subGm[f].variableIndex(0);
1043 
1044  const LabelType lla[] = {0};
1045  const LabelType llb[] = {1};
1046 
1047 
1048  ValueType e0 = subGm[f](lla);
1049  ValueType e1 = subGm[f](llb);
1050  hoe.AddUnaryTerm(var, e1 - e0);
1051  }
1052  else
1053  {
1054 
1055  // unsigned int numAssignments = std::pow(2,size);
1056  unsigned int numAssignments = 1 << size;
1057 
1058 
1059  // -- // ValueType coeffs[numAssignments];
1060  for (unsigned int subset = 1; subset < numAssignments; ++subset)
1061  {
1062  coeffs[subset] = 0;
1063  }
1064  // For each boolean assignment, get the clique energy at the
1065  // corresponding labeling
1066  // -- // LabelType cliqueLabels[size];
1067  for (unsigned int assignment = 0; assignment < numAssignments; ++assignment)
1068  {
1069  for (unsigned int i = 0; i < size; ++i)
1070  {
1071  //if ( assignment%2 == (std::pow(2,i))%2 )
1072  if (assignment & (1 << i))
1073  {
1074  cliqueLabels[i] = 0;
1075  }
1076  else
1077  {
1078  cliqueLabels[i] = 1;
1079  }
1080  }
1081  ValueType energy = subGm[f](cliqueLabels.begin());
1082  for (unsigned int subset = 1; subset < numAssignments; ++subset)
1083  {
1084  // if (assigment%2 != subset%2)
1085  if (assignment & ~subset)
1086  {
1087  continue;
1088  }
1089  //(assigment%2 == subset%2)
1090  else
1091  {
1092  int parity = 0;
1093  for (unsigned int b = 0; b < size; ++b)
1094  {
1095  parity ^= (((assignment ^ subset) & (1 << b)) != 0);
1096  }
1097  coeffs[subset] += parity ? -energy : energy;
1098  }
1099  }
1100  }
1101  typename HigherOrderEnergy<ValueType, maxOrder_> ::VarId vars[maxOrder_];
1102  for (unsigned int subset = 1; subset < numAssignments; ++subset)
1103  {
1104  int degree = 0;
1105  for (unsigned int b = 0; b < size; ++b)
1106  {
1107  if (subset & (1 << b))
1108  {
1109  vars[degree++] = subGm[f].variableIndex(b);
1110  }
1111  }
1112  std::sort(vars, vars + degree);
1113  hoe.AddTerm(coeffs[subset], degree, vars);
1114  }
1115  }
1116  }
1117  SOLVER qr(subGm.numberOfVariables(), 0);
1118  hoe.ToQuadratic(qr);
1119  qr.Solve();
1120  IndexType numberOfChangedVariables = 0;
1121 
1122 
1123  // get result arg
1124  for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
1125  {
1126  const IndexType globalVi = localToGlobalVi_[lvi];
1127  const LabelType l = qr.GetLabel(lvi);
1128  if (l == 0 || l == 1)
1129  {
1130  (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
1131  }
1132  else
1133  {
1134  (*argResult_)[globalVi] = (*argBest_)[globalVi];
1135  }
1136  }
1137  valueResult_ = gm_.evaluate(*argResult_);
1138  if (AccumulationType::bop(valueBest_, valueResult_))
1139  {
1140  valueResult_ = valueBest_;
1141  std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
1142  }
1143  modelProxy.freeModel();
1144  return valueResult_;
1145 }
1146 
1147 
1148 
1149 }
1150 
1151 #endif //OPENGM_AUX_FUSION_MOVER_HXX
IndexType numberOfFusionMoveVariable() const
IndexType numberOfFactors() const
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
Fallback implementation of member functions of OpenGM functions.
IndexType shape(const IndexType) 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.
HlFusionMover< _GM, ACC > type
FuseViewFunction(const FactorType &factor, const std::vector< LabelType > &argA, const std::vector< LabelType > &argB)
FusionMoverType::SubGmType SubGmType
IndexType size() const
ExplicitFunction< ValueType, IndexType, LabelType > ArrayFunction
void createModel(const UInt64Type nVar)
void addFactor(const F &f, ITER viBegin, ITER viEnd)
FusionMover(const GM &gm)
FuseViewFunction< GM > FuseViewingFunction
GM::FactorType FactorType
detail_types::UInt64Type UInt64Type
uint64
Definition: config.hxx:300
meta::TypeListGenerator< FuseViewingFunction, FuseViewingFixingFunction, ArrayFunction >::type SubFunctionTypeList
GraphicalModel< ValueType, typename GM::OperatorType, SubFunctionTypeList, SubSpaceType > SubGmType
ValueType operator()(Iterator begin) const
MODEL_TYPE::SpaceType SpaceType
ValueType valueA() const
opengm::SimpleDiscreteSpace< IndexType, LabelType > SubSpaceType
IndexType dimension() const
Optimization by Linear Programming (LP) or Integer LP using IBM ILOG CPLEX http://www.ilog.com/products/cplex/.
Definition: lpcplex.hxx:38
ValueType valueResult() const
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 numberOfVariables() const
HQPBO Algorithm .
Definition: hqpbo.hxx:22
std::vector< LabelType > LabelVector
HlFusionMover(const GM &gm, const Parameter &param)
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Definition: submodel2.hxx:24
ValueType operator()(Iterator begin) const
ValueType valueB() const
GM::OperatorType OperatorType
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
IndexType dimension() 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)
[class reducedinference] Reduced Inference Implementation of the reduction techniques proposed in J...
void addFactor(const F &f, ITER viBegin, ITER viEnd)
HlFusionMover< _GM, _ACC > type
OpenGM runtime error.
Definition: opengm.hxx:100
opengm::LazyFlipper< SubGmType, AccumulationType > LazyFlipperSubInf
void createModel(const UInt64Type nVar)
void createModel(const UInt64Type nVar)