OpenGM  2.3.x
Discrete Graphical Model Library
graphicalmodeldecomposition.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_GRAPHICALMODELDECOMPOSITION_HXX
3 #define OPENGM_GRAPHICALMODELDECOMPOSITION_HXX
4 
5 #include <vector>
6 #include <list>
7 #include <set>
8 #include <map>
9 #include <limits>
10 
11 namespace opengm {
12 
14 
15 class GraphicalModelDecomposition
16 {
17 public:
18  class SubFactor {
19  public:
20  size_t subModelId_;
21  size_t subFactorId_;
22  std::vector<size_t> subIndices_;
23  SubFactor(const size_t&, const size_t&, const std::vector<size_t>&);
24  SubFactor(const size_t&, const std::vector<size_t>&);
25  };
26  typedef SubFactor EmptySubFactor;
27 /*
28  class EmptySubFactor {
29  public:
30  size_t subModelId_;
31  size_t subFactorId_;
32  std::vector<size_t> subIndices_;
33  EmptySubFactor(const size_t&, const std::vector<size_t>&);
34  };
35 */
36  class SubVariable {
37  public:
38  size_t subModelId_;
39  size_t subVariableId_;
40  SubVariable(const size_t&, const size_t&);
41  };
42 
43  typedef std::list<SubFactor> SubFactorListType;
44  typedef std::list<SubFactor> EmptySubFactorListType;
45  typedef std::list<SubVariable> SubVariableListType;
46 
47  GraphicalModelDecomposition();
48  GraphicalModelDecomposition(const size_t numVariables, const size_t numFactors, const size_t numSubModels=0);
49  size_t addSubModel();
50  size_t addSubFactor(const size_t& subModel, const size_t& factorId, const std::vector<size_t>& subIndices);
51  size_t addSubFactor(const size_t& subModel, const std::vector<size_t>& indices, const std::vector<size_t>& subIndices);
52  size_t addSubVariable(const size_t& subModel, const size_t& variableId);
53 
54  void reorder();
55  void complete();
56  template <class GM> bool isValid(const GM&) const;
57  const std::vector<SubFactorListType>& getFactorLists() const
58  { return subFactorLists_; }
59  const std::map<std::vector<size_t>,EmptySubFactorListType>& getEmptyFactorLists() const
60  { return emptySubFactorLists_; }
61  const std::vector<SubVariableListType>& getVariableLists() const
62  {return subVariableLists_; }
63  size_t numberOfSubModels() const
64  { return numberOfSubModels_; }
65  size_t numberOfSubVariables(size_t subModel) const
66  { return numberOfSubVariables_[subModel]; }
67  size_t numberOfSubFactors(size_t subModel) const
68  { return numberOfSubFactors_[subModel]; }
69 
70 private:
71  size_t numberOfVariables_;
72  size_t numberOfFactors_;
73  size_t numberOfSubModels_;
74  std::vector<size_t> numberOfSubFactors_; //vectorsize = numberOfModels
75  std::vector<size_t> numberOfSubVariables_; //vectorsize = numberOfModels
76  std::vector<SubFactorListType> subFactorLists_; //vectorsize = numberOfFactors
77  std::vector<SubVariableListType> subVariableLists_; //vectorsize = numberOfVariabels
78  std::map<std::vector<size_t>,EmptySubFactorListType> emptySubFactorLists_; //mapindex = realFactorIndices
79 };
80 
81 inline
82 GraphicalModelDecomposition::SubFactor::
83 SubFactor
84 (
85  const size_t& sM,
86  const size_t& sF,
87  const std::vector<size_t>& sI
88 )
89 : subModelId_(sM),
90  subFactorId_(sF),
91  subIndices_(sI)
92 {}
93 
94 inline
95 GraphicalModelDecomposition::SubFactor::
96 SubFactor
97 (
98  const size_t& sM,
99  const std::vector<size_t>& sI
100 )
101 : subModelId_(sM),
102  subIndices_(sI)
103 {}
104 
105 inline
106 GraphicalModelDecomposition::SubVariable::
107 SubVariable
108 (
109  const size_t& sM,
110  const size_t& sV
111 )
112 : subModelId_(sM),
113  subVariableId_(sV)
114 {}
115 
116 inline
117 GraphicalModelDecomposition::
118 GraphicalModelDecomposition()
119 {
120  numberOfVariables_ = 0;
121  numberOfFactors_ = 0;
122  numberOfSubModels_ = 0;
123 }
124 
125 inline
126 GraphicalModelDecomposition::
127 GraphicalModelDecomposition
128 (
129  const size_t numNodes,
130  const size_t numFactors,
131  const size_t numSubModels
132 )
133 : numberOfVariables_(numNodes),
134  numberOfFactors_(numFactors),
135  numberOfSubModels_(numSubModels)
136 {
137  numberOfSubFactors_.resize(numberOfSubModels_,0);
138  numberOfSubVariables_.resize(numberOfSubModels_,0);
139  subFactorLists_.resize(numberOfFactors_);
140  subVariableLists_.resize(numberOfVariables_);
141 }
142 
143 inline size_t
144 GraphicalModelDecomposition::addSubModel()
145 {
146  numberOfSubFactors_.push_back(0);
147  numberOfSubVariables_.push_back(0);
148  return numberOfSubModels_++;
149 }
150 
151 inline size_t
152 GraphicalModelDecomposition::addSubFactor
153 (
154  const size_t& subModel,
155  const size_t& factorId,
156  const std::vector<size_t>& subIndices
157 )
158 {
159  OPENGM_ASSERT(subModel < numberOfSubModels_);
160  OPENGM_ASSERT(factorId < numberOfFactors_);
161  if(!NO_DEBUG) {
162  for(size_t i=0; i<subIndices.size(); ++i) {
163  OPENGM_ASSERT(subIndices[i] < numberOfSubVariables_[subModel]);
164  }
165  }
166  subFactorLists_[factorId].push_back(SubFactor(subModel,numberOfSubFactors_[subModel],subIndices));
167  return numberOfSubFactors_[subModel]++;
168 }
169 
170 inline size_t
171 GraphicalModelDecomposition::addSubFactor
172 (
173  const size_t& subModel,
174  const std::vector<size_t>& indices,
175  const std::vector<size_t>& subIndices
176 )
177 {
178  OPENGM_ASSERT(subModel < numberOfSubModels_);
179  if(!NO_DEBUG) {
180  for(size_t i=0; i<subIndices.size(); ++i) {
181  OPENGM_ASSERT(subIndices[i] < numberOfSubVariables_[subModel]);
182  }
183  }
184  emptySubFactorLists_[indices].push_back(SubFactor(subModel,subIndices));
185  return numberOfSubFactors_[subModel]++;
186 }
187 
188 inline size_t
189 GraphicalModelDecomposition::addSubVariable
190 (
191  const size_t& subModel,
192  const size_t& variableId
193 ) {
194  OPENGM_ASSERT(subModel < numberOfSubModels_);
195  OPENGM_ASSERT(variableId < numberOfVariables_);
196  subVariableLists_[variableId].push_back(SubVariable(subModel,numberOfSubVariables_[subModel]));
197  return numberOfSubVariables_[subModel]++;
198 }
199 
200 inline void GraphicalModelDecomposition::complete()
201 {
202  SubVariableListType::iterator it;
203  SubFactorListType::iterator it2;
204  EmptySubFactorListType::iterator it3;
205 
206  // build mapping: (subModel, subVariable) -> (realVariable)
207  std::vector<std::vector<size_t> > subVariable2realVariable(numberOfSubModels_);
208  for(size_t subModelId=0; subModelId<numberOfSubModels_; ++subModelId) {
209  subVariable2realVariable[subModelId].resize(numberOfSubVariables_[subModelId],0);
210  }
211  for(size_t varId=0; varId<numberOfVariables_; ++varId) {
212  for(it = subVariableLists_[varId].begin(); it!=subVariableLists_[varId].end();++it) {
213  const size_t& subModelId = (*it).subModelId_;
214  const size_t& subVariableId = (*it).subVariableId_;
215  subVariable2realVariable[subModelId][subVariableId] = varId;
216  }
217  }
218 
219  // build mapping: (realVariable) -> (realUnaryFactor)
220  std::vector<size_t> realVariable2realUnaryFactors(numberOfVariables_,std::numeric_limits<std::size_t>::max());
221  for(size_t factorId=0; factorId<numberOfFactors_; ++factorId) {
222  if(!subFactorLists_[factorId].empty() && subFactorLists_[factorId].front().subIndices_.size()==1) {
223  const size_t& subModelId = subFactorLists_[factorId].front().subModelId_;
224  const size_t& subVariableId = subFactorLists_[factorId].front().subIndices_[0];
225  const size_t& realVariableId = subVariable2realVariable[subModelId][subVariableId];
226  realVariable2realUnaryFactors[realVariableId] = factorId;
227  }
228  }
229 
230  // add missing unary Factors
231  for(size_t varId=0; varId<numberOfVariables_; ++varId) {
232  if(subVariableLists_[varId].size()>1) {
233  std::vector<std::set<size_t> > required(numberOfSubModels_);
234  // find Missing SubFactors
235  for(it = subVariableLists_[varId].begin(); it!=subVariableLists_[varId].end();++it) {
236  const size_t& subModelId = (*it).subModelId_;
237  const size_t& subVariableId = (*it).subVariableId_;
238  required[subModelId].insert(subVariableId);
239  }
240  if(realVariable2realUnaryFactors[varId] < std::numeric_limits<size_t>::max()) {
241  const size_t& factorId = realVariable2realUnaryFactors[varId];
242  // find included SubFactors
243  for(it2 = subFactorLists_[factorId].begin(); it2!=subFactorLists_[factorId].end();++it2) {
244  const size_t& subModelId = (*it2).subModelId_;
245  const size_t& subVariableId = (*it2).subIndices_[0];
246  required[subModelId].erase(subVariableId);
247  }
248  // add SubFactor that are still missing
249  for(size_t subModelId=0; subModelId<numberOfSubModels_; ++subModelId) {
250  for(std::set<size_t>::const_iterator setit=required[subModelId].begin(); setit!=required[subModelId].end(); setit++) {
251  const std::vector<size_t> subIndices(1,(*setit));
252  addSubFactor(subModelId, factorId, subIndices);
253  }
254  }
255  }
256  else{
257  // find included SubFactors
258  std::vector<size_t> subIndices(1,varId);
259  for(it3 = emptySubFactorLists_[subIndices].begin(); it3!=emptySubFactorLists_[subIndices].end();++it3) {
260  const size_t& subModelId = (*it3).subModelId_;
261  const size_t& subVariableId = (*it3).subIndices_[0];
262  required[subModelId].erase(subVariableId);
263  }
264  // add SubFactor that are still missing
265  for(size_t subModelId=0; subModelId<numberOfSubModels_; ++subModelId) {
266  for(std::set<size_t>::const_iterator setit=required[subModelId].begin(); setit!=required[subModelId].end(); setit++) {
267  const std::vector<size_t> indices(1,varId);
268  const std::vector<size_t> subIndices(1,(*setit));
269  addSubFactor(subModelId,indices, subIndices);
270  }
271  }
272  }
273  }
274  }
275 }
276 
277 inline void GraphicalModelDecomposition::reorder()
278 {
279  SubVariableListType::iterator it;
280  SubFactorListType::iterator it2;
281  EmptySubFactorListType::iterator it3;
282  std::map<std::vector<size_t>, EmptySubFactorListType>::iterator it4;
283 
284  std::vector<size_t> varCount(numberOfSubModels_,0);
285  std::vector<std::vector<size_t> > subVarMap(numberOfSubModels_);
286  for(size_t subModel=0; subModel<numberOfSubModels_; ++subModel) {
287  subVarMap[subModel].resize(numberOfSubVariables_[subModel],0);
288  }
289 
290  // re-order SubVariableIds
291  for(size_t varId=0; varId<numberOfVariables_; ++varId) {
292  for(it = subVariableLists_[varId].begin(); it!=subVariableLists_[varId].end();++it) {
293  const size_t& subModelId = (*it).subModelId_;
294  const size_t& subVariableId = (*it).subVariableId_;
295  subVarMap[subModelId][subVariableId] = varCount[subModelId];
296  (*it).subVariableId_ = varCount[subModelId]++;
297  }
298  }
299 
300  // reset FactorSubIndices
301  for(size_t factorId=0; factorId<numberOfFactors_; ++factorId) {
302  for(it2 = subFactorLists_[factorId].begin(); it2!=subFactorLists_[factorId].end();++it2) {
303  const size_t& subModelId = (*it2).subModelId_;
304  for(size_t i=0; i<(*it2).subIndices_.size();++i) {
305  (*it2).subIndices_[i] = subVarMap[subModelId][(*it2).subIndices_[i]];
306  }
307  for(size_t i=1; i<(*it2).subIndices_.size();++i) {
308  OPENGM_ASSERT((*it2).subIndices_[i-1] < (*it2).subIndices_[i]);
309  }
310  }
311  }
312  for(it4=emptySubFactorLists_.begin() ; it4 != emptySubFactorLists_.end(); it4++ ) {
313  for(it3 = (*it4).second.begin(); it3!=(*it4).second.end();++it3) {
314  const size_t& subModelId = (*it3).subModelId_;
315  for(size_t i=0; i<(*it3).subIndices_.size();++i) {
316  (*it3).subIndices_[i] = subVarMap[subModelId][(*it3).subIndices_[i]];
317  }
318  for(size_t i=1; i<(*it3).subIndices_.size();++i) {
319  OPENGM_ASSERT((*it3).subIndices_[i-1] < (*it3).subIndices_[i]);
320  }
321  }
322  }
323 }
324 
325 template <class GM>
326 bool GraphicalModelDecomposition::isValid(const GM& gm) const
327 {
328  OPENGM_ASSERT(subVariableLists_.size() == gm.numberOfVariables());
329  OPENGM_ASSERT(subFactorLists_.size() == gm.numberOfFactors());
330  if(!NO_DEBUG) {
331  for(size_t i=0; i<gm.numberOfVariables(); ++i) {
332  OPENGM_ASSERT(subVariableLists_[i].size() > 0);
333  }
334  }
335  for(size_t i=0; i<gm.numberOfFactors(); ++i) {
336  OPENGM_ASSERT(subFactorLists_[i].size() > 0);
337  for(SubFactorListType::const_iterator it=subFactorLists_[i].begin() ; it != subFactorLists_[i].end(); it++ ) {
338  OPENGM_ASSERT((*it).subIndices_.size() == gm[i].numberOfVariables());
339  // check consistency of SubIndices of SubFactors
340  for(size_t j=0; j<gm[i].numberOfVariables(); ++j) {
341  const SubVariableListType &list = subVariableLists_[gm[i].variableIndex(j)];
342  bool check = false;
343  for(SubVariableListType::const_iterator it2=list.begin() ; it2 != list.end(); it2++ ) {
344  if(((*it2).subModelId_ == (*it).subModelId_) && ((*it2).subVariableId_ == (*it).subIndices_[j])) {
345  check = true;
346  }
347  }
348  OPENGM_ASSERT(check);
349  }
350  }
351  }
352 
353  bool ret = true;
354  if(subVariableLists_.size() != gm.numberOfVariables()) {
355  ret = false;
356  }
357  if(subFactorLists_.size() != gm.numberOfFactors()) {
358  ret = false;
359  }
360  for(size_t i=0; i<gm.numberOfVariables(); ++i) {
361  if(subVariableLists_[i].size()==0) {
362  ret = false;
363  }
364  }
365  for(size_t i=0; i<gm.numberOfFactors(); ++i) {
366  if(subFactorLists_[i].size()==0) {
367  ret = false;
368  }
369  for(SubFactorListType::const_iterator it=subFactorLists_[i].begin() ; it != subFactorLists_[i].end(); it++ ) {
370  if((*it).subIndices_.size() != gm[i].numberOfVariables()) {
371  ret = false;
372  }
373  //Check Consistency of SubIndices of SubFactors
374  //This might be very timeconsuming
375  /*
376  for(size_t j=0; j<gm[i].numberOfVariables(); ++j) {
377  const SubVariableListType &list = subVariableLists_[gm[i].variableIndex(j)];
378  bool check = false;
379  for(SubVariableListType::const_iterator it2=list.begin() ; it2 != list.end(); it2++ ) {
380  if( (*it2).subModelId == (*it).subModelId && (*it2).subVariableId == (*it).subIndices_[j]) {
381  check = true;
382  }
383  }
384  if(!check) {ret=false;}
385  }
386  */
387  }
388  }
389  return ret;
390 }
391 
393 
394 } // namespace opengm
395 
396 #endif // #ifndef OPENGM_GRAPHICALMODELDECOMPOSITION_HXX
397 
The OpenGM namespace.
Definition: config.hxx:43
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
const bool NO_DEBUG
Definition: config.hxx:64