OpenGM  2.3.x
Discrete Graphical Model Library
messagepassing_trbp.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_TREEREWEIGTHEDBELIEFPROPAGATION_HXX
3 #define OPENGM_TREEREWEIGTHEDBELIEFPROPAGATION_HXX
4 
5 #include <vector>
6 #include <map>
7 #include <list>
8 #include <set>
9 
10 #include "opengm/opengm.hxx"
17 
18 namespace opengm {
20  template<class GM, class BUFFER, class OP, class ACC>
21  class VariableHullTRBP {
22  public:
23  typedef GM GraphicalModelType;
24  typedef BUFFER BufferType;
25  typedef typename BUFFER::ArrayType BufferArrayType;
26  typedef typename GM::ValueType ValueType;
27  typedef typename GM::IndependentFactorType IndependentFactorType;
28 
29  VariableHullTRBP();
30  void assign(const GM&, const size_t, const std::vector<ValueType>*);
31  BUFFER& connectFactorHullTRBP(const size_t, BUFFER&);
32  size_t numberOfBuffers() const;
33  void propagateAll(const GM&, const ValueType& = 0, const bool = false);
34  void propagate(const GM&, const size_t, const ValueType& = 0, const bool = false);
35  void marginal(const GM&, const size_t, IndependentFactorType&, const bool = true) const;
36  //typename GM::ValueType bound() const;
37  template<class DIST> ValueType distance(const size_t) const;
38 
39  private:
40  std::vector<BUFFER* > outBuffer_;
41  std::vector<BUFFER > inBuffer_;
42  std::vector<ValueType> rho_;
43  };
44 
45  // Wrapper class for factor nodes
46  template<class GM, class BUFFER, class OP, class ACC>
47  class FactorHullTRBP {
48  public:
49  typedef GM GraphicalModelType;
50  typedef BUFFER BufferType;
51  typedef typename BUFFER::ArrayType BufferArrayType;
52  typedef typename GM::FactorType FactorType;
53  typedef typename GM::IndependentFactorType IndependentFactorType;
54  typedef typename GM::ValueType ValueType;
55 
56  FactorHullTRBP();
57  size_t numberOfBuffers() const { return inBuffer_.size(); }
58  //size_t variableIndex(size_t i) const { return variableIndices_[i]; }
59  void assign(const GM&, const size_t, std::vector<VariableHullTRBP<GM,BUFFER,OP,ACC> >&, const std::vector<ValueType>*);
60  void propagateAll(const ValueType& = 0, const bool = true);
61  void propagate(const size_t, const ValueType& = 0, const bool = true);
62  void marginal(IndependentFactorType&, const bool = true) const;
63  //typename GM::ValueType bound() const;
64  template<class DIST> ValueType distance(const size_t) const;
65 
66  private:
67  FactorType* myFactor_;
68  std::vector<BUFFER* > outBuffer_;
69  std::vector<BUFFER > inBuffer_;
70  ValueType rho_;
71  };
73 
75  template<class GM, class ACC, class BUFFER = opengm::MessageBuffer<marray::Marray<double> > >
77  public:
78  typedef typename GM::ValueType ValueType;
79  typedef typename GM::IndependentFactorType IndependentFactorType;
80  typedef typename GM::FactorType FactorType;
81  typedef typename GM::OperatorType OperatorType;
82  typedef FactorHullTRBP<GM, BUFFER, OperatorType, ACC> FactorHullType;
83  typedef VariableHullTRBP<GM, BUFFER, OperatorType, ACC> VariableHullType;
84  typedef std::vector<ValueType> SpecialParameterType;
85  template<class _GM>
86  struct RebindGm{
88  };
89 
90  template<class _GM,class _ACC>
93  };
94 
95  template<class MP_PARAM>
96  static void initializeSpecialParameter(const GM& gm,MP_PARAM& mpParameter) {
97  // set rho if not set manually
98  if (mpParameter.specialParameter_.size() == 0) {
99  // set rho by tree decomposition
100  opengm::GraphicalModelDecomposer<GM> decomposer;
101  const opengm::GraphicalModelDecomposition decomposition = decomposer.decomposeIntoSpanningTrees(gm);
102  OPENGM_ASSERT(decomposition.isValid(gm));
103  typedef typename GraphicalModelDecomposition::SubFactorListType SubFactorListType;
104  const std::vector<SubFactorListType>& subFactorList = decomposition.getFactorLists();
105  mpParameter.specialParameter_.resize(gm.numberOfFactors());
106  for (size_t factorId = 0; factorId < gm.numberOfFactors(); ++factorId) {
107  mpParameter.specialParameter_[factorId] = 1.0 / subFactorList[factorId].size();
108  }
109  }
110  else if (mpParameter.specialParameter_.size() != gm.numberOfFactors()) {
111  throw RuntimeError("The parameter rho has been set incorrectly.");
112  }
113  if(!NO_DEBUG) {
114  // test rho
115  OPENGM_ASSERT(mpParameter.specialParameter_.size() == gm.numberOfFactors());
116  for (size_t i = 0; i < gm.numberOfFactors(); ++i) {
117  if(gm.numberOfVariables() < 2) {
118  OPENGM_ASSERT(mpParameter.specialParameter_[i] == 1); // ??? allow for numerical deviation
119  }
120  OPENGM_ASSERT(mpParameter.specialParameter_[i] > 0);
121  }
122  }
123  }
124  };
125 
126  template<class GM, class BUFFER, class OP, class ACC>
127  inline VariableHullTRBP<GM, BUFFER, OP, ACC>::VariableHullTRBP()
128  {}
129 
130  template<class GM, class BUFFER, class OP, class ACC>
131  inline void VariableHullTRBP<GM, BUFFER, OP, ACC>::assign
132  (
133  const GM& gm,
134  const size_t variableIndex,
135  const std::vector<ValueType>* rho
136  ) {
137  size_t numberOfFactors = gm.numberOfFactors(variableIndex);
138  rho_.resize(numberOfFactors);
139  for(size_t j = 0; j < numberOfFactors; ++j) {
140  rho_[j] = (*rho)[gm.factorOfVariable(variableIndex,j)];
141  }
142  inBuffer_.resize(numberOfFactors);
143  outBuffer_.resize(numberOfFactors);
144  // allocate input-buffer
145  for(size_t j = 0; j < numberOfFactors; ++j) {
146  inBuffer_[j].assign(gm.numberOfLabels(variableIndex), OP::template neutral<ValueType > ());
147  }
148  }
149 
150 
151  template<class GM, class BUFFER, class OP, class ACC>
152  inline size_t VariableHullTRBP<GM, BUFFER, OP, ACC>::numberOfBuffers() const {
153  return inBuffer_.size();
154  }
155 
156  template<class GM, class BUFFER, class OP, class ACC>
157  inline BUFFER& VariableHullTRBP<GM, BUFFER, OP, ACC>::connectFactorHullTRBP(
158  const size_t bufferNumber,
159  BUFFER& variableOutBuffer
160  ) {
161  outBuffer_[bufferNumber] =&variableOutBuffer;
162  return inBuffer_[bufferNumber];
163  }
164 
165  template<class GM, class BUFFER, class OP, class ACC>
166  void VariableHullTRBP<GM, BUFFER, OP, ACC>::propagate(
167  const GM& gm,
168  const size_t id,
169  const ValueType& damping,
170  const bool useNormalization
171  ) {
172  OPENGM_ASSERT(id < outBuffer_.size());
173  outBuffer_[id]->toggle();
174  if(numberOfBuffers() < 2) {
175  return; // nothing to send
176  }
177  // initialize neutral message
178  BufferArrayType& newMessage = outBuffer_[id]->current();
179  opengm::messagepassingOperations::operateW<GM>(inBuffer_, id, rho_, newMessage);
180 
181  // damp message
182  if(damping != 0) {
183  BufferArrayType& oldMessage = outBuffer_[id]->old();
184  if(useNormalization) {
185  opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
186  opengm::messagepassingOperations::normalize<OP,ACC>(oldMessage);
187  }
188  opengm::messagepassingOperations::weightedMean<OP>(newMessage, oldMessage, damping, newMessage);
189  }
190  if(useNormalization) {
191  opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
192  }
193  }
194 
195 
196 
197  template<class GM, class BUFFER, class OP, class ACC>
198  inline void VariableHullTRBP<GM, BUFFER, OP, ACC>::propagateAll
199  (
200  const GM& gm,
201  const ValueType& damping,
202  const bool useNormalization
203  ) {
204  for(size_t j = 0; j < numberOfBuffers(); ++j) {
205  propagate(gm, j, damping, useNormalization);
206  }
207  }
208 
209  template<class GM, class BUFFER, class OP, class ACC>
210  inline void VariableHullTRBP<GM, BUFFER, OP, ACC>::marginal
211  (
212  const GM& gm,
213  const size_t variableIndex,
215  const bool useNormalization
216  ) const {
217  // set out to neutral
218  out.assign(gm, &variableIndex, &variableIndex+1, OP::template neutral<ValueType>());
219  opengm::messagepassingOperations::operateW<GM>(inBuffer_, rho_, out);
220 
221  // Normalization::normalize output
222  if(useNormalization) {
223  opengm::messagepassingOperations::normalize<OP,ACC>(out);
224  }
225  }
226 /*
227  template<class GM, class BUFFER, class OP, class ACC>
228  inline typename GM::ValueType VariableHullTRBP<GM, BUFFER, OP, ACC>::bound
229  ()const
230  {
231 
232  typename BUFFER::ArrayType a(inBuffer_[0].current().shapeBegin(),inBuffer_[0].current().shapeEnd());
233  opengm::messagepassingOperations::operateW<GM>(inBuffer_, rho_, a);
234  ValueType v;
235 
236  if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
237  v = a(0);
238  for(size_t n=1; n<a.size(); ++n) {
239  ACC::op(a(n),v);
240  }
241  }
242  else{
243  ACC::ineutral(v);
244  }
245 
246  return v;
247 
248  //return opengm::messagepassingOperations::template boundOperation<ValueType,OP,ACC>(a,a);
249  }
250 */
251  template<class GM, class BUFFER, class OP, class ACC>
252  template<class DIST>
253  inline typename GM::ValueType VariableHullTRBP<GM, BUFFER, OP, ACC>::distance
254  (
255  const size_t j
256  ) const {
257  return inBuffer_[j].template dist<DIST > ();
258  }
259 
260  template<class GM, class BUFFER, class OP, class ACC>
261  inline FactorHullTRBP<GM, BUFFER, OP, ACC>::FactorHullTRBP()
262  {}
263 
264  template<class GM, class BUFFER, class OP, class ACC>
265  inline void FactorHullTRBP<GM, BUFFER, OP, ACC>::assign
266  (
267  const GM& gm,
268  const size_t factorIndex,
269  std::vector<VariableHullTRBP<GM, BUFFER, OP, ACC> >& variableHulls,
270  const std::vector<ValueType>* rho
271  ) {
272  rho_ = (*rho)[factorIndex];
273  myFactor_ = (FactorType*) (&gm[factorIndex]);
274  inBuffer_.resize(gm[factorIndex].numberOfVariables());
275  outBuffer_.resize(gm[factorIndex].numberOfVariables());
276 
277  for(size_t n=0; n<gm.numberOfVariables(factorIndex); ++n) {
278  size_t var = gm.variableOfFactor(factorIndex,n);
279  inBuffer_[n].assign(gm.numberOfLabels(var), OP::template neutral<ValueType > ());
280  size_t bufferNumber = 1000000;
281  for(size_t i=0; i<gm.numberOfFactors(var); ++i) {
282  if(gm.factorOfVariable(var,i)==factorIndex)
283  bufferNumber=i;
284  }
285  OPENGM_ASSERT(bufferNumber!=1000000)
286  outBuffer_[n] =&(variableHulls[var].connectFactorHullTRBP(bufferNumber, inBuffer_[n]));
287  }
288  }
289 
290  template<class GM, class BUFFER, class OP, class ACC>
291  void FactorHullTRBP<GM, BUFFER, OP, ACC>::propagate
292  (
293  const size_t id,
294  const ValueType& damping,
295  const bool useNormalization
296  ) {
297  OPENGM_ASSERT(id < outBuffer_.size());
298  outBuffer_[id]->toggle();
299  BufferArrayType& newMessage = outBuffer_[id]->current();
300  opengm::messagepassingOperations::operateWF<GM,ACC>(*myFactor_, rho_, inBuffer_, id, newMessage);
301 
302  // damp message
303  if(damping != 0) {
304  BufferArrayType& oldMessage = outBuffer_[id]->old();
305  if(useNormalization) {
306  opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
307  opengm::messagepassingOperations::normalize<OP,ACC>(oldMessage);
308  }
309  opengm::messagepassingOperations::weightedMean<OP>(newMessage, oldMessage, damping, newMessage);
310  }
311  // Normalization::normalize message
312  if(useNormalization) {
313  opengm::messagepassingOperations::normalize<OP,ACC>(newMessage);
314  }
315  }
316 
317 
318  template<class GM, class BUFFER, class OP, class ACC>
319  inline void FactorHullTRBP<GM, BUFFER, OP, ACC>::propagateAll
320  (
321  const ValueType& damping,
322  const bool useNormalization
323  ) {
324  for(size_t j = 0; j < numberOfBuffers(); ++j) {
325  propagate(j, damping, useNormalization);
326  }
327  }
328 
329  template<class GM, class BUFFER, class OP, class ACC>
330  inline void FactorHullTRBP<GM, BUFFER, OP, ACC>::marginal
331  (
333  const bool useNormalization
334  ) const
335  {
336  opengm::messagepassingOperations::operateWF<GM>(*(const_cast<FactorType*> (myFactor_)), rho_, inBuffer_, out);
337 
338  if(useNormalization) {
339  opengm::messagepassingOperations::normalize<OP,ACC>(out);
340  }
341  }
342 /*
343  template<class GM, class BUFFER, class OP, class ACC>
344  inline typename GM::ValueType FactorHullTRBP<GM, BUFFER, OP, ACC>::bound
345  () const
346  {
347 
348  //typename GM::IndependentFactorType a = *myFactor_;
349  typename GM::IndependentFactorType a = *myFactor_;
350  //opengm::messagepassingOperations::operateWF<GM>(*(const_cast<FactorType*> (myFactor_)), rho_, inBuffer_, a);
351  opengm::messagepassingOperations::operateFiW<GM>(*myFactor_,outBuffer_, rho_, a);
352 
353  ValueType v;
354 
355  if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
356  v = a(0);
357  for(size_t n=1; n<a.size(); ++n) {
358  ACC::op(a(n),v);
359  }
360  }
361  else{
362  ACC::ineutral(v);
363  }
364 
365  return v;
366 
367  //return opengm::messagepassingOperations::template boundOperation<ValueType,OP,ACC>(a,b);
368 
369  }
370 */
371  template<class GM, class BUFFER, class OP, class ACC>
372  template<class DIST>
373  inline typename GM::ValueType FactorHullTRBP<GM, BUFFER, OP, ACC>::distance
374  (
375  const size_t j
376  ) const {
377  return inBuffer_[j].template dist<DIST > ();
378  }
379 
380 } // namespace opengm
381 
382 #endif // #ifndef OPENGM_BELIEFPROPAGATION_HXX
383 
Update rules for the MessagePassing framework.
The OpenGM namespace.
Definition: config.hxx:43
TrbpUpdateRules< _GM, ACC, BUFFER > type
std::vector< ValueType > SpecialParameterType
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
VariableHullTRBP< GM, BUFFER, OperatorType, ACC > VariableHullType
const bool NO_DEBUG
Definition: config.hxx:64
TrbpUpdateRules< _GM, _ACC, BUFFER > type
GM::IndependentFactorType IndependentFactorType
FactorHullTRBP< GM, BUFFER, OperatorType, ACC > FactorHullType
static void initializeSpecialParameter(const GM &gm, MP_PARAM &mpParameter)
OpenGM runtime error.
Definition: opengm.hxx:100