OpenGM  2.3.x
Discrete Graphical Model Library
label_cost_function.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_LABEL_COST_FUNCTION_HXX_
2 #define OPENGM_LABEL_COST_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>
18 
19 template<class VALUE_TYPE, class INDEX_TYPE = size_t, class LABEL_TYPE = size_t>
20 class LabelCostFunction : public FunctionBase<LabelCostFunction<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 COST_ITERATOR_TYPE>
30  LabelCostFunction(SHAPE_ITERATOR_TYPE shapeBegin, SHAPE_ITERATOR_TYPE shapeEnd, COST_ITERATOR_TYPE costsBegin, COST_ITERATOR_TYPE costsEnd);
31  template <class SHAPE_ITERATOR_TYPE>
32  LabelCostFunction(SHAPE_ITERATOR_TYPE shapeBegin, SHAPE_ITERATOR_TYPE shapeEnd, const LabelType label, const ValueType cost);
33  template <class COST_ITERATOR_TYPE>
34  LabelCostFunction(const IndexType numVariables, const LabelType numLabels, COST_ITERATOR_TYPE costsBegin, COST_ITERATOR_TYPE costsEnd);
35  LabelCostFunction(const IndexType numVariables, const LabelType numLabels, const LabelType label, const ValueType cost);
37 
38  // function access
39  template<class Iterator>
40  ValueType operator()(Iterator statesBegin) const; // function evaluation
41  size_t shape(const size_t i) const; // number of labels of the indicated input variable
42  size_t dimension() const; // number of input variables
43  size_t size() const; // number of parameters
44 
45 protected:
46  // storage
47  std::vector<LabelType> shape_;
48  IndexType numVariables_;
49  LabelType maxNumLabels_;
51  size_t size_;
52  std::vector<ValueType> costs_;
54  LabelType singleLabel_;
55  ValueType singleCost_;
56 
57  // friends
58  friend class FunctionSerialization<LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >;
59  friend class LPFunctionTransfer_impl<LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>, VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>;
60 };
61 
64 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
65 struct FunctionRegistration<LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> > {
66  enum ID {
67  // TODO set final Id
69  };
70 };
71 
73 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
74 class FunctionSerialization<LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> > {
75 public:
76  typedef typename LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::ValueType ValueType;
77 
78  static size_t indexSequenceSize(const LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
79  static size_t valueSequenceSize(const LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
80  template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
81  static void serialize(const LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR);
82  template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
83  static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>&);
84 };
86 
87 /***********************
88  * class documentation *
89  ***********************/
281 /******************
282  * implementation *
283  ******************/
284 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
286  numVariables_(), maxNumLabels_(), useSameNumLabels_(), size_(), costs_(),
287  useSingleCost_(), singleLabel_(), singleCost_() {
288 
289 }
290 
291 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
292 template <class SHAPE_ITERATOR_TYPE, class COST_ITERATOR_TYPE>
293 inline LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::LabelCostFunction(SHAPE_ITERATOR_TYPE shapeBegin, SHAPE_ITERATOR_TYPE shapeEnd, COST_ITERATOR_TYPE costsBegin, COST_ITERATOR_TYPE costsEnd)
294  : shape_(shapeBegin, shapeEnd), numVariables_(shape_.size()),
295  maxNumLabels_(numVariables_ > 0 ? *std::max_element(shape_.begin(), shape_.end()) : 0),
296  useSameNumLabels_(numVariables_ > 0 ? std::equal(shape_.begin() + 1, shape_.end(), shape_.begin()) : true),
297  size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<SHAPE_ITERATOR_TYPE>::value_type>())),
298  costs_(costsBegin, costsEnd), useSingleCost_(false), singleLabel_(),
299  singleCost_() {
301 }
302 
303 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
304 template <class SHAPE_ITERATOR_TYPE>
305 inline LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::LabelCostFunction(SHAPE_ITERATOR_TYPE shapeBegin, SHAPE_ITERATOR_TYPE shapeEnd, const LabelType label, const ValueType cost)
306  : shape_(shapeBegin, shapeEnd), numVariables_(shape_.size()),
307  maxNumLabels_(numVariables_ > 0 ? *std::max_element(shape_.begin(), shape_.end()) : 0),
308  useSameNumLabels_(numVariables_ > 0 ? std::equal(shape_.begin() + 1, shape_.end(), shape_.begin()) : true),
309  size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<SHAPE_ITERATOR_TYPE>::value_type>())),
310  costs_(), useSingleCost_(true), singleLabel_(label), singleCost_(cost) {
312 }
313 
314 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
315 template <class COST_ITERATOR_TYPE>
316 inline LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::LabelCostFunction(const IndexType numVariables, const LabelType numLabels, COST_ITERATOR_TYPE costsBegin, COST_ITERATOR_TYPE costsEnd)
317  : shape_(), numVariables_(numVariables), maxNumLabels_(numLabels),
318  useSameNumLabels_(true),
319  size_(unsignedIntegerPow(maxNumLabels_, numVariables_)),
320  costs_(costsBegin, costsEnd), useSingleCost_(false), singleLabel_(),
321  singleCost_() {
323 }
324 
325 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
326 inline LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>::LabelCostFunction(const IndexType numVariables, const LabelType numLabels, const LabelType label, const ValueType cost)
327  : shape_(), numVariables_(numVariables), maxNumLabels_(numLabels),
328  useSameNumLabels_(true),
329  size_(unsignedIntegerPow(maxNumLabels_, numVariables_)), costs_(),
330  useSingleCost_(true), singleLabel_(label), singleCost_(cost) {
332 }
333 
334 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
336 
337 }
338 
339 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
340 template<class Iterator>
342  if(useSingleCost_) {
343  if(std::find(statesBegin, statesBegin + numVariables_, singleLabel_) == statesBegin + numVariables_) {
344  return 0.0;
345  } else {
346  return singleCost_;
347  }
348  } else {
349  std::vector<bool> labelIsUsed(maxNumLabels_, false);
350  ValueType result = 0.0;
351  LabelType numLabelsFound = 0;
352  const Iterator statesEnd = statesBegin + numVariables_;
353  while(statesBegin != statesEnd) {
354  const LabelType currentLabel = *statesBegin;
355  OPENGM_ASSERT(currentLabel < maxNumLabels_);
356  if(!labelIsUsed[currentLabel]) {
357  labelIsUsed[currentLabel] = true;
358  ++numLabelsFound;
359  result += costs_[currentLabel];
360  }
361  if(numLabelsFound == maxNumLabels_) {
362  break;
363  }
364  ++statesBegin;
365  }
366  return result;
367  }
368 }
369 
370 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
372  OPENGM_ASSERT(i < numVariables_);
373  if(useSameNumLabels_) {
374  return maxNumLabels_;
375  } else {
376  return shape_[i];
377  }
378 }
379 
380 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
382  return numVariables_;
383 }
384 
385 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
387  return size_;
388 }
389 
391 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
393  const size_t dimensionSize = 1;
394  const size_t useSameNumLabelsSize = 1;
395  const size_t shapeSize = src.useSameNumLabels_ ? 1 : src.dimension();
396  const size_t useSingleCostSize = 1;
397  const size_t costsSize = 1;
398 
399  const size_t totalIndexSize = dimensionSize + useSameNumLabelsSize +
400  shapeSize + useSingleCostSize + costsSize;
401  return totalIndexSize;
402 }
403 
404 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
405 inline size_t FunctionSerialization<LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >::valueSequenceSize(const LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>& src) {
406  const size_t costsSize = src.useSingleCost_ ? 1 : src.costs_.size();
407 
408  const size_t totalValueSize = costsSize;
409  return totalValueSize;
410 }
411 
412 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
413 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
414 inline void FunctionSerialization<LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >::serialize(const LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>& src, INDEX_OUTPUT_ITERATOR indexOutIterator, VALUE_OUTPUT_ITERATOR valueOutIterator) {
415  // index output
416  // dimension
417  *indexOutIterator = src.dimension();
418  ++indexOutIterator;
419 
420  // use same number of labels
421  *indexOutIterator = src.useSameNumLabels_ ? 1 : 0;
422  ++indexOutIterator;
423 
424  // shape
425  if(src.useSameNumLabels_) {
426  *indexOutIterator = src.maxNumLabels_;
427  ++indexOutIterator;
428  } else {
429  for(size_t i = 0; i < src.dimension(); ++i) {
430  *indexOutIterator = src.shape_[i];
431  ++indexOutIterator;
432  }
433  }
434 
435  // use single cost
436  *indexOutIterator = src.useSingleCost_ ? 1 : 0;
437  ++indexOutIterator;
438  if(src.useSingleCost_) {
439  *indexOutIterator = src.singleLabel_;
440  } else {
441  *indexOutIterator = src.costs_.size();
442  }
443 
444  // value output
445  // costs
446  if(src.useSingleCost_) {
447  *valueOutIterator = src.singleCost_;
448  } else {
449  for(size_t i = 0; i < src.costs_.size(); ++i) {
450  *valueOutIterator = src.costs_[i];
451  ++valueOutIterator;
452  }
453  }
454 }
455 
456 template<class VALUE_TYPE, class INDEX_TYPE, class LABEL_TYPE>
457 template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
458 inline void FunctionSerialization<LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE> >::deserialize(INDEX_INPUT_ITERATOR indexInIterator, VALUE_INPUT_ITERATOR valueInIterator, LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>& dst) {
459  // index input
460  // dimension
461  const size_t dimension = *indexInIterator;
462  ++indexInIterator;
463 
464  // use same number of Labels
465  const bool useSameNumLabels = *indexInIterator == 1 ? true : false;
466  ++indexInIterator;
467 
468  // shape
469  INDEX_INPUT_ITERATOR shapeBegin = indexInIterator;
470  INDEX_INPUT_ITERATOR shapeEnd = indexInIterator + (useSameNumLabels ? 1 : dimension);
471  indexInIterator += (useSameNumLabels ? 1 : dimension);
472 
473  // use single cost
474  const bool useSingleCost = *indexInIterator == 1 ? true : false;
475  ++indexInIterator;
476  const size_t costsSize = *indexInIterator;
477 
478  // value input
479  // coefficients
480  VALUE_INPUT_ITERATOR costsBegin = valueInIterator;
481  VALUE_INPUT_ITERATOR costsEnd = valueInIterator + costsSize;
482 
483  if(useSameNumLabels) {
484  if(useSingleCost) {
485  dst = LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(dimension, *shapeBegin, costsSize, *costsBegin);
486  } else {
487  dst = LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(dimension, *shapeBegin, costsBegin, costsEnd);
488  }
489  } else {
490  if(useSingleCost) {
491  dst = LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(shapeBegin, shapeEnd, costsSize, *costsBegin);
492  } else {
493  dst = LabelCostFunction<VALUE_TYPE, INDEX_TYPE, LABEL_TYPE>(shapeBegin, shapeEnd, costsBegin, costsEnd);
494  }
495  }
496 }
498 
499 } // namespace opengm
500 
501 
502 
503 #endif /* OPENGM_LABEL_COST_FUNCTION_HXX_ */
LABEL_TYPE LabelType
Typedef of the LABEL_TYPE template parameter type from the class LabelCostFunction.
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.
STL namespace.
size_t unsignedIntegerPow(size_t base, size_t exponent)
Unsigned integer power function.
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
A label cost function class penalizing the usage of labels.
IndexType numVariables_
Storage for the number of variables of the function.
std::vector< LabelType > shape_
Storage for the shape of the function which is used if all variables can have different numbers of la...
ValueType singleCost_
Storage for cost of the single label which has label costs. Is only used when useSingleCost_ is set t...
Default implementation for class opengm::LPFunctionTransfer.
~LabelCostFunction()
LabelCostFunction destructor.
INDEX_TYPE IndexType
Typedef of the INDEX_TYPE template parameter type from the class LabelCostFunction.
std::vector< ValueType > costs_
Storage for the label costs which is used if all labels can have label costs.
bool useSameNumLabels_
Indicator to tell if all variables have the same number of labels.
size_t shape(const size_t i) const
Number of labels of the indicated input variable.
const size_t FUNCTION_TYPE_ID_OFFSET
User-defined function have ids smaller than FUNCTION_TYPE_ID_OFFSET.
LabelCostFunction()
LabelCostFunction constructor.
bool useSingleCost_
Indicator to tell if only a single label has label costs.
LabelType maxNumLabels_
Storage for the maximum number of labels of the function.
VALUE_TYPE ValueType
Typedef of the VALUE_TYPE template parameter type from the class LabelCostFunction.
ValueType operator()(Iterator statesBegin) const
Function evaluation.
size_t size_
Stores the size of the label cost function.
LabelType singleLabel_
Storage for the single label which has label costs. Is only used when useSingleCost_ is set to true...
size_t dimension() const
Number of input variables.
size_t size() const
Number of parameters.