Macaulay2 Engine
Loading...
Searching...
No Matches
comb.cpp
Go to the documentation of this file.
1// Copyright 1997-2013 by Michael E. Stillman
2
3#include "comb.hpp"
4#include "text-io.hpp"
5#include <ostream>
6
7typedef unsigned long int ulong;
8
10{
11 ulong c = a + b;
12 if (c < a)
13 {
14 emit_line("ulong integer addition overflow");
15 exit(-1);
16 }
17 return c;
18}
19
21{
22 assert(p <= n);
23 // we also need to assert that all values placed are size_t without overflow
24 mTable = newarray(size_t *, p + 1);
25 for (size_t i = 0; i <= p; i++) mTable[i] = newarray_atomic(size_t, n + 1);
26
27 // Now fill in the table completely
28 for (size_t i = 1; i <= mMaxSubsetSize; i++) mTable[i][0] = 0;
29 for (size_t j = 0; j <= mNumElements; j++) mTable[0][j] = 1;
30 for (size_t i = 1; i <= mMaxSubsetSize; i++)
31 for (size_t j = 1; j <= mNumElements; j++)
32 mTable[i][j] = range_safe_add(mTable[i][j - 1], mTable[i - 1][j - 1]);
33}
34
36{
37 for (size_t i = 0; i <= mMaxSubsetSize; i++) freemem(mTable[i]);
39}
40
42{
43 if (a.size() == 0) return true;
44 return isValid(mNumElements, a.size(), &(a[0]));
45}
46
47bool Subsets::isValid(size_t nElements, size_t subsetSize, const size_t *a)
48{
49 if (subsetSize > nElements) return false;
50 if (subsetSize == 0) return true;
51 if (a[subsetSize - 1] > nElements) return false;
52 for (size_t i = 1; i < subsetSize; i++)
53 if (a[i] <= a[i - 1]) return false;
54 return true;
55}
56bool Subsets::isValid(size_t nElements, size_t subsetSize, const int *a)
57{
58 if (subsetSize > nElements) return false;
59 if (subsetSize == 0) return true;
60 if (a[subsetSize - 1] > nElements) return false;
61 for (size_t i = 1; i < subsetSize; i++)
62 if (a[i] <= a[i - 1]) return false;
63 return true;
64}
65
66size_t Subsets::encode(const Subset &a)
67{
68 // Subsets should be an ascending sequence of ints, all in the range
69 // 0..mNumElements-1
70 assert(a.size() <= mMaxSubsetSize);
71 assert(isValid(a));
72
73 size_t result = 0;
74
75 for (size_t i = 0; i < a.size(); i++) result += binom(a[i], i + 1);
76
77 return result;
78}
79
80size_t Subsets::encodeBoundary(size_t e, const Subset &a)
81// Take out the e-th element of a (e=0..a.size()-1), and then encode that
82// a.size()-1 subset.
83{
84 assert(a.size() <= mMaxSubsetSize);
85 assert(isValid(a));
86
87 size_t result = 0;
88
89 for (size_t i = 0; i < e; i++) result += binom(a[i], i + 1);
90
91 for (size_t i = e + 1; i < a.size(); i++) result += binom(a[i], i);
92
93 return result;
94}
95
96void Subsets::decode(size_t val, Subset &result)
97{
98 size_t tmp = val;
99 size_t subsetSize = result.size();
100 assert(val <= binom(mNumElements, subsetSize));
101
102 size_t len = mNumElements;
103
104 for (size_t i = subsetSize; i > 0; i--)
105 {
106 size_t bit;
107 size_t bot = 0;
108 while (bit = len % 2, len >>= 1)
109 {
110 if (binom(bot + len, i) <= tmp)
111 {
112 bot += len;
113 len += bit;
114 }
115 }
116 result[i - 1] = bot;
117 tmp -= binom(bot, i);
118 len = bot + 1;
119 }
120
121 assert(isValid(result));
122}
123
125{
126 if (s.size() == 0) return false;
127 return increment(n, s.size(), &(s[0]));
128#if 0
129 size_t p = s.size();
130 for (size_t i=0; i<p; i++)
131 {
132 // Attempt to increment this one element
133 if ((i < p-1 && s[i]+1 < s[i+1])
134 || (i == p-1 && s[i]+1 < n))
135 {
136 s[i]++;
137 for (size_t j=0; j<i; j++)
138 s[j] = j;
139 return true;
140 }
141 }
142 return false;
143#endif
144}
145
146bool Subsets::increment(size_t n, size_t subset_size, size_t *subset)
147{
148 size_t p = subset_size;
149 for (size_t i = 0; i < p; i++)
150 {
151 // Attempt to increment this one element
152 if ((i < p - 1 && subset[i] + 1 < subset[i + 1]) ||
153 (i == p - 1 && subset[i] + 1 < n))
154 {
155 subset[i]++;
156 for (size_t j = 0; j < i; j++) subset[j] = j;
157 return true;
158 }
159 }
160 return false;
161}
162
164 const Subset &t,
165 Subset &result)
166{
167 size_t p = s.size();
168 size_t q = t.size();
169 assert(p + q == result.size());
170 size_t a = 0;
171 size_t b = 0;
172 size_t c = 0;
173 size_t sign = 0;
174 if (p == 0 && q == 0) return 1;
175 for (;;)
176 {
177 if (a >= p)
178 {
179 while (b < q) result[c++] = t[b++];
180 break;
181 }
182 else if (b >= q)
183 {
184 while (a < p) result[c++] = s[a++];
185 break;
186 }
187 if (s[a] > t[b])
188 {
189 sign += p - a;
190 result[c++] = t[b++];
191 }
192 else if (s[a] < t[b])
193 {
194 result[c++] = s[a++];
195 }
196 else
197 return 0;
198 }
199 if ((sign % 2) == 0) return 1;
200 return -1;
201}
202
203void Subsets::show(std::ostream &o, const Subset &a)
204{
205 o << "[";
206 for (size_t i = 0; i < a.size(); i++)
207 {
208 if (i > 0) o << ",";
209 o << a[i];
210 }
211 o << "]";
212}
213
214// Local Variables:
215// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
216// indent-tabs-mode: nil
217// End:
static bool increment(size_t n, Subset &s)
Definition comb.cpp:124
~Subsets()
Definition comb.cpp:35
size_t mNumElements
Definition comb.hpp:125
bool isValid(const Subset &a)
Definition comb.cpp:41
static int concatenateSubsets(const Subset &s, const Subset &t, Subset &result)
Definition comb.cpp:163
Subsets(size_t n, size_t p)
Definition comb.cpp:20
size_t encode(const Subset &a)
Definition comb.cpp:66
void decode(size_t val, Subset &result)
Definition comb.cpp:96
size_t binom(size_t n, size_t p)
Definition comb.hpp:117
size_t ** mTable
Definition comb.hpp:124
size_t encodeBoundary(size_t index, const Subset &a)
Definition comb.cpp:80
static void show(std::ostream &o, const Subset &a)
Definition comb.cpp:203
size_t mMaxSubsetSize
Definition comb.hpp:127
ulong range_safe_add(ulong a, ulong b)
Definition comb.cpp:9
unsigned long int ulong
Definition comb.cpp:7
std::vector< size_t > Subset
Definition comb.hpp:58
Subsets — combinatorial-number-system encoding of p-subsets of {0,...,n-1}.
int p
void freemem(void *s)
Definition m2-mem.cpp:103
void size_t s
Definition m2-mem.cpp:271
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define newarray(T, len)
Definition newdelete.hpp:82
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
void emit_line(const char *s)
Definition text-io.cpp:47
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.