OpenGM  2.3.x
Discrete Graphical Model Library
pottsg.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_POTTS_G_FUNCTION_HXX
3 #define OPENGM_POTTS_G_FUNCTION_HXX
4 
5 #include <algorithm>
6 #include <vector>
7 
8 #include "opengm/opengm.hxx"
12 
13 namespace opengm {
14 
35 template<class T, class I=size_t, class L=size_t>
37 : public FunctionBase<PottsGFunction<T, I, L>, T, I, L>
38 {
39 public:
40  typedef T ValueType;
41  typedef I IndexType;
42  typedef L LabelType;
43 
45  template<class ITERATOR> PottsGFunction(ITERATOR, ITERATOR);
46  template<class ITERATOR, class ITERATOR2> PottsGFunction(ITERATOR, ITERATOR, ITERATOR2);
47  LabelType shape(const size_t) const;
48  size_t size() const;
49  size_t dimension() const;
50  template<class ITERATOR> ValueType operator()(ITERATOR) const;
51  bool isPotts() const;
52  bool isGeneralizedPotts() const;
53  template<class LABELITERATOR> void setByLabel(LABELITERATOR, T);
54  void setByPartition(size_t, T);
55 
56  static const size_t BellNumbers_[16];
57  static const size_t MaximalOrder_ = 11; // maximal order currently supported
58 
59 private:
60  std::vector<LabelType> shape_;
61  std::vector<ValueType> values_;
62  size_t size_;
63  mutable Partitions<size_t,size_t> P;
64 
65 friend class FunctionSerialization<PottsGFunction<T, I, L> > ;
66 };
67 
68 template<class T, class I, class L>
69 const size_t PottsGFunction<T, I, L>::BellNumbers_[16] = {1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, 27644437, 190899322, 1382958545};
70 
73 template<class T, class I, class L>
74 struct FunctionRegistration<PottsGFunction<T, I, L> > {
75  enum ID {
77  };
78 };
79 
81 template<class T, class I, class L>
82 class FunctionSerialization<PottsGFunction<T, I, L> > {
83 public:
84  typedef typename PottsGFunction<T, I, L>::ValueType ValueType;
85 
86  static size_t indexSequenceSize(const PottsGFunction<T, I, L> &);
87  static size_t valueSequenceSize(const PottsGFunction<T, I, L> &);
88  template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
89  static void serialize(const PottsGFunction<T, I, L> &, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR );
90  template<class INDEX_INPUT_ITERATOR , class VALUE_INPUT_ITERATOR>
91  static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, PottsGFunction<T, I, L> &);
92 };
94 
95 template<class T, class I, class L>
96 template<class ITERATOR>
97 inline
99 (
100  ITERATOR shapeBegin,
101  ITERATOR shapeEnd
102 )
103 : shape_(shapeBegin, shapeEnd),
104  size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<ITERATOR>::value_type >()))
105 {
106 
107  OPENGM_ASSERT(shape_.size() <= MaximalOrder_);
108  if(shape_.size()<=4){
109  values_.resize(BellNumbers_[shape_.size()], 0);
110  }else{
111  P.resize(shape_.size());
112  values_.resize(P.BellNumber(shape_.size()), 0);
113  }
114  OPENGM_ASSERT(BellNumbers_[shape_.size()] == values_.size());
115 }
116 
117 template<class T, class I, class L>
118 template<class ITERATOR, class ITERATOR2>
119 inline
121 (
122  ITERATOR shapeBegin,
123  ITERATOR shapeEnd,
124  ITERATOR2 valuesBegin
125 )
126 : shape_(shapeBegin, shapeEnd),
127  size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<ITERATOR>::value_type >()))
128 {
129  OPENGM_ASSERT(shape_.size() <= MaximalOrder_);
130  if(shape_.size()<=4){
131  values_.resize(BellNumbers_[shape_.size()]);
132  }else{
133  P.resize(shape_.size());
134  values_.resize(P.BellNumber(shape_.size()), 0);
135  }
136  for(size_t i=0; i<values_.size(); ++i) {
137  values_[i] = *valuesBegin;
138  ++valuesBegin;
139  }
140  OPENGM_ASSERT(BellNumbers_[shape_.size()] == values_.size());
141 
142 }
143 
144 template<class T, class I, class L>
145 inline
147 : shape_(),
148  size_(0)
149 {}
150 
151 template<class T, class I, class L>
152 template<class ITERATOR>
153 inline T
155 {
156  // Memory requirement for indexer
157  // order=2 1bit
158  // order=3 3bit
159  // order=4 6bit
160  // order=5 10bit
161  // order=6 11bit
162 
163  ValueType value;
164 
165  //Old code for order up to 4
166  if(shape_.size()<=4){
167  size_t indexer = 0;
168  size_t bit = 1;
169  for(size_t i=1; i<shape_.size(); ++i) {
170  for(size_t j=0; j<i; ++j) {
171  if(*(begin+i)==*(begin+j)) {
172  indexer += bit;
173  }
174  bit *= 2;
175  }
176  }
177  switch (indexer) {
178  case 0: value = values_[0]; break; //x_1!=x_2 && x_0!=x_2 && x_0!=x_1
179  case 1: value = values_[1]; break; //x_1!=x_2 && x_0!=x_2 && x_0==x_1
180  case 2: value = values_[2]; break; //x_1!=x_2 && x_0==x_2 && x_0!=x_1
181  //case 3: ERROR x_1!=x_2 && x_0==x_2 && x_0==x_1
182  case 4: value = values_[3]; break; //x_1==x_2 && x_0!=x_2 && x_0!=x_1
183  //case 5: ERROR x_1==x_2 && x_0!=x_2 && x_0==x_1
184  //case 6: ERROR x_1==x_2 && x_0==x_2 && x_0!=x_1
185  case 7: value = values_[4]; break; //x_1==x_2 && x_0==x_2 && x_0==x_1
186 
187  case 8: value = values_[5]; break; // x_2!=x_3 && x_1!=x_3 && x_0==x_3 && x_1!=x_2 && x_0!=x_2 && x_0!=x_1
188  case 12: value = values_[6]; break; // x_2!=x_3 && x_1!=x_3 && x_0==x_3 && x_1==x_2 && x_0!=x_2 && x_0!=x_1
189  case 16: value = values_[7]; break; // x_2!=x_3 && x_1==x_3 && x_0!=x_3 && x_1!=x_2 && x_0!=x_2 && x_0!=x_1
190  case 18: value = values_[8]; break; // x_2!=x_3 && x_1==x_3 && x_0!=x_3 && x_1!=x_2 && x_0==x_2 && x_0!=x_1
191  case 25: value = values_[9]; break; // x_2!=x_3 && x_1==x_3 && x_0==x_3 && x_1!=x_2 && x_0!=x_2 && x_0==x_1
192  case 32: value = values_[10]; break; // x_2==x_3 && x_1!=x_3 && x_0!=x_3 && x_1!=x_2 && x_0!=x_2 && x_0!=x_1
193  case 33: value = values_[11]; break; // x_2==x_3 && x_1!=x_3 && x_0!=x_3 && x_1!=x_2 && x_0!=x_2 && x_0==x_1
194  case 42: value = values_[12]; break; // x_2==x_3 && x_1!=x_3 && x_0==x_3 && x_1!=x_2 && x_0==x_2 && x_0!=x_1
195  case 52: value = values_[13]; break; // x_2==x_3 && x_1==x_3 && x_0==x_3 && x_1==x_2 && x_0!=x_2 && x_0!=x_1
196  case 63: value = values_[14]; break; // x_2==x_3 && x_1==x_3 && x_0==x_3 && x_1==x_2 && x_0==x_2 && x_0==x_1
197  default: value = 0;
198  }
199  }
200  else{//new code for larger orders
201  const size_t n = P.label2Index(begin, shape_.size());
202  value = values_[n];
203  }
204  return value;
205 }
206 
207 template<class T, class I, class L>
208 template<class LABELITERATOR>
209 void PottsGFunction<T, I, L>::setByLabel(LABELITERATOR it, T value)
210 {
211  if(shape_.size()<=4){
212  size_t indexer = 0;
213  size_t bit = 1;
214  for(size_t i=1; i<shape_.size(); ++i) {
215  for(size_t j=0; j<i; ++j) {
216  if(*(it+i)==*(it+j)) indexer += bit;
217  bit *= 2;
218  }
219  }
220  setByPartition(indexer, value);
221  }
222  else{
223  size_t n = P.label2Index(it,shape_.size());
224  values_[n] = value;
225  }
226 }
227 
228 template<class T, class I, class L>
229 void PottsGFunction<T, I, L>::setByPartition(size_t partition, T value)
230 {
231  if(shape_.size()<=4){
232  switch(partition) {
233  case 0: values_[0] = value; break; //x_1!=x_2 && x_0!=x_2 && x_i!=x_j
234  case 1: values_[1] = value; break; //x_1!=x_2 && x_0!=x_2 && x_0==x_1
235  case 2: values_[2] = value; break; //x_1!=x_2 && x_0!=x_2 && x_0==x_2
236  //case 3: ERROR x_1!=x_2 && x_0==x_2 && x_0==x_1
237  case 4: values_[3] = value; break; //x_1==x_2 && x_0!=x_2 && x_0!=x_1
238  //case 5: ERROR x_1==x_2 && x_0!=x_2 && x_0==x_1
239  //case 6: ERROR x_1==x_2 && x_0==x_2 && x_0!=x_1
240  case 7: values_[4] = value; break; //x_1==x_2 && x_0==x_2 && x_0==x_1
241  case 8: values_[5] = value; break; // x_2!=x_3 && x_1!=x_3 && x_0==x_3 && x_1!=x_2 && x_0!=x_2 && x_0!=x_1
242  case 12: values_[6] = value; break; // x_2!=x_3 && x_1!=x_3 && x_0==x_3 && x_1==x_2 && x_0!=x_2 && x_0!=x_1
243  case 16: values_[7] = value; break; // x_2!=x_3 && x_1==x_3 && x_0!=x_3 && x_1!=x_2 && x_0!=x_2 && x_0!=x_1
244  case 18: values_[8] = value; break; // x_2!=x_3 && x_1==x_3 && x_0!=x_3 && x_1!=x_2 && x_0==x_2 && x_0!=x_1
245  case 25: values_[9] = value; break; // x_2!=x_3 && x_1==x_3 && x_0==x_3 && x_1!=x_2 && x_0!=x_2 && x_0==x_1
246  case 32: values_[10] = value; break; // x_2==x_3 && x_1!=x_3 && x_0!=x_3 && x_1!=x_2 && x_0!=x_2 && x_0!=x_1
247  case 33: values_[11] = value; break; // x_2==x_3 && x_1!=x_3 && x_0!=x_3 && x_1!=x_2 && x_0!=x_2 && x_0==x_1
248  case 42: values_[12] = value; break; // x_2==x_3 && x_1!=x_3 && x_0==x_3 && x_1!=x_2 && x_0==x_2 && x_0!=x_1
249  case 52: values_[13] = value; break; // x_2==x_3 && x_1==x_3 && x_0!=x_3 && x_1==x_2 && x_0!=x_2 && x_0!=x_1
250  case 63: values_[14] = value; break; // x_2==x_3 && x_1==x_3 && x_0==x_3 && x_1==x_2 && x_0==x_2 && x_0==x_1
251  default: OPENGM_ASSERT(false);
252  }
253  }
254  else{
255  size_t n = P.number2Index(partition);
256  values_[n] = value;
257  }
258 }
259 
260 template<class T, class I, class L>
263 (
264  const size_t i
265 ) const
266 {
267  OPENGM_ASSERT(i < shape_.size());
268  return shape_[i];
269 }
270 
271 template<class T, class I, class L>
272 inline size_t
274 {
275  return shape_.size();
276 }
277 
278 template<class T, class I, class L>
279 inline size_t
281  return size_;
282 }
283 
284 template<class T, class I, class L>
285 inline bool
287 {
288  bool t = true;
289  for(size_t i=1; i<values_.size()-1; ++i)
290  t &= values_[0] == values_[i];
291  return t;
292 }
293 
294 template<class T, class I, class L>
295 inline bool
297 {
298  return true;
299 }
300 
301 template<class T, class I, class L>
302 inline size_t
304 (
305  const PottsGFunction<T, I, L> & src
306 ) {
307  return src.dimension()+1;
308 }
309 
310 template<class T, class I, class L>
311 inline size_t
312 FunctionSerialization<PottsGFunction<T, I, L> >::valueSequenceSize
313 (
314  const PottsGFunction<T, I, L> & src
315 ) {
316  return src.values_.size();
317 }
318 
319 template<class T, class I, class L>
320 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
321 inline void
322 FunctionSerialization<PottsGFunction<T, I, L> >::serialize
323 (
324  const PottsGFunction<T, I, L> & src,
325  INDEX_OUTPUT_ITERATOR indexOutIterator,
326  VALUE_OUTPUT_ITERATOR valueOutIterator
327 ) {
328  const size_t dim = src.dimension();
329  *indexOutIterator = dim;
330  ++indexOutIterator;
331  for(size_t i=0; i<dim; ++i) {
332  *indexOutIterator = src.shape(i);
333  ++indexOutIterator;
334  }
335  for(size_t i=0; i<src.values_.size(); ++i) {
336  *valueOutIterator = src.values_[i];
337  ++valueOutIterator;
338  }
339 }
340 
341 template<class T, class I, class L>
342 template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR >
343 inline void
344 FunctionSerialization<PottsGFunction<T, I, L> >::deserialize
345 (
346  INDEX_INPUT_ITERATOR indexInIterator,
347  VALUE_INPUT_ITERATOR valueInIterator,
348  PottsGFunction<T, I, L> & dst
349 ) {
350  const size_t dim=*indexInIterator;
351  ++indexInIterator;
352  std::vector<size_t> shape(dim);
353  std::vector<T> values(dst.BellNumbers_[dim]);
354  for(size_t i=0; i<dim; ++i) {
355  shape[i]=*indexInIterator;
356  ++indexInIterator;
357  }
358  for(size_t i=0; i<values.size(); ++i) {
359  values[i] = *valueInIterator;
360  ++valueInIterator;
361  }
362  dst = PottsGFunction<T, I, L>(shape.begin(), shape.end(), values.begin());
363 }
364 
365 } // namespace opengm
366 
367 #endif // #ifndef OPENGM_POTTS_G_FUNCTION_HXX
The OpenGM namespace.
Definition: config.hxx:43
Fallback implementation of member functions of OpenGM functions.
bool isPotts() const
Definition: pottsg.hxx:286
size_t dimension() const
Definition: pottsg.hxx:273
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
ValueType operator()(ITERATOR) const
const size_t FUNCTION_TYPE_ID_OFFSET
User-defined function have ids smaller than FUNCTION_TYPE_ID_OFFSET.
void setByPartition(size_t, T)
Definition: pottsg.hxx:229
bool isGeneralizedPotts() const
Definition: pottsg.hxx:296
static const size_t MaximalOrder_
Definition: pottsg.hxx:57
Generalized Potts Function.
Definition: pottsg.hxx:36
LabelType shape(const size_t) const
Definition: pottsg.hxx:263
void setByLabel(LABELITERATOR, T)
Definition: pottsg.hxx:209
size_t size() const
Definition: pottsg.hxx:280
static const size_t BellNumbers_[16]
Definition: pottsg.hxx:56