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 #include <functional>
6 
7 #include <opengm/opengm.hxx>
11 
12 namespace opengm {
13 
14 /*********************
15  * class definition *
16  *********************/
17 template<class FUNCTION_TYPE, class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
18 class LPFunctionTransfer_impl;
19 
20 template<class VALUE_TYPE, class INDEX_TYPE = size_t, class LABEL_TYPE = size_t>
21 class SumConstraintFunction : public FunctionBase<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>, VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> {
22 public:
23  // typedefs
24  typedef VALUE_TYPE ValueType;
25  typedef INDEX_TYPE IndexType;
26  typedef LABEL_TYPE LabelType;
27 
28  // constructors
30  template <class SHAPE_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
31  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);
32  template <class COEFFICIENTS_ITERATOR_TYPE>
33  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);
35 
36  // function access
37  template<class Iterator>
38  ValueType operator()(Iterator statesBegin) const; // function evaluation
39  size_t shape(const size_t i) const; // number of labels of the indicated input variable
40  size_t dimension() const; // number of input variables
41  size_t size() const; // number of parameters
42 
43 protected:
44  // storage
45  std::vector<LabelType> shape_;
46  size_t numVariables_;
48  LabelType maxNumLabels_;
49  size_t size_;
50  std::vector<ValueType> coefficients_;
52  std::vector<size_t> coefficientsOffsets_;
53  ValueType lambda_;
54  ValueType bound_;
55 
56  // friends
57  friend class FunctionSerialization<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >;
58  friend class LPFunctionTransfer_impl<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>, VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>;
59 };
60 
63 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
64 struct FunctionRegistration<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> > {
65  enum ID {
66  // TODO set final Id
68  };
69 };
70 
72 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
73 class FunctionSerialization<SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> > {
74 public:
76 
77  static size_t indexSequenceSize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
78  static size_t valueSequenceSize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
79  template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
80  static void serialize(const SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR);
81  template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
82  static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
83 };
85 
86 /***********************
87  * class documentation *
88  ***********************/
298 /******************
299  * implementation *
300  ******************/
301 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
306 
307 }
308 
309 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
310 template <class SHAPE_ITERATOR_TYPE, class COEFFICIENTS_ITERATOR_TYPE>
311 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)
312  : shape_(shapeBegin, shapeEnd), numVariables_(shape_.size()),
313  useSameNumLabels_(numVariables_ > 0 ? std::equal(shape_.begin() + 1, shape_.end(), shape_.begin()) : true),
314  maxNumLabels_(numVariables_ > 0 ? *std::max_element(shape_.begin(), shape_.end()) : 0),
315  size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<SHAPE_ITERATOR_TYPE>::value_type>())),
316  coefficients_(coefficientsBegin, coefficientsEnd),
317  shareCoefficients_(shareCoefficients), coefficientsOffsets_(),
318  lambda_(lambda), bound_(bound) {
319  if(shareCoefficients_) {
321  } else {
322  OPENGM_ASSERT(std::accumulate(shape_.begin(), shape_.end(), size_t(0), std::plus<size_t>()) == coefficients_.size());
324  // compute coefficients offsets
325  size_t currentOffset = 0;
326  for(size_t i = 0; i < numVariables_; ++i) {
327  coefficientsOffsets_[i] = currentOffset;
328  currentOffset += shape_[i];
329  }
330  }
331 }
332 
333 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
334 template <class COEFFICIENTS_ITERATOR_TYPE>
335 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)
336  : shape_(), numVariables_(numVariables), useSameNumLabels_(true),
337  maxNumLabels_(numLabels),
339  coefficients_(coefficientsBegin, coefficientsEnd),
340  shareCoefficients_(shareCoefficients), coefficientsOffsets_(),
341  lambda_(lambda), bound_(bound) {
342  if(shareCoefficients_) {
344  } else {
347  // compute coefficients offsets
348  size_t currentOffset = 0;
349  for(size_t i = 0; i < numVariables_; ++i) {
350  coefficientsOffsets_[i] = currentOffset;
351  currentOffset += maxNumLabels_;
352  }
353  }
354 }
355 
356 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
358 
359 }
360 
361 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
362 template<class Iterator>
364  ValueType sumConstraintViolation = -bound_;
365  if(shareCoefficients_) {
366  for(size_t i = 0; i < numVariables_; ++i) {
367  sumConstraintViolation += coefficients_[statesBegin[i]];
368  }
369  } else {
370  for(size_t i = 0; i < numVariables_; ++i) {
371  sumConstraintViolation += coefficients_[coefficientsOffsets_[i] + statesBegin[i]];
372  }
373  }
374  return std::abs(sumConstraintViolation) * lambda_;
375 }
376 
377 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
380  if(useSameNumLabels_) {
381  return maxNumLabels_;
382  } else {
383  return shape_[i];
384  }
385 }
386 
387 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
389  return numVariables_;
390 }
391 
392 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
394  return size_;
395 }
396 
398 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
400  const size_t sameNumLabelsSize = 1;
401  const size_t numVariablesSize = 1;
402  const size_t shapeSize = src.useSameNumLabels_ ? 1 : src.shape_.size();
403  const size_t shareCoefficientsSize = 1;
404  const size_t coefficientsSize = 1;
405 
406  const size_t totalIndexSize = sameNumLabelsSize + numVariablesSize
407  + shapeSize + shareCoefficientsSize + coefficientsSize;
408  return totalIndexSize;
409 }
410 
411 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
413  const size_t coefficientsSize = src.coefficients_.size();
414  const size_t lambdaSize = 1;
415  const size_t boundSize = 1;
416 
417  const size_t totalValueSize = coefficientsSize + lambdaSize + boundSize;
418  return totalValueSize;
419 }
420 
421 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
422 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
423 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) {
424  // index output
425  // shape
426  *indexOutIterator = static_cast<typename INDEX_OUTPUT_ITERATOR::value_type>(src.useSameNumLabels_);
427  ++indexOutIterator;
428  *indexOutIterator = src.numVariables_;
429  ++indexOutIterator;
430  if(src.useSameNumLabels_) {
431  *indexOutIterator = src.maxNumLabels_;
432  ++indexOutIterator;
433  } else {
434  for(size_t i = 0; i < src.shape_.size(); ++i) {
435  *indexOutIterator = src.shape_[i];
436  ++indexOutIterator;
437  }
438  }
439 
440  // share coefficients
441  *indexOutIterator = src.shareCoefficients_;
442  ++indexOutIterator;
443 
444  // coefficients size
445  *indexOutIterator = src.coefficients_.size();
446 
447  // value output
448  // coefficients
449  for(size_t i = 0; i <src.coefficients_.size(); ++i) {
450  *valueOutIterator = src.coefficients_[i];
451  ++valueOutIterator;
452  }
453 
454  // lambda
455  *valueOutIterator = src.lambda_;
456  ++valueOutIterator;
457 
458  // bound
459  *valueOutIterator = src.bound_;
460 }
461 
462 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
463 template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
464 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) {
465  typedef VALUE_TYPE ValueType;
466  typedef INDEX_TYPE IndexType;
467 
468  // index input
469  // shape
470  const bool useSameNumLabels = *indexInIterator;
471  ++indexInIterator;
472  const IndexType numVariables = *indexInIterator;
473  ++indexInIterator;
474  INDEX_INPUT_ITERATOR shapeBegin = indexInIterator;
475  indexInIterator += (useSameNumLabels ? 1 : numVariables);
476  INDEX_INPUT_ITERATOR shapeEnd = indexInIterator;
477  // share coefficients
478  const bool shareCoefficients = *indexInIterator;
479  ++indexInIterator;
480  // coefficients size
481  const size_t numCoeffiecients = *indexInIterator;
482 
483  // value input
484  // coefficients
485  VALUE_INPUT_ITERATOR coefficientsBegin = valueInIterator;
486  VALUE_INPUT_ITERATOR coefficientsEnd = valueInIterator + numCoeffiecients;
487  valueInIterator += numCoeffiecients;
488 
489  // lambda
490  const ValueType lambda = *valueInIterator;
491  ++valueInIterator;
492 
493  // bound
494  const ValueType bound = *valueInIterator;
495 
496  if(useSameNumLabels) {
497  dst = SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(numVariables, *shapeBegin, coefficientsBegin, coefficientsEnd, shareCoefficients, lambda, bound);
498  } else {
499  dst = SumConstraintFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(shapeBegin, shapeEnd, coefficientsBegin, coefficientsEnd, shareCoefficients, lambda, bound);
500  }
501 }
503 
504 } // namespace opengm
505 
506 #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.
ValueType operator()(Iterator statesBegin) const
Function evaluation.
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_
Stores the size of the function.
std::vector< ValueType > coefficients_
The coefficients of the equality constraint.
Default implementation for class opengm::LPFunctionTransfer.
ValueType bound_
The bound for the equality constraint.
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.
size_t shape(const size_t i) const
Number of labels of the indicated input variable.
SumConstraintFunction()
SumConstraintFunction constructor.
size_t numVariables_
The number of variables of the function.
size_t dimension() const
Number of input variables.
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 size() const
Number of parameters.
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...