2 #ifndef OPENGM_DUALDECOMPOSITION_BASE_HXX
3 #define OPENGM_DUALDECOMPOSITION_BASE_HXX
65 maximalDualOrder_(
std::numeric_limits<
size_t>::max()),
67 maximalNumberOfIterations_(100),
68 minimalAbsAccuracy_(0.0),
69 minimalRelAccuracy_(0.0),
71 fillSubLabelings_(false),
74 stepsizeExponent_(0.5),
76 stepsizeMax_(
std::numeric_limits<double>::infinity()),
77 stepsizePrimalDualGapStride_(false),
78 stepsizeNormalizedSubgradient_(false),
82 double getStepsize(
size_t iteration,
double primalDualGap,
double subgradientNorm){
85 if(stepsizePrimalDualGapStride_){
86 stepsize *= fabs(primalDualGap) / subgradientNorm / subgradientNorm;
89 stepsize /= (1+std::pow( stepsizeScale_*(
double)(iteration),stepsizeExponent_));
90 if(stepsizeNormalizedSubgradient_)
91 stepsize /= subgradientNorm;
110 const ValueType bound,
const ValueType bestBound,
111 const ValueType value,
const ValueType bestValue,
112 double primalTime,
double dualTime
127 const ValueType bound,
const ValueType bestBound,
128 const ValueType value,
const ValueType bestValue,
129 const double primalTime,
const double dualTime
136 times_.push_back(times_.back() + totalTimer_.
elapsedTime());
137 values_.push_back(value);
138 bounds_.push_back(bound);
139 primalTimes_.push_back(primalTime);
140 dualTimes_.push_back(dualTime);
151 const std::vector<ValueType>&
values(){
return values_;}
152 const std::vector<ValueType>&
bounds(){
return bounds_;}
153 const std::vector<double>&
times(){
return times_;}
155 const std::vector<double>&
dualTimes(){
return dualTimes_;}
158 std::vector<ValueType> values_;
159 std::vector<ValueType> bounds_;
160 std::vector<double> times_;
161 std::vector<double> primalTimes_;
162 std::vector<double> dualTimes_;
167 template<
class GM,
class DUALBLOCK>
192 template<
class ITERATOR>
void addDualBlock(
const SubFactorListType&,ITERATOR,ITERATOR);
194 template<
class ACC>
void getBounds(
const std::vector<std::vector<LabelType> >&,
const std::vector<SubVariableListType>&, ValueType&, ValueType&, std::vector<LabelType>&);
208 template<
class DUALVAR>
struct DDIsView {
static bool isView(){
return false;}};
209 template<>
struct DDIsView<
marray::View<double,false> > {
static bool isView(){
return true;}};
210 template<>
struct DDIsView<
marray::View<double,true> > {
static bool isView(){
return true;}};
211 template<>
struct DDIsView<
marray::View<float,false> > {
static bool isView(){
return true;}};
212 template<>
struct DDIsView<
marray::View<float,true> > {
static bool isView(){
return true;}};
217 template<
class DUALVAR,
class T>
228 template<
class GM,
class DUALBLOCK>
232 template<
class GM,
class DUALBLOCK>
236 opengm::GraphicalModelDecomposer<GmType> decomposer;
243 opengm::GraphicalModelDecomposer<GmType> decomposer;
250 opengm::GraphicalModelDecomposer<GmType> decomposer;
257 opengm::GraphicalModelDecomposer<GmType> decomposer;
264 opengm::GraphicalModelDecomposer<GmType> decomposer;
271 opengm::GraphicalModelDecomposer<GmType> decomposer;
278 opengm::GraphicalModelDecomposer<GmType> decomposer;
288 const std::vector<SubVariableListType>& subVariableLists = para.
decomposition_.getVariableLists();
289 const std::vector<SubFactorListType>& subFactorLists = para.
decomposition_.getFactorLists();
291 const size_t numberOfSubModels = para.
decomposition_.numberOfSubModels();
295 typename SubVariableListType::const_iterator it;
296 typename SubFactorListType::const_iterator it2;
297 typename SubFactorListType::const_iterator it3;
301 std::vector<std::vector<size_t> > numStates(numberOfSubModels);
302 for(
size_t subModelId=0; subModelId<numberOfSubModels; ++subModelId){
303 numStates[subModelId].resize(para.
decomposition_.numberOfSubVariables(subModelId),0);
306 for(
size_t varId=0; varId<gm_.numberOfVariables(); ++varId){
307 for(it = subVariableLists[varId].begin(); it!=subVariableLists[varId].end();++it){
308 numStates[(*it).subModelId_][(*it).subVariableId_] = gm_.numberOfLabels(varId);
312 subGm_.resize(numberOfSubModels);
313 for(
size_t subModelId=0; subModelId<numberOfSubModels; ++subModelId){
318 numDualsOvercomplete_ = 0;
319 numDualsMinimal_ = 0;
321 for(
size_t factorId=0; factorId<gm_.numberOfFactors(); ++factorId){
322 if(subFactorLists[factorId].size()>1 && (gm_[factorId].numberOfVariables() <= para.
maximalDualOrder_)){
323 addDualBlock(subFactorLists[factorId], gm_[factorId].shapeBegin(), gm_[factorId].shapeEnd());
324 numDualsOvercomplete_ += subFactorLists[factorId].size() * gm_[factorId].size();
325 numDualsMinimal_ += (subFactorLists[factorId].size()-1) * gm_[factorId].size();
329 for(it4=emptySubFactorLists.begin() ; it4 != emptySubFactorLists.end(); it4++ ){
331 std::vector<size_t> shape((*it4).first.size());
333 for(
size_t i=0; i<(*it4).first.size(); ++i){
334 shape[i] = gm_.numberOfLabels((*it4).first[i]);
335 temp *= gm_.numberOfLabels((*it4).first[i]);
337 numDualsOvercomplete_ += (*it4).second.size() * temp;
338 numDualsMinimal_ += ((*it4).second.size()-1) * temp;
339 addDualBlock((*it4).second,shape.begin(),shape.end());
347 size_t dualCounter = 0;
348 for(
size_t factorId=0; factorId<gm_.numberOfFactors(); ++factorId){
349 if(subFactorLists[factorId].size()>1 && (gm_[factorId].numberOfVariables() <= para.
maximalDualOrder_)){
350 std::vector<DualVariableType*> offsets = getDualPointers(dualCounter++);
352 for(it2 = subFactorLists[factorId].begin(); it2!=subFactorLists[factorId].end();++it2){
353 OPENGM_ASSERT(offsets[i]->dimension() == gm_[factorId].numberOfVariables());
354 for(
size_t j=0; j<offsets[i]->dimension();++j)
355 OPENGM_ASSERT(offsets[i]->shape(j) == gm_[factorId].shape(j));
357 const size_t subModelId = (*it2).subModelId_;
358 const ViewFunctionType function(gm_,factorId, 1.0/subFactorLists[factorId].size(),offsets[i++]);
360 subGm_[subModelId].addFactor(funcId,(*it2).subIndices_.begin(),(*it2).subIndices_.end());
364 for(it2 = subFactorLists[factorId].begin(); it2!=subFactorLists[factorId].end();++it2){
365 const size_t subModelId = (*it2).subModelId_;
366 const ViewFunctionType function(gm_,factorId, 1.0/subFactorLists[factorId].size());
368 subGm_[subModelId].addFactor(funcId,(*it2).subIndices_.begin(),(*it2).subIndices_.end());
373 for(it4=emptySubFactorLists.begin() ; it4 != emptySubFactorLists.end(); it4++ ){
376 std::vector<DualVariableType*> offsets = getDualPointers(dualCounter++);
377 for(it3 = (*it4).second.begin(); it3!=(*it4).second.end();++it3){
378 const size_t subModelId = (*it3).subModelId_;
381 subGm_[subModelId].addFactor(funcId,(*it3).subIndices_.begin(),(*it3).subIndices_.end());
389 template<
class GM,
class DUALBLOCK>
390 template <
class ITERATOR>
399 template<
class GM,
class DUALBLOCK>
402 return dualBlocks_[dualBlockId].getPointers();
405 template<
class GM,
class DUALBLOCK>
409 const std::vector<std::vector<LabelType> >& subStates,
410 const std::vector<SubVariableListType>& subVariableLists,
411 ValueType& lowerBound,
412 ValueType& upperBound,
413 std::vector<LabelType> & upperState
416 bool useFilling = parameter().fillSubLabelings_;
420 for(
size_t subModelId=0; subModelId<subGm_.size(); ++subModelId){
421 lowerBound += subGm_[subModelId].evaluate(subStates[subModelId]);
425 Accumulation<ValueType,LabelType,ACC> ac;
429 for(
size_t varId=0; varId<gm_.numberOfVariables(); ++varId){
430 for(
typename SubVariableListType::const_iterator its = subVariableLists[varId].begin();
431 its!=subVariableLists[varId].end();++its){
432 const size_t& subModelId = (*its).subModelId_;
433 const size_t& subVariableId = (*its).subVariableId_;
434 if(subVariableId != varId){
439 for(
size_t subModelId=0; subModelId<subGm_.size(); ++subModelId){
440 if(gm_.numberOfVariables() != subGm_[subModelId].numberOfVariables()){
452 std::vector<std::vector<IndexType> > subVariable2TrueVariable(subGm_.size());
454 for(
size_t s=0; s<subGm_.size();++s){
455 subVariable2TrueVariable[s].resize(subGm_[s].numberOfVariables());
458 std::vector<LabelType> defaultLabel(gm_.numberOfVariables());
459 for(
size_t varId=0; varId<gm_.numberOfVariables(); ++varId){
460 std::map<LabelType,size_t> labelCount;
461 for(
typename SubVariableListType::const_iterator its = subVariableLists[varId].begin(); its!=subVariableLists[varId].end();++its){
462 const size_t& subModelId = (*its).subModelId_;
463 const size_t& subVariableId = (*its).subVariableId_;
465 subVariable2TrueVariable[subModelId][subVariableId] = varId;
467 ++labelCount[subStates[subModelId][subVariableId]];
470 for(
typename std::map<LabelType,size_t>::iterator it=labelCount.begin(); it!=labelCount.end(); ++it){
471 if( it->second > c ){
473 defaultLabel[varId] = it->first;
477 ac(gm_.evaluate(defaultLabel),defaultLabel);
482 for(
size_t subModelId=0; subModelId<subGm_.size(); ++subModelId){
485 std::vector<LabelType> label(defaultLabel);
486 for(
size_t i=0; i<subStates[subModelId].size(); ++i){
487 label[subVariable2TrueVariable[subModelId][i]]=subStates[subModelId][i];
489 ac(gm_.evaluate(label),label);
493 ac(gm_.evaluate(subStates[subModelId]),subStates[subModelId]);
496 upperBound = ac.value();
497 ac.state(upperState);
500 template <
class GM,
class DUALBLOCK>
504 typename std::vector<DualBlockType>::const_iterator it;
505 for(it = dualBlocks_.begin(); it != dualBlocks_.end(); ++it){
506 norm += (*it).duals_.size();
508 norm = pow(norm,1.0/L);
double minimalRelAccuracy_
the relative accuracy that has to be guaranteed to stop with an approximate solution (set 0 for optim...
void getBounds(const std::vector< std::vector< LabelType > > &, const std::vector< SubVariableListType > &, ValueType &, ValueType &, std::vector< LabelType > &)
std::vector< DualBlockType > dualBlocks_
bool stepsizePrimalDualGapStride_
Discrete space in which variables can have differently many labels.
Runtime-flexible multi-dimensional views and arrays.
DecompositionType::SubFactor SubFactorType
DualDecompositionBaseParameter()
DecompositionType::SubVariable SubVariableType
void operator()(const DDType &dd, const ValueType bound, const ValueType bestBound, const ValueType value, const ValueType bestValue, double primalTime, double dualTime)
std::vector< DualVariableType * > getDualPointers(size_t)
void operator()(const DDType &dd, const ValueType bound, const ValueType bestBound, const ValueType value, const ValueType bestValue, const double primalTime, const double dualTime)
const SubGmType & subModel(size_t subModelId) const
virtual DualDecompositionBaseParameter & parameter()=0
DecompositionType::SubVariableListType SubVariableListType
size_t numberOfBlocks_
number of blocks for block decomposition
size_t numDualsOvercomplete_
Array-Interface to an interval of memory.
Platform-independent runtime measurements.
size_t k_
size of inner clique of kfan
double minimalAbsAccuracy_
the absolut accuracy that has to be guaranteed to stop with an approximate solution (set 0 for optima...
const std::vector< double > & primalTimes()
#define OPENGM_ASSERT(expression)
const std::vector< double > & dualTimes()
virtual void allocate()=0
double subGradientNorm(double L=1) const
GraphicalModelDecomposition decomposition_
decomposition of the model (needs to fit to the model structure)
const std::vector< ValueType > & values()
std::vector< SubGmType > subGm_
void init(DualDecompositionBaseParameter &)
bool stepsizeNormalizedSubgradient_
bool fillSubLabelings_
use filling to generate full labelings from non-spanning subproblems. If one labeling is generated fo...
DualDecompositionBase(const GmType &)
double elapsedTime() const
DecompositionId decompositionId_
type of decomposition that should be used (independent of model structure)
DDType::ValueType ValueType
void DualVarAssign(DUALVAR &dv, T *t)
const std::vector< double > & times()
Function that refers to a factor of another GraphicalModel.
std::vector< std::set< size_t > > subVariables_
vectors of variables of the subproblems - used form manual variable decomposition only...
GraphicalModelDecomposition DecompositionType
DDType::ValueType ValueType
size_t numberOfThreads_
number of threads for primal problems
void addDualBlock(const SubFactorListType &, ITERATOR, ITERATOR)
size_t maximalDualOrder_
maximum order of dual variables (order of the corresponding factor)
double getStepsize(size_t iteration, double primalDualGap, double subgradientNorm)
std::vector< std::vector< size_t > > subFactors_
vectors of factors of the subproblems - used form manual decomposition only.
ModelViewFunction< GmType, DualVariableType > ViewFunctionType
GraphicalModel< ValueType, OperatorType, typename meta::TypeListGenerator< ViewFunctionType >::type, opengm::DiscreteSpace< IndexType, LabelType > > SubGmType
const std::vector< ValueType > & bounds()
DualBlockType::DualVariableType DualVariableType
DecompositionType::SubFactorListType SubFactorListType
size_t maximalNumberOfIterations_
maximum number of dual iterations
const size_t * shapeEnd() const
Get a constant iterator to the end of the shape vector.
const size_t * shapeBegin() const
Get a constant iterator to the beginning of the shape vector.
A framework for inference algorithms based on Lagrangian decomposition.
std::vector< Tribool > modelWithSameVariables_
void assign(const allocator_type &=allocator_type())
Clear View.