2 #ifndef OPENGM_DUALDDECOMPOSITION_SUBGRADIENT_HXX
3 #define OPENGM_DUALDDECOMPOSITION_SUBGRADIENT_HXX
22 template<
class GM,
class INF,
class DUALBLOCK >
52 Parameter() : useAdaptiveStepsize_(false), useProjectedAdaptiveStepsize_(false){};
63 virtual std::string
name()
const {
return "DualDecompositionSubGradient";};
72 virtual void allocate();
74 void dualStep(
const size_t);
75 template <
class T_IndexType,
class T_LabelType>
76 void getPartialSubGradient(
const size_t,
const std::vector<T_IndexType>&, std::vector<T_LabelType>&)
const;
77 double euclideanProjectedSubGradientNorm();
80 std::vector<std::vector<LabelType> > subStates_;
82 Accumulation<ValueType,LabelType,AccumulationType> acUpperBound_;
83 Accumulation<ValueType,LabelType,AccumulationType> acNegLowerBound_;
86 std::vector<ValueType> values_;
89 std::vector<ValueType> mem_;
99 template<
class GM,
class INF,
class DUALBLOCK>
104 subStates_.resize(
subGm_.size());
105 for(
size_t i=0; i<
subGm_.size(); ++i)
106 subStates_[i].resize(
subGm_[i].numberOfVariables());
109 template<
class GM,
class INF,
class DUALBLOCK>
114 subStates_.resize(
subGm_.size());
115 for(
size_t i=0; i<
subGm_.size(); ++i)
116 subStates_[i].resize(
subGm_[i].numberOfVariables());
122 template <
class GM,
class INF,
class DUALBLOCK>
125 if(DDIsView<DualVariableType>::isView()){
126 mem_.resize(numDualsOvercomplete_,0.0);
131 ValueType *data = &mem_[0];
132 for(
typename std::vector<DualBlockType>::iterator it=dualBlocks_.begin(); it!=dualBlocks_.end(); ++it){
133 for(
size_t i=0; i<(*it).duals_.size(); ++i){
134 DualVariableType& dv = (*it).duals_[i];
136 if(DDIsView<DualVariableType>::isView())
141 template <
class GM,
class INF,
class DUALBLOCK>
142 DualDecompositionBaseParameter& DualDecompositionSubGradient<GM,INF,DUALBLOCK>::parameter()
148 template<
class GM,
class INF,
class DUALBLOCK>
153 return infer(visitor);
155 template<
class GM,
class INF,
class DUALBLOCK>
156 template<
class VISITOR>
160 std::cout.precision(15);
162 visitor.begin(*
this);
164 for(
size_t iteration=0; iteration<para_.maximalNumberOfIterations_; ++iteration){
172 for(
size_t subModelId=0; subModelId<subGm_.size(); ++subModelId){
173 InfType inf(subGm_[subModelId],para_.subPara_);
175 inf.arg(subStates_[subModelId]);
181 std::vector<LabelType> temp;
182 std::vector<LabelType> temp2;
183 const std::vector<SubVariableListType>& subVariableLists = para_.decomposition_.getVariableLists();
184 (*this).template getBounds<AccumulationType>(subStates_, subVariableLists, lowerBound_, upperBound_, temp);
185 acNegLowerBound_(-lowerBound_,temp2);
186 acUpperBound_(upperBound_, temp);
190 if(para_.useAdaptiveStepsize_){
191 stepsize = para_.stepsizeStride_ * fabs(acUpperBound_.value() - lowerBound_)
192 /(*this).subGradientNorm(1);
194 else if(para_.useProjectedAdaptiveStepsize_){
195 double subgradientNorm = euclideanProjectedSubGradientNorm();
196 stepsize = para_.stepsizeStride_ * fabs(acUpperBound_.value() - lowerBound_)
197 /subgradientNorm/subgradientNorm;
200 double primalDualGap = fabs(acUpperBound_.value() + acNegLowerBound_.value());
201 double subgradientNorm = euclideanProjectedSubGradientNorm();
202 stepsize = para_.getStepsize(iteration,primalDualGap,subgradientNorm);
211 std::vector<size_t> s;
212 for(
typename std::vector<DualBlockType>::const_iterator it = dualBlocks_.begin(); it != dualBlocks_.end(); ++it){
213 const size_t numDuals = (*it).duals_.size();
214 typename SubFactorListType::const_iterator lit = (*((*it).subFactorList_)).begin();
215 s.resize((*lit).subIndices_.size());
216 for(
size_t i=0; i<numDuals; ++i){
217 getPartialSubGradient<size_t>((*lit).subModelId_, (*lit).subIndices_, s);
219 (*it).duals_[i](s.begin()) += stepsize;
220 for(
size_t j=0; j<numDuals; ++j){
221 (*it).duals_[j](s.begin()) -= stepsize/numDuals;
230 if(visitor(*
this)!= 0){
238 AccumulationType::iop(0.0001,-0.0001,o);
239 OPENGM_ASSERT(AccumulationType::bop(lowerBound_, upperBound_+o));
240 OPENGM_ASSERT(AccumulationType::bop(-acNegLowerBound_.value(), acUpperBound_.value()+o));
242 if( fabs(acUpperBound_.value() + acNegLowerBound_.value()) <= para_.minimalAbsAccuracy_
243 || fabs((acUpperBound_.value()+ acNegLowerBound_.value())/acUpperBound_.value()) <= para_.minimalRelAccuracy_){
257 template<
class GM,
class INF,
class DUALBLOCK>
259 arg(std::vector<LabelType>& conf,
const size_t n)
const
265 acUpperBound_.state(conf);
270 template<
class GM,
class INF,
class DUALBLOCK>
273 return acUpperBound_.value();
276 template<
class GM,
class INF,
class DUALBLOCK>
279 return -acNegLowerBound_.value();
285 template <
class GM,
class INF,
class DUALBLOCK>
291 template <
class GM,
class INF,
class DUALBLOCK>
292 template <
class T_IndexType,
class T_LabelType>
293 inline void DualDecompositionSubGradient<GM,INF,DUALBLOCK>::getPartialSubGradient
295 const size_t subModelId,
296 const std::vector<T_IndexType>& subIndices,
297 std::vector<T_LabelType> & s
301 for(
size_t n=0; n<s.size(); ++n){
302 s[n] = subStates_[subModelId][subIndices[n]];
306 template <
class GM,
class INF,
class DUALBLOCK>
307 double DualDecompositionSubGradient<GM,INF,DUALBLOCK>::euclideanProjectedSubGradientNorm()
310 std::vector<LabelType> s;
312 typename std::vector<DUALBLOCK>::const_iterator it;
313 typename SubFactorListType::const_iterator lit;
314 for(it = dualBlocks_.begin(); it != dualBlocks_.end(); ++it){
315 const size_t numDuals = (*it).duals_.
size();
317 lit = (*((*it).subFactorList_)).begin();
318 s.resize((*lit).subIndices_.size());
319 for(
size_t i=0; i<numDuals; ++i){
320 getPartialSubGradient((*lit).subModelId_, (*lit).subIndices_, s);
324 for(
size_t i=0; i<M.
size(); ++i){
325 norm += M(i) * pow(1.0 - M(i)/numDuals,2);
326 norm += (numDuals-M(i)) * pow( M(i)/numDuals,2);
InfType::Parameter subPara_
Parameter for Subproblems.
INF::AccumulationType AccumulationType
DecompositionType::SubVariable SubVariableType
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
DecompositionType::SubVariableListType SubVariableListType
DualDecompositionBase< GmType, DualBlockType > DDBaseType
Platform-independent runtime measurements.
#define OPENGM_ASSERT(expression)
virtual std::string name() const
visitors::TimingVisitor< DualDecompositionSubGradient< GM, INF, DUALBLOCK > > TimingVisitorType
bool useAdaptiveStepsize_
DualBlockType::SubFactorType SubFactorType
std::vector< SubGmType > subGm_
void init(DualDecompositionBaseParameter &)
virtual const GmType & graphicalModel() const
virtual InferenceTermination infer()
DualDecompositionSubGradient(const GmType &)
DDBaseType::SubGmType SubGmType
DDBaseType::SubVariableListType SubVariableListType
Dual-Decomposition-Subgradient Inference based on dual decomposition using sub-gradient descent Refe...
void DualVarAssign(DUALVAR &dv, T *t)
const size_t size() const
Get the number of data items.
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
DualBlockType::SubFactorListType SubFactorListType
bool useProjectedAdaptiveStepsize_
virtual ValueType value() const
return the solution (value)
Runtime-flexible multi-dimensional array.
DualBlockType::DualVariableType DualVariableType
DDBaseType::SubVariableType SubVariableType
Minimization as a unary accumulation.
visitors::EmptyVisitor< DualDecompositionSubGradient< GM, INF, DUALBLOCK > > EmptyVisitorType
virtual ValueType bound() const
return a bound on the solution
visitors::VerboseVisitor< DualDecompositionSubGradient< GM, INF, DUALBLOCK > > VerboseVisitorType
A framework for inference algorithms based on Lagrangian decomposition.