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>
197 model_ =
new MODEL_TYPE(SpaceType(nVar, 2));
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);
236 model_->AddNode(nVar);
243 template<
class F,
class ITER>
248 if (f.dimension() == 1)
250 model_->AddUnaryTerm(*viBegin, f(c00_), f(c11_));
254 model_->AddPairwiseTerm(
255 viBegin[0], viBegin[1],
271 template<
class MODEL_TYPE>
282 model_ =
new MODEL_TYPE(nVar, 2, param_,
true);
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_;
396 std::vector<LabelType> subSpace_;
397 std::vector<IndexType> localToGlobalVi_;
398 std::vector<IndexType> globalToLocalVi_;
404 template<
class GM,
class ACC>
414 template<
class _GM,
class _ACC>
430 typedef kolmogorov::qpbo::QPBO<double> QpboSubInf;
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
461 fusionSolver_(fusionSolver),
462 maxSubgraphSize_(maxSubgraphSize),
463 reducedInf_(reducedInf),
464 connectedComponents_(connectedComponents),
465 tentacles_(tentacles),
466 fusionTimeLimit_(fusionTimeLimit)
474 fusionSolver_(p.fusionSolver_),
475 maxSubgraphSize_(p.maxSubgraphSize_),
476 reducedInf_(p.reducedInf_),
477 connectedComponents_(p.connectedComponents_),
478 tentacles_(p.tentacles_),
479 fusionTimeLimit_(p.fusionTimeLimit_)
497 factorOrder_(gm.factorOrder()) {
500 if(param_.fusionSolver_==DefaulFusion){
501 param_.fusionSolver_= LazyFlipperFusion;
503 param_.fusionSolver_ = QpboFusion;
509 if(param_.fusionSolver_ == QpboFusion){
511 throw RuntimeError(
"WITH_QPBO need to be enabled for QpboFusion");
514 if(param_.fusionSolver_ == CplexFuison){
516 throw RuntimeError(
"WITH_CPLEX need to be enabled for CplexFusion");
519 if(param_.reducedInf_){
521 throw RuntimeError(
"WITH_QPBO need to be enabled for reducedInference");
528 bool fuse(
const LabelVector & argA,
const LabelVector argB, LabelVector & argRes,
531 fusionMover_.setup(argA, argB, argRes, valA, valB);
535 if(fusionMover_.numberOfFusionMoveVariable()>0){
536 if(param_.fusionSolver_ == QpboFusion){
539 valRes = fusionMover_.
template fuseQpbo<QpboSubInf> ();
542 typename HQPBOSubInf::Parameter subInfParam;
543 valRes = fusionMover_.
template fuse<HQPBOSubInf> (subInfParam,
true);
547 else if(param_.fusionSolver_ == CplexFuison){
550 if(param_.reducedInf_){
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);
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);
572 else if(param_.fusionSolver_ == LazyFlipperFusion){
573 if(param_.reducedInf_){
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);
585 valRes = fusionMover_.
template fuse<LazyFlipperSubInf> (fuseInfParam,
true);
589 throw RuntimeError(
"Unknown Fusion Type! Maybe caused by missing linking!");
599 const GraphicalModelType & gm_;
601 FusionMoverType fusionMover_;
698 template<
class GM,
class ACC>
702 subSpace_(gm.numberOfVariables(), 2),
703 localToGlobalVi_(gm.numberOfVariables()),
704 globalToLocalVi_(gm.numberOfVariables()),
711 template<
class GM,
class ACC>
721 for (IndexType vi = 0; vi < gm_.numberOfVariables(); ++vi)
723 if (argA[vi] != argB[vi])
725 localToGlobalVi_[nLocalVar_] = vi;
726 globalToLocalVi_[vi] = nLocalVar_;
730 std::copy(argA.begin(), argA.end(), resultArg.begin());
735 argResult_ = &resultArg;
740 if (ACC::bop(valueA, valueB))
755 template<
class GM,
class ACC>
756 template<
class MODEL_PROXY>
763 modelProxy.createModel(nLocalVar_);
764 std::set<IndexType> addedFactors;
765 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
768 const IndexType vi = localToGlobalVi_[lvi];
769 const IndexType nFacVi = gm_.numberOfFactors(vi);
771 for (IndexType f = 0; f < nFacVi; ++f)
773 const IndexType fi = gm_.factorOfVariable(vi, f);
774 const IndexType fOrder = gm_.numberOfVariables(fi);
779 OPENGM_CHECK_OP( localToGlobalVi_[lvi], == , gm_[fi].variableIndex(0),
"internal error");
780 OPENGM_CHECK_OP( globalToLocalVi_[gm_[fi].variableIndex(0)], == , lvi,
"internal error");
782 const IndexType vis[] = {lvi};
783 const IndexType globalVi = localToGlobalVi_[lvi];
788 const LabelType c[] = { (*argA_)[globalVi], (*argB_)[globalVi] };
790 f(1) = gm_[fi](c + 1);
794 modelProxy.addFactor(f, vis, vis + 1);
798 else if ( addedFactors.find(fi) == addedFactors.end() )
800 addedFactors.insert(fi);
801 IndexType fixedVar = 0;
802 IndexType notFixedVar = 0;
804 for (IndexType vf = 0; vf < fOrder; ++vf)
806 const IndexType viFactor = gm_[fi].variableIndex(vf);
807 if ((*argA_)[viFactor] != (*argB_)[viFactor])
826 std::vector<IndexType> lvis(fOrder);
827 for (IndexType vf = 0; vf < fOrder; ++vf)
829 lvis[vf] = globalToLocalVi_[gm_[fi].variableIndex(vf)];
839 modelProxy.addFactor(f, lvis.begin(), lvis.end());
851 std::vector<IndexType> lvis;
852 lvis.reserve(notFixedVar);
853 for (IndexType vf = 0; vf < fOrder; ++vf)
855 const IndexType gvi = gm_[fi].variableIndex(vf);
856 if ((*argA_)[gvi] != (*argB_)[gvi])
858 lvis.push_back(globalToLocalVi_[gvi]);
867 modelProxy.addFactor(f, lvis.begin(), lvis.end());
880 template<
class GM,
class ACC>
881 template<
class SOLVER>
884 const typename SOLVER::Parameter ¶m,
890 this->fillSubModel(modelProxy);
896 SOLVER solver(*(modelProxy.
model_), param);
897 std::vector<LabelType> localArg(nLocalVar_);
900 std::fill( localArg.begin(), localArg.end(),bestLabel_);
901 solver.setStartingPoint(localArg.begin());
905 solver.arg(localArg);
906 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
908 const IndexType globalVi = localToGlobalVi_[lvi];
910 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
912 valueResult_ = gm_.evaluate(*argResult_);
913 if (AccumulationType::bop(valueBest_, valueResult_))
915 valueResult_ = valueBest_;
916 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
920 valueResult_ = valueBest_;
927 template<
class GM,
class ACC>
928 template<
class SOLVER>
931 const typename SOLVER::Parameter ¶m
936 this->fillSubModel(modelProxy);
940 std::vector<LabelType> localArg(nLocalVar_);
941 modelProxy.
model_->infer();
942 modelProxy.
model_->arg(localArg);
944 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
946 const IndexType globalVi = localToGlobalVi_[lvi];
948 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
950 valueResult_ = gm_.evaluate(*argResult_);
952 if (AccumulationType::bop(valueBest_, valueResult_))
954 valueResult_ = valueBest_;
955 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
963 template<
class GM,
class ACC>
964 template<
class SOLVER>
971 this->fillSubModel(modelProxy);
974 modelProxy.
model_->MergeParallelEdges();
977 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
979 const IndexType globalVi = localToGlobalVi_[lvi];
980 modelProxy.
model_->SetLabel(lvi, bestLabel_);
985 modelProxy.
model_->Improve();
988 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
990 const IndexType globalVi = localToGlobalVi_[lvi];
992 if (l == 0 || l == 1)
994 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
998 (*argResult_)[globalVi] = (*argBest_)[globalVi];
1001 valueResult_ = gm_.evaluate(*argResult_);
1002 if (AccumulationType::bop(valueBest_, valueResult_))
1004 valueResult_ = valueBest_;
1005 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
1008 return valueResult_;
1012 template<
class GM,
class ACC>
1013 template<
class SOLVER>
1022 this->fillSubModel(modelProxy);
1027 unsigned int maxNumAssignments = 1 << maxOrder_;
1028 std::vector<ValueType> coeffs(maxNumAssignments);
1029 std::vector<LabelType> cliqueLabels(maxOrder_);
1031 HigherOrderEnergy<ValueType, maxOrder_> hoe;
1042 IndexType var = subGm[f].variableIndex(0);
1048 ValueType e0 = subGm[f](lla);
1049 ValueType e1 = subGm[f](llb);
1050 hoe.AddUnaryTerm(var, e1 - e0);
1056 unsigned int numAssignments = 1 << size;
1060 for (
unsigned int subset = 1; subset < numAssignments; ++subset)
1067 for (
unsigned int assignment = 0; assignment < numAssignments; ++assignment)
1069 for (
unsigned int i = 0; i < size; ++i)
1072 if (assignment & (1 << i))
1074 cliqueLabels[i] = 0;
1078 cliqueLabels[i] = 1;
1081 ValueType energy = subGm[f](cliqueLabels.begin());
1082 for (
unsigned int subset = 1; subset < numAssignments; ++subset)
1085 if (assignment & ~subset)
1093 for (
unsigned int b = 0; b < size; ++b)
1095 parity ^= (((assignment ^ subset) & (1 << b)) != 0);
1097 coeffs[subset] += parity ? -energy : energy;
1101 typename HigherOrderEnergy<ValueType, maxOrder_> ::VarId vars[maxOrder_];
1102 for (
unsigned int subset = 1; subset < numAssignments; ++subset)
1105 for (
unsigned int b = 0; b < size; ++b)
1107 if (subset & (1 << b))
1109 vars[degree++] = subGm[f].variableIndex(b);
1112 std::sort(vars, vars + degree);
1113 hoe.AddTerm(coeffs[subset], degree, vars);
1118 hoe.ToQuadratic(qr);
1120 IndexType numberOfChangedVariables = 0;
1124 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
1126 const IndexType globalVi = localToGlobalVi_[lvi];
1128 if (l == 0 || l == 1)
1130 (*argResult_)[globalVi] = (l == 0 ? (*argA_)[globalVi] : (*argB_)[globalVi]) ;
1134 (*argResult_)[globalVi] = (*argBest_)[globalVi];
1137 valueResult_ = gm_.evaluate(*argResult_);
1138 if (AccumulationType::bop(valueBest_, valueResult_))
1140 valueResult_ = valueBest_;
1141 std::copy(argBest_->begin(), argBest_->end(), argResult_->begin());
1144 return valueResult_;
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)
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
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
meta::TypeListGenerator< FuseViewingFunction, FuseViewingFixingFunction, ArrayFunction >::type SubFunctionTypeList
GraphicalModel< ValueType, typename GM::OperatorType, SubFunctionTypeList, SubSpaceType > SubGmType
ValueType operator()(Iterator begin) const
MODEL_TYPE::SpaceType SpaceType
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/.
FusionSolver fusionSolver_
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)
bool connectedComponents_
FuseViewFixFunction< GM > FuseViewingFixingFunction
IndexType numberOfVariables() const
std::vector< LabelType > LabelVector
HlFusionMover(const GM &gm, const Parameter ¶m)
#define OPENGM_CHECK_OP(A, OP, B, TXT)
ValueType operator()(Iterator begin) 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::LazyFlipper< SubGmType, AccumulationType > LazyFlipperSubInf
void createModel(const UInt64Type nVar)
void createModel(const UInt64Type nVar)
GM::FactorType FactorType