OpenGM  2.3.x
Discrete Graphical Model Library
messagepassing_operations_withFunctors.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_MESSAGEPASSING_OPERATIONS_HXX
3 #define OPENGM_MESSAGEPASSING_OPERATIONS_HXX
4 
5 #include <opengm/opengm.hxx>
10 
12 
13 namespace opengm {
14  namespace messagepassingOperations {
15 
16 // out = M(M.shape, OP:neutral)
18  template<class OP, class M>
19  inline void clean(M& out) {
20  for(size_t n=0; n<out.size(); ++n ) {
21  OP::neutral(out(n));
22  }
23  }
24 
25  template<class OP, class ACC, class M>
26  inline void normalize
27  (
28  M& out
29  ) {
30  typename M::ValueType v;
31  ACC::neutral(v);
32  for(size_t n=0; n<out.size(); ++n)
33  ACC::op(out(n),v);
34 
35  if( opengm::meta::Compare<OP,opengm::Multiplier>::value && v <= 0.00001)
36  return;
37  if(opengm::meta::Compare<OP,opengm::Multiplier>::value)
38  OPENGM_ASSERT(v > 0.00001); // ??? this should be checked in released code
39  for(size_t n=0; n<out.size();++n ) {
40  OP::iop(v,out(n));
41  }
42  }
43 
45  template<class OP, class M, class T>
46  inline void weightedMean
47  (
48  const M& in1,
49  const M& in2,
50  const T alpha,
51  M& out
52  ) {
55  T v1,v2;
56  const T oneMinusAlpha=static_cast<T>(1)-alpha;
57 
58  for(size_t n=0; n<out.size();++n ) {
59  OP::hop(in1(n),alpha, v1);
60  OP::hop(in2(n),oneMinusAlpha,v2);
61  OP::op(v1,v2,out(n));
62  }
63  }
64 
66  template<class OP, class BUFFER, class M>
67  inline void operate
68  (
69  const std::vector<BUFFER>& vec,
70  M& out
71  ) {
74  clean<OP>(out);
75  for(size_t j = 0; j < vec.size(); ++j) {
76  const typename BUFFER::ArrayType& b = vec[j].current();
77  OPENGM_ASSERT(b.size()==out.size());
78  for(size_t n=0; n<out.size(); ++n)
79  OP::op(b(n), out(n));
80  }
81  }
82 
84  template<class GM, class BUFFER, class M>
85  inline void operateW
86  (
87  const std::vector<BUFFER>& vec,
88  const std::vector<typename GM::ValueType>& rho,
89  M& out
90  ) {
91  typedef typename GM::OperatorType OP;
92  clean<OP>(out);
96  for(size_t j = 0; j < vec.size(); ++j) {
97  const typename BUFFER::ArrayType& b = vec[j].current();
98  typename GM::ValueType e = rho[j];
99  typename GM::ValueType v;
100  for(size_t n=0; n<out.size(); ++n) {
101  OP::hop(b(n),e,v);
102  OP::op(v,out(n));
103  }
104  }
105  }
106 
108  template<class OP, class BUFVEC, class M, class INDEX>
109  inline void operate
110  (
111  const BUFVEC& vec,
112  const INDEX i,
113  M& out
114  ) {
115  clean<OP>(out);
119  for(size_t j = 0; j < i; ++j) {
120  const M& f = vec[j].current();
121  for(size_t n=0; n<out.size(); ++n)
122  OP::op(f(n), out(n));
123  }
124  for(size_t j = i+1; j < vec.size(); ++j) {
125  const M& f = vec[j].current();
126  for(size_t n=0; n<out.size(); ++n)
127  OP::op(f(n), out(n));
128  }
129  }
130 
132  template<class GM, class BUFVEC, class M, class INDEX>
133  inline void operateW
134  (
135  const BUFVEC& vec,
136  const INDEX i,
137  const std::vector<typename GM::ValueType>& rho,
138  M& out
139  ) {
140  typedef typename GM::OperatorType OP;
141  OPENGM_ASSERT(vec[i].current().size()==out.size());
142  typename GM::ValueType v;
143  const typename GM::ValueType e = rho[i]-1;
144  const M& b = vec[i].current();
145  for(size_t n=0; n<out.size(); ++n) {
146  //OP::hop(b(n),e,v);
147  //OP::op(v,out(n));
148  OP::hop(b(n),e,out(n));
149  }
150 
151  for(size_t j = 0; j < i; ++j) {
152  const M& b = vec[j].current();
153  const typename GM::ValueType e = rho[j];
154  OPENGM_ASSERT(b.size()==out.size());
155  for(size_t n=0; n<out.size(); ++n) {
156  OP::hop(b(n),e,v);
157  OP::op(v,out(n));
158  }
159  }
160  for(size_t j = i+1; j < vec.size(); ++j) {
161  const M& b = vec[j].current();
162  const typename GM::ValueType e = rho[j];
163  OPENGM_ASSERT(b.size()==out.size());
164  for(size_t n=0; n<out.size(); ++n) {
165  OP::hop(b(n),e,v);
166  OP::op(v,out(n));
167  }
168  }
169  }
170 
172 
173  template<class GM, class ACC, class BUFVEC, class ARRAY ,class INDEX>
174  struct OperateF_Functor{
175  OperateF_Functor(
176  const BUFVEC & vec,
177  const INDEX i,
178  ARRAY & out
179  )
180  : vec_(vec),
181  i_(i),
182  out_(out){
183  }
184 
185  template<class FUNCTION>
186  void operator()(const FUNCTION & f){
187  typedef typename GM::OperatorType OP;
188  if(f.dimension()==2) {
189  size_t count[2];
190  typename GM::ValueType v;
191  for(size_t n=0; n<out_.size(); ++n)
192  ACC::neutral(out_(n));
193  if(i_==0){
194  for(count[0]=0;count[0]<f.shape(0);++count[0]){
195  for(count[1]=0;count[1]<f.shape(1);++count[1]) {
196  v = f(count);
197  OP::op(vec_[1].current()(count[1]), v);
198  ACC::op(v,out_(count[0]));
199  }
200  }
201  }else{
202  for(count[0]=0;count[0]<f.shape(0);++count[0]){
203  for(count[1]=0;count[1]<f.shape(1);++count[1]) {
204  v = f(count);
205  OP::op(vec_[0].current()(count[0]), v);
206  ACC::op(v,out_(count[1]));
207  }
208  }
209  }
210  }
211  else{
212  // accumulation over all variables except x
213  typedef typename GM::IndexType IndexType;
214  typedef typename GM::LabelType LabelType;
215  // neutral initialization of output
216  for(size_t n=0; n<f.shape(i_); ++n)
217  ACC::neutral(out_(n));
218  // factor shape iterator
219  typedef typename FUNCTION::FunctionShapeIteratorType FunctionShapeIteratorType;
220  opengm::ShapeWalker<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(),f.dimension());
221  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
222  // loop over the variables
223  // initialize output value with value of the factor at this coordinate
224  // operate j=[0,..i-1]
225  typename GM::ValueType value=f(shapeWalker.coordinateTuple().begin());
226  for(IndexType j=0;j<static_cast<typename GM::IndexType>(i_);++j) {
227  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
228  OP::op(vec_[j].current()(label),value);
229  }
230  // operate j=[i+1,..,vec.size()]
231  for(IndexType j=i_+1;j< vec_.size();++j) {
232  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
233  OP::op(vec_[j].current()(label),value);
234  }
235  // accumulate
236  ACC::op(value,out_(shapeWalker.coordinateTuple()[i_]));
237  }
238  }
239  }
240 
241 
242  const BUFVEC & vec_;
243  const INDEX i_;
244  ARRAY & out_;
245  };
246 
247  template<class GM, class ACC, class BUFVEC, class ARRAY, class INDEX>
248  inline void operateF
249  (
250  const typename GM::FactorType& f,
251  const BUFVEC& vec,
252  const INDEX i,
253  ARRAY& out
254  ) {
255  OperateF_Functor<GM,ACC,BUFVEC,ARRAY,INDEX> functor(vec,i,out);
256  f.callFunctor(functor);
257  }
258 
259 
261  template<class GM, class ACC, class BUFVEC, class M ,class INDEX>
262  struct OperateWF_Functor{
263  typedef typename GM::IndexType IndexType;
264  typedef typename GM::LabelType LabelType;
265  typedef typename GM::ValueType ValueType;
266  typedef typename GM::OperatorType OP;
267 
268  OperateWF_Functor(const ValueType rho, const BUFVEC & vec, const INDEX i,M & out)
269  : rho_(rho), vec_(vec), i_(i), out_(out){}
270 
271  template<class FUNCTION>
272  void operator()(const FUNCTION & f){
273  // neutral initialization of output
274  for(size_t n=0; n<f.shape(i_); ++n)
275  ACC::neutral(out_(n));
276  // factor shape iterator
277  typedef typename FUNCTION::FunctionShapeIteratorType FunctionShapeIteratorType;
278  opengm::ShapeWalker<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(),f.dimension());
279  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
280  // loop over the variables
281  // initialize output value with value of the factor at this coordinate
282  // operate j=[0,..i-1]
283  ValueType value;
284  OP::ihop(f(shapeWalker.coordinateTuple().begin()),rho_,value);
285  for(IndexType j=0;j<static_cast<typename GM::IndexType>(i_);++j) {
286  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
287  OP::op(vec_[j].current()(label),value);
288  }
289  // operate j=[i+1,..,vec.size()]
290  for(IndexType j=i_+1;j< vec_.size();++j) {
291  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
292  OP::op(vec_[j].current()(label),value);
293  }
294  // accumulate
295  ACC::op(value,out_(shapeWalker.coordinateTuple()[i_]));
296  }
297  }
298 
299  const ValueType rho_;
300  const BUFVEC & vec_;
301  const INDEX i_;
302  M & out_;
303  };
304 
305  template<class GM, class ACC, class BUFVEC, class M, class INDEX>
306  inline void operateWF
307  (
308  const typename GM::FactorType& f,
309  const typename GM::ValueType rho,
310  const BUFVEC& vec,
311  const INDEX i,
312  M& out
313  ) {
314  OperateWF_Functor<GM,ACC,BUFVEC,M,INDEX> functor(rho,vec,i,out);
315  f.callFunctor(functor);
316  }
317 
318 
320  template<class GM, class BUFVEC>
321  struct OperatorF2_Functor{
322  typedef typename GM::IndexType IndexType;
323  typedef typename GM::LabelType LabelType;
324  typedef typename GM::ValueType ValueType;
325  typedef typename GM::OperatorType OP;
326  OperatorF2_Functor(const BUFVEC& vec, typename GM::IndependentFactorType& out):vec_(vec), out_(out){}
327 
328  template<class FUNCTION>
329  void operator()(const FUNCTION & f){
330  OPENGM_ASSERT(out_.numberOfVariables()!=0);
331  // shape iterator
332  typedef typename FUNCTION::FunctionShapeIteratorType FunctionShapeIteratorType;
333  opengm::ShapeWalker<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(),f.dimension());
334  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) {
335  // loop over the variables
336  ValueType value=f(shapeWalker.coordinateTuple().begin());
337  for(IndexType j=0;j<static_cast<typename GM::IndexType>(vec_.size());++j) {
338  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
339  OP::op(vec_[j].current()(label),value);
340  }
341  out_(scalarIndex)=value;
342  }
343  }
344 
345  const BUFVEC& vec_;
346  typename GM::IndependentFactorType& out_;
347  };
348  template<class GM, class BUFVEC>
349  inline void operateF
350  (
351  const typename GM::FactorType& f,
352  const BUFVEC& vec,
353  typename GM::IndependentFactorType& out
354  )
355  {
356  OperatorF2_Functor<GM, BUFVEC> functor(vec,out);
357  f.callFunctor(functor);
358  }
359 
361  template<class GM, class BUFVEC>
362  struct OperatorWF2_Functor{
363  typedef typename GM::IndexType IndexType;
364  typedef typename GM::LabelType LabelType;
365  typedef typename GM::ValueType ValueType;
366  typedef typename GM::OperatorType OP;
367  OperatorWF2_Functor(ValueType rho, const BUFVEC& vec, typename GM::IndependentFactorType& out) : rho_(rho), vec_(vec), out_(out){}
368 
369  template<class FUNCTION>
370  void operator()(const FUNCTION & f){
371  // shape iterator
372  typedef typename FUNCTION::FunctionShapeIteratorType FunctionShapeIteratorType;
373  opengm::ShapeWalker<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(),f.dimension());
374  for(IndexType scalarIndex=0;scalarIndex<f.size();++scalarIndex,++shapeWalker) { // loop over the variables
375  ValueType value;
376  OP::ihop(f(shapeWalker.coordinateTuple().begin()),rho_,value);
377  for(IndexType j=0;j<static_cast<typename GM::IndexType>(vec_.size());++j) {
378  const LabelType label=static_cast<LabelType>(shapeWalker.coordinateTuple()[j]);
379  OP::op(vec_[j].current()(label),value);
380  }
381  out_(scalarIndex)=value;
382  }
383  }
384 
385  const ValueType rho_;
386  const BUFVEC& vec_;
387  typename GM::IndependentFactorType& out_;
388  };
389 
390  template<class GM, class BUFVEC>
391  inline void operateWF
392  (
393  const typename GM::FactorType& f,
394  const typename GM::ValueType rho,
395  const BUFVEC& vec,
396  typename GM::IndependentFactorType& out
397  ) {
398  OperatorWF2_Functor<GM, BUFVEC> functor(rho,vec,out);
399  f.callFunctor(functor);
400  }
401 
402  } // namespace messagepassingOperations
403 } // namespace opengm
404 
406 
407 #endif
The OpenGM namespace.
Definition: config.hxx:43
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77