1 #ifndef OPENGM_AUX_FUSION_MOVER_HXX
2 #define OPENGM_AUX_FUSION_MOVER_HXX
16 #include "opengm/inference/fix-fusion/fusion-move.hpp"
39 :
public FunctionBase<FuseViewFunction<GM>, typename GM::ValueType, typename GM::IndexType, typename GM::LabelType>
52 const FactorType &factor,
53 const std::vector<LabelType> &argA,
54 const std::vector<LabelType> &argB
59 iteratorBuffer_(factor.numberOfVariables())
66 template<
class Iterator>
69 for (IndexType i = 0; i < iteratorBuffer_.size(); ++i)
74 iteratorBuffer_[i] = argA_->operator[](factor_->variableIndex(i));
78 iteratorBuffer_[i] = argB_->operator[](factor_->variableIndex(i));
81 return factor_->operator()(iteratorBuffer_.begin());
84 IndexType
shape(
const IndexType)
const
91 return iteratorBuffer_.size();
96 return std::pow(2, iteratorBuffer_.size());
99 FactorType
const *factor_;
100 std::vector<LabelType>
const *argA_;
101 std::vector<LabelType>
const *argB_;
102 mutable std::vector<LabelType> iteratorBuffer_;
108 :
public FunctionBase<FuseViewFixFunction<GM>, typename GM::ValueType, typename GM::IndexType, typename GM::LabelType>
121 const FactorType &factor,
122 const std::vector<LabelType> &argA,
123 const std::vector<LabelType> &argB
129 iteratorBuffer_(factor.numberOfVariables())
131 for (IndexType v = 0; v < factor.numberOfVariables(); ++v)
133 const IndexType vi = factor.variableIndex(v);
134 if (argA[vi] != argB[vi])
136 notFixedPos_.push_back(v);
140 iteratorBuffer_[v] = argA[vi];
147 template<
class Iterator>
150 for (IndexType i = 0; i < notFixedPos_.size(); ++i)
152 const IndexType nfp = notFixedPos_[i];
156 iteratorBuffer_[nfp] = argA_->operator[](factor_->variableIndex(nfp));
160 iteratorBuffer_[nfp] = argB_->operator[](factor_->variableIndex(nfp));
163 return factor_->operator()(iteratorBuffer_.begin());
166 IndexType
shape(
const IndexType)
const
173 return notFixedPos_.size();
178 return std::pow(2, notFixedPos_.size());
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_;
188 template<
class MODEL_TYPE>
204 template<
class F,
class ITER>
207 model_->addFactor(
model_->addFunction(f), viBegin, viEnd);
214 template<
class MODEL_TYPE>
235 model_ =
new MODEL_TYPE(nVar, 0);
243 template<
class F,
class ITER>
248 if (f.dimension() == 1)
255 viBegin[0], viBegin[1],
271 template<
class MODEL_TYPE>
289 template<
class F,
class ITER>
292 model_->addFactor(viBegin, viEnd, f);
301 template<
class GM,
class ACC>
320 typedef typename meta::TypeListGenerator< FuseViewingFunction, FuseViewingFixingFunction, ArrayFunction >::type
SubFunctionTypeList;
327 const std::vector<LabelType> &argA,
328 const std::vector<LabelType> &argB,
329 std::vector<LabelType> &resultArg,
340 template<
class SOLVER>
342 const typename SOLVER::Parameter ¶m,
343 const bool warmStart =
false
347 template<
class SOLVER>
349 const typename SOLVER::Parameter ¶m
352 template<
class SOLVER>
357 template<
class SOLVER>
375 template<
class MODEL_PROXY>
376 void fillSubModel(MODEL_PROXY &modelProy);
379 static const size_t maxOrder_ = 9;
381 const GraphicalModelType &gm_;
383 std::vector<LabelType>
const *argA_;
384 std::vector<LabelType>
const *argB_;
385 std::vector<LabelType>
const *argBest_;
386 std::vector<LabelType> *argResult_;
390 ValueType valueBest_;
391 ValueType valueResult_;
396 std::vector<LabelType> subSpace_;
397 std::vector<IndexType> localToGlobalVi_;
398 std::vector<IndexType> globalToLocalVi_;
399 IndexType nLocalVar_;
404 template<
class GM,
class ACC>
418 typedef kolmogorov::qpbo::QPBO<double> QpboSubInf;
442 const size_t maxSubgraphSize = 2,
443 const bool reducedInf =
false,
444 const bool tentacles =
false,
445 const bool connectedComponents =
false,
446 const double fusionTimeLimit = 100.0
470 factorOrder_(gm.factorOrder()) {
484 throw RuntimeError(
"WITH_QPBO need to be enabled for QpboFusion");
489 throw RuntimeError(
"WITH_CPLEX need to be enabled for CplexFusion");
494 throw RuntimeError(
"WITH_QPBO need to be enabled for reducedInference");
501 bool fuse(
const LabelVector & argA,
const LabelVector argB, LabelVector & argRes,
502 const ValueType valA,
const ValueType valB,ValueType & valRes){
504 fusionMover_.
setup(argA, argB, argRes, valA, valB);
512 valRes = fusionMover_.
template fuseQpbo<QpboSubInf> ();
515 typename HQPBOSubInf::Parameter subInfParam;
516 valRes = fusionMover_.
template fuse<HQPBOSubInf> (subInfParam,
true);
527 typename _CplexSubInf::Parameter _subInfParam;
528 _subInfParam.integerConstraint_ =
true;
529 _subInfParam.numberOfThreads_ = 1;
532 valRes = fusionMover_.
template fuse<CplexReducedSubInf> (subInfParam,
true);
537 typename CplexSubInf::Parameter p;
538 p.integerConstraint_ =
true;
539 p.numberOfThreads_ = 1;
541 valRes = fusionMover_.
template fuse<CplexSubInf> (p,
true);
550 typename _LfSubInf::Parameter _subInfParam;
553 valRes = fusionMover_.
template fuse<LfReducedSubInf> (subInfParam,
true);
558 valRes = fusionMover_.
template fuse<LazyFlipperSubInf> (fuseInfParam,
true);
562 throw RuntimeError(
"Unknown Fusion Type! Maybe caused by missing linking!");
572 const GraphicalModelType & gm_;
574 FusionMoverType fusionMover_;
671 template<
class GM,
class ACC>
675 subSpace_(gm.numberOfVariables(), 2),
676 localToGlobalVi_(gm.numberOfVariables()),
677 globalToLocalVi_(gm.numberOfVariables()),
684 template<
class GM,
class ACC>
694 for (IndexType vi = 0; vi < gm_.numberOfVariables(); ++vi)
696 if (argA[vi] != argB[vi])
698 localToGlobalVi_[nLocalVar_] = vi;
699 globalToLocalVi_[vi] = nLocalVar_;
703 std::copy(argA.begin(), argA.end(), resultArg.begin());
708 argResult_ = &resultArg;
713 if (ACC::bop(valueA, valueB))
728 template<
class GM,
class ACC>
729 template<
class MODEL_PROXY>
736 modelProxy.createModel(nLocalVar_);
737 std::set<IndexType> addedFactors;
738 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
741 const IndexType vi = localToGlobalVi_[lvi];
742 const IndexType nFacVi = gm_.numberOfFactors(vi);
744 for (IndexType f = 0; f < nFacVi; ++f)
746 const IndexType fi = gm_.factorOfVariable(vi, f);
747 const IndexType fOrder = gm_.numberOfVariables(fi);
752 OPENGM_CHECK_OP( localToGlobalVi_[lvi], == , gm_[fi].variableIndex(0),
"internal error");
753 OPENGM_CHECK_OP( globalToLocalVi_[gm_[fi].variableIndex(0)], == , lvi,
"internal error");
755 const IndexType vis[] = {lvi};
756 const IndexType globalVi = localToGlobalVi_[lvi];
758 ArrayFunction f(subSpace_.begin(), subSpace_.begin() + 1);
761 const LabelType c[] = { (*argA_)[globalVi], (*argB_)[globalVi] };
763 f(1) = gm_[fi](c + 1);
767 modelProxy.addFactor(f, vis, vis + 1);
771 else if ( addedFactors.find(fi) == addedFactors.end() )
773 addedFactors.insert(fi);
774 IndexType fixedVar = 0;
775 IndexType notFixedVar = 0;
777 for (IndexType vf = 0; vf < fOrder; ++vf)
779 const IndexType viFactor = gm_[fi].variableIndex(vf);
780 if ((*argA_)[viFactor] != (*argB_)[viFactor])
799 std::vector<IndexType> lvis(fOrder);
800 for (IndexType vf = 0; vf < fOrder; ++vf)
802 lvis[vf] = globalToLocalVi_[gm_[fi].variableIndex(vf)];
806 FuseViewingFunction f(gm_[fi], *argA_, *argB_);
812 modelProxy.addFactor(f, lvis.begin(), lvis.end());
824 std::vector<IndexType> lvis;
825 lvis.reserve(notFixedVar);
826 for (IndexType vf = 0; vf < fOrder; ++vf)
828 const IndexType gvi = gm_[fi].variableIndex(vf);
829 if ((*argA_)[gvi] != (*argB_)[gvi])
831 lvis.push_back(globalToLocalVi_[gvi]);
838 FuseViewingFixingFunction f(gm_[fi], *argA_, *argB_);
840 modelProxy.addFactor(f, lvis.begin(), lvis.end());
853 template<
class GM,
class ACC>
854 template<
class SOLVER>
855 typename FusionMover<GM, ACC>::ValueType
857 const typename SOLVER::Parameter ¶m,
863 this->fillSubModel(modelProxy);
869 SOLVER solver(*(modelProxy.
model_), param);
870 std::vector<LabelType> localArg(nLocalVar_);
873 std::fill( localArg.begin(), localArg.end(),bestLabel_);
874 solver.setStartingPoint(localArg.begin());
878 solver.arg(localArg);
879 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
881 const IndexType globalVi = localToGlobalVi_[lvi];
883 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
885 valueResult_ = gm_.evaluate(*argResult_);
886 if (AccumulationType::bop(valueBest_, valueResult_))
888 valueResult_ = valueBest_;
889 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
893 valueResult_ = valueBest_;
900 template<
class GM,
class ACC>
901 template<
class SOLVER>
904 const typename SOLVER::Parameter ¶m
909 this->fillSubModel(modelProxy);
913 std::vector<LabelType> localArg(nLocalVar_);
914 modelProxy.
model_->infer();
915 modelProxy.
model_->arg(localArg);
917 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
919 const IndexType globalVi = localToGlobalVi_[lvi];
921 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
923 valueResult_ = gm_.evaluate(*argResult_);
925 if (AccumulationType::bop(valueBest_, valueResult_))
927 valueResult_ = valueBest_;
928 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
936 template<
class GM,
class ACC>
937 template<
class SOLVER>
944 this->fillSubModel(modelProxy);
947 modelProxy.
model_->MergeParallelEdges();
950 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
952 const IndexType globalVi = localToGlobalVi_[lvi];
953 modelProxy.
model_->SetLabel(lvi, bestLabel_);
958 modelProxy.
model_->Improve();
961 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
963 const IndexType globalVi = localToGlobalVi_[lvi];
965 if (l == 0 || l == 1)
967 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
971 (*argResult_)[globalVi] = (*argBest_)[globalVi];
974 valueResult_ = gm_.evaluate(*argResult_);
975 if (AccumulationType::bop(valueBest_, valueResult_))
977 valueResult_ = valueBest_;
978 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
985 template<
class GM,
class ACC>
986 template<
class SOLVER>
995 this->fillSubModel(modelProxy);
1000 unsigned int maxNumAssignments = 1 << maxOrder_;
1001 std::vector<ValueType> coeffs(maxNumAssignments);
1002 std::vector<LabelType> cliqueLabels(maxOrder_);
1004 HigherOrderEnergy<ValueType, maxOrder_> hoe;
1015 IndexType var = subGm[f].variableIndex(0);
1021 ValueType e0 = subGm[f](lla);
1022 ValueType e1 = subGm[f](llb);
1023 hoe.AddUnaryTerm(var, e1 - e0);
1029 unsigned int numAssignments = 1 << size;
1033 for (
unsigned int subset = 1; subset < numAssignments; ++subset)
1040 for (
unsigned int assignment = 0; assignment < numAssignments; ++assignment)
1042 for (
unsigned int i = 0; i < size; ++i)
1045 if (assignment & (1 << i))
1047 cliqueLabels[i] = 0;
1051 cliqueLabels[i] = 1;
1054 ValueType energy = subGm[f](cliqueLabels.begin());
1055 for (
unsigned int subset = 1; subset < numAssignments; ++subset)
1058 if (assignment & ~subset)
1066 for (
unsigned int b = 0; b < size; ++b)
1068 parity ^= (((assignment ^ subset) & (1 << b)) != 0);
1070 coeffs[subset] += parity ? -energy : energy;
1074 typename HigherOrderEnergy<ValueType, maxOrder_> ::VarId vars[maxOrder_];
1075 for (
unsigned int subset = 1; subset < numAssignments; ++subset)
1078 for (
unsigned int b = 0; b < size; ++b)
1080 if (subset & (1 << b))
1082 vars[degree++] = subGm[f].variableIndex(b);
1085 std::sort(vars, vars + degree);
1086 hoe.AddTerm(coeffs[subset], degree, vars);
1091 hoe.ToQuadratic(qr);
1093 IndexType numberOfChangedVariables = 0;
1097 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
1099 const IndexType globalVi = localToGlobalVi_[lvi];
1101 if (l == 0 || l == 1)
1103 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
1107 (*argResult_)[globalVi] = (*argBest_)[globalVi];
1110 valueResult_ = gm_.evaluate(*argResult_);
1111 if (AccumulationType::bop(valueBest_, valueResult_))
1113 valueResult_ = valueBest_;
1114 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
1117 return valueResult_;
1124 #endif //OPENGM_AUX_FUSION_MOVER_HXX
ValueType fuseAd3(const typename SOLVER::Parameter ¶m)
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)
Fallback implementation of member functions of OpenGM functions.
FusionMover< GraphicalModelType, AccumulationType > FusionMoverType
ViewFixVariablesFunction< GM > FixFunction
GM::OperatorType OperatorType
IndexType shape(const IndexType) const
Ad3ModelProxy(const typename MODEL_TYPE::Parameter param)
Discrete space in which all variables have the same number of labels.
ValueType operator()(Iterator begin) const
FuseViewFunction(const FactorType &factor, const std::vector< LabelType > &argA, const std::vector< LabelType > &argB)
FusionMoverType::SubGmType SubGmType
ExplicitFunction< ValueType, IndexType, LabelType > ArrayFunction
void createModel(const UInt64Type nVar)
void addFactor(const F &f, ITER viBegin, ITER viEnd)
FusionMover(const GM &gm)
IndexType numberOfFusionMoveVariable() const
ValueType valueResult() const
FuseViewFunction< GM > FuseViewingFunction
GM::FactorType FactorType
detail_types::UInt64Type UInt64Type
uint64
meta::TypeListGenerator< FuseViewingFunction, FuseViewingFixingFunction, ArrayFunction >::type SubFunctionTypeList
GraphicalModel< ValueType, typename GM::OperatorType, SubFunctionTypeList, SubSpaceType > SubGmType
MODEL_TYPE::SpaceType SpaceType
ValueType operator()(Iterator begin) const
opengm::SimpleDiscreteSpace< IndexType, LabelType > SubSpaceType
Optimization by Linear Programming (LP) or Integer LP using IBM ILOG CPLEX http://www.ilog.com/products/cplex/.
FusionSolver fusionSolver_
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)
bool connectedComponents_
FuseViewFixFunction< GM > FuseViewingFixingFunction
IndexType dimension() const
void setup(const std::vector< LabelType > &argA, const std::vector< LabelType > &argB, std::vector< LabelType > &resultArg, const ValueType valueA, const ValueType valueB)
std::vector< LabelType > LabelVector
HlFusionMover(const GM &gm, const Parameter ¶m)
#define OPENGM_CHECK_OP(A, OP, B, TXT)
GM::OperatorType OperatorType
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
IndexType numberOfVariables() const
A generalization of ICM B. Andres, J. H. Kappes, U. Koethe and Hamprecht F. A., The Lazy Flipper: MA...
MODEL_TYPE::Parameter param_
void addFactor(const F &f, ITER viBegin, ITER viEnd)
ValueType fuse(const typename SOLVER::Parameter ¶m, const bool warmStart=false)
[class reducedinference] Reduced Inference Implementation of the reduction techniques proposed in J...
void addFactor(const F &f, ITER viBegin, ITER viEnd)
IndexType numberOfFactors() const
opengm::LazyFlipper< SubGmType, AccumulationType > LazyFlipperSubInf
void createModel(const UInt64Type nVar)
void createModel(const UInt64Type nVar)
GM::FactorType FactorType
IndexType shape(const IndexType) const
IndexType dimension() const