8 #ifndef PRIMAL_LPBOUND_HXX_
9 #define PRIMAL_LPBOUND_HXX_
19 using trws_base::FactorWrapper;
20 using trws_base::VariableToFactorMapping;
34 template<
class ValueType>
38 size_t maxIterationNumber)
61 template <
class GM,
class ACC>
78 template<
class ValueIterator>
79 void setVariable(IndexType var, ValueIterator inputBegin);
80 template<
class ValueIterator>
81 void getVariable(IndexType var, ValueIterator outputBegin);
86 template<
class Matrix>
94 void _checkPWFactorID(IndexType factorId,
const std::string& message_prefix=std::string());
97 std::vector<UnaryFactor> _unaryFactors;
98 VariableToFactorMapping<GM> _mapping;
100 std::vector<ValueType> _bufferedValues;
101 IndexType _lastActiveSolver;
102 ValueType _totalValue;
105 template <
class GM,
class ACC>
108 std::vector<IndexType> numOfunaryFactors(gm.numberOfVariables(),0);
109 for (IndexType factorId=0;factorId<gm.numberOfFactors();++factorId)
111 if (gm[factorId].numberOfVariables()!=1)
114 numOfunaryFactors[gm[factorId].variableIndex(0)]++;
117 IndexType moreCount=std::count_if(numOfunaryFactors.begin(),numOfunaryFactors.end(),std::bind2nd(std::greater<IndexType>(),1));
119 throw std::runtime_error(
"PrimalLPBound::CheckDuplicateUnaryFactors: all variables must have not more then a single associated unary factor!");
122 template <
class GM,
class ACC>
125 template <
class GM,
class ACC>
128 template <
class GM,
class ACC>
132 #ifdef TRWS_DEBUG_OUTPUT
135 param.relativePrecision_,param.maxIterationNumber_),
136 _unaryFactors(gm.numberOfVariables()),
138 _bufferedValues(gm.numberOfFactors(),ValueTypeNan),
139 _lastActiveSolver(InvalidIndex),
140 _totalValue(ValueTypeNan)
144 for (
size_t i=0;i<_unaryFactors.size();++i)
145 _unaryFactors[i].assign(_gm.numberOfLabels(i),0);
148 template <
class GM,
class ACC>
149 template<
class Iterator>
153 _totalValue=ValueTypeNan;
154 std::copy(inputBegin,inputBegin+_unaryFactors[var].size(),_unaryFactors[var].begin());
157 IndexType numOfFactors=_gm.numberOfFactors(var);
158 for (IndexType i=0;i<numOfFactors;++i)
160 IndexType factorId=_gm.factorOfVariable(var,i);
162 _bufferedValues[factorId] = ValueTypeNan;
166 template <
class GM,
class ACC>
167 template<
class Iterator>
171 std::copy(_unaryFactors[var].begin(),_unaryFactors[var].end(),outputBegin);
174 template <
class GM,
class ACC>
178 if (_gm[factorId].numberOfVariables() !=2 )
179 std::runtime_error(message_prefix +
"Function can be applied to second order factors only!");
182 template <
class GM,
class ACC>
185 _checkPWFactorID(factorId,
"PrimalLPBound::getFactorValue(): ");
187 if (_bufferedValues[factorId] == ValueTypeNan)
189 const typename GM::FactorType& factor=_gm[factorId];
190 IndexType var0=factor.variableIndex(0),
191 var1=factor.variableIndex(1);
192 _solver.Init(_unaryFactors[var0].size(),_unaryFactors[var1].size(),FactorWrapper<typename GM::FactorType>(factor));
193 _bufferedValues[factorId]=_solver.Solve(_unaryFactors[var0].begin(),_unaryFactors[var1].begin());
194 _lastActiveSolver=factorId;
197 return _bufferedValues[factorId];
200 template <
class GM,
class ACC>
201 template<
class Matrix>
204 _checkPWFactorID(factorId,
"PrimalLPBound::getFactorVariable(): ");
206 if (_lastActiveSolver!=factorId)
207 getFactorValue(factorId);
209 return _solver.GetSolution(&matrix);
212 template <
class GM,
class ACC>
217 IndexType factorId=_mapping(varId);
219 if (factorId==VariableToFactorMapping<GM>::InvalidIndex)
222 if (_bufferedValues[factorId] != ValueTypeNan)
223 return _bufferedValues[factorId];
226 const UnaryFactor& uf=_unaryFactors[varId];
229 const typename GM::FactorType& f=_gm[factorId];
230 for (LabelType i=0;i<uf.size();++i)
233 _bufferedValues[factorId]=sum;
237 template <
class GM,
class ACC>
240 if (_totalValue==ValueTypeNan)
243 for (IndexType factorId=0;factorId<_gm.numberOfFactors();++factorId)
245 const typename GM::FactorType& f=_gm[factorId];
246 switch (f.numberOfVariables())
248 case 1: _totalValue+=getVariableValue(f.variableIndex(0));
break;
249 case 2: _totalValue+=getFactorValue(factorId);
break;
250 default:
throw std::runtime_error(
"PrimalLPBound::getTotalValue(): Only factors of order <= 2 are supported!");
void setVariable(IndexType var, ValueIterator inputBegin)
static const floatType floatTypeEps
void getVariable(IndexType var, ValueIterator outputBegin)
size_t maxIterationNumber_
TransportSolver::TransportationSolver< ACC, FactorWrapper< typename GM::FactorType > > Solver
#define OPENGM_ASSERT(expression)
Solver::floatType ValueType
static void CheckDuplicateUnaryFactors(const GM &gm)
PrimalLPBound_Parameter< ValueType > Parameter
ValueType getVariableValue(IndexType varId)
DenseMatrix::ValueType floatType
ValueType getFactorVariable(IndexType factorId, Matrix &matrix)
std::vector< ValueType > UnaryFactor
static const ValueType ValueTypeNan
static const IndexType InvalidIndex
PrimalLPBound_Parameter(ValueType relativePrecision, size_t maxIterationNumber)
bool IsFactorVariableBuffered(IndexType factorId) const
ValueType getTotalValue()
static const size_t defaultMaxIterationNumber
ValueType relativePrecision_
PrimalLPBound(const GM &gm, const Parameter ¶m=Parameter(Solver::floatTypeEps, Solver::defaultMaxIterationNumber))
[class primallpbound] PrimalLPBound - estimating primal local polytope bound and feasible primal solu...
bool IsValueBuffered(IndexType factorId) const
ValueType getFactorValue(IndexType factorId)