OpenGM  2.3.x
Discrete Graphical Model Library
accumulator.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_FUNCTION_LEVEL_ACCUMULATOR_HXX
3 #define OPENGM_FUNCTION_LEVEL_ACCUMULATOR_HXX
4 
9 
10 namespace opengm {
11 
13 
15 template<class A, class B, class ACC>
16 class AccumulateAllImpl {
17  typedef typename A::LabelType LabelType;
18  typedef typename A::ValueType ValueType;
19 
20 public:
21  static void op(const A&, B&);
22  static void op(const A&, B&, std::vector<LabelType>& state);
23 };
24 
26 template<class A, class B, class ACC>
27 class AccumulateSomeImpl {
28  typedef typename A::LabelType LabelType;
29  typedef typename A::IndexType IndexType;
30  typedef typename A::ValueType ValueType;
31  typedef std::vector<IndexType> ViSequenceType;
32 
33 public:
34  template<class Iterator,class VIS_A,class VIS_B>
35  static void op(const A&, const VIS_A &, Iterator, Iterator, B&, VIS_B&);
36 };
37 
39 template<class A, class ACC>
40 class AccumulateSomeInplaceImpl {
41  typedef typename A::LabelType LabelType;
42  typedef typename A::IndexType IndexType;
43  typedef typename A::ValueType ValueType;
44  typedef std::vector<IndexType> ViSequenceType;
45 
46 public:
47  template<class Iterator>
48  static void op(A&, ViSequenceType&, Iterator, Iterator);
49 };
50 
52 template<class A, class B, class ACC>
53 void AccumulateAllImpl<A, B, ACC>::op
54 (
55  const A& a,
56  B& b
57 ) {
58  OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
59  opengm::Accumulation<ValueType, LabelType, ACC> acc;
60  const size_t dimA = a.dimension();
61  const size_t numElement = a.size();
62  if(dimA != 0) {
63  typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
64  ShapeIterType shapeABegin(a, 0);
65  opengm::ShapeWalker< ShapeIterType> shapeWalker(shapeABegin, dimA);
66  const opengm::FastSequence<size_t> & coordinate = shapeWalker.coordinateTuple();
67  for(size_t i=0; i<numElement ; ++i) {
68  acc(a(coordinate.begin()));
69  ++shapeWalker;
70  }
71  }
72  else {
73  size_t indexSequenceToScalar[] = {0};
74  acc(a(indexSequenceToScalar));
75  }
76  b = static_cast<B>(acc.value());
77 }
78 
80 template<class A, class B, class ACC>
81 void AccumulateAllImpl<A, B, ACC>::op
82 (
83  const A& a,
84  B& b,
85  std::vector<typename AccumulateAllImpl<A, B, ACC>::LabelType>& state
86 ) {
87  OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
88  opengm::Accumulation<ValueType, LabelType, ACC> acc;
89  const size_t dimA = a.dimension();
90  const size_t numElement = a.size();
91  if(dimA != 0) {
92  state.resize(dimA);
93  typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
94  ShapeIterType shapeABegin(a, 0);
95  opengm::ShapeWalker< ShapeIterType> shapeWalker(shapeABegin, dimA);
96  const opengm::FastSequence<size_t> & coordinate = shapeWalker.coordinateTuple();
97  for(size_t i=0; i<numElement; ++i) {
98  acc(a(coordinate.begin()), coordinate);
99  ++shapeWalker;
100  }
101  acc.state(state);
102  }
103  else {
104  size_t indexSequenceToScalar[] = {0};
105  acc(a(indexSequenceToScalar));
106  state.clear();
107  }
108  b = static_cast<B>(acc.value());
109 }
110 
112 template<class A, class B, class ACC>
113 template<class Iterator,class VIS_A,class VIS_B>
114 void AccumulateSomeImpl<A, B, ACC>::op
115 (
116  const A& a,
117  const VIS_A & viA,
118  Iterator viAccBegin,
119  Iterator viAccEnd,
120  B& b,
121  VIS_B & viB
122 ) {
123  OPENGM_ASSERT(a.dimension() == viA.size());
124  OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
125  const size_t dimA = a.dimension();
126  viB.clear();
127  b.assign();
128  if(dimA != 0) {
129  size_t rawViSize = std::distance(viAccBegin, viAccEnd);
132  opengm::FastSequence<size_t> shapeNotAcc;
133  opengm::FastSequence<size_t> notAccPosition;
134  for(size_t i=0; i <dimA; ++i) {
135  bool found = false;
136  for(size_t j=0; j < rawViSize; ++j) {
137  if(static_cast<opengm::UInt64Type>(viA[i]) == static_cast<opengm::UInt64Type>(viAccBegin[j])) {
138  viAcc.push_back(viAccBegin[j]);
139  shapeAcc.push_back(a.shape(i));
140  found = true;
141  break;
142  }
143  }
144  if(!found) {
145  viB.push_back(viA[i]);
146  shapeNotAcc.push_back(a.shape(i));
147  notAccPosition.push_back(i);
148  }
149  }
150  if(shapeAcc.size() == dimA) {
151  // accumulate over all variables ???
152  ValueType scalarAccResult;
153  AccumulateAllImpl<A, ValueType, ACC>::op(a, scalarAccResult);
154  size_t indexSequenceToScalar[] = {0};
155  size_t shapeToScalarArray[] = {0};
156  b.resize(shapeToScalarArray, shapeToScalarArray);
157  b(indexSequenceToScalar) = scalarAccResult;
158  }
159  else if(shapeAcc.size() == 0) {
160  // accumulate over no variable
161  // ==> copy function
162  b.resize(shapeNotAcc.begin(), shapeNotAcc.end());
163  opengm::ShapeWalker< opengm::FastSequence<size_t>::const_iterator> shapeWalker(shapeNotAcc.begin(), dimA);
164  const opengm::FastSequence<size_t> & coordinate = shapeWalker.coordinateTuple();
165  for(size_t i=0; i <a.size() ; ++i) {
166  b(coordinate.begin()) = a(coordinate.begin());
167  ++shapeWalker;
168  }
169  viB.assign(viA.begin(),viA.end());
170  }
171  else {
172  // resize dstFactor
173  b.resize(shapeNotAcc.begin(), shapeNotAcc.end());
174  // create a shapeWalker to walk over NOTACC:
175  opengm::ShapeWalker< opengm::FastSequence<size_t>::const_iterator> walker(shapeNotAcc.begin(), shapeNotAcc.size());
176  const opengm::FastSequence<size_t> & coordinateNotAcc = walker.coordinateTuple();
177  // create a subshape walker to walker over ACC
178  typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
179  ShapeIterType shapeABegin(a, 0);
180  SubShapeWalker< ShapeIterType ,opengm::FastSequence<size_t>,opengm::FastSequence<size_t> >
181  subWalker(shapeABegin, dimA, notAccPosition, coordinateNotAcc);
182  const size_t subSizeAcc = subWalker.subSize();
183  // loop over variables we don't want to accumulate over
184  for(size_t i=0; i<b.size(); ++i) {
185  // loop over the variables we want to accumulate over
186  // create an accumulator
187  Accumulation<ValueType, LabelType, ACC> acc;
188  subWalker.resetCoordinate();
189  for(size_t j=0; j < subSizeAcc; ++j) {
190  acc(a( subWalker.coordinateTuple().begin()));
191  ++subWalker;
192  }
193  b(coordinateNotAcc.begin()) = acc.value();
194  ++walker;
195  }
196  }
197  }
198  else {
199  Accumulation<ValueType, LabelType, ACC> acc;
200  size_t indexSequenceToScalar[] = {0};
201  ValueType accRes=static_cast<ValueType>(0.0);
202  acc(accRes);
203  size_t shapeToScalarArray[] = {0};
204  b.resize(shapeToScalarArray, shapeToScalarArray);
205  b(indexSequenceToScalar) = acc.value();
206  }
207  OPENGM_ASSERT(b.dimension() == viB.size());
208  OPENGM_ASSERT(b.dimension() != 0 || (b.dimension() == 0 && b.size() == 1));
209 }
210 
212 template<class A, class ACC>
213 template<class Iterator>
214 void AccumulateSomeInplaceImpl<A, ACC>::op
215 (
216  A& a,
217  ViSequenceType& viA,
218  Iterator viAccBegin,
219  Iterator viAccEnd
220 ) {
221  OPENGM_ASSERT(a.dimension() == viA.size());
222  OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
223  const size_t dimA = a.dimension();
225  if(dimA != 0) {
226  const size_t rawViSize = std::distance(viAccBegin, viAccEnd);
229  opengm::FastSequence<size_t> shapeNotAcc;
230  opengm::FastSequence<size_t> notAccPosition;
231  for(size_t i = 0; i <dimA; ++i) {
232  bool found = false;
233  for(size_t j=0; j < rawViSize; ++j) {
234  if( static_cast<UInt64Type>(viA[i]) == static_cast<UInt64Type>(viAccBegin[j])) {
235  viAcc.push_back(viAccBegin[j]);
236  shapeAcc.push_back(a.shape(i));
237  found = true;
238  break;
239  }
240  }
241  if(!found) {
242  viB.push_back(viA[i]);
243  shapeNotAcc.push_back(a.shape(i));
244  notAccPosition.push_back(i);
245  }
246  }
247  if(shapeAcc.size() == dimA) {
248  // accumulate over all variables
249  ValueType scalarAccResult;
250  AccumulateAllImpl<A, ValueType, ACC>::op(a, scalarAccResult);
251  a.assign();
252  size_t shapeToScalarArray[] = {0};
253  a.resize(shapeToScalarArray, shapeToScalarArray);
254  a(shapeToScalarArray) = scalarAccResult;
255  viA.clear();
256  }
257  else if(shapeAcc.size() == 0) {
258  // accumulate over no variable
259  // do nothing
260  }
261  else {
262  // resize dstFactor
263  A b;
264  b.resize(shapeNotAcc.begin(), shapeNotAcc.end());
265  // create a shapeWalker to walk over NOTACC:
266  opengm::ShapeWalker< typename opengm::FastSequence<size_t>::const_iterator> walker(shapeNotAcc.begin(), shapeNotAcc.size());
267  const opengm::FastSequence<size_t> & coordinateNotAcc = walker.coordinateTuple();
268  // create a subshape walker to walker over ACC
269  typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>, true> ShapeIterType;
270  ShapeIterType shapeABegin(a, 0);
271  SubShapeWalker< ShapeIterType,opengm::FastSequence<size_t> ,opengm::FastSequence<size_t> >
272  subWalker(shapeABegin, dimA, notAccPosition, coordinateNotAcc);
273  const size_t subSizeAcc = subWalker.subSize();
274  // loop over variables we don't want to accumulate
275  for(size_t i=0; i < b.size(); ++i) {
276  // loop over the variables we want to accumulate
277  // create an accumulator
278  Accumulation<ValueType, LabelType, ACC> acc;
279  subWalker.resetCoordinate();
280  for(size_t j=0; j<subSizeAcc; ++j) {
281  acc(a(subWalker.coordinateTuple().begin()));
282  ++subWalker;
283  }
284  b(coordinateNotAcc.begin()) = acc.value();
285  ++walker;
286  }
287  a = b;
288  viA.assign(viB.begin(),viB.end());
289  }
290  }
291  else {
292  Accumulation<ValueType, LabelType, ACC> acc;
293  ValueType accRes=static_cast<ValueType>(0.0);
294  acc(accRes);
295  a.assign();
296  a(0) = acc.value();
297  }
298  OPENGM_ASSERT(a.dimension() == viA.size());
299  OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
300 }
301 
302 } // namespace opengm
303 
305 
306 #endif // OPENGM_FUNCTION_LEVEL_ACCUMULATOR_HXX
The OpenGM namespace.
Definition: config.hxx:43
void assign(ITERATOR, ITERATOR)
assign values
size_t size() const
size
void push_back(const T &)
append a value
Vector that stores values on the stack if size is smaller than MAX_STACK.
T const * end() const
end iterator
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
T const * begin() const
begin iterator