OpenGM  2.3.x
Discrete Graphical Model Library
function_properties_base.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_FUNCTION_PROPERTIES_BASE_HXX
3 #define OPENGM_FUNCTION_PROPERTIES_BASE_HXX
4 
5 #include <cmath>
6 
7 #include "opengm/opengm.hxx"
15 #include "opengm/operations/or.hxx"
22 
23 #define OPENGM_FLOAT_TOL 0.000001
24 
25 namespace opengm {
26 
27 template<class T>
28 inline bool isNumericEqual(const T a, const T b) {
29  if(meta::IsFloatingPoint<T>::value) {
30  if(a < b) {
31  return b-a<OPENGM_FLOAT_TOL ? true : false;
32  }
33  else {
34  return a - b < OPENGM_FLOAT_TOL ? true : false;
35  }
36  }
37  else {
38  return a == b;
39  }
40 }
41 
43 template<class FUNCTION, class VALUE, class INDEX = size_t, class LABEL = size_t>
44 class FunctionBase {
45 private:
46  typedef VALUE ReturnType;
47  typedef const VALUE& ReturnReferenceType;
48 
49 public:
50  bool isPotts() const;
51  bool isGeneralizedPotts() const;
52  bool isSubmodular() const;
53  bool isSquaredDifference() const;
54  bool isTruncatedSquaredDifference() const;
55  bool isAbsoluteDifference() const;
56  bool isTruncatedAbsoluteDifference() const;
57  bool isLinearConstraint() const;
58 
59 
62  MinMaxFunctor<VALUE> minMax() const;
63 
64  ReturnType min() const;
65  ReturnType max() const;
66  ReturnType sum() const;
67  ReturnType product() const;
68 
72  template<class ACC>
73  ReturnType accumulate() const;
74 
93  template<class FUNCTOR>
94  void forAllValuesInOrder(FUNCTOR& functor) const;
95 
96  template<class FUNCTOR>
97  void forAllValuesInSwitchedOrder(FUNCTOR& functor) const;
98 
102  template<class FUNCTOR>
103  void forAllValuesInAnyOrder(FUNCTOR& functor) const;
104 
108  template<class FUNCTOR>
109  void forAtLeastAllUniqueValues(FUNCTOR& functor) const ;
110 
111 
112  template<class COORDINATE_FUNCTOR>
113  void forAllValuesInOrderWithCoordinate(COORDINATE_FUNCTOR& functor) const;
114  template<class COORDINATE_FUNCTOR>
115  void forAllValuesInAnyOrderWithCoordinate(COORDINATE_FUNCTOR& functor) const;
116  template<class COORDINATE_FUNCTOR>
117  void forAtLeastAllUniqueValuesWithCoordinate(COORDINATE_FUNCTOR& functor) const ;
118 
119  bool operator==(const FUNCTION&) const;
120 
121 private:
122  typedef FUNCTION FunctionType;
123  typedef FunctionShapeAccessor<FunctionType> FunctionShapeAccessorType;
124 
125 public:
126  typedef AccessorIterator<FunctionShapeAccessorType, true> FunctionShapeIteratorType;
127 
128  FunctionShapeIteratorType functionShapeBegin() const;
129  FunctionShapeIteratorType functionShapeEnd() const;
130 
131  size_t numberOfWeights()const{
132  return 0;
133  }
134  INDEX weightIndex(const size_t weightNumber)const{
135  throw RuntimeError("Function base has no parameters,this needs to be implemented in any function type");
136  }
137  void setWeights(const opengm::learning::Weights<VALUE>& /*weights*/) const {}
138  template<class ITERATOR>
139  VALUE weightGradient(size_t,ITERATOR) const {return 0;}
140 
141 };
142 
143 
144 
145 
146 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
147 inline bool
149 (
150  const FUNCTION& fb
151 ) const{
152  const FunctionType& fa=*static_cast<FunctionType const *>(this);
153  const size_t dimA=fa.dimension();
154  // compare dimension
155  if(dimA==fb.dimension()) {
156  // compare shape
157  for(size_t i=0;i<dimA;++i) {
158  if(fa.shape(i)!=fb.shape(i)) {
159  return false;
160  }
161  }
162  // compare all values
163  ShapeWalker<FunctionShapeIteratorType> shapeWalker(fa.functionShapeBegin(), dimA);
164  for(INDEX i=0;i<fa.size();++i, ++shapeWalker) {
165  if(isNumericEqual(fa(shapeWalker.coordinateTuple().begin()), fb(shapeWalker.coordinateTuple().begin()))==false) {
166  return false;
167  }
168  }
169  }
170  else{
171  return false;
172  }
173  return true;
174 }
175 
176 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
177 template<class COORDINATE_FUNCTOR>
178 inline void
180 (
181  COORDINATE_FUNCTOR& functor
182 ) const {
183  const FunctionType& f=*static_cast<FunctionType const *>(this);
184  ShapeWalker<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(), f.dimension());
185  for(INDEX i=0;i<f.size();++i, ++shapeWalker) {
186  functor(f(shapeWalker.coordinateTuple().begin()),shapeWalker.coordinateTuple().begin());
187  }
188 }
189 
190 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
191 template<class COORDINATE_FUNCTOR>
192 inline void
194 (
195  COORDINATE_FUNCTOR& functor
196 ) const{
197  this->forAllValuesInOrderWithCoordinate(functor);
198 }
199 
200 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
201 template<class COORDINATE_FUNCTOR>
202 inline void
204 (
205  COORDINATE_FUNCTOR& functor
206 ) const {
208 }
209 
210 
211 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
212 template<class FUNCTOR>
213 inline void
215 (
216  FUNCTOR& functor
217 ) const {
218  const FunctionType& f=*static_cast<FunctionType const *>(this);
219  ShapeWalker<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(), f.dimension());
220  for(INDEX i=0;i<f.size();++i, ++shapeWalker) {
221  functor(f(shapeWalker.coordinateTuple().begin()));
222  }
223 }
224 
225 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
226 template<class FUNCTOR>
227 inline void
229 (
230  FUNCTOR& functor
231 ) const {
232  const FunctionType& f=*static_cast<FunctionType const *>(this);
233  ShapeWalkerSwitchedOrder<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(), f.dimension());
234  for(INDEX i=0;i<f.size();++i, ++shapeWalker) {
235  functor(f(shapeWalker.coordinateTuple().begin()));
236  }
237 }
238 
239 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
240 template<class FUNCTOR>
241 inline void
243 (
244  FUNCTOR& functor
245 ) const {
246  static_cast<FunctionType const *>(this)->forAllValuesInOrder(functor);
247 }
248 
249 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
250 template<class FUNCTOR>
251 inline void
253 (
254  FUNCTOR& functor
255 ) const {
256  static_cast<FunctionType const *>(this)->forAllValuesInAnyOrder(functor);
257 }
258 
259 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
262  const FunctionType& f=*static_cast<FunctionType const *>(this);
263  return FunctionShapeIteratorType(FunctionShapeAccessorType(f), 0);
264 }
265 
266 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
269  const FunctionType& f=*static_cast<FunctionType const *>(this);
270  return FunctionShapeIteratorType(FunctionShapeAccessorType(f), f.dimension());
271 }
272 
273 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
274 inline bool
276  const FunctionType& f=*static_cast<FunctionType const *>(this);
277  if(f.dimension()==2) {
278  OPENGM_ASSERT(f.shape(0)>static_cast<LABEL>(1));
279  LABEL c[2]={1, 0};
280  //get possible weight
281  VALUE weight=f(c);
282  for( c[1]=0;c[1]<f.shape(1);++c[1]) {
283  for( c[0]=0;c[0]<f.shape(0);++c[0]) {
284  VALUE d= static_cast<VALUE> (c[0]<c[1] ? c[1]-c[0]:c[0]-c[1]);
285  d*=d;
286  if( isNumericEqual(f(c), d*weight )==false)
287  return false;
288  }
289  }
290  return true;
291  }
292  return false;
293 }
294 
295 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
296 inline bool
298  const FunctionType& f=*static_cast<FunctionType const *>(this);
299  if(f.dimension()==2) {
300  OPENGM_ASSERT(f.shape(0)>static_cast<LABEL>(1));
301  LABEL c[2]={1, 0};
302  //get possible weight
303  VALUE weight=f(c);
304  //get possible truncation (compute the biggest possible distance => value is the truncation value)
305  c[0]=f.shape(0)-static_cast<LABEL>(1);
306  VALUE truncated=f(c);
307  for( c[1]=0;c[1]<f.shape(1);++c[1]) {
308  for( c[0]=0;c[0]<f.shape(0);++c[0]) {
309  VALUE d= static_cast<VALUE> (c[0]<c[1] ? c[1]-c[0]:c[0]-c[1]);
310  d*=d;
311  const VALUE fval=f(c);
312  const VALUE compare=d*weight;
313  if( isNumericEqual(fval, compare )==false && ((isNumericEqual(fval, truncated) && truncated<compare)==false)) {
314  return false;
315  }
316  }
317  }
318  return true;
319  }
320  return false;
321 }
322 
323 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
324 inline bool
326  const FunctionType& f=*static_cast<FunctionType const *>(this);
327  if(f.dimension()==2) {
328  OPENGM_ASSERT(f.shape(0)>static_cast<LABEL>(1));
329  LABEL c[2]={1, 0};
330  //get possible weight
331  VALUE weight=f(c);
332  for( c[1]=0;c[1]<f.shape(1);++c[1]) {
333  for( c[0]=0;c[0]<f.shape(0);++c[0]) {
334  VALUE d= static_cast<VALUE> (c[0]<c[1] ? c[1]-c[0]:c[0]-c[1]);
335  if( isNumericEqual(f(c), d*weight )==false)
336  return false;
337  }
338  }
339  return true;
340  }
341  return false;
342 }
343 
344 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
345 inline bool
347  const FunctionType& f=*static_cast<FunctionType const *>(this);
348  if(f.dimension()==2) {
349  OPENGM_ASSERT(f.shape(0)>static_cast<LABEL>(1));
350  LABEL c[2]={1, 0};
351  //get possible weight
352  VALUE weight=f(c);
353  //get possible truncation (compute the biggest possible distance => value is the truncation value)
354  c[0]=f.shape(0)-static_cast<LABEL>(1);
355  VALUE truncated=f(c);
356  for( c[1]=0;c[1]<f.shape(1);++c[1]) {
357  for( c[0]=0;c[0]<f.shape(0);++c[0]) {
358  VALUE d= static_cast<VALUE> (c[0]<c[1] ? c[1]-c[0]:c[0]-c[1]);
359  const VALUE fval=f(c);
360  const VALUE compare=d*weight;
361  if( isNumericEqual(fval, compare )==false && ((isNumericEqual(fval, truncated) && truncated<compare)==false)) {
362  return false;
363  }
364  }
365  }
366  return true;
367  }
368  return false;
369 }
370 
371 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
372 inline bool
374  const FunctionType& f=*static_cast<FunctionType const *>(this);
375  if (f.size()<=2) return true;//BSD: Bug fixed?
376  ShapeWalker<FunctionShapeIteratorType> shapeWalker(f.functionShapeBegin(), f.dimension());
377  VALUE vEqual=f(shapeWalker.coordinateTuple().begin());
378  ++shapeWalker;
379  VALUE vNotEqual=f(shapeWalker.coordinateTuple().begin());
380  ++shapeWalker;
381  for(INDEX i=2;i<f.size();++i, ++shapeWalker) {
382  // all labels are equal
383  if(isEqualValueVector(shapeWalker.coordinateTuple()) ) {
384  if(vEqual!=f(shapeWalker.coordinateTuple().begin()))
385  return false;
386  }
387  // all labels are not equal
388  else{
389  if(vNotEqual!=f(shapeWalker.coordinateTuple().begin()))
390  return false;
391  }
392  }
393  return true;
394 }
395 
396 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
397 inline bool
399  const FunctionType& f=*static_cast<FunctionType const *>(this);
400  if(f.dimension()==2) {
401  LABEL l[] = {0, 1};
402  VALUE v0 = f(l);
403  l[1]=0;
404  VALUE v1 = f(l);
405  for(l[0]=0;l[0]<f.shape(0);++l[0]) {
406  for(l[1]=0;l[1]<f.shape(1);++l[1]) {
407  if((l[0]==l[1] && f(l)!=v1) || ((l[0]!=l[1] && f(l)!=v0)) ) return false;
408  }
409  }
410  return true;
411  }
412  else if(f.dimension()==3) {
413  LABEL l[] = {0, 1, 2};
414  VALUE v000 = f(l);
415  l[2]=0; l[1]=1; l[0]=1;
416  VALUE v001 = f(l);
417  l[2]=1; l[1]=0; l[0]=1;
418  VALUE v010 = f(l);
419  l[2]=1; l[1]=1; l[0]=0;
420  VALUE v100 = f(l);
421  l[2]=0; l[1]=0; l[0]=0;
422  VALUE v111 = f(l);
423  for(l[0]=0;l[0]<f.shape(0);++l[0]) {
424  for(l[1]=0;l[1]<f.shape(1);++l[1]) {
425  for(l[2]=0;l[2]<f.shape(2);++l[2]) {
426  if((l[1]!=l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v000) ) return false;
427  if((l[1]!=l[2] && l[0]!=l[2] && l[0]==l[1] && f(l)!=v001) ) return false;
428  if((l[1]!=l[2] && l[0]==l[2] && l[0]!=l[1] && f(l)!=v010) ) return false;
429  if((l[1]==l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v100) ) return false;
430  if((l[1]==l[2] && l[0]==l[2] && l[0]==l[1] && f(l)!=v111) ) return false;
431  }
432  }
433  }
434  return true;
435  }
436  else if(f.dimension()==4) {
437  LABEL l[] = {0, 1, 2, 3};
438  VALUE v000000 = f(l);
439  l[3]=2; l[2]=1; l[1]=0;l[0]=0;
440  VALUE v000001 = f(l);
441  l[3]=2; l[2]=0; l[1]=1;l[0]=0;
442  VALUE v000010 = f(l);
443  l[3]=2; l[2]=0; l[1]=0;l[0]=1;
444  VALUE v000100 = f(l);
445  l[3]=1; l[2]=0; l[1]=0;l[0]=0; //3-1
446  VALUE v000111 = f(l);
447  l[3]=0; l[2]=1; l[1]=2; l[0]=0;
448  VALUE v001000 = f(l);
449  l[3]=0; l[2]=1; l[1]=1; l[0]=0;
450  VALUE v001100 = f(l);
451  l[3]=0; l[2]=1; l[1]=0; l[0]=0; //3-1
452  VALUE v011001 = f(l);
453  l[3]=0; l[2]=0; l[1]=0; l[0]=1; //3-1
454  VALUE v110100 = f(l);
455  l[3]=0; l[2]=0; l[1]=0; l[0]=0;
456  VALUE v111111 = f(l);
457  l[3]=1; l[2]=1; l[1]=0; l[0]=0;
458  VALUE v100001 = f(l);
459  l[3]=1; l[2]=0; l[1]=1; l[0]=0;
460  VALUE v010010 = f(l);
461  l[3]=0; l[2]=0; l[1]=1; l[0]=2;
462  VALUE v100000 = f(l);
463  l[3]=0; l[2]=1; l[1]=0; l[0]=2;
464  VALUE v010000 = f(l);
465  l[3]=0; l[2]=0; l[1]=1; l[0]=0; //3-1
466  VALUE v101010 = f(l);
467 
468 
469  for(l[0]=0;l[0]<f.shape(0);++l[0]) {
470  for(l[1]=0;l[1]<f.shape(1);++l[1]) {
471  for(l[2]=0;l[2]<f.shape(2);++l[2]) {
472  for(l[3]=0;l[3]<f.shape(3);++l[3]) {
473  if((l[2]!=l[3] && l[1]!=l[3] && l[0]!=l[3] && l[1]!=l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v000000) ) {std::cout<<"1"; return false;}
474  if((l[2]!=l[3] && l[1]!=l[3] && l[0]!=l[3] && l[1]!=l[2] && l[0]!=l[2] && l[0]==l[1] && f(l)!=v000001) ) {std::cout<<"1"; return false;}
475  if((l[2]!=l[3] && l[1]!=l[3] && l[0]!=l[3] && l[1]!=l[2] && l[0]==l[2] && l[0]!=l[1] && f(l)!=v000010) ) {std::cout<<"1"; return false;}
476  if((l[2]!=l[3] && l[1]!=l[3] && l[0]!=l[3] && l[1]==l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v000100) ) {std::cout<<"1"; return false;}
477  if((l[2]!=l[3] && l[1]!=l[3] && l[0]!=l[3] && l[1]==l[2] && l[0]==l[2] && l[0]==l[1] && f(l)!=v000111) ) {std::cout<<"1"; return false;}
478 
479  if((l[2]!=l[3] && l[1]!=l[3] && l[0]==l[3] && l[1]!=l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v001000) ) {std::cout<<"1"; return false;}
480  if((l[2]!=l[3] && l[1]!=l[3] && l[0]==l[3] && l[1]==l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v001100) ) {std::cout<<"1"; return false;}
481 
482  if((l[2]!=l[3] && l[1]==l[3] && l[0]!=l[3] && l[1]!=l[2] && l[0]==l[2] && l[0]!=l[1] && f(l)!=v010010) ) {std::cout<<"1"; return false;}
483  if((l[2]!=l[3] && l[1]==l[3] && l[0]!=l[3] && l[1]!=l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v010000) ) {std::cout<<"1"; return false;}
484  if((l[2]!=l[3] && l[1]==l[3] && l[0]==l[3] && l[1]!=l[2] && l[0]!=l[2] && l[0]==l[1] && f(l)!=v011001) ) {std::cout<<"1"; return false;}
485 
486  if((l[2]==l[3] && l[1]==l[3] && l[0]!=l[3] && l[1]==l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v110100) ) {std::cout<<"1"; return false;}
487  if((l[2]==l[3] && l[1]==l[3] && l[0]==l[3] && l[1]==l[2] && l[0]==l[2] && l[0]==l[1] && f(l)!=v111111) ) {std::cout<<"1"; return false;}
488 
489  if((l[2]==l[3] && l[1]!=l[3] && l[0]!=l[3] && l[1]!=l[2] && l[0]!=l[2] && l[0]==l[1] && f(l)!=v100001) ) {std::cout<<"1"; return false;}
490  if((l[2]==l[3] && l[1]!=l[3] && l[0]!=l[3] && l[1]!=l[2] && l[0]!=l[2] && l[0]!=l[1] && f(l)!=v100000) ) {std::cout<<"1"; return false;}
491  if((l[2]==l[3] && l[1]!=l[3] && l[0]==l[3] && l[1]!=l[2] && l[0]==l[2] && l[0]!=l[1] && f(l)!=v101010) ) {std::cout<<"1"; return false;}
492  }
493  }
494  }
495  }
496  return true;
497  }
498  else{
499  return false;
500  }
501 }
502 
503 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
504 inline bool
506  const FunctionType& f = *static_cast<FunctionType const *>(this);
507  if(f.dimension()==1){
508  return true;
509  }
510  if(f.dimension()!=2 ||f.shape(0)!=2 || f.shape(1)!=2) {
511  throw RuntimeError("Fallback FunctionBase::isSubmodular only defined for binary functions with order less than 3");
512  }
513  LABEL l00[] = {0, 0};
514  LABEL l01[] = {0, 1};
515  LABEL l10[] = {1, 0};
516  LABEL l11[] = {1, 1};
517 
518  return f(l00)+f(l11)<= f(l10)+f(l01);
519 }
520 
521 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
522 inline bool
524  // by default all Functions are not of type linear constraint.
525  return false;
526 }
527 
528 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
529 inline MinMaxFunctor<VALUE>
531  const FunctionType& f=*static_cast<FunctionType const *>(this);
533  const VALUE tmp=f(c.begin());
534  MinMaxFunctor<VALUE> minMax(tmp, tmp);
535  static_cast<FunctionType const *>(this)->forAtLeastAllUniqueValues(minMax);
536  return minMax;
537 }
538 
539 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
540 inline typename FunctionBase<FUNCTION, VALUE, INDEX, LABEL>::ReturnType
542  const FunctionType& f=*static_cast<FunctionType const *>(this);
544  AccumulationFunctor<Minimizer, VALUE> accumulator(f(c.begin()));
545  static_cast<FunctionType const *>(this)->forAtLeastAllUniqueValues(accumulator);
546  return accumulator.value();
547 }
548 
549 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
550 inline typename FunctionBase<FUNCTION, VALUE, INDEX, LABEL>::ReturnType
552  const FunctionType& f=*static_cast<FunctionType const *>(this);
554  AccumulationFunctor<Maximizer, VALUE> accumulator(f(c.begin()));
555  static_cast<FunctionType const *>(this)->forAtLeastAllUniqueValues(accumulator);
556  return accumulator.value();
557 }
558 
559 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
560 inline typename FunctionBase<FUNCTION, VALUE, INDEX, LABEL>::ReturnType
562  AccumulationFunctor<Integrator, VALUE> accumulator(static_cast<VALUE>(0));
563  static_cast<FunctionType const *>(this)->forAllValuesInAnyOrder(accumulator);
564  return accumulator.value();
565 }
566 
567 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
568 inline typename FunctionBase<FUNCTION, VALUE, INDEX, LABEL>::ReturnType
570  AccumulationFunctor<Multiplier, VALUE> accumulator(static_cast<VALUE>(1));;
571  static_cast<FunctionType const *>(this)->forAllValuesInAnyOrder(accumulator);
572  return accumulator.value();
573 }
574 
575 template<class FUNCTION, class VALUE, class INDEX, class LABEL>
576 template<class ACC>
577 inline typename FunctionBase<FUNCTION, VALUE, INDEX, LABEL>::ReturnType
579  if(meta::Compare<ACC, Minimizer>::value ) {
580  return static_cast<FunctionType const *>(this)->min();
581  }
582  else if( meta::Compare<ACC, Maximizer>::value ) {
583  return static_cast<FunctionType const *>(this)->max();
584  }
585  else if( meta::Compare<ACC, Adder>::value ) {
586  return static_cast<FunctionType const *>(this)->sum();
587  }
588  else if( meta::Compare<ACC, Integrator>::value ) {
589  return static_cast<FunctionType const *>(this)->sum();
590  }
591  else if( meta::Compare<ACC, Multiplier>::value ) {
592  return static_cast<FunctionType const *>(this)->product();
593  }
594  else{
595  AccumulationFunctor<ACC, VALUE> accumulator;
596  static_cast<FunctionType const *>(this)->forAllValuesInOrder(accumulator);
597  return accumulator.value();
598  }
599 }
600 
601 } // namespace opengm
602 
603 #endif // OPENGM_FUNCTION_PROPERTIES_BASE_HXX
#define OPENGM_FLOAT_TOL
void forAtLeastAllUniqueValuesWithCoordinate(COORDINATE_FUNCTOR &functor) const
void forAllValuesInAnyOrder(FUNCTOR &functor) const
call a functor for each value of the function (in un-specified order)
void setWeights(const opengm::learning::Weights< VALUE > &) const
FunctionShapeIteratorType functionShapeEnd() const
The OpenGM namespace.
Definition: config.hxx:43
Fallback implementation of member functions of OpenGM functions.
bool isNumericEqual(const T a, const T b)
ReturnType accumulate() const
accumulate all values of the function
VALUE weightGradient(size_t, ITERATOR) const
AccessorIterator< FunctionShapeAccessorType, true > FunctionShapeIteratorType
bool operator==(const FUNCTION &) const
void forAllValuesInOrderWithCoordinate(COORDINATE_FUNCTOR &functor) const
Vector that stores values on the stack if size is smaller than MAX_STACK.
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
void forAllValuesInSwitchedOrder(FUNCTOR &functor) const
void forAllValuesInAnyOrderWithCoordinate(COORDINATE_FUNCTOR &functor) const
INDEX weightIndex(const size_t weightNumber) const
size_t size() const
number of entries a value table encoding this function would have (used for I/O)
MinMaxFunctor< VALUE > minMax() const
find minimum and maximum of the function in a single sweep
truncated squared difference of the labels of two variables
void forAtLeastAllUniqueValues(FUNCTOR &functor) const
call a functor for at least all unique values of the function
FunctionShapeIteratorType functionShapeBegin() const
void forAllValuesInOrder(FUNCTOR &functor) const
call a functor for each value of the function (in lexicographical order of the variable indices) ...
OpenGM runtime error.
Definition: opengm.hxx:100
size_t shape(const IndexType) const
extension a value table encoding this function would have