WaveBlocksND
combinatorics.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <array>
4 #include <list>
5 
6 
7 namespace waveblocks {
8  namespace math {
9  template<int D> using partition_t = std::array<int, D>;
10  template<int D> using partitions_t = std::list<partition_t<D>>;
11  template<int D> using point_t = std::array<int, D>;
12  template<int D> using latticepoints_t = std::list<point_t<D>>;
13  template<int D> using permutation_t = std::array<int, D>;
14  template<int D> using permutations_t = std::list<permutation_t<D>>;
15 
19  template<int D>
20  int sum(const point_t<D> Z) {
21  int s = 0;
22  for(int i=0; i<D; i++) {
23  s += Z[i];
24  }
25  return s;
26  }
27 
31  template<int D>
32  int nz(const point_t<D> Z) {
33  int s = 0;
34  for(int i=0; i<D; i++) {
35  if(Z[i] == 0) {
36  s++;
37  }
38  }
39  return s;
40  }
41 
45  template<int D>
46  int nnz(const point_t<D> Z) {
47  return D - nz<D>(Z);
48  }
49 
57  template<int D>
58  partitions_t<D> partitions(const int K) {
61 
62  P.fill(0);
63  partitions.push_back(P);
64 
65  while(sum<D>(P) <= K) {
66  int p0 = P[0];
67  bool broke = false;
68  for(int i=1; i < D; i++) {
69  p0 += P[i];
70  if(P[0] <= P[i] + 1) {
71  P[i] = 0;
72  } else {
73  P[0] = p0 - i * (P[i] + 1);
74  for(int j=1; j <= i; j++) {
75  P[j] = P[i] + 1;
76  }
77  partitions.push_back(P);
78  broke = true;
79  break;
80  }
81  }
82  if(!broke) {
83  P[0] = p0 + 1;
84  if(sum<D>(P) <= K) {
85  partitions.push_back(P);
86  }
87  }
88  }
89 
90  return partitions;
91  }
92 
99  template<int D>
102  point_t<D> k;
103 
104  for(int n=0; n <= N; n++) {
105  k.fill(0);
106  k[0] = n;
107  L.push_back(k);
108  int c = 1;
109  while(k[D-1] < n) {
110  if(c == D) {
111  for(int i = c-1; i > 0; i--) {
112  c = i;
113  if(k[i-1] != 0) {
114  break;
115  }
116  }
117  }
118  k[c-1]--;
119  c++;
120  k[c-1] = n;
121  for(int t=0; t < c-1; t++) {
122  k[c-1] -= k[t];
123  }
124  if(c < D) {
125  for(int t=c; t < D; t++) {
126  k[t] = 0;
127  }
128  }
129  L.push_back(k);
130  }
131  }
132 
133  return L;
134  }
135 
141  template<int D>
144  permutation_t<D> P = permutation;
145 
146  permutations.push_back(P);
147 
148  bool broke = true;
149  while(broke) {
150  broke = false;
151  for(int i=1; i < D; i++) {
152  int pi = P[i];
153  if(P[i-1] > pi) {
154  int I = i;
155  if(i > 1) {
156  int J = I;
157  int u = I / 2;
158  for(int j=0; j < u; j++) {
159  int pj = P[j];
160  if(pj <= pi) {
161  I--;
162  }
163  P[j] = P[i-j-1];
164  P[i-j-1] = pj;
165  if(P[j] > pi) {
166  J = j + 1;
167  }
168  }
169  if(P[I-1] <= pi) {
170  I = J;
171  }
172  }
173  P[i] = P[I-1];
174  P[I-1] = pi;
175  permutations.push_back(P);
176  broke = true;
177  break;
178  }
179  }
180  }
181 
182  return permutations;
183  }
184  }
185 }
std::list< point_t< D >> latticepoints_t
Definition: combinatorics.hpp:12
Definition: coefficients_file_parser.cpp:10
constexpr T pi()
Definition: pi.hpp:6
std::array< int, D > point_t
Definition: combinatorics.hpp:11
var c
Definition: jquery.js:23
partitions_t< D > partitions(const int K)
Definition: combinatorics.hpp:58
int nnz(const point_t< D > Z)
Definition: combinatorics.hpp:46
std::list< partition_t< D >> partitions_t
Definition: combinatorics.hpp:10
int nz(const point_t< D > Z)
Definition: combinatorics.hpp:32
latticepoints_t< D > lattice_points(const int N)
Definition: combinatorics.hpp:100
permutations_t< D > permutations(const permutation_t< D > permutation)
Definition: combinatorics.hpp:142
function L
Definition: jquery.js:16
std::array< int, D > permutation_t
Definition: combinatorics.hpp:13
std::list< permutation_t< D >> permutations_t
Definition: combinatorics.hpp:14
std::array< int, D > partition_t
Definition: combinatorics.hpp:9
int sum(const point_t< D > Z)
Sum of the components of the point Z.
Definition: combinatorics.hpp:20
var k
Definition: jquery.js:23
Z
Definition: jquery.js:23