OpenGM  2.3.x
Discrete Graphical Model Library
inference.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_INFERENCE_HXX
3 #define OPENGM_INFERENCE_HXX
4 
5 #include <vector>
6 #include <string>
7 #include <list>
8 #include <limits>
9 #include <exception>
10 
11 #include "opengm/opengm.hxx"
12 
13 #define OPENGM_GM_TYPE_TYPEDEFS \
14  typedef typename GraphicalModelType::LabelType LabelType; \
15  typedef typename GraphicalModelType::IndexType IndexType; \
16  typedef typename GraphicalModelType::ValueType ValueType; \
17  typedef typename GraphicalModelType::OperatorType OperatorType; \
18  typedef typename GraphicalModelType::FactorType FactorType; \
19  typedef typename GraphicalModelType::IndependentFactorType IndependentFactorType; \
20  typedef typename GraphicalModelType::FunctionIdentifier FunctionIdentifier \
21 
22 namespace opengm {
23 
25  UNKNOWN=0,
26  NORMAL=1,
27  TIMEOUT=2,
30 };
31 
33 template <class GM, class ACC>
34 class Inference
35 {
36 public:
37  typedef GM GraphicalModelType;
38  typedef ACC AccumulationType;
39  typedef typename GraphicalModelType::LabelType LabelType;
40  typedef typename GraphicalModelType::IndexType IndexType;
41  typedef typename GraphicalModelType::ValueType ValueType;
42  typedef typename GraphicalModelType::OperatorType OperatorType;
43  typedef typename GraphicalModelType::FactorType FactorType;
44  typedef typename GraphicalModelType::IndependentFactorType IndependentFactorType;
45  typedef typename GraphicalModelType::FunctionIdentifier FunctionIdentifier;
46 
47  virtual ~Inference() {}
48 
49  virtual std::string name() const = 0;
50  virtual const GraphicalModelType& graphicalModel() const = 0;
51  virtual InferenceTermination infer() = 0;
55 
56  // member functions with default definition
57  virtual void setStartingPoint(typename std::vector<LabelType>::const_iterator);
58  virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const;
59  virtual InferenceTermination args(std::vector<std::vector<LabelType> >&) const;
60  virtual InferenceTermination marginal(const size_t, IndependentFactorType&) const;
61  virtual InferenceTermination factorMarginal(const size_t, IndependentFactorType&) const;
62  virtual ValueType bound() const;
63  virtual ValueType value() const;
64  InferenceTermination constrainedOptimum(std::vector<IndexType>&,std::vector<LabelType>&, std::vector<LabelType>&) const;
65  InferenceTermination modeFromMarginal(std::vector<LabelType>&) const;
66  InferenceTermination modeFromFactorMarginal(std::vector<LabelType>&) const;
67 };
68 
72 template<class GM, class ACC>
75  std::vector<LabelType>& arg,
76  const size_t argIndex
77 ) const
78 {
79  return UNKNOWN;
80 }
81 
84 template<class GM, class ACC>
85 inline void
87  typename std::vector<LabelType>::const_iterator begin
88 )
89 {}
90 
91 template<class GM, class ACC>
94  std::vector<std::vector<LabelType> >& out
95 ) const
96 {
97  return UNKNOWN;
98 }
99 
103 template<class GM, class ACC>
106  const size_t variableIndex,
108  ) const
109 {
110  return UNKNOWN;
111 }
112 
116 template<class GM, class ACC>
119  const size_t factorIndex,
121 ) const
122 {
123  return UNKNOWN;
124 }
125 
126 
127 template<class GM, class ACC>
130  std::vector<IndexType>& variableIndices,
131  std::vector<LabelType>& givenLabels,
132  std::vector<LabelType>& conf
133 ) const
134 {
135  const GM& gm = graphicalModel();
136  std::vector<IndexType> waitingVariables;
137  size_t variableId = 0;
138  size_t numberOfVariables = gm.numberOfVariables();
139  size_t numberOfFixedVariables = 0;
140  conf.assign(gm.numberOfVariables(),std::numeric_limits<LabelType>::max());
141  OPENGM_ASSERT(variableIndices.size()>=givenLabels.size());
142  for(size_t i=0; i<givenLabels.size() ;++i) {
143  OPENGM_ASSERT( variableIndices[i]<gm.numberOfVariables());
144  OPENGM_ASSERT( givenLabels[i]<gm.numberOfLabels(variableIndices[i]));
145  conf[variableIndices[i]] = givenLabels[i];
146  waitingVariables.push_back(variableIndices[i]);
147  ++numberOfFixedVariables;
148  }
149  while(variableId<gm.numberOfVariables() && numberOfFixedVariables<numberOfVariables) {
150  while(waitingVariables.size()>0 && numberOfFixedVariables<numberOfVariables) {
151  size_t var = waitingVariables.back();
152  waitingVariables.pop_back();
153 
154  //Search unset neighbourd variable
155  for(size_t i=0; i<gm.numberOfFactors(var); ++i) {
156  size_t var2=var;
157  size_t afactorId = gm.factorOfVariable(var,i);
158  for(size_t n=0; n<gm[afactorId].numberOfVariables();++n) {
159  if(conf[gm[afactorId].variableIndex(n)] == std::numeric_limits<LabelType>::max()) {
160  var2=gm[afactorId].variableIndex(n);
161  break;
162  }
163  }
164  if(var2 != var) {
165  //Set this variable
167  //marginal(var2, t);
168  for(size_t i=0; i<gm.numberOfFactors(var2); ++i) {
169  size_t factorId = gm.factorOfVariable(var2,i);
170  if(factorId != afactorId) continue;
171  std::vector<IndexType> knownVariables;
172  std::vector<LabelType> knownStates;
173  std::vector<IndexType> unknownVariables;
175  InferenceTermination term = factorMarginal(factorId, out);
176  if(NORMAL != term) {
177  return term;
178  }
179  for(size_t n=0; n<gm[factorId].numberOfVariables();++n) {
180  if(gm[factorId].variableIndex(n)!=var2) {
181  if(conf[gm[factorId].variableIndex(n)] < std::numeric_limits<LabelType>::max()) {
182  knownVariables.push_back(gm[factorId].variableIndex(n));
183  knownStates.push_back(conf[gm[factorId].variableIndex(n)]);
184  }else{
185  unknownVariables.push_back(gm[factorId].variableIndex(n));
186  }
187  }
188  }
189 
190  out.fixVariables(knownVariables.begin(), knownVariables.end(), knownStates.begin());
191  if(unknownVariables.size()>0)
192  out.template accumulate<AccumulationType>(unknownVariables.begin(),unknownVariables.end());
193  OperatorType::op(out,t);
194  }
195  ValueType value;
196  std::vector<LabelType> state(t.numberOfVariables());
197  t.template accumulate<AccumulationType>(value,state);
198  conf[var2] = state[0];
199  ++numberOfFixedVariables;
200  waitingVariables.push_back(var2);
201  }
202  }
203  }
204  if(conf[variableId]==std::numeric_limits<LabelType>::max()) {
205  //Set variable state
207  InferenceTermination term = marginal(variableId, out);
208  if(NORMAL != term) {
209  return term;
210  }
211  ValueType value;
212  std::vector<LabelType> state(out.numberOfVariables());
213  out.template accumulate<AccumulationType>(value,state);
214  conf[variableId] = state[0];
215  waitingVariables.push_back(variableId);
216  }
217  ++variableId;
218  }
219  return NORMAL;
220 }
221 
222 /*
223 template<class GM, class ACC>
224 InferenceTermination
225 Inference<GM, ACC>::constrainedOptimum(
226  std::vector<IndexType>& variableIndices,
227  std::vector<LabelType>& givenLabels,
228  std::vector<LabelType>& conf
229 ) const
230 {
231  const GM& gm = graphicalModel();
232  std::vector<IndexType> waitingVariables;
233  size_t variableId = 0;
234  size_t numberOfVariables = gm.numberOfVariables();
235  size_t numberOfFixedVariables = 0;
236  conf.assign(gm.numberOfVariables(),std::numeric_limits<LabelType>::max());
237  OPENGM_ASSERT(variableIndices.size()>=givenLabels.size());
238  for(size_t i=0; i<givenLabels.size() ;++i) {
239  OPENGM_ASSERT( variableIndices[i]<gm.numberOfVariables());
240  OPENGM_ASSERT( givenLabels[i]<gm.numberOfLabels(variableIndices[i]));
241  conf[variableIndices[i]] = givenLabels[i];
242  waitingVariables.push_back(variableIndices[i]);
243  ++numberOfFixedVariables;
244  }
245  while(variableId<gm.numberOfVariables() && numberOfFixedVariables<numberOfVariables) {
246  while(waitingVariables.size()>0 && numberOfFixedVariables<numberOfVariables) {
247  size_t var = waitingVariables.back();
248  waitingVariables.pop_back();
249 
250  //Search unset neighbourd variable
251  for(size_t i=0; i<gm.numberOfFactors(var); ++i) {
252  size_t var2=var;
253  size_t afactorId = gm.factorOfVariable(var,i);
254  for(size_t n=0; n<gm[afactorId].numberOfVariables();++n) {
255  if(conf[gm[afactorId].variableIndex(n)] == std::numeric_limits<LabelType>::max()) {
256  var2=gm[afactorId].variableIndex(n);
257  break;
258  }
259  }
260  if(var2 != var) {
261  //Set this variable
262  IndependentFactorType t;
263  //marginal(var2, t);
264  for(size_t i=0; i<gm.numberOfFactors(var2); ++i) {
265  size_t factorId = gm.factorOfVariable(var2,i);
266  if(factorId != afactorId) continue;
267  std::vector<IndexType> knownVariables;
268  std::vector<LabelType> knownStates;
269  std::vector<IndexType> unknownVariables;
270  IndependentFactorType out;
271  InferenceTermination term = factorMarginal(factorId, out);
272  if(NORMAL != term) {
273  return term;
274  }
275  for(size_t n=0; n<gm[factorId].numberOfVariables();++n) {
276  if(gm[factorId].variableIndex(n)!=var2) {
277  if(conf[gm[factorId].variableIndex(n)] < std::numeric_limits<LabelType>::max()) {
278  knownVariables.push_back(gm[factorId].variableIndex(n));
279  knownStates.push_back(conf[gm[factorId].variableIndex(n)]);
280  }else{
281  unknownVariables.push_back(gm[factorId].variableIndex(n));
282  }
283  }
284  }
285 
286  out.fixVariables(knownVariables.begin(), knownVariables.end(), knownStates.begin());
287  if(unknownVariables.size()>0)
288  out.template accumulate<AccumulationType>(unknownVariables.begin(),unknownVariables.end());
289  OperatorType::op(out,t);
290  }
291  ValueType value;
292  std::vector<LabelType> state(t.numberOfVariables());
293  t.template accumulate<AccumulationType>(value,state);
294  conf[var2] = state[0];
295  ++numberOfFixedVariables;
296  waitingVariables.push_back(var2);
297  }
298  }
299  }
300  if(conf[variableId]==std::numeric_limits<LabelType>::max()) {
301  //Set variable state
302  IndependentFactorType out;
303  InferenceTermination term = marginal(variableId, out);
304  if(NORMAL != term) {
305  return term;
306  }
307  ValueType value;
308  std::vector<LabelType> state(out.numberOfVariables());
309  out.template accumulate<AccumulationType>(value,state);
310  conf[variableId] = state[0];
311  waitingVariables.push_back(variableId);
312  }
313  ++variableId;
314  }
315  return NORMAL;
316 }
317 */
318 
319 template<class GM, class ACC>
322  std::vector<LabelType>& conf
323  ) const
324 {
325  const GM& gm = graphicalModel();
326  //const space_type& space = gm.space();
327  size_t numberOfNodes = gm.numberOfVariables();
328  conf.resize(gm.numberOfVariables());
330  for(size_t node=0; node<numberOfNodes; ++node) {
331  InferenceTermination term = marginal(node, out);
332  if(NORMAL != term) {
333  return term;
334  }
335  ValueType value = out(0);
336  size_t state = 0;
337  for(size_t i=1; i<gm.numberOfLabels(node); ++i) {
338  if(ACC::bop(out(i), value)) {
339  value = out(i);
340  state = i;
341  }
342  }
343  conf[node] = state;
344  }
345  return NORMAL;
346 }
347 
348 template<class GM, class ACC>
351  std::vector<LabelType>& conf
352 ) const
353 {
354  const GM& gm = graphicalModel();
355  std::vector<IndexType> knownVariables;
356  std::vector<LabelType> knownStates;
358  for(size_t node=0; node<gm.numberOfVariables(); ++node) {
359  InferenceTermination term = marginal(node, out);
360  if(NORMAL != term) {
361  return term;
362  }
363  ValueType value = out(0);
364  size_t state = 0;
365  bool unique = true;
366  for(size_t i=1; i<gm.numberOfLabels(node); ++i) {
367 
368  //ValueType q = out(i)/value;
369  //if(q<1.001 && q>0.999) {
370  // unique=false;
371  //}
372  if(fabs(out(i) - value)<0.00001) {
373  unique=false;
374  }
375  else if(ACC::bop(out(i), value)) {
376  value = out(i);
377  state = i;
378  unique=true;
379  }
380  }
381  if(unique) {
382  knownVariables.push_back(node);
383  knownStates.push_back(state);
384  }
385  }
386  return constrainedOptimum( knownVariables, knownStates, conf);
387 }
388 
390 template<class GM, class ACC>
391 typename GM::ValueType
393 {
394  if(ACC::hasbop()){
395  // Default implementation if ACC defines an ordering
396  std::vector<LabelType> s;
397  const GM& gm = graphicalModel();
398  if(NORMAL == arg(s)) {
399  return gm.evaluate(s);
400  }
401  else {
402  return ACC::template neutral<ValueType>();
403  }
404  }else{
405  //TODO: Maybe throw an exception here
406  //throw std::runtime_error("There is no default implementation for this type of semi-ring");
407  return std::numeric_limits<ValueType>::quiet_NaN();
408  }
409 }
410 
412 template<class GM, class ACC>
413 typename GM::ValueType
415  if(ACC::hasbop()){
416  // Default implementation if ACC defines an ordering
417  return ACC::template ineutral<ValueType>();
418  }else{
419  //TODO: Maybe throw an exception here
420  //throw std::runtime_error("There is no default implementation for this type of semi-ring");
421  return std::numeric_limits<ValueType>::quiet_NaN();
422  }
423 }
424 
425 } // namespace opengm
426 
427 #endif // #ifndef OPENGM_INFERENCE_HXX
The OpenGM namespace.
Definition: config.hxx:43
virtual std::string name() const =0
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Definition: inference.hxx:74
virtual const GraphicalModelType & graphicalModel() const =0
virtual void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
Definition: inference.hxx:86
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
GraphicalModelType::OperatorType OperatorType
Definition: inference.hxx:42
virtual InferenceTermination args(std::vector< std::vector< LabelType > > &) const
Definition: inference.hxx:93
virtual InferenceTermination infer()=0
virtual ~Inference()
Definition: inference.hxx:47
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:40
GraphicalModelType::FactorType FactorType
Definition: inference.hxx:43
virtual ValueType bound() const
return a bound on the solution
Definition: inference.hxx:414
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:41
virtual InferenceTermination marginal(const size_t, IndependentFactorType &) const
output a solution for a marginal for a specific variable
Definition: inference.hxx:105
Inference algorithm interface.
Definition: inference.hxx:34
GraphicalModelType::FunctionIdentifier FunctionIdentifier
Definition: inference.hxx:45
virtual ValueType value() const
return the solution (value)
Definition: inference.hxx:392
InferenceTermination constrainedOptimum(std::vector< IndexType > &, std::vector< LabelType > &, std::vector< LabelType > &) const
Definition: inference.hxx:129
virtual InferenceTermination factorMarginal(const size_t, IndependentFactorType &) const
output a solution for a marginal for all variables connected to a factor
Definition: inference.hxx:118
GraphicalModelType::LabelType LabelType
Definition: inference.hxx:39
InferenceTermination modeFromMarginal(std::vector< LabelType > &) const
Definition: inference.hxx:321
InferenceTermination modeFromFactorMarginal(std::vector< LabelType > &) const
Definition: inference.hxx:350
InferenceTermination
Definition: inference.hxx:24
GraphicalModelType::IndependentFactorType IndependentFactorType
Definition: inference.hxx:44