OpenGM  2.3.x
Discrete Graphical Model Library
graphicalmodel_function_wrapper.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_GRAPHICALMODEL_FUNCTION_WRAPPER_HXX
3 #define OPENGM_GRAPHICALMODEL_FUNCTION_WRAPPER_HXX
4 
5 #include <vector>
6 #include <set>
7 #include <algorithm>
8 #include <functional>
9 #include <numeric>
10 #include <map>
11 #include <list>
12 #include <set>
13 #include <functional>
14 
17 #include "opengm/opengm.hxx"
25 
26 namespace opengm {
27 
29 
30 template<
31  class T,
32  class OPERATOR,
33  class FUNCTION_TYPE_LIST ,
34  class SPACE
35 >
36 class GraphicalModel;
37 
38 template<class GRAPHICAL_MODEL> class Factor;
39 
40 namespace detail_graphical_model {
41 
42  #define OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( RETURN_TYPE , FUNCTION_NAME ) \
43  template<size_t NUMBER_OF_FUNCTIONS> \
44  template<class GM> \
45  inline RETURN_TYPE \
46  FunctionWrapper<NUMBER_OF_FUNCTIONS>::FUNCTION_NAME \
47  ( \
48  GM const * gm, \
49  const size_t functionIndex, \
50  const size_t functionType \
51  ) { \
52  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex; \
53  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) { \
54  return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
55  } \
56  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) { \
57  if(functionType==0) \
58  return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
59  else \
60  return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
61  } \
62  if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) { \
63  switch(functionType) { \
64  case 0: \
65  return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
66  case 1: \
67  return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
68  case 2: \
69  return gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
70  case 3: \
71  return gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
72  case 4: \
73  return gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
74  case 5: \
75  return gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
76  case 6: \
77  return gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
78  case 7: \
79  return gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
80  case 8: \
81  return gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
82  case 9: \
83  return gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
84  case 10: \
85  return gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
86  case 11: \
87  return gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
88  case 12: \
89  return gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
90  case 13: \
91  return gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
92  case 14: \
93  return gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
94  case 15: \
95  return gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].FUNCTION_NAME(); \
96  default: \
97  return FunctionWrapperExecutor< \
98  16, \
99  NUMBER_OF_FUNCTIONS, \
100  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value \
101  >::FUNCTION_NAME(gm,functionIndex,functionType); \
102  } \
103  } \
104  } \
105  template<size_t IX, size_t DX> \
106  template<class GM> \
107  RETURN_TYPE FunctionWrapperExecutor<IX, DX, false>::FUNCTION_NAME \
108  ( \
109  GM const* gm, \
110  const size_t functionIndex, \
111  const size_t functionType \
112  ) { \
113  if(functionType==IX) { \
114  return gm->template functions<IX>()[functionIndex].FUNCTION_NAME(); \
115  } \
116  else { \
117  return FunctionWrapperExecutor<IX+1, DX, meta::Bool<IX+1==DX>::value >::FUNCTION_NAME (gm, functionIndex,functionType); \
118  } \
119  } \
120  template<size_t IX, size_t DX> \
121  template<class GM> \
122  RETURN_TYPE FunctionWrapperExecutor<IX, DX, true>::FUNCTION_NAME \
123  ( \
124  GM const* gm, \
125  const size_t functionIndex, \
126  const size_t functionType \
127  ) { \
128  throw RuntimeError("Incorrect function type id."); \
129  }
130 
131  template<size_t IX, size_t DX, bool end>
132  struct FunctionWrapperExecutor;
133 
134  template<size_t IX, size_t DX>
135  struct FunctionWrapperExecutor<IX,DX,false>{
136 
137  template <class GM,class FUNCTOR>
138  static void callFunctor(const GM *,const typename GM::IndexType ,const size_t ,FUNCTOR & functor);
139 
140 
141  template <class GM,class ITERATOR>
142  static void getValues(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
143  template <class GM,class ITERATOR>
144  static void getValuesSwitchedOrder(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
145  template <class GM,class ITERATOR>
146  static typename GM::ValueType getValue(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
147  template <class GM,class FUNCTOR>
148  static void forAllValuesInAnyOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
149  template <class GM,class FUNCTOR>
150  static void forAtLeastAllUniqueValues(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
151  template <class GM,class FUNCTOR>
152  static void forAllValuesInOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
153  template <class GM,class FUNCTOR>
154  static void forAllValuesInSwitchedOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
155  template <class GM,int PROPERTY>
156  static bool binaryProperty(const GM *,const typename GM::IndexType ,const size_t );
157  template <class GM,int PROPERTY>
158  static typename GM::ValueType valueProperty(const GM *,const typename GM::IndexType ,const size_t );
159  template <class GM>
160  static size_t numberOfFunctions(const GM *,const size_t );
161  template <class GM_SOURCE,class GM_DEST>
162  static void assignFunctions(const GM_SOURCE & ,GM_DEST &);
163  template<class GM>
164  static bool isPotts(GM const *,const size_t ,const size_t);
165  template<class GM>
166  static bool isGeneralizedPotts(GM const *,const size_t ,const size_t);
167  template<class GM>
168  static bool isSubmodular(GM const *,const size_t ,const size_t);
169  template<class GM>
170  static typename GM::ValueType min(GM const *,const size_t ,const size_t);
171  template<class GM>
172  static typename GM::ValueType max(GM const *,const size_t ,const size_t);
173  template<class GM>
174  static typename GM::ValueType sum(GM const *,const size_t ,const size_t);
175  template<class GM>
176  static typename GM::ValueType product(GM const *,const size_t ,const size_t);
177  template<class GM>
178  static bool isSquaredDifference(GM const *,const size_t ,const size_t);
179  template<class GM>
180  static bool isTruncatedSquaredDifference(GM const *,const size_t ,const size_t);
181  template<class GM>
182  static bool isAbsoluteDifference(GM const *,const size_t ,const size_t);
183  template<class GM>
184  static bool isTruncatedAbsoluteDifference(GM const *,const size_t ,const size_t);
185  template<class GM>
186  static bool isLinearConstraint(GM const *,const size_t ,const size_t);
187  };
188 
189  template<size_t IX, size_t DX>
190  struct FunctionWrapperExecutor<IX,DX,true>{
191 
192  template <class GM,class FUNCTOR>
193  static void callFunctor(const GM *,const typename GM::IndexType ,const size_t ,FUNCTOR & functor);
194 
195  template <class GM,class ITERATOR>
196  static typename GM::ValueType getValue(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
197  template <class GM,class ITERATOR>
198  static void getValues(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
199  template <class GM,class ITERATOR>
200  static void getValuesSwitchedOrder(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
201  template <class GM,class FUNCTOR>
202  static void forAllValuesInAnyOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
203  template <class GM,class FUNCTOR>
204  static void forAtLeastAllUniqueValues(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
205  template <class GM,class FUNCTOR>
206  static void forAllValuesInOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
207  template <class GM,class FUNCTOR>
208  static void forAllValuesInSwitchedOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
209  template <class GM,int PROPERTY>
210  static bool binaryProperty(const GM *,const typename GM::IndexType ,const size_t );
211  template <class GM,int PROPERTY>
212  static typename GM::ValueType valueProperty(const GM *,const typename GM::IndexType ,const size_t );
213  template <class GM>
214  static size_t numberOfFunctions(const GM *,const size_t functionTypeIndex);
215  template <class GM_SOURCE,class GM_DEST>
216  static void assignFunctions(const GM_SOURCE & ,GM_DEST &);
217  template<class GM>
218  static bool isPotts(GM const *,const size_t ,const size_t);
219  template<class GM>
220  static bool isGeneralizedPotts(GM const *,const size_t ,const size_t);
221  template<class GM>
222  static bool isSubmodular(GM const *,const size_t,const size_t );
223  template<class GM>
224  static typename GM::ValueType min(GM const *,const size_t ,const size_t);
225  template<class GM>
226  static typename GM::ValueType max(GM const *,const size_t ,const size_t);
227  template<class GM>
228  static typename GM::ValueType sum(GM const *,const size_t ,const size_t);
229  template<class GM>
230  static typename GM::ValueType product(GM const *,const size_t ,const size_t);
231  template<class GM>
232  static bool isSquaredDifference(GM const *,const size_t ,const size_t);
233  template<class GM>
234  static bool isTruncatedSquaredDifference(GM const *,const size_t ,const size_t);
235  template<class GM>
236  static bool isAbsoluteDifference(GM const *,const size_t ,const size_t);
237  template<class GM>
238  static bool isTruncatedAbsoluteDifference(GM const *,const size_t ,const size_t);
239  template<class GM>
240  static bool isLinearConstraint(GM const *,const size_t ,const size_t);
241  };
242 
243  template<size_t NUMBER_OF_FUNCTIONS>
244  struct FunctionWrapper{
245 
246  template <class GM,class FUNCTOR>
247  static void callFunctor(const GM *,const typename GM::IndexType ,const size_t ,FUNCTOR & functor);
248 
249  template <class GM,class OUT_ITERATOR>
250  static void getValues(const GM *,OUT_ITERATOR,const typename GM::IndexType ,const size_t );
251  template <class GM,class OUT_ITERATOR>
252  static void getValuesSwitchedOrder(const GM *,OUT_ITERATOR,const typename GM::IndexType ,const size_t );
253  template <class GM,class ITERATOR>
254  static typename GM::ValueType getValue(const GM *,ITERATOR,const typename GM::IndexType ,const size_t );
255  template <class GM,class FUNCTOR>
256  static void forAllValuesInAnyOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
257  template <class GM,class FUNCTOR>
258  static void forAtLeastAllUniqueValues(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
259  template <class GM,class FUNCTOR>
260  static void forAllValuesInOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
261  template <class GM,class FUNCTOR>
262  static void forAllValuesInSwitchedOrder(const GM *,FUNCTOR &,const typename GM::IndexType ,const size_t );
263  template <class GM,int PROPERTY>
264  static bool binaryProperty(const GM *,const typename GM::IndexType ,const size_t );
265  template <class GM,int PROPERTY>
266  static typename GM::ValueType valueProperty(const GM *,const typename GM::IndexType ,const size_t );
267  template <class GM>
268  static size_t numberOfFunctions(const GM *,const size_t functionTypeIndex);
269  template <class GM_SOURCE,class GM_DEST>
270  static void assignFunctions(const GM_SOURCE & ,GM_DEST &);
271  template<class GM>
272  static bool isPotts(GM const *,const size_t,const size_t);
273  template<class GM>
274  static bool isGeneralizedPotts(GM const *,const size_t ,const size_t);
275  template<class GM>
276  static bool isSubmodular(GM const *,const size_t ,const size_t);
277  template<class GM>
278  static typename GM::ValueType min(GM const *,const size_t ,const size_t);
279  template<class GM>
280  static typename GM::ValueType max(GM const *,const size_t ,const size_t);
281  template<class GM>
282  static typename GM::ValueType sum(GM const *,const size_t ,const size_t);
283  template<class GM>
284  static typename GM::ValueType product(GM const *,const size_t ,const size_t);
285  template<class GM>
286  static bool isSquaredDifference(GM const *,const size_t ,const size_t);
287  template<class GM>
288  static bool isTruncatedSquaredDifference(GM const *,const size_t ,const size_t);
289  template<class GM>
290  static bool isAbsoluteDifference(GM const *,const size_t ,const size_t);
291  template<class GM>
292  static bool isTruncatedAbsoluteDifference(GM const *,const size_t ,const size_t);
293  template<class GM>
294  static bool isLinearConstraint(GM const *,const size_t ,const size_t);
295  };
296 } //namespace detail_graphical_model
297 
298 // implementaion
299 namespace detail_graphical_model {
300  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isSubmodular)
301  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isPotts)
302  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isGeneralizedPotts)
303  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isSquaredDifference)
304  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isTruncatedSquaredDifference)
305  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isAbsoluteDifference)
306  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isTruncatedAbsoluteDifference)
307  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( bool, isLinearConstraint)
308  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, min)
309  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, max)
310  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, sum)
311  OPENGM_BASIC_FUNCTION_WRAPPER_CODE_GENERATOR_MACRO( typename GM::ValueType, product)
312 
313  template<size_t IX,size_t DX>
314  template<class GM,class ITERATOR>
315  inline typename GM::ValueType
316  FunctionWrapperExecutor<IX,DX,false>::getValue
317  (
318  const GM * gm,
319  ITERATOR iterator,
320  const typename GM::IndexType functionIndex,
321  const size_t functionType
322  ) {
323  if(IX==functionType) {
324  return gm-> template functions<IX>()[functionIndex](iterator);
325  }
326  else{
327  return FunctionWrapperExecutor<
328  meta::Increment<IX>::value,
329  DX,
330  meta::EqualNumber<
331  meta::Increment<IX>::value,
332  DX
333  >::value
334  >::getValue(gm,iterator,functionIndex,functionType);
335  }
336  }
337 
338  template<size_t IX,size_t DX>
339  template <class GM,class FUNCTOR>
340  inline void
341  FunctionWrapperExecutor<IX,DX,false>::forAllValuesInAnyOrder
342  (
343  const GM * gm,
344  FUNCTOR & functor,
345  const typename GM::IndexType functionIndex,
346  const size_t functionType
347  ) {
348  if(IX==functionType) {
349  gm-> template functions<IX>()[functionIndex].forAllValuesInAnyOrder(functor);
350  }
351  else{
352  FunctionWrapperExecutor<
353  meta::Increment<IX>::value,
354  DX,
355  meta::EqualNumber<
356  meta::Increment<IX>::value,
357  DX
358  >::value
359  >::forAllValuesInAnyOrder(gm,functor,functionIndex,functionType);
360  }
361  }
362 
363  template<size_t IX,size_t DX>
364  template <class GM,class FUNCTOR>
365  inline void
366  FunctionWrapperExecutor<IX,DX,false>::forAtLeastAllUniqueValues
367  (
368  const GM * gm,
369  FUNCTOR & functor,
370  const typename GM::IndexType functionIndex,
371  const size_t functionType
372  ) {
373  if(IX==functionType) {
374  gm-> template functions<IX>()[functionIndex].forAtLeastAllUniqueValues(functor);
375  }
376  else{
377  FunctionWrapperExecutor<
378  meta::Increment<IX>::value,
379  DX,
380  meta::EqualNumber<
381  meta::Increment<IX>::value,
382  DX
383  >::value
384  >::forAtLeastAllUniqueValues(gm,functor,functionIndex,functionType);
385  }
386  }
387 
388  template<size_t IX,size_t DX>
389  template <class GM,class FUNCTOR>
390  inline void
391  FunctionWrapperExecutor<IX,DX,false>::forAllValuesInOrder
392  (
393  const GM * gm,
394  FUNCTOR & functor,
395  const typename GM::IndexType functionIndex,
396  const size_t functionType
397  ) {
398  if(IX==functionType) {
399  gm-> template functions<IX>()[functionIndex].forAllValuesInOrder(functor);
400  }
401  else{
402  FunctionWrapperExecutor<
403  meta::Increment<IX>::value,
404  DX,
405  meta::EqualNumber<
406  meta::Increment<IX>::value,
407  DX
408  >::value
409  >::forAllValuesInOrder(gm,functor,functionIndex,functionType);
410  }
411  }
412 
413  template<size_t IX,size_t DX>
414  template <class GM,class FUNCTOR>
415  inline void
416  FunctionWrapperExecutor<IX,DX,false>::forAllValuesInSwitchedOrder
417  (
418  const GM * gm,
419  FUNCTOR & functor,
420  const typename GM::IndexType functionIndex,
421  const size_t functionType
422  ) {
423  if(IX==functionType) {
424  gm-> template functions<IX>()[functionIndex].forAllValuesInSwitchedOrder(functor);
425  }
426  else{
427  FunctionWrapperExecutor<
428  meta::Increment<IX>::value,
429  DX,
430  meta::EqualNumber<
431  meta::Increment<IX>::value,
432  DX
433  >::value
434  >::forAllValuesInSwitchedOrder(gm,functor,functionIndex,functionType);
435  }
436  }
437 
438 
439  template<size_t IX,size_t DX>
440  template <class GM,int PROPERTY>
441  inline bool
442  FunctionWrapperExecutor<IX,DX,false>::binaryProperty
443  (
444  const GM * gm,
445  const typename GM::IndexType functionIndex,
446  const size_t functionType
447  ) {
448  if(IX==functionType) {
449  typedef typename GM::FunctionTypeList FTypeList;
450  typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
451  return BinaryFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<IX>()[functionIndex]);
452  }
453  else{
454  return FunctionWrapperExecutor<
455  meta::Increment<IX>::value,
456  DX,
457  meta::EqualNumber<
458  meta::Increment<IX>::value,
459  DX
460  >::value
461  >:: template binaryProperty<GM,PROPERTY>(gm,functionIndex,functionType);
462  }
463  }
464 
465  template<size_t IX,size_t DX>
466  template <class GM,int PROPERTY>
467  inline typename GM::ValueType
468  FunctionWrapperExecutor<IX,DX,false>::valueProperty
469  (
470  const GM * gm,
471  const typename GM::IndexType functionIndex,
472  const size_t functionType
473  ) {
474  if(IX==functionType) {
475  typedef typename GM::FunctionTypeList FTypeList;
476  typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
477  return ValueFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<IX>()[functionIndex]);
478  }
479  else{
480  return FunctionWrapperExecutor<
481  meta::Increment<IX>::value,
482  DX,
483  meta::EqualNumber<
484  meta::Increment<IX>::value,
485  DX
486  >::value
487  >:: template valueProperty<GM,PROPERTY>(gm,functionIndex,functionType);
488  }
489  }
490 
491  template<size_t IX,size_t DX>
492  template<class GM,class FUNCTOR>
493  inline void
494  FunctionWrapperExecutor<IX,DX,false>::callFunctor
495  (
496  const GM * gm,
497  const typename GM::IndexType functionIndex,
498  const size_t functionType,
499  FUNCTOR & functor
500  ) {
501  if(IX==functionType) {
502  // COPY FUNCTION TO ITERATR
503  typedef typename GM::FunctionTypeList FTypeList;
504  typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
505  typedef typename FunctionType::FunctionShapeIteratorType FunctionShapeIteratorType;
506 
507  const FunctionType & function = gm-> template functions<IX>()[functionIndex];
508  functor(function);
509 
510  }
511  else{
512  return FunctionWrapperExecutor<
513  meta::Increment<IX>::value,
514  DX,
515  meta::EqualNumber<
516  meta::Increment<IX>::value,
517  DX
518  >::value
519  >::callFunctor(gm,functionIndex,functionType,functor);
520  }
521  }
522 
523 
524  template<size_t IX,size_t DX>
525  template<class GM,class ITERATOR>
526  inline void
527  FunctionWrapperExecutor<IX,DX,false>::getValues
528  (
529  const GM * gm,
530  ITERATOR iterator,
531  const typename GM::IndexType functionIndex,
532  const size_t functionType
533  ) {
534  if(IX==functionType) {
535  // COPY FUNCTION TO ITERATR
536  typedef typename GM::FunctionTypeList FTypeList;
537  typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
538  typedef typename FunctionType::FunctionShapeIteratorType FunctionShapeIteratorType;
539 
540  const FunctionType & function = gm-> template functions<IX>()[functionIndex];
541  ShapeWalker< FunctionShapeIteratorType > walker(function.functionShapeBegin(),function.dimension());
542  for (size_t i = 0; i < function.size(); ++i) {
543  *iterator = function(walker.coordinateTuple().begin());
544  ++iterator;
545  ++walker;
546  }
547 
548  }
549  else{
550  return FunctionWrapperExecutor<
551  meta::Increment<IX>::value,
552  DX,
553  meta::EqualNumber<
554  meta::Increment<IX>::value,
555  DX
556  >::value
557  >::getValues(gm,iterator,functionIndex,functionType);
558  }
559  }
560 
561  template<size_t IX,size_t DX>
562  template<class GM,class ITERATOR>
563  inline void
564  FunctionWrapperExecutor<IX,DX,false>::getValuesSwitchedOrder
565  (
566  const GM * gm,
567  ITERATOR iterator,
568  const typename GM::IndexType functionIndex,
569  const size_t functionType
570  ) {
571  if(IX==functionType) {
572  // COPY FUNCTION TO ITERATR
573  typedef typename GM::FunctionTypeList FTypeList;
574  typedef typename meta::TypeAtTypeList<FTypeList,IX>::type FunctionType;
575  typedef typename FunctionType::FunctionShapeIteratorType FunctionShapeIteratorType;
576 
577  const FunctionType & function = gm-> template functions<IX>()[functionIndex];
578  ShapeWalkerSwitchedOrder< FunctionShapeIteratorType > walker(function.functionShapeBegin(),function.dimension());
579  for (size_t i = 0; i < function.size(); ++i) {
580  *iterator = function(walker.coordinateTuple().begin());
581  ++iterator;
582  ++walker;
583  }
584 
585  }
586  else{
587  return FunctionWrapperExecutor<
588  meta::Increment<IX>::value,
589  DX,
590  meta::EqualNumber<
591  meta::Increment<IX>::value,
592  DX
593  >::value
594  >::getValuesSwitchedOrder(gm,iterator,functionIndex,functionType);
595  }
596  }
597 
598  template<size_t IX,size_t DX>
599  template<class GM,class ITERATOR>
600  inline void
601  FunctionWrapperExecutor<IX,DX,true>::getValues
602  (
603  const GM * gm,
604  ITERATOR iterator,
605  const typename GM::IndexType functionIndex,
606  const size_t functionType
607  ) {
608  throw RuntimeError("Incorrect function type id.");
609  }
610  template<size_t IX,size_t DX>
611  template<class GM,class ITERATOR>
612  inline void
613  FunctionWrapperExecutor<IX,DX,true>::getValuesSwitchedOrder
614  (
615  const GM * gm,
616  ITERATOR iterator,
617  const typename GM::IndexType functionIndex,
618  const size_t functionType
619  ) {
620  throw RuntimeError("Incorrect function type id.");
621  }
622 
623  template<size_t IX,size_t DX>
624  template<class GM,class FUNCTOR>
625  inline void
626  FunctionWrapperExecutor<IX,DX,true>::callFunctor
627  (
628  const GM * gm,
629  const typename GM::IndexType functionIndex,
630  const size_t functionType,
631  FUNCTOR & f
632  ) {
633  throw RuntimeError("Incorrect function type id.");
634  }
635 
636  template<size_t IX,size_t DX>
637  template<class GM,class ITERATOR>
638  inline typename GM::ValueType
639  FunctionWrapperExecutor<IX,DX,true>::getValue
640  (
641  const GM * gm,
642  ITERATOR iterator,
643  const typename GM::IndexType functionIndex,
644  const size_t functionType
645  ) {
646  throw RuntimeError("Incorrect function type id.");
647  return typename GM::ValueType();
648  }
649 
650  template<size_t IX,size_t DX>
651  template <class GM,class FUNCTOR>
652  inline void
653  FunctionWrapperExecutor<IX,DX,true>::forAllValuesInAnyOrder
654  (
655  const GM * gm,
656  FUNCTOR & functor,
657  const typename GM::IndexType functionIndex,
658  const size_t functionType
659  ) {
660  throw RuntimeError("Incorrect function type id.");
661  }
662 
663  template<size_t IX,size_t DX>
664  template <class GM,class FUNCTOR>
665  inline void
666  FunctionWrapperExecutor<IX,DX,true>::forAtLeastAllUniqueValues
667  (
668  const GM * gm,
669  FUNCTOR & functor,
670  const typename GM::IndexType functionIndex,
671  const size_t functionType
672  ) {
673  throw RuntimeError("Incorrect function type id.");
674  }
675 
676  template<size_t IX,size_t DX>
677  template <class GM,class FUNCTOR>
678  inline void
679  FunctionWrapperExecutor<IX,DX,true>::forAllValuesInOrder
680  (
681  const GM * gm,
682  FUNCTOR & functor,
683  const typename GM::IndexType functionIndex,
684  const size_t functionType
685  ) {
686  throw RuntimeError("Incorrect function type id.");
687  }
688 
689  template<size_t IX,size_t DX>
690  template <class GM,class FUNCTOR>
691  inline void
692  FunctionWrapperExecutor<IX,DX,true>::forAllValuesInSwitchedOrder
693  (
694  const GM * gm,
695  FUNCTOR & functor,
696  const typename GM::IndexType functionIndex,
697  const size_t functionType
698  ) {
699  throw RuntimeError("Incorrect function type id.");
700  }
701 
702  template<size_t IX,size_t DX>
703  template <class GM,int PROPERTY>
704  inline bool
705  FunctionWrapperExecutor<IX,DX,true>::binaryProperty
706  (
707  const GM * gm,
708  const typename GM::IndexType functionIndex,
709  const size_t functionType
710  ) {
711  throw RuntimeError("Incorrect function type id.");
712  return false;
713  }
714 
715  template<size_t IX,size_t DX>
716  template <class GM,int PROPERTY>
717  inline typename GM::ValueType
718  FunctionWrapperExecutor<IX,DX,true>::valueProperty
719  (
720  const GM * gm,
721  const typename GM::IndexType functionIndex,
722  const size_t functionType
723  ) {
724  throw RuntimeError("Incorrect function type id.");
725  return false;
726  }
727 
728  template<size_t IX,size_t DX>
729  template<class GM>
730  inline size_t
731  FunctionWrapperExecutor<IX,DX,false>::numberOfFunctions
732  (
733  const GM * gm,
734  const size_t functionType
735  ) {
736  if(IX==functionType) {
737  return gm->template functions<IX>().size();
738  }
739  else{
740  return FunctionWrapperExecutor<
741  meta::Increment<IX>::value,
742  DX,
743  meta::EqualNumber<
744  meta::Increment<IX>::value,
745  DX
746  >::value
747  >::numberOfFunctions(gm,functionType);
748  }
749  }
750 
751  template<size_t IX,size_t DX>
752  template<class GM>
753  inline size_t
754  FunctionWrapperExecutor<IX,DX,true>::numberOfFunctions
755  (
756  const GM * gm,
757  const size_t functionType
758  ) {
759  throw RuntimeError("Incorrect function type id.");
760  }
761 
762  template<size_t IX,size_t DX>
763  template<class GM_SOURCE,class GM_DEST>
764  inline void
765  FunctionWrapperExecutor<IX,DX,false>::assignFunctions
766  (
767  const GM_SOURCE & gmSource,
768  GM_DEST & gmDest
769  ) {
770  typedef typename meta::TypeAtTypeList<
771  typename GM_SOURCE::FunctionTypeList ,
772  IX
773  >::type SourceTypeAtIX;
774  typedef meta::SizeT<
775  meta::GetIndexInTypeList<
776  typename GM_DEST::FunctionTypeList,
777  SourceTypeAtIX
778  >::value
779  > PositionOfSourceTypeInDestType;
780  gmDest.template functions<PositionOfSourceTypeInDestType::value> () =
781  gmSource.template functions<IX> ();
782 
783  //recursive call to the rest
784  FunctionWrapperExecutor<
785  meta::Increment<IX>::value,
786  DX,
787  meta::EqualNumber<
788  meta::Increment<IX>::value,
789  DX
790  >::value
791  >::assignFunctions(gmSource,gmDest);
792  }
793 
794  template<size_t IX,size_t DX>
795  template<class GM_SOURCE,class GM_DEST>
796  inline void
797  FunctionWrapperExecutor<IX,DX,true>::assignFunctions
798  (
799  const GM_SOURCE & gmSource,
800  GM_DEST & gmDest
801  ) {
802  }
803 
804  template<size_t NUMBER_OF_FUNCTIONS>
805  template<class GM_SOURCE,class GM_DEST>
806  inline void
807  FunctionWrapper<NUMBER_OF_FUNCTIONS>::assignFunctions
808  (
809  const GM_SOURCE & gmSource,
810  GM_DEST & gmDest
811  ) {
812  typedef FunctionWrapperExecutor<0, NUMBER_OF_FUNCTIONS, meta::Bool<NUMBER_OF_FUNCTIONS==0>::value> ExecutorType;
813  return ExecutorType::assignFunctions(gmSource, gmDest);
814  }
815 
816  template<size_t NUMBER_OF_FUNCTIONS>
817  template<class GM>
818  inline size_t
819  FunctionWrapper<NUMBER_OF_FUNCTIONS>::numberOfFunctions
820  (
821  const GM * gm,
822  const size_t functionType
823  ) {
824  typedef FunctionWrapperExecutor<0, NUMBER_OF_FUNCTIONS, meta::Bool<NUMBER_OF_FUNCTIONS==0>::value> ExecutorType;
825  return ExecutorType::numberOfFunctions(gm, functionType);
826  }
827 
828 
829  template<size_t NUMBER_OF_FUNCTIONS>
830  template<class GM,class FUNCTOR>
831  inline void
832  FunctionWrapper<NUMBER_OF_FUNCTIONS>::callFunctor
833  (
834  const GM * gm,
835  const typename GM::IndexType functionIndex,
836  const size_t functionType,
837  FUNCTOR & functor
838  ) {
839  FunctionWrapperExecutor<
840  0,
841  NUMBER_OF_FUNCTIONS,
842  opengm::meta::BiggerOrEqualNumber<0,NUMBER_OF_FUNCTIONS>::value
843  >::callFunctor(gm,functionIndex,functionType,functor);
844  }
845 
846 
847  template<size_t NUMBER_OF_FUNCTIONS>
848  template<class GM,class ITERATOR>
849  inline void
850  FunctionWrapper<NUMBER_OF_FUNCTIONS>::getValues
851  (
852  const GM * gm,
853  ITERATOR iterator,
854  const typename GM::IndexType functionIndex,
855  const size_t functionType
856  ) {
857  FunctionWrapperExecutor<
858  0,
859  NUMBER_OF_FUNCTIONS,
860  opengm::meta::BiggerOrEqualNumber<0,NUMBER_OF_FUNCTIONS>::value
861  >::getValues(gm,iterator,functionIndex,functionType);
862  }
863 
864  template<size_t NUMBER_OF_FUNCTIONS>
865  template<class GM,class ITERATOR>
866  inline void
867  FunctionWrapper<NUMBER_OF_FUNCTIONS>::getValuesSwitchedOrder
868  (
869  const GM * gm,
870  ITERATOR iterator,
871  const typename GM::IndexType functionIndex,
872  const size_t functionType
873  ) {
874  FunctionWrapperExecutor<
875  0,
876  NUMBER_OF_FUNCTIONS,
877  opengm::meta::BiggerOrEqualNumber<0,NUMBER_OF_FUNCTIONS>::value
878  >::getValuesSwitchedOrder(gm,iterator,functionIndex,functionType);
879  }
880 
881  template<size_t NUMBER_OF_FUNCTIONS>
882  template<class GM,class ITERATOR>
883  inline typename GM::ValueType
884  FunctionWrapper<NUMBER_OF_FUNCTIONS>::getValue
885  (
886  const GM * gm,
887  ITERATOR iterator,
888  const typename GM::IndexType functionIndex,
889  const size_t functionType
890  ) {
891  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
892  // special implementation if there is only one function typelist
893  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
894  return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex](iterator);
895  }
896  // special implementation if there are only two functions in the typelist
897  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
898  if(functionType==0)
899  return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex](iterator);
900  else
901  return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex](iterator);
902  }
903  // general case : 3 or more functions in the typelist
904  if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
905  switch(functionType) {
906  case 0:
907  return gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex](iterator);
908  case 1:
909  return gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex](iterator);
910  case 2:
911  return gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex](iterator);
912  case 3:
913  return gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex](iterator);
914  case 4:
915  return gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex](iterator);
916  case 5:
917  return gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex](iterator);
918  case 6:
919  return gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex](iterator);
920  case 7:
921  return gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex](iterator);
922  case 8:
923  return gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex](iterator);
924  case 9:
925  return gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex](iterator);
926  case 10:
927  return gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex](iterator);
928  case 11:
929  return gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex](iterator);
930  case 12:
931  return gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex](iterator);
932  case 13:
933  return gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex](iterator);
934  case 14:
935  return gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex](iterator);
936  case 15:
937  return gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex](iterator);
938  default:
939  // meta/template recursive "if-else" generation if the
940  // function index is bigger than 15
941  return FunctionWrapperExecutor<
942  16,
943  NUMBER_OF_FUNCTIONS,
944  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
945  >::getValue(gm,iterator,functionIndex,functionType);
946  }
947  }
948  }
949 
950 
951  template<size_t NUMBER_OF_FUNCTIONS>
952  template<class GM,class FUNCTOR>
953  inline void
954  FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAllValuesInAnyOrder
955  (
956  const GM * gm,
957  FUNCTOR & functor,
958  const typename GM::IndexType functionIndex,
959  const size_t functionType
960  ) {
961  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
962  // special implementation if there is only one function typelist
963  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
964  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
965  }
966  // special implementation if there are only two functions in the typelist
967  else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
968  if(functionType==0)
969  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
970  else
971  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
972  }
973  // general case : 3 or more functions in the typelist
974  else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
975  switch(functionType) {
976  case 0:
977  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
978  break;
979  case 1:
980  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
981  break;
982  case 2:
983  gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
984  break;
985  case 3:
986  gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
987  break;
988  case 4:
989  gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
990  break;
991  case 5:
992  gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
993  break;
994  case 6:
995  gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
996  break;
997  case 7:
998  gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
999  break;
1000  case 8:
1001  gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1002  break;
1003  case 9:
1004  gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1005  break;
1006  case 10:
1007  gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1008  break;
1009  case 11:
1010  gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1011  break;
1012  case 12:
1013  gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1014  break;
1015  case 13:
1016  gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1017  break;
1018  case 14:
1019  gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1020  break;
1021  case 15:
1022  gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAllValuesInAnyOrder(functor);
1023  break;
1024  default:
1025  // meta/template recursive "if-else" generation if the
1026  // function index is bigger than 15
1027  FunctionWrapperExecutor<
1028  16,
1029  NUMBER_OF_FUNCTIONS,
1030  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
1031  >::forAllValuesInAnyOrder(gm,functor,functionIndex,functionType);
1032  }
1033  }
1034  }
1035 
1036 
1037  template<size_t NUMBER_OF_FUNCTIONS>
1038  template<class GM,class FUNCTOR>
1039  inline void
1040  FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAtLeastAllUniqueValues
1041  (
1042  const GM * gm,
1043  FUNCTOR & functor,
1044  const typename GM::IndexType functionIndex,
1045  const size_t functionType
1046  ) {
1047  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
1048  // special implementation if there is only one function typelist
1049  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
1050  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1051  }
1052  // special implementation if there are only two functions in the typelist
1053  else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
1054  if(functionType==0)
1055  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1056  else
1057  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1058  }
1059  // general case : 3 or more functions in the typelist
1060  else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
1061  switch(functionType) {
1062  case 0:
1063  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1064  break;
1065  case 1:
1066  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1067  break;
1068  case 2:
1069  gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1070  break;
1071  case 3:
1072  gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1073  break;
1074  case 4:
1075  gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1076  break;
1077  case 5:
1078  gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1079  break;
1080  case 6:
1081  gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1082  break;
1083  case 7:
1084  gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1085  break;
1086  case 8:
1087  gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1088  break;
1089  case 9:
1090  gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1091  break;
1092  case 10:
1093  gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1094  break;
1095  case 11:
1096  gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1097  break;
1098  case 12:
1099  gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1100  break;
1101  case 13:
1102  gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1103  break;
1104  case 14:
1105  gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1106  break;
1107  case 15:
1108  gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAtLeastAllUniqueValues(functor);
1109  break;
1110  default:
1111  // meta/template recursive "if-else" generation if the
1112  // function index is bigger than 15
1113  FunctionWrapperExecutor<
1114  16,
1115  NUMBER_OF_FUNCTIONS,
1116  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
1117  >::forAtLeastAllUniqueValues(gm,functor,functionIndex,functionType);
1118  }
1119  }
1120  }
1121 
1122  template<size_t NUMBER_OF_FUNCTIONS>
1123  template<class GM,class FUNCTOR>
1124  inline void
1125  FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAllValuesInOrder
1126  (
1127  const GM * gm,
1128  FUNCTOR & functor,
1129  const typename GM::IndexType functionIndex,
1130  const size_t functionType
1131  ) {
1132  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
1133  // special implementation if there is only one function typelist
1134  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
1135  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1136  }
1137  // special implementation if there are only two functions in the typelist
1138  else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
1139  if(functionType==0)
1140  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1141  else
1142  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1143  }
1144  // general case : 3 or more functions in the typelist
1145  else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
1146  switch(functionType) {
1147  case 0:
1148  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1149  break;
1150  case 1:
1151  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1152  break;
1153  case 2:
1154  gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1155  break;
1156  case 3:
1157  gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1158  break;
1159  case 4:
1160  gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1161  break;
1162  case 5:
1163  gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1164  break;
1165  case 6:
1166  gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1167  break;
1168  case 7:
1169  gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1170  break;
1171  case 8:
1172  gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1173  break;
1174  case 9:
1175  gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1176  break;
1177  case 10:
1178  gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1179  break;
1180  case 11:
1181  gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1182  break;
1183  case 12:
1184  gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1185  break;
1186  case 13:
1187  gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1188  break;
1189  case 14:
1190  gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1191  break;
1192  case 15:
1193  gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAllValuesInOrder(functor);
1194  break;
1195  default:
1196  // meta/template recursive "if-else" generation if the
1197  // function index is bigger than 15
1198  FunctionWrapperExecutor<
1199  16,
1200  NUMBER_OF_FUNCTIONS,
1201  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
1202  >::forAllValuesInOrder(gm,functor,functionIndex,functionType);
1203  }
1204  }
1205  }
1206 
1207 
1208  template<size_t NUMBER_OF_FUNCTIONS>
1209  template<class GM,class FUNCTOR>
1210  inline void
1211  FunctionWrapper<NUMBER_OF_FUNCTIONS>::forAllValuesInSwitchedOrder
1212  (
1213  const GM * gm,
1214  FUNCTOR & functor,
1215  const typename GM::IndexType functionIndex,
1216  const size_t functionType
1217  ) {
1218  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
1219  // special implementation if there is only one function typelist
1220  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {
1221  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1222  }
1223  // special implementation if there are only two functions in the typelist
1224  else if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
1225  if(functionType==0)
1226  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1227  else
1228  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1229  }
1230  // general case : 3 or more functions in the typelist
1231  else if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
1232  switch(functionType) {
1233  case 0:
1234  gm->template functions<meta::MinimumNumber<0,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1235  break;
1236  case 1:
1237  gm->template functions<meta::MinimumNumber<1,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1238  break;
1239  case 2:
1240  gm->template functions<meta::MinimumNumber<2,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1241  break;
1242  case 3:
1243  gm->template functions<meta::MinimumNumber<3,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1244  break;
1245  case 4:
1246  gm->template functions<meta::MinimumNumber<4,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1247  break;
1248  case 5:
1249  gm->template functions<meta::MinimumNumber<5,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1250  break;
1251  case 6:
1252  gm->template functions<meta::MinimumNumber<6,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1253  break;
1254  case 7:
1255  gm->template functions<meta::MinimumNumber<7,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1256  break;
1257  case 8:
1258  gm->template functions<meta::MinimumNumber<8,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1259  break;
1260  case 9:
1261  gm->template functions<meta::MinimumNumber<9,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1262  break;
1263  case 10:
1264  gm->template functions<meta::MinimumNumber<10,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1265  break;
1266  case 11:
1267  gm->template functions<meta::MinimumNumber<11,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1268  break;
1269  case 12:
1270  gm->template functions<meta::MinimumNumber<12,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1271  break;
1272  case 13:
1273  gm->template functions<meta::MinimumNumber<13,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1274  break;
1275  case 14:
1276  gm->template functions<meta::MinimumNumber<14,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1277  break;
1278  case 15:
1279  gm->template functions<meta::MinimumNumber<15,MaxIndex::value >::value >()[functionIndex].forAllValuesInSwitchedOrder(functor);
1280  break;
1281  default:
1282  // meta/template recursive "if-else" generation if the
1283  // function index is bigger than 15
1284  FunctionWrapperExecutor<
1285  16,
1286  NUMBER_OF_FUNCTIONS,
1287  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
1288  >::forAllValuesInSwitchedOrder(gm,functor,functionIndex,functionType);
1289  }
1290  }
1291  }
1292 
1293 
1294  template<size_t NUMBER_OF_FUNCTIONS>
1295  template <class GM,int PROPERTY>
1296  inline bool
1297  FunctionWrapper<NUMBER_OF_FUNCTIONS>::binaryProperty
1298  (
1299  const GM * gm,
1300  const typename GM::IndexType functionIndex,
1301  const size_t functionType
1302  ) {
1303  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
1304  typedef typename GM::FunctionTypeList FTypeList;
1305  // special implementation if there is only one function typelist
1306 
1307 
1308  #define OPENGM_FWRAPPER_PROPERTY_GEN_MACRO( NUMBER) typedef meta::Int< NUMBER > Number; \
1309  typedef meta::Int<meta::MinimumNumber<Number::value,MaxIndex::value >::value> SaveNumber; \
1310  typedef typename meta::TypeAtTypeList<FTypeList,SaveNumber::value>::type FunctionType; \
1311  return BinaryFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<SaveNumber::value>()[functionIndex])
1312 
1313  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(0);}
1314  // special implementation if there are only two functions in the typelist
1315  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
1316  if(functionType==0){OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(1);}
1317  else{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(2);}
1318  }
1319  // general case : 3 or more functions in the typelist
1320  if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
1321  switch(functionType) {
1322  case 0 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(0);}
1323  case 1 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(1);}
1324  case 2 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(2);}
1325  case 3 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(3);}
1326  case 4 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(4);}
1327  case 5 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(5);}
1328  case 6 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(6);}
1329  case 7 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(7);}
1330  case 8 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(8);}
1331  case 9 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(9);}
1332  case 10 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(10);}
1333  case 11 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(11);}
1334  case 12 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(12);}
1335  case 13 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(13);}
1336  case 14 :{OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(14);}
1337  case 15 :{ OPENGM_FWRAPPER_PROPERTY_GEN_MACRO(15);}
1338  default:{
1339  //meta/template recursive "if-else" generation if the
1340  //function index is bigger than 15
1341  return FunctionWrapperExecutor<
1342  16,
1343  NUMBER_OF_FUNCTIONS,
1344  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
1345  >:: template binaryProperty <GM,PROPERTY> (gm,functionIndex,functionType);
1346  }
1347  }
1348  }
1349  #undef OPENGM_FWRAPPER_PROPERTY_GEN_MACRO
1350  }
1351 
1352  template<size_t NUMBER_OF_FUNCTIONS>
1353  template <class GM,int PROPERTY>
1354  inline typename GM::ValueType
1355  FunctionWrapper<NUMBER_OF_FUNCTIONS>::valueProperty
1356  (
1357  const GM * gm,
1358  const typename GM::IndexType functionIndex,
1359  const size_t functionType
1360  ) {
1361  typedef typename opengm::meta::SizeT< opengm::meta::Decrement<NUMBER_OF_FUNCTIONS>::value > MaxIndex;
1362  typedef typename GM::FunctionTypeList FTypeList;
1363  // special implementation if there is only one function typelist
1364 
1365 
1366  #define OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO( NUMBER) typedef meta::Int< NUMBER > Number; \
1367  typedef meta::Int<meta::MinimumNumber<Number::value,MaxIndex::value >::value> SaveNumber; \
1368  typedef typename meta::TypeAtTypeList<FTypeList,SaveNumber::value>::type FunctionType; \
1369  return ValueFunctionProperties<PROPERTY, FunctionType>::op(gm-> template functions<SaveNumber::value>()[functionIndex])
1370 
1371  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,1>::value) {OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(0);}
1372  // special implementation if there are only two functions in the typelist
1373  if(meta::EqualNumber<NUMBER_OF_FUNCTIONS,2>::value) {
1374  if(functionType==0){OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(1);}
1375  else{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(2);}
1376  }
1377  // general case : 3 or more functions in the typelist
1378  if(meta::BiggerOrEqualNumber<NUMBER_OF_FUNCTIONS,3>::value) {
1379  switch(functionType) {
1380  case 0 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(0);}
1381  case 1 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(1);}
1382  case 2 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(2);}
1383  case 3 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(3);}
1384  case 4 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(4);}
1385  case 5 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(5);}
1386  case 6 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(6);}
1387  case 7 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(7);}
1388  case 8 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(8);}
1389  case 9 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(9);}
1390  case 10 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(10);}
1391  case 11 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(11);}
1392  case 12 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(12);}
1393  case 13 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(13);}
1394  case 14 :{OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(14);}
1395  case 15 :{ OPENGM_FWRAPPER_VALUE_PROPERTY_GEN_MACRO(15);}
1396  default:{
1397  //meta/template recursive "if-else" generation if the
1398  //function index is bigger than 15
1399  return FunctionWrapperExecutor<
1400  16,
1401  NUMBER_OF_FUNCTIONS,
1402  opengm::meta::BiggerOrEqualNumber<16,NUMBER_OF_FUNCTIONS >::value
1403  >:: template valueProperty <GM,PROPERTY> (gm,functionIndex,functionType);
1404  }
1405  }
1406  }
1407  #undef OPENGM_FWRAPPER_PROPERTY_GEN_MACRO
1408  }
1409 
1410 } // namespace detail_graphical_model
1411 
1413 
1414 } // namespace opengm
1415 
1416 #endif // #ifndef OPENGM_GRAPHICALMODEL_FUNCTION_WRAPPER_HXX
The OpenGM namespace.
Definition: config.hxx:43