2 #ifndef OPENGM_GRAPHICALMODEL_MANIPULATOR_HXX
3 #define OPENGM_GRAPHICALMODEL_MANIPULATOR_HXX
62 typedef typename meta::TypeListGenerator<
87 void fixVariable(
const typename GM::IndexType,
const typename GM::LabelType);
93 bool isFixed(
const typename GM::IndexType)
const;
96 void expand(IndexType, IndexType, std::vector<bool>&);
101 std::vector<bool> fixVariable_;
102 std::vector<LabelType> fixVariableLabel_;
110 bool validSubModels_;
111 std::vector<MGM> submodels_;
112 std::vector<IndexType> var2subProblem_;
115 std::vector<IndexType> tentacleRoots_;
116 std::vector<opengm::ExplicitFunction<ValueType,IndexType,LabelType> > tentacleFunctions_;
117 std::vector<std::vector<std::vector<LabelType> > > tentacleLabelCandidates_;
118 std::vector<std::vector<IndexType> > tentacleVars_;
119 std::vector<bool> tentacleFactor_;
120 ValueType tentacleConstValue_;
129 return fixVariable_[vi];
136 fixVariable_(
std::vector<
bool>(gm.numberOfVariables(),false)),
137 fixVariableLabel_(
std::vector<
LabelType>(gm.numberOfVariables(),0)),
140 validSubModels_(false),
141 var2subProblem_(
std::vector<
IndexType>(gm.numberOfVariables(),0))
170 return submodels_[i];
178 return submodels_.size();
186 validSubModels_=
false;
197 tentacleFactor_.resize(gm_.numberOfFactors(),
false);
214 fixVariable_[var]=
true;
215 fixVariableLabel_[var]=l;
225 fixVariable_[var]=
false;
236 for(
IndexType var=0; var<fixVariable_.size(); ++var)
237 fixVariable_[var]=
false;
248 if(isLocked() && ml.size()==mgm_.numberOfVariables()){
249 ol.resize(gm_.numberOfVariables());
251 for(
IndexType var=0; var<gm_.numberOfVariables(); ++var){
252 if(fixVariable_[var]){
253 ol[var] = fixVariableLabel_[var];
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];
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());
279 for(
IndexType var=0; var<gm_.numberOfVariables(); ++var){
280 if(fixVariable_[var]){
281 conf[var] = fixVariableLabel_[var];
284 conf[var] = subconf[sp][varCount[sp]++];
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];
305 std::vector<IndexType> varMap(gm_.numberOfVariables(),0);
308 for(
IndexType var=0; var<gm_.numberOfVariables();++var){
309 if(fixVariable_[var]==
false){
310 varMap[var] = numberOfVariables++;
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);
324 std::vector<PositionAndLabel<IndexType,LabelType> > fixedVars;
325 std::vector<IndexType> MVars;
329 GM::OperatorType::neutral(constant);
330 for(
IndexType f=0; f<gm_.numberOfFactors();++f){
331 if(tentacleFactor_[f])
continue;
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]));
339 MVars.push_back(varMap[var]);
343 if(fixedVars.size()==0){
345 mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.end());
346 }
else if(fixedVars.size()==gm_[f].numberOfVariables()){
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)];
351 GM::OperatorType::op(gm_[f](fixedStates.begin()),constant);
354 mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.end());
356 }
else if(mode_==DROP){
357 if(fixedVars.size()==0){
359 mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.end());
362 throw std::runtime_error(
"Unsupported manipulation mode");
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);
377 mgm_.addFactor(mgm_.addFunction(func),MVars.begin(), MVars.begin());
389 validSubModels_ =
true;
392 std::vector<bool> closedVar = fixVariable_;
394 for(
IndexType var=0 ; var<gm_.numberOfVariables(); ++var){
398 expand(var, numberOfSubproblems, closedVar);
400 ++numberOfSubproblems;
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]]++;
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);
415 for(
IndexType var=0; var<gm_.numberOfVariables(); ++var){
416 if(fixVariable_[var]==
false){
417 shape[var2subProblem_[var]][varMap[var]] = gm_.numberOfLabels(var);
420 for (
size_t i=0; i<numberOfSubproblems; ++i){
421 MSpaceType space(shape[i].begin(),shape[i].end());
422 submodels_[i] =
MGM(space);
425 std::vector<PositionAndLabel<IndexType,LabelType> > fixedVars;
426 std::vector<IndexType> MVars;
429 GM::OperatorType::neutral(constant);
431 for(
IndexType f=0; f<gm_.numberOfFactors();++f){
432 if(tentacleFactor_[f])
continue;
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]));
441 MVars.push_back(varMap[var]);
442 subproblem = var2subProblem_[var];
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)];
451 GM::OperatorType::op(gm_[f](fixedStates.begin()),constant);
453 else if(fixedVars.size()==0){
455 submodels_[subproblem].addFactor(submodels_[subproblem].addFunction(func),MVars.begin(), MVars.end());
458 submodels_[subproblem].addFactor(submodels_[subproblem].addFunction(func),MVars.begin(), MVars.end());
460 }
else if(mode_==DROP){
461 if(fixedVars.size()==0){
463 submodels_[subproblem].addFactor(submodels_[subproblem].addFunction(func),MVars.begin(), MVars.end());
466 throw std::runtime_error(
"Unsupported manipulation mode");
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);
480 submodels_[0].addFactor( submodels_[0].addFunction(func),MVars.begin(), MVars.begin());
498 if(mode_!=FIX)
throw std::runtime_error (
"lockAndTentacelElimination only supports the mode FIX, yet");
501 tentacleFactor_.resize(gm_.numberOfFactors(),
false);
502 std::vector<bool> tFactor(gm_.numberOfFactors(),
false);
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;
513 for(
IndexType factor = 0 ; factor < gm_.numberOfFactors() ; ++factor){
515 for(
typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(factor); vit!=gm_.variablesOfFactorEnd(factor); ++vit){
516 if(!fixVariable_[*vit]){
517 ++factorDegree[factor];
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;
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;
540 if(leafs.size()==0)
return;
544 std::map<IndexType, IndexType> representives;
545 typename std::set<typename GM::IndexType>::iterator it;
546 typename std::set<typename GM::IndexType>::iterator fi;
548 while(!leafs.empty()){
553 for(
typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(var); fit !=gm_.factorsOfVariableEnd(var); ++fit){
555 --factorDegree[*fit];
556 if(factorDegree[*fit]<=1){
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]){
566 --variableDegree[*vit];
567 if(variableDegree[*vit]==1 && !pushed2Leafs[*vit] ){
568 leafs.push_back(*vit);
569 pushed2Leafs[*vit] =
true;
571 isInTentacle[*vit] =
true;
581 for(
IndexType var=0; var<gm_.numberOfVariables(); ++var){
582 if( isInTentacle[var] )
584 if( isInTentacle[var] && variableDegree[var]>0){
589 if( isInTentacle[var] && variableDegree[var]==0){
590 for(
typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(var); fit !=gm_.factorsOfVariableEnd(var); ++fit){
595 for(
IndexType factor=0; factor<gm_.numberOfFactors();++factor){
598 for(
typename GM::ConstVariableIterator vit=gm_.variablesOfFactorBegin(factor); vit!=gm_.variablesOfFactorEnd(factor); ++vit){
599 if(!fixVariable_[*vit] && variableDegree[*vit]>0) ++count;
608 for(
IndexType var=0; var<gm_.numberOfVariables(); ++var){
613 tentacleRoots_.reserve(numRootVars);
614 tentacleFunctions_.reserve(numRootVars);
615 tentacleLabelCandidates_.reserve(numRootVars);
616 tentacleVars_.reserve(numRootVars);
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;
626 std::vector<IndexType> varList;
628 bool hasRoot =
false;
630 varList.push_back(var);
631 visitedVar[var] =
true;
632 while(i<varList.size()){
643 for(
typename GM::ConstFactorIterator fit=gm_.factorsOfVariableBegin(v); fit !=gm_.factorsOfVariableEnd(v); ++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);
661 std::sort(varList.begin(),varList.end());
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;
673 std::vector<PositionAndLabel<IndexType,LabelType> > fixedVars;
674 std::vector<IndexType> freeVars;
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){
679 tFactor[*fit] =
false;
682 tentacleFactor_[*fit]=hasRoot;
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]));
690 else if(isInTentacle[*vit]){
691 freeVars.push_back(gmvar2ttvar[*vit]);
698 if(fixedVars.size()==0){
714 typename DP::Parameter dpPara;
717 dpPara.roots_ = std::vector<IndexType>(1,gmvar2ttvar[root]);
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 );
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){
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];
736 tentacleRoots_.push_back(root);
737 LabelType shape = gm_.numberOfLabels(root);
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;
751 dpPara.roots_ = std::vector<IndexType>(1,0);
774 for(
size_t i=0; i<arg.size();++i){
775 fixVariable_[varList[i]]=
true;
776 fixVariableLabel_[varList[i]]=arg[i];
785 typename BP::Parameter para;
786 typename BP::IndependentFactorType m;
787 para.useNormalization_=
false;
790 std::vector<ValueType> valuesdp;
791 std::vector<std::vector<LabelType> > substatesdp(gm_.numberOfLabels(root),std::vector<LabelType>(gmt.
numberOfVariables(),0));
796 para.inferSequential_=
false;
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);
807 for(
size_t i=0;i<shape;++i){
810 bp.constrainedOptimum(rootIndex,rootLabel,substates[i]);
812 func(&i) = gmt.
evaluate(substates[i]);
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;
828 para.useNormalization_ =
true;
830 para.inferSequential_=
true;
835 std::vector<LabelType> arg;
838 fixVariable_[varList[i]]=
true;
839 fixVariableLabel_[varList[i]]=arg[i];
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);
872 #endif // #ifndef OPENGM_GRAPHICALMODEL_HXX
Update rules for the MessagePassing framework.
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
bool isLocked() const
return true if model is locked
GraphicalModelManipulator.
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
void unlock()
unlock model
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)
GraphicalModel< ValueType, typename GM::OperatorType, MFunctionTypeList, MSpaceType > MGM
void buildModifiedSubModels()
build modified sub-models
reference to a Factor of a GraphicalModel
GraphicalModelManipulator(const GM &gm, const ManipulationMode mode=FIX)
#define OPENGM_ASSERT_OP(a, op, b)
runtime assertion
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
void lockAndTentacelElimination()
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