OpenGM  2.3.x
Discrete Graphical Model Library
sum_constraint_function.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_SUM_CONSTRAINT_FUNCTION_HXX_
2 #define OPENGM_SUM_CONSTRAINT_FUNCTION_HXX_
3 
4 #include <cmath>
5 
6 #include <opengm/opengm.hxx>
10 
11 namespace opengm {
12 
13 /*********************
14  * class definition *
15  *********************/
16 template<class FUNCTION_TYPE, class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
17 class LPFunctionTransfer_impl;
18 
19 template<class VALUE_TYPE, class INDEX_TYPE = size_t, class LABEL_TYPE = size_t>
20 class SumConstraintFunction : public FunctionBase<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>, VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> {
21 public:
22  // typedefs
23  typedef VALUE_TYPE ValueType;
24  typedef INDEX_TYPE IndexType;
25  typedef LABEL_TYPE LabelType;
26 
27  // constructors
29  template <class SHAPE_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
30  SumConstraintFunction(SHAPE_ITERATOR_TYPE shapeBegin, SHAPE_ITERATOR_TYPE shapeEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, COEFFICIENTS_ITERATOR_TYPE coefficientsEnd, const bool shareCoefficients, const ValueType lambda = 1.0, const ValueType bound = 0.0);
31  template <class COEFFICIENTS_ITERATOR_TYPE>
32  SumConstraintFunction(const IndexType numVariables, const LabelType numLabels, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, COEFFICIENTS_ITERATOR_TYPE coefficientsEnd, const bool shareCoefficients, const ValueType lambda = 1.0, const ValueType bound = 0.0);
34 
35  // function access
36  template<class Iterator>
37  ValueType operator()(Iterator statesBegin) const; // function evaluation
38  size_t shape(const size_t i) const; // number of labels of the indicated input variable
39  size_t dimension() const; // number of input variables
40  size_t size() const; // number of parameters
41 
42 protected:
43  // storage
44  std::vector<LabelType> shape_;
45  size_t numVariables_;
47  LabelType maxNumLabels_;
48  size_t size_;
49  std::vector<ValueType> coefficients_;
51  std::vector<size_t> coefficientsOffsets_;
52  ValueType lambda_;
53  ValueType bound_;
54 
55  // friends
56  friend class FunctionSerialization<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >;
57  friend class LPFunctionTransfer_impl<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>, VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>;
58 };
59 
62 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
63 struct FunctionRegistration<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> > {
64  enum ID {
65  // TODO set final Id
67  };
68 };
69 
71 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
72 class FunctionSerialization<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> > {
73 public:
74  typedef typename SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::ValueType ValueType;
75 
76  static size_t indexSequenceSize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
77  static size_t valueSequenceSize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
78  template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
79  static void serialize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR);
80  template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
81  static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
82 };
84 
85 /***********************
86  * class documentation *
87  ***********************/
297 /******************
298  * implementation *
299  ******************/
300 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
302  : shape_(), numVariables_(), useSameNumLabels_(), maxNumLabels_(), size_(),
303  coefficients_(), shareCoefficients_(),
304  coefficientsOffsets_(), lambda_(), bound_() {
305 
306 }
307 
308 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
309 template <class SHAPE_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
310 inline SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::SumConstraintFunction(SHAPE_ITERATOR_TYPE shapeBegin, SHAPE_ITERATOR_TYPE shapeEnd, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, COEFFICIENTS_ITERATOR_TYPE coefficientsEnd, const bool shareCoefficients, const ValueType lambda, const ValueType bound)
311  : shape_(shapeBegin, shapeEnd), numVariables_(shape_.size()),
312  useSameNumLabels_(numVariables_ > 0 ? std::equal(shape_.begin() + 1, shape_.end(), shape_.begin()) : true),
313  maxNumLabels_(numVariables_ > 0 ? *std::max_element(shape_.begin(), shape_.end()) : 0),
314  size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<SHAPE_ITERATOR_TYPE>::value_type>())),
315  coefficients_(coefficientsBegin, coefficientsEnd),
316  shareCoefficients_(shareCoefficients), coefficientsOffsets_(),
317  lambda_(lambda), bound_(bound) {
318  if(shareCoefficients_) {
320  } else {
321  OPENGM_ASSERT(std::accumulate(shape_.begin(), shape_.end(), size_t(0), std::plus<size_t>()) == coefficients_.size());
323  // compute coefficients offsets
324  size_t currentOffset = 0;
325  for(size_t i = 0; i < numVariables_; ++i) {
326  coefficientsOffsets_[i] = currentOffset;
327  currentOffset += shape_[i];
328  }
329  }
330 }
331 
332 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
333 template <class COEFFICIENTS_ITERATOR_TYPE>
334 inline SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::SumConstraintFunction(const IndexType numVariables, const LabelType numLabels, COEFFICIENTS_ITERATOR_TYPE coefficientsBegin, COEFFICIENTS_ITERATOR_TYPE coefficientsEnd, const bool shareCoefficients, const ValueType lambda, const ValueType bound)
335  : shape_(), numVariables_(numVariables), useSameNumLabels_(true),
336  maxNumLabels_(numLabels),
337  size_(unsignedIntegerPow(maxNumLabels_, numVariables_)),
338  coefficients_(coefficientsBegin, coefficientsEnd),
339  shareCoefficients_(shareCoefficients), coefficientsOffsets_(),
340  lambda_(lambda), bound_(bound) {
341  if(shareCoefficients_) {
343  } else {
346  // compute coefficients offsets
347  size_t currentOffset = 0;
348  for(size_t i = 0; i < numVariables_; ++i) {
349  coefficientsOffsets_[i] = currentOffset;
350  currentOffset += maxNumLabels_;
351  }
352  }
353 }
354 
355 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
357 
358 }
359 
360 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
361 template<class Iterator>
363  ValueType sumConstraintViolation = -bound_;
364  if(shareCoefficients_) {
365  for(size_t i = 0; i < numVariables_; ++i) {
366  sumConstraintViolation += coefficients_[statesBegin[i]];
367  }
368  } else {
369  for(size_t i = 0; i < numVariables_; ++i) {
370  sumConstraintViolation += coefficients_[coefficientsOffsets_[i] + statesBegin[i]];
371  }
372  }
373  return std::abs(sumConstraintViolation) * lambda_;
374 }
375 
376 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
378  OPENGM_ASSERT(i < numVariables_);
379  if(useSameNumLabels_) {
380  return maxNumLabels_;
381  } else {
382  return shape_[i];
383  }
384 }
385 
386 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
388  return numVariables_;
389 }
390 
391 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
393  return size_;
394 }
395 
397 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
399  const size_t sameNumLabelsSize = 1;
400  const size_t numVariablesSize = 1;
401  const size_t shapeSize = src.useSameNumLabels_ ? 1 : src.shape_.size();
402  const size_t shareCoefficientsSize = 1;
403  const size_t coefficientsSize = 1;
404 
405  const size_t totalIndexSize = sameNumLabelsSize + numVariablesSize
406  + shapeSize + shareCoefficientsSize + coefficientsSize;
407  return totalIndexSize;
408 }
409 
410 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
411 inline size_t FunctionSerialization<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >::valueSequenceSize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>& src) {
412  const size_t coefficientsSize = src.coefficients_.size();
413  const size_t lambdaSize = 1;
414  const size_t boundSize = 1;
415 
416  const size_t totalValueSize = coefficientsSize + lambdaSize + boundSize;
417  return totalValueSize;
418 }
419 
420 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
421 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
422 inline void FunctionSerialization<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >::serialize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>& src, INDEX_OUTPUT_ITERATOR indexOutIterator, VALUE_OUTPUT_ITERATOR valueOutIterator) {
423  // index output
424  // shape
425  *indexOutIterator = static_cast<typename INDEX_OUTPUT_ITERATOR::value_type>(src.useSameNumLabels_);
426  ++indexOutIterator;
427  *indexOutIterator = src.numVariables_;
428  ++indexOutIterator;
429  if(src.useSameNumLabels_) {
430  *indexOutIterator = src.maxNumLabels_;
431  ++indexOutIterator;
432  } else {
433  for(size_t i = 0; i < src.shape_.size(); ++i) {
434  *indexOutIterator = src.shape_[i];
435  ++indexOutIterator;
436  }
437  }
438 
439  // share coefficients
440  *indexOutIterator = src.shareCoefficients_;
441  ++indexOutIterator;
442 
443  // coefficients size
444  *indexOutIterator = src.coefficients_.size();
445 
446  // value output
447  // coefficients
448  for(size_t i = 0; i <src.coefficients_.size(); ++i) {
449  *valueOutIterator = src.coefficients_[i];
450  ++valueOutIterator;
451  }
452 
453  // lambda
454  *valueOutIterator = src.lambda_;
455  ++valueOutIterator;
456 
457  // bound
458  *valueOutIterator = src.bound_;
459 }
460 
461 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
462 template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
463 inline void FunctionSerialization<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >::deserialize(INDEX_INPUT_ITERATOR indexInIterator, VALUE_INPUT_ITERATOR valueInIterator, SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>& dst) {
464  typedef VALUE_TYPE ValueType;
465  typedef INDEX_TYPE IndexType;
466 
467  // index input
468  // shape
469  const bool useSameNumLabels = *indexInIterator;
470  ++indexInIterator;
471  const IndexType numVariables = *indexInIterator;
472  ++indexInIterator;
473  INDEX_INPUT_ITERATOR shapeBegin = indexInIterator;
474  indexInIterator += (useSameNumLabels ? 1 : numVariables);
475  INDEX_INPUT_ITERATOR shapeEnd = indexInIterator;
476  // share coefficients
477  const bool shareCoefficients = *indexInIterator;
478  ++indexInIterator;
479  // coefficients size
480  const size_t numCoeffiecients = *indexInIterator;
481 
482  // value input
483  // coefficients
484  VALUE_INPUT_ITERATOR coefficientsBegin = valueInIterator;
485  VALUE_INPUT_ITERATOR coefficientsEnd = valueInIterator + numCoeffiecients;
486  valueInIterator += numCoeffiecients;
487 
488  // lambda
489  const ValueType lambda = *valueInIterator;
490  ++valueInIterator;
491 
492  // bound
493  const ValueType bound = *valueInIterator;
494 
495  if(useSameNumLabels) {
496  dst = SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(numVariables, *shapeBegin, coefficientsBegin, coefficientsEnd, shareCoefficients, lambda, bound);
497  } else {
498  dst = SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(shapeBegin, shapeEnd, coefficientsBegin, coefficientsEnd, shareCoefficients, lambda, bound);
499  }
500 }
502 
503 } // namespace opengm
504 
505 #endif /* OPENGM_SUM_CONSTRAINT_FUNCTION_HXX_ */
The OpenGM namespace.
Definition: config.hxx:43
Fallback implementation of member functions of OpenGM functions.
Provides implementation for the power function of unsigned integer values.
bool useSameNumLabels_
Tell if each variable of the function has the same number of labels.
STL namespace.
size_t unsignedIntegerPow(size_t base, size_t exponent)
Unsigned integer power function.
INDEX_TYPE IndexType
Typedef of the INDEX_TYPE template parameter type from the class SumConstraintFunction.
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
LABEL_TYPE LabelType
Typedef of the LABEL_TYPE template parameter type from the class SumConstraintFunction.
~SumConstraintFunction()
SumConstraintFunction destructor.
size_t size() const
Number of parameters.
size_t size_
Stores the size of the function.
std::vector< ValueType > coefficients_
The coefficients of the equality constraint.
size_t dimension() const
Number of input variables.
Default implementation for class opengm::LPFunctionTransfer.
ValueType bound_
The bound for the equality constraint.
ValueType operator()(Iterator statesBegin) const
Function evaluation.
const size_t FUNCTION_TYPE_ID_OFFSET
User-defined function have ids smaller than FUNCTION_TYPE_ID_OFFSET.
VALUE_TYPE ValueType
Typedef of the VALUE_TYPE template parameter type from the class SumConstraintFunction.
SumConstraintFunction()
SumConstraintFunction constructor.
size_t numVariables_
The number of variables of the function.
bool shareCoefficients_
Tell if the labels of the variables share the same coefficients.
A sum constraint function class penalizing the violation of a given linear equality constraint...
std::vector< size_t > coefficientsOffsets_
The Offsets of the SumConstraintFunction::coefficients_ indices for each variable. Only valid if SumConstraintFunction::shareCoefficients_ is set to false.
LabelType maxNumLabels_
The maximum number of labels of the variables.
size_t shape(const size_t i) const
Number of labels of the indicated input variable.
ValueType lambda_
The scaling factor for the violation of the equality constraint.
T abs(const T &x)
Definition: opengm.hxx:111
std::vector< LabelType > shape_
The shape of the function. Only valid if SumConstraintFunction::useSameNumLabels_ is set to false...