OpenGM  2.3.x
Discrete Graphical Model Library
partitions.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef OPENGM_PARTITIONS_HXX
3 #define OPENGM_PARTITIONS_HXX
4 
5 #include <vector>
6 #include <algorithm>
7 
8 namespace opengm {
9 
11  template<class I=size_t, class L=size_t>
12  class Partitions {
13  public:
14  typedef I EdgeLabelType;
15  typedef L NodeLabelType;
16 
17  void resize(size_t N) { buildPartitions(N);}
18  size_t BellNumber(size_t N) { return Bell[N]; }
19  EdgeLabelType getPartition(size_t n){ return partitions[n];}
20 
21  template<class T>
22  void getPartition(const size_t n, std::vector<T>& l){
23  const EdgeLabelType el = getPartition(n);
24  const size_t N = l.size();
25  size_t base=1;
26  l[0] = 0;
27  for(size_t v1=1; v1<N; ++v1){
28  l[v1]=v1;
29  for(size_t v2=0; v2<v1; ++v2){
30  if( (el & base) == base){
31  l[v1] = l[v2];
32  }
33  base *= 2;
34  }
35  }
36  }
37 
38  size_t number2Index(const EdgeLabelType el){
39  typename std::vector<EdgeLabelType>::iterator it;
40  it = find(partitions.begin(), partitions.end(), el);
41 
42  if(it == partitions.end() )
43  return -1;
44  else
45  //return (size_t)(it-partitions.begin())/sizeof(EdgeLabelType);
46  return std::distance(partitions.begin(),it);
47  }
48 
49  size_t label2Index(const std::vector<NodeLabelType>& l){
50  buildPartitions(l.size());
51  EdgeLabelType el = label2Number(l);
52  return number2Index(el);
53  }
54 
55  template<class IT>
56  size_t label2Index(const IT begin, const size_t order){
57  buildPartitions(order);
58  EdgeLabelType el = label2Number(begin,order);
59  return number2Index(el);
60  }
61 
62  EdgeLabelType label2Number(const std::vector<NodeLabelType>& l){
63  EdgeLabelType indicator = 0;
64  EdgeLabelType base = 1;
65 
66  for(size_t v1=1; v1<l.size(); ++v1){
67  for(size_t v2=0; v2<v1; ++v2){
68  indicator += base * (l[v1] == l[v2]);
69  base*=2;
70  }
71  }
72  return indicator;
73  }
74 
75  template<class IT>
76  EdgeLabelType label2Number(IT begin, size_t order){
77  EdgeLabelType indicator = 0;
78  EdgeLabelType base = 1;
79 
80  for(size_t v1=1; v1<order; ++v1){
81  for(size_t v2=0; v2<v1; ++v2){
82  indicator += base * (*(begin+v1) == *(begin+v2) );
83  base*=2;
84  }
85  }
86  return indicator;
87  }
88 
89  private:
90  static const size_t Bell[16];// = {1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, 27644437, 190899322, 1382958545};
91  static std::vector<EdgeLabelType> partitions;
92 
93  bool increment( std::vector<NodeLabelType>& l){
94  size_t N=l.size();
95  size_t p=0;
96  std::vector<NodeLabelType> maxV(N+1,0);
97  for(size_t i=N; i>0 ; --i)
98  maxV[i-1] = std::max(maxV[i],l[i-1]);
99 
100  //find position to increment
101  for(p=0; p<=N; ++p){
102  if(p==N) return false;
103  if(l[p]<N-1-p && ( (p==N-1) || (l[p]<=maxV[p+1] )))
104  break;
105  }
106  //std::cout<<"X " <<p<<std::endl;
107  ++l[p];
108  maxV[p] = std::max(maxV[p+1], l[p]);
109  //set succesors
110  for(size_t q=p; q>0;--q){
111  l[q-1]=0;
112  maxV[q-1] = maxV[p];
113  }
114  return true;
115  }
116 
117 
118  void buildPartitions(size_t N){
119  if(partitions.size() >= Bell[N])
120  return;
121  if(N*(N-1)/2>sizeof(I)*8){
122  throw std::runtime_error("Error: EdgeIndexType is to small!");
123  }
124 
125  partitions.clear();
126  partitions.reserve(Bell[N]);
127 
128  std::vector<NodeLabelType> l(N,0);
129  partitions.push_back(label2Number(l));
130  while( increment(l) ){
131  partitions.push_back( label2Number(l) );
132  }
133  //std::cout << "B("<<N<<") = "<<partitions.size()<<" == "<<Bell[N]<<std::endl;
134  //assert(partitions.size() == Bell[N]);
135  std::sort(partitions.begin(), partitions.end());
136  return;
137  }
138  };
139 
140  template<class I, class L>
141  const size_t Partitions<I, L>::Bell[16] = {1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597, 27644437, 190899322, 1382958545};
142 
143  template<class I, class L>
144  std::vector<I> Partitions<I, L>::partitions;
145 
146 }
147 #endif
size_t label2Index(const IT begin, const size_t order)
Definition: partitions.hxx:56
The OpenGM namespace.
Definition: config.hxx:43
EdgeLabelType getPartition(size_t n)
Definition: partitions.hxx:19
void resize(size_t N)
Definition: partitions.hxx:17
EdgeLabelType label2Number(const std::vector< NodeLabelType > &l)
Definition: partitions.hxx:62
size_t BellNumber(size_t N)
Definition: partitions.hxx:18
size_t number2Index(const EdgeLabelType el)
Definition: partitions.hxx:38
size_t label2Index(const std::vector< NodeLabelType > &l)
Definition: partitions.hxx:49
void getPartition(const size_t n, std::vector< T > &l)
Definition: partitions.hxx:22
EdgeLabelType label2Number(IT begin, size_t order)
Definition: partitions.hxx:76
Enumaration of partitions of a set of N nodes.
Definition: partitions.hxx:12