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
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
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
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
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
00089 if (mpParameter.specialParameter_.size() == 0) {
00090
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
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);
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
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;
00167 }
00168
00169 BufferArrayType& newMessage = outBuffer_[id]->current();
00170 opengm::messagepassingOperations::operateW<GM>(inBuffer_, id, rho_, newMessage);
00171
00172
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
00209 out.assign(gm, &variableIndex, &variableIndex+1, OP::template neutral<ValueType>());
00210 opengm::messagepassingOperations::operateW<GM>(inBuffer_, rho_, out);
00211
00212
00213 if(useNormalization) {
00214 opengm::messagepassingOperations::normalize<OP,ACC>(out);
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
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
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
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
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
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 }
00372
00373 #endif // #ifndef OPENGM_BELIEFPROPAGATION_HXX
00374