OpenGM  2.3.x
Discrete Graphical Model Library
graphicalmodel_factor_accumulator.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_ACCUMULATIONWRAPPER_HXX
3 #define OPENGM_ACCUMULATIONWRAPPER_HXX
4 
7 
8 namespace opengm {
9 
11 
12 namespace functionwrapper {
13 
14  struct FactorFlag;
15  struct IndependentFactorFlag;
16  struct IndependentFactorOrFactorFlag;
17  struct ScalarFlag;
18  struct ErrorFlag;
19 
20  namespace executor {
21 
22  template<class A, class B, class ACC, size_t IX, size_t DX, bool END>
23  class AccumulateAllExecutor;
24 
25  template<class A, class B, class ACC, size_t IX, size_t DX>
26  class AccumulateAllExecutor<A, B, ACC, IX, DX, false> {
27  public:
28  static inline void op
29  (
30  const A& a,
31  B& b,
32  const size_t rtia
33  ) {
34  if(rtia==IX) {
35  typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
36  const FunctionTypeA& fa = meta::GetFunction<A, IX>::get(a);
37  typedef opengm::AccumulateAllImpl<FunctionTypeA, B, ACC> AccumulationType;
38  AccumulationType::op(fa, b);
39  }
40  else {
41  typedef AccumulateAllExecutor<A, B, ACC, IX+1, DX, meta::Bool<IX+1==DX>::value > NewExecutorType;
42  NewExecutorType::op(a, b, rtia);
43  }
44  };
45 
46  static inline void op
47  (
48  const A & a,
49  B & b,
50  std::vector<typename A::LabelType> & state,
51  const size_t rtia
52  ) {
53  if(rtia==IX) {
54  typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
55  const FunctionTypeA& fa = meta::GetFunction<A, IX>::get(a);
56  typedef opengm::AccumulateAllImpl<FunctionTypeA, B, ACC> AccumulationType;
57  AccumulationType::op(fa, b,state);
58  }
59  else {
60  typedef AccumulateAllExecutor<A, B, ACC, IX+1, DX, meta::Bool<IX+1==DX>::value> NewExecutorType;
61  NewExecutorType::op(a, b, state, rtia);
62  }
63  }
64  };
65 
66  template<class A, class B, class ACC, size_t IX, size_t DX>
67  class AccumulateAllExecutor<A, B, ACC, IX, DX, true> {
68  public:
69  typedef std::vector<size_t> ViType;
70 
71  static inline void op
72  (
73  const A & a,
74  B & b,
75  const size_t rtia
76  ) {
77  throw RuntimeError("wrong function id");
78  };
79  template<class INDEX_TYPE>
80  static inline void op
81  (
82  const A & a,
83  B & b,
84  std::vector<INDEX_TYPE> & state,
85  const size_t rtia
86  ) {
87  throw RuntimeError("wrong function id");
88  }
89  };
90 
91  template<class A, class B, class ACC, size_t IX, size_t DX, bool END>
92  class AccumulateSomeExecutor;
93 
94  template<class A, class B, class ACC, size_t IX, size_t DX>
95  class AccumulateSomeExecutor<A, B, ACC, IX, DX, false>
96  {
97  public:
98  typedef typename A::VisContainerType ViTypeA;
99  typedef typename B::VisContainerType ViTypeB;
100 
101  template<class ViAccIter>
102  static void op
103  (
104  const A & a,
105  ViAccIter beginViAcc,
106  ViAccIter endViAcc,
107  B & b,
108  const size_t rtia
109  ) {
110  if(rtia==IX) {
111  typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
112  typedef typename meta::GetFunction<B, 0>::FunctionType FunctionTypeB;
113  const FunctionTypeA & fa=meta::GetFunction<A, IX>::get(a);
114  FunctionTypeB & fb=meta::GetFunction<B, 0>::get(b);
115  const ViTypeA & viA=a.variableIndexSequence();
116  ViTypeB & viB=b.variableIndexSequence();
117  typedef opengm::AccumulateSomeImpl<FunctionTypeA, FunctionTypeB, ACC> AccumulationType;
118  AccumulationType::op(fa, viA, beginViAcc, endViAcc, fb, viB);
119  }
120  else{
121  typedef AccumulateSomeExecutor<A, B, ACC, IX+1, DX, meta::Bool<IX+1==DX>::value > NewExecutorType;
122  NewExecutorType::op(a, beginViAcc, endViAcc, b, rtia);
123  }
124  }
125  };
126 
127  template<class A, class B, class ACC, size_t IX, size_t DX>
128  class AccumulateSomeExecutor<A, B, ACC, IX, DX, true> {
129  public:
130  //typedef std::vector<size_t> ViType;
131  typedef typename A::VisContainerType ViTypeA;
132  typedef typename B::VisContainerType ViTypeB;
133  template<class ViAccIter>
134  static void op
135  (
136  const A & a,
137  ViAccIter beginViAcc ,
138  ViAccIter endViAcc,
139  B & b,
140  const size_t rtia
141  ) {
142  throw RuntimeError("wrong function id");
143  }
144  };
145 
146  } // namespace executor
147 
148  template<class A, class B, class ACC>
149  class AccumulateAllWrapper {
150  public:
151  static void op
152  (
153  const A & a,
154  B & b
155  ) {
156  typedef typename meta::EvalIf
157  <
158  meta::IsIndependentFactor<A>::value,
159  meta::Self<meta::SizeT<1> >,
160  meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
161  >::type NFA;
162  typedef executor::AccumulateAllExecutor<A, B, ACC, 0, NFA::value, NFA::value==0> ExecutorType;
163  ExecutorType::op(a, b, opengm::meta::GetFunctionTypeIndex<A>::get(a));
164  }
165 
166  template<class LABEL_TYPE>
167  static void op
168  (
169  const A & a,
170  B & b,
171  std::vector<LABEL_TYPE> & state
172  ) {
173  typedef typename meta::EvalIf
174  <
175  meta::IsIndependentFactor<A>::value,
176  meta::Self<meta::SizeT<1> >,
177  meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
178  >::type NFA;
179  typedef executor::AccumulateAllExecutor<A, B, ACC, 0, NFA::value, NFA::value==0> ExecutorType;
180  ExecutorType::op
181  (a, b, state, opengm::meta::GetFunctionTypeIndex<A>::get(a));
182  }
183  };
184 
185  template<class A, class B, class ACC>
186  class AccumulateSomeWrapper {
187  typedef typename A::VisContainerType ViTypeA;
188  typedef typename B::VisContainerType ViTypeB;
189 
190  public:
191  template<class ViAccIter>
192  static void op(
193  const A& a,
194  ViAccIter beginViAcc,
195  ViAccIter endViAcc,
196  B& b
197  ) {
198  //const ViType & viA=a.variableIndexSequence();
199  //ViType & viB = b.variableIndexSequence(); // initialize references
200  typedef typename meta::EvalIf
201  <
202  meta::IsIndependentFactor<A>::value,
203  meta::Self<meta::SizeT<1> >,
204  meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
205  >::type NFA;
206  typedef executor::AccumulateSomeExecutor<A, B, ACC, 0, NFA::value, NFA::value==0> ExecutorType;
207  ExecutorType::op (a, beginViAcc, endViAcc, b, opengm::meta::GetFunctionTypeIndex<A>::get(a));
208  }
209  };
210 
211 } // namespace functionwrapper
212 
213 template<class ACC, class A, class B>
214 inline void accumulate
215 (
216  const A & a,
217  B & b
218 ) {
219  functionwrapper::AccumulateAllWrapper<A, B, ACC>::op(a, b);
220 }
221 
222 template<class ACC, class A, class B,class INDEX_TYPE>
223 inline void accumulate
224 (
225  const A & a,
226  B & b,
227  std::vector<INDEX_TYPE> & state
228 ) {
229  functionwrapper::AccumulateAllWrapper<A, B, ACC>::op(a, b, state);
230 }
231 
232 template<class ACC, class A, class ViAccIterator, class B>
233 inline void accumulate
234 (
235  const A & a,
236  ViAccIterator viAccBegin,
237  ViAccIterator viAccEnd,
238  B & b
239 ) {
240  functionwrapper::AccumulateSomeWrapper<A, B, ACC>::op(a, viAccBegin, viAccEnd, b);
241 }
242 
243 template<class ACC, class A, class ViAccIterator>
244 inline void accumulate
245 (
246  A & a,
247  ViAccIterator viAccBegin,
248  ViAccIterator viAccEnd
249 ) {
250  opengm::AccumulateSomeInplaceImpl<typename A::FunctionType, ACC>::op(opengm::meta::GetFunction<A,0>::get(a), a.variableIndexSequence(), viAccBegin, viAccEnd);
251 }
252 
254 
255 } // end namespace opengm
256 
257 #endif // #ifndef OPENGM_ACCUMULATIONWRAPPER_HXX
The OpenGM namespace.
Definition: config.hxx:43