OpenGM  2.3.x
Discrete Graphical Model Library
indicator_variable.hxx
Go to the documentation of this file.
1 #ifndef OPENGM_INDICATOR_VARIABLE_HXX_
2 #define OPENGM_INDICATOR_VARIABLE_HXX_
3 
4 #include <utility> // for std::pair
5 #include <vector>
6 #include <algorithm>
7 
8 namespace opengm {
9 
10 /*********************
11  * class definition *
12  *********************/
13 template <class INDEX_TYPE = size_t, class LABEL_TYPE = size_t>
15 public:
16  // typedefs
17  typedef INDEX_TYPE IndexType;
18  typedef LABEL_TYPE LabelType;
19 
21 
22  typedef std::pair<IndexType, LabelType> VariableLabelPair;
23  typedef std::vector<VariableLabelPair> VariableLabelPairContainerType;
24 
25  typedef typename VariableLabelPairContainerType::const_iterator IteratorType;
26 
27  // constructors
29  IndicatorVariable(const IndexType variable, const LabelType label, const LogicalOperatorType logicalOperatorType = And);
30  IndicatorVariable(const VariableLabelPair& variableLabelPair, const LogicalOperatorType logicalOperatorType = And);
31  IndicatorVariable(const VariableLabelPairContainerType& variableLabelPairs, const LogicalOperatorType logicalOperatorType = And);
32  template<class ITERATOR_TYPE>
33  IndicatorVariable(const ITERATOR_TYPE variableLabelPairsBegin, const ITERATOR_TYPE variableLabelPairsEnd, const LogicalOperatorType logicalOperatorType = And);
34 
35  // modify
36  void reserve(const size_t numPairs);
37  void add(const IndexType variable, const LabelType label);
38  void add(const VariableLabelPair& variableLabelPair);
39  void add(const VariableLabelPairContainerType& variableLabelPairs);
40  template<class ITERATOR_TYPE>
41  void add(const ITERATOR_TYPE variableLabelPairsBegin, const ITERATOR_TYPE variableLabelPairsEnd);
42  void setLogicalOperatorType(const LogicalOperatorType logicalOperatorType);
43 
44  // evaluate
45  template<class ITERATOR_TYPE>
46  bool operator()(const ITERATOR_TYPE statesBegin) const;
47 
48  // const access
49  IteratorType begin() const;
50  IteratorType end() const;
52 protected:
53  // storage
54  VariableLabelPairContainerType variableLabelPairs_;
56 
57  // friends
58  template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
59  friend bool operator==(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
60  template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
61  friend bool operator!=(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
62  template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
63  friend bool operator<(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
64  template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
65  friend bool operator>(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
66  template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
67  friend bool operator<=(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
68  template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
69  friend bool operator>=(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
70 };
71 
72 // operators for IndicatorVariable
73 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
75 
76 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
78 
79 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
80 bool operator<(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
81 
82 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
84 
85 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
86 bool operator<=(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2);
87 
88 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
90 
91 /***********************
92  * class documentation *
93  ***********************/
429 /******************
430  * implementation *
431  ******************/
432 
433 // constructors
434 template <class INDEX_TYPE, class LABEL_TYPE>
436 : variableLabelPairs_(), logicalOperatorType_(And) {
437 
438 }
439 
440 template <class INDEX_TYPE, class LABEL_TYPE>
441 inline IndicatorVariable<INDEX_TYPE, LABEL_TYPE>::IndicatorVariable(const IndexType variable, const LabelType label, const LogicalOperatorType logicalOperatorType)
442 : variableLabelPairs_(1, VariableLabelPair(variable, label)),
443  logicalOperatorType_(logicalOperatorType) {
444 
445 }
446 
447 template <class INDEX_TYPE, class LABEL_TYPE>
449 : variableLabelPairs_(1, variableLabelPair),
450  logicalOperatorType_(logicalOperatorType) {
451 
452 }
453 
454 template <class INDEX_TYPE, class LABEL_TYPE>
456 : variableLabelPairs_(variableLabelPairs),
457  logicalOperatorType_(logicalOperatorType) {
458  std::sort(variableLabelPairs_.begin(), variableLabelPairs_.end());
459 }
460 
461 template <class INDEX_TYPE, class LABEL_TYPE>
462 template<class ITERATOR_TYPE>
463 inline IndicatorVariable<INDEX_TYPE, LABEL_TYPE>::IndicatorVariable(const ITERATOR_TYPE variableLabelPairsBegin, const ITERATOR_TYPE variableLabelPairsEnd, const LogicalOperatorType logicalOperatorType)
464 : variableLabelPairs_(variableLabelPairsBegin, variableLabelPairsEnd),
465  logicalOperatorType_(logicalOperatorType) {
466  std::sort(variableLabelPairs_.begin(), variableLabelPairs_.end());
467 }
468 
469 // modify
470 template <class INDEX_TYPE, class LABEL_TYPE>
471 inline void IndicatorVariable<INDEX_TYPE, LABEL_TYPE>::reserve(const size_t numPairs) {
472  variableLabelPairs_.reserve(numPairs);
473 }
474 
475 template <class INDEX_TYPE, class LABEL_TYPE>
476 inline void IndicatorVariable<INDEX_TYPE, LABEL_TYPE>::add(const IndexType variable, const LabelType label) {
477  variableLabelPairs_.push_back(VariableLabelPair(variable, label));
478  std::sort(variableLabelPairs_.begin(), variableLabelPairs_.end());
479 }
480 
481 template <class INDEX_TYPE, class LABEL_TYPE>
483  variableLabelPairs_.push_back(variableLabelPair);
484  std::sort(variableLabelPairs_.begin(), variableLabelPairs_.end());
485 }
486 
487 template <class INDEX_TYPE, class LABEL_TYPE>
489  variableLabelPairs_.insert(variableLabelPairs_.end(), variableLabelPairs.begin(), variableLabelPairs.end());
490  std::sort(variableLabelPairs_.begin(), variableLabelPairs_.end());
491 }
492 
493 template <class INDEX_TYPE, class LABEL_TYPE>
494 template<class ITERATOR_TYPE>
495 inline void IndicatorVariable<INDEX_TYPE, LABEL_TYPE>::add(const ITERATOR_TYPE variableLabelPairsBegin, const ITERATOR_TYPE variableLabelPairsEnd) {
496  variableLabelPairs_.insert(variableLabelPairs_.end(), variableLabelPairsBegin, variableLabelPairsEnd);
497  std::sort(variableLabelPairs_.begin(), variableLabelPairs_.end());
498 }
499 
500 template <class INDEX_TYPE, class LABEL_TYPE>
502  logicalOperatorType_ = logicalOperatorType;
503 }
504 
505 // evaluate
506 template <class INDEX_TYPE, class LABEL_TYPE>
507 template<class ITERATOR_TYPE>
508 inline bool IndicatorVariable<INDEX_TYPE, LABEL_TYPE>::operator()(const ITERATOR_TYPE statesBegin) const {
509  bool result = true;
510  if(logicalOperatorType_ == And) {
511  for(IteratorType indicatorVariableIter = begin(); indicatorVariableIter != end(); ++indicatorVariableIter) {
512  if(indicatorVariableIter->second != statesBegin[indicatorVariableIter->first]) {
513  result = false;
514  break;
515  }
516  }
517  } else if(logicalOperatorType_ == Or) {
518  result = false;
519  for(IteratorType indicatorVariableIter = begin(); indicatorVariableIter != end(); ++indicatorVariableIter) {
520  if(indicatorVariableIter->second == statesBegin[indicatorVariableIter->first]) {
521  result = true;
522  break;
523  }
524  }
525  } else {
526  // logicalOperatorType_ == Not
527  for(IteratorType indicatorVariableIter = begin(); indicatorVariableIter != end(); ++indicatorVariableIter) {
528  if(indicatorVariableIter->second == statesBegin[indicatorVariableIter->first]) {
529  result = false;
530  break;
531  }
532  }
533  }
534  return result;
535 }
536 
537 // const access
538 template <class INDEX_TYPE, class LABEL_TYPE>
540  return variableLabelPairs_.begin();
541 }
542 
543 template <class INDEX_TYPE, class LABEL_TYPE>
545  return variableLabelPairs_.end();
546 }
547 
548 template <class INDEX_TYPE, class LABEL_TYPE>
550  return logicalOperatorType_;
551 }
552 
553 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
555  return (indicatorVar1.logicalOperatorType_ == indicatorVar2.logicalOperatorType_) && (indicatorVar1.variableLabelPairs_ == indicatorVar2.variableLabelPairs_);
556 }
557 
558 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
560  return (indicatorVar1.logicalOperatorType_ != indicatorVar2.logicalOperatorType_) || (indicatorVar1.variableLabelPairs_ != indicatorVar2.variableLabelPairs_);
561 }
562 
563 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
564 bool operator<(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2) {
565  if(indicatorVar1.logicalOperatorType_ < indicatorVar2.logicalOperatorType_) {
566  return true;
567  } else if(indicatorVar1.logicalOperatorType_ > indicatorVar2.logicalOperatorType_) {
568  return false;
569  } else {
570  if(indicatorVar1.variableLabelPairs_.size() > indicatorVar2.variableLabelPairs_.size()) {
571  return false;
572  }
573  if(indicatorVar1.variableLabelPairs_.size() == indicatorVar2.variableLabelPairs_.size()) {
574  if(indicatorVar1.variableLabelPairs_.size() == 0) {
575  return false;
576  }
577  for(size_t i = 0; i < indicatorVar1.variableLabelPairs_.size(); ++i) {
578  if(indicatorVar1.variableLabelPairs_[i].first > indicatorVar2.variableLabelPairs_[i].first) {
579  return false;
580  } else if(indicatorVar1.variableLabelPairs_[i].first == indicatorVar2.variableLabelPairs_[i].first) {
581  if(indicatorVar1.variableLabelPairs_[i].second >= indicatorVar2.variableLabelPairs_[i].second) {
582  return false;
583  }
584  }
585  }
586  }
587  return true;
588  }
589 }
590 
591 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
593  if(indicatorVar1.logicalOperatorType_ < indicatorVar2.logicalOperatorType_) {
594  return false;
595  } else if(indicatorVar1.logicalOperatorType_ > indicatorVar2.logicalOperatorType_) {
596  return true;
597  } else {
598  if(indicatorVar1.variableLabelPairs_.size() < indicatorVar2.variableLabelPairs_.size()) {
599  return false;
600  }
601  if(indicatorVar1.variableLabelPairs_.size() == indicatorVar2.variableLabelPairs_.size()) {
602  if(indicatorVar1.variableLabelPairs_.size() == 0) {
603  return false;
604  }
605  for(size_t i = 0; i < indicatorVar1.variableLabelPairs_.size(); ++i) {
606  if(indicatorVar1.variableLabelPairs_[i].first < indicatorVar2.variableLabelPairs_[i].first) {
607  return false;
608  } else if(indicatorVar1.variableLabelPairs_[i].first == indicatorVar2.variableLabelPairs_[i].first) {
609  if(indicatorVar1.variableLabelPairs_[i].second <= indicatorVar2.variableLabelPairs_[i].second) {
610  return false;
611  }
612  }
613  }
614  }
615  return true;
616  }
617 }
618 
619 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
620 bool operator<=(const IndicatorVariable<INDEX1_TYPE, LABEL1_TYPE>& indicatorVar1, const IndicatorVariable<INDEX2_TYPE, LABEL2_TYPE>& indicatorVar2) {
621  if(indicatorVar1.logicalOperatorType_ < indicatorVar2.logicalOperatorType_) {
622  return true;
623  } else if(indicatorVar1.logicalOperatorType_ > indicatorVar2.logicalOperatorType_) {
624  return false;
625  } else {
626  if(indicatorVar1.variableLabelPairs_.size() > indicatorVar2.variableLabelPairs_.size()) {
627  return false;
628  }
629  if(indicatorVar1.variableLabelPairs_.size() == indicatorVar2.variableLabelPairs_.size()) {
630  for(size_t i = 0; i < indicatorVar1.variableLabelPairs_.size(); ++i) {
631  if(indicatorVar1.variableLabelPairs_[i].first > indicatorVar2.variableLabelPairs_[i].first) {
632  return false;
633  } else if(indicatorVar1.variableLabelPairs_[i].first == indicatorVar2.variableLabelPairs_[i].first) {
634  if(indicatorVar1.variableLabelPairs_[i].second > indicatorVar2.variableLabelPairs_[i].second) {
635  return false;
636  }
637  }
638  }
639  }
640  return true;
641  }
642 }
643 
644 template<class INDEX1_TYPE, class LABEL1_TYPE, class INDEX2_TYPE, class LABEL2_TYPE>
646  if(indicatorVar1.logicalOperatorType_ < indicatorVar2.logicalOperatorType_) {
647  return false;
648  } else if(indicatorVar1.logicalOperatorType_ > indicatorVar2.logicalOperatorType_) {
649  return true;
650  } else {
651  if(indicatorVar1.variableLabelPairs_.size() < indicatorVar2.variableLabelPairs_.size()) {
652  return false;
653  }
654  if(indicatorVar1.variableLabelPairs_.size() == indicatorVar2.variableLabelPairs_.size()) {
655  for(size_t i = 0; i < indicatorVar1.variableLabelPairs_.size(); ++i) {
656  if(indicatorVar1.variableLabelPairs_[i].first < indicatorVar2.variableLabelPairs_[i].first) {
657  return false;
658  } else if(indicatorVar1.variableLabelPairs_[i].first == indicatorVar2.variableLabelPairs_[i].first) {
659  if(indicatorVar1.variableLabelPairs_[i].second < indicatorVar2.variableLabelPairs_[i].second) {
660  return false;
661  }
662  }
663  }
664  }
665  return true;
666  }
667 }
668 
669 } // namespace opengm
670 
671 #endif /* OPENGM_INDICATOR_VARIABLE_HXX_ */
friend bool operator!=(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
Inequality operator for IndicatorVariable.
bool operator>=(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
The OpenGM namespace.
Definition: config.hxx:43
friend bool operator>=(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
Greater equal operator for IndicatorVariable.
LABEL_TYPE LabelType
Typedef of the LABEL_TYPE template parameter type from the class IndicatorVariable.
The indicator variable will be interpreted as 1 if none of the variables associated by the indicator ...
IteratorType begin() const
Get the iterator over the sequence of variable label pairs from the indicator variable.
VariableLabelPairContainerType::const_iterator IteratorType
A const iterator to iterate over the VariableLabelPair elements.
bool operator!=(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
bool operator==(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
IteratorType end() const
Get the end iterator of the sequence of variable label pairs from the indicator variable.
VariableLabelPairContainerType variableLabelPairs_
Storage for the variable label pairs.
friend bool operator==(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
Equality operator for IndicatorVariable.
std::vector< VariableLabelPair > VariableLabelPairContainerType
A vector containing VariableLabelPair elements.
IndicatorVariable()
IndicatorVariable constructor.
void setLogicalOperatorType(const LogicalOperatorType logicalOperatorType)
Set the logical operator type of the indicator variable.
friend bool operator>(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
Greater operator for IndicatorVariable.
void reserve(const size_t numPairs)
Preallocate memory.
bool operator>(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
void add(const IndexType variable, const LabelType label)
Add a variable label pair to the indicator variable.
Combine a group of variables to a new variable.
std::pair< IndexType, LabelType > VariableLabelPair
A pair representing a single state of a variable.
LogicalOperatorType logicalOperatorType_
Storage for the logical operator type of the indicator variable.
bool operator()(const ITERATOR_TYPE statesBegin) const
Evaluation operator to check if the indicator variable is active for the given labeling.
The indicator variable will be interpreted as 1 if all variables associated by the indicator variable...
The indicator variable will be interpreted as 1 if at least one of the variables associated by the in...
LogicalOperatorType
This enum defines the logical operator types which are supported by the indicator variables...
LogicalOperatorType getLogicalOperatorType() const
Get the logical operator type of the indicator variable.
Disjunction as a binary operation.
Definition: or.hxx:10
Conjunction as a binary operation.
Definition: and.hxx:10
INDEX_TYPE IndexType
Typedef of the INDEX_TYPE template parameter type from the class IndicatorVariable.