OpenGM  2.3.x
Discrete Graphical Model Library
messagepassing_operations.hxx
Go to the documentation of this file.
2 
3 
4 // The following implementation is obsolote since the functor concept (included above is much faster.
5 // We keep this code for compareision, but will remove is without further anouncemant.
6 
7 
8 #pragma once
9 #ifndef OPENGM_MESSAGEPASSING_OPERATIONS_HXX
10 #define OPENGM_MESSAGEPASSING_OPERATIONS_HXX
11 
12 #include <opengm/opengm.hxx>
17 
19 
20 namespace opengm {
21 namespace messagepassingOperations {
22 
23 // out = M(M.shape, OP:neutral)
25 template<class OP, class M>
26 inline void clean(M& out) {
27  for(size_t n=0; n<out.size(); ++n ) {
28  OP::neutral(out(n));
29  }
30 /*
31  const size_t loopSize= out.size()/2;
32  for(size_t n=0; n<loopSize;n+=2 ) {
33  OP::neutral(out(n));
34  OP::neutral(out(n+1));
35  }
36  const size_t loopSize2= loopSize*2;
37  if(loopSize2!=out.size()) {
38  OP::neutral(out(loopSize2));
39  }
40 */
41 }
42 
43 template<class OP, class ACC, class M>
44 inline void normalize
45 (
46  M& out
47 ) {
48  typename M::ValueType v;
49  ACC::neutral(v);
50  for(size_t n=0; n<out.size(); ++n)
51  ACC::op(out(n),v);
52 
53  if( opengm::meta::Compare<OP,opengm::Multiplier>::value && v <= 0.00001)
54  return;
55  if(opengm::meta::Compare<OP,opengm::Multiplier>::value)
56  OPENGM_ASSERT(v > 0.00001); // ??? this should be checked in released code
57  for(size_t n=0; n<out.size();++n ) {
58  OP::iop(v,out(n));
59  }
60 /*
61  const size_t loopSize= out.size()/2;
62  for(size_t n=0; n<loopSize;n+=2 ) {
63  OP::iop(v,out(n));
64  OP::iop(v,out(n+1));
65  }
66  const size_t loopSize2= loopSize*2;
67  if(loopSize2!=out.size()) {
68  OP::iop(v,out(loopSize2));
69  }
70 */
71 }
72 
74 template<class OP, class M, class T>
75 inline void weightedMean
76 (
77  const M& in1,
78  const M& in2,
79  const T alpha,
80  M& out
81 ) {
84  T v1,v2;
85  const T oneMinusAlpha=static_cast<T>(1)-alpha;
86 
87  for(size_t n=0; n<out.size();++n ) {
88  OP::hop(in1(n),alpha, v1);
89  OP::hop(in2(n),oneMinusAlpha,v2);
90  OP::op(v1,v2,out(n));
91  }
92  /*
93  const size_t loopSize= out.size()/2;
94  for(size_t n=0; n<loopSize;n+=2 ) {
95  OP::hop(in1(n),alpha, v1);
96  OP::hop(in2(n),oneMinusAlpha,v2);
97  OP::op(v1,v2,out(n));
98 
99  OP::hop(in1(n+1),alpha, v1);
100  OP::hop(in2(n+1),oneMinusAlpha,v2);
101  OP::op(v1,v2,out(n+1));
102  }
103  const size_t loopSize2= loopSize*2;
104  if(loopSize2!=out.size()) {
105  OP::hop(in1(loopSize2),alpha, v1);
106  OP::hop(in2(loopSize2),oneMinusAlpha,v2);
107  OP::op(v1,v2,out(loopSize2));
108  }
109  */
110 }
111 
113 template<class OP, class BUFFER, class M>
114 inline void operate
115 (
116  const std::vector<BUFFER>& vec,
117  M& out
118 ) {
121  clean<OP>(out);
122  for(size_t j = 0; j < vec.size(); ++j) {
123  const typename BUFFER::ArrayType& b = vec[j].current();
124  OPENGM_ASSERT(b.size()==out.size());
125  for(size_t n=0; n<out.size(); ++n)
126  OP::op(b(n), out(n));
127  }
128 }
129 
131 template<class GM, class BUFFER, class M>
132 inline void operateW
133 (
134  const std::vector<BUFFER>& vec,
135  const std::vector<typename GM::ValueType>& rho,
136  M& out
137 ) {
138  typedef typename GM::OperatorType OP;
139  clean<OP>(out);
143  for(size_t j = 0; j < vec.size(); ++j) {
144  const typename BUFFER::ArrayType& b = vec[j].current();
145  typename GM::ValueType e = rho[j];
146  typename GM::ValueType v;
147  for(size_t n=0; n<out.size(); ++n) {
148  OP::hop(b(n),e,v);
149  OP::op(v,out(n));
150  }
151  }
152 }
153 
155 template<class OP, class BUFVEC, class M, class INDEX>
156 inline void operate
157 (
158  const BUFVEC& vec,
159  const INDEX i,
160  M& out
161 ) {
162  clean<OP>(out);
166  for(size_t j = 0; j < i; ++j) {
167  const M& f = vec[j].current();
168  for(size_t n=0; n<out.size(); ++n)
169  OP::op(f(n), out(n));
170  }
171  for(size_t j = i+1; j < vec.size(); ++j) {
172  const M& f = vec[j].current();
173  for(size_t n=0; n<out.size(); ++n)
174  OP::op(f(n), out(n));
175  }
176 }
177 
179 template<class GM, class BUFVEC, class M, class INDEX>
180 inline void operateW
181 (
182  const BUFVEC& vec,
183  const INDEX i,
184  const std::vector<typename GM::ValueType>& rho,
185  M& out
186 ) {
187  typedef typename GM::OperatorType OP;
188  OPENGM_ASSERT(vec[i].current().size()==out.size());
189  typename GM::ValueType v;
190  const typename GM::ValueType e = rho[i]-1;
191  const M& b = vec[i].current();
192  for(size_t n=0; n<out.size(); ++n) {
193  //OP::hop(b(n),e,v);
194  //OP::op(v,out(n));
195  OP::hop(b(n),e,out(n));
196  }
197 
198  for(size_t j = 0; j < i; ++j) {
199  const M& b = vec[j].current();
200  const typename GM::ValueType e = rho[j];
201  OPENGM_ASSERT(b.size()==out.size());
202  for(size_t n=0; n<out.size(); ++n) {
203  OP::hop(b(n),e,v);
204  OP::op(v,out(n));
205  }
206  }
207  for(size_t j = i+1; j < vec.size(); ++j) {
208  const M& b = vec[j].current();
209  const typename GM::ValueType e = rho[j];
210  OPENGM_ASSERT(b.size()==out.size());
211  for(size_t n=0; n<out.size(); ++n) {
212  OP::hop(b(n),e,v);
213  OP::op(v,out(n));
214  }
215  }
216 }
217 
218 
220 template<class GM, class ACC, class BUFVEC, class ARRAY, class INDEX>
221 inline void operateF
222 (
223  const typename GM::FactorType& f,
224  const BUFVEC& vec,
225  const INDEX i,
226  ARRAY& out
227 ) { //TODO: Speedup, Inplace
228  typedef typename GM::OperatorType OP;
229  if(f.numberOfVariables()==2) {
230  size_t count[2];
231  typename GM::ValueType v;
232  for(size_t n=0; n<out.size(); ++n)
233  ACC::neutral(out(n));
234  for(count[0]=0;count[0]<f.numberOfLabels(0);++count[0]) {
235  for(count[1]=0;count[1]<f.numberOfLabels(1);++count[1]) {
236  v = f(count);
237  if(i==0)
238  OP::op(vec[1].current()(count[1]), v);
239  else
240  OP::op(vec[0].current()(count[0]), v);
241  ACC::op(v,out(count[i]));
242  }
243  }
244  }
245  else{
246  // accumulation over all variables except x
247  typedef typename GM::IndexType IndexType;
248  typedef typename GM::LabelType LabelType;
249  // neutral initialization of output
250  for(size_t n=0; n<f.numberOfLabels(i); ++n)
251  ACC::neutral(out(n));
252  // factor shape iterator
253  typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
254  opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
255  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
256  // loop over the variables
257  // initialize output value with value of the factor at this coordinate
258  // operate j=[0,..i-1]
259  typename GM::ValueType value=f(shapeWalker.coordinateTuple().begin());
260  for(IndexType j=0;j<static_cast<typename GM::IndexType>(i);++j) {
261  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
262  OP::op(vec[j].current()(label),value);
263  }
264  // operate j=[i+1,..,vec.size()]
265  for(IndexType j=i+1;j< vec.size();++j) {
266  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
267  OP::op(vec[j].current()(label),value);
268  }
269  // accumulate
270  ACC::op(value,out(shapeWalker.coordinateTuple()[i]));
271  }
272  }
273 }
274 
276 template<class GM, class ACC, class BUFVEC, class M, class INDEX>
277 inline void operateWF
278 (
279  const typename GM::FactorType& f,
280  const typename GM::ValueType rho,
281  const BUFVEC& vec,
282  const INDEX i,
283  M& out
284 ) {//TODO: Speedup, Inplace
285  typedef typename GM::IndexType IndexType;
286  typedef typename GM::LabelType LabelType;
287  typedef typename GM::OperatorType OP;
288  // neutral initialization of output
289  for(size_t n=0; n<f.numberOfLabels(i); ++n)
290  ACC::neutral(out(n));
291  // factor shape iterator
292  typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
293  opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
294  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
295  // loop over the variables
296  // initialize output value with value of the factor at this coordinate
297  // operate j=[0,..i-1]
298  typename GM::ValueType value;
299  OP::ihop(f(shapeWalker.coordinateTuple().begin()),rho,value);
300  for(IndexType j=0;j<static_cast<typename GM::IndexType>(i);++j) {
301  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
302  OP::op(vec[j].current()(label),value);
303  }
304  // operate j=[i+1,..,vec.size()]
305  for(IndexType j=i+1;j< vec.size();++j) {
306  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
307  OP::op(vec[j].current()(label),value);
308  }
309  // accumulate
310  ACC::op(value,out(shapeWalker.coordinateTuple()[i]));
311  }
312 
313  //typedef typename GM::OperatorType OP;
314  //typename GM::IndependentFactorType temp = f;
315  //OP::ihop(f, rho, temp);
316  //std::vector<size_t> accVar;
317  //accVar.reserve(vec.size());
318  //for(size_t j = 0; j < i; ++j) {
319  // size_t var = f.variableIndex(j);
320  // typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
321  // for(size_t n=0; n<dummy.size();++n)
322  // dummy(n) = vec[j].current()(n);
323  // OP::op(dummy, temp);
324  // accVar.push_back(f.variableIndex(j));
325  //}
326  //for(size_t j = i+1; j < vec.size(); ++j) {
327  // size_t var = f.variableIndex(j);
328  // typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
329  // for(size_t n=0; n<dummy.size();++n)
330  // dummy(n) = vec[j].current()(n);
331  // OP::op(dummy, temp);
332  // accVar.push_back(f.variableIndex(j));
333  //}
334  //temp.template accumulate<ACC> (accVar.begin(), accVar.end());
335  //for(size_t n=0; n<temp.size(); ++n) {
336  // out(n) = temp(n);
337  //}
338 }
339 
341 template<class GM, class BUFVEC>
342 inline void operateF
343 (
344  const typename GM::FactorType& f,
345  const BUFVEC& vec,
346  typename GM::IndependentFactorType& out
347 )
348 {
349  OPENGM_ASSERT(out.numberOfVariables()!=0);
350  //TODO: Speedup
351  typedef typename GM::IndexType IndexType;
352  typedef typename GM::LabelType LabelType;
353  typedef typename GM::OperatorType OP;
354  // factor shape iterator
355  typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
356  opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
357  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
358  // loop over the variables
359  typename GM::ValueType value=f(shapeWalker.coordinateTuple().begin());
360  for(IndexType j=0;j<static_cast<typename GM::IndexType>(vec.size());++j) {
361  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
362  OP::op(vec[j].current()(label),value);
363  }
364  out(scalarIndex)=value;
365  }
366  //typedef typename GM::OperatorType OP;
367  //out = f;
368  // accumulation over all variables except x
369  //for(size_t j = 0; j < vec.size(); ++j) {
370  // size_t var = f.variableIndex(j);
371  // typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
372  // for(size_t n=0; n<dummy.size();++n)
373  // dummy(n) = vec[j].current()(n);
374  // //OPENGM_ASSERT(f.variableIndex(j)==vec[j].current().variableIndex(0));
375  // OP::op(dummy, out);
376  //}
377 }
378 
379 
381 template<class GM, class BUFVEC>
382 inline void operateWF
383 (
384  const typename GM::FactorType& f,
385  const typename GM::ValueType rho,
386  const BUFVEC& vec,
387  typename GM::IndependentFactorType& out
388 ) {//TODO: Speedup
389  typedef typename GM::OperatorType OP;
390  typedef typename GM::IndexType IndexType;
391  typedef typename GM::LabelType LabelType;
392  typedef typename GM::FactorType::ShapeIteratorType FactorShapeIteratorType;
393  opengm::ShapeWalker<FactorShapeIteratorType> shapeWalker(f.shapeBegin(),f.numberOfVariables());
394  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
395  // loop over the variables
396  typename GM::ValueType value;
397  OP::ihop(f(shapeWalker.coordinateTuple().begin()),rho,value);
398  for(IndexType j=0;j<static_cast<typename GM::IndexType>(vec.size());++j) {
399  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
400  OP::op(vec[j].current()(label),value);
401  }
402  out(scalarIndex)=value;
403  }
404 
405  //OP::ihop(f, rho, out);
406  //for(size_t j = 0; j < vec.size(); ++j) {
407  // size_t var = f.variableIndex(j);
408  // typename GM::IndependentFactorType dummy(&var, &var+1,vec[j].current().shapeBegin(),vec[j].current().shapeEnd());
409  // for(size_t n=0; n<dummy.size();++n)
410  // dummy(n) = vec[j].current()(n);
411  // //OPENGM_ASSERT(f.variableIndex(j)==vec[j].current().variableIndex(0));
412  // OP::op(dummy, out);
413  //}
414 }
415 /*
416 
417 template<class GM, class BUFVEC>
418 void operateFi(
419  const typename GM::FactorType& myFactor,
420  const BUFVEC& vec,
421  typename GM::IndependentFactorType& b
422  )
423 {//SPEED ME UP
424  typedef typename GM::OperatorType OP;
425  b=myFactor;
426  for(size_t j=0; j<vec.size();++j) {
427  size_t var = myFactor.variableIndex(j);
428  typename GM::IndependentFactorType dummy(&var, &var+1,vec[j]->current().shapeBegin(),vec[j]->current().shapeEnd());
429  for(size_t n=0; n<dummy.size();++n)
430  dummy(n) = vec[j]->current()(n);
431  OP::iop(dummy,b);
432  }
433 }
434 
435 template<class GM, class BUFVEC>
436 void operateFiW(
437  const typename GM::FactorType& myFactor,
438  const BUFVEC& vec,
439  const typename GM::ValueType rho,
440  typename GM::IndependentFactorType& b
441  )
442 {//SPEED ME UP
443  typedef typename GM::OperatorType OP;
444  b=myFactor;
445  for(size_t j=0; j<vec.size();++j) {
446  size_t var = myFactor.variableIndex(j);
447  typename GM::IndependentFactorType dummy(&var, &var+1,vec[j]->current().shapeBegin(),vec[j]->current().shapeEnd());
448  for(size_t n=0; n<dummy.size();++n)
449  OP::hop(vec[j]->current()(n),rho,dummy(n));
450  OP::iop(dummy,b);
451  }
452 }
453 
454 template<class A, class B, class T, class OP, class ACC>
455 T boundOperation(const A& a, const B& b)
456 {
457  T v;
458 
459  if(typeid(ACC)==typeid(opengm::Adder) && typeid(OP)==typeid(opengm::Multiplier)) {
460  T t;
461  OP::hop(a(0),b(0),v);
462  for(size_t n=1; n<a.size(); ++n) {
463  OP::hop(a(n),b(n),t);
464  OP::op(t,v);
465  }
466  }
467  else if(typeid(ACC)==typeid(opengm::Minimizer) || typeid(ACC)==typeid(opengm::Maximizer)) {
468  v = b(0);
469  for(size_t n=1; n<a.size(); ++n) {
470  ACC::bop( a(n),v );
471  }
472  }
473  else{
474  ACC::neutral(v);
475  }
476  return v;
477 }
478 */
479 
480 } // namespace messagepassingOperations
481 } // namespace opengm
482 
484 
485 #endif
The OpenGM namespace.
Definition: config.hxx:43
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77