44 default:
return std::string(
"UNKNOWN");
57 LabelType
numberOfLabels(IndexType varId)
const{
return _gm.numberOfLabels(varId);}
60 SubModel&
subModel(IndexType modelId){
return *_subModels[modelId];}
61 const SubModel&
subModel(IndexType modelId)
const{
return *_subModels[modelId];}
62 IndexType
size(IndexType subModelId)
const{
return (IndexType)_subModels[subModelId]->size();}
64 const SubVariableListType&
getSubVariableList(IndexType varId)
const{
return _variableDecomposition[varId];}
66 #ifdef TRWS_DEBUG_OUTPUT
67 void PrintTestData(std::ostream& fout)
const;
68 void PrintVariableDecompositionConsistency(std::ostream& fout)
const;
75 void _InitSubModels(
const DDVectorType* pddvector=0);
79 std::vector<SubModel*> _subModels;
80 std::vector<SubVariableListType> _variableDecomposition;
81 VariableToFactorMap _var2FactorMap;
85 template<
class ValueType>
96 ValueType precision=1.0,
97 bool absolutePrecision=
true,
98 ValueType minRelativeDualImprovement=-1.0,
99 bool fastComputations=
true,
100 bool canonicalNormalization=
false):
101 maxNumberOfIterations_(maxIternum),
102 precision_(precision),
103 absolutePrecision_(absolutePrecision),
104 minRelativeDualImprovement_(minRelativeDualImprovement),
105 fastComputations_(fastComputations),
106 canonicalNormalization_(canonicalNormalization)
123 #ifdef TRWS_DEBUG_OUTPUT
136 const_iterator
end(IndexType varId,MoveDirection md)
const{
return (md==
Storage::Direct ? _forwardFactors[varId].
end() : _backwardFactors[varId].
end());}
137 #ifdef TRWS_DEBUG_OUTPUT
138 void PrintTestData(std::ostream& fout);
141 std::vector<FactorList> _forwardFactors;
142 std::vector<FactorList> _backwardFactors;
147 _forwardFactors(gm.numberOfVariables()),
148 _backwardFactors(gm.numberOfVariables())
150 std::vector<IndexType> varIDs(2);
151 for (
IndexType factorId=0;factorId<gm.numberOfFactors();++factorId)
153 switch (gm[factorId].numberOfVariables())
157 gm[factorId].variableIndices(varIDs.begin());
158 if (varIDs[0] < varIDs[1])
160 _forwardFactors[varIDs[1]].push_back(
FactorVarID(factorId,varIDs[0],0));
161 _backwardFactors[varIDs[0]].push_back(
FactorVarID(factorId,varIDs[1],1));
165 _forwardFactors[varIDs[0]].push_back(
FactorVarID(factorId,varIDs[1],1));
166 _backwardFactors[varIDs[1]].push_back(
FactorVarID(factorId,varIDs[0],0));
169 default:
throw std::runtime_error(
"PreviousFactor::PreviousFactor: only the factors of order <=2 are supported!");
174 #ifdef TRWS_DEBUG_OUTPUT
178 fout <<
"Forward factors:"<<std::endl;
179 for (
size_t varId=0;varId<_forwardFactors.size();++varId)
181 fout <<
"varId="<<varId<<
", ";
182 for (
size_t i=0;i<_forwardFactors[varId].size();++i)
183 _forwardFactors[varId][i].print(fout);
187 fout <<
"Backward factors:"<<std::endl;
188 for (
size_t varId=0;varId<_backwardFactors.size();++varId)
190 fout <<
"varId="<<varId<<
", ";
191 for (
size_t i=0;i<_backwardFactors[varId].size();++i)
192 _backwardFactors[varId][i].print(fout);
198 template <
class SubSolver>
202 typedef typename SubSolver::GMType
GM;
204 typedef typename SubSolver::ACCType
ACC;
227 #ifdef TRWS_DEBUG_OUTPUT
228 ,std::ostream& fout=std::cout
238 #ifdef TRWS_DEBUG_OUTPUT
239 virtual void PrintTestData(std::ostream& fout)
const;
243 virtual std::pair<ValueType,ValueType>
GetMarginals(IndexType variable, OutputIteratorType begin){
return std::make_pair((ValueType)0,(ValueType)0);};
254 virtual InferenceTermination
infer(){EmptyVisitorParent vis; EmptyVisitorType visitor(&vis,
this);
return infer(visitor);};
255 template<
class VISITOR> InferenceTermination
infer(VISITOR&);
263 template<
class VISITOR> InferenceTermination
infer_visitor_updates(VISITOR& visitor,
size_t* pinterCounter=0);
264 InferenceTermination
core_infer(
size_t* piterCounter=0){EmptyVisitorParent vis; EmptyVisitorType visitor(&vis,
this);
return _core_infer(visitor,piterCounter);};
277 template <
class VISITOR> InferenceTermination
_core_infer(VISITOR& visitor,
size_t* piterCounter=0);
279 virtual void _postprocessMarginals(
typename std::vector<ValueType>::iterator begin,
typename std::vector<ValueType>::iterator end)=0;
280 virtual void _normalizeMarginals(
typename std::vector<ValueType>::iterator begin,
typename std::vector<ValueType>::iterator end,SubSolver* subSolver)=0;
286 virtual void _SumUpForwardMarginals(std::vector<ValueType>* pout,const_marginals_iterators_pair itpair)=0;
288 {
_integerLabeling[varId]=std::max_element(sumMarginal.begin(),sumMarginal.end(),ACC::template ibop<ValueType>)-sumMarginal.begin();}
294 IndexType
_order(IndexType i);
295 IndexType
_core_order(IndexType i,IndexType totalSize);
308 #ifdef TRWS_DEBUG_OUTPUT
336 template<
class ValueType>
343 ValueType precision=1.0,
344 bool absolutePrecision=
true,
345 ValueType minRelativeDualImprovement=2*std::numeric_limits<ValueType>::epsilon(),
346 bool fastComputations=
true,
347 bool canonicalNormalization=
false)
348 :parent(maxIternum,precision,absolutePrecision,minRelativeDualImprovement,fastComputations,canonicalNormalization),
349 smoothingValue_(smValue){};
352 template<
class GM,
class ACC>
373 #ifdef TRWS_DEBUG_OUTPUT
374 ,std::ostream& fout=std::cout
377 parent(storage,params
378 #ifdef TRWS_DEBUG_OUTPUT
387 #ifdef TRWS_DEBUG_OUTPUT
388 void PrintTestData(std::ostream& fout)
const;
398 std::pair<ValueType,ValueType>
GetMarginals(IndexType variable, OutputIteratorType begin);
413 template<
class ITERATOR>
417 ITERATOR end=begin+(it.second-it.first);
418 std::copy(it.first,it.second,begin);
419 ValueType mul; ACC::op(1.0,-1.0,mul);
427 void _postprocessMarginals(
typename std::vector<ValueType>::iterator begin,
typename std::vector<ValueType>::iterator end);
428 void _normalizeMarginals(
typename std::vector<ValueType>::iterator begin,
typename std::vector<ValueType>::iterator end,SubSolver* subSolver);
438 template<
class ValueType>
444 ValueType precision=1.0,
445 bool absolutePrecision=
true,
446 ValueType minRelativeDualImprovement=-1.0,
447 bool fastComputations=
true,
448 bool canonicalNormalization=
false,
450 parent(maxIternum,precision,absolutePrecision,minRelativeDualImprovement,fastComputations,canonicalNormalization),
458 size_t treeAgreeMaxStableIter()
const{
return (treeAgreeMaxStableIter_==0 ? parent::maxNumberOfIterations_ : treeAgreeMaxStableIter_);}
462 size_t treeAgreeMaxStableIter_;
465 template<
class GM,
class ACC>
490 #ifdef TRWS_DEBUG_OUTPUT
491 ,std::ostream& fout=std::cout
494 parent(storage,params
495 #ifdef TRWS_DEBUG_OUTPUT
507 void getTreeAgreement(std::vector<bool>& out,std::vector<LabelType>* plabeling=0,std::vector<std::vector<LabelType> >* ptreeLabelings=0);
511 void _postprocessMarginals(
typename std::vector<ValueType>::iterator begin,
typename std::vector<ValueType>::iterator end);
512 void _normalizeMarginals(
typename std::vector<ValueType>::iterator begin,
typename std::vector<ValueType>::iterator end,SubSolver* subSolver);
533 template <
class SubSolver>
535 #ifdef TRWS_DEBUG_OUTPUT
540 _factorProperties(storage.masterModel()),
541 _ftable(storage.masterModel()),
543 #ifdef TRWS_DEBUG_OUTPUT
554 _integerLabeling(storage.masterModel().numberOfVariables(),0),
555 _bestIntegerLabeling(storage.masterModel().numberOfVariables(),0),
558 #ifdef TRWS_DEBUG_OUTPUT
563 #ifdef TRWS_DEBUG_OUTPUT
568 template <
class SubSolver>
571 for_each(_subSolvers.begin(),_subSolvers.end(),DeallocatePointer<SubSolver>);
574 template <
class SubSolver>
577 _subSolvers.resize(_storage.numberOfModels());
578 for (
size_t modelId=0;modelId<_subSolvers.size();++modelId)
579 _subSolvers[modelId]=
new SubSolver(_storage.subModel(modelId),_factorProperties,_parameters.fastComputations_);
582 template <
class SubSolver>
585 OPENGM_ASSERT((ACC::bop(-1,1) ? 1 : -1 )*(primalBound-dualBound) > -dualBound*std::numeric_limits<ValueType>::epsilon());
590 ValueType endPrecision=std::max((
ValueType)fabs(dualBound)*std::numeric_limits<ValueType>::epsilon(),_parameters.precision_);
595 if (_parameters.absolutePrecision_)
597 if (fabs(primalBound-dualBound) <= endPrecision)
604 if (fabs((primalBound-dualBound))<= fabs(dualBound)*endPrecision )
634 template <
class SubSolver>
637 if (relativeThreshold >=0.0)
640 if (ACC::bop(_dualBound, (_oldDualBound + static_cast<ValueType>(fabs(_dualBound))*mul*relativeThreshold)))
646 template <
class SubSolver>
649 _lastDualUpdate=fabs(_dualBound-_oldDualBound);
651 if (CheckDualityGap(_bestIntegerBound,_dualBound))
653 #ifdef TRWS_DEBUG_OUTPUT
654 _fout <<
"TRWSPrototype::_CheckStoppingCondition(): duality gap <= specified precision!" <<std::endl;
660 if (_CheckConvergence(_parameters.minRelativeDualImprovement_))
662 #ifdef TRWS_DEBUG_OUTPUT
663 _fout <<
"TRWSPrototype::_CheckStoppingCondition(): Dual update is smaller than the specified threshold. Stopping"<<std::endl;
669 _oldDualBound=_dualBound;
674 template <
class SubSolver>
675 template <
class VISITOR>
678 for (
size_t iterationCounter=0;iterationCounter<_parameters.maxNumberOfIterations_;++iterationCounter)
680 #ifdef TRWS_DEBUG_OUTPUT
681 _fout <<
"Iteration Nr."<<iterationCounter<<
"-------------------------------------"<<std::endl;
686 #ifdef TRWS_DEBUG_OUTPUT
687 _fout <<
"dualBound=" << _dualBound <<
", primalBound="<<_GetPrimalBound() <<std::endl;
689 _EstimateTRWSBound();
690 const size_t visitorReturn = visitor();
692 if (piterCounter!=0) *piterCounter=iterationCounter+1;
695 if (_CheckStoppingCondition(&returncode))
709 template <
class SubSolver>
713 for (
size_t i=0;i<_subSolvers.size();++i)
714 dualBound+=_subSolvers[i]->GetObjectiveValue();
719 template <
class SubSolver>
722 std::for_each(_subSolvers.begin(), _subSolvers.end(), std::mem_fun(&SubSolver::Move));
723 _moveDirection=SubModel::ReverseDirection(_moveDirection);
724 _dualBound=_GetObjectiveValue();
727 template <
class SubSolver>
730 std::for_each(_subSolvers.begin(), _subSolvers.end(), std::mem_fun(&SubSolver::MoveBack));
731 _moveDirection=SubModel::ReverseDirection(_moveDirection);
734 template <
class SubSolver>
737 return (_moveDirection==SubModel::Direct ? i : totalSize-i-1);
740 template <
class SubSolver>
743 return _core_order(i,_storage.numberOfSharedVariables());
746 template <
class SubSolver>
749 std::for_each(_subSolvers.begin(), _subSolvers.end(), std::mem_fun(&SubSolver::FinalizeMove));
750 _moveDirection=SubModel::ReverseDirection(_moveDirection);
751 _EstimateIntegerLabeling();
754 #ifdef TRWS_DEBUG_OUTPUT
755 template <
class SubSolver>
758 fout <<
"_dualBound:" << _dualBound <<std::endl;
759 fout <<
"_oldDualBound:" << _oldDualBound <<std::endl;
760 fout <<
"_lastDualUpdate=" << _lastDualUpdate << std::endl;
761 fout <<
"_moveDirection:" << _moveDirection <<std::endl;
762 fout <<
"_integerBound=" << _integerBound << std::endl;
763 fout <<
"_bestIntegerBound=" << _bestIntegerBound << std::endl;
764 fout <<
"_integerLabeling=" << _integerLabeling;
765 fout <<
"_bestIntegerLabeling=" << _bestIntegerLabeling;
769 template <
class SubSolver>
770 template <
class VISITOR>
779 template <
class SubSolver>
780 template <
class VISITOR>
785 _oldDualBound=_dualBound;
786 #ifdef TRWS_DEBUG_OUTPUT
787 _fout <<
"ForwardMove: dualBound=" << _dualBound <<std::endl;
790 const size_t visitorReturn = visitor();
800 returncode=_core_infer(visitor,piterCounter);
801 if (piterCounter!=0) ++(*piterCounter);
805 template <
class SubSolver>
810 _dualBound=_GetObjectiveValue();
814 template <
class SubSolver>
817 std::vector<ValueType> averageMarginal;
819 for (
IndexType i=0;i<_storage.numberOfSharedVariables();++i)
822 const typename Storage::SubVariableListType& varList=_storage.getSubVariableList(varId);
823 averageMarginal.assign(_storage.numberOfLabels(varId),0.0);
826 for(
typename Storage::SubVariableListType::const_iterator modelIt=varList.begin();modelIt!=varList.end();++modelIt)
828 SubSolver& subSolver=*_subSolvers[modelIt->subModelId_];
829 std::vector<ValueType>& marginals=_marginals[modelIt->subModelId_];
830 marginals.resize(_storage.numberOfLabels(varId));
832 IndexType startNodeIndex=_core_order(0,_storage.size(modelIt->subModelId_));
834 if (modelIt->subVariableId_!=startNodeIndex)
835 subSolver.PushBack();
837 typename SubSolver::const_iterators_pair marginalsit=subSolver.GetMarginals();
839 std::copy(marginalsit.first,marginalsit.second,marginals.begin());
840 if (_parameters.canonicalNormalization_)
841 _normalizeMarginals(marginals.begin(),marginals.end(),&subSolver);
842 std::transform(marginals.begin(),marginals.end(),averageMarginal.begin(),averageMarginal.begin(),std::plus<ValueType>());
844 transform_inplace(averageMarginal.begin(),averageMarginal.end(),std::bind1st(std::multiplies<ValueType>(),-1.0/varList.size()));
849 for(
typename Storage::SubVariableListType::const_iterator modelIt=varList.begin();modelIt!=varList.end();++modelIt)
851 SubSolver& subSolver=*_subSolvers[modelIt->subModelId_];
852 std::vector<ValueType>& marginals=_marginals[modelIt->subModelId_];
854 std::transform(marginals.begin(),marginals.end(),averageMarginal.begin(),marginals.begin(),std::plus<ValueType>());
856 _postprocessMarginals(marginals.begin(),marginals.end());
858 subSolver.IncreaseUnaryWeights(marginals.begin(),marginals.end());
860 IndexType startNodeIndex=_core_order(0,_storage.size(modelIt->subModelId_));
862 if (modelIt->subVariableId_!=startNodeIndex)
863 subSolver.UpdateMarginals();
864 else subSolver.InitReverseMove();
869 _EvaluateIntegerBounds();
870 _dualBound=_GetObjectiveValue();
873 template <
class SubSolver>
876 for (
IndexType i=0;i<_storage.numberOfSharedVariables();++i)
880 const typename Storage::SubVariableListType& varList=_storage.getSubVariableList(varId);
881 _sumMarginal.assign(_storage.masterModel().numberOfLabels(varId),0.0);
882 for(
typename Storage::SubVariableListType::const_iterator modelIt=varList.begin();modelIt!=varList.end();++modelIt)
885 _SumUpForwardMarginals(&_sumMarginal,itpair);
890 for (;begin!=end;++begin)
892 LabelType fixedLabel=_integerLabeling[begin->varId];
895 if (_sumMarginal.size() > fixedLabel)
896 _sumMarginal[_integerLabeling[begin->varId]]-=_factorProperties.getFunctionParameters(begin->factorId)[0];
899 const typename GM::FactorType& pwfactor=_storage.masterModel()[begin->factorId];
903 std::vector<opengm::PositionAndLabel<IndexType,LabelType> >(1,
904 opengm::PositionAndLabel<IndexType,LabelType>(localVarIndx,
907 for (
LabelType j=0;j<_sumMarginal.size();++j)
908 _sumMarginal[j]+=pencil(&j);
911 _EstimateIntegerLabel(varId,_sumMarginal);
915 template <
class SubSolver>
918 _integerBound=_storage.masterModel().evaluate(_integerLabeling.begin());
919 if (ACC::bop(_integerBound,_bestIntegerBound))
921 _bestIntegerLabeling=_integerLabeling;
922 _bestIntegerBound=_integerBound;
930 _structureType(structureType),
932 _variableDecomposition(),
935 _InitSubModels(pddvector);
941 for_each(_subModels.begin(),_subModels.end(),DeallocatePointer<SubModel>);
947 std::auto_ptr<Decomposition<GM> > pdecomposition;
949 switch (_structureType)
958 pdecomposition=std::auto_ptr<Decomposition<GM> >(
new EdgeDecomposition<GM>(_gm));
961 case GENERALSTRUCTURE:
963 pdecomposition=std::auto_ptr<Decomposition<GM> >(
new MonotoneChainsDecomposition<GM>(_gm));
967 throw std::runtime_error(
"DecompositionStorage::_InitSubModels: Unknown decomposition type!");
977 pdecomposition->ComputeVariableDecomposition(&_variableDecomposition);
978 size_t numberOfModels=pdecomposition->getNumberOfSubModels();
979 _subModels.resize(numberOfModels);
980 for (
size_t modelId=0;modelId<numberOfModels;++modelId)
982 const typename SubModel::IndexList& varList=pdecomposition->getVariableList(modelId);
983 typename SubModel::IndexList numOfSubModelsPerVar(varList.size());
985 for (
size_t varIndx=0;varIndx<varList.size();++varIndx)
986 numOfSubModelsPerVar[varIndx]=_variableDecomposition[varList[varIndx]].size();
988 _subModels[modelId]=
new SubModel(_gm,_var2FactorMap,varList,pdecomposition->getFactorList(modelId),numOfSubModelsPerVar);
992 addDDvector(*pddvector);
994 }
catch(std::runtime_error& err)
1004 if (delta.size()!=getDDVectorSize())
1005 throw std::runtime_error(
"DecompositionStorage<GM>::addDDvector(): Error: size of the input vector does not match the size of the graphical model.");
1007 typename DDVectorType::const_iterator deltaIt=delta.begin();
1008 for (
IndexType varId=0;varId<masterModel().numberOfVariables();++varId)
1011 if (varList.size()==1)
continue;
1012 typename SubVariableListType::const_iterator modelIt=varList.begin();
1013 IndexType firstModelId=modelIt->subModelId_;
1014 IndexType firstModelVariableId=modelIt->subVariableId_;
1016 for(;modelIt!=varList.end();++modelIt)
1018 std::transform(subModel(modelIt->subModelId_).ufBegin(modelIt->subVariableId_),
1019 subModel(modelIt->subModelId_).ufEnd(modelIt->subVariableId_),
1020 deltaIt,subModel(modelIt->subModelId_).ufBegin(modelIt->subVariableId_),
1021 std::plus<ValueType>());
1023 std::transform(subModel(firstModelId).ufBegin(firstModelVariableId),
1024 subModel(firstModelId).ufEnd(firstModelVariableId),
1025 deltaIt,subModel(firstModelId).ufBegin(firstModelVariableId),
1026 std::minus<ValueType>());
1027 deltaIt+=masterModel().numberOfLabels(varId);
1035 pddvector->resize(getDDVectorSize());
1036 typename DDVectorType::iterator gradientIt=pddvector->begin();
1038 for (
IndexType varId=0;varId<_gm.numberOfVariables();++varId)
1042 if (varList.size()==1)
continue;
1043 typename SubVariableListType::const_iterator modelIt=varList.begin();
1044 uf.resize(_gm.numberOfLabels(varId));
1045 _gm[_var2FactorMap(varId)].copyValues(uf.begin());
1046 transform_inplace(uf.begin(),uf.end(),std::bind2nd(std::multiplies<ValueType>(),1.0/varList.size()));
1048 for(;modelIt!=varList.end();++modelIt)
1050 const std::vector<ValueType>& buffer=subModel(modelIt->subModelId_).unaryFactors(modelIt->subVariableId_);
1051 gradientIt=std::transform(buffer.begin(),buffer.end(),uf.begin(),gradientIt,std::minus<ValueType>());
1061 for (
IndexType varId=0;varId<_gm.numberOfVariables();++varId)
1062 varsize+=(getSubVariableList(varId).size()-1)*_gm.numberOfLabels(varId);
1066 #ifdef TRWS_DEBUG_OUTPUT
1070 fout <<
"_variableDecomposition: "<<std::endl;
1071 for (
size_t variableId=0;variableId<_variableDecomposition.size();++variableId)
1079 void DecompositionStorage<GM>::PrintVariableDecompositionConsistency(std::ostream& fout)
const
1081 fout <<
"Variable decomposition consistency:" <<std::endl;
1082 for (
size_t varId=0;varId<_gm.numberOfVariables();++varId)
1084 fout << varId<<
": ";
1085 const SubVariableListType& varList=_variableDecomposition[varId];
1086 typename SubVariableListType::const_iterator modelIt=varList.begin();
1087 std::vector<ValueType> sum(_gm.numberOfLabels(varId),0.0);
1088 while (modelIt!=varList.end())
1090 const SubModel& subModel=*_subModels[modelIt->subModelId_];
1091 std::transform(subModel.unaryFactors(modelIt->subVariableId_).begin(),subModel.unaryFactors(modelIt->subVariableId_).end(),
1092 sum.begin(),sum.begin(),std::plus<ValueType>());
1095 std::vector<ValueType> originalFactor(_gm.numberOfLabels(varId),0.0);
1096 _gm[varId].copyValues(originalFactor.begin());
1098 std::transform(sum.begin(),sum.end(),originalFactor.begin(),sum.begin(),std::minus<ValueType>());
1099 fout << std::accumulate(sum.begin(),sum.end(),(ValueType)0.0)<<std::endl;
1106 template<
class GM,
class ACC>
1109 parent::_moveDirection=SubModel::Direct;
1110 std::for_each(parent::_subSolvers.begin(), parent::_subSolvers.end(), std::mem_fun_t<void,SubSolver>(&SubSolver::InitMove));
1113 template<
class GM,
class ACC>
1119 template<
class GM,
class ACC>
1122 std::transform(itpair.first,itpair.second,pout->begin(),pout->begin(),std::plus<ValueType>());
1125 template<
class GM,
class ACC>
1128 if (parent::_parameters.canonicalNormalization_)
return;
1129 std::vector<ValueType> bounds(parent::_storage.numberOfModels());
1130 for (
size_t i=0;i<bounds.size();++i)
1131 bounds[i]=parent::_subSolvers[i]->GetObjectiveValue();
1133 ValueType min=*std::min_element(bounds.begin(),bounds.end());
1134 ValueType max=*std::max_element(bounds.begin(),bounds.end());
1135 ValueType eps; ACC::iop(max-min,min-max,eps);
1136 ACC::iop(min,max,_pseudoBoundValue);
1137 #ifdef TRWS_DEBUG_OUTPUT
1138 parent::_fout <<
"min="<<min<<
", max="<<max<<
", eps="<<eps<<
", pseudo bound="<<bounds.size()*_pseudoBoundValue<<std::endl;
1143 template<
class GM,
class ACC>
1147 ValueType maxVal=*std::max_element(begin,end,ACC::template bop<ValueType>);
1151 template<
class GM,
class ACC>
1155 plabeling->resize(parent::_storage.masterModel().numberOfVariables());
1156 if (ptreeLabelings!=0)
1157 ptreeLabelings->assign(parent::_storage.masterModel().numberOfVariables(),std::vector<LabelType>());
1159 out.assign(parent::_storage.masterModel().numberOfVariables(),
true);
1160 for (
size_t varId=0;varId<parent::_storage.masterModel().numberOfVariables();++varId)
1162 const typename Storage::SubVariableListType& varList=parent::_storage.getSubVariableList(varId);
1164 for(
typename Storage::SubVariableListType::const_iterator modelIt=varList.begin()
1165 ;modelIt!=varList.end();++modelIt)
1167 size_t check_label=parent::_subSolvers[modelIt->subModelId_]->arg()[modelIt->subVariableId_];
1169 if (plabeling!=0) (*plabeling)[varId]=check_label;
1170 if (ptreeLabelings!=0) (*ptreeLabelings)[varId].push_back(check_label);
1172 if (modelIt==varList.begin())
1175 }
else if (check_label!=label)
1186 template<
class GM,
class ACC>
1189 getTreeAgreement(_treeAgree);
1190 size_t agree_count=count(_treeAgree.begin(),_treeAgree.end(),
true);
1191 if (agree_count > _agree_count)
1193 _treeAgree_iterationCounter=0;
1194 _agree_count=agree_count;
1197 ++_treeAgree_iterationCounter;
1199 #ifdef TRWS_DEBUG_OUTPUT
1200 parent::_fout <<
"tree-agreement: " << agree_count <<
" out of "<<_treeAgree.size() <<
", ="<<100*(double)agree_count/_treeAgree.size()<<
"%"<<std::endl;
1203 if (_treeAgree.size()==agree_count)
1205 #ifdef TRWS_DEBUG_OUTPUT
1206 parent::_fout <<
"Problem solved."<<std::endl;
1214 template<
class GM,
class ACC>
1217 if (CheckTreeAgreement(pterminationCode))
return true;
1219 if (_treeAgree_iterationCounter > _parameters.treeAgreeMaxStableIter())
1221 #ifdef TRWS_DEBUG_OUTPUT
1222 parent::_fout <<
"There were no improvement of tree agreement during last "<<_treeAgree_iterationCounter <<
" steps. Aborting."<<std::endl;
1224 *pterminationCode=
NORMAL;
1228 return parent::_CheckStoppingCondition(pterminationCode);
1232 #ifdef TRWS_DEBUG_OUTPUT
1233 template<
class GM,
class ACC>
1236 fout <<
"_smoothingValue:"<<_smoothingValue <<std::endl;
1237 parent::PrintTestData(fout);
1241 template<
class GM,
class ACC>
1244 parent::_moveDirection=SubModel::Direct;
1245 std::for_each(parent::_subSolvers.begin(), parent::_subSolvers.end(), std::bind2nd(std::mem_fun(&SubSolver::InitMove),_smoothingValue));
1248 template<
class GM,
class ACC>
1250 typename std::vector<ValueType>::iterator end,
SubSolver* subSolver)
1253 ValueType logPartition=subSolver->ComputeObjectiveValue();
1255 transform_inplace(begin,end,std::bind2nd(std::plus<ValueType>(),-logPartition/_smoothingValue));
1258 template<
class GM,
class ACC>
1261 transform_inplace(begin,end,std::bind1st(std::multiplies<ValueType>(),-_smoothingValue));
1264 template<
class GM,
class ACC>
1267 std::transform(pout->begin(),pout->end(),itpair.first,pout->begin(),
plus2ndMul<ValueType>(_smoothingValue));
1270 template<
class GM,
class ACC>
1274 std::fill_n(begin,parent::_storage.numberOfLabels(varId),0.0);
1275 const typename Storage::SubVariableListType& varList=parent::_storage.getSubVariableList(varId);
1279 for(
typename Storage::SubVariableListType::const_iterator modelIt=varList.begin();modelIt!=varList.end();++modelIt)
1281 std::vector<ValueType>& normMarginals=parent::_marginals[modelIt->subModelId_];
1282 normMarginals.resize(parent::_storage.numberOfLabels(varId));
1283 GetMarginalsForSubModel(modelIt->subModelId_,modelIt->subVariableId_,normMarginals.begin());
1284 std::transform(normMarginals.begin(),normMarginals.end(),begin,begin,std::plus<ValueType>());
1286 transform_inplace(begin,begin+parent::_storage.numberOfLabels(varId),std::bind1st(std::multiplies<ValueType>(),1.0/varList.size()));
1289 for (
typename Storage::SubVariableListType::const_iterator modelIt=varList.begin();modelIt!=varList.end();++modelIt)
1291 std::vector<ValueType>& normMarginals=parent::_marginals[modelIt->subModelId_];
1293 for (
typename std::vector<ValueType>::const_iterator bm=normMarginals.begin(); bm!=normMarginals.end();++bm)
1296 ValueType diff=std::min((*bm-*begin0),*begin0); ++begin0;
1297 ell2Norm+=diff*diff;
1298 ellInftyNorm=std::max((
ValueType)fabs(diff),ellInftyNorm);
1302 return std::make_pair(sqrt(ell2Norm),ellInftyNorm);
1306 template<
class GM,
class ACC>
1312 for (
size_t i=0;i<parent::_subSolvers.size();++i)
1313 derivativeValue+=parent::_subSolvers[i]->MoveBackGetDerivative();
1315 parent::_moveDirection=SubModel::ReverseDirection(parent::_moveDirection);
1316 return derivativeValue;
TRWSPrototype_Parameters< ValueType > parent
const SubModel & subModel(IndexType modelId) const
ValueType getBound(size_t i) const
StructureType getStructureType() const
virtual ValueType value() const
std::vector< LabelType > _integerLabeling
void _postprocessMarginals(typename std::vector< ValueType >::iterator begin, typename std::vector< ValueType >::iterator end)
virtual InferenceTermination infer()
parent::SubVariableListType SubVariableListType
OutputContainerType::iterator OutputIteratorType
void _EstimateTRWSBound()
parent::LabelType LabelType
parent::ValueType ValueType
bool ConvergenceFlag() const
const SubVariableListType & getSubVariableList(IndexType varId) const
ValueType _smoothingValue
std::vector< bool > _treeAgree
ValueType minRelativeDualImprovement_
SubSolver::const_iterators_pair const_marginals_iterators_pair
virtual void _SumUpForwardMarginals(std::vector< ValueType > *pout, const_marginals_iterators_pair itpair)=0
IndexType size(IndexType subModelId) const
bool CheckDualityGap(ValueType primalBound, ValueType dualBound)
std::vector< bool > _nodeMask
size_t _treeAgree_iterationCounter
parent::IndexType IndexType
size_t maxNumberOfIterations_
DecompositionStorage(const GM &gm, StructureType structureType=GENERALSTRUCTURE, const DDVectorType *pddvector=0)
std::pair< ValueType, ValueType > GetMarginals(IndexType variable, OutputIteratorType begin)
const GM & masterModel() const
parent::IndexType IndexType
PreviousFactorTable< GM > _ftable
TRWSPrototype< SumProdSolver< GM, ACC, typename std::vector< typename GM::ValueType >::const_iterator > > parent
ValueType _GetObjectiveValue()
virtual ValueType _GetPrimalBound()
parent::const_marginals_iterators_pair const_marginals_iterators_pair
FactorVarID(IndexType fID, IndexType vID, IndexType lID)
std::vector< std::vector< ValueType > > _marginals
computation optimization
std::vector< ValueType > _sumMarginal
DecompositionStorage< GM > Storage
virtual std::pair< ValueType, ValueType > GetMarginals(IndexType variable, OutputIteratorType begin)
void _normalizeMarginals(typename std::vector< ValueType >::iterator begin, typename std::vector< ValueType >::iterator end, SubSolver *subSolver)
void SetSmoothing(ValueType smoothingValue)
parent::LabelType LabelType
bool CheckTreeAgreement(InferenceTermination *pterminationCode)
#define OPENGM_ASSERT(expression)
TRWSPrototype_Parameters(size_t maxIternum, ValueType precision=1.0, bool absolutePrecision=true, ValueType minRelativeDualImprovement=-1.0, bool fastComputations=true, bool canonicalNormalization=false)
Storage::UnaryFactor UnaryFactor
const FactorProperties & getFactorProperties() const
virtual void _InitMove()=0
parent::UnaryFactor UnaryFactor
void _normalizeMarginals(typename std::vector< ValueType >::iterator begin, typename std::vector< ValueType >::iterator end, SubSolver *subSolver)
parent::SubVariable SubVariable
parent::ValueType ValueType
virtual const std::vector< LabelType > & arg() const
ValueType GetMarginalsAndDerivativeMove()
DecompositionStorage< GM > Storage
virtual void _EstimateTRWSBound()
static const size_t StopInfBoundReached
void getTreeAgreement(std::vector< bool > &out, std::vector< LabelType > *plabeling=0, std::vector< std::vector< LabelType > > *ptreeLabelings=0)
InputIterator transform_inplace(InputIterator first, InputIterator last, UnaryOperator op)
std::vector< SubSolver * > _subSolvers
T _MulNormalize(Iterator begin, Iterator end, T initialValue)
LabelType numberOfLabels(IndexType varId) const
ValueType lastDualUpdate() const
size_t getDDVectorSize() const
MonotoneChainsDecomposition< GM >::SubVariableListType SubVariableListType
ValueType smoothingValue_
SubModel::MoveDirection _moveDirection
parent::OutputContainerType OutputContainerType
IndexType _order(IndexType i)
VariableToFactorMapping< GM > VariableToFactorMap
SumProdTRWS_Parameters(size_t maxIternum, ValueType smValue, ValueType precision=1.0, bool absolutePrecision=true, ValueType minRelativeDualImprovement=2 *std::numeric_limits< ValueType >::epsilon(), bool fastComputations=true, bool canonicalNormalization=false)
static StructureType getStructureType(const std::string &structName)
void _SumUpForwardMarginals(std::vector< ValueType > *pout, const_marginals_iterators_pair itpair)
SumProdTRWS_Parameters< ValueType > Parameters
Storage::MoveDirection MoveDirection
ValueType _pseudoBoundValue
virtual ValueType GetBestIntegerBound() const
SequenceStorage< GM > SubModel
IndexType numberOfModels() const
SequenceStorage< GM > SubModel
SubModel::UnaryFactor UnaryFactor
MaxSumTRWS_Parameters< ValueType > Parameters
size_t _localConsistencyCounter
void GetMarginalsForSubModel(IndexType modelId, IndexType localVarId, ITERATOR begin)
virtual void _normalizeMarginals(typename std::vector< ValueType >::iterator begin, typename std::vector< ValueType >::iterator end, SubSolver *subSolver)=0
parent::SubSolverType SubSolver
bool _CheckStoppingCondition(InferenceTermination *pterminationCode)
IndexType numberOfSharedVariables() const
std::vector< ValueType > UnaryFactor
size_t treeAgreeMaxStableIter() const
std::vector< bool > _mask
PreviousFactorTable(const GM &gm)
void _EvaluateIntegerBounds()
std::vector< ValueType > OutputContainerType
FactorList::const_iterator const_iterator
SequenceStorage< GM > SubModel
TRWSPrototype_Parameters< ValueType > parent
void EstimateIntegerLabelingAndBound()
void addDDvector(const DDVectorType &ddvector)
virtual void _postprocessMarginals(typename std::vector< ValueType >::iterator begin, typename std::vector< ValueType >::iterator end)=0
FactorProperties _factorProperties
virtual bool _CheckStoppingCondition(InferenceTermination *pterminationCode)
std::vector< typename GM::ValueType > DDVectorType
std::vector< LabelType > _bestIntegerLabeling
ValueType _oldDualBound
>current dual bound (it is improved monotonically)
void GetMarginalsMove()
>returns "averaged" over subsolvers marginals
parent::EmptyVisitorType EmptyVisitorType
void _SumUpForwardMarginals(std::vector< ValueType > *pout, const_marginals_iterators_pair itpair)
std::vector< FactorVarID > FactorList
bool _CheckConvergence(ValueType relativeThreshold)
void setTreeAgreeMaxStableIter(size_t val)
MaxSumTRWS_Parameters(size_t maxIternum, ValueType precision=1.0, bool absolutePrecision=true, ValueType minRelativeDualImprovement=-1.0, bool fastComputations=true, bool canonicalNormalization=false, size_t treeAgreeMaxStableIter=0)
void _postprocessMarginals(typename std::vector< ValueType >::iterator begin, typename std::vector< ValueType >::iterator end)
InferenceTermination infer_visitor_updates(VISITOR &visitor, size_t *pinterCounter=0)
OutputContainerType::iterator OutputIteratorType
SequenceStorage< GM > Storage
parent::OutputContainerType OutputContainerType
virtual ValueType bound() const
TRWSPrototype_Parameters< ValueType > Parameters
TRWSPrototype< MaxSumSolver< GM, ACC, typename std::vector< typename GM::ValueType >::const_iterator > > parent
void _EstimateIntegerLabeling()
ValueType GetSmoothing() const
TRWSPrototype(Storage &storage, const Parameters ¶ms)
MonotoneChainsDecomposition< GM >::SubVariable SubVariable
parent::InferenceTermination InferenceTermination
const_iterator end(IndexType varId, MoveDirection md) const
const_iterator begin(IndexType varId, MoveDirection md) const
void _EstimateIntegerLabel(IndexType varId, const std::vector< ValueType > &sumMarginal)
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
SubModel & subModel(IndexType modelId)
parent::InferenceTermination InferenceTermination
InferenceTermination _core_infer(VISITOR &visitor, size_t *piterCounter=0)
opengm::InferenceTermination InferenceTermination
ValueType _bestIntegerBound
DecompositionStorage< GM > Storage
bool canonicalNormalization_
InferenceTermination core_infer(size_t *piterCounter=0)
FactorProperties::ParameterStorageType _factorParameters
visitors::EmptyVisitor< TRWSPrototype< SubSolverType > > EmptyVisitorParent
void getDDVector(DDVectorType *ddvector) const
static const size_t ContinueInf
ValueType getDerivative(size_t i) const
besides computation of marginals returns derivative w.r.t. _smoothingValue
void _InitSubSolvers()
>best label index
SequenceStorage< GM > SubModel
parent::SubSolverType SubSolver
static std::string getString(StructureType structure)
visitors::VisitorWrapper< EmptyVisitorParent, TRWSPrototype< SubSolver > > EmptyVisitorType
FunctionParameters< GM > FactorProperties
MaxSumTRWS(Storage &storage, const Parameters ¶ms)
ValueType _lastDualUpdate
previous dual bound (it is improved monotonically)
parent::const_marginals_iterators_pair const_marginals_iterators_pair
virtual bool _CheckConvergence(ValueType relativeThreshold)
IndexType _core_order(IndexType i, IndexType totalSize)
T _MaxNormalize_inplace(Iterator begin, Iterator end, T init, Comp comp)
SumProdTRWS(Storage &storage, const Parameters ¶ms)