1 #ifndef TRWS_SUBPROBLEMSOLVER_HXX_
2 #define TRWS_SUBPROBLEMSOLVER_HXX_
13 #ifdef TRWS_DEBUG_OUTPUT
20 #ifdef TRWS_DEBUG_OUTPUT
21 using OUT::operator <<;
37 SequenceStorage(
const GM&
masterModel,
const VariableToFactorMap& var2FactorMap,
const IndexList& variableList,
const IndexList& pwFactorList,
const IndexList& numberOfTreesPerFactor);
40 IndexType
size()
const{
return (IndexType)_directIndex.size();};
42 #ifdef TRWS_DEBUG_OUTPUT
43 void PrintTestData(std::ostream& fout)
const;
56 IndexType
pwForwardFactor(IndexType var)
const{assert(var<_pwForwardIndex.size());
return _pwForwardIndex[var];}
61 const UnaryFactor&
unaryFactors(IndexType indx)
const{assert(indx<_unaryFactors.size());
return _unaryFactors[indx];}
62 typename UnaryFactor::iterator
ufBegin(IndexType indx){assert(indx<_unaryFactors.size());
return _unaryFactors[indx].begin();}
63 typename UnaryFactor::iterator
ufEnd (IndexType indx){assert(indx<_unaryFactors.size());
return _unaryFactors[indx].end() ;}
64 IndexType
varIndex(IndexType var)
const{assert(var<_directIndex.size());
return _directIndex[var];};
66 template<
class ITERATOR>
67 ValueType
evaluate(ITERATOR labeling);
69 void _ConsistencyCheck();
70 void _Reset(
const IndexList& numOfSequencesPerFactor);
71 void _Reset(IndexType var,IndexType numOfSequences);
73 const GM& _masterModel;
75 IndexList _directIndex;
76 IndexList _pwForwardIndex;
77 std::vector<UnaryFactor> _unaryFactors;
78 std::vector<MoveDirection> _pwDirection;
79 const VariableToFactorMap& _var2FactorMap;
99 return _factorTypes[factorId];
105 return _parameters[factorId];
107 #ifdef TRWS_DEBUG_OUTPUT
108 void PrintStatusData(std::ostream& fout);
111 void _checkConsistency()
const;
112 void _getPottsParameters(
const typename GM::FactorType& factor,ParameterStorageType* pstorage)
const;
114 std::vector<ParameterStorageType> _parameters;
115 std::vector<FunctionType> _factorTypes;
120 : _gm(gm),_parameters(_gm.numberOfFactors()),_factorTypes(_gm.numberOfFactors())
122 for (
IndexType i=0;i<_gm.numberOfFactors();++i)
124 const typename GM::FactorType& f=_gm[i];
126 if ((f.numberOfVariables()==2) && f.isPotts())
128 _factorTypes[i]=
POTTS;
129 _getPottsParameters(f,&_parameters[i]);
141 for (
size_t i=0;i<_parameters.size();++i)
142 if (_factorTypes[i]==POTTS)
149 void FunctionParameters<GM>::_getPottsParameters(
const typename GM::FactorType& f,ParameterStorageType* pstorage)
const
152 pstorage->assign(2,0.0);
156 if ((f.numberOfLabels(0)>0) && (f.numberOfLabels(1)>0))
157 (*pstorage)[1]=f(&v00[0]);
158 if (f.numberOfLabels(0)>1)
159 (*pstorage)[0]=f(&v10[0])-f(&v00[0]);
160 else if (f.numberOfLabels(1)>1)
161 (*pstorage)[0]=f(&v01[0])-f(&v00[0]);
164 #ifdef TRWS_DEBUG_OUTPUT
166 void FunctionParameters<GM>:: PrintStatusData(std::ostream& fout)
169 for (
size_t i=0;i<_parameters.size();++i) numPotts+= (_factorTypes[i]==POTTS ? 1 : 0) ;
170 fout <<
"Total number of factors:" <<_factorTypes.size()<<std::endl;
171 fout <<
"Number of POTTS p/w factors:" << numPotts <<std::endl;
177 template<
class GM,
class ACC,
class InputIterator>
196 typedef std::pair<typename UnaryFactor::const_iterator,typename UnaryFactor::const_iterator>
const_iterators_pair;
199 static const IndexType
NaN;
201 DynamicProgramming(Storage& storage,
const FactorProperties& factorProperties,
bool fastComputations=
true);
255 template<
class ITERATOR>
260 #ifdef TRWS_DEBUG_OUTPUT
261 virtual void PrintTestData(std::ostream& fout)
const;
268 void _PottsUnaryTransform(LabelType newSize,
const typename FactorProperties::ParameterStorageType& params);
271 void _InitMove(ValueType rho,MoveDirection movedirection);
272 virtual void _Push();
281 IndexType
_core_next(IndexType begin,MoveDirection dir)
const;
282 IndexType
_next(IndexType begin)
const;
283 IndexType
_previous(IndexType begin)
const;
307 template<
class GM,
class ACC,
class InputIterator>
323 :parent(storage,factorProperties,fastComputations),
328 #ifdef TRWS_DEBUG_OUTPUT
329 void PrintTestData(std::ostream& fout)
const
331 parent::PrintTestData(fout);
332 fout <<
"_labeling: "<<
_labeling<<std::endl;
350 template<
class GM,
class ACC,
class InputIterator>
353 OPENGM_ASSERT((parent::_currentUnaryIndex==0)||(parent::_currentUnaryIndex==parent::size()-1));
354 OPENGM_ASSERT(_labeling[parent::_currentUnaryIndex]<parent::_marginals[parent::_currentUnaryIndex].size());
356 IndexType bk_currentUnaryIndex=parent::_currentUnaryIndex;
359 parent::_moveDirection=parent::Storage::ReverseDirection(parent::_moveDirection);
362 LabelType optLabel=_labeling[parent::_currentUnaryIndex];
366 parent::_currentUnaryIndex=parent::_next(parent::_currentUnaryIndex);
367 _marginalsTemp=parent::_marginals[parent::_currentUnaryIndex];
368 _SumUpBackwardEdges(&_marginalsTemp,optLabel);
370 _labeling[parent::_currentUnaryIndex]=optLabel=std::max_element(_marginalsTemp.begin(),_marginalsTemp.end(),
371 ACC::template ibop<ValueType>)-_marginalsTemp.begin();
375 parent::_moveDirection=bk_moveDirection;
376 parent::_currentUnaryIndex=bk_currentUnaryIndex;
379 template<
class GM,
class ACC,
class InputIterator>
383 _labeling[parent::_currentUnaryIndex]=std::max_element(parent::_marginals[parent::_currentUnaryIndex].begin(),
384 parent::_marginals[parent::_currentUnaryIndex].end(),ACC::template ibop<ValueType>)
385 -parent::_marginals[parent::_currentUnaryIndex].begin();
386 return parent::_marginals[parent::_currentUnaryIndex][_labeling[parent::_currentUnaryIndex]];
389 template<
class GM,
class ACC,
class InputIterator>
392 parent::FinalizeMove();
393 _EstimateOptimalLabeling();
396 template <
class T,
class ACC>
struct compToValue : std::unary_function <T,T> {
399 {
return (ACC::template bop<T>(x,_val) ? x : _val);}
404 template<
class GM,
class ACC,
class InputIterator>
413 typename UnaryFactor::iterator bestValIt=std::max_element(puf->begin(),puf->end(),ACC::template ibop<ValueType>);
417 if (ACC::bop(params[0],static_cast<ValueType>(0.0)))
419 *bestValIt=ACC::template neutral<ValueType>();
420 secondBestVal=*std::max_element(puf->begin(),puf->end(),ACC::template ibop<ValueType>);
428 if (ACC::bop(params[0],static_cast<ValueType>(0.0)))
429 ACC::op(secondBestVal+params[0],bestVal,*bestValIt);
433 transform_inplace(puf->begin(),puf->end(),std::bind1st(std::plus<ValueType>(),params[1]));
435 if (newSize< puf->size())
436 puf->resize(newSize);
437 else if (newSize > puf->size())
439 puf->resize(newSize,params[0]+params[1]+bestVal);
446 template<
class GM,
class ACC,
class InputIterator>
449 IndexType factorId=parent::_storage.pwForwardFactor(parent::_nextPWIndex());
452 parent::_currentUnaryIndex=parent::_next(parent::_currentUnaryIndex);
453 LabelType newSize=parent::_storage.unaryFactors(parent::_currentUnaryIndex).size();
454 parent::_PottsUnaryTransform(newSize,parent::_factorProperties.getFunctionParameters(factorId));
455 std::transform(parent::_currentUnaryFactor.begin(),parent::_currentUnaryFactor.end(),
456 parent::_storage.unaryFactors(parent::_currentUnaryIndex).begin(),
466 template<
class GM,
class ACC,
class InputIterator>
482 SumProdSolver(Storage& storage,
const FactorProperties& factorProperties,
bool fastComputations=
true)
483 :parent(storage,factorProperties,fastComputations),
_averagingFlag(false){ACC::op(1.0,-1.0,
_mul);};
514 #ifdef TRWS_DEBUG_OUTPUT
518 fout <<
"_directIndex:" <<_directIndex;
519 fout <<
"_pwForwardIndex:" <<_pwForwardIndex;
520 fout <<
"_unaryFactors:" <<std::endl<<_unaryFactors;
521 fout <<
"_pwDirection:" << _pwDirection;
529 const IndexList& numOfSequencesPerFactor)
530 :_masterModel(masterModel),
531 _directIndex(variableList),
532 _pwForwardIndex(pwFactorList),
533 _pwDirection(pwFactorList.size())
534 ,_var2FactorMap(var2FactorMap)
538 _Reset(numOfSequencesPerFactor);
544 exception_check((_directIndex.size()-1)==_pwForwardIndex.size(),
"DynamicProgramming::_ConsistencyCheck(): (_directIndex.size()-1)!=_pwForwardIndex.size()");
547 for (IndexType i=0;i<size()-1;++i)
549 exception_check(_masterModel[pwForwardFactor(i)].numberOfVariables()==2,
"DynamicProgramming::_ConsistencyCheck():factor.numberOfVariables()!=2");
550 _masterModel[pwForwardFactor(i)].variableIndices(&v[0]);
552 if (v[0]==varIndex(i))
554 exception_check(v[1]==varIndex(i+1),
"DynamicProgramming::_ConsistencyCheck(): v[1]!=varIndex(i+1)");
555 _pwDirection[i]=Direct;
557 else if (v[0]==varIndex(i+1))
559 exception_check(v[1]==varIndex(i),
"DynamicProgramming::_ConsistencyCheck(): v[1]!=varIndex(i)");
560 _pwDirection[i]=Reverse;
563 throw std::runtime_error(
"DynamicProgramming::_ConsistencyCheck(): pairwise factor does not correspond to unaries!");
568 void SequenceStorage<GM>::_Reset(
const IndexList& numOfSequencesPerFactor)
570 for (IndexType var=0;var<size();++var)
571 _Reset(var,numOfSequencesPerFactor[var]);
575 void SequenceStorage<GM>::_Reset(IndexType var,IndexType numOfSequences)
578 UnaryFactor& uf=_unaryFactors[var];
579 _masterModel[_var2FactorMap(varIndex(var))].copyValues(uf.begin());
580 transform_inplace(uf.begin(),uf.end(),std::bind2nd(std::multiplies<ValueType>(),1.0/numOfSequences));
587 pfactors->resize(size());
588 for (
size_t i=0;i<pfactors->size();++i)
589 (*pfactors)[i].assign(_masterModel[_var2FactorMap(varIndex(i))].size(),0.0);
602 template<
class ITERATOR>
607 for (
size_t i=0;i<size();++i)
609 value+=_unaryFactors[i][*labeling];
612 if (pwDirection(i)==Direct)
613 value+=_masterModel[_pwForwardIndex[i]](labeling);
616 std::valarray<LabelType> ind(2);
617 ind[0]=*(labeling+1); ind[1]=*labeling;
618 value+= _masterModel[_pwForwardIndex[i]](labeling);
627 template<
class GM,
class ACC,
class InputIterator>
630 template<
class GM,
class ACC,
class InputIterator>
632 :_fastComputation(fastComputation),
634 _factorProperties(factorProperties),
635 _objectiveValue(0.0),
637 _moveDirection(
Storage::Direct),
638 _bInitializationNeeded(true),
640 _currentUnaryFactor(0),
642 _currentUnaryIndex(NaN)
647 #ifdef TRWS_DEBUG_OUTPUT
648 template<
class GM,
class ACC,
class InputIterator>
651 fout <<
"_marginals:" <<std::endl<<_marginals;
652 fout <<
"_objectiveValue="<<_objectiveValue<<std::endl;
653 fout <<
"_rho="<<_rho<<std::endl;
654 fout <<
"_moveDirection="<< _moveDirection<<std::endl;
655 fout <<
"_currentPWFactor="<<_currentPWFactor;
656 fout <<
"_currentUnaryFactor="<<_currentUnaryFactor;
657 fout <<
"_currentUnaryIndex=" <<_currentUnaryIndex<<std::endl;
661 template<
class GM,
class ACC,
class InputIterator>
665 if (dir==Storage::Direct)
667 assert(begin<_storage.size()-1);
672 assert((begin>0) && (begin<_storage.size()));
677 template<
class GM,
class ACC,
class InputIterator>
681 return _core_next(begin,_moveDirection);
684 template<
class GM,
class ACC,
class InputIterator>
688 if (_moveDirection==Storage::Direct)
689 return _core_next(begin,Storage::Reverse);
691 return _core_next(begin,Storage::Direct);
694 template<
class GM,
class ACC,
class InputIterator>
698 if (_moveDirection==Storage::Direct)
699 return _currentUnaryIndex;
701 return _currentUnaryIndex-1;
705 template<
class GM,
class ACC,
class InputIterator>
708 const Factor& f=_storage.masterModel()[_storage.pwForwardFactor(_nextPWIndex())];
709 _currentPWFactor.resize(f.size());
710 if ( ((_moveDirection==Storage::Direct) && (_storage.pwDirection(_nextPWIndex())==Storage::Direct)) ||
711 ((_moveDirection==Storage::Reverse) && (_storage.pwDirection(_nextPWIndex())==Storage::Reverse)) )
712 f.copyValues(_currentPWFactor.begin());
714 f.copyValuesSwitchedOrder(_currentPWFactor.begin());
718 template<
class GM,
class ACC,
class InputIterator>
721 LabelType trgsize=_storage.unaryFactors(_next(_currentUnaryIndex)).size();
724 _makeLocalCopyOfPWFactor(trgsize);
725 assert(_currentPWFactor.size()==(_currentUnaryFactor.size()*trgsize));
727 if (_rho!=1.0) std::transform(_currentPWFactor.begin(),_currentPWFactor.end(),_currentPWFactor.begin(),std::bind2nd(std::multiplies<ValueType>(),1.0/_rho));
729 _spst.resize(_currentUnaryFactor.size(),trgsize);
732 for (
LabelType i=0;i<_currentUnaryFactor.size();++i)
733 transform_inplace(_spst.beginSrcNC(&_currentPWFactor[0],i),_spst.endSrcNC(&_currentPWFactor[0],i),std::bind2nd(std::plus<ValueType>(),_currentUnaryFactor[i]));
736 template<
class GM,
class ACC,
class InputIterator>
739 assert(index < _storage.size());
740 _currentUnaryIndex=index;
741 _currentUnaryFactor.resize(_storage.unaryFactors(_currentUnaryIndex).size());
742 std::copy(_storage.unaryFactors(_currentUnaryIndex).begin(),_storage.unaryFactors(_currentUnaryIndex).end(),_currentUnaryFactor.begin());
745 template<
class T,
class Iterator,
class Comp>
748 T max=*std::max_element(begin,end,comp);
775 template<
class GM,
class ACC,
class InputIterator>
778 LabelType srcsize=_storage.unaryFactors(_previous(_currentUnaryIndex)).size();
780 _spst.resize(srcsize,_currentUnaryFactor.size());
784 for (
LabelType i=0;i<_currentUnaryFactor.size();++i)
785 _currentUnaryFactor[i]+=
_MaxNormalize_inplace(_spst.beginTrgNC(&_currentPWFactor[0],i),_spst.endTrgNC(&_currentPWFactor[0],i),(
ValueType)0.0,ACC::template ibop<ValueType>);
789 pbuffer->resize(_currentUnaryFactor.size());
790 for (
LabelType i=0;i<_currentUnaryFactor.size();++i)
792 (*pbuffer)[i]=(_currentUnaryFactor[i]+=
_MaxNormalize_inplace(_spst.beginTrgNC(&_currentPWFactor[0],i),_spst.endTrgNC(&_currentPWFactor[0],i),(
ValueType)0.0,ACC::template ibop<ValueType>));
799 template<
class GM,
class ACC,
class InputIterator>
803 _PushMessagesToFactor();
804 _InitCurrentUnaryBuffer(_next(_currentUnaryIndex));
807 _BackUpForwardMarginals();
810 template<
class GM,
class ACC,
class InputIterator>
813 std::copy(_currentUnaryFactor.begin(),_currentUnaryFactor.end(),_marginals[_currentUnaryIndex].begin());
816 template<
class GM,
class ACC,
class InputIterator>
819 UnaryFactor& marginals=_marginals[_currentUnaryIndex];
820 std::transform(_currentUnaryFactor.begin(),_currentUnaryFactor.end(),marginals.begin(),marginals.begin(),std::plus<ValueType>());
821 std::transform(marginals.begin(),marginals.end(),_storage.unaryFactors(_currentUnaryIndex).begin(),marginals.begin(),
plus2ndMul<ValueType>(-1.0/_rho));
825 template<
class GM,
class ACC,
class InputIterator>
828 if (_bInitializationNeeded)
831 _bInitializationNeeded=
false;
834 for (
IndexType i=0;i<_storage.size()-1;++i)
847 template<
class GM,
class ACC,
class InputIterator>
850 if (_bInitializationNeeded)
852 _InitReverseMoveBack();
856 _SumUpBufferToMarginals();
862 template<
class GM,
class ACC,
class InputIterator>
866 for (
IndexType i=0;i<_storage.size()-1;++i)
872 template<
class GM,
class ACC,
class InputIterator>
876 _moveDirection=movedirection;
878 if (_moveDirection==Storage::Direct)
879 _InitCurrentUnaryBuffer(0);
881 _InitCurrentUnaryBuffer(_storage.size()-1);
883 _bInitializationNeeded=
false;
887 template<
class GM,
class ACC,
class InputIterator>
890 _core_InitMoves(rho,movedirection);
895 template<
class GM,
class ACC,
class InputIterator>
898 _objectiveValue=ComputeObjectiveValue();
899 _bInitializationNeeded=
true;
903 template<
class GM,
class ACC,
class InputIterator>
906 exception_check((
LabelType)
abs(end-begin)==_storage.unaryFactors(_currentUnaryIndex).size(),
"SumProdSequenceTRWSSolver::IncreaseUnaryWeights(): (end-begin)!=unaryFactor.size()");
908 std::transform(begin,end,_storage.ufBegin(_currentUnaryIndex),_storage.ufBegin(_currentUnaryIndex),std::plus<ValueType>());
909 std::transform(_currentUnaryFactor.begin(),_currentUnaryFactor.end(),begin,_currentUnaryFactor.begin(),
plus2ndMul<ValueType>(1.0/_rho));
912 template<
class GM,
class ACC,
class InputIterator>
916 if (_currentUnaryIndex >= _storage.size())
return NaN;
918 if (_moveDirection==Storage::Direct)
919 return (_currentUnaryIndex==0 ? NaN : _storage.pwForwardFactor(_currentUnaryIndex-1));
921 return (_currentUnaryIndex==_storage.size()-1 ? NaN : _storage.pwForwardFactor(_currentUnaryIndex));
924 template<
class GM,
class ACC,
class InputIterator>
928 if (_currentUnaryIndex >= (
IndexType)_storage.size())
return NaN;
930 if (_moveDirection==Storage::Direct)
931 return (_currentUnaryIndex==_storage.size()-1 ? NaN : _storage.pwForwardFactor(_currentUnaryIndex));
933 return (_currentUnaryIndex==0 ? NaN : _storage.pwForwardFactor(_currentUnaryIndex-1));
936 template<
class T,
class InputIterator,
class OutputIterator,
class Comp >
937 T
_MaxNormalize(InputIterator begin, InputIterator end, OutputIterator outBegin, T init,Comp comp)
939 T max=*std::max_element(begin,end,comp);
940 std::transform(begin,end,outBegin,std::bind2nd(std::minus<T>(),max));
944 template<
class Iterator,
class T>
947 T acc=std::accumulate(begin,end,(T)0.0);
948 std::transform(begin,end,begin,std::bind1st(std::multiplies<T>(),1.0/acc));
949 return initialValue+acc;
967 template<
class GM,
class ACC,
class InputIterator>
971 IndexType factorId=parent::getPrevPWId();
976 if (fixedLabel<u.size())
977 u[fixedLabel]-=parent::_factorProperties.getFunctionParameters(factorId)[0];
982 const typename GM::FactorType& pwfactor=parent::_storage.masterModel()[factorId];
984 OPENGM_ASSERT( (parent::_storage.varIndex(parent::_currentUnaryIndex)==pwfactor.variableIndex(0)) || (parent::_storage.varIndex(parent::_currentUnaryIndex)==pwfactor.variableIndex(1)));
986 IndexType localVarIndx = (parent::_storage.varIndex(parent::_currentUnaryIndex)==pwfactor.variableIndex(0) ? 1 : 0);
988 std::vector<opengm::PositionAndLabel<IndexType,LabelType> >(1,
989 opengm::PositionAndLabel<IndexType,LabelType>(localVarIndx,
999 template<
class GM,
class ACC,
class InputIterator>
1002 LabelType srcsize=parent::_marginals[parent::_previous(parent::_currentUnaryIndex)].size();
1004 parent::_spst.resize(srcsize,parent::_currentUnaryFactor.size());
1007 for (
LabelType i=0;i<parent::_currentUnaryFactor.size();++i)
1008 parent::_currentUnaryFactor[i]+=_mul*log(std::accumulate(parent::_spst.beginTrg(&parent::_currentPWFactor[0],i),parent::_spst.endTrg(&parent::_currentPWFactor[0],i),
ValueType(0.0)));
1033 template<
class GM,
class ACC,
class InputIterator>
1036 std::transform(_unaryBuffer.begin(),_unaryBuffer.end(),parent::_marginals[parent::_currentUnaryIndex].begin(),
1037 _unaryBuffer.begin(),std::plus<ValueType>());
1038 std::transform(_unaryBuffer.begin(),_unaryBuffer.end(),parent::_storage.unaryFactors(parent::_currentUnaryIndex).begin(),_unaryBuffer.begin(),
plus2ndMul<ValueType>(-1.0/parent::_rho));
1047 LabelType srcsize=parent::_marginals[parent::_previous(parent::_currentUnaryIndex)].size();
1048 parent::_spst.resize(srcsize,parent::_currentUnaryFactor.size());
1051 for (
LabelType i=0;i<parent::_currentUnaryFactor.size();++i)
1053 tmpbuf[i]*=std::accumulate(parent::_spst.beginTrg(&parent::_currentPWFactor[0],i),
1054 parent::_spst.endTrg(&parent::_currentPWFactor[0],i),(
ValueType)0.0);
1055 _unaryBuffer[i]*=std::inner_product(parent::_spst.beginTrg(&parent::_currentPWFactor[0],i),
1056 parent::_spst.endTrg(&parent::_currentPWFactor[0],i),
1057 parent::_spst.beginTrg(&_copyPWfactor[0],i),
1069 _derivativeValue+=acc*std::accumulate(_unaryBuffer.begin(),_unaryBuffer.end(),(
ValueType)0.0);
1074 thresholdMulAndExp(T threshold):_mul(ACC::template bop<T>(1.0,0.0) ? 1.0 : -1.0),_threshold(threshold){};
1076 {_buf=fabs(x);
return (_buf >= _threshold ? 0.0 : exp(-_buf));}
1108 template<
class GM,
class ACC,
class InputIterator>
1112 parent::_PushMessagesToFactor();
1116 _InitCurrentUnaryBuffer(parent::_next(parent::_currentUnaryIndex));
1119 parent::_ClearMessages(&_unaryBuffer);
1123 _ExponentiatePWFactor();
1128 _PushMessagesToVariable();
1132 template<
class GM,
class ACC,
class InputIterator>
1143 for (
size_t i=0;i<parent::size();++i)
1145 _unaryBuffer.resize(parent::_marginals[i].size());
1150 _MaxNormalize(parent::_marginals[i].begin(),parent::_marginals[i].end(),_unaryBuffer.begin(),(
ValueType)0.0,ACC::template ibop<ValueType>);
1152 std::transform(_unaryBuffer.begin(),_unaryBuffer.end(),_unaryBuffer.begin(),
thresholdMulAndExp<ValueType,ACC>(-log(std::numeric_limits<ValueType>::epsilon())));
1153 ValueType acc=std::accumulate(_unaryBuffer.begin(),_unaryBuffer.end(),(
ValueType)0.0);
1159 derivativeBound+=log(_unaryBuffer.size()-std::count(_unaryBuffer.begin(),_unaryBuffer.end(),(
ValueType)0.0));
1162 unaryAverage+=acc*std::inner_product(_unaryBuffer.begin(),_unaryBuffer.end(),parent::_storage.unaryFactors(i).begin(),(
ValueType)0.0);
1175 return unaryAverage;
1216 template<
class GM,
class ACC,
class InputIterator>
1220 if (parent::_bInitializationNeeded)
1222 parent::_InitReverseMoveBack();
1225 _averagingFlag=
true;
1226 _derivativeValue=0.0;
1230 for (
size_t i=0;i<parent::size()-1;++i)
1233 parent::_SumUpBufferToMarginals();
1241 _derivativeValue+=_GetAveragedUnaryFactors(derivativeBound);
1246 parent::FinalizeMove();
1247 _averagingFlag=
false;
1252 _derivativeValue=(parent::GetObjectiveValue()-_derivativeValue)/parent::_rho;
1256 ACC::iop(_derivativeValue,_mul*derivativeBound,_derivativeValue);
1260 return _derivativeValue;
1263 template<
class GM,
class ACC,
class InputIterator>
1269 _ExponentiatePWFactor();
1272 _PushMessagesToVariable();
1276 template<
class GM,
class ACC,
class InputIterator>
1283 template<
class GM,
class ACC,
class InputIterator>
1287 typename UnaryFactor::const_iterator begin=parent::_marginals[parent::_currentUnaryIndex].begin(),
1288 end=parent::_marginals[parent::_currentUnaryIndex].end();
1289 parent::_unaryTemp.resize(end-begin);
1291 std::transform(parent::_unaryTemp.begin(),parent::_unaryTemp.end(),parent::_unaryTemp.begin(),
mulAndExp<ValueType>(_mul));
1292 logPartition+=_mul*parent::_rho*(log(std::accumulate(parent::_unaryTemp.begin(),parent::_unaryTemp.end(),(
ValueType)0.0)));
1293 return logPartition;
1297 template<
class GM,
class ACC,
class InputIterator>
1300 parent::_makeLocalCopyOfPWFactor(trgsize);
1302 _copyPWfactor=parent::_currentPWFactor;
1305 template<
class GM,
class ACC,
class InputIterator>
1308 parent::_InitCurrentUnaryBuffer(index);
1310 if (parent::_rho!=1.0)
transform_inplace(parent::_currentUnaryFactor.begin(),parent::_currentUnaryFactor.end(),std::bind2nd(std::multiplies<ValueType>(),1.0/parent::_rho));
void _PushMessagesToVariable()
std::vector< IndexList > IndexTable
UnaryFactor::iterator ufBegin(IndexType indx)
>const access
void AllocateUnaryFactors(std::vector< UnaryFactor > *pfactors)
void _ExponentiatePWFactor()
IndexType pwForwardFactor(IndexType var) const
IndexType varIndex(IndexType var) const
>non-const access
DynamicProgramming< GM, ACC, InputIterator > parent
void exception_check(bool condition, const std::string &str)
ValueType _getMarginalsLogNormalizer() const
T _MaxNormalize(InputIterator begin, InputIterator end, OutputIterator outBegin, T init, Comp comp)
UnaryFactor::iterator ufEnd(IndexType indx)
>non-const access TODO: make a pair of iterators from a single function call
FunctionType getFunctionType(IndexType factorId) const
parent::const_iterators_pair const_iterators_pair
SequenceStorage< GM > Storage
Storage::UnaryFactor UnaryFactor
virtual ~DynamicProgramming()
void _SumUpBufferToMarginals()
void _PushMessagesToFactor()
Storage::IndexList IndexList
ValueType _GetAveragedUnaryFactors(ValueType &derivativeBound)
subtract it if you want to get normalized log-marginals from non-normalized ones
virtual void Move()
>initializes move, which is reverse to the current one//TODO: remove virtual ?
VariableToFactorMapping< GM > VariableToFactorMap
ValueType MoveBackGetDerivative()
UnaryFactor _currentUnaryFactor
LabelType numOfLabels() const
parent::UnaryFactor UnaryFactor
MaxSumSolver(typename parent::Storage &storage, const FactorProperties &factorProperties, bool fastComputations=true)
virtual void FinalizeMove()
#define OPENGM_ASSERT(expression)
MoveDirection getMoveDirection() const
returns an external (_gm[.]) pairwise index, which is in front of the current variable. For the first variable this::NaN is returned
IndexType _currentUnaryIndex
virtual void _InitCurrentUnaryBuffer(IndexType index)
parent::MoveDirection MoveDirection
std::vector< ValueType > ParameterStorageType
const FactorProperties & _factorProperties
virtual ValueType ComputeObjectiveValue()=0
parent::FactorProperties FactorProperties
static MoveDirection ReverseDirection(MoveDirection dir)
InputIterator transform_inplace(InputIterator first, InputIterator last, UnaryOperator op)
T _MulNormalize(Iterator begin, Iterator end, T initialValue)
const UnaryFactor & unaryFactors(IndexType indx) const
virtual void _makeLocalCopyOfPWFactor(LabelType trgsize)
ValueType _derivativeValue
const LabelingType & arg()
ValueType _objectiveValue
void _PottsUnaryTransform(LabelType newSize, const typename FactorProperties::ParameterStorageType ¶ms)
parent::ValueType ValueType
Storage::MoveDirection MoveDirection
virtual IndexType getPrevPWId() const
returns an external (_gm[.]) pairwise index, which follows the current variable. For the last variabl...
GraphicalModelType::IndexType IndexType
void _ClearMessages(UnaryFactor *pbuffer=0)
const GM & masterModel() const
IndexType _nextPWIndex() const
virtual void _BackUpForwardMarginals()
FunctionParameters< GM > FactorProperties
static const IndexType NaN
FunctionParameters(const GM &gm)
std::vector< ValueType > UnaryFactor
DynamicProgramming< GM, ACC, InputIterator > parent
const ParameterStorageType & getFunctionParameters(IndexType factorId) const
void _InitMove(ValueType rho, MoveDirection movedirection)
>initializes move, which is reverse to the current one
void _InitReverseMoveBack()
UnaryFactor _copyPWfactor
UnaryFactor::const_iterator ConstIterator
IndexType _previous(IndexType begin) const
bool _bInitializationNeeded
DynamicProgramming(Storage &storage, const FactorProperties &factorProperties, bool fastComputations=true)
parent::IndexType IndexType
Pseudo2DArray< ValueType > _spst
virtual void IncreaseUnaryWeights(InputIteratorType begin, InputIteratorType end)
thresholdMulAndExp(T threshold)
parent::InputIteratorType InputIteratorType
void InitMove(MoveDirection movedirection)
MoveDirection pwDirection(IndexType pwInd) const
std::vector< IndexType > IndexList
SumProdSolver(Storage &storage, const FactorProperties &factorProperties, bool fastComputations=true)
ValueType getDerivative() const
>makes MoveBack and returns derivative w.r.t. _smoothingValue
parent::LabelType LabelType
const_iterators_pair GetMarginals(IndexType indx) const
void _SumUpBackwardEdges(UnaryFactor *u, LabelType fixedLabel) const
virtual void UpdateMarginals()
std::pair< typename UnaryFactor::const_iterator, typename UnaryFactor::const_iterator > const_iterators_pair
ValueType evaluate(ITERATOR labeling)
std::vector< LabelType > LabelingType
void _core_InitMoves(ValueType rho, MoveDirection movedirection)
parent::FactorProperties FactorProperties
parent::IndexType IndexType
InputIterator InputIteratorType
std::vector< UnaryFactor > _marginals
void _InitCurrentUnaryBuffer(IndexType index)
ValueType evaluate(ITERATOR labeling)
virtual IndexType getNextPWId() const
updates marginals in the current node so, that they correspond to the forward (backward) accumulated ...
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
parent::LabelType LabelType
UnaryFactor _marginalsTemp
IndexType _next(IndexType begin) const
void _EstimateOptimalLabeling()
void InitMove(ValueType rho, MoveDirection movedirection)
const_iterators_pair GetMarginals() const
void SetFastComputation(bool fc)
SequenceStorage(const GM &masterModel, const VariableToFactorMap &var2FactorMap, const IndexList &variableList, const IndexList &pwFactorList, const IndexList &numberOfTreesPerFactor)
void InitMove(ValueType rho)
MoveDirection _moveDirection
parent::InputIteratorType InputIteratorType
ValueType GetObjectiveValue() const
IndexType _core_next(IndexType begin, MoveDirection dir) const
ValueType ComputeObjectiveValue()
ValueType ComputeObjectiveValue()
virtual void InitReverseMove()
parent::ValueType ValueType
UnaryFactor _currentPWFactor
T _MaxNormalize_inplace(Iterator begin, Iterator end, T init, Comp comp)
void _makeLocalCopyOfPWFactor(LabelType trgsize)
parent::UnaryFactor UnaryFactor