messagepassing_trbp.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_TREEREWEIGTHEDBELIEFPROPAGATION_HXX
00003 #define OPENGM_TREEREWEIGTHEDBELIEFPROPAGATION_HXX
00004 
00005 #include <vector>
00006 #include <map>
00007 #include <list>
00008 #include <set>
00009 
00010 #include "opengm/opengm.hxx"
00011 #include "opengm/inference/messagepassing/messagepassing_buffer.hxx"
00012 #include "opengm/graphicalmodel/decomposition/graphicalmodeldecomposer.hxx"
00013 #include "opengm/utilities/tribool.hxx"
00014 #include "opengm/operations/weightedoperations.hxx"
00015 #include "opengm/operations/normalize.hxx"
00016 #include "opengm/inference/messagepassing/messagepassing_operations.hxx"
00017 
00018 namespace opengm {
00020    template<class GM, class BUFFER, class OP, class ACC>
00021    class VariableHullTRBP {
00022    public:
00023       typedef GM                                    GraphicalModelType;
00024       typedef BUFFER                                BufferType;
00025       typedef typename BUFFER::ArrayType            BufferArrayType;
00026       typedef typename GM::ValueType                ValueType;
00027       typedef typename GM::IndependentFactorType    IndependentFactorType;
00028 
00029       VariableHullTRBP();
00030       void assign(const GM&, const size_t, const std::vector<ValueType>*);
00031       BUFFER& connectFactorHullTRBP(const size_t, BUFFER&);
00032       size_t numberOfBuffers() const;
00033       void propagateAll(const GM&, const ValueType& = 0, const bool = false);
00034       void propagate(const GM&, const size_t, const ValueType& = 0, const bool = false);
00035       void marginal(const GM&, const size_t, IndependentFactorType&, const bool = true) const;
00036       //typename GM::ValueType bound() const;
00037       template<class DIST> ValueType distance(const size_t) const;
00038 
00039    private:
00040       std::vector<BUFFER* >  outBuffer_;
00041       std::vector<BUFFER >   inBuffer_;
00042       std::vector<ValueType> rho_;
00043    };
00044 
00045    // Wrapper class for factor nodes
00046    template<class GM, class BUFFER, class OP, class ACC>
00047    class FactorHullTRBP {
00048    public:
00049       typedef GM                                 GraphicalModelType;
00050       typedef BUFFER                             BufferType;
00051       typedef typename BUFFER::ArrayType         BufferArrayType;
00052       typedef typename GM::FactorType            FactorType;
00053       typedef typename GM::IndependentFactorType IndependentFactorType;
00054       typedef typename GM::ValueType             ValueType;
00055 
00056       FactorHullTRBP();
00057       size_t numberOfBuffers() const       { return inBuffer_.size(); }
00058       //size_t variableIndex(size_t i) const { return variableIndices_[i]; }
00059       void assign(const GM&, const size_t, std::vector<VariableHullTRBP<GM,BUFFER,OP,ACC> >&, const std::vector<ValueType>*);
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*           myFactor_;
00068       std::vector<BUFFER* > outBuffer_;
00069       std::vector<BUFFER >  inBuffer_;
00070       ValueType             rho_;
00071    };
00073 
00075    template<class GM, class ACC, class BUFFER = opengm::MessageBuffer<marray::Marray<double> > >
00076    class TrbpUpdateRules {
00077    public:
00078       typedef typename GM::ValueType ValueType;
00079       typedef typename GM::IndependentFactorType IndependentFactorType;
00080       typedef typename GM::FactorType FactorType;
00081       typedef typename GM::OperatorType OperatorType;
00082       typedef FactorHullTRBP<GM, BUFFER, OperatorType, ACC> FactorHullType;
00083       typedef VariableHullTRBP<GM, BUFFER, OperatorType, ACC> VariableHullType;
00084       typedef std::vector<ValueType> SpecialParameterType;
00085 
00086       template<class MP_PARAM>
00087       static void initializeSpecialParameter(const GM& gm,MP_PARAM& mpParameter) {
00088          // set rho if not set manually
00089          if (mpParameter.specialParameter_.size() == 0) {
00090             // set rho by tree decomposition
00091             opengm::GraphicalModelDecomposer<GM> decomposer;
00092             const opengm::GraphicalModelDecomposition decomposition = decomposer.decomposeIntoSpanningTrees(gm);
00093             OPENGM_ASSERT(decomposition.isValid(gm));
00094             typedef typename GraphicalModelDecomposition::SubFactorListType SubFactorListType;
00095             const std::vector<SubFactorListType>& subFactorList = decomposition.getFactorLists();
00096             mpParameter.specialParameter_.resize(gm.numberOfFactors());
00097             for (size_t factorId = 0; factorId < gm.numberOfFactors(); ++factorId) {
00098                mpParameter.specialParameter_[factorId] = 1.0 / subFactorList[factorId].size();
00099             }
00100          }
00101          else if (mpParameter.specialParameter_.size() != gm.numberOfFactors()) {
00102             throw RuntimeError("The parameter rho has been set incorrectly.");
00103          }
00104          if(!NO_DEBUG) {
00105             // test rho
00106             OPENGM_ASSERT(mpParameter.specialParameter_.size() == gm.numberOfFactors());
00107             for (size_t i = 0; i < gm.numberOfFactors(); ++i) {
00108                if(gm.numberOfVariables() < 2) { 
00109                   OPENGM_ASSERT(mpParameter.specialParameter_[i] == 1); // ??? allow for numerical deviation
00110                }
00111                OPENGM_ASSERT(mpParameter.specialParameter_[i] > 0);
00112             }
00113          }
00114       }
00115    };
00116 
00117    template<class GM, class BUFFER, class OP, class ACC>
00118    inline VariableHullTRBP<GM, BUFFER, OP, ACC>::VariableHullTRBP()
00119    {}
00120 
00121    template<class GM, class BUFFER, class OP, class ACC>
00122    inline void VariableHullTRBP<GM, BUFFER, OP, ACC>::assign
00123    (
00124       const GM& gm,
00125       const size_t variableIndex,
00126       const std::vector<ValueType>* rho
00127    ) {
00128       size_t numberOfFactors = gm.numberOfFactors(variableIndex);
00129       rho_.resize(numberOfFactors);
00130       for(size_t j = 0; j < numberOfFactors; ++j) {
00131          rho_[j] = (*rho)[gm.factorOfVariable(variableIndex,j)];
00132       }
00133       inBuffer_.resize(numberOfFactors);
00134       outBuffer_.resize(numberOfFactors);
00135       // allocate input-buffer
00136       for(size_t j = 0; j < numberOfFactors; ++j) {
00137          inBuffer_[j].assign(gm.numberOfLabels(variableIndex), OP::template neutral<ValueType > ());
00138       }
00139    }
00140 
00141 
00142    template<class GM, class BUFFER, class OP, class ACC>
00143    inline size_t VariableHullTRBP<GM, BUFFER, OP, ACC>::numberOfBuffers() const {
00144       return inBuffer_.size();
00145    }
00146 
00147    template<class GM, class BUFFER, class OP, class ACC>
00148    inline BUFFER& VariableHullTRBP<GM, BUFFER, OP, ACC>::connectFactorHullTRBP(
00149       const size_t bufferNumber,
00150       BUFFER& variableOutBuffer
00151    ) {
00152       outBuffer_[bufferNumber] =&variableOutBuffer;
00153       return inBuffer_[bufferNumber];
00154    }
00155 
00156    template<class GM, class BUFFER, class OP, class ACC>
00157    void VariableHullTRBP<GM, BUFFER, OP, ACC>::propagate(
00158       const GM& gm,
00159       const size_t id,
00160       const ValueType& damping,
00161       const bool useNormalization
00162    ) {
00163       OPENGM_ASSERT(id < outBuffer_.size());
00164       outBuffer_[id]->toggle();
00165       if(numberOfBuffers() < 2) {
00166          return; // nothing to send
00167       }
00168       // initialize neutral message
00169       BufferArrayType& newMessage = outBuffer_[id]->current();
00170       opengm::messagepassingOperations::operateW<GM>(inBuffer_, id, rho_, newMessage); 
00171 
00172       // damp message 
00173       if(damping != 0) {
00174          BufferArrayType& oldMessage = outBuffer_[id]->old();
00175          if(useNormalization) {
00176             opengm::messagepassingOperations::normalize<OP,ACC>(newMessage); 
00177             opengm::messagepassingOperations::normalize<OP,ACC>(oldMessage);
00178          }
00179          opengm::messagepassingOperations::weightedMean<OP>(newMessage, oldMessage, damping, newMessage);
00180       }
00181       if(useNormalization) {
00182          opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
00183       }
00184    }
00185 
00186 
00187 
00188    template<class GM, class BUFFER, class OP, class ACC>
00189    inline void VariableHullTRBP<GM, BUFFER, OP, ACC>::propagateAll
00190    (
00191       const GM& gm,
00192       const ValueType& damping,
00193       const bool useNormalization
00194    ) {
00195       for(size_t j = 0; j < numberOfBuffers(); ++j) {
00196          propagate(gm, j, damping, useNormalization);
00197       }
00198    }
00199 
00200    template<class GM, class BUFFER, class OP, class ACC>
00201    inline void VariableHullTRBP<GM, BUFFER, OP, ACC>::marginal
00202    (
00203       const GM& gm,
00204       const size_t variableIndex,
00205       IndependentFactorType& out,
00206       const bool useNormalization
00207    ) const {
00208       // set out to neutral
00209       out.assign(gm, &variableIndex, &variableIndex+1, OP::template neutral<ValueType>());
00210       opengm::messagepassingOperations::operateW<GM>(inBuffer_, rho_, out);
00211 
00212       // Normalization::normalize output
00213       if(useNormalization) { 
00214          opengm::messagepassingOperations::normalize<OP,ACC>(out);
00215       }
00216    }
00217 /*
00218    template<class GM, class BUFFER, class OP, class ACC>
00219    inline typename GM::ValueType VariableHullTRBP<GM, BUFFER, OP, ACC>::bound
00220    ()const
00221    {
00222      
00223       typename BUFFER::ArrayType a(inBuffer_[0].current().shapeBegin(),inBuffer_[0].current().shapeEnd());
00224       opengm::messagepassingOperations::operateW<GM>(inBuffer_, rho_, a);
00225       ValueType v;
00226         
00227       if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
00228          v = a(0);
00229          for(size_t n=1; n<a.size(); ++n) {
00230             ACC::op(a(n),v);
00231          }
00232       }
00233       else{
00234          ACC::ineutral(v);
00235       } 
00236 
00237       return v;
00238     
00239       //return  opengm::messagepassingOperations::template boundOperation<ValueType,OP,ACC>(a,a); 
00240    } 
00241 */ 
00242    template<class GM, class BUFFER, class OP, class ACC>
00243    template<class DIST>
00244    inline typename GM::ValueType VariableHullTRBP<GM, BUFFER, OP, ACC>::distance
00245    (
00246       const size_t j
00247    ) const {
00248       return inBuffer_[j].template dist<DIST > ();
00249    }
00250 
00251    template<class GM, class BUFFER, class OP, class ACC>
00252    inline FactorHullTRBP<GM, BUFFER, OP, ACC>::FactorHullTRBP()
00253    {}
00254 
00255    template<class GM, class BUFFER, class OP, class ACC>
00256    inline void FactorHullTRBP<GM, BUFFER, OP, ACC>::assign
00257    (
00258       const GM& gm,
00259       const size_t factorIndex,
00260       std::vector<VariableHullTRBP<GM, BUFFER, OP, ACC> >& variableHulls,
00261       const std::vector<ValueType>* rho
00262    ) {
00263       rho_ = (*rho)[factorIndex];
00264       myFactor_ = (FactorType*) (&gm[factorIndex]);
00265       inBuffer_.resize(gm[factorIndex].numberOfVariables());
00266       outBuffer_.resize(gm[factorIndex].numberOfVariables());
00267 
00268       for(size_t n=0; n<gm.numberOfVariables(factorIndex); ++n) {
00269          size_t var = gm.variableOfFactor(factorIndex,n);
00270          inBuffer_[n].assign(gm.numberOfLabels(var), OP::template neutral<ValueType > ());
00271          size_t bufferNumber = 1000000;
00272          for(size_t i=0; i<gm.numberOfFactors(var); ++i) {
00273             if(gm.factorOfVariable(var,i)==factorIndex)
00274                bufferNumber=i;
00275          }
00276          OPENGM_ASSERT(bufferNumber!=1000000)
00277          outBuffer_[n] =&(variableHulls[var].connectFactorHullTRBP(bufferNumber, inBuffer_[n]));
00278       }
00279    }
00280 
00281    template<class GM, class BUFFER, class OP, class ACC>
00282    void FactorHullTRBP<GM, BUFFER, OP, ACC>::propagate
00283    (
00284       const size_t id,
00285       const ValueType& damping,
00286       const bool useNormalization
00287    ) {
00288       OPENGM_ASSERT(id < outBuffer_.size());
00289       outBuffer_[id]->toggle();
00290       BufferArrayType& newMessage = outBuffer_[id]->current();
00291       opengm::messagepassingOperations::operateWF<GM,ACC>(*myFactor_, rho_, inBuffer_, id, newMessage);
00292 
00293       // damp message
00294       if(damping != 0) { 
00295          BufferArrayType& oldMessage = outBuffer_[id]->old(); 
00296          if(useNormalization) {
00297             opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
00298             opengm::messagepassingOperations::normalize<OP,ACC>(oldMessage);
00299          }
00300          opengm::messagepassingOperations::weightedMean<OP>(newMessage, oldMessage, damping, newMessage);
00301       }
00302       // Normalization::normalize message
00303       if(useNormalization) {
00304          opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
00305       }
00306    }
00307 
00308  
00309    template<class GM, class BUFFER, class OP, class ACC>
00310    inline void FactorHullTRBP<GM, BUFFER, OP, ACC>::propagateAll
00311    (
00312       const ValueType& damping,
00313       const bool useNormalization
00314    ) {
00315       for(size_t j = 0; j < numberOfBuffers(); ++j) {
00316          propagate(j, damping, useNormalization);
00317       }
00318    }
00319 
00320    template<class GM, class BUFFER, class OP, class ACC>
00321    inline void FactorHullTRBP<GM, BUFFER, OP, ACC>::marginal
00322    (
00323       IndependentFactorType& out,
00324       const bool useNormalization
00325    ) const 
00326    {
00327       opengm::messagepassingOperations::operateWF<GM>(*(const_cast<FactorType*> (myFactor_)), rho_, inBuffer_, out);
00328 
00329       if(useNormalization) {
00330          opengm::messagepassingOperations::normalize<OP,ACC>(out);
00331       }
00332    }
00333 /*
00334    template<class GM, class BUFFER, class OP, class ACC>
00335    inline typename GM::ValueType FactorHullTRBP<GM, BUFFER, OP, ACC>::bound
00336    () const
00337    {
00338 
00339       //typename GM::IndependentFactorType a = *myFactor_; 
00340       typename GM::IndependentFactorType a = *myFactor_;
00341       //opengm::messagepassingOperations::operateWF<GM>(*(const_cast<FactorType*> (myFactor_)), rho_, inBuffer_, a);
00342       opengm::messagepassingOperations::operateFiW<GM>(*myFactor_,outBuffer_, rho_, a);
00343 
00344       ValueType v;
00345        
00346       if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
00347          v = a(0);
00348          for(size_t n=1; n<a.size(); ++n) {
00349             ACC::op(a(n),v);
00350          }
00351       }
00352       else{
00353          ACC::ineutral(v);
00354       } 
00355 
00356       return v;
00357 
00358       //return opengm::messagepassingOperations::template boundOperation<ValueType,OP,ACC>(a,b);
00359 
00360    }
00361 */
00362    template<class GM, class BUFFER, class OP, class ACC>
00363    template<class DIST>
00364    inline typename GM::ValueType FactorHullTRBP<GM, BUFFER, OP, ACC>::distance
00365    (
00366       const size_t j
00367    ) const {
00368       return inBuffer_[j].template dist<DIST > ();
00369    }
00370 
00371 } // namespace opengm
00372 
00373 #endif // #ifndef OPENGM_BELIEFPROPAGATION_HXX
00374 
 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