alphaexpansion.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_ALPHAEXPANSION_HXX
00003 #define OPENGM_ALPHAEXPANSION_HXX
00004 
00005 #include "opengm/inference/inference.hxx"
00006 #include "opengm/inference/visitors/visitor.hxx"
00007 
00008 namespace opengm {
00009 
00012 template<class GM, class INF>
00013 class AlphaExpansion
00014 : public Inference<GM, typename INF::AccumulationType>
00015 {
00016 public:
00017    typedef GM GraphicalModelType;
00018    typedef INF InferenceType; 
00019    typedef typename INF::AccumulationType AccumulationType;
00020    OPENGM_GM_TYPE_TYPEDEFS;
00021    typedef VerboseVisitor<AlphaExpansion<GM,INF> > VerboseVisitorType;
00022    typedef TimingVisitor<AlphaExpansion<GM,INF> > TimingVisitorType;
00023    typedef EmptyVisitor<AlphaExpansion<GM,INF> > EmptyVisitorType;
00024 
00025    struct Parameter {
00026       typedef typename InferenceType::Parameter InferenceParameter;
00027       enum LabelingIntitialType {DEFAULT_LABEL, RANDOM_LABEL, LOCALOPT_LABEL, EXPLICIT_LABEL};
00028       enum OrderType {DEFAULT_ORDER, RANDOM_ORDER, EXPLICIT_ORDER};
00029 
00030       Parameter
00031       (
00032          const size_t maxNumberOfSteps  = 1000,
00033          const InferenceParameter& para = InferenceParameter()
00034       )
00035       :  parameter_(para),
00036          maxNumberOfSteps_(maxNumberOfSteps),
00037          labelInitialType_(DEFAULT_LABEL),
00038          orderType_(DEFAULT_ORDER),
00039          randSeedOrder_(0),
00040          randSeedLabel_(0),
00041          labelOrder_(),
00042          label_()
00043       {}
00044 
00045       InferenceParameter parameter_;
00046       size_t maxNumberOfSteps_;
00047       LabelingIntitialType labelInitialType_;
00048       OrderType orderType_;
00049       unsigned int randSeedOrder_;
00050       unsigned int randSeedLabel_;
00051       std::vector<LabelType> labelOrder_;
00052       std::vector<LabelType> label_;
00053    };
00054 
00055    AlphaExpansion(const GraphicalModelType&, Parameter para = Parameter());
00056 
00057    std::string name() const;
00058    const GraphicalModelType& graphicalModel() const;
00059    template<class StateIterator>
00060       void setState(StateIterator, StateIterator);
00061    InferenceTermination infer();
00062    void reset();
00063    template<class Visitor>
00064       InferenceTermination infer(Visitor& visitor);
00065    void setStartingPoint(typename std::vector<LabelType>::const_iterator);
00066    InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
00067 
00068 private:
00069    const GraphicalModelType& gm_;
00070    Parameter parameter_;
00071    std::vector<LabelType> label_;
00072    std::vector<LabelType> labelList_;
00073    size_t maxState_;
00074    size_t alpha_;
00075    size_t counter_;
00076    void incrementAlpha();
00077    void setLabelOrder(std::vector<LabelType>& l);
00078    void setLabelOrderRandom(unsigned int);
00079    void setInitialLabel(std::vector<LabelType>& l);
00080    void setInitialLabelLocalOptimal();
00081    void setInitialLabelRandom(unsigned int);
00082    void addUnary(INF&, const size_t var, const ValueType v0, const ValueType v1);
00083    void addPairwise(INF&, const size_t var1, const size_t var2, const ValueType v0, const ValueType v1, const ValueType v2, const ValueType v3);
00084 };
00085 
00086 template<class GM, class INF>
00087 inline std::string
00088 AlphaExpansion<GM, INF>::name() const
00089 {
00090    return "Alpha-Expansion";
00091 }
00092 
00093 template<class GM, class INF>
00094 inline const typename AlphaExpansion<GM, INF>::GraphicalModelType&
00095 AlphaExpansion<GM, INF>::graphicalModel() const
00096 {
00097    return gm_;
00098 }
00099 
00100 template<class GM, class INF>
00101 template<class StateIterator>
00102 inline void
00103 AlphaExpansion<GM, INF>::setState
00104 (
00105    StateIterator begin,
00106    StateIterator end
00107 )
00108 {
00109    label_.assign(begin, end);
00110 }
00111 
00112 template<class GM, class INF>
00113 inline void
00114 AlphaExpansion<GM,INF>::setStartingPoint
00115 (
00116    typename std::vector<typename AlphaExpansion<GM,INF>::LabelType>::const_iterator begin
00117 ) {
00118    try{
00119       label_.assign(begin, begin+gm_.numberOfVariables());
00120    }
00121    catch(...) {
00122       throw RuntimeError("unsuitable starting point");
00123    }
00124 }
00125 
00126 template<class GM, class INF>
00127 inline
00128 AlphaExpansion<GM, INF>::AlphaExpansion
00129 (
00130    const GraphicalModelType& gm,
00131    Parameter para
00132 )
00133 :  gm_(gm),
00134    parameter_(para),
00135    maxState_(0)
00136 {
00137    for(size_t j=0; j<gm_.numberOfFactors(); ++j) {
00138       if(gm_[j].numberOfVariables() > 2) {
00139          throw RuntimeError("This implementation of Alpha-Expansion supports only factors of order <= 2.");
00140       }
00141    }
00142    for(size_t i=0; i<gm_.numberOfVariables(); ++i) {
00143       size_t numSt = gm_.numberOfLabels(i);
00144       if(numSt > maxState_) {
00145          maxState_ = numSt;
00146       }
00147    }
00148 
00149    if(parameter_.labelInitialType_ == Parameter::RANDOM_LABEL) {
00150       setInitialLabelRandom(parameter_.randSeedLabel_);
00151    }
00152    else if(parameter_.labelInitialType_ == Parameter::LOCALOPT_LABEL) {
00153       setInitialLabelLocalOptimal();
00154    }
00155    else if(parameter_.labelInitialType_ == Parameter::EXPLICIT_LABEL) {
00156       setInitialLabel(parameter_.label_);
00157    }
00158    else{
00159       label_.resize(gm_.numberOfVariables(), 0);
00160    }
00161 
00162 
00163    if(parameter_.orderType_ == Parameter::RANDOM_ORDER) {
00164       setLabelOrderRandom(parameter_.randSeedOrder_);
00165    }
00166    else if(parameter_.orderType_ == Parameter::EXPLICIT_ORDER) {
00167       setLabelOrder(parameter_.labelOrder_);
00168    }
00169    else{
00170       labelList_.resize(maxState_);
00171       for(size_t i=0; i<maxState_; ++i)
00172          labelList_[i] = i;
00173    }
00174 
00175    counter_ = 0;
00176    alpha_   = labelList_[counter_];
00177 }
00178 
00179 // reset assumes that the structure of
00180 // the graphical model has not changed
00181 template<class GM, class INF>
00182 inline void
00183 AlphaExpansion<GM, INF>::reset() {
00184    if(parameter_.labelInitialType_ == Parameter::RANDOM_LABEL) {
00185       setInitialLabelRandom(parameter_.randSeedLabel_);
00186    }
00187    else if(parameter_.labelInitialType_ == Parameter::LOCALOPT_LABEL) {
00188       setInitialLabelLocalOptimal();
00189    }
00190    else if(parameter_.labelInitialType_ == Parameter::EXPLICIT_LABEL) {
00191       setInitialLabel(parameter_.label_);
00192    }
00193    else{
00194       std::fill(label_.begin(),label_.end(),0);
00195    }
00196 
00197 
00198    if(parameter_.orderType_ == Parameter::RANDOM_ORDER) {
00199       setLabelOrderRandom(parameter_.randSeedOrder_);
00200    }
00201    else if(parameter_.orderType_ == Parameter::EXPLICIT_ORDER) {
00202       setLabelOrder(parameter_.labelOrder_);
00203    }
00204    else{
00205       for(size_t i=0; i<maxState_; ++i)
00206          labelList_[i] = i;
00207    }
00208    counter_ = 0;
00209    alpha_   = labelList_[counter_];
00210 }
00211 
00212 template<class GM, class INF>
00213 inline void
00214 AlphaExpansion<GM, INF>::addUnary
00215 (
00216    INF& inf,
00217    const size_t var1,
00218    const ValueType v0,
00219    const ValueType v1
00220 ) {
00221    const size_t shape[] = {2};
00222    size_t vars[] = {var1};
00223    opengm::IndependentFactor<ValueType,IndexType,LabelType> fac(vars, vars+1, shape, shape+1);
00224    fac(0) = v0;
00225    fac(1) = v1;
00226    inf.addFactor(fac);
00227 }
00228 
00229 template<class GM, class INF>
00230 inline void
00231 AlphaExpansion<GM, INF>::addPairwise
00232 (
00233    INF& inf,
00234    const size_t var1,
00235    const size_t var2,
00236    const ValueType v0,
00237    const ValueType v1,
00238    const ValueType v2,
00239    const ValueType v3
00240 ) {
00241    const LabelType shape[] = {2, 2};
00242    const IndexType vars[]  = {var1, var2};
00243    opengm::IndependentFactor<ValueType,IndexType,LabelType> fac(vars, vars+2, shape, shape+2);
00244    fac(0, 0) = v0;
00245    fac(0, 1) = v1;
00246    fac(1, 0) = v2;
00247    fac(1, 1) = v3;
00248    inf.addFactor(fac);
00249 }
00250 
00251 template<class GM, class INF>
00252 inline InferenceTermination
00253 AlphaExpansion<GM, INF>::infer()
00254 {
00255    EmptyVisitorType visitor;
00256    return infer(visitor);
00257 }
00258 
00259 template<class GM, class INF>
00260 template<class Visitor>
00261 InferenceTermination
00262 AlphaExpansion<GM, INF>::infer
00263 (
00264    Visitor& visitor
00265 )
00266 {
00267    size_t it = 0;
00268    size_t countUnchanged = 0;
00269    size_t numberOfVariables = gm_.numberOfVariables();
00270    std::vector<size_t> variable2Node(numberOfVariables);
00271    ValueType energy = gm_.evaluate(label_);
00272    visitor.begin(*this,energy,energy);
00273    LabelType vecA[1];
00274    LabelType vecX[1];
00275    LabelType vecAA[2];
00276    LabelType vecAX[2];
00277    LabelType vecXA[2];
00278    LabelType vecXX[2];
00279    while(it++ < parameter_.maxNumberOfSteps_ && countUnchanged < maxState_) {
00280       size_t numberOfAuxiliaryNodes = 0;
00281       for(size_t k=0 ; k<gm_.numberOfFactors(); ++k) {
00282          const FactorType& factor = gm_[k];
00283          if(factor.numberOfVariables() == 2) {
00284             size_t var1 = factor.variableIndex(0);
00285             size_t var2 = factor.variableIndex(1);
00286             if(label_[var1] != label_[var2] && label_[var1] != alpha_ && label_[var2] != alpha_ ) {
00287                ++numberOfAuxiliaryNodes;
00288             }
00289          }
00290       }
00291       std::vector<size_t> numFacDim(4, 0);
00292       INF inf(numberOfVariables + numberOfAuxiliaryNodes, numFacDim, parameter_.parameter_);
00293       size_t varX = numberOfVariables;
00294       size_t countAlphas = 0;
00295       for (size_t k=0 ; k<gm_.numberOfVariables(); ++k) {
00296          if (label_[k] == alpha_ ) {
00297             addUnary(inf, k, 0, std::numeric_limits<ValueType>::infinity());
00298             ++countAlphas;
00299          }
00300       }
00301       if(countAlphas < gm_.numberOfVariables()) {
00302          for (size_t k=0 ; k<gm_.numberOfFactors(); ++k) {
00303             const  FactorType& factor = gm_[k];
00304             if(factor.numberOfVariables() == 1) {
00305                size_t var = factor.variableIndex(0);
00306                vecA[0] = alpha_;
00307                vecX[0] = label_[var];
00308                if (label_[var] != alpha_ ) {
00309                   addUnary(inf, var, factor(vecA), factor(vecX));
00310                }
00311             }
00312             else if (factor.numberOfVariables() == 2) {
00313                size_t var1 = factor.variableIndex(0);
00314                size_t var2 = factor.variableIndex(1);
00315                std::vector<IndexType> vars(2); vars[0]=var1;vars[1]=var2;
00316                vecAA[0] = vecAA[1] = alpha_;
00317                vecAX[0] = alpha_;       vecAX[1] = label_[var2];
00318                vecXA[0] = label_[var1]; vecXA[1] = alpha_;
00319                vecXX[0] = label_[var1]; vecXX[1] = label_[var2];
00320                if(label_[var1]==alpha_ && label_[var2]==alpha_) {
00321                   continue;
00322                }
00323                else if(label_[var1]==alpha_) {
00324                   addUnary(inf, var2, factor(vecAA), factor(vecAX));
00325                }
00326                else if(label_[var2]==alpha_) {
00327                   addUnary(inf, var1, factor(vecAA), factor(vecXA));
00328                }
00329                else if(label_[var1]==label_[var2]) {
00330                   addPairwise(inf, var1, var2, factor(vecAA), factor(vecAX), factor(vecXA), factor(vecXX));
00331                }
00332                else{
00333                   OPENGM_ASSERT(varX < numberOfVariables + numberOfAuxiliaryNodes);
00334                   addPairwise(inf, var1, varX, 0, factor(vecAX), 0, 0);
00335                   addPairwise(inf, var2, varX, 0, factor(vecXA), 0, 0);
00336                   addUnary(inf, varX, factor(vecAA), factor(vecXX));
00337                   ++varX;
00338                }
00339             }
00340          }
00341          std::vector<LabelType> state;
00342          inf.infer();
00343          inf.arg(state);
00344          OPENGM_ASSERT(state.size() == numberOfVariables + numberOfAuxiliaryNodes);
00345          for(size_t var=0; var<numberOfVariables ; ++var) {
00346             if (label_[var] != alpha_ && state[var]==0) {
00347                label_[var] = alpha_;
00348             }
00349             OPENGM_ASSERT(label_[var] < gm_.numberOfLabels(var));
00350          }
00351       }
00352       OPENGM_ASSERT(gm_.numberOfVariables() == label_.size());
00353       ValueType energy2 = gm_.evaluate(label_);
00354       visitor(*this,energy2,energy,alpha_);
00355       // OPENGM_ASSERT(!AccumulationType::ibop(energy2, energy));
00356       if(AccumulationType::bop(energy2, energy)) {
00357          energy=energy2;
00358          countUnchanged = 0;
00359       }
00360       else{
00361          ++countUnchanged;
00362       }
00363       incrementAlpha();
00364       OPENGM_ASSERT(alpha_ < maxState_);
00365    }
00366    visitor.end(*this,energy,energy);
00367    return NORMAL;
00368 }
00369 
00370 template<class GM, class INF>
00371 inline InferenceTermination
00372 AlphaExpansion<GM, INF>::arg
00373 (
00374    std::vector<LabelType>& arg,
00375    const size_t n
00376 ) const
00377 {
00378    if(n > 1) {
00379       return UNKNOWN;
00380    }
00381    else {
00382       OPENGM_ASSERT(label_.size() == gm_.numberOfVariables());
00383       arg.resize(label_.size());
00384       for(size_t i=0; i<label_.size(); ++i) {
00385          arg[i] = label_[i];
00386       }
00387       return NORMAL;
00388    }
00389 }
00390 
00391 template<class GM, class INF>
00392 inline void
00393 AlphaExpansion<GM, INF>::setLabelOrder
00394 (
00395    std::vector<LabelType>& l
00396 ) {
00397    if(l.size() == maxState_) {
00398       labelList_=l;
00399    }
00400 }
00401 
00402 template<class GM, class INF>
00403 inline void
00404 AlphaExpansion<GM, INF>::setLabelOrderRandom
00405 (
00406    unsigned int seed
00407 ) {
00408    srand(seed);
00409    labelList_.resize(maxState_);
00410    for (size_t i=0; i<maxState_;++i) {
00411       labelList_[i]=i;
00412    }
00413    random_shuffle(labelList_.begin(), labelList_.end());
00414 }
00415 
00416 template<class GM, class INF>
00417 inline void
00418 AlphaExpansion<GM, INF>::setInitialLabel
00419 (
00420    std::vector<LabelType>& l
00421 ) {
00422    label_.resize(gm_.numberOfVariables());
00423    if(l.size() == label_.size()) {
00424       for(size_t i=0; i<l.size();++i) {
00425          if(l[i]>=gm_.numberOfLabels(i)) return;
00426       }
00427       for(size_t i=0; i<l.size();++i) {
00428          label_[i] = l[i];
00429       }
00430    }
00431 }
00432 
00433 template<class GM, class INF>
00434 inline void
00435 AlphaExpansion<GM, INF>::setInitialLabelLocalOptimal() {
00436    label_.resize(gm_.numberOfVariables(), 0);
00437    std::vector<size_t> accVec;
00438    for(size_t i=0; i<gm_.numberOfFactors();++i) {
00439       if(gm_[i].numberOfVariables()==1) {
00440          std::vector<size_t> state(1, 0);
00441          ValueType value = gm_[i](state.begin());
00442          for(state[0]=1; state[0]<gm_.numberOfLabels(i); ++state[0]) {
00443             if(AccumulationType::bop(gm_[i](state.begin()), value)) {
00444                value = gm_[i](state.begin());
00445                label_[i] = state[0];
00446             }
00447          }
00448       }
00449    }
00450 }
00451 
00452 template<class GM, class INF>
00453 inline void
00454 AlphaExpansion<GM, INF>::setInitialLabelRandom
00455 (
00456    unsigned int seed
00457 ) {
00458    srand(seed);
00459    label_.resize(gm_.numberOfVariables());
00460    for(size_t i=0; i<gm_.numberOfVariables();++i) {
00461       label_[i] = rand() % gm_.numberOfLabels(i);
00462    }
00463 }
00464 
00465 template<class GM, class INF>
00466 inline void
00467 AlphaExpansion<GM, INF>::incrementAlpha() {
00468    counter_ = (counter_+1) % maxState_;
00469    alpha_ = labelList_[counter_];
00470 }
00471 
00472 } // namespace opengm
00473 
00474 #endif // #ifndef OPENGM_ALPHAEXPANSION_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:01 2013 for OpenGM by  doxygen 1.6.3