icm.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_ICM_HXX
00003 #define OPENGM_ICM_HXX
00004 
00005 #include <vector>
00006 #include <string>
00007 #include <iostream>
00008 
00009 #include "opengm/opengm.hxx"
00010 #include "opengm/inference/visitors/visitor.hxx"
00011 #include "opengm/inference/inference.hxx"
00012 #include "opengm/inference/movemaker.hxx"
00013 #include "opengm/datastructures/buffer_vector.hxx"
00014 
00015 namespace opengm {
00016   
00020 template<class GM, class ACC>
00021 class ICM : public Inference<GM, ACC>
00022 {
00023 public:
00024    enum MoveType {
00025       SINGLE_VARIABLE = 0,
00026       FACTOR = 1
00027    };
00028    typedef ACC AccumulationType;
00029    typedef GM GraphicalModelType;
00030    OPENGM_GM_TYPE_TYPEDEFS;
00031    typedef Movemaker<GraphicalModelType> MovemakerType;
00032    typedef VerboseVisitor<ICM<GM,ACC> > VerboseVisitorType;
00033    typedef EmptyVisitor<ICM<GM,ACC> > EmptyVisitorType;
00034    typedef TimingVisitor<ICM<GM,ACC> > TimingVisitorType;
00035 
00036    class Parameter {
00037    public:
00038       Parameter(
00039          const std::vector<LabelType>& startPoint
00040       )
00041       :  moveType_(SINGLE_VARIABLE),
00042          startPoint_(startPoint) 
00043          {}
00044 
00045       Parameter(
00046          MoveType moveType, 
00047          const std::vector<LabelType>& startPoint 
00048       )
00049       :  moveType_(moveType),
00050          startPoint_(startPoint) 
00051          {}
00052       
00053       Parameter(
00054          MoveType moveType = SINGLE_VARIABLE
00055       )
00056       :  moveType_(moveType),
00057          startPoint_() 
00058       {}
00059       
00060       MoveType moveType_;
00061       std::vector<LabelType>  startPoint_;
00062    };
00063 
00064    ICM(const GraphicalModelType&);
00065    ICM(const GraphicalModelType&, const Parameter&);
00066    std::string name() const;
00067    const GraphicalModelType& graphicalModel() const;
00068    InferenceTermination infer();
00069    void reset();
00070    template<class VisitorType>
00071       InferenceTermination infer(VisitorType&);
00072    void setStartingPoint(typename std::vector<LabelType>::const_iterator);
00073    virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const ;
00074    size_t currentMoveType() const;
00075 
00076 private:
00077       const GraphicalModelType& gm_;
00078       MovemakerType movemaker_;
00079       Parameter param_;
00080       MoveType currentMoveType_;
00081        
00082 };
00083 
00084 template<class GM, class ACC>
00085 inline size_t
00086 ICM<GM, ACC>::currentMoveType()const{
00087    return currentMoveType_==SINGLE_VARIABLE?0:1;
00088 }
00089    
00090 template<class GM, class ACC>
00091 inline
00092 ICM<GM, ACC>::ICM
00093 (
00094       const GraphicalModelType& gm
00095 )
00096 :  gm_(gm),
00097    movemaker_(gm),
00098    param_(Parameter()),
00099    currentMoveType_(SINGLE_VARIABLE) {
00100 }
00101 
00102 template<class GM, class ACC>
00103 ICM<GM, ACC>::ICM
00104 (
00105       const GraphicalModelType& gm,
00106       const Parameter& parameter
00107 )
00108 :  gm_(gm),
00109    movemaker_(gm),
00110    param_(parameter),
00111    currentMoveType_(SINGLE_VARIABLE)
00112 {
00113    if(parameter.startPoint_.size() == gm.numberOfVariables()) {
00114       movemaker_.initialize(parameter.startPoint_.begin() );
00115    }
00116    else if(parameter.startPoint_.size() != 0) {
00117       throw RuntimeError("unsuitable starting point");
00118    }
00119 }
00120       
00121 template<class GM, class ACC>
00122 inline void
00123 ICM<GM, ACC>::reset()
00124 {
00125    if(param_.startPoint_.size() == gm_.numberOfVariables()) {
00126       movemaker_.initialize(param_.startPoint_.begin() );
00127    }
00128    else if(param_.startPoint_.size() != 0) {
00129       throw RuntimeError("unsuitable starting point");
00130    }
00131    else{
00132       movemaker_.reset();
00133    }
00134 }
00135    
00136 template<class GM, class ACC>
00137 inline void 
00138 ICM<GM,ACC>::setStartingPoint
00139 (
00140    typename std::vector<typename ICM<GM,ACC>::LabelType>::const_iterator begin
00141 ) {
00142    movemaker_.initialize(begin);
00143 }
00144    
00145 template<class GM, class ACC>
00146 inline std::string
00147 ICM<GM, ACC>::name() const
00148 {
00149    return "ICM";
00150 }
00151 
00152 template<class GM, class ACC>
00153 inline const typename ICM<GM, ACC>::GraphicalModelType&
00154 ICM<GM, ACC>::graphicalModel() const
00155 {
00156    return gm_;
00157 }
00158   
00159 template<class GM, class ACC>
00160 inline InferenceTermination
00161 ICM<GM,ACC>::infer()
00162 {
00163    EmptyVisitorType v;
00164    return infer(v);
00165 }
00166 
00167   
00168 template<class GM, class ACC>
00169 template<class VisitorType>
00170 InferenceTermination ICM<GM,ACC>::infer
00171 (
00172    VisitorType& visitor
00173 )
00174 {
00175    visitor.begin(*this,movemaker_.value(), movemaker_.value());
00176    if(param_.moveType_==SINGLE_VARIABLE ||param_.moveType_==FACTOR) {
00177       bool updates = true;
00178       std::vector<bool> isLocalOptimal(gm_.numberOfVariables());
00179       std::vector<opengm::RandomAccessSet<IndexType> >variableAdjacencyList;
00180       gm_.variableAdjacencyList(variableAdjacencyList);
00181       size_t v=0,s=0,n=0;
00182       while(updates) {
00183          updates = false;
00184          for(v=0; v<gm_.numberOfVariables(); ++v) {
00185             if(isLocalOptimal[v]==false) {
00186                for(s=0; s<gm_.numberOfLabels(v); ++s) {
00187                   if(s != movemaker_.state(v)) {
00188                      if(AccumulationType::bop(movemaker_.valueAfterMove(&v, &v+1, &s), movemaker_.value())) {
00189                         movemaker_.move(&v, &v+1, &s);
00190                         for(n=0;n<variableAdjacencyList[v].size();++n) {
00191                            isLocalOptimal[variableAdjacencyList[v][n]]=false;
00192                         }
00193                         updates = true;
00194                         visitor(*this,movemaker_.value(), movemaker_.value());
00195                      }
00196                   }
00197                }
00198                isLocalOptimal[v]=true;
00199             }
00200          }
00201       }
00202    }
00203    if(param_.moveType_==FACTOR) {
00204       currentMoveType_=FACTOR;
00205       //visitor(*this, movemaker_.value(),movemaker_.value());
00206       bool updates = true;
00207       std::vector<bool> isLocalOptimal(gm_.numberOfFactors(),false);
00208       //std::vector<opengm::RandomAccessSet<size_t> >variableAdjacencyList;
00209       opengm::BufferVector<LabelType> stateBuffer;
00210       stateBuffer.reserve(10);
00211       //gm_.factorAdjacencyList(variableAdjacencyList);
00212       size_t f=0,ff=0,v=0;
00213       while(updates) {
00214          updates = false;
00215          for(f=0; f<gm_.numberOfFactors(); ++f) {
00216             if(isLocalOptimal[f]==false && gm_[f].numberOfVariables()>1) {
00217                stateBuffer.clear();
00218                stateBuffer.resize(gm_[f].numberOfVariables());
00219                for(v=0;v<gm_[f].numberOfVariables();++v) {
00220                   stateBuffer[v]=movemaker_.state(gm_[f].variableIndex(v));
00221                }
00222                ValueType oldValue=movemaker_.value();
00223                ValueType newValue=movemaker_. template moveOptimally<ACC>(gm_[f].variableIndicesBegin(),gm_[f].variableIndicesEnd());   
00224                if(ACC::bop(newValue,oldValue)) {
00225                   updates = true ;
00226                   visitor(*this,movemaker_.value(), movemaker_.value());
00227                   for(v=0;v<gm_[f].numberOfVariables();++v) {
00228                      const size_t varIndex=gm_[f].variableIndex(v);
00229                      if(stateBuffer[v]!=movemaker_.state(varIndex)) {
00230                         for(ff=0;ff<gm_.numberOfFactors(varIndex);++ff) {
00231                            isLocalOptimal[gm_.factorOfVariable(varIndex,ff)]=false;
00232                         }
00233                      }
00234                   }
00235                }
00236                isLocalOptimal[f]=true;
00237             }
00238          }
00239       }
00240    }
00241    visitor.end(*this,movemaker_.value(), movemaker_.value());
00242    return NORMAL;
00243 }
00244 
00245 template<class GM, class ACC>
00246 inline InferenceTermination
00247 ICM<GM,ACC>::arg
00248 (
00249       std::vector<LabelType>& x,
00250       const size_t N
00251 ) const
00252 {
00253    if(N==1) {
00254       x.resize(gm_.numberOfVariables());
00255       for(size_t j=0; j<x.size(); ++j) {
00256          x[j] = movemaker_.state(j);
00257       }
00258       return NORMAL;
00259    }
00260    else {
00261       return UNKNOWN;
00262    }
00263 }
00264 
00265 } // namespace opengm
00266 
00267 #endif // #ifndef OPENGM_ICM_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:03 2013 for OpenGM by  doxygen 1.6.3