messagepassing_bp.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_BELIEFPROPAGATION_HXX
00003 #define OPENGM_BELIEFPROPAGATION_HXX
00004 
00005 #include <vector>
00006 #include <map>
00007 #include <list>
00008 #include <set>
00009 
00010 #include "opengm/opengm.hxx"
00011 #include "opengm/utilities/tribool.hxx"
00012 #include "opengm/operations/weightedoperations.hxx"
00013 #include "opengm/operations/normalize.hxx"
00014 #include "opengm/utilities/metaprogramming.hxx"
00015 #include "opengm/inference/messagepassing/messagepassing_operations.hxx"
00016 #include "opengm/inference/messagepassing/messagepassing_buffer.hxx"
00017 
00018 namespace opengm {
00019 
00021 
00022    template<class GM, class BUFFER, class OP, class ACC>
00023    class VariableHullBP {
00024    public:
00025       typedef GM                                  GraphicalModelType;
00026       typedef BUFFER                              BufferType;
00027       typedef typename BUFFER::ArrayType          BufferArrayType;
00028       typedef typename GM::FactorType             FactorType;
00029       typedef typename GM::IndependentFactorType  IndependentFactorType;
00030       typedef typename GM::ValueType              ValueType;
00031 
00032       VariableHullBP();
00033       void assign(const GM&, const size_t, const meta::EmptyType*);
00034       BUFFER& connectFactorHullBP(const size_t, BUFFER&);
00035       size_t numberOfBuffers() const;
00036       void propagateAll(const GM&, const ValueType& = 0, const bool = false);
00037       void propagate(const GM&, const size_t, const ValueType& = 0, const bool = false);
00038       void marginal(const GM&, const size_t, IndependentFactorType&, const bool = true) const; 
00039       //typename GM::ValueType bound() const;
00040       template<class DIST> ValueType distance(const size_t) const;
00041       const typename BUFFER::ArrayType& outBuffer(const size_t) const;
00042 
00043    private:
00044       std::vector<BUFFER* > outBuffer_;
00045       std::vector<BUFFER > inBuffer_;
00046    };
00047 
00048    template<class GM, class BUFFER, class OP, class ACC>
00049    class FactorHullBP {
00050    public:
00051       typedef GM                                  GraphicalModelType;
00052       typedef BUFFER                              BufferType;
00053       typedef typename BUFFER::ArrayType          BufferArrayType;
00054       typedef typename GM::FactorType             FactorType;
00055       typedef typename GM::IndependentFactorType  IndependentFactorType;
00056       typedef typename GM::ValueType              ValueType;
00057   
00058       size_t numberOfBuffers() const        { return inBuffer_.size(); }
00059       void assign(const GM&, const size_t, std::vector<VariableHullBP<GM,BUFFER,OP,ACC> >&, const meta::EmptyType*);
00060       void propagateAll(const ValueType& = 0, const bool = true);
00061       void propagate(const size_t, const ValueType& = 0, const bool = true);
00062       void marginal(IndependentFactorType&, const bool = true) const;
00063       //typename GM::ValueType bound() const;
00064       template<class DIST> ValueType distance(const size_t) const;
00065 
00066    private:
00067       FactorType const* myFactor_;
00068       std::vector<BUFFER* > outBuffer_;
00069       std::vector<BUFFER > inBuffer_;
00070    };
00071 
00073 
00075    template<class GM, class ACC, class BUFFER = MessageBuffer<marray::Marray<double> > >
00076    class BeliefPropagationUpdateRules {
00077    public:
00078       typedef GM                                  GraphicalModelType;
00079       typedef BUFFER                              BufferType;
00080       typedef typename BUFFER::ArrayType          BufferArrayType; 
00081       typedef typename GM::ValueType              ValueType; 
00082       typedef typename GM::IndependentFactorType  IndependentFactorType;
00083       typedef typename GM::FactorType             FactorType;
00084       typedef typename GM::OperatorType           OperatorType;
00086       typedef FactorHullBP<GM, BufferType, OperatorType, ACC> FactorHullType;
00087       typedef VariableHullBP<GM, BufferType, OperatorType, ACC> VariableHullType;
00088       typedef meta::EmptyType SpecialParameterType;
00089 
00090       template<class MP_PARAM>
00091          static void initializeSpecialParameter(const GM& gm, MP_PARAM& mpParameter)
00092             {}
00094    };
00095 
00096    template<class GM, class BUFFER, class OP, class ACC>
00097    inline  VariableHullBP<GM, BUFFER, OP, ACC>::VariableHullBP()
00098    {}
00099 
00100    template<class GM, class BUFFER, class OP, class ACC>
00101    inline void VariableHullBP<GM, BUFFER, OP, ACC>::assign
00102    (
00103       const GM& gm,
00104       const size_t variableIndex,
00105       const meta::EmptyType* et
00106    ) {
00107       size_t numberOfFactors = gm.numberOfFactors(variableIndex);
00108       inBuffer_.resize(numberOfFactors);
00109       outBuffer_.resize(numberOfFactors);
00110       for(size_t j = 0; j < numberOfFactors; ++j) {
00111          inBuffer_[j].assign(gm.numberOfLabels(variableIndex), OP::template neutral<ValueType>());
00112       }
00113    }
00114 
00115    template<class GM, class BUFFER, class OP, class ACC>
00116    inline size_t VariableHullBP<GM, BUFFER, OP, ACC>::numberOfBuffers() const {
00117       return outBuffer_.size();
00118    }
00119 
00120    template<class GM, class BUFFER, class OP, class ACC>
00121    inline BUFFER& VariableHullBP<GM, BUFFER, OP, ACC>::connectFactorHullBP
00122    (
00123       const size_t bufferNumber,
00124       BUFFER& variableOutBuffer
00125    ) {
00126       OPENGM_ASSERT(bufferNumber < numberOfBuffers());
00127       outBuffer_[bufferNumber] = &variableOutBuffer;
00128       return inBuffer_[bufferNumber];
00129    }
00130 
00131    template<class GM, class BUFFER, class OP, class ACC >
00132    inline void VariableHullBP<GM, BUFFER, OP, ACC>::propagate
00133    (
00134       const GM& gm,
00135       const size_t bufferNumber,
00136       const ValueType& damping,
00137       const bool useNormalization
00138    ) {
00139       OPENGM_ASSERT(bufferNumber < numberOfBuffers());
00140       outBuffer_[bufferNumber]->toggle();
00141       if(inBuffer_.size() < 2) {
00142          return; // nothing to send
00143       }
00144       // initialize neutral message
00145       BufferArrayType& newMessage = outBuffer_[bufferNumber]->current();
00146       opengm::messagepassingOperations::operate<OP>(inBuffer_, bufferNumber, newMessage);
00147 
00148       // damp message
00149       if(damping != 0) {
00150          BufferArrayType& oldMessage = outBuffer_[bufferNumber]->old();
00151          opengm::messagepassingOperations::weightedMean<OP>(newMessage, oldMessage, damping, newMessage);
00152       }
00153       // normalize message
00154       if(useNormalization) {
00155          opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
00156       }
00157    }
00158 
00159   
00160    template<class GM, class BUFFER, class OP, class ACC>
00161    inline void VariableHullBP<GM, BUFFER, OP, ACC>::propagateAll
00162    (
00163       const GM& gm,
00164       const ValueType& damping,
00165       const bool useNormalization
00166    ) {
00167       for(size_t bufferNumber = 0; bufferNumber < numberOfBuffers(); ++bufferNumber) {
00168          propagate(gm, bufferNumber, damping, useNormalization);
00169       }
00170    }
00171 
00172    template<class GM, class BUFFER, class OP, class ACC >
00173    inline void VariableHullBP<GM, BUFFER, OP, ACC>::marginal
00174    (
00175       const GM& gm,
00176       const size_t variableIndex,
00177       IndependentFactorType& out,
00178       const bool useNormalization
00179    ) const {
00180 
00181       // set out to neutral
00182       out.assign(gm, &variableIndex, &variableIndex+1, OP::template neutral<ValueType>());
00183       opengm::messagepassingOperations::operate<OP>(inBuffer_, out);
00184 
00185       // normalize output
00186       if(useNormalization) {
00187          opengm::messagepassingOperations::normalize<OP,ACC>(out);
00188       }
00189    }
00190 /*
00191    template<class GM, class BUFFER, class OP, class ACC>
00192    inline typename GM::ValueType VariableHullBP<GM, BUFFER, OP, ACC>::bound() const
00193    { 
00194       ValueType v;
00195       //OP::neutral(v);
00196 
00197       BufferArrayType a(inBuffer_[0].current().shapeBegin(),inBuffer_[0].current().shapeEnd());
00198       opengm::messagepassingOperations::operate<OP>(inBuffer_, a);
00199 
00200       if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
00201          v = a(0);
00202          for(size_t n=1; n<a.size(); ++n) {
00203             ACC::op(a(n),v);
00204          }
00205       }
00206       else{
00207          ACC::ineutral(v);
00208       }  
00209       //ACC::ineutral(v);
00210 
00211       //v = opengm::messagepassingOperations::template boundOperation<ValueType,OP,ACC>(a,a); 
00212 //      ACC::ineutral(v);
00213       return v;
00214    } 
00215 */
00216 
00217    template<class GM, class BUFFER, class OP, class ACC >
00218    template<class DIST>
00219    inline typename GM::ValueType VariableHullBP<GM, BUFFER, OP, ACC>::distance
00220    (
00221       const size_t bufferNumber
00222    ) const {
00223       return inBuffer_[bufferNumber].template dist<DIST > ();
00224    }
00225 
00226    template<class GM, class BUFFER, class OP, class ACC >
00227    inline const typename BUFFER::ArrayType& VariableHullBP<GM, BUFFER, OP, ACC>::outBuffer
00228    (
00229       const size_t bufferIndex
00230    ) const {
00231       OPENGM_ASSERT(bufferIndex < outBuffer_.size());
00232       return outBuffer_[bufferIndex]->current();
00233    }
00234 
00235    template<class GM, class BUFFER, class OP, class ACC>
00236    inline void FactorHullBP<GM, BUFFER, OP, ACC>::assign
00237    (
00238       const GM& gm,
00239       const size_t factorIndex,
00240       std::vector<VariableHullBP<GM, BUFFER, OP, ACC> >& variableHulls,
00241       const meta::EmptyType* et
00242    ) {
00243       myFactor_ = (FactorType *const)(&gm[factorIndex]);
00244       inBuffer_.resize(gm[factorIndex].numberOfVariables());
00245       outBuffer_.resize(gm[factorIndex].numberOfVariables());
00246       for(size_t n=0; n<gm.numberOfVariables(factorIndex); ++n) {
00247          size_t variableIndex = gm.variableOfFactor(factorIndex,n);
00248          inBuffer_[n].assign(gm.numberOfLabels(variableIndex), OP::template neutral<ValueType > ());
00249          size_t bufferNumber = 1000000;
00250          for(size_t i=0; i<gm.numberOfFactors(variableIndex); ++i) {
00251             if(gm.factorOfVariable(variableIndex,i) == factorIndex) {
00252                bufferNumber=i;
00253                break;
00254             }
00255          } 
00256          outBuffer_[n] =&(variableHulls[variableIndex].connectFactorHullBP(bufferNumber, inBuffer_[n]));
00257       }
00258    }
00259 
00260    template<class GM, class BUFFER, class OP, class ACC >
00261    inline void FactorHullBP<GM, BUFFER, OP, ACC>::propagate
00262    (
00263       const size_t id,
00264       const ValueType& damping,
00265       const bool useNormalization
00266    ) {
00267       OPENGM_ASSERT(id < outBuffer_.size());
00268       outBuffer_[id]->toggle();
00269       BufferArrayType& newMessage = outBuffer_[id]->current();
00270       opengm::messagepassingOperations::operateF<GM,ACC>(*myFactor_, inBuffer_, id, newMessage);
00271 
00272       // damp message
00273       if(damping != 0) {
00274          BufferArrayType& oldMessage = outBuffer_[id]->old();
00275          opengm::messagepassingOperations::weightedMean<OP>(newMessage, oldMessage, damping, newMessage);
00276       }
00277       // normalize message
00278       if(useNormalization) {
00279          opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
00280       }
00281    }
00282 
00283    template<class GM, class BUFFER, class OP, class ACC >
00284    inline void FactorHullBP<GM, BUFFER, OP, ACC>::propagateAll
00285    (
00286       const ValueType& damping,
00287       const bool useNormalization
00288    ) {
00289       for(size_t j = 0; j < inBuffer_.size(); ++j) {
00290          propagate(j, damping, useNormalization);
00291       }
00292    }
00293 
00294    template<class GM, class BUFFER, class OP, class ACC>
00295    inline void FactorHullBP<GM, BUFFER, OP, ACC>::marginal
00296    (
00297       IndependentFactorType& out,
00298       const bool useNormalization
00299    ) const 
00300    {  
00301       opengm::messagepassingOperations::operateF<GM>(*myFactor_, inBuffer_,out);
00302 
00303       if(useNormalization) {
00304          opengm::messagepassingOperations::normalize<OP,ACC>(out);
00305       }
00306    }
00307 /*
00308    template<class GM, class BUFFER, class OP, class ACC>
00309    inline typename GM::ValueType FactorHullBP<GM, BUFFER, OP, ACC>::bound
00310    () const
00311    {
00312       //typename GM::IndependentFactorType a = myFactor_; 
00313       typename GM::IndependentFactorType a = *myFactor_;
00314       //opengm::messagepassingOperations::operateF<GM>(*myFactor_, inBuffer_,a);
00315       opengm::messagepassingOperations::operateFi<GM>(*myFactor_, outBuffer_, a);
00316       //return opengm::messagepassingOperations::boundOperation<ValueType,OP,ACC>(a,b);
00317       ValueType v;
00318       if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
00319          v = a(0);
00320          for(size_t n=1; n<a.size(); ++n) {
00321             ACC::op(a(n),v);
00322          }
00323       }
00324       else{
00325          ACC::ineutral(v);
00326       }  
00327       return v;
00328    }
00329 */
00330    template<class GM, class BUFFER, class OP, class ACC >
00331    template<class DIST>
00332    inline typename GM::ValueType FactorHullBP<GM, BUFFER, OP, ACC>::distance
00333    (
00334       const size_t j
00335    ) const {
00336       return inBuffer_[j].template dist<DIST > ();
00337    }
00338 
00339 } // namespace opengm
00340 
00341 #endif // #ifndef OPENGM_BELIEFPROPAGATION_HXX
00342 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:04 2013 for OpenGM by  doxygen 1.6.3