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 
196 
197 
198  template<class LABEL_ITER>
200  typedef SubsetAccessor<VariablesIteratorType, LABEL_ITER> Accessor;
201  typedef AccessorIterator<Accessor, true> Iter;
202  };
203 
204  template<class LABEL_ITER>
206  gmToFactorLabelsBegin(LABEL_ITER gmLabelsBegin)const{
207  typedef typename GmToFactorLabelIter<LABEL_ITER>::Accessor Accessor;
208  Accessor accessor(variableIndicesBegin(),variableIndicesEnd(), gmLabelsBegin);
209  return Iter(accessor, 0);
210  }
211 
212  template<class LABEL_ITER>
214  gmToFactorLabelsEnd(LABEL_ITER gmLabelsBegin)const{
215  typedef typename GmToFactorLabelIter<LABEL_ITER>::Accessor Accessor;
216  typedef typename GmToFactorLabelIter<LABEL_ITER>::Iter Iter;
217  Accessor accessor(variableIndicesBegin(),variableIndicesEnd(), gmLabelsBegin);
218  return Iter(accessor, this->numberOfVariables());
219  }
220 
221 
222 private:
223  void testInvariant() const;
224  //std::vector<IndexType> & variableIndexSequence();
225  const VisContainerType & variableIndexSequence() const;
226  template<size_t FUNCTION_TYPE_INDEX>
227  typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_TYPE_INDEX>::type& function();
228 
229  GraphicalModelPointerType gm_;
230  IndexType functionIndex_;
231  opengm::UInt8Type functionTypeId_;
232  //std::vector<IndexType> variableIndices_;
233  //IndexType order_;
234  //IndexType indexInVisVector_;
235  VisContainerType vis_;
236 template<typename, typename, typename, typename>
237  friend class GraphicalModel;
238 template<size_t>
239  friend struct opengm::detail_graphical_model::FunctionWrapper;
240 template<size_t, size_t, bool>
241  friend struct opengm::detail_graphical_model::FunctionWrapperExecutor;
242 template<typename>
243  friend class Factor;
244 template<typename GM_>
245  friend void opengm::hdf5::save(const GM_&, const std::string&, const std::string&);
246 template<typename GM_>
247  friend void opengm::hdf5::load(GM_&, const std::string&, const std::string&);
248 template<typename, typename, typename >
249  friend class IndependentFactor;
250 
251 // friends for unary
252 template<class, class, class, class>
253  friend class opengm::functionwrapper::binary::OperationWrapperSelector;
254 template<class , class, class>
255  friend class opengm::functionwrapper::unary::OperationWrapperSelector;
256 
257 template<class, class, class, class, class, class, class>
258  friend class opengm::functionwrapper::binary::OperationWrapper;
259 
260 template <class, size_t>
261  friend class opengm::meta::GetFunction;
262 template<class, class, class>
263  friend class opengm::functionwrapper::AccumulateSomeWrapper;
264 
265 template<class, class, class, size_t, size_t, bool >
266  friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
267 
268 template<class, class, class, size_t, size_t, bool>
269  friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
270 
271 template<class A, class B, class OP, size_t IX, size_t DX, bool>
272  friend class opengm::functionwrapper::executor::unary::OperationExecutor;
273 };
274 
276 template<class T, class I, class L>
278 public:
279  typedef T ValueType;
280  typedef I IndexType;
281  typedef L LabelType;
283  typedef typename meta::TypeListGenerator<FunctionType>::type FunctionTypeList;
285  NrOfFunctionTypes = 1
286  };
287  typedef const size_t* ShapeIteratorType;
288  typedef typename std::vector<IndexType>::const_iterator VariablesIteratorType;
289 
290  typedef std::vector<IndexType> VisContainerType;
291 
293  IndependentFactor(const ValueType);
294 
295  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
296  IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
297  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
298  IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
299  template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
300  IndependentFactor(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType = ValueType());
302  template<class GRAPHICAL_MODEL>
304  IndependentFactor& operator=(const IndependentFactor&);
305  template<class GRAPHICAL_MODEL>
306  IndependentFactor& operator=(const Factor<GRAPHICAL_MODEL>&);
307  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
308  void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
309  template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
310  void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
311  template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
312  void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR);
313  template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
314  void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType);
315  void assign(const ValueType);
316 
317  ShapeIteratorType shapeBegin() const;
318  ShapeIteratorType shapeEnd() const;
319  VariablesIteratorType variableIndicesBegin()const;
320  VariablesIteratorType variableIndicesEnd()const;
321  const std::vector<IndexType>& variableIndexSequence() const;
322  template<size_t FUNCTION_TYPE_INDEX>
323  const FunctionType& function() const;
324  size_t numberOfVariables() const;
325  IndexType numberOfLabels(const IndexType) const;
326  IndexType shape(const size_t dimIndex) const;
327  size_t size() const;
328  IndexType variableIndex(const size_t) const;
329  template<class ITERATOR>
330  void variableIndices(ITERATOR) const;
331  template<class ITERATOR>
332  T operator()(ITERATOR) const;
333  T operator()(const IndexType) const;
334  T operator()(const IndexType, const IndexType) const;
335  T operator()(const IndexType, const IndexType, const IndexType) const;
336  T operator()(const IndexType, const IndexType, const IndexType, const IndexType) const;
337 
338  template<class INDEX_ITERATOR, class STATE_ITERATOR>
339  void fixVariables(INDEX_ITERATOR, INDEX_ITERATOR, STATE_ITERATOR);
340  template<class ITERATOR>
341  T& operator()(ITERATOR);
342  T& operator()(const IndexType);
343  T& operator()(const IndexType, const IndexType);
344  T& operator()(const IndexType, const IndexType, const IndexType);
345  T& operator()(const IndexType, const IndexType, const IndexType, const IndexType);
346  template<class UNARY_OPERATOR_TYPE>
347  void operateUnary(UNARY_OPERATOR_TYPE unaryOperator);
348  template<class BINARY_OPERATOR_TYPE>
349  void operateBinary(const T value, BINARY_OPERATOR_TYPE binaryOperator);
350  template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
351  void operateBinary(const Factor<GRAPHICAL_MODEL>&, BINARY_OPERATOR_TYPE binaryOperator);
352  template<class BINARY_OPERATOR_TYPE>
353  void operateBinary(const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
354  template<class BINARY_OPERATOR_TYPE>
355  void operateBinary(const IndependentFactor<T, I, L>&, const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
356  void subtractOffset();
357 
358  template<class ACCUMULATOR>
359  void accumulate(ValueType&, std::vector<LabelType>&) const;
360  template<class ACCUMULATOR>
361  void accumulate(ValueType&) const;
362  template<class ACCUMULATOR, class VariablesIterator>
363  void accumulate(VariablesIterator, VariablesIterator, IndependentFactor<T, I, L> &) const;
364  template<class ACCUMULATOR, class VariablesIterator>
365  void accumulate(VariablesIterator, VariablesIterator) ;
366  const FunctionType& function() const;
367 
368  bool isPotts()
369  { return function_.isPotts(); }
371  { return function_.isGeneralizedPotts(); }
373  { return function_.isSubmodular(); }
375  { return function_.isSquaredDifference(); }
377  { return function_.isTruncatedSquaredDifference(); }
379  { return function_.isAbsoluteDifference(); }
381  { return function_.isTruncatedAbsoluteDifference(); }
382 
383  T min() {return function_.min();}
384  T max() {return function_.max();}
385  T sum() {return function_.sum();}
386  T product() {return function_.product();}
387 
388 private:
389  template<size_t FUNCTION_TYPE_INDEX>
390  FunctionType& function();
391  std::vector<IndexType>& variableIndexSequence();
392 
393  std::vector<IndexType> variableIndices_;
394  FunctionType function_;
395 
396 template<typename>
397  friend class Factor;
398 template<typename, typename, typename, typename>
399  friend class GraphicalModel;
400 //friends for unary
401 template<class, class, class, class>
402  friend class opengm::functionwrapper::binary::OperationWrapperSelector;
403 template<class , class, class>
404  friend class opengm::functionwrapper::unary::OperationWrapperSelector;
405 template<class, class, class, class, class, class, class>
406  friend class opengm::functionwrapper::binary::OperationWrapper;
407 template <class, size_t>
408  friend class opengm::meta::GetFunction;
409 template<class, class, class>
410  friend class opengm::functionwrapper::AccumulateSomeWrapper;
411 template<class, class, class, size_t, size_t, bool>
412  friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
413 template<class, class, class, size_t, size_t, bool>
414  friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
415 template<class A, class B, class OP, size_t IX, size_t DX, bool>
416  friend class opengm::functionwrapper::executor::unary::OperationExecutor;
417 template<class ACC, class A, class ViAccIterator>
418  friend void accumulate(A &, ViAccIterator, ViAccIterator );
419 };
420 
421 
422 template<class GRAPHICAL_MODEL>
424 : gm_(NULL),
425  functionIndex_(),
426  vis_()
427 {}
428 
430 template<class GRAPHICAL_MODEL>
432 (
435  const UInt8Type functionTypeId,
436  const typename Factor<GRAPHICAL_MODEL>::IndexType order,
437  const typename Factor<GRAPHICAL_MODEL>::IndexType indexInVisVector
438 )
439 : gm_(gm),
440  functionIndex_(functionIndex),
441  functionTypeId_(functionTypeId),
442  vis_(gm->factorsVis_, indexInVisVector,order)
443 {
444  /*
445  if(!opengm::NO_DEBUG) {
446  if(variableIndices_.size() != 0) {
447  OPENGM_ASSERT(variableIndices_[0] < gm->numberOfVariables());
448  for(size_t i = 1; i < variableIndices_.size(); ++i) {
449  OPENGM_ASSERT(variableIndices_[i] < gm->numberOfVariables());
450  }
451  }
452  }
453  */
454 }
455 
457 template<class GRAPHICAL_MODEL>
459 (
461 )
462 : gm_(gm),
463  functionIndex_(0),
464  functionTypeId_(0),
465  vis_(gm_->factorsVis_)
466 {}
467 
468 template<class GRAPHICAL_MODEL>
470 (
471  const Factor& src
472 )
473 : gm_(src.gm_),
474  functionIndex_(src.functionIndex_),
475  functionTypeId_(src.functionTypeId_),
476  vis_(src.vis_)
477 {}
478 
479 template<class GRAPHICAL_MODEL>
482 (
483  const Factor& src
484 )
485 {
486  if(&src != this) {
487  functionTypeId_ = src.functionTypeId_;
488  functionIndex_ = src.functionIndex_;
489  //variableIndices_ = src.variableIndices_;
490  vis_=src.vis_;
491  }
492  return *this;
493 }
494 
495 template<class GRAPHICAL_MODEL>
498 {
499  return ShapeIteratorType(ShapeAccessorType(this), 0);
500 }
501 
502 template<class GRAPHICAL_MODEL>
505 {
506  return ShapeIteratorType(ShapeAccessorType(this), vis_.size());
507 }
508 
509 
510 
511 template<class GRAPHICAL_MODEL>
512 inline const typename Factor<GRAPHICAL_MODEL>::VisContainerType &
514 {
515  return this->vis_;
516 }
517 
518 
520 template<class GRAPHICAL_MODEL>
521 inline typename Factor<GRAPHICAL_MODEL>::IndexType
523 (
524  const IndexType j
525 ) const {
526  return gm_->numberOfLabels(vis_[j]);
527 }
528 
529 template<class GRAPHICAL_MODEL>
532 {
533  return vis_.size();
534 }
535 
537 template<class GRAPHICAL_MODEL>
540  const IndexType j
541 ) const
542 {
543  return vis_[j];
544 }
545 
547 template<class GRAPHICAL_MODEL>
550  const IndexType j
551 ) const
552 {
553  OPENGM_ASSERT(j < vis_.size());
554  return gm_->numberOfLabels(vis_[j]);
555 }
556 
559 template<class GRAPHICAL_MODEL>
560 template<class ITERATOR>
563  ITERATOR begin
564 ) const
565 {
566  return opengm::detail_graphical_model::FunctionWrapper<
568  >::getValue (this->gm_, begin, functionIndex_, functionTypeId_);
569 }
570 
571 
575 template<class GRAPHICAL_MODEL>
576 template<class FUNCTOR>
577 inline void
579  FUNCTOR & functor
580 ) const
581 {
582  return opengm::detail_graphical_model::FunctionWrapper<
584  >::callFunctor(this->gm_, functionIndex_, functionTypeId_,functor);
585 }
586 
590 template<class GRAPHICAL_MODEL>
591 template<class FUNCTOR>
592 inline void
594  FUNCTOR & functor
595 ) const
596 {
597  ViFunctor< Factor<GRAPHICAL_MODEL> , FUNCTOR> viFunctor(*this,functor);
598 
599  return opengm::detail_graphical_model::FunctionWrapper<
601  >::callFunctor(this->gm_, functionIndex_, functionTypeId_,viFunctor);
602 }
603 
604 
607 template<class GRAPHICAL_MODEL>
608 template<class ITERATOR>
609 inline void
611  ITERATOR begin
612 ) const
613 {
614  opengm::detail_graphical_model::FunctionWrapper<
616  >::getValues (this->gm_, begin, functionIndex_, functionTypeId_);
617 }
618 
619 template<class GRAPHICAL_MODEL>
620 template<class ITERATOR>
621 inline void
623  ITERATOR begin
624 ) const
625 {
626  opengm::detail_graphical_model::FunctionWrapper<
628  >::getValuesSwitchedOrder (this->gm_, begin, functionIndex_, functionTypeId_);
629 }
630 
633 template<class GRAPHICAL_MODEL>
634 template<int FunctionType, class ITERATOR>
636 Factor<GRAPHICAL_MODEL>::operator()
637 (
638  ITERATOR begin
639 ) const {
640  return gm_-> template functions<FunctionType>()[functionIndex_].operator()(begin);
641 }
642 
654 template<class GRAPHICAL_MODEL>
655 template<int PROPERTY>
656 inline bool
658 {
659  return opengm::detail_graphical_model::FunctionWrapper<
661  >:: template binaryProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
662 }
663 
664 
676 template<class GRAPHICAL_MODEL>
677 template<int PROPERTY>
678 inline typename GRAPHICAL_MODEL::ValueType
680 {
681  return opengm::detail_graphical_model::FunctionWrapper<
683  >:: template valueProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
684 }
685 
695 template<class GRAPHICAL_MODEL>
696 template<class FUNCTOR>
697 inline void
699 (
700  FUNCTOR & functor
701 )const{
702  opengm::detail_graphical_model::FunctionWrapper<
704  >:: template forAllValuesInAnyOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
705 }
706 
707 
717 template<class GRAPHICAL_MODEL>
718 template<class FUNCTOR>
719 inline void
721 (
722  FUNCTOR & functor
723 )const{
724  opengm::detail_graphical_model::FunctionWrapper<
726  >:: template forAtLeastAllUniqueValues<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
727 }
728 
738 template<class GRAPHICAL_MODEL>
739 template<class FUNCTOR>
740 inline void
742 (
743  FUNCTOR & functor
744 )const{
745  opengm::detail_graphical_model::FunctionWrapper<
747  >:: template forAllValuesInOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
748 }
749 
750 template<class GRAPHICAL_MODEL>
751 template<class FUNCTOR>
752 inline void
754 (
755  FUNCTOR & functor
756 )const{
757  opengm::detail_graphical_model::FunctionWrapper<
759  >:: template forAllValuesInSwitchedOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
760 }
761 
762 template<class GRAPHICAL_MODEL>
763 inline bool
765 {
766  return opengm::detail_graphical_model::FunctionWrapper<
768  >::isPotts (this->gm_, functionIndex_, functionTypeId_);
769 }
770 
771 template<class GRAPHICAL_MODEL>
772 inline bool
774 {
775  return opengm::detail_graphical_model::FunctionWrapper<
777  >::isGeneralizedPotts (this->gm_, functionIndex_, functionTypeId_);
778 }
779 
780 template<class GRAPHICAL_MODEL>
781 inline bool
783 {
784  return opengm::detail_graphical_model::FunctionWrapper<
786  >::isSubmodular (this->gm_, functionIndex_, functionTypeId_);
787 }
788 
789 template<class GRAPHICAL_MODEL>
790 inline bool
792 {
793  if(this->numberOfVariables()==2) {
794  return opengm::detail_graphical_model::FunctionWrapper<
796  >::isSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
797  }
798  else {
799  return false;
800  }
801 }
802 
803 template<class GRAPHICAL_MODEL>
804 inline bool
806 {
807  if(this->numberOfVariables()==2) {
808  return opengm::detail_graphical_model::FunctionWrapper<
810  >::isTruncatedSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
811  }
812  else {
813  return false;
814  }
815 }
816 
817 template<class GRAPHICAL_MODEL>
818 inline bool
820 {
821  if(this->numberOfVariables() == 2) {
822  return opengm::detail_graphical_model::FunctionWrapper<
824  >::isAbsoluteDifference(this->gm_, functionIndex_, functionTypeId_);
825  }
826  else {
827  return false;
828  }
829 }
830 
831 template<class GRAPHICAL_MODEL>
832 inline bool
834 {
835  if(this->numberOfVariables()==2) {
836  return opengm::detail_graphical_model::FunctionWrapper<
838  >::isTruncatedAbsoluteDifference (this->gm_, functionIndex_, functionTypeId_);
839  }
840  else{
841  return false;
842  }
843 }
844 
845 template<class GRAPHICAL_MODEL>
846 inline bool
848 {
849  return opengm::detail_graphical_model::FunctionWrapper<
851  >::isLinearConstraint (this->gm_, functionIndex_, functionTypeId_);
852 }
853 
854 template<class GRAPHICAL_MODEL>
857  return opengm::detail_graphical_model::FunctionWrapper<
859  >::sum (this->gm_, functionIndex_, functionTypeId_);
860 }
861 
862 template<class GRAPHICAL_MODEL>
865  return opengm::detail_graphical_model::FunctionWrapper<
867  >::product (this->gm_, functionIndex_, functionTypeId_);
868 }
869 
870 template<class GRAPHICAL_MODEL>
873  return opengm::detail_graphical_model::FunctionWrapper<
875  >::min (this->gm_, functionIndex_, functionTypeId_);
876 }
877 
878 template<class GRAPHICAL_MODEL>
881  return opengm::detail_graphical_model::FunctionWrapper<
883  >::max (this->gm_, functionIndex_, functionTypeId_);
884 }
885 
886 template<class GRAPHICAL_MODEL>
887 template<class ITERATOR>
889 (
890  ITERATOR out
891 ) const {
892  for(IndexType j = 0; j < numberOfVariables(); ++j) {
893  *out = this->variableIndex(j);
894  ++out;
895  }
896 }
897 
898 template<class GRAPHICAL_MODEL>
899 template<size_t FUNCTION_TYPE_INDEX>
900 inline typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
902  typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
903  OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
904  return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
905  functionData_.functions_[functionIndex_];
906 }
907 
908 template<class GRAPHICAL_MODEL>
909 template<size_t FUNCTION_TYPE_INDEX>
910 inline const typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
912  typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
913  OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
914  return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
915  functionData_.functions_[functionIndex_];
916 }
917 
918 template<class GRAPHICAL_MODEL>
921  return vis_.begin();
922 }
923 
924 template<class GRAPHICAL_MODEL>
927  return vis_.end();
928 }
929 
930 template<class GRAPHICAL_MODEL>
933 {
934  if(vis_.size() != 0) {
935  size_t val = this->shape(0);
936  for(size_t i = 1; i<this->numberOfVariables(); ++i) {
937  val *= this->shape(i);
938  }
939  return val;
940  }
941  return 1;
942 }
943 
944 template<class GRAPHICAL_MODEL>
945 inline void Factor<GRAPHICAL_MODEL>::testInvariant() const {
946  opengm::functionwrapper::executor::FactorInvariant
947  <
948  0,
950  meta::EqualNumber<Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes, 0>::value
951  >::op( *gm_, *this);
952 }
953 
954 template<class GRAPHICAL_MODEL>
955 inline opengm::UInt8Type
957  return static_cast<UInt8Type> (functionTypeId_);
958 }
959 
960 template<class GRAPHICAL_MODEL>
963  return functionIndex_;
964 }
965 
966 template<class T, class I, class L>
968 : variableIndices_(),
969  function_(1.0)
970 {}
971 
973 template<class T, class I, class L>
975 (
976  const ValueType constant
977 )
978 : variableIndices_(),
979  function_(constant)
980 {}
981 
987 template<class T, class I, class L>
988 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
990 (
991  VARIABLE_INDEX_ITERATOR beginVi,
992  VARIABLE_INDEX_ITERATOR endVi,
993  SHAPE_ITERATOR beginShape,
994  SHAPE_ITERATOR endShape
995 )
996 : variableIndices_(beginVi, endVi),
997  function_(beginShape, endShape, 1)
998 {
999  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
1000  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
1001 }
1002 
1003 template<class T, class I, class L>
1004 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
1007  VARIABLE_INDEX_ITERATOR beginVi,
1008  VARIABLE_INDEX_ITERATOR endVi,
1009  SHAPE_ITERATOR beginShape,
1010  SHAPE_ITERATOR endShape,
1011  const ValueType constant
1012 )
1013 : variableIndices_(beginVi, endVi),
1014  function_(beginShape, endShape, constant)
1015 {
1016  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
1017  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
1018 }
1019 
1020 template<class T, class I, class L>
1021 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
1024  VARIABLE_INDEX_ITERATOR beginVi,
1025  VARIABLE_INDEX_ITERATOR endVi,
1026  SHAPE_ITERATOR beginShape,
1027  SHAPE_ITERATOR endShape
1028 ) {
1029  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
1030  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
1031  function_.assign();
1032  function_.resize(beginShape, endShape, 1);
1033  variableIndices_.assign(beginVi, endVi);
1034 }
1035 
1036 template<class T, class I, class L>
1037 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
1040  VARIABLE_INDEX_ITERATOR beginVi,
1041  VARIABLE_INDEX_ITERATOR endVi,
1042  SHAPE_ITERATOR beginShape,
1043  SHAPE_ITERATOR endShape,
1044  const ValueType constant
1045 ) {
1046  OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
1047  OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
1048  function_.assign();
1049  function_.resize(beginShape, endShape, constant);
1050  variableIndices_.assign(beginVi, endVi);
1051 }
1052 
1054 template<class T, class I, class L>
1055 template<size_t FUNCTION_TYPE_INDEX>
1058 {
1059  return function_;
1060 }
1061 
1062 template<class T, class I, class L>
1063 inline const typename IndependentFactor<T, I, L>::FunctionType&
1065 {
1066  return function_;
1067 }
1068 
1069 template<class T, class I, class L>
1070 template<size_t FUNCTION_TYPE_INDEX>
1071 inline const typename IndependentFactor<T, I, L>::FunctionType&
1073 {
1074  return function_;
1075 }
1076 
1077 template<class T, class I, class L>
1078 inline void
1081  const ValueType constant
1082 )
1083 {
1084  typename IndependentFactor<T, I, L>::FunctionType c(constant);
1085  function_ = c;
1086  variableIndices_.clear();
1087 }
1088 
1089 template<class T, class I, class L>
1090 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
1093  const GRAPHICAL_MODEL& gm,
1094  VARIABLE_INDEX_ITERATOR begin,
1095  VARIABLE_INDEX_ITERATOR end
1096 )
1097 {
1098  OPENGM_ASSERT(opengm::isSorted(begin, end));
1099  this->variableIndices_.assign(begin, end);
1100  std::vector<size_t> factorShape(variableIndices_.size());
1101  for(size_t i = 0; i < factorShape.size(); ++i) {
1102  factorShape[i] = gm.numberOfLabels(variableIndices_[i]);
1103  }
1104  this->function_.assign();
1105  this->function_.resize(factorShape.begin(), factorShape.end());
1106 }
1107 
1108 template<class T, class I, class L>
1109 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
1112  const GRAPHICAL_MODEL& gm,
1113  VARIABLE_INDEX_ITERATOR begin,
1114  VARIABLE_INDEX_ITERATOR end,
1115  const ValueType value
1116 ) {
1117  OPENGM_ASSERT(opengm::isSorted(begin, end));
1118  this->variableIndices_.assign(begin, end);
1119  std::vector<size_t> factorShape(variableIndices_.size());
1120  for(size_t i = 0; i < factorShape.size(); ++i) {
1121  factorShape[i] = static_cast<size_t> (gm.numberOfLabels(this->variableIndices_[i]));
1122  //factorShape[i]=gm.numbersOfStates_[ this->variableIndices_[i] ];
1123  // (gm.numberOfLabels( 1));
1124  }
1125  this->function_.assign();
1126  this->function_.resize(factorShape.begin(), factorShape.end(), value);
1127 }
1128 
1129 template<class T, class I, class L>
1130 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
1133  const GRAPHICAL_MODEL& gm,
1134  VARIABLE_INDEX_ITERATOR begin,
1135  VARIABLE_INDEX_ITERATOR end,
1136  const ValueType value
1137 )
1138 : variableIndices_(begin, end)
1139 {
1140  OPENGM_ASSERT(opengm::isSorted(begin, end));
1141  std::vector<size_t> shape(variableIndices_.size());
1142  for(size_t i = 0; i < shape.size(); ++i) {
1143  shape[i] = gm.numberOfLabels(variableIndices_[i]);
1144  }
1145  this->function_.assign();
1146  this->function_.resize(shape.begin(), shape.end(), value);
1147 }
1148 
1149 template<class T, class I, class L>
1152  const IndependentFactor<T, I, L>& src
1153 )
1154 : variableIndices_(src.variableIndices_)
1155 {
1156  if(src.variableIndices_.size() == 0) {
1157  FunctionType tmp(src.function_(0));
1158  function_ = tmp;
1159  }
1160  else {
1161  function_ = src.function_;
1162  }
1163 }
1164 
1165 template<class T, class I, class L>
1166 template<class GRAPHICAL_MODEL>
1169  const Factor<GRAPHICAL_MODEL>& src
1170 )
1171 : variableIndices_(src.variableIndicesBegin(), src.variableIndicesEnd()) {
1172  //resize dst function
1173  const size_t dimension = src.numberOfVariables();
1174  if(dimension!=0) {
1175  function_.assign();
1176  function_.resize(src.shapeBegin(), src.shapeEnd());
1177  //iterators and walkersbeginbegin
1178  ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
1179  const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
1180  for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
1181  function_(coordinate.begin()) = src(coordinate.begin());
1182  ++walker;
1183  }
1184  }
1185  else{
1186  function_.assign();
1187  size_t indexToScalar[]={0};
1188  //function_(indexToScalar)=(src.operator()(indexToScalar));
1189 
1190  ExplicitFunction<T,I,L> tmp(src.operator()(indexToScalar));
1191  function_ = tmp;
1192  }
1193 }
1194 
1195 template<class T, class I, class L>
1199  const IndependentFactor& src
1200 )
1201 {
1202  if(this != &src) {
1203  function_ = src.function_;
1204  variableIndices_ = src.variableIndices_;
1205  }
1206  return *this;
1207 }
1208 
1209 template<class T, class I, class L>
1210 template<class GRAPHICAL_MODEL>
1212 IndependentFactor<T, I, L>::operator=
1214  const Factor<GRAPHICAL_MODEL>& src
1215 )
1216 {
1217  this->variableIndices_.resize(src.numberOfVariables());
1218  for(size_t i=0;i<src.numberOfVariables();++i)
1219  variableIndices_[i] = src.variableIndex(i);
1220  //resize dst function
1221  const size_t dimension = src.numberOfVariables();
1222  if(dimension!=0) {
1223  function_.assign();
1224  function_.resize(src.shapeBegin(), src.shapeEnd());
1225  //iterators and walkers
1226  ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
1227  const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
1228  for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
1229  function_(scalarIndex) = src(coordinate.begin());
1230  ++walker;
1231  }
1232  }
1233  else {
1234  size_t indexToScalar[]={0};
1235  function_=ExplicitFunction<T>(src(indexToScalar));
1236  }
1237  return * this;
1238 }
1239 
1240 template<class T, class I, class L>
1241 inline size_t
1243 {
1244  return variableIndices_.size();
1245 }
1246 
1248 template<class T, class I, class L>
1252  const IndexType index
1253 ) const
1254 {
1255  OPENGM_ASSERT(index < variableIndices_.size());
1256  return function_.shape(index);
1257 }
1258 
1260 template<class T, class I, class L>
1261 inline size_t
1263 {
1264  return function_.size();
1265 }
1266 
1268 template<class T, class I, class L>
1272  const size_t index
1273 ) const {
1274  if(variableIndices_.size() == 0) {
1275  return 0;
1276  }
1277  OPENGM_ASSERT(index < variableIndices_.size());
1278  return function_.shape(index);
1279 }
1280 
1281 template<class T, class I, class L>
1284 {
1285  return function_.shapeBegin();
1286 }
1287 
1288 template<class T, class I, class L>
1291 {
1292  return function_.shapeEnd();
1293 }
1294 
1295 template<class T, class I, class L>
1298 {
1299  return variableIndices_.begin();
1300 }
1301 
1302 template<class T, class I, class L>
1305 {
1306  return variableIndices_.end();
1307 }
1308 
1309 
1311 template<class T, class I, class L>
1312 inline I
1315  const size_t index
1316 ) const {
1317  OPENGM_ASSERT(index < variableIndices_.size());
1318  return variableIndices_[index];
1319 }
1320 
1321 template<class T, class I, class L>
1322 inline void
1324  if(variableIndices_.size() == 0) {
1325  function_(0) = static_cast<ValueType> (0);
1326  }
1327  else {
1328  T v;
1329  std::vector<size_t> states;
1330  opengm::accumulate<Minimizer>(*this, v, states);
1331  (*this) -= v;
1332  }
1333 }
1334 
1337 template<class T, class I, class L>
1338 template<class ITERATOR>
1339 inline T
1340 IndependentFactor<T, I, L>::operator()
1342  ITERATOR begin
1343 ) const {
1344  return function_(begin);
1345 }
1346 
1347 template<class T, class I, class L>
1348 inline std::vector<I>&
1350 {
1351  return this->variableIndices_;
1352 }
1353 
1354 template<class T, class I, class L>
1355 inline const std::vector<I>&
1357 {
1358  return this->variableIndices_;
1359 }
1360 
1362 template<class T, class I, class L>
1363 inline T
1364 IndependentFactor<T, I, L>::operator()
1366  const IndexType x0
1367 ) const
1368 {
1369  return function_(x0);
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
1380 {
1381  OPENGM_ASSERT(2 == variableIndices_.size());
1382  return function_(x0, x1);
1383 }
1384 
1386 template<class T, class I, class L>
1387 inline T
1388 IndependentFactor<T, I, L>::operator()
1390  const IndexType x0,
1391  const IndexType x1,
1392  const IndexType x2
1393 ) const
1394 {
1395  OPENGM_ASSERT(3 == variableIndices_.size());
1396  return function_(x0, x1, x2);
1397 }
1398 
1400 template<class T, class I, class L>
1401 inline T
1404  const IndexType x0,
1405  const IndexType x1,
1406  const IndexType x2,
1407  const IndexType x3
1408 ) const
1409 {
1410  OPENGM_ASSERT(4 == variableIndices_.size());
1411  return function_(x0, x1, x2, x3);
1412 }
1413 
1414 template<class T, class I, class L>
1415 template<class UNARY_OPERATOR_TYPE>
1416 inline void
1419  UNARY_OPERATOR_TYPE unaryOperator
1420 ) {
1421  if(this->variableIndices_.size() != 0) {
1422  for(size_t i = 0; i < function_.size(); ++i) {
1423  function_(i) = static_cast<T> (unaryOperator(function_(i)));
1424  }
1425  }
1426  else {
1427  function_(0) = static_cast<T> (unaryOperator(function_(0)));
1428  }
1429 }
1430 
1431 template<class T, class I, class L>
1432 template<class BINARY_OPERATOR_TYPE>
1433 inline void
1436  const T value,
1437  BINARY_OPERATOR_TYPE binaryOperator
1438 ) {
1439  if(this->variableIndices_.size() != 0) {
1440  for(size_t i = 0; i < function_.size(); ++i) {
1441  function_(i) = static_cast<T> (binaryOperator(function_(i), value));
1442  }
1443  }
1444  else {
1445  function_(0) = static_cast<T> (binaryOperator(function_(0), value));
1446  }
1447 }
1448 
1449 template<class T, class I, class L>
1450 template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
1451 inline void
1454  const Factor<GRAPHICAL_MODEL>& srcB,
1455  BINARY_OPERATOR_TYPE binaryOperator
1456 ) {
1457  opengm::operateBinary(*this, srcB, binaryOperator);
1458 }
1459 
1460 template<class T, class I, class L>
1461 template<class BINARY_OPERATOR_TYPE>
1462 inline void
1465  const IndependentFactor<T, I, L>& srcB,
1466  BINARY_OPERATOR_TYPE binaryOperator
1467 ) {
1468  opengm::operateBinary(*this, srcB, binaryOperator);
1469 }
1470 
1471 template<class T, class I, class L>
1472 template<class BINARY_OPERATOR_TYPE>
1473 inline void
1476  const IndependentFactor<T, I, L>& srcA,
1477  const IndependentFactor<T, I, L>& srcB,
1478  BINARY_OPERATOR_TYPE binaryOperator
1479 ) {
1480  opengm::operateBinary(srcA, srcB, *this, binaryOperator);
1481 }
1482 
1483 template<class T, class I, class L>
1484 template<class ACCUMULATOR>
1485 inline void
1488  T& result,
1489  std::vector<LabelType>& resultState
1490 ) const {
1491  opengm::accumulate<ACCUMULATOR> (*this, result, resultState);
1492 }
1493 
1494 template<class T, class I, class L>
1495 template<class ACCUMULATOR>
1496 inline void
1499  T& result
1500 ) const {
1501  opengm::accumulate<ACCUMULATOR> (*this, result);
1502 }
1503 
1504 template<class T, class I, class L>
1505 template<class ACCUMULATOR, class VariablesIterator>
1506 inline void
1509  VariablesIterator begin,
1510  VariablesIterator end,
1511  IndependentFactor<T, I, L>& dstFactor
1512 ) const {
1513  opengm::accumulate<ACCUMULATOR> (*this, begin, end, dstFactor);
1514 }
1515 
1516 template<class T, class I, class L>
1517 template<class ACCUMULATOR, class VariablesIterator>
1518 inline void
1520  VariablesIterator begin,
1521  VariablesIterator end
1522 ) {
1523  opengm::accumulate<ACCUMULATOR> (*this, begin, end);
1524 }
1525 
1528 template<class T, class I, class L>
1529 template<class ITERATOR>
1530 inline T&
1532  ITERATOR begin
1533 ) {
1534  return function_(begin);
1535 }
1536 
1538 template<class T, class I, class L>
1539 inline T&
1541  const IndexType x0
1542 ) {
1543  return function_(x0);
1544 }
1545 
1547 template<class T, class I, class L>
1548 inline T&
1550  const IndexType x0,
1551  const IndexType x1
1552 ) {
1553  OPENGM_ASSERT(2 == variableIndices_.size());
1554  return function_(x0, x1);
1555 }
1556 
1558 template<class T, class I, class L>
1560  const IndexType x0,
1561  const IndexType x1,
1562  const IndexType x2
1563 ) {
1564  OPENGM_ASSERT(3 == variableIndices_.size());
1565  return function_(x0, x1, x2);
1566 }
1567 
1569 template<class T, class I, class L>
1571  const IndexType x0,
1572  const IndexType x1,
1573  const IndexType x2,
1574  const IndexType x3
1575 ) {
1576  OPENGM_ASSERT(4 == variableIndices_.size());
1577  return function_(x0, x1, x2, x3);
1578 }
1579 
1580 template<class T, class I, class L>
1581 template<class ITERATOR>
1582 inline void
1585  ITERATOR out
1586 ) const {
1587  for(size_t j=0; j<variableIndices_.size(); ++j) {
1588  *out = variableIndices_[j];
1589  ++out;
1590  }
1591 }
1592 
1597 template<class T, class I, class L>
1598 template<class INDEX_ITERATOR, class STATE_ITERATOR>
1599 void
1602  INDEX_ITERATOR beginIndex,
1603  INDEX_ITERATOR endIndex,
1604  STATE_ITERATOR beginLabels
1605 ) {
1606  if(this->variableIndices_.size() != 0) {
1607  OPENGM_ASSERT(opengm::isSorted(beginIndex, endIndex));
1608  opengm::FastSequence<IndexType> variablesToFix;
1609  opengm::FastSequence<IndexType> variablesNotToFix;
1610  opengm::FastSequence<IndexType> positionOfVariablesToFix;
1613  // find the variables to fix:
1614  while(beginIndex != endIndex) {
1615  size_t counter = 0;
1616  if(*beginIndex>this->variableIndices_.back()) {
1617  break;
1618  }
1619  for(size_t i = counter; i<this->variableIndices_.size(); ++i) {
1620  if(*beginIndex<this->variableIndices_[i])break;
1621  else if(*beginIndex == this->variableIndices_[i]) {
1622  ++counter;
1623  variablesToFix.push_back(*beginIndex);
1624  newStates.push_back(*beginLabels);
1625  positionOfVariablesToFix.push_back(i);
1626  }
1627  }
1628  ++beginIndex;
1629  ++beginLabels;
1630  }
1631  for(size_t i = 0; i<this->variableIndices_.size(); ++i) {
1632  bool found = false;
1633  for(size_t j = 0; j < variablesToFix.size(); ++j) {
1634  if(variablesToFix[j] == this->variableIndices_[i]) {
1635  found = true;
1636  break;
1637  }
1638  }
1639  if(found == false) {
1640  variablesNotToFix.push_back(this->variableIndices_[i]);
1641  newShape.push_back(this->numberOfLabels(i));
1642  }
1643  }
1644  if(variablesToFix.size() != 0) {
1645  FunctionType& factorFunction = this->function_;
1646  std::vector<LabelType> fullCoordinate(this->numberOfVariables());
1647  if(variablesToFix.size() == this->variableIndices_.size()) {
1648  FunctionType tmp(factorFunction(newStates.begin()));
1649  factorFunction = tmp;
1650  this->variableIndices_.clear();
1651  }
1652  else {
1653  SubShapeWalker<
1657  > subWalker
1658  (shapeBegin(), factorFunction.dimension(), positionOfVariablesToFix, newStates);
1659  FunctionType tmp(newShape.begin(), newShape.end());
1660  const size_t subSize = subWalker.subSize();
1661  subWalker.resetCoordinate();
1662  for(size_t i = 0; i < subSize; ++i) {
1663  tmp(i) = factorFunction(subWalker.coordinateTuple().begin());
1664  ++subWalker;
1665  }
1666  factorFunction = tmp;
1667  this->variableIndices_.assign(variablesNotToFix.begin(), variablesNotToFix.end());
1668  }
1669  OPENGM_ASSERT(factorFunction.dimension()==variablesNotToFix.size());
1670  OPENGM_ASSERT(newShape.size()==variablesNotToFix.size());
1671  OPENGM_ASSERT(factorFunction.dimension()==newShape.size());
1672  }
1673  }
1674 }
1675 
1676 #define OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION(BINARY_OPERATOR_SYMBOL, BINARY_INPLACE_OPERATOR_SYMBOL, BINARY_FUNCTOR_NAME) \
1677 template<class T, class I, class L> \
1678 inline IndependentFactor<T, I, L> & \
1679 operator BINARY_INPLACE_OPERATOR_SYMBOL \
1680 ( \
1681  IndependentFactor<T, I, L>& op1, \
1682  const T& op2 \
1683 ) { \
1684  op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T>()); \
1685  return op1; \
1686 } \
1687 template<class GRAPHICAL_MODEL> \
1688 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > & \
1689 operator BINARY_INPLACE_OPERATOR_SYMBOL \
1690 ( \
1691  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
1692  const Factor<GRAPHICAL_MODEL>& op2 \
1693 ) { \
1694  op1.operateBinary(op2, BINARY_FUNCTOR_NAME<typename GRAPHICAL_MODEL::ValueType> ()); \
1695  return op1; \
1696 } \
1697 template<class T, class I, class L> \
1698 inline IndependentFactor<T, I, L> & \
1699 operator BINARY_INPLACE_OPERATOR_SYMBOL \
1700 ( \
1701  IndependentFactor<T, I, L>& op1, \
1702  const IndependentFactor<T, I, L>& op2 \
1703 ) { \
1704  op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T> ()); \
1705  return op1; \
1706 } \
1707 template<class T, class I, class L> \
1708 inline IndependentFactor<T, I, L> \
1709 operator BINARY_OPERATOR_SYMBOL \
1710 ( \
1711  const IndependentFactor<T, I, L>& op1, \
1712  const IndependentFactor<T, I, L>& op2 \
1713 ) { \
1714  IndependentFactor<T, I, L> tmp; \
1715  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
1716  return tmp; \
1717 } \
1718 template<class T, class I, class L> \
1719 inline IndependentFactor<T, I, L> \
1720 operator BINARY_OPERATOR_SYMBOL \
1721 ( \
1722  const T & op1, \
1723  const IndependentFactor<T, I, L>& op2 \
1724 ) { \
1725  IndependentFactor<T, I, L> tmp; \
1726  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
1727  return tmp; \
1728 } \
1729 template<class T, class I, class L> \
1730 inline IndependentFactor<T, I, L> \
1731 operator BINARY_OPERATOR_SYMBOL \
1732 ( \
1733  const IndependentFactor<T, I, L>& op1, \
1734  const T & op2 \
1735 ) { \
1736  IndependentFactor<T, I, L> tmp; \
1737  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
1738  return tmp; \
1739 } \
1740 template<class GRAPHICAL_MODEL> \
1741 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1742 operator BINARY_OPERATOR_SYMBOL \
1743 ( \
1744  const Factor<GRAPHICAL_MODEL> & op1, \
1745  const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op2 \
1746 ) { \
1747  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1748  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1749  return tmp; \
1750 } \
1751 template<class GRAPHICAL_MODEL> \
1752 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1753 operator BINARY_OPERATOR_SYMBOL \
1754 ( \
1755  const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
1756  const Factor<GRAPHICAL_MODEL> & op2 \
1757 ) { \
1758  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1759  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1760  return tmp; \
1761 } \
1762 template<class GRAPHICAL_MODEL> \
1763 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1764 operator BINARY_OPERATOR_SYMBOL \
1765 ( \
1766  const Factor<GRAPHICAL_MODEL>& op1, \
1767  const Factor<GRAPHICAL_MODEL>& op2 \
1768 ) { \
1769  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1770  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1771  return tmp; \
1772 } \
1773 template<class GRAPHICAL_MODEL> \
1774 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1775 operator BINARY_OPERATOR_SYMBOL \
1776 ( \
1777  const Factor<GRAPHICAL_MODEL>& op1, \
1778  const typename GRAPHICAL_MODEL::ValueType & op2 \
1779 ) { \
1780  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1781  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1782  return tmp; \
1783 } \
1784 template<class GRAPHICAL_MODEL> \
1785 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
1786 operator BINARY_OPERATOR_SYMBOL \
1787 ( \
1788  const typename GRAPHICAL_MODEL::ValueType & op1, \
1789  const Factor<GRAPHICAL_MODEL>& op2 \
1790 ) { \
1791  IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
1792  opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
1793  return tmp; \
1794 } \
1795 
1802 
1804 
1805 namespace functionwrapper {
1806 
1807  namespace executor {
1808 
1809  template<size_t IX, size_t DX>
1810  template<class GM, class FACTOR>
1811  void FactorInvariant<IX, DX, false>::op
1812  (
1813  const GM & gm,
1814  const FACTOR & factor
1815  ) {
1816  typedef typename GM::IndexType IndexType;
1817  typedef typename GM::LabelType LabelType;
1818  if(factor.functionType() == IX) {
1819  const IndexType functionIndex = static_cast<IndexType>(factor.functionIndex());
1820  const size_t numVar = static_cast<size_t>(factor.numberOfVariables());
1821  const size_t dimFunction = static_cast<size_t>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].dimension());
1822  const IndexType numberOfFunctions = static_cast<IndexType>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_.size());
1823 
1824  OPENGM_CHECK_OP(functionIndex , < ,numberOfFunctions,
1825  "function index must be smaller than numberOfFunctions for that given function type")
1826  OPENGM_CHECK_OP(numVar , == ,dimFunction,
1827  "number of variable indices of the factor must match the functions dimension")
1828  for(size_t i = 0; i < numVar; ++i) {
1829  const LabelType numberOfLabelsOfFunction = meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].shape(i);
1830  OPENGM_CHECK_OP(factor.numberOfLabels(i) , == , numberOfLabelsOfFunction,
1831  "number of labels of the variables in a factor must match the functions shape")
1832  }
1833  }
1834  else {
1835  FactorInvariant
1836  <
1837  meta::Increment<IX>::value,
1838  DX,
1839  meta::EqualNumber< meta::Increment<IX>::value, DX>::value
1840  >::op(gm, factor);
1841  }
1842  }
1843 
1844  template<size_t IX, size_t DX>
1845  template<class GM, class FACTOR>
1846  void FactorInvariant<IX, DX, true>::op
1847  (
1848  const GM & gm,
1849  const FACTOR & factor
1850  ) {
1851  throw RuntimeError("Incorrect function type id.");
1852  }
1853 
1854  } // namespace executor
1855 } // namespace functionwrapper
1856 
1858 
1859 } // namespace opengm
1860 
1861 #endif // #ifndef OPENGM_GRAPHICALMODEL_FACTOR_HXX
void assign(const allocator_type &=allocator_type())
Clear Marray.
Definition: marray.hxx:3350
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...
ShapeIteratorType shapeBegin() const
VariablesIteratorType variableIndicesBegin() const
The OpenGM namespace.
Definition: config.hxx:43
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...
Factor (with corresponding function and variable indices), independent of a GraphicalModel.
GmToFactorLabelIter< LABEL_ITER >::Iter gmToFactorLabelsBegin(LABEL_ITER gmLabelsBegin) const
const size_t * shapeEnd() const
Get a constant iterator to the end of the shape vector.
Definition: marray.hxx:1756
ShapeIteratorType shapeEnd() const
IndexType variableIndex(const IndexType) const
return the index of the j-th variable
const FunctionType & function() const
T const * begin() const
begin iterator
detail_types::UInt8Type UInt8Type
SizeT.
Definition: config.hxx:294
GraphicalModelType::LabelType LabelType
ValueType max() const
void push_back(const T &)
append a value
VariablesIteratorType variableIndicesBegin() const
STL namespace.
IndexType shape(const IndexType) const
return the extension a value table encoding this factor would have in the dimension of the j-th varia...
void load(GM_ &gm, const std::string &, const std::string &)
bool isLinearConstraint() const
IndexType numberOfVariables() const
bool isGeneralizedPotts() const
GraphicalModelType::ValueType ValueType
SubsetAccessor< VariablesIteratorType, LABEL_ITER > Accessor
VariablesIteratorType variableIndicesEnd() const
Vector that stores values on the stack if size is smaller than MAX_STACK.
GraphicalModelType::FunctionTypeList FunctionTypeList
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
void copyValuesSwitchedOrder(ITERATOR iterator) const
GRAPHICAL_MODEL * GraphicalModelPointerType
void load(const hid_t &, const std::string &, Marray< T > &)
Load an Marray from an HDF5 dataset.
std::vector< IndexType >::const_iterator VariablesIteratorType
size_t size() const
size
#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
bool binaryProperty() const
compute a binary property of a factor
Abstraction (wrapper class) of factors, independent of the function used to implement the factor...
ShapeIteratorType shapeEnd() const
ValueType sum() const
GraphicalModelType::IndexType IndexType
ExplicitFunction< ValueType, IndexType, LabelType > FunctionType
const size_t * shapeBegin() const
Get a constant iterator to the beginning of the shape vector.
Definition: marray.hxx:1742
IndexType functionIndex() const
void forAllValuesInAnyOrder(FUNCTOR &functor) const
call a functor for all values in no defined order
ValueType product() const
UInt8Type functionType() const
#define OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION(BINARY_OPERATOR_SYMBOL, BINARY_INPLACE_OPERATOR_SYMBOL, BINARY_FUNCTOR_NAME)
IndexType variableIndex(const size_t) const
return the index of the j-th variable
void forAtLeastAllUniqueValues(FUNCTOR &functor) const
call a functor for at least all unique values in no defined order
void variableIndices(ITERATOR) const
ViFunctor(const FACTOR &factor, FUNCTOR &functor)
T const * end() const
end iterator
bool isTruncatedSquaredDifference() const
IndexType dimension() const
IndexType numberOfLabels(const IndexType) const
return the number of labels of the j-th variable
bool isTruncatedAbsoluteDifference() const
void operateBinary(const T value, BINARY_OPERATOR_TYPE binaryOperator)
VisContainerType::const_iterator VariablesIteratorType
ShapeIteratorType shapeBegin() const
meta::TypeListGenerator< FunctionType >::type FunctionTypeList
std::vector< IndexType > VisContainerType
const meta::TypeAtTypeList< FunctionTypeList, FUNCTION_TYPE_INDEX >::type & function() const
void copyValues(ITERATOR iterator) const
copies the values of a factors into an iterator
ValueType valueProperty() const
void fixVariables(INDEX_ITERATOR, INDEX_ITERATOR, STATE_ITERATOR)
assign specific labels to a specific subset of variables (reduces the order)
const std::vector< IndexType > & variableIndexSequence() const
IndexType size() const
void forAllValuesInOrder(FUNCTOR &functor) const
call a functor for all values in last coordinate major order
void save(const hid_t &, const std::string &, const Marray< T > &)
Save an Marray as an HDF5 dataset.
const size_t dimension() const
Get the dimension.
Definition: marray.hxx:1711
AccessorIterator< Accessor, true > Iter
void accumulate(ValueType &, std::vector< LabelType > &) const
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Definition: submodel2.hxx:24
FACTOR::VariablesIteratorType ViIterator
IndexType numberOfLabels(const IndexType) const
return the number of labels of a specific variable
GRAPHICAL_MODEL GraphicalModelType
GmToFactorLabelIter< LABEL_ITER >::Iter gmToFactorLabelsEnd(LABEL_ITER gmLabelsBegin) const
VariablesIteratorType variableIndicesEnd() const
T operator()(ITERATOR) const
evaluate the function underlying the factor, given labels to be assigned the variables ...
ValueType min() const
bool isAbsoluteDifference() const
const size_t shape(const size_t) const
Get the shape in one dimension.
Definition: marray.hxx:1725
ValueType operator()(ITERATOR) const
evaluate the factor for a sequence of labels
void forAllValuesInSwitchedOrder(FUNCTOR &functor) const
void operateUnary(UNARY_OPERATOR_TYPE unaryOperator)
void variableIndices(ITERATOR out) const
void operator()(const FUNCTION &function)
bool isSquaredDifference() const
VectorView< std::vector< IndexType >, IndexType > VisContainerType
IndexType shape(const size_t dimIndex) const
return the extension of the value table of the of the function in a specific dimension ...
const IndexType size() const
Definition: vector_view.hxx:75
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
void resize(ShapeIterator, ShapeIterator, const T &=T())
Resize (existing entries are preserved, new entries are initialized).
Definition: marray.hxx:3886
const size_t size() const
Get the number of data items.
Definition: marray.hxx:1698
size_t size() const
return the number of entries of the value table of the function