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