OpenGM  2.3.x
Discrete Graphical Model Library
graphicalmodel_factor.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_GRAPHICALMODEL_FACTOR_HXX
3 #define OPENGM_GRAPHICALMODEL_FACTOR_HXX
4 
5 #include <vector>
6 #include <set>
7 #include <algorithm>
8 #include <functional>
9 #include <numeric>
10 #include <map>
11 #include <list>
12 #include <set>
13 #include <functional>
14 
18 #include "opengm/opengm.hxx"
26 
28 
29 namespace opengm {
30 
31 
32 template<class FACTOR,class FUNCTOR>
33 class ViFunctor{
34 public:
35  ViFunctor(const FACTOR & factor, FUNCTOR & functor)
36  : factor_(factor),
37  functor_(functor)
38  {
39 
40  }
41  typedef typename FACTOR::VariablesIteratorType ViIterator;
42 
43  template<class FUNCTION>
44  void operator()(const FUNCTION & function){
45  functor_(factor_.variableIndicesBegin(),factor_.variableIndicesEnd(),function);
46  }
47 private:
48  const FACTOR & factor_;
49  FUNCTOR & functor_;
50 };
51 
52 
54 
55 template<
56  class T,
57  class OPERATOR,
58  class FUNCTION_TYPE_LIST,
59  class SPACE
60 > class GraphicalModel;
61 
62 template<class GRAPHICAL_MODEL> class Factor;
63 
64 namespace hdf5 {
65  template<class GM>
66  void save(const GM&, const std::string&, const std::string&);
67  template<class GM_>
68  void load(GM_& gm, const std::string&, const std::string&);
69 }
70 
71 namespace functionwrapper {
72  namespace executor {
73  template<size_t IX, size_t DX, bool END>
74  struct FactorInvariant;
75  template<size_t IX, size_t DX>
76  struct FactorInvariant<IX, DX, false> {
77  template<class GM, class FACTOR>
78  void static op(const GM &, const FACTOR &);
79  };
80  template<size_t IX, size_t DX>
81  struct FactorInvariant<IX, DX, true> {
82  template<class GM, class FACTOR>
83  void static op(const GM &, const FACTOR &);
84  };
85  } // namespace executor
86 } // namespace functionwrapper
87 
88 namespace detail_graphical_model {
89  template<size_t DX>
90  struct FunctionWrapper;
91  template<size_t DX, class VALUE_TYPE>
92  struct FunctionValueWrapper;
93  template<size_t IX, size_t DX, bool end>
94  struct FunctionWrapperExecutor;
95  template<size_t IX, size_t DX, bool end, class VALUE_TYPE>
96  struct FunctionValueWrapperExecutor;
97 }
98 
100 
102 template<class GRAPHICAL_MODEL>
103 class Factor {
104 public:
105  typedef GRAPHICAL_MODEL* GraphicalModelPointerType;
106  typedef GRAPHICAL_MODEL GraphicalModelType;
108  NrOfFunctionTypes = GraphicalModelType::NrOfFunctionTypes
109  };
110 
111  typedef typename GraphicalModelType::FunctionTypeList FunctionTypeList;
112  typedef typename GraphicalModelType::ValueType ValueType;
113  typedef typename GraphicalModelType::LabelType LabelType;
114  typedef typename GraphicalModelType::IndexType IndexType;
115 
117  typedef FactorShapeAccessor<Factor<GRAPHICAL_MODEL> > ShapeAccessorType;
120  typedef typename opengm::AccessorIterator<ShapeAccessorType, true> ShapeIteratorType;
122 
123 
124 
125 
126 
127  // construction and assignment
128  Factor();
129  Factor(GraphicalModelPointerType);
130  Factor(const Factor&);
131  Factor(GraphicalModelPointerType, const IndexType, const UInt8Type, const IndexType,const IndexType);
132  Factor& operator=(const Factor&);
133 
134  /*
135  template<int FUNCTION_TYPE>
136  IndexType size() const;
137  */
138  IndexType size() const;
139  IndexType numberOfVariables() const;
140  IndexType numberOfLabels(const IndexType) const;
141  IndexType shape(const IndexType) const;
142  IndexType variableIndex(const IndexType) const;
143  ShapeIteratorType shapeBegin() const;
144  ShapeIteratorType shapeEnd() const;
145  template<size_t FUNCTION_TYPE_INDEX>
146  const typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_TYPE_INDEX>::type& function() const;
147  VariablesIteratorType variableIndicesBegin() const;
148  VariablesIteratorType variableIndicesEnd() const;
149  template<class ITERATOR>
150  ValueType operator()(ITERATOR) const;
151 
152  template<class FUNCTOR>
153  void callFunctor(FUNCTOR & f)const;
154 
155  template<class FUNCTOR>
156  void callViFunctor(FUNCTOR & f)const;
157 
158  template<class ITERATOR>
159  void copyValues(ITERATOR iterator) const;
160  template<class ITERATOR>
161  void copyValuesSwitchedOrder(ITERATOR iterator) const;
162  template<int FunctionType, class ITERATOR>
163  ValueType operator()(ITERATOR) const;
164  UInt8Type functionType() const;
165  IndexType functionIndex() const;
166  template<class ITERATOR>
167  void variableIndices(ITERATOR out) const;
168  bool isPotts() const;
169  bool isGeneralizedPotts() const;
170  bool isSubmodular() const;
171  bool isSquaredDifference() const;
172  bool isTruncatedSquaredDifference() const;
173  bool isAbsoluteDifference() const;
174  bool isTruncatedAbsoluteDifference() const;
175  bool isLinearConstraint() const;
176  template<int PROPERTY>
177  bool binaryProperty()const;
178  template<int PROPERTY>
179  ValueType valueProperty()const;
180 
181  template<class FUNCTOR>
182  void forAllValuesInAnyOrder(FUNCTOR & functor)const;
183  template<class FUNCTOR>
184  void forAtLeastAllUniqueValues(FUNCTOR & functor)const;
185  template<class FUNCTOR>
186  void forAllValuesInOrder(FUNCTOR & functor)const;
187  template<class FUNCTOR>
188  void forAllValuesInSwitchedOrder(FUNCTOR & functor)const;
189 
190  ValueType sum() const;
191  ValueType product() const;
192  ValueType min() const;
193  ValueType max() const;
194  IndexType dimension()const{return this->numberOfVariables();}
195 private:
196  void testInvariant() const;
197  //std::vector<IndexType> & variableIndexSequence();
198  const VisContainerType & variableIndexSequence() const;
199  template<size_t FUNCTION_TYPE_INDEX>
200  typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_TYPE_INDEX>::type& function();
201 
202  GraphicalModelPointerType gm_;
203  IndexType functionIndex_;
204  opengm::UInt8Type functionTypeId_;
205  //std::vector<IndexType> variableIndices_;
206  //IndexType order_;
207  //IndexType indexInVisVector_;
208  VisContainerType vis_;
209 template<typename, typename, typename, typename>
210  friend class GraphicalModel;
211 template<size_t>
212  friend struct opengm::detail_graphical_model::FunctionWrapper;
213 template<size_t, size_t, bool>
214  friend struct opengm::detail_graphical_model::FunctionWrapperExecutor;
215 template<typename>
216  friend class Factor;
217 template<typename GM_>
218  friend void opengm::hdf5::save(const GM_&, const std::string&, const std::string&);
219 template<typename GM_>
220  friend void opengm::hdf5::load(GM_&, const std::string&, const std::string&);
221 template<typename, typename, typename >
222  friend class IndependentFactor;
223 
224 // friends for unary
225 template<class, class, class, class>
226  friend class opengm::functionwrapper::binary::OperationWrapperSelector;
227 template<class , class, class>
228  friend class opengm::functionwrapper::unary::OperationWrapperSelector;
229 
230 template<class, class, class, class, class, class, class>
231  friend class opengm::functionwrapper::binary::OperationWrapper;
232 
233 template <class, size_t>
234  friend class opengm::meta::GetFunction;
235 template<class, class, class>
236  friend class opengm::functionwrapper::AccumulateSomeWrapper;
237 
238 template<class, class, class, size_t, size_t, bool >
239  friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
240 
241 template<class, class, class, size_t, size_t, bool>
242  friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
243 
244 template<class A, class B, class OP, size_t IX, size_t DX, bool>
245  friend class opengm::functionwrapper::executor::unary::OperationExecutor;
246 };
247 
249 template<class T, class I, class L>
251 public:
252  typedef T ValueType;
253  typedef I IndexType;
254  typedef L LabelType;
256  typedef typename meta::TypeListGenerator<FunctionType>::type FunctionTypeList;
259  };
260  typedef const size_t* ShapeIteratorType;
261  typedef typename std::vector<IndexType>::const_iterator VariablesIteratorType;
262 
263  typedef std::vector<IndexType> VisContainerType;
264 
266  IndependentFactor(const ValueType);
267 
268  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
269  IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
270  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
271  IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
272  template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
273  IndependentFactor(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType = ValueType());
275  template<class GRAPHICAL_MODEL>
278  template<class GRAPHICAL_MODEL>
280  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
281  void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
282  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
283  void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
284  template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
285  void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR);
286  template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
287  void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType);
288  void assign(const ValueType);
289 
290  ShapeIteratorType shapeBegin() const;
291  ShapeIteratorType shapeEnd() const;
292  VariablesIteratorType variableIndicesBegin()const;
293  VariablesIteratorType variableIndicesEnd()const;
294  const std::vector<IndexType>& variableIndexSequence() const;
295  template<size_t FUNCTION_TYPE_INDEX>
296  const FunctionType& function() const;
297  size_t numberOfVariables() const;
298  IndexType numberOfLabels(const IndexType) const;
299  IndexType shape(const size_t dimIndex) const;
300  size_t size() const;
301  IndexType variableIndex(const size_t) const;
302  template<class ITERATOR>
303  void variableIndices(ITERATOR) const;
304  template<class ITERATOR>
305  T operator()(ITERATOR) const;
306  T operator()(const IndexType) const;
307  T operator()(const IndexType, const IndexType) const;
308  T operator()(const IndexType, const IndexType, const IndexType) const;
309  T operator()(const IndexType, const IndexType, const IndexType, const IndexType) const;
310 
311  template<class INDEX_ITERATOR, class STATE_ITERATOR>
312  void fixVariables(INDEX_ITERATOR, INDEX_ITERATOR, STATE_ITERATOR);
313  template<class ITERATOR>
314  T& operator()(ITERATOR);
315  T& operator()(const IndexType);
316  T& operator()(const IndexType, const IndexType);
317  T& operator()(const IndexType, const IndexType, const IndexType);
318  T& operator()(const IndexType, const IndexType, const IndexType, const IndexType);
319  template<class UNARY_OPERATOR_TYPE>
320  void operateUnary(UNARY_OPERATOR_TYPE unaryOperator);
321  template<class BINARY_OPERATOR_TYPE>
322  void operateBinary(const T value, BINARY_OPERATOR_TYPE binaryOperator);
323  template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
324  void operateBinary(const Factor<GRAPHICAL_MODEL>&, BINARY_OPERATOR_TYPE binaryOperator);
325  template<class BINARY_OPERATOR_TYPE>
326  void operateBinary(const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
327  template<class BINARY_OPERATOR_TYPE>
328  void operateBinary(const IndependentFactor<T, I, L>&, const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
329  void subtractOffset();
330 
331  template<class ACCUMULATOR>
332  void accumulate(ValueType&, std::vector<LabelType>&) const;
333  template<class ACCUMULATOR>
334  void accumulate(ValueType&) const;
335  template<class ACCUMULATOR, class VariablesIterator>
336  void accumulate(VariablesIterator, VariablesIterator, IndependentFactor<T, I, L> &) const;
337  template<class ACCUMULATOR, class VariablesIterator>
338  void accumulate(VariablesIterator, VariablesIterator) ;
339  const FunctionType& function() const;
340 
341  bool isPotts()
342  { return function_.isPotts(); }
344  { return function_.isGeneralizedPotts(); }
346  { return function_.isSubmodular(); }
348  { return function_.isSquaredDifference(); }
350  { return function_.isTruncatedSquaredDifference(); }
352  { return function_.isAbsoluteDifference(); }
354  { return function_.isTruncatedAbsoluteDifference(); }
355 
356  T min() {return function_.min();}
357  T max() {return function_.max();}
358  T sum() {return function_.sum();}
359  T product() {return function_.product();}
360 
361 private:
362  template<size_t FUNCTION_TYPE_INDEX>
363  FunctionType& function();
364  std::vector<IndexType>& variableIndexSequence();
365 
366  std::vector<IndexType> variableIndices_;
367  FunctionType function_;
368 
369 template<typename>
370  friend class Factor;
371 template<typename, typename, typename, typename>
372  friend class GraphicalModel;
373 //friends for unary
374 template<class, class, class, class>
375  friend class opengm::functionwrapper::binary::OperationWrapperSelector;
376 template<class , class, class>
377  friend class opengm::functionwrapper::unary::OperationWrapperSelector;
378 template<class, class, class, class, class, class, class>
379  friend class opengm::functionwrapper::binary::OperationWrapper;
380 template <class, size_t>
381  friend class opengm::meta::GetFunction;
382 template<class, class, class>
383  friend class opengm::functionwrapper::AccumulateSomeWrapper;
384 template<class, class, class, size_t, size_t, bool>
385  friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
386 template<class, class, class, size_t, size_t, bool>
387  friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
388 template<class A, class B, class OP, size_t IX, size_t DX, bool>
389  friend class opengm::functionwrapper::executor::unary::OperationExecutor;
390 template<class ACC, class A, class ViAccIterator>
391  friend void accumulate(A &, ViAccIterator, ViAccIterator );
392 };
393 
394 
395 template<class GRAPHICAL_MODEL>
397 : gm_(NULL),
398  functionIndex_(),
399  vis_()
400 {}
401 
403 template<class GRAPHICAL_MODEL>
405 (
407  const typename Factor<GRAPHICAL_MODEL>::IndexType functionIndex,
408  const UInt8Type functionTypeId,
409  const typename Factor<GRAPHICAL_MODEL>::IndexType order,
410  const typename Factor<GRAPHICAL_MODEL>::IndexType indexInVisVector
411 )
412 : gm_(gm),
413  functionIndex_(functionIndex),
414  functionTypeId_(functionTypeId),
415  vis_(gm->factorsVis_, indexInVisVector,order)
416 {
417  /*
418  if(!opengm::NO_DEBUG) {
419  if(variableIndices_.size() != 0) {
420  OPENGM_ASSERT(variableIndices_[0] < gm->numberOfVariables());
421  for(size_t i = 1; i < variableIndices_.size(); ++i) {
422  OPENGM_ASSERT(variableIndices_[i] < gm->numberOfVariables());
423  }
424  }
425  }
426  */
427 }
428 
430 template<class GRAPHICAL_MODEL>
432 (
434 )
435 : gm_(gm),
436  functionIndex_(0),
437  functionTypeId_(0),
438  vis_(gm_->factorsVis_)
439 {}
440 
441 template<class GRAPHICAL_MODEL>
443 (
444  const Factor& src
445 )
446 : gm_(src.gm_),
447  functionIndex_(src.functionIndex_),
448  functionTypeId_(src.functionTypeId_),
449  vis_(src.vis_)
450 {}
451 
452 template<class GRAPHICAL_MODEL>
455 (
456  const Factor& src
457 )
458 {
459  if(&src != this) {
460  functionTypeId_ = src.functionTypeId_;
461  functionIndex_ = src.functionIndex_;
462  //variableIndices_ = src.variableIndices_;
463  vis_=src.vis_;
464  }
465  return *this;
466 }
467 
468 template<class GRAPHICAL_MODEL>
471 {
472  return ShapeIteratorType(ShapeAccessorType(this), 0);
473 }
474 
475 template<class GRAPHICAL_MODEL>
478 {
479  return ShapeIteratorType(ShapeAccessorType(this), vis_.size());
480 }
481 
482 
483 
484 template<class GRAPHICAL_MODEL>
485 inline const typename Factor<GRAPHICAL_MODEL>::VisContainerType &
487 {
488  return this->vis_;
489 }
490 
491 
493 template<class GRAPHICAL_MODEL>
494 inline typename Factor<GRAPHICAL_MODEL>::IndexType
496 (
497  const IndexType j
498 ) const {
499  return gm_->numberOfLabels(vis_[j]);
500 }
501 
502 template<class GRAPHICAL_MODEL>
505 {
506  return vis_.size();
507 }
508 
510 template<class GRAPHICAL_MODEL>
513  const IndexType j
514 ) const
515 {
516  return vis_[j];
517 }
518 
520 template<class GRAPHICAL_MODEL>
523  const IndexType j
524 ) const
525 {
526  OPENGM_ASSERT(j < vis_.size());
527  return gm_->numberOfLabels(vis_[j]);
528 }
529 
532 template<class GRAPHICAL_MODEL>
533 template<class ITERATOR>
536  ITERATOR begin
537 ) const
538 {
539  return opengm::detail_graphical_model::FunctionWrapper<
541  >::getValue (this->gm_, begin, functionIndex_, functionTypeId_);
542 }
543 
544 
548 template<class GRAPHICAL_MODEL>
549 template<class FUNCTOR>
550 inline void
552  FUNCTOR & functor
553 ) const
554 {
555  return opengm::detail_graphical_model::FunctionWrapper<
557  >::callFunctor(this->gm_, functionIndex_, functionTypeId_,functor);
558 }
559 
563 template<class GRAPHICAL_MODEL>
564 template<class FUNCTOR>
565 inline void
567  FUNCTOR & functor
568 ) const
569 {
570  ViFunctor< Factor<GRAPHICAL_MODEL> , FUNCTOR> viFunctor(*this,functor);
571 
572  return opengm::detail_graphical_model::FunctionWrapper<
574  >::callFunctor(this->gm_, functionIndex_, functionTypeId_,viFunctor);
575 }
576 
577 
580 template<class GRAPHICAL_MODEL>
581 template<class ITERATOR>
582 inline void
584  ITERATOR begin
585 ) const
586 {
587  opengm::detail_graphical_model::FunctionWrapper<
589  >::getValues (this->gm_, begin, functionIndex_, functionTypeId_);
590 }
591 
592 template<class GRAPHICAL_MODEL>
593 template<class ITERATOR>
594 inline void
596  ITERATOR begin
597 ) const
598 {
599  opengm::detail_graphical_model::FunctionWrapper<
601  >::getValuesSwitchedOrder (this->gm_, begin, functionIndex_, functionTypeId_);
602 }
603 
606 template<class GRAPHICAL_MODEL>
607 template<int FunctionType, class ITERATOR>
609 Factor<GRAPHICAL_MODEL>::operator()
610 (
611  ITERATOR begin
612 ) const {
613  return gm_-> template functions<FunctionType>()[functionIndex_].operator()(begin);
614 }
615 
627 template<class GRAPHICAL_MODEL>
628 template<int PROPERTY>
629 inline bool
631 {
632  return opengm::detail_graphical_model::FunctionWrapper<
634  >:: template binaryProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
635 }
636 
637 
649 template<class GRAPHICAL_MODEL>
650 template<int PROPERTY>
651 inline typename GRAPHICAL_MODEL::ValueType
653 {
654  return opengm::detail_graphical_model::FunctionWrapper<
656  >:: template valueProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
657 }
658 
668 template<class GRAPHICAL_MODEL>
669 template<class FUNCTOR>
670 inline void
672 (
673  FUNCTOR & functor
674 )const{
675  opengm::detail_graphical_model::FunctionWrapper<
677  >:: template forAllValuesInAnyOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
678 }
679 
680 
690 template<class GRAPHICAL_MODEL>
691 template<class FUNCTOR>
692 inline void
694 (
695  FUNCTOR & functor
696 )const{
697  opengm::detail_graphical_model::FunctionWrapper<
699  >:: template forAtLeastAllUniqueValues<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
700 }
701 
711 template<class GRAPHICAL_MODEL>
712 template<class FUNCTOR>
713 inline void
715 (
716  FUNCTOR & functor
717 )const{
718  opengm::detail_graphical_model::FunctionWrapper<
720  >:: template forAllValuesInOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
721 }
722 
723 template<class GRAPHICAL_MODEL>
724 template<class FUNCTOR>
725 inline void
727 (
728  FUNCTOR & functor
729 )const{
730  opengm::detail_graphical_model::FunctionWrapper<
732  >:: template forAllValuesInSwitchedOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
733 }
734 
735 template<class GRAPHICAL_MODEL>
736 inline bool
738 {
739  return opengm::detail_graphical_model::FunctionWrapper<
741  >::isPotts (this->gm_, functionIndex_, functionTypeId_);
742 }
743 
744 template<class GRAPHICAL_MODEL>
745 inline bool
747 {
748  return opengm::detail_graphical_model::FunctionWrapper<
750  >::isGeneralizedPotts (this->gm_, functionIndex_, functionTypeId_);
751 }
752 
753 template<class GRAPHICAL_MODEL>
754 inline bool
756 {
757  return opengm::detail_graphical_model::FunctionWrapper<
759  >::isSubmodular (this->gm_, functionIndex_, functionTypeId_);
760 }
761 
762 template<class GRAPHICAL_MODEL>
763 inline bool
765 {
766  if(this->numberOfVariables()==2) {
767  return opengm::detail_graphical_model::FunctionWrapper<
769  >::isSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
770  }
771  else {
772  return false;
773  }
774 }
775 
776 template<class GRAPHICAL_MODEL>
777 inline bool
779 {
780  if(this->numberOfVariables()==2) {
781  return opengm::detail_graphical_model::FunctionWrapper<
783  >::isTruncatedSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
784  }
785  else {
786  return false;
787  }
788 }
789 
790 template<class GRAPHICAL_MODEL>
791 inline bool
793 {
794  if(this->numberOfVariables() == 2) {
795  return opengm::detail_graphical_model::FunctionWrapper<
797  >::isAbsoluteDifference(this->gm_, functionIndex_, functionTypeId_);
798  }
799  else {
800  return false;
801  }
802 }
803 
804 template<class GRAPHICAL_MODEL>
805 inline bool
807 {
808  if(this->numberOfVariables()==2) {
809  return opengm::detail_graphical_model::FunctionWrapper<
811  >::isTruncatedAbsoluteDifference (this->gm_, functionIndex_, functionTypeId_);
812  }
813  else{
814  return false;
815  }
816 }
817 
818 template<class GRAPHICAL_MODEL>
819 inline bool
821 {
822  return opengm::detail_graphical_model::FunctionWrapper<
824  >::isLinearConstraint (this->gm_, functionIndex_, functionTypeId_);
825 }
826 
827 template<class GRAPHICAL_MODEL>
830  return opengm::detail_graphical_model::FunctionWrapper<
832  >::sum (this->gm_, functionIndex_, functionTypeId_);
833 }
834 
835 template<class GRAPHICAL_MODEL>
838  return opengm::detail_graphical_model::FunctionWrapper<
840  >::product (this->gm_, functionIndex_, functionTypeId_);
841 }
842 
843 template<class GRAPHICAL_MODEL>
846  return opengm::detail_graphical_model::FunctionWrapper<
848  >::min (this->gm_, functionIndex_, functionTypeId_);
849 }
850 
851 template<class GRAPHICAL_MODEL>
854  return opengm::detail_graphical_model::FunctionWrapper<
856  >::max (this->gm_, functionIndex_, functionTypeId_);
857 }
858 
859 template<class GRAPHICAL_MODEL>
860 template<class ITERATOR>
862 (
863  ITERATOR out
864 ) const {
865  for(IndexType j = 0; j < numberOfVariables(); ++j) {
866  *out = this->variableIndex(j);
867  ++out;
868  }
869 }
870 
871 template<class GRAPHICAL_MODEL>
872 template<size_t FUNCTION_TYPE_INDEX>
873 inline typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
875  typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
876  OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
877  return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
878  functionData_.functions_[functionIndex_];
879 }
880 
881 template<class GRAPHICAL_MODEL>
882 template<size_t FUNCTION_TYPE_INDEX>
883 inline const typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
885  typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
886  OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
887  return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
888  functionData_.functions_[functionIndex_];
889 }
890 
891 template<class GRAPHICAL_MODEL>
894  return vis_.begin();
895 }
896 
897 template<class GRAPHICAL_MODEL>
900  return vis_.end();
901 }
902 
903 template<class GRAPHICAL_MODEL>
906 {
907  if(vis_.size() != 0) {
908  size_t val = this->shape(0);
909  for(size_t i = 1; i<this->numberOfVariables(); ++i) {
910  val *= this->shape(i);
911  }
912  return val;
913  }
914  return 1;
915 }
916 
917 template<class GRAPHICAL_MODEL>
918 inline void Factor<GRAPHICAL_MODEL>::testInvariant() const {
919  opengm::functionwrapper::executor::FactorInvariant
920  <
921  0,
923  meta::EqualNumber<Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes, 0>::value
924  >::op( *gm_, *this);
925 }
926 
927 template<class GRAPHICAL_MODEL>
928 inline opengm::UInt8Type
930  return static_cast<UInt8Type> (functionTypeId_);
931 }
932 
933 template<class GRAPHICAL_MODEL>
936  return functionIndex_;
937 }
938 
939 template<class T, class I, class L>
941 : variableIndices_(),
942  function_(1.0)
943 {}
944 
946 template<class T, class I, class L>
948 (
949  const ValueType constant
950 )
951 : variableIndices_(),
952  function_(constant)
953 {}
954 
960 template<class T, class I, class L>
961 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
963 (
964  VARIABLE_INDEX_ITERATOR beginVi,
965  VARIABLE_INDEX_ITERATOR endVi,
966  SHAPE_ITERATOR beginShape,
967  SHAPE_ITERATOR endShape
968 )
969 : variableIndices_(beginVi, endVi),
970  function_(beginShape, endShape, 1)
971 {
972  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
973  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
974 }
975 
976 template<class T, class I, class L>
977 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
979 (
980  VARIABLE_INDEX_ITERATOR beginVi,
981  VARIABLE_INDEX_ITERATOR endVi,
982  SHAPE_ITERATOR beginShape,
983  SHAPE_ITERATOR endShape,
984  const ValueType constant
985 )
986 : variableIndices_(beginVi, endVi),
987  function_(beginShape, endShape, constant)
988 {
989  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
990  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
991 }
992 
993 template<class T, class I, class L>
994 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
996 (
997  VARIABLE_INDEX_ITERATOR beginVi,
998  VARIABLE_INDEX_ITERATOR endVi,
999  SHAPE_ITERATOR beginShape,
1000  SHAPE_ITERATOR endShape
1001 ) {
1002  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
1003  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
1004  function_.assign();
1005  function_.resize(beginShape, endShape, 1);
1006  variableIndices_.assign(beginVi, endVi);
1007 }
1008 
1009 template<class T, class I, class L>
1010 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
1013  VARIABLE_INDEX_ITERATOR beginVi,
1014  VARIABLE_INDEX_ITERATOR endVi,
1015  SHAPE_ITERATOR beginShape,
1016  SHAPE_ITERATOR endShape,
1017  const ValueType constant
1018 ) {
1019  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
1020  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
1021  function_.assign();
1022  function_.resize(beginShape, endShape, constant);
1023  variableIndices_.assign(beginVi, endVi);
1024 }
1025 
1027 template<class T, class I, class L>
1028 template<size_t FUNCTION_TYPE_INDEX>
1031 {
1032  return function_;
1033 }
1034 
1035 template<class T, class I, class L>
1036 inline const typename IndependentFactor<T, I, L>::FunctionType&
1038 {
1039  return function_;
1040 }
1041 
1042 template<class T, class I, class L>
1043 template<size_t FUNCTION_TYPE_INDEX>
1044 inline const typename IndependentFactor<T, I, L>::FunctionType&
1046 {
1047  return function_;
1048 }
1049 
1050 template<class T, class I, class L>
1051 inline void
1054  const ValueType constant
1055 )
1056 {
1057  typename IndependentFactor<T, I, L>::FunctionType c(constant);
1058  function_ = c;
1059  variableIndices_.clear();
1060 }
1061 
1062 template<class T, class I, class L>
1063 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
1066  const GRAPHICAL_MODEL& gm,
1067  VARIABLE_INDEX_ITERATOR begin,
1068  VARIABLE_INDEX_ITERATOR end
1069 )
1070 {
1071  OPENGM_ASSERT(opengm::isSorted(begin, end));
1072  this->variableIndices_.assign(begin, end);
1073  std::vector<size_t> factorShape(variableIndices_.size());
1074  for(size_t i = 0; i < factorShape.size(); ++i) {
1075  factorShape[i] = gm.numberOfLabels(variableIndices_[i]);
1076  }
1077  this->function_.assign();
1078  this->function_.resize(factorShape.begin(), factorShape.end());
1079 }
1080 
1081 template<class T, class I, class L>
1082 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
1085  const GRAPHICAL_MODEL& gm,
1086  VARIABLE_INDEX_ITERATOR begin,
1087  VARIABLE_INDEX_ITERATOR end,
1088  const ValueType value
1089 ) {
1090  OPENGM_ASSERT(opengm::isSorted(begin, end));
1091  this->variableIndices_.assign(begin, end);
1092  std::vector<size_t> factorShape(variableIndices_.size());
1093  for(size_t i = 0; i < factorShape.size(); ++i) {
1094  factorShape[i] = static_cast<size_t> (gm.numberOfLabels(this->variableIndices_[i]));
1095  //factorShape[i]=gm.numbersOfStates_[ this->variableIndices_[i] ];
1096  // (gm.numberOfLabels( 1));
1097  }
1098  this->function_.assign();
1099  this->function_.resize(factorShape.begin(), factorShape.end(), value);
1100 }
1101 
1102 template<class T, class I, class L>
1103 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
1106  const GRAPHICAL_MODEL& gm,
1107  VARIABLE_INDEX_ITERATOR begin,
1108  VARIABLE_INDEX_ITERATOR end,
1109  const ValueType value
1110 )
1111 : variableIndices_(begin, end)
1112 {
1113  OPENGM_ASSERT(opengm::isSorted(begin, end));
1114  std::vector<size_t> shape(variableIndices_.size());
1115  for(size_t i = 0; i < shape.size(); ++i) {
1116  shape[i] = gm.numberOfLabels(variableIndices_[i]);
1117  }
1118  this->function_.assign();
1119  this->function_.resize(shape.begin(), shape.end(), value);
1120 }
1121 
1122 template<class T, class I, class L>
1125  const IndependentFactor<T, I, L>& src
1126 )
1127 : variableIndices_(src.variableIndices_)
1128 {
1129  if(src.variableIndices_.size() == 0) {
1130  FunctionType tmp(src.function_(0));
1131  function_ = tmp;
1132  }
1133  else {
1134  function_ = src.function_;
1135  }
1136 }
1137 
1138 template<class T, class I, class L>
1139 template<class GRAPHICAL_MODEL>
1142  const Factor<GRAPHICAL_MODEL>& src
1143 )
1144 : variableIndices_(src.variableIndicesBegin(), src.variableIndicesEnd()) {
1145  //resize dst function
1146  const size_t dimension = src.numberOfVariables();
1147  if(dimension!=0) {
1148  function_.assign();
1149  function_.resize(src.shapeBegin(), src.shapeEnd());
1150  //iterators and walkersbeginbegin
1151  ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
1152  const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
1153  for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
1154  function_(coordinate.begin()) = src(coordinate.begin());
1155  ++walker;
1156  }
1157  }
1158  else{
1159  function_.assign();
1160  size_t indexToScalar[]={0};
1161  //function_(indexToScalar)=(src.operator()(indexToScalar));
1162 
1163  ExplicitFunction<T,I,L> tmp(src.operator()(indexToScalar));
1164  function_ = tmp;
1165  }
1166 }
1167 
1168 template<class T, class I, class L>
1172  const IndependentFactor& src
1173 )
1174 {
1175  if(this != &src) {
1176  function_ = src.function_;
1177  variableIndices_ = src.variableIndices_;
1178  }
1179  return *this;
1180 }
1181 
1182 template<class T, class I, class L>
1183 template<class GRAPHICAL_MODEL>
1185 IndependentFactor<T, I, L>::operator=
1187  const Factor<GRAPHICAL_MODEL>& src
1188 )
1189 {
1190  this->variableIndices_.resize(src.numberOfVariables());
1191  for(size_t i=0;i<src.numberOfVariables();++i)
1192  variableIndices_[i] = src.variableIndex(i);
1193  //resize dst function
1194  const size_t dimension = src.numberOfVariables();
1195  if(dimension!=0) {
1196  function_.assign();
1197  function_.resize(src.shapeBegin(), src.shapeEnd());
1198  //iterators and walkers
1199  ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
1200  const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
1201  for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
1202  function_(scalarIndex) = src(coordinate.begin());
1203  ++walker;
1204  }
1205  }
1206  else {
1207  size_t indexToScalar[]={0};
1208  function_=ExplicitFunction<T>(src(indexToScalar));
1209  }
1210  return * this;
1211 }
1212 
1213 template<class T, class I, class L>
1214 inline size_t
1216 {
1217  return variableIndices_.size();
1218 }
1219 
1221 template<class T, class I, class L>
1225  const IndexType index
1226 ) const
1227 {
1228  OPENGM_ASSERT(index < variableIndices_.size());
1229  return function_.shape(index);
1230 }
1231 
1233 template<class T, class I, class L>
1234 inline size_t
1236 {
1237  return function_.size();
1238 }
1239 
1241 template<class T, class I, class L>
1245  const size_t index
1246 ) const {
1247  if(variableIndices_.size() == 0) {
1248  return 0;
1249  }
1250  OPENGM_ASSERT(index < variableIndices_.size());
1251  return function_.shape(index);
1252 }
1253 
1254 template<class T, class I, class L>
1257 {
1258  return function_.shapeBegin();
1259 }
1260 
1261 template<class T, class I, class L>
1264 {
1265  return function_.shapeEnd();
1266 }
1267 
1268 template<class T, class I, class L>
1271 {
1272  return variableIndices_.begin();
1273 }
1274 
1275 template<class T, class I, class L>
1278 {
1279  return variableIndices_.end();
1280 }
1281 
1282 
1284 template<class T, class I, class L>
1285 inline I
1288  const size_t index
1289 ) const {
1290  OPENGM_ASSERT(index < variableIndices_.size());
1291  return variableIndices_[index];
1292 }
1293 
1294 template<class T, class I, class L>
1295 inline void
1297  if(variableIndices_.size() == 0) {
1298  function_(0) = static_cast<ValueType> (0);
1299  }
1300  else {
1301  T v;
1302  std::vector<size_t> states;
1303  opengm::accumulate<Minimizer>(*this, v, states);
1304  (*this) -= v;
1305  }
1306 }
1307 
1310 template<class T, class I, class L>
1311 template<class ITERATOR>
1312 inline T
1313 IndependentFactor<T, I, L>::operator()
1315  ITERATOR begin
1316 ) const {
1317  return function_(begin);
1318 }
1319 
1320 template<class T, class I, class L>
1321 inline std::vector<I>&
1323 {
1324  return this->variableIndices_;
1325 }
1326 
1327 template<class T, class I, class L>
1328 inline const std::vector<I>&
1330 {
1331  return this->variableIndices_;
1332 }
1333 
1335 template<class T, class I, class L>
1336 inline T
1337 IndependentFactor<T, I, L>::operator()
1339  const IndexType x0
1340 ) const
1341 {
1342  return function_(x0);
1343 }
1344 
1346 template<class T, class I, class L>
1347 inline T
1348 IndependentFactor<T, I, L>::operator()
1350  const IndexType x0,
1351  const IndexType x1
1352 ) const
1353 {
1354  OPENGM_ASSERT(2 == variableIndices_.size());
1355  return function_(x0, x1);
1356 }
1357 
1359 template<class T, class I, class L>
1360 inline T
1361 IndependentFactor<T, I, L>::operator()
1363  const IndexType x0,
1364  const IndexType x1,
1365  const IndexType x2
1366 ) const
1367 {
1368  OPENGM_ASSERT(3 == variableIndices_.size());
1369  return function_(x0, x1, x2);
1370 }
1371 
1373 template<class T, class I, class L>
1374 inline T
1375 IndependentFactor<T, I, L>::operator()
1377  const IndexType x0,
1378  const IndexType x1,
1379  const IndexType x2,
1380  const IndexType x3
1381 ) const
1382 {
1383  OPENGM_ASSERT(4 == variableIndices_.size());
1384  return function_(x0, x1, x2, x3);
1385 }
1386 
1387 template<class T, class I, class L>
1388 template<class UNARY_OPERATOR_TYPE>
1389 inline void
1392  UNARY_OPERATOR_TYPE unaryOperator
1393 ) {
1394  if(this->variableIndices_.size() != 0) {
1395  for(size_t i = 0; i < function_.size(); ++i) {
1396  function_(i) = static_cast<T> (unaryOperator(function_(i)));
1397  }
1398  }
1399  else {
1400  function_(0) = static_cast<T> (unaryOperator(function_(0)));
1401  }
1402 }
1403 
1404 template<class T, class I, class L>
1405 template<class BINARY_OPERATOR_TYPE>
1406 inline void
1409  const T value,
1410  BINARY_OPERATOR_TYPE binaryOperator
1411 ) {
1412  if(this->variableIndices_.size() != 0) {
1413  for(size_t i = 0; i < function_.size(); ++i) {
1414  function_(i) = static_cast<T> (binaryOperator(function_(i), value));
1415  }
1416  }
1417  else {
1418  function_(0) = static_cast<T> (binaryOperator(function_(0), value));
1419  }
1420 }
1421 
1422 template<class T, class I, class L>
1423 template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
1424 inline void
1427  const Factor<GRAPHICAL_MODEL>& srcB,
1428  BINARY_OPERATOR_TYPE binaryOperator
1429 ) {
1430  opengm::operateBinary(*this, srcB, binaryOperator);
1431 }
1432 
1433 template<class T, class I, class L>
1434 template<class BINARY_OPERATOR_TYPE>
1435 inline void
1438  const IndependentFactor<T, I, L>& srcB,
1439  BINARY_OPERATOR_TYPE binaryOperator
1440 ) {
1441  opengm::operateBinary(*this, srcB, binaryOperator);
1442 }
1443 
1444 template<class T, class I, class L>
1445 template<class BINARY_OPERATOR_TYPE>
1446 inline void
1449  const IndependentFactor<T, I, L>& srcA,
1450  const IndependentFactor<T, I, L>& srcB,
1451  BINARY_OPERATOR_TYPE binaryOperator
1452 ) {
1453  opengm::operateBinary(srcA, srcB, *this, binaryOperator);
1454 }
1455 
1456 template<class T, class I, class L>
1457 template<class ACCUMULATOR>
1458 inline void
1461  T& result,
1462  std::vector<LabelType>& resultState
1463 ) const {
1464  opengm::accumulate<ACCUMULATOR> (*this, result, resultState);
1465 }
1466 
1467 template<class T, class I, class L>
1468 template<class ACCUMULATOR>
1469 inline void
1472  T& result
1473 ) const {
1474  opengm::accumulate<ACCUMULATOR> (*this, result);
1475 }
1476 
1477 template<class T, class I, class L>
1478 template<class ACCUMULATOR, class VariablesIterator>
1479 inline void
1482  VariablesIterator begin,
1483  VariablesIterator end,
1484  IndependentFactor<T, I, L>& dstFactor
1485 ) const {
1486  opengm::accumulate<ACCUMULATOR> (*this, begin, end, dstFactor);
1487 }
1488 
1489 template<class T, class I, class L>
1490 template<class ACCUMULATOR, class VariablesIterator>
1491 inline void
1493  VariablesIterator begin,
1494  VariablesIterator end
1495 ) {
1496  opengm::accumulate<ACCUMULATOR> (*this, begin, end);
1497 }
1498 
1501 template<class T, class I, class L>
1502 template<class ITERATOR>
1503 inline T&
1505  ITERATOR begin
1506 ) {
1507  return function_(begin);
1508 }
1509 
1511 template<class T, class I, class L>
1512 inline T&
1514  const IndexType x0
1515 ) {
1516  return function_(x0);
1517 }
1518 
1520 template<class T, class I, class L>
1521 inline T&
1523  const IndexType x0,
1524  const IndexType x1
1525 ) {
1526  OPENGM_ASSERT(2 == variableIndices_.size());
1527  return function_(x0, x1);
1528 }
1529 
1531 template<class T, class I, class L>
1533  const IndexType x0,
1534  const IndexType x1,
1535  const IndexType x2
1536 ) {
1537  OPENGM_ASSERT(3 == variableIndices_.size());
1538  return function_(x0, x1, x2);
1539 }
1540 
1542 template<class T, class I, class L>
1544  const IndexType x0,
1545  const IndexType x1,
1546  const IndexType x2,
1547  const IndexType x3
1548 ) {
1549  OPENGM_ASSERT(4 == variableIndices_.size());
1550  return function_(x0, x1, x2, x3);
1551 }
1552 
1553 template<class T, class I, class L>
1554 template<class ITERATOR>
1555 inline void
1558  ITERATOR out
1559 ) const {
1560  for(size_t j=0; j<variableIndices_.size(); ++j) {
1561  *out = variableIndices_[j];
1562  ++out;
1563  }
1564 }
1565 
1570 template<class T, class I, class L>
1571 template<class INDEX_ITERATOR, class STATE_ITERATOR>
1572 void
1575  INDEX_ITERATOR beginIndex,
1576  INDEX_ITERATOR endIndex,
1577  STATE_ITERATOR beginLabels
1578 ) {
1579  if(this->variableIndices_.size() != 0) {
1580  OPENGM_ASSERT(opengm::isSorted(beginIndex, endIndex));
1581  opengm::FastSequence<IndexType> variablesToFix;
1582  opengm::FastSequence<IndexType> variablesNotToFix;
1583  opengm::FastSequence<IndexType> positionOfVariablesToFix;
1586  // find the variables to fix:
1587  while(beginIndex != endIndex) {
1588  size_t counter = 0;
1589  if(*beginIndex>this->variableIndices_.back()) {
1590  break;
1591  }
1592  for(size_t i = counter; i<this->variableIndices_.size(); ++i) {
1593  if(*beginIndex<this->variableIndices_[i])break;
1594  else if(*beginIndex == this->variableIndices_[i]) {
1595  ++counter;
1596  variablesToFix.push_back(*beginIndex);
1597  newStates.push_back(*beginLabels);
1598  positionOfVariablesToFix.push_back(i);
1599  }
1600  }
1601  ++beginIndex;
1602  ++beginLabels;
1603  }
1604  for(size_t i = 0; i<this->variableIndices_.size(); ++i) {
1605  bool found = false;
1606  for(size_t j = 0; j < variablesToFix.size(); ++j) {
1607  if(variablesToFix[j] == this->variableIndices_[i]) {
1608  found = true;
1609  break;
1610  }
1611  }
1612  if(found == false) {
1613  variablesNotToFix.push_back(this->variableIndices_[i]);
1614  newShape.push_back(this->numberOfLabels(i));
1615  }
1616  }
1617  if(variablesToFix.size() != 0) {
1618  FunctionType& factorFunction = this->function_;
1619  std::vector<LabelType> fullCoordinate(this->numberOfVariables());
1620  if(variablesToFix.size() == this->variableIndices_.size()) {
1621  FunctionType tmp(factorFunction(newStates.begin()));
1622  factorFunction = tmp;
1623  this->variableIndices_.clear();
1624  }
1625  else {
1626  SubShapeWalker<
1627  ShapeIteratorType,
1630  > subWalker
1631  (shapeBegin(), factorFunction.dimension(), positionOfVariablesToFix, newStates);
1632  FunctionType tmp(newShape.begin(), newShape.end());
1633  const size_t subSize = subWalker.subSize();
1634  subWalker.resetCoordinate();
1635  for(size_t i = 0; i < subSize; ++i) {
1636  tmp(i) = factorFunction(subWalker.coordinateTuple().begin());
1637  ++subWalker;
1638  }
1639  factorFunction = tmp;
1640  this->variableIndices_.assign(variablesNotToFix.begin(), variablesNotToFix.end());
1641  }
1642  OPENGM_ASSERT(factorFunction.dimension()==variablesNotToFix.size());
1643  OPENGM_ASSERT(newShape.size()==variablesNotToFix.size());
1644  OPENGM_ASSERT(factorFunction.dimension()==newShape.size());
1645  }
1646  }
1647 }
1648 
1649 #define OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION(BINARY_OPERATOR_SYMBOL, BINARY_INPLACE_OPERATOR_SYMBOL, BINARY_FUNCTOR_NAME) \
1650 template<class T, class I, class L> \
1651 inline IndependentFactor<T, I, L> & \
1652 operator BINARY_INPLACE_OPERATOR_SYMBOL \
1653 ( \
1654  IndependentFactor<T, I, L>& op1, \
1655  const T& op2 \
1656 ) { \
1657  op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T>()); \
1658  return op1; \
1659 } \
1660 template<class GRAPHICAL_MODEL> \
1661 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > & \
1662 operator BINARY_INPLACE_OPERATOR_SYMBOL \
1663 ( \
1664  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
1665  const Factor<GRAPHICAL_MODEL>& op2 \
1666 ) { \
1667  op1.operateBinary(op2, BINARY_FUNCTOR_NAME<typename GRAPHICAL_MODEL::ValueType> ()); \
1668  return op1; \
1669 } \
1670 template<class T, class I, class L> \
1671 inline IndependentFactor<T, I, L> & \
1672 operator BINARY_INPLACE_OPERATOR_SYMBOL \
1673 ( \
1674  IndependentFactor<T, I, L>& op1, \
1675  const IndependentFactor<T, I, L>& op2 \
1676 ) { \
1677  op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T> ()); \
1678  return op1; \
1679 } \
1680 template<class T, class I, class L> \
1681 inline IndependentFactor<T, I, L> \
1682 operator BINARY_OPERATOR_SYMBOL \
1683 ( \
1684  const IndependentFactor<T, I, L>& op1, \
1685  const IndependentFactor<T, I, L>& op2 \
1686 ) { \
1687  IndependentFactor<T, I, L> tmp; \
1688  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
1689  return tmp; \
1690 } \
1691 template<class T, class I, class L> \
1692 inline IndependentFactor<T, I, L> \
1693 operator BINARY_OPERATOR_SYMBOL \
1694 ( \
1695  const T & op1, \
1696  const IndependentFactor<T, I, L>& op2 \
1697 ) { \
1698  IndependentFactor<T, I, L> tmp; \
1699  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
1700  return tmp; \
1701 } \
1702 template<class T, class I, class L> \
1703 inline IndependentFactor<T, I, L> \
1704 operator BINARY_OPERATOR_SYMBOL \
1705 ( \
1706  const IndependentFactor<T, I, L>& op1, \
1707  const T & op2 \
1708 ) { \
1709  IndependentFactor<T, I, L> tmp; \
1710  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
1711  return tmp; \
1712 } \
1713 template<class GRAPHICAL_MODEL> \
1714 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1715 operator BINARY_OPERATOR_SYMBOL \
1716 ( \
1717  const Factor<GRAPHICAL_MODEL> & op1, \
1718  const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op2 \
1719 ) { \
1720  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1721  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1722  return tmp; \
1723 } \
1724 template<class GRAPHICAL_MODEL> \
1725 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1726 operator BINARY_OPERATOR_SYMBOL \
1727 ( \
1728  const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
1729  const Factor<GRAPHICAL_MODEL> & op2 \
1730 ) { \
1731  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1732  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1733  return tmp; \
1734 } \
1735 template<class GRAPHICAL_MODEL> \
1736 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1737 operator BINARY_OPERATOR_SYMBOL \
1738 ( \
1739  const Factor<GRAPHICAL_MODEL>& op1, \
1740  const Factor<GRAPHICAL_MODEL>& op2 \
1741 ) { \
1742  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1743  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1744  return tmp; \
1745 } \
1746 template<class GRAPHICAL_MODEL> \
1747 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1748 operator BINARY_OPERATOR_SYMBOL \
1749 ( \
1750  const Factor<GRAPHICAL_MODEL>& op1, \
1751  const typename GRAPHICAL_MODEL::ValueType & op2 \
1752 ) { \
1753  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1754  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1755  return tmp; \
1756 } \
1757 template<class GRAPHICAL_MODEL> \
1758 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1759 operator BINARY_OPERATOR_SYMBOL \
1760 ( \
1761  const typename GRAPHICAL_MODEL::ValueType & op1, \
1762  const Factor<GRAPHICAL_MODEL>& op2 \
1763 ) { \
1764  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1765  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1766  return tmp; \
1767 } \
1768 
1775 
1777 
1778 namespace functionwrapper {
1779 
1780  namespace executor {
1781 
1782  template<size_t IX, size_t DX>
1783  template<class GM, class FACTOR>
1784  void FactorInvariant<IX, DX, false>::op
1785  (
1786  const GM & gm,
1787  const FACTOR & factor
1788  ) {
1789  typedef typename GM::IndexType IndexType;
1790  typedef typename GM::LabelType LabelType;
1791  if(factor.functionType() == IX) {
1792  const IndexType functionIndex = static_cast<IndexType>(factor.functionIndex());
1793  const size_t numVar = static_cast<size_t>(factor.numberOfVariables());
1794  const size_t dimFunction = static_cast<size_t>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].dimension());
1795  const IndexType numberOfFunctions = static_cast<IndexType>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_.size());
1796 
1797  OPENGM_CHECK_OP(functionIndex , < ,numberOfFunctions,
1798  "function index must be smaller than numberOfFunctions for that given function type")
1799  OPENGM_CHECK_OP(numVar , == ,dimFunction,
1800  "number of variable indices of the factor must match the functions dimension")
1801  for(size_t i = 0; i < numVar; ++i) {
1802  const LabelType numberOfLabelsOfFunction = meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].shape(i);
1803  OPENGM_CHECK_OP(factor.numberOfLabels(i) , == , numberOfLabelsOfFunction,
1804  "number of labels of the variables in a factor must match the functions shape")
1805  }
1806  }
1807  else {
1808  FactorInvariant
1809  <
1810  meta::Increment<IX>::value,
1811  DX,
1812  meta::EqualNumber< meta::Increment<IX>::value, DX>::value
1813  >::op(gm, factor);
1814  }
1815  }
1816 
1817  template<size_t IX, size_t DX>
1818  template<class GM, class FACTOR>
1819  void FactorInvariant<IX, DX, true>::op
1820  (
1821  const GM & gm,
1822  const FACTOR & factor
1823  ) {
1824  throw RuntimeError("Incorrect function type id.");
1825  }
1826 
1827  } // namespace executor
1828 } // namespace functionwrapper
1829 
1831 
1832 } // namespace opengm
1833 
1834 #endif // #ifndef OPENGM_GRAPHICALMODEL_FACTOR_HXX
void assign(const allocator_type &=allocator_type())
Clear Marray.
Definition: marray.hxx:3350
void accumulate(ValueType &, std::vector< LabelType > &) const
VariablesIteratorType variableIndicesEnd() const
void forAtLeastAllUniqueValues(FUNCTOR &functor) const
call a functor for at least all unique values in no defined order
The OpenGM namespace.
Definition: config.hxx:43
VariablesIteratorType variableIndicesBegin() const
ValueType sum() const
Factor (with corresponding function and variable indices), independent of a GraphicalModel.
size_t size() const
size
bool binaryProperty() const
compute a binary property of a factor
IndependentFactor & operator=(const IndependentFactor &)
void forAllValuesInSwitchedOrder(FUNCTOR &functor) const
IndexType dimension() const
detail_types::UInt8Type UInt8Type
SizeT.
Definition: config.hxx:294
UInt8Type functionType() const
IndexType size() const
bool isLinearConstraint() const
ShapeIteratorType shapeEnd() const
void variableIndices(ITERATOR out) const
GraphicalModelType::LabelType LabelType
const FunctionType & function() const
void push_back(const T &)
append a value
STL namespace.
bool isTruncatedAbsoluteDifference() const
void load(GM_ &gm, const std::string &, const std::string &)
ShapeIteratorType shapeBegin() const
void copyValuesSwitchedOrder(ITERATOR iterator) const
GraphicalModelType::ValueType ValueType
ValueType max() const
Vector that stores values on the stack if size is smaller than MAX_STACK.
T const * end() const
end iterator
VariablesIteratorType variableIndicesBegin() const
GraphicalModelType::FunctionTypeList FunctionTypeList
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
GRAPHICAL_MODEL * GraphicalModelPointerType
IndexType variableIndex(const size_t) const
return the index of the j-th variable
std::vector< IndexType >::const_iterator VariablesIteratorType
IndexType shape(const size_t dimIndex) const
return the extension of the value table of the of the function in a specific dimension ...
VariablesIteratorType variableIndicesEnd() const
ValueType min() const
void forAllValuesInOrder(FUNCTOR &functor) const
call a functor for all values in last coordinate major order
#define OPENGM_META_ASSERT(assertion, msg)
opengm compile time assertion
Definition: opengm.hxx:87
void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR)
opengm::AccessorIterator< ShapeAccessorType, true > ShapeIteratorType
Abstraction (wrapper class) of factors, independent of the function used to implement the factor...
IndexType numberOfVariables() const
GraphicalModelType::IndexType IndexType
const size_t dimension() const
Get the dimension.
Definition: marray.hxx:1711
void callFunctor(FUNCTOR &f) const
call a functor for the function of the factor the first and only argument passed to the functor is th...
ExplicitFunction< ValueType, IndexType, LabelType > FunctionType
const std::vector< IndexType > & variableIndexSequence() const
ValueType product() const
#define OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION(BINARY_OPERATOR_SYMBOL, BINARY_INPLACE_OPERATOR_SYMBOL, BINARY_FUNCTOR_NAME)
ViFunctor(const FACTOR &factor, FUNCTOR &functor)
void operateBinary(const T value, BINARY_OPERATOR_TYPE binaryOperator)
VisContainerType::const_iterator VariablesIteratorType
meta::TypeListGenerator< FunctionType >::type FunctionTypeList
bool isAbsoluteDifference() const
std::vector< IndexType > VisContainerType
void callViFunctor(FUNCTOR &f) const
call a functor for the function of the factor the first to arguments passed to the functor are a begi...
void variableIndices(ITERATOR) const
void fixVariables(INDEX_ITERATOR, INDEX_ITERATOR, STATE_ITERATOR)
assign specific labels to a specific subset of variables (reduces the order)
IndexType variableIndex(const IndexType) const
return the index of the j-th variable
ValueType operator()(ITERATOR) const
evaluate the factor for a sequence of labels
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Definition: submodel2.hxx:24
FACTOR::VariablesIteratorType ViIterator
T const * begin() const
begin iterator
GRAPHICAL_MODEL GraphicalModelType
bool isSubmodular() const
const meta::TypeAtTypeList< FunctionTypeList, FUNCTION_TYPE_INDEX >::type & function() const
IndexType functionIndex() const
void forAllValuesInAnyOrder(FUNCTOR &functor) const
call a functor for all values in no defined order
Factor & operator=(const Factor &)
void copyValues(ITERATOR iterator) const
copies the values of a factors into an iterator
bool isSquaredDifference() const
void operateUnary(UNARY_OPERATOR_TYPE unaryOperator)
void operator()(const FUNCTION &function)
bool isGeneralizedPotts() const
bool isTruncatedSquaredDifference() const
IndexType numberOfLabels(const IndexType) const
return the number of labels of a specific variable
ValueType valueProperty() const
VectorView< std::vector< IndexType >, IndexType > VisContainerType
ShapeIteratorType shapeEnd() const
ShapeIteratorType shapeBegin() const
size_t size() const
return the number of entries of the value table of the function
OpenGM runtime error.
Definition: opengm.hxx:100
void save(const GM &, const std::string &, const std::string &)
save a graphical model to an HDF5 file
T operator()(ITERATOR) const
evaluate the function underlying the factor, given labels to be assigned the variables ...
IndexType numberOfLabels(const IndexType) const
return the number of labels of the j-th variable
IndexType shape(const IndexType) const
return the extension a value table encoding this factor would have in the dimension of the j-th varia...