OpenGM  2.3.x
Discrete Graphical Model Library
permutable_label_fusion_mover.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_PERMUTABLE_LABEL_FUSION_MOVER_HXX
2 #define OPENGM_PERMUTABLE_LABEL_FUSION_MOVER_HXX
3 
4 
9 
10 // FIXME
11 #include <opengm/inference/cgc.hxx>
12 
16 
17 
18 #ifndef NOVIGRA
19 
20 #ifdef WITH_BOOST
21  #ifndef WITH_BOOST_GRAPH
22  #define WITH_BOOST_GRAPH
23  #endif
24 #endif
25 
26 #include <vigra/adjacency_list_graph.hxx>
27 #include <vigra/merge_graph_adaptor.hxx>
28 #include <vigra/hierarchical_clustering.hxx>
29 #include <vigra/priority_queue.hxx>
30 #include <vigra/random.hxx>
31 #include <vigra/graph_algorithms.hxx>
32 
33 #endif
34 
35 namespace opengm{
36 
37 
38 
39 
40 
41 
42 
43  #ifndef NOVIGRA
44  template<class GM, class ACC >
45  class McClusterOp{
46  public:
47  typedef ACC AccumulationType;
48  typedef GM GraphicalModelType;
50 
51  typedef vigra::AdjacencyListGraph Graph;
52  typedef vigra::MergeGraphAdaptor< Graph > MergeGraph;
53 
54 
55  typedef typename MergeGraph::Edge Edge;
56  typedef ValueType WeightType;
57  typedef IndexType index_type;
58  struct Parameter
59  {
60 
61 
62 
64  const float stopWeight = 0.0
65  )
66  :
67  stopWeight_(stopWeight){
68  }
69  float stopWeight_;
70  };
71 
72 
73  McClusterOp(const Graph & graph ,
74  MergeGraph & mergegraph,
75  const Parameter & param,
76  std::vector<ValueType> & weights
77  )
78  :
79  graph_(graph),
80  mergeGraph_(mergegraph),
81  pq_(graph.edgeNum()),
82  param_(param),
83  weights_(weights){
84 
85  for(size_t i=0; i<graph_.edgeNum(); ++i){
86  size_t u = graph_.id(graph_.u(graph_.edgeFromId(i)));
87  size_t v = graph_.id(graph_.v(graph_.edgeFromId(i)));
88  pq_.push(i, weights_[i]);
89  }
90  }
91 
92 
93 
94 
95  void reset(){
96  pq_.reset();
97  }
98 
99 
100 
102  index_type minLabel = pq_.top();
103  while(mergeGraph_.hasEdgeId(minLabel)==false){
104  pq_.deleteItem(minLabel);
105  minLabel = pq_.top();
106  }
107  return Edge(minLabel);
108  }
109 
111  WeightType contractionWeight(){
112  index_type minLabel = pq_.top();
113  while(mergeGraph_.hasEdgeId(minLabel)==false){
114  pq_.deleteItem(minLabel);
115  minLabel = pq_.top();
116  }
117  return pq_.topPriority();
118 
119  }
120 
122  MergeGraph & mergeGraph(){
123  return mergeGraph_;
124  }
125 
126  bool done()const{
127  return pq_.topPriority()<=ValueType(param_.stopWeight_);
128  }
129 
130  void mergeEdges(const Edge & a,const Edge & b){
131  weights_[a.id()]+=weights_[b.id()];
132  pq_.push(a.id(), weights_[a.id()]);
133  pq_.deleteItem(b.id());
134  }
135 
136  void eraseEdge(const Edge & edge){
137  pq_.deleteItem(edge.id());
138  }
139 
140  const Graph & graph_;
141  MergeGraph & mergeGraph_;
142  vigra::ChangeablePriorityQueue< ValueType ,std::greater<ValueType> > pq_;
144  std::vector<ValueType> & weights_;
145  };
146 
147 
148  #endif
149 
150 
151 
152 
153 
154 template<class GM, class ACC>
156 
157 public:
158 
159  typedef GM GraphicalModelType;
160  typedef ACC AccumulationType;
162  typedef std::map<UInt64Type, ValueType> MapType;
163  typedef typename MapType::iterator MapIter;
164  typedef typename MapType::const_iterator MapCIter;
165 
166 
168 
177  };
178 
179  struct Parameter{
181  const FusionSolver fusionSolver = SelfType::DefaultSolver,
182  const bool planar = false,
183  const std::string workflow = std::string(),
184  const int nThreads = 1,
185  const bool decompose = false,
186  const std::vector<bool> & allowCutsWithin = std::vector<bool>()
187  )
188  :
189  fusionSolver_(fusionSolver),
190  planar_(planar),
191  workflow_(workflow),
192  nThreads_(nThreads),
193  decompose_(decompose),
194  allowCutsWithin_(allowCutsWithin)
195  {
196 
197  }
199  bool planar_;
200  std::string workflow_;
203  std::vector<bool> allowCutsWithin_;
204 
205  };
206 
211 
212 
213  PermutableLabelFusionMove(const GraphicalModelType & gm, const Parameter & param = Parameter())
214  :
215  gm_(gm),
216  param_(param)
217  {
218  if(param_.fusionSolver_ == DefaultSolver){
219 
220  #ifdef WITH_CPLEX
221  param_.fusionSolver_ = MulticutSolver;
222  #endif
223 
224  if(param_.fusionSolver_ == DefaultSolver){
225  #ifdef WITH_QPBO
226  param_.fusionSolver_ = CgcSolver;
227  #endif
228  }
229  if(param_.fusionSolver_ == DefaultSolver){
230  #ifdef WITH_ISINF
231  if(param_.planar_){
232  param_.fusionSolver_ = CgcSolver;
233  }
234  #endif
235  }
236  if(param_.fusionSolver_ == DefaultSolver){
237  #ifndef NOVIGRA
238  if(param_.planar_){
240  }
241  #endif
242  }
243  if(param_.fusionSolver_ == DefaultSolver){
244  throw RuntimeError("WITH_CPLEX or WITH_QPBO or WITH_ISINF must be enabled");
245  }
246  }
247  }
248 
249 
250 
251  void printArg(const std::vector<LabelType> arg) {
252  const size_t nx = 3; // width of the grid
253  const size_t ny = 3; // height of the grid
254  const size_t numberOfLabels = nx*ny;
255 
256  size_t i=0;
257  for(size_t y = 0; y < ny; ++y){
258 
259  for(size_t x = 0; x < nx; ++x) {
260  std::cout<<arg[i]<<" ";
261  }
262  std::cout<<"\n";
263  ++i;
264  }
265 
266  }
267 
268 
269  size_t intersect(
270  const std::vector<LabelType> & a,
271  const std::vector<LabelType> & b,
272  std::vector<LabelType> & res
273  ){
274  Partition<LabelType> ufd(gm_.numberOfVariables());
275  for(size_t fi=0; fi< gm_.numberOfFactors(); ++fi){
276  if(gm_[fi].numberOfVariables()==2){
277 
278  const size_t vi0 = gm_[fi].variableIndex(0);
279  const size_t vi1 = gm_[fi].variableIndex(1);
280 
281 
282 
283  if(a[vi0] == a[vi1] && b[vi0] == b[vi1]){
284  ufd.merge(vi0, vi1);
285  }
286  }
287  else if(gm_[fi].numberOfVariables()==1){
288 
289  }
290  else{
291  throw RuntimeError("only implemented for second order");
292  }
293  }
294  std::map<LabelType, LabelType> repr;
295  ufd.representativeLabeling(repr);
296  for(size_t vi=0; vi<gm_.numberOfVariables(); ++vi){
297  res[vi]=repr[ufd.find(vi)];
298  }
299  //std::cout<<" A\n";
300  //printArg(a);
301  //std::cout<<" B\n";
302  //printArg(b);
303  //std::cout<<" RES\n";
304  //printArg(res);
305 
306  return ufd.numberOfSets();
307  }
308 
309  bool fuse(
310  const std::vector<LabelType> & a,
311  const std::vector<LabelType> & b,
312  std::vector<LabelType> & res,
313  const ValueType valA,
314  const ValueType valB,
315  ValueType & valRes
316  ){
317 
318  if(param_.fusionSolver_ == ClassicFusion)
319  return fuseClassic(a,b,res,valA,valB,valRes);
320 
321  std::vector<LabelType> ab(gm_.numberOfVariables());
322  IndexType numNewVar = this->intersect(a, b, ab);
323  //std::cout<<"numNewVar "<<numNewVar<<"\n";
324 
325  if(numNewVar==1){
326  return false;
327  }
328 
329  const ValueType intersectedVal = gm_.evaluate(ab);
330 
331 
332 
333  // get the new smaller graph
334 
335 
336  MapType accWeights;
337  size_t erasedEdges = 0;
338  size_t notErasedEdges = 0;
339 
340 
341  LabelType lAA[2]={0, 0};
342  LabelType lAB[2]={0, 1};
343 
344 
345 
346 
347  for(size_t fi=0; fi< gm_.numberOfFactors(); ++fi){
348  if(gm_[fi].numberOfVariables()==2){
349  const size_t vi0 = gm_[fi].variableIndex(0);
350  const size_t vi1 = gm_[fi].variableIndex(1);
351 
352  const size_t cVi0 = ab[vi0] < ab[vi1] ? ab[vi0] : ab[vi1];
353  const size_t cVi1 = ab[vi0] < ab[vi1] ? ab[vi1] : ab[vi0];
354 
355  OPENGM_CHECK_OP(cVi0,<,gm_.numberOfVariables(),"");
356  OPENGM_CHECK_OP(cVi1,<,gm_.numberOfVariables(),"");
357 
358 
359  if(cVi0 == cVi1){
360  ++erasedEdges;
361  }
362  else{
363  ++notErasedEdges;
364 
365  // get the weight
366  ValueType val00 = gm_[fi](lAA);
367  ValueType val01 = gm_[fi](lAB);
368  ValueType weight = val01 - val00;
369 
370  //std::cout<<"vAA"<<val00<<" vAB "<<val01<<" w "<<weight<<"\n";
371 
372  // compute key
373  const UInt64Type key = cVi0 + numNewVar*cVi1;
374 
375  // check if key is in map
376  MapIter iter = accWeights.find(key);
377 
378  // key not yet in map
379  if(iter == accWeights.end()){
380  accWeights[key] = weight;
381  }
382  // key is in map
383  else{
384  iter->second += weight;
385  }
386 
387  }
388 
389  }
390  }
391  OPENGM_CHECK_OP(erasedEdges+notErasedEdges, == , gm_.numberOfFactors(),"something wrong");
392  //std::cout<<"erased edges "<<erasedEdges<<"\n";
393  //std::cout<<"not erased edges "<<notErasedEdges<<"\n";
394  //std::cout<<"LEFT OVER FACTORS "<<accWeights.size()<<"\n";
395 
396 
397 
398  //std::cout<<"INTERSECTED SIZE "<<numNewVar<<"\n";
399 
400  if(param_.fusionSolver_ == CgcSolver){
401  return doMoveCgc(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
402  }
403  else if(param_.fusionSolver_ == MulticutSolver){
404  return doMoveMulticut(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
405  }
406  else if(param_.fusionSolver_ == MulticutNativeSolver){
407  return doMoveMulticutNative(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
408  }
409  else if(param_.fusionSolver_ == HierachicalClusteringSolver){
410  return doMoveHierachicalClustering(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
411  }
412  else if(param_.fusionSolver_ == BaseSolver){
413  return doMoveBase(accWeights,ab,numNewVar, a, b, res, valA, valB, valRes);
414  }
415  else{
416  throw RuntimeError("unknown fusionSolver");
417  return false;
418  }
419 
420  }
421 
422 
424  const std::vector<LabelType> & a,
425  const std::vector<LabelType> & b,
426  std::vector<LabelType> & res,
427  const ValueType valA,
428  const ValueType valB,
429  ValueType & valRes
430  ){
431  LabelType maxL = *std::max_element(a.begin(), a.end());
432  std::vector<LabelType> bb = b;
433  for(size_t i=0; i<bb.size(); ++i){
434  bb[i] += maxL;
435  }
437  HlFusionMover<GM, ACC> hlf(gm_,p);
438  hlf.fuse(a,b,res, valA, valB, valRes);
439  // make dense
440  std::map<LabelType, LabelType> mdense;
441 
442  LabelType dl=0;
443  for(size_t i=0;i<res.size(); ++i){
444  const LabelType resL = res[i];
445  if(mdense.find(resL) == mdense.end()){
446  res[i] = dl;
447  ++dl;
448  }
449  else{
450  res[i] = mdense[res[i]];
451  }
452  }
453  valRes = gm_.evaluate(res);
454  if(valRes< std::min(valA,valB)){
455  // make dense
456  std::map<LabelType, LabelType> mdense;
457 
458  LabelType dl=0;
459  for(size_t i=0;i<res.size(); ++i){
460  const LabelType resL = res[i];
461  if(mdense.find(resL) == mdense.end()){
462  res[i] = dl;
463  ++dl;
464  }
465  else{
466  res[i] = mdense[res[i]];
467  }
468  }
469  }
470  else if(valA<valRes){
471  valRes=valA;
472  res = a;
473  }
474  else{
475  valRes=valB;
476  res = b;
477  }
478  }
479 
480  bool fuseMmwc(
481  const std::vector<LabelType> & a,
482  const std::vector<LabelType> & b,
483  std::vector<LabelType> & res,
484  const ValueType valA,
485  const ValueType valB,
486  ValueType & valRes
487  ){
488  std::vector<LabelType> ab(gm_.numberOfVariables());
489  IndexType numNewVar = this->intersect(a, b, ab);
490 
491  if(numNewVar==1){
492  return false;
493  }
494 
495  const ValueType intersectedVal = gm_.evaluate(ab);
496 
497 
498 
499  // get the new smaller graph
500 
501 
502  MapType accWeights;
503  size_t erasedEdges = 0;
504  size_t notErasedEdges = 0;
505 
506 
507  LabelType lAA[2]={0, 0};
508  LabelType lAB[2]={0, 1};
509 
510  size_t ushape[] = { size_t(numNewVar), size_t(gm_.maxNumberOfLabels()) };
511 
512  marray::Marray<ValueType> accUnaries(ushape, ushape+2,0.0);
513 
514  for(size_t fi=0; fi< gm_.numberOfFactors(); ++fi){
515  if(gm_[fi].numberOfVariables()==2){
516  const size_t vi0 = gm_[fi].variableIndex(0);
517  const size_t vi1 = gm_[fi].variableIndex(1);
518 
519  const size_t cVi0 = ab[vi0] < ab[vi1] ? ab[vi0] : ab[vi1];
520  const size_t cVi1 = ab[vi0] < ab[vi1] ? ab[vi1] : ab[vi0];
521 
522  OPENGM_CHECK_OP(cVi0,<,gm_.numberOfVariables(),"");
523  OPENGM_CHECK_OP(cVi1,<,gm_.numberOfVariables(),"");
524 
525 
526  if(cVi0 == cVi1){
527  ++erasedEdges;
528  }
529  else{
530  ++notErasedEdges;
531 
532  // get the weight
533  ValueType val00 = gm_[fi](lAA);
534  ValueType val01 = gm_[fi](lAB);
535  ValueType weight = val01 - val00;
536 
537  //std::cout<<"vAA"<<val00<<" vAB "<<val01<<" w "<<weight<<"\n";
538 
539  // compute key
540  const UInt64Type key = cVi0 + numNewVar*cVi1;
541 
542  // check if key is in map
543  MapIter iter = accWeights.find(key);
544 
545  // key not yet in map
546  if(iter == accWeights.end()){
547  accWeights[key] = weight;
548  }
549  // key is in map
550  else{
551  iter->second += weight;
552  }
553 
554  }
555 
556  }
557  if(gm_[fi].numberOfVariables()==1){
558  const IndexType cVi = ab[gm_[fi].numberOfVariables()];
559  for(LabelType l=0 ; l<ushape[1]; ++l){
560  accUnaries(cVi,l)+=gm_[fi](&l);
561  }
562  }
563  }
564 
565 
566 
567  OPENGM_CHECK_OP(erasedEdges+notErasedEdges, == , gm_.numberOfFactors(),"something wrong");
568 
569 
570 
571 
572  return doMoveMmcw(accWeights,accUnaries,ab,numNewVar, a, b, res, valA, valB, valRes);
573 
574 
575  }
577  const MapType & accWeights,
578  const marray::Marray<ValueType> & accUnaries,
579  const std::vector<LabelType> & ab,
580  const IndexType numNewVar,
581  const std::vector<LabelType> & a,
582  const std::vector<LabelType> & b,
583  std::vector<LabelType> & res,
584  const ValueType valA,
585  const ValueType valB,
586  ValueType & valRes
587  ){
588  // make the actual sub graphical model
589  SubSpace subSpace(numNewVar, 2);
590  SubModel subGm(subSpace);
591 
592  // reserve space
593  subGm. template reserveFunctions<PFunction>(accWeights.size());
594  subGm. template reserveFunctions<EFunction>(numNewVar);
595 
596  subGm.reserveFactors(accWeights.size()+numNewVar);
597  subGm.reserveFactorsVarialbeIndices(accWeights.size()*2+numNewVar);
598  size_t efshape[] = {accUnaries.shape(1)};
599  EFunction ef(efshape,efshape+1);
600 
601  // unaries
602  for(IndexType vi=0; vi<numNewVar; ++vi){
603  for(LabelType l=0; l<accUnaries.shape(1); ++l){
604  ef(&l) = accUnaries(vi, l);
605  }
606  subGm.addFactor(subGm.addFunction(ef), &vi, &vi+1);
607  }
608 
609  // higher order
610  for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
611  const UInt64Type key = i->first;
612  const ValueType weight = i->second;
613 
614  const UInt64Type cVi1 = key/numNewVar;
615  const UInt64Type cVi0 = key - cVi1*numNewVar;
616  const UInt64Type vis[2] = {cVi0, cVi1};
617 
618  PFunction pf(numNewVar, numNewVar, 0.0, weight);
619  subGm.addFactor(subGm.addFunction(pf), vis, vis+2);
620  }
621 
622  std::vector<LabelType> subArg;
623 
624 
625  //::cout<<"WITH MC\n";
626  typedef Multicut<SubModel, Minimizer> Inf;
627  typedef typename Inf::Parameter Param;
628  Param p(0,0.0);
629 
630  if(param_.nThreads_ <= 0){
631  p.numThreads_ = 0;
632  }
633  else{
634  p.numThreads_ = param_.nThreads_;
635  }
636  p.workFlow_ = param_.workflow_;
637  p.allowCutsWithin_ = param_.allowCutsWithin_;
638 
639 
640  Inf inf(subGm,p);
641  inf.infer();
642 
643  // special arg
644  std::vector<size_t> oarg = inf.getSegmentation();
645  // usual arg
646  inf.arg(subArg);
647 
648  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
649  res[vi] = oarg[ab[vi]];
650  }
651 
652  ValueType resultVal = subGm.evaluate(subArg);
653  //std::cout<<"gm val inf "<<resultVal<<"\n";
654  // add the weight from the cuts within
655  const LabelType lAB[] = {0,1};
656  for(size_t f=0; f<subGm.numberOfFactors(); ++f){
657 
658  if(gm_.numberOfFactors()==1){
659  IndexType vi0 = subGm[f].variableIndex(0);
660  IndexType vi1 = subGm[f].variableIndex(1);
661 
662  if(subArg[vi0] == subArg[vi1] && oarg[vi0] != oarg[vi1]){
663  resultVal+=gm_[f](lAB);
664  }
665  }
666  }
667  //std::cout<<"mmcw val inf "<<resultVal<<"\n";
668  valRes = resultVal;
669  return true;
670  }
671  bool doMoveCgc(
672  const MapType & accWeights,
673  const std::vector<LabelType> & ab,
674  const IndexType numNewVar,
675  const std::vector<LabelType> & a,
676  const std::vector<LabelType> & b,
677  std::vector<LabelType> & res,
678  const ValueType valA,
679  const ValueType valB,
680  ValueType & valRes
681  ){
682 
683 
684  // make the actual sub graphical model
685  SubSpace subSpace(numNewVar, numNewVar);
686  SubModel subGm(subSpace);
687 
688  // reserve space
689  subGm. template reserveFunctions<PFunction>(accWeights.size());
690  subGm.reserveFactors(accWeights.size());
691  subGm.reserveFactorsVarialbeIndices(accWeights.size()*2);
692 
693  for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
694  const UInt64Type key = i->first;
695  const ValueType weight = i->second;
696 
697  const UInt64Type cVi1 = key/numNewVar;
698  const UInt64Type cVi0 = key - cVi1*numNewVar;
699  const UInt64Type vis[2] = {cVi0, cVi1};
700 
701  PFunction pf(numNewVar, numNewVar, 0.0, weight);
702  subGm.addFactor(subGm.addFunction(pf), vis, vis+2);
703  }
704 
705  std::vector<LabelType> subArg;
706 
707  //::cout<<"WITH MC\n";
708  typedef CGC<SubModel, Minimizer> Inf;
709  typedef typename Inf::Parameter Param;
710 
711  Param p;
712  p.planar_ = param_.planar_;
713 
714  Inf inf(subGm,p);
715  inf.infer();
716  inf.arg(subArg);
717 
718  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
719  res[vi] = subArg[ab[vi]];
720  }
721  const ValueType resultVal = subGm.evaluate(subArg);
722  const ValueType projectedResultVal = gm_.evaluate(res);
723  const std::vector<LabelType> & bestArg = valA < valB ? a : b;
724  const ValueType bestProposalVal = valA < valB ? valA : valB;
725 
726  valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
727  if(projectedResultVal < bestProposalVal){
728  //for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
729  // res[vi] = subArg[ab[vi]];
730  //}
731  }
732  else{
733  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
734  res[vi] = bestArg[vi];
735  }
736  }
737  return true;
738 
739  }
740 
742  const MapType & accWeights,
743  const std::vector<LabelType> & ab,
744  const IndexType numNewVar,
745  const std::vector<LabelType> & a,
746  const std::vector<LabelType> & b,
747  std::vector<LabelType> & res,
748  const ValueType valA,
749  const ValueType valB,
750  ValueType & valRes
751  ){
752  const std::vector<LabelType> & bestArg = valA < valB ? a : b;
753  valRes = valA < valB ? valA : valB;
754  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
755  res[vi] = bestArg[vi];
756  }
757  return true;
758  }
759 
761  const MapType & accWeights,
762  const std::vector<LabelType> & ab,
763  const IndexType numNewVar,
764  const std::vector<LabelType> & a,
765  const std::vector<LabelType> & b,
766  std::vector<LabelType> & res,
767  const ValueType valA,
768  const ValueType valB,
769  ValueType & valRes
770  ){
771  // make the actual sub graphical model
772  SubSpace subSpace(numNewVar, numNewVar);
773  SubModel subGm(subSpace);
774 
775  // reserve space
776  subGm. template reserveFunctions<PFunction>(accWeights.size());
777  subGm.reserveFactors(accWeights.size());
778  subGm.reserveFactorsVarialbeIndices(accWeights.size()*2);
779 
780  for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
781  const UInt64Type key = i->first;
782  const ValueType weight = i->second;
783 
784  const UInt64Type cVi1 = key/numNewVar;
785  const UInt64Type cVi0 = key - cVi1*numNewVar;
786  const UInt64Type vis[2] = {cVi0, cVi1};
787 
788  PFunction pf(numNewVar, numNewVar, 0.0, weight);
789  subGm.addFactor(subGm.addFunction(pf), vis, vis+2);
790  }
791 
792  std::vector<LabelType> subArg;
793 
794  //try{
795  //::cout<<"WITH MC\n";
796  typedef Multicut<SubModel, Minimizer> McInf;
797  typedef typename McInf::Parameter McParam;
798  McParam pmc(0,0.0);
799 
800  if(param_.nThreads_ <= 0){
801  pmc.numThreads_ = 0;
802  }
803  else{
804  pmc.numThreads_ = param_.nThreads_;
805  }
806  pmc.workFlow_ = param_.workflow_;
807 
808 
809  if(param_.decompose_ == false){
810  McInf inf(subGm,pmc);
811  inf.infer();
812  inf.arg(subArg);
813  }
814  else{
815  typedef DMC<SubModel, McInf> DmcInf;
816  typedef typename DmcInf::Parameter DmcParam;
817  typedef typename DmcInf::InfParam DmcInfParam;
818  DmcParam dmcParam;
819  DmcInfParam dmcInfParam(pmc);
820 
821  dmcParam.infParam_ = dmcInfParam;
822 
823  DmcInf inf(subGm, dmcParam);
824  inf.infer();
825  inf.arg(subArg);
826  }
827  //}
828  //catch(...){
829  // std::cout<<"error from cplex\n....\n";
830  //}
831 
832  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
833  res[vi] = subArg[ab[vi]];
834  }
835  const ValueType resultVal = subGm.evaluate(subArg);
836  const ValueType projectedResultVal = gm_.evaluate(res);
837  const std::vector<LabelType> & bestArg = valA < valB ? a : b;
838  const ValueType bestProposalVal = valA < valB ? valA : valB;
839 
840  valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
841  if(projectedResultVal < bestProposalVal){
842  //for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
843  // res[vi] = subArg[ab[vi]];
844  //}
845  }
846  else{
847  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
848  res[vi] = bestArg[vi];
849  }
850  }
851  return true;
852  }
853 
854 
856  const MapType & accWeights,
857  const std::vector<LabelType> & ab,
858  const IndexType numNewVar,
859  const std::vector<LabelType> & a,
860  const std::vector<LabelType> & b,
861  std::vector<LabelType> & res,
862  const ValueType valA,
863  const ValueType valB,
864  ValueType & valRes
865  ){
866 
867  std::vector<LabelType> subArg;
868 
869  //::cout<<"WITH MC\n";
870  typedef Multicut<SubModel, Minimizer> Inf;
871  typedef typename Inf::Parameter Param;
872  Param p(0,0.0);
873 
874  if(param_.nThreads_ <= 0){
875  p.numThreads_ = 0;
876  }
877  else{
878  p.numThreads_ = param_.nThreads_;
879  }
880  p.workFlow_ = param_.workflow_;
881 
882  Inf inf(numNewVar, accWeights, p);
883  inf.infer();
884  inf.arg(subArg);
885 
886 
887 
888  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
889  res[vi] = subArg[ab[vi]];
890  }
891 
892  const ValueType projectedResultVal = gm_.evaluate(res);
893  const std::vector<LabelType> & bestArg = valA < valB ? a : b;
894  const ValueType bestProposalVal = valA < valB ? valA : valB;
895 
896  valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
897  if(projectedResultVal < bestProposalVal){
898  //for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
899  // res[vi] = subArg[ab[vi]];
900  //}
901  }
902  else{
903  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
904  res[vi] = bestArg[vi];
905  }
906  }
907  return true;
908  }
909 
911  const MapType & accWeights,
912  const std::vector<LabelType> & ab,
913  const IndexType numNewVar,
914  const std::vector<LabelType> & a,
915  const std::vector<LabelType> & b,
916  std::vector<LabelType> & res,
917  const ValueType valA,
918  const ValueType valB,
919  ValueType & valRes
920  ){
921  #ifndef NOVIGRA
922  typedef vigra::AdjacencyListGraph Graph;
923  typedef typename Graph::Edge Edge;
924  typedef vigra::MergeGraphAdaptor< Graph > MergeGraph;
925  typedef McClusterOp<GM,ACC> ClusterOp;
926  typedef typename ClusterOp::Parameter ClusterOpParam;
927  typedef vigra::HierarchicalClustering< ClusterOp > HC;
928  typedef typename HC::Parameter HcParam;
929 
930  std::vector<ValueType> weights(accWeights.size(),0.0);
931 
932  Graph graph(numNewVar, accWeights.size());
933  for(MapCIter i = accWeights.begin(); i!=accWeights.end(); ++i){
934  const UInt64Type key = i->first;
935  const ValueType weight = i->second;
936 
937  const UInt64Type cVi1 = key/numNewVar;
938  const UInt64Type cVi0 = key - cVi1*numNewVar;
939 
940  const Edge e = graph.addEdge(cVi0, cVi1);
941  weights[graph.id(e)] = weight;
942  }
943 
944  MergeGraph mg(graph);
945 
946 
947 
948 
949  const ClusterOpParam clusterOpParam;
950  ClusterOp clusterOp(graph, mg, clusterOpParam, weights);
951 
952 
953 
954 
955  HcParam p;
956  HC hc(clusterOp,p);
957 
958  //std::cout<<"start\n";
959  hc.cluster();
960 
961 
962 
963  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
964  res[vi] = hc.reprNodeId(ab[vi]);
965  }
966 
967  const ValueType projectedResultVal = gm_.evaluate(res);
968  const std::vector<LabelType> & bestArg = valA < valB ? a : b;
969  const ValueType bestProposalVal = valA < valB ? valA : valB;
970 
971  valRes = bestProposalVal < projectedResultVal ? bestProposalVal : projectedResultVal;
972  if(projectedResultVal < bestProposalVal){
973  //for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
974  // res[vi] = subArg[ab[vi]];
975  //}
976  }
977  else{
978  for(IndexType vi=0; vi<gm_.numberOfVariables(); ++vi){
979  res[vi] = bestArg[vi];
980  }
981  }
982  return true;
983  #else
984  throw RuntimeError("needs VIGRA");
985  return false;
986  #endif
987  }
988 
989 private:
990  const GM & gm_;
991  Parameter param_;
992 };
993 
994 
995 
996 
997 
998 }
999 
1000 
1001 #endif /* OPENGM_PERMUTABLE_LABEL_FUSION_MOVER_HXX */
IndexType addFactor(const FunctionIdentifier &, ITERATOR, ITERATOR)
add a factor to the graphical model
The OpenGM namespace.
Definition: config.hxx:43
MergeGraph & mergeGraph()
get a reference to the merge
McClusterOp(const Graph &graph, MergeGraph &mergegraph, const Parameter &param, std::vector< ValueType > &weights)
PermutableLabelFusionMove< GM, ACC > SelfType
vigra::AdjacencyListGraph Graph
SimpleDiscreteSpace< IndexType, LabelType > SubSpace
bool doMoveMmcw(const MapType &accWeights, const marray::Marray< ValueType > &accUnaries, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
size_t intersect(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res)
FunctionIdentifier addFunction(const FUNCTION_TYPE &)
add a function to the graphical model
const size_t shape(const size_t) const
Get the shape in one dimension.
Definition: marray.hxx:1725
Discrete space in which all variables have the same number of labels.
ValueType evaluate(ITERATOR) const
evaluate the modeled function for a given labeling
void printArg(const std::vector< LabelType > arg)
void reserveFactors(const size_t numF)
bool doMoveHierachicalClustering(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
detail_types::UInt64Type UInt64Type
uint64
Definition: config.hxx:300
Experimental Multicut.
Definition: cgc.hxx:121
PermutableLabelFusionMove(const GraphicalModelType &gm, const Parameter &param=Parameter())
void mergeEdges(const Edge &a, const Edge &b)
PottsFunction< ValueType, IndexType, LabelType > PFunction
Parameter(const FusionSolver fusionSolver=SelfType::DefaultSolver, const bool planar=false, const std::string workflow=std::string(), const int nThreads=1, const bool decompose=false, const std::vector< bool > &allowCutsWithin=std::vector< bool >())
bool doMoveBase(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
WeightType contractionWeight()
get the edge weight of the edge which should be contracted next
bool doMoveMulticut(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
void reserveFactorsVarialbeIndices(const size_t size)
vigra::MergeGraphAdaptor< Graph > MergeGraph
bool doMoveMulticutNative(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
bool doMoveCgc(const MapType &accWeights, const std::vector< LabelType > &ab, const IndexType numNewVar, const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
bool fuse(const LabelVector &argA, const LabelVector argB, LabelVector &argRes, const ValueType valA, const ValueType valB, ValueType &valRes)
ExplicitFunction< ValueType, IndexType, LabelType > EFunction
std::map< UInt64Type, ValueType > MapType
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Definition: submodel2.hxx:24
Potts function for two variables.
Definition: potts.hxx:19
std::vector< ValueType > & weights_
Disjoint set data structure with path compression.
Definition: partition.hxx:13
bool fuse(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
bool fuseMmwc(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
IndexType numberOfFactors() const
GraphicalModel< ValueType, Adder, OPENGM_TYPELIST_2(EFunction, PFunction), SubSpace > SubModel
OpenGM runtime error.
Definition: opengm.hxx:100
bool fuseClassic(const std::vector< LabelType > &a, const std::vector< LabelType > &b, std::vector< LabelType > &res, const ValueType valA, const ValueType valB, ValueType &valRes)
vigra::ChangeablePriorityQueue< ValueType,std::greater< ValueType > > pq_