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