OpenGM  2.3.x
Discrete Graphical Model Library
graphicalmodel_manipulator.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_GRAPHICALMODEL_MANIPULATOR_HXX
3 #define OPENGM_GRAPHICALMODEL_MANIPULATOR_HXX
4 
5 #include <exception>
6 #include <set>
7 #include <vector>
8 #include <queue>
9 
16 
19 
20 #include <iostream>
21 
22 namespace opengm {
23 
46  template<class GM>
48  {
49  public:
50  typedef GM OGM;
51  typedef typename GM::SpaceType OSpaceType;
52  typedef typename GM::IndexType IndexType;
53  typedef typename GM::LabelType LabelType;
54  typedef typename GM::ValueType ValueType;
55 
57  FIX, //fix variables in factors that are fixed.
58  DROP //drop factors that include fixed variables.
59  };
60 
62  typedef typename meta::TypeListGenerator<
68 
69  GraphicalModelManipulator(const GM& gm, const ManipulationMode mode = FIX);
70 
71  //BuildModels
72  void buildModifiedModel();
74 
75  //Get Models
76  const OGM& getOriginalModel() const;
77  const MGM& getModifiedModel() const;
78  const MGM& getModifiedSubModel(size_t) const;
79 
80  //GetInfo
81  size_t numberOfSubmodels() const;
82  void modifiedState2OriginalState(const std::vector<LabelType>&, std::vector<LabelType>&) const;
83  void modifiedSubStates2OriginalState(const std::vector<std::vector<LabelType> >&, std::vector<LabelType>&) const;
84  bool isLocked() const;
85 
86  //Manipulation
87  void fixVariable(const typename GM::IndexType, const typename GM::LabelType);
88  void freeVariable(const typename GM::IndexType);
89  void freeAllVariables();
90  void unlock();
91  void lock();
92  template<class ACC> void lockAndTentacelElimination();
93  bool isFixed(const typename GM::IndexType)const;
94 
95  private:
96  void expand(IndexType, IndexType, std::vector<bool>&);
97 
98  //General Members
99  const OGM& gm_; // original model
100  bool locked_; // if true no more manipulation is allowed
101  std::vector<bool> fixVariable_; // flag if variables are fixed
102  std::vector<LabelType> fixVariableLabel_; // label of fixed variables (otherwise undefined)
103  ManipulationMode mode_;
104 
105  //Modified Model
106  bool validModel_; // true if modified model is valid
107  MGM mgm_; // modified model
108 
109  //Modified SubModels
110  bool validSubModels_; // true if themodified submodels are valid
111  std::vector<MGM> submodels_; // modified submodels
112  std::vector<IndexType> var2subProblem_; // subproblem of variable (for fixed variables undefined)
113 
114  //Tentacles
115  std::vector<IndexType> tentacleRoots_; // Root-node of the tentacles
116  std::vector<opengm::ExplicitFunction<ValueType,IndexType,LabelType> > tentacleFunctions_; // functions that replace the tentacles
117  std::vector<std::vector<std::vector<LabelType> > > tentacleLabelCandidates_; // Candidates for labeling of the tentacles
118  std::vector<std::vector<IndexType> > tentacleVars_; // Variable-list of the tentacles
119  std::vector<bool> tentacleFactor_; // factor is included in a tentacle
120  ValueType tentacleConstValue_;
121 
122 
123  };
124 
125 
126  template<class GM>
127  bool GraphicalModelManipulator<GM>::isFixed(const typename GM::IndexType vi) const
128  {
129  return fixVariable_[vi];
130  }
131 
132  template<class GM>
134  : gm_(gm),
135  locked_(false),
136  fixVariable_(std::vector<bool>(gm.numberOfVariables(),false)),
137  fixVariableLabel_(std::vector<LabelType>(gm.numberOfVariables(),0)),
138  mode_(mode),
139  validModel_(false),
140  validSubModels_(false),
141  var2subProblem_(std::vector<IndexType>(gm.numberOfVariables(),0))
142  {
143  return;
144  }
145 
147  template<class GM>
148  inline const typename GraphicalModelManipulator<GM>::OGM &
150  {
151  return gm_;
152  }
153 
155  template<class GM>
156  inline const typename GraphicalModelManipulator<GM>::MGM &
158  {
159  OPENGM_ASSERT(isLocked() && validModel_);
160  return mgm_;
161  }
162 
164  template<class GM>
165  inline const typename GraphicalModelManipulator<GM>::MGM &
167  {
168  OPENGM_ASSERT(isLocked() && validSubModels_);
169  OPENGM_ASSERT(i < submodels_.size());
170  return submodels_[i];
171  }
172 
174  template<class GM>
176  {
177  OPENGM_ASSERT(isLocked());
178  return submodels_.size();
179  }
180 
182  template<class GM>
184  {
185  locked_=false;
186  validSubModels_=false;
187  validModel_=false;
188  submodels_.clear();
189  freeAllVariables();
190  }
191 
193  template<class GM>
195  {
196  locked_=true;
197  tentacleFactor_.resize(gm_.numberOfFactors(),false);
198  }
199 
200 
202  template<class GM>
204  {
205  return locked_;
206  }
207 
209  template<class GM>
210  void GraphicalModelManipulator<GM>::fixVariable(const typename GM::IndexType var, const typename GM::LabelType l)
211  {
212  OPENGM_ASSERT(!isLocked());
213  if(!isLocked()){
214  fixVariable_[var]=true;
215  fixVariableLabel_[var]=l;
216  }
217  }
218 
220  template<class GM>
221  void GraphicalModelManipulator<GM>::freeVariable(const typename GM::IndexType var)
222  {
223  OPENGM_ASSERT(!isLocked());
224  if(!isLocked()){
225  fixVariable_[var]=false;
226  }
227  }
228 
230  template<class GM>
232  {
233  OPENGM_ASSERT(!isLocked())
234 
235  if(!isLocked()){
236  for(IndexType var=0; var<fixVariable_.size(); ++var)
237  fixVariable_[var]=false;
238  }
239  }
240 
242  template<class GM>
243  void GraphicalModelManipulator<GM>::modifiedState2OriginalState(const std::vector<LabelType>& ml, std::vector<LabelType>& ol) const
244  {
245  OPENGM_ASSERT(isLocked());
246  OPENGM_ASSERT(ml.size()==mgm_.numberOfVariables());
247 
248  if(isLocked() && ml.size()==mgm_.numberOfVariables()){
249  ol.resize(gm_.numberOfVariables());
250  size_t c = 0;
251  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
252  if(fixVariable_[var]){
253  ol[var] = fixVariableLabel_[var];
254  }else{
255  ol[var] = ml[c++];
256  }
257  }
258  // Get labels for tentacle variables
259  for (size_t i=0; i<tentacleRoots_.size();++i){
260  const LabelType l = ol[tentacleRoots_[i]];
261  for(size_t k=0; k<tentacleVars_[i].size();++k){
262  ol[tentacleVars_[i][k]] = tentacleLabelCandidates_[i][l][k];
263  //std::cout <<tentacleVars_[i][k] << " <- "<<tentacleLabelCandidates_[i][l][k]<<std::endl;
264  }
265  OPENGM_ASSERT( l == ol[tentacleRoots_[i]]);
266  }
267  }
268  }
269 
271  template<class GM>
272  void GraphicalModelManipulator<GM>::modifiedSubStates2OriginalState(const std::vector<std::vector<LabelType> >& subconf, std::vector<LabelType>& conf) const
273  {
274  conf.resize(gm_.numberOfVariables());
275  std::vector<IndexType> varCount(submodels_.size(),0);
276  for(IndexType i=0;i<submodels_.size(); ++i){
277  OPENGM_ASSERT(submodels_[i].numberOfVariables()==subconf[i].size());
278  }
279  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
280  if(fixVariable_[var]){
281  conf[var] = fixVariableLabel_[var];
282  }else{
283  const IndexType sp=var2subProblem_[var];
284  conf[var] = subconf[sp][varCount[sp]++];
285  }
286  }
287  // Get labels for tentacle variables
288  for (size_t i=0; i<tentacleRoots_.size();++i){
289  const LabelType l = conf[tentacleRoots_[i]];
290  for(size_t k=0; k<tentacleVars_[i].size();++k){
291  conf[tentacleVars_[i][k]] = tentacleLabelCandidates_[i][l][k];
292  }
293  OPENGM_ASSERT( l == conf[tentacleRoots_[i]] );
294  }
295  }
296 
298  template<class GM>
299  void
301  {
302  locked_ = true;
303  validModel_ = true;
304  IndexType numberOfVariables = 0;
305  std::vector<IndexType> varMap(gm_.numberOfVariables(),0);
306 
307  //building variable mapping between input and output models
308  for(IndexType var=0; var<gm_.numberOfVariables();++var){
309  if(fixVariable_[var]==false){
310  varMap[var] = numberOfVariables++;
311  }
312  }
313 
314  //construction of label space for non-fixed variables
315  std::vector<LabelType> shape(numberOfVariables,0);
316  for(IndexType var=0; var<gm_.numberOfVariables();++var){
317  if(fixVariable_[var]==false){
318  shape[varMap[var]] = gm_.numberOfLabels(var);
319  }
320  }
321  MSpaceType space(shape.begin(),shape.end());
322  mgm_ = MGM(space);
323 
324  std::vector<PositionAndLabel<IndexType,LabelType> > fixedVars;
325  std::vector<IndexType> MVars;
326 
327 
328  ValueType constant;
329  GM::OperatorType::neutral(constant);
330  for(IndexType f=0; f<gm_.numberOfFactors();++f){
331  if(tentacleFactor_[f]) continue;
332  fixedVars.resize(0);
333  MVars.resize(0);
334  for(IndexType i=0; i<gm_[f].numberOfVariables(); ++i){
335  const IndexType var = gm_[f].variableIndex(i);
336  if(fixVariable_[var]){
337  fixedVars.push_back(PositionAndLabel<IndexType,LabelType>(i,fixVariableLabel_[var]));
338  }else{
339  MVars.push_back(varMap[var]);
340  }
341  }
342  if(mode_==FIX){
343  if(fixedVars.size()==0){//non fixed
344  const ViewFunction<GM> func(gm_[f]);
345  mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.end());
346  }else if(fixedVars.size()==gm_[f].numberOfVariables()){//all fixed
347  std::vector<LabelType> fixedStates(gm_[f].numberOfVariables(),0);
348  for(IndexType i=0; i<gm_[f].numberOfVariables(); ++i){
349  fixedStates[i]=fixVariableLabel_[ gm_[f].variableIndex(i)];
350  }
351  GM::OperatorType::op(gm_[f](fixedStates.begin()),constant);
352  }else{
353  const ViewFixVariablesFunction<GM> func(gm_[f], fixedVars);
354  mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.end());
355  }
356  } else if(mode_==DROP){
357  if(fixedVars.size()==0){//non fixed
358  const ViewFunction<GM> func(gm_[f]);
359  mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.end());
360  }
361  } else{
362  throw std::runtime_error("Unsupported manipulation mode");
363  }
364  }
365  if(mode_==FIX){
366  // Add Tentacle nodes
367  for(size_t i=0; i<tentacleRoots_.size(); ++i){
368  IndexType var = varMap[tentacleRoots_[i]];
369  mgm_.addFactor(mgm_.addFunction(tentacleFunctions_[i]), &var, &var+1);
370  }
371 
372  // Add constant
373  {
374  //std::cout <<"* Const= "<<constant<<std::endl;
375  LabelType temp;
376  ConstantFunction<ValueType, IndexType, LabelType> func(&temp, &temp, constant);
377  mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.begin());
378  }
379  //std::cout << "* numvars : " << mgm_.numberOfVariables() <<std::endl;
380  }
381  }
382 
384  template<class GM>
385  void
387  {
388  locked_ = true;
389  validSubModels_ = true;
390 
391  //Find Connected Components
392  std::vector<bool> closedVar = fixVariable_;
393  IndexType numberOfSubproblems = 0;
394  for(IndexType var=0 ; var<gm_.numberOfVariables(); ++var){
395  if(closedVar[var])
396  continue;
397  else{
398  expand(var, numberOfSubproblems, closedVar);
399  }
400  ++numberOfSubproblems;
401  }
402  if(numberOfSubproblems==0) numberOfSubproblems=1;
403  submodels_.resize(numberOfSubproblems);
404  std::vector<IndexType> numberOfVariables(numberOfSubproblems,0);
405  std::vector<IndexType> varMap(gm_.numberOfVariables(),0);
406  for(IndexType var=0; var<gm_.numberOfVariables();++var){
407  if(fixVariable_[var]==false){
408  varMap[var] = numberOfVariables[var2subProblem_[var]]++;
409  }
410  }
411  std::vector<std::vector<LabelType> > shape(numberOfSubproblems);
412  for (size_t i=0; i<numberOfSubproblems; ++i){
413  shape[i] = std::vector<LabelType>(numberOfVariables[i],0);
414  }
415  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
416  if(fixVariable_[var]==false){
417  shape[var2subProblem_[var]][varMap[var]] = gm_.numberOfLabels(var);
418  }
419  }
420  for (size_t i=0; i<numberOfSubproblems; ++i){
421  MSpaceType space(shape[i].begin(),shape[i].end());
422  submodels_[i] = MGM(space);
423  }
424 
425  std::vector<PositionAndLabel<IndexType,LabelType> > fixedVars;
426  std::vector<IndexType> MVars;
427 
428  ValueType constant;
429  GM::OperatorType::neutral(constant);
430 
431  for(IndexType f=0; f<gm_.numberOfFactors();++f){
432  if(tentacleFactor_[f]) continue;
433  IndexType subproblem = 0;
434  fixedVars.resize(0);
435  MVars.resize(0);
436  for(IndexType i=0; i<gm_[f].numberOfVariables(); ++i){
437  const IndexType var = gm_[f].variableIndex(i);
438  if(fixVariable_[var]){
439  fixedVars.push_back(PositionAndLabel<IndexType,LabelType>(i,fixVariableLabel_[var]));
440  }else{
441  MVars.push_back(varMap[var]);
442  subproblem = var2subProblem_[var];
443  }
444  }
445  if(mode_==FIX){
446  if(MVars.size()==0){ //constant, all fixed
447  std::vector<LabelType> fixedStates(gm_[f].numberOfVariables(),0);
448  for(IndexType i=0; i<gm_[f].numberOfVariables(); ++i){
449  fixedStates[i]=fixVariableLabel_[ gm_[f].variableIndex(i)];
450  }
451  GM::OperatorType::op(gm_[f](fixedStates.begin()),constant);
452  }
453  else if(fixedVars.size()==0){//non fixed
454  const ViewFunction<GM> func(gm_[f]);
455  submodels_[subproblem].addFactor(submodels_[subproblem].addFunction(func),MVars.begin(), MVars.end());
456  }else{
457  const ViewFixVariablesFunction<GM> func(gm_[f], fixedVars);
458  submodels_[subproblem].addFactor(submodels_[subproblem].addFunction(func),MVars.begin(), MVars.end());
459  }
460  } else if(mode_==DROP){
461  if(fixedVars.size()==0){//non fixed
462  const ViewFunction<GM> func(gm_[f]);
463  submodels_[subproblem].addFactor(submodels_[subproblem].addFunction(func),MVars.begin(), MVars.end());
464  }
465  }else{
466  throw std::runtime_error("Unsupported manipulation mode");
467  }
468  }
469  if(mode_==FIX){
470  // Add Tentacle nodes
471  for(size_t i=0; i<tentacleRoots_.size(); ++i){
472  IndexType var = varMap[tentacleRoots_[i]];
473  IndexType subproblem = var2subProblem_[tentacleRoots_[i]];
474  submodels_[subproblem].addFactor(submodels_[subproblem].addFunction(tentacleFunctions_[i]), &var, &var+1);
475  }
476  {
477  //std::cout <<"Const= "<<constant<<std::endl;
478  LabelType temp;
479  ConstantFunction<ValueType, IndexType, LabelType> func(&temp, &temp, constant);
480  submodels_[0].addFactor( submodels_[0].addFunction(func),MVars.begin(), MVars.begin());
481  }
482  }
483  //std::cout << " numvars : " << submodels_[0].numberOfVariables() <<std::endl;
484  }
485 
487 // ACC Manipulation
489 
490  // std::vector<bool> fixVariable_; // flag if variables are fixed
491  // std::vector<LabelType> fixVariableLabel_; // label of fixed variables (otherwise undefined)
492 
493  template<class GM>
494  template<class ACC>
496  {
497  if(locked_) return;
498  if(mode_!=FIX) throw std::runtime_error ("lockAndTentacelElimination only supports the mode FIX, yet");
499 
500  locked_ = true;
501  tentacleFactor_.resize(gm_.numberOfFactors(),false);
502  std::vector<bool> tFactor(gm_.numberOfFactors(),false);
503 
504  //std::cout << "start detecting tentacles" << std::endl;
505 
506  std::vector<IndexType> variableDegree(gm_.numberOfVariables(), 0);
507  std::vector<IndexType> factorDegree(gm_.numberOfFactors(), 0);
508  std::vector<bool> isRoot(gm_.numberOfVariables(), false);
509  std::vector<bool> isInTentacle(gm_.numberOfVariables(), false);
510  std::vector<IndexType> leafs;
511 
512  //SETUP DEGREE
513  for(IndexType factor = 0 ; factor < gm_.numberOfFactors() ; ++factor){
514  //Factor degree
515  for(typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(factor); vit!=gm_.variablesOfFactorEnd(factor); ++vit){
516  if(!fixVariable_[*vit]){
517  ++factorDegree[factor];
518  }
519  }
520  if(factorDegree[factor]>1){
521  for(typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(factor); vit!=gm_.variablesOfFactorEnd(factor); ++vit){
522  if(!fixVariable_[*vit]){
523  variableDegree[*vit] += 1;
524  }
525  }
526  }
527  }
528 
529  //SETUP LEAFS
530  std::vector<bool> pushed2Leafs(gm_.numberOfFactors(), false);
531  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
532  if(variableDegree[var] <= 1 && !fixVariable_[var]){
533  leafs.push_back(var);
534  pushed2Leafs[var] = true;
535  isInTentacle[var] = true;
536  }
537  }
538 
539  //std::cout << "Found "<<leafs.size()<<" leafs."<<std::endl;
540  if(leafs.size()==0) return;
541  //
542 
543  // Find Tentacle variables
544  std::map<IndexType, IndexType> representives;
545  typename std::set<typename GM::IndexType>::iterator it;
546  typename std::set<typename GM::IndexType>::iterator fi;
547 
548  while(!leafs.empty()){
549  IndexType var=leafs.back();
550  leafs.pop_back();
551  OPENGM_ASSERT(isInTentacle[var]);
552  // Reduce factor order
553  for(typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(var); fit !=gm_.factorsOfVariableEnd(var); ++fit){
554  OPENGM_ASSERT(factorDegree[*fit]>0);
555  --factorDegree[*fit];
556  if(factorDegree[*fit]<=1){
557  tFactor[*fit]=true;
558  }
559  }
560  // Check for new vars
561  for(typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(var); fit !=gm_.factorsOfVariableEnd(var); ++fit){
562  if(factorDegree[*fit]==1){
563  for(typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(*fit); vit!=gm_.variablesOfFactorEnd(*fit); ++vit){
564  if(!fixVariable_[*vit]){
565  OPENGM_ASSERT(variableDegree[*vit]>0);
566  --variableDegree[*vit];
567  if(variableDegree[*vit]==1 && !pushed2Leafs[*vit] ){
568  leafs.push_back(*vit);
569  pushed2Leafs[*vit] = true;
570  }
571  isInTentacle[*vit] = true;
572  }
573  }
574  }
575  }
576  }
577 
578 
579  IndexType numTentacleVars = 0;
580  IndexType numRootVars = 0;
581  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
582  if( isInTentacle[var] )
583  ++numTentacleVars;
584  if( isInTentacle[var] && variableDegree[var]>0){
585  ++numRootVars;
586  isRoot[var]=true;
587  OPENGM_ASSERT_OP(variableDegree[var],>,0);
588  }
589  if( isInTentacle[var] && variableDegree[var]==0){
590  for(typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(var); fit !=gm_.factorsOfVariableEnd(var); ++fit){
591  OPENGM_ASSERT(tFactor[*fit]);
592  }
593  }
594  }
595  for(IndexType factor=0; factor<gm_.numberOfFactors();++factor){
596  if(tFactor[factor]){
597  size_t count =0;
598  for(typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(factor); vit!=gm_.variablesOfFactorEnd(factor); ++vit){
599  if(!fixVariable_[*vit] && variableDegree[*vit]>0) ++count;
600  }
601  OPENGM_ASSERT_OP(factorDegree[factor],<=,count);
602  OPENGM_ASSERT_OP(factorDegree[factor]+1,>=,count);
603  OPENGM_ASSERT_OP(factorDegree[factor],<=,1);
604 
605  }
606  }
607 
608  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
609  if( isRoot[var])
610  OPENGM_ASSERT(variableDegree[var]>0);
611  }
612  //std::cout << "Found "<<numTentacleVars<<" tentacle variables and "<< numRootVars <<" root variables."<<std::endl;
613  tentacleRoots_.reserve(numRootVars);
614  tentacleFunctions_.reserve(numRootVars);
615  tentacleLabelCandidates_.reserve(numRootVars);
616  tentacleVars_.reserve(numRootVars);
617 
618 
619  // Find Tentacels
620  size_t numTentacles = 0;
621  std::vector<IndexType> gmvar2ttvar(gm_.numberOfVariables());
622  std::vector<bool> visitedVar(gm_.numberOfVariables(), false);
623  for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
624  if(!isInTentacle[var] || visitedVar[var]) continue;
625 
626  std::vector<IndexType> varList;
627  size_t i = 0;
628  bool hasRoot = false;
629  IndexType root = 0;
630  varList.push_back(var);
631  visitedVar[var] = true;
632  while(i<varList.size()){
633  IndexType v = varList[i];
634  if(isRoot[v]){
635  OPENGM_ASSERT_OP(variableDegree[v],>,0);
636  OPENGM_ASSERT(!hasRoot);
637  hasRoot = true;
638  root = v;
639  }else{
640  OPENGM_ASSERT_OP(variableDegree[v],==,0);
641  }
642 
643  for(typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(v); fit !=gm_.factorsOfVariableEnd(v); ++fit){
644  if(tFactor[*fit]){
645  for(typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(*fit); vit!=gm_.variablesOfFactorEnd(*fit); ++vit){
646  if(!fixVariable_[*vit] && !visitedVar[*vit]){
647  visitedVar[*vit] = true;
648  varList.push_back(*vit);
649  }
650  }
651  }
652  else{
653  OPENGM_ASSERT(hasRoot);
654  }
655  }
656  ++i;
657  }
658 
659  // ** Solve tentacle **
660  //std::cout << "Tentacle "<<numTentacles<<" has "<<varList.size()<<" variables and " << hasRoot << " roots."<<std::endl;
661  std::sort(varList.begin(),varList.end());
662  //setup model
663  std::vector<LabelType> numStates(varList.size());
664  for(size_t i=0; i<varList.size(); ++i){
665  numStates[i] = gm_.numberOfLabels(varList[i]);
666  gmvar2ttvar[varList[i]] = i;
667  //std::cout << varList[i]<<" ";
668  }
669  //std::cout<<std::endl;
670 
671  MGM gmt(typename MGM::SpaceType(numStates.begin(),numStates.end()));
672  // Find factors an add those
673  std::vector<PositionAndLabel<IndexType,LabelType> > fixedVars;
674  std::vector<IndexType> freeVars;
675 
676  for(typename std::vector<IndexType>::iterator it=varList.begin(); it!= varList.end(); ++it){
677  for(typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(*it); fit !=gm_.factorsOfVariableEnd(*it); ++fit){
678  if( tFactor[*fit] ){
679  tFactor[*fit] = false;
680  //if(hasRoot) continue;
681  //factor is only a tentacle factor if the tencale has a root, othrewise it can be fixed by DP
682  tentacleFactor_[*fit]=hasRoot;
683  fixedVars.resize(0);
684  freeVars.resize(0);
685  IndexType pos = 0;
686  for(typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(*fit); vit!=gm_.variablesOfFactorEnd(*fit); ++vit){
687  if(fixVariable_[*vit]){
688  fixedVars.push_back(PositionAndLabel<IndexType,LabelType>(pos,fixVariableLabel_[*vit]));
689  }
690  else if(isInTentacle[*vit]){
691  freeVars.push_back(gmvar2ttvar[*vit]);
692  }
693  else{//no tentacle factor
694  OPENGM_ASSERT(hasRoot);
695  }
696  ++pos;
697  }
698  if(fixedVars.size()==0){//non fixed
699  const ViewFunction<GM> func(gm_[*fit]);
700  gmt.addFactor(gmt.addFunction(func),freeVars.begin(), freeVars.end());
701  }else{
702  const ViewFixVariablesFunction<GM> func(gm_[*fit], fixedVars);
703  gmt.addFactor(gmt.addFunction(func),freeVars.begin(), freeVars.end());
704  }
705  }
706  }
707  }
708  //if(hasRoot) continue;
709 
710  // Infer
711  if(gmt.maxFactorOrder()<=2){
712  //std::cout << "DP" <<std::endl;
714  typename DP::Parameter dpPara;
715 
716  if(hasRoot){
717  dpPara.roots_ = std::vector<IndexType>(1,gmvar2ttvar[root]);
718  DP dp(gmt,dpPara);
719  dp.infer();
720  std::vector<ValueType> values;
721  std::vector<IndexType> nodes;
722  std::vector<std::vector<LabelType> > substates;
723  dp.getNodeInfo(dpPara.roots_[0], values ,substates ,nodes );
724  OPENGM_ASSERT_OP( gm_.numberOfLabels(root), ==, substates.size());
725 
726  std::vector<std::vector<LabelType> > orderedSubstates(substates.size(),std::vector<LabelType>(varList.size(),0));
727  for(size_t i=0; i<orderedSubstates.size();++i){
728  OPENGM_ASSERT_OP(varList.size(),==,substates[i].size()+1);
729  OPENGM_ASSERT_OP(varList.size(),==,orderedSubstates[i].size());
730  orderedSubstates[i][dpPara.roots_[0]] = i;
731  for (size_t n=0; n<substates[i].size(); ++n)
732  orderedSubstates[i][nodes[n]]=substates[i][n];
733  }
734 
735  //tentacleRoots_.push_back(dpPara.roots_[0]);
736  tentacleRoots_.push_back(root);
737  LabelType shape = gm_.numberOfLabels(root);
739  for(LabelType l=0; l<shape; ++l)
740  func(&l) = values[l];
741  tentacleFunctions_.push_back(func);
742  tentacleLabelCandidates_.push_back(orderedSubstates);
743  tentacleVars_.push_back(varList);
744  for(size_t i=0; i<varList.size();++i){
745  if(varList[i]==root) continue;
746  fixVariable_[varList[i]]=true;
747  fixVariableLabel_[varList[i]]= 0; //only a dummy entry
748  }
749  }
750  else{
751  dpPara.roots_ = std::vector<IndexType>(1,0);
752  DP dp(gmt,dpPara);
753  dp.infer();
754 
755 /*
756  ValueType v;
757  std::vector<ValueType> values;
758  std::vector<IndexType> nodes;
759  std::vector<std::vector<LabelType> > substates;
760  dp.getNodeInfo(dpPara.roots_[0], values ,substates ,nodes );
761  ValueType optl=0;
762  for(LabelType l=1; l<values.size();++l)
763  if(ACC::bop(values[optl],values[l]))
764  optl=l;
765  for(size_t i=0; i<substates[optl].size();++i){
766  fixVariable_[varList[i]]=true;
767  fixVariableLabel_[varList[i]]=substates[optl][i];
768  }
769 */
770 
771 
772  std::vector<LabelType> arg(gmt.numberOfVariables(),0);
773  dp.arg(arg);
774  for(size_t i=0; i<arg.size();++i){
775  fixVariable_[varList[i]]=true;
776  fixVariableLabel_[varList[i]]=arg[i];
777  }
778 
779  }
780  }
781  else{
782  //std::cout << "BP" <<std::endl;
783  typedef opengm::BeliefPropagationUpdateRules<MGM,ACC> UpdateRulesType;
785  typename BP::Parameter para;
786  typename BP::IndependentFactorType m;
787  para.useNormalization_=false;
788  if(hasRoot){
789 
790  std::vector<ValueType> valuesdp;
791  std::vector<std::vector<LabelType> > substatesdp(gm_.numberOfLabels(root),std::vector<LabelType>(gmt.numberOfVariables(),0));
792 
793  //std::cout << "with root" <<std::endl;
794  // In order to use constrainedOptimum, we have to calculate all marginals, i.e. no tree-tricks can be used!
795  para.isAcyclic_ = opengm::Tribool::False;
796  para.inferSequential_= false;
797  para.maximumNumberOfSteps_ = gmt.numberOfVariables()-1;
798  BP bp(gmt,para);
799  bp.infer();
800  //bp.marginal(gmvar2ttvar[root], m);
801  LabelType shape = gm_.numberOfLabels(root);
803  std::vector<std::vector<LabelType> > substates(shape);
804  std::vector<IndexType> rootIndex(1,gmvar2ttvar[root]);
805  std::vector<LabelType> rootLabel(1,0);
806 
807  for(size_t i=0;i<shape;++i){
808  substates[i].resize(gmt.numberOfVariables(),0);
809  rootLabel[0]=i;
810  bp.constrainedOptimum(rootIndex,rootLabel,substates[i]);
811  OPENGM_ASSERT_OP(substates[i].size(),==,gmt.numberOfVariables());
812  func(&i) = gmt.evaluate(substates[i]);
813  OPENGM_ASSERT_OP(substates[i][gmvar2ttvar[root]],==,i);
814  }
815  //tentacleRoots_.push_back(gmvar2ttvar[root]);
816  tentacleRoots_.push_back(root);
817  tentacleFunctions_.push_back(func);
818  tentacleLabelCandidates_.push_back(substates);
819  tentacleVars_.push_back(varList);
820  for(size_t i=0; i<varList.size();++i){
821  if(varList[i]==root) continue;
822  fixVariable_[varList[i]]=true;
823  fixVariableLabel_[varList[i]]= 0; //only a dummy entry
824  }
825  }
826  else{
827  //std::cout << "with no root" <<std::endl;
828  para.useNormalization_ = true;
829  para.isAcyclic_ = opengm::Tribool::True;
830  para.inferSequential_= true;
831  BP bp(gmt,para);
832  //Bruteforce<MGM,ACC> bp(gmt);
833 
834  bp.infer();
835  std::vector<LabelType> arg;
836  bp.arg(arg);
837  for(IndexType i=0; i<gmt.numberOfVariables();++i){
838  fixVariable_[varList[i]]=true;
839  fixVariableLabel_[varList[i]]=arg[i];
840  }
841  }
842  }
843  //std::cout <<"x "<< std::endl;
844  ++numTentacles;
845  }
846  //std::cout <<"done "<< std::endl;
847  }
848 
850 // Private Methods
852  template<class GM>
853  void
854  GraphicalModelManipulator<GM>::expand(IndexType var, IndexType CCN, std::vector<bool>& closedVar)
855  {
856  if(closedVar[var])
857  return;
858  else{
859  closedVar[var] = true;
860  var2subProblem_[var] = CCN;
861  for( typename GM::ConstFactorIterator itf = gm_.factorsOfVariableBegin(var); itf!=gm_.factorsOfVariableEnd(var); ++itf){
862  for( typename GM::ConstVariableIterator itv = gm_.variablesOfFactorBegin(*itf); itv!=gm_.variablesOfFactorEnd(*itf);++itv){
863  expand(*itv, CCN, closedVar);
864  }
865  }
866  }
867  }
868 
869 
870 } //namespace opengm
871 
872 #endif // #ifndef OPENGM_GRAPHICALMODEL_HXX
Update rules for the MessagePassing framework.
Constant function.
Definition: constant.hxx:19
void modifiedState2OriginalState(const std::vector< LabelType > &, std::vector< LabelType > &) const
transforming label of the modified to the labeling of the original problem
IndexType addFactor(const FunctionIdentifier &, ITERATOR, ITERATOR)
add a factor to the graphical model
The OpenGM namespace.
Definition: config.hxx:43
bool isLocked() const
return true if model is locked
Discrete space in which variables can have differently many labels.
bool isFixed(const typename GM::IndexType) const
void buildModifiedModel()
build modified model
FunctionIdentifier addFunction(const FUNCTION_TYPE &)
add a function to the graphical model
void modifiedSubStates2OriginalState(const std::vector< std::vector< LabelType > > &, std::vector< LabelType > &) const
transforming label of the modified subproblems to the labeling of the original problem ...
ValueType evaluate(ITERATOR) const
evaluate the modeled function for a given labeling
STL namespace.
A framework for message passing algorithms Cf. F. R. Kschischang, B. J. Frey and H...
void fixVariable(const typename GM::IndexType, const typename GM::LabelType)
fix label for variable
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
GraphicalModel< ValueType, typename GM::OperatorType, MFunctionTypeList, MSpaceType > MGM
void buildModifiedSubModels()
build modified sub-models
reference to a Factor of a GraphicalModel
Definition: view.hxx:13
GraphicalModelManipulator(const GM &gm, const ManipulationMode mode=FIX)
#define OPENGM_ASSERT_OP(a, op, b)
runtime assertion
Definition: opengm.hxx:53
meta::TypeListGenerator< ViewFixVariablesFunction< GM >, ViewFunction< GM >, ConstantFunction< ValueType, IndexType, LabelType >, ExplicitFunction< ValueType, IndexType, LabelType > >::type MFunctionTypeList
const MGM & getModifiedModel() const
return the modified graphical model
const MGM & getModifiedSubModel(size_t) const
return the i-th modified sub graphical model
void freeVariable(const typename GM::IndexType)
remove fixed label for variable
const OGM & getOriginalModel() const
return the original graphical model
void freeAllVariables()
remove fixed label for all variable
size_t numberOfSubmodels() const
return the number of submodels
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
IndexType numberOfVariables() const
size_t maxFactorOrder() const
return maximum factor order
opengm::DiscreteSpace< IndexType, LabelType > MSpaceType