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
7
typedef
unsigned
long
int
ulong
;
8
9
inline
ulong
range_safe_add
(
ulong
a,
ulong
b)
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
20
Subsets::Subsets
(
size_t
n,
size_t
p
) :
mNumElements
(n),
mMaxSubsetSize
(
p
)
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
35
Subsets::~Subsets
()
36
{
37
for
(
size_t
i = 0; i <=
mMaxSubsetSize
; i++)
freemem
(
mTable
[i]);
38
freemem
(
mTable
);
39
}
40
41
bool
Subsets::isValid
(
const
Subset
&a)
42
{
43
if
(a.size() == 0)
return
true
;
44
return
isValid
(
mNumElements
, a.size(), &(a[0]));
45
}
46
47
bool
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
}
56
bool
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
66
size_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
80
size_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
96
void
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
124
bool
Subsets::increment
(
size_t
n,
Subset
&
s
)
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
146
bool
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
163
int
Subsets::concatenateSubsets
(
const
Subset
&
s
,
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
203
void
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:
Subsets::increment
static bool increment(size_t n, Subset &s)
Definition
comb.cpp:124
Subsets::~Subsets
~Subsets()
Definition
comb.cpp:35
Subsets::mNumElements
size_t mNumElements
Definition
comb.hpp:125
Subsets::isValid
bool isValid(const Subset &a)
Definition
comb.cpp:41
Subsets::concatenateSubsets
static int concatenateSubsets(const Subset &s, const Subset &t, Subset &result)
Definition
comb.cpp:163
Subsets::Subsets
Subsets(size_t n, size_t p)
Definition
comb.cpp:20
Subsets::encode
size_t encode(const Subset &a)
Definition
comb.cpp:66
Subsets::decode
void decode(size_t val, Subset &result)
Definition
comb.cpp:96
Subsets::binom
size_t binom(size_t n, size_t p)
Definition
comb.hpp:117
Subsets::mTable
size_t ** mTable
Definition
comb.hpp:124
Subsets::encodeBoundary
size_t encodeBoundary(size_t index, const Subset &a)
Definition
comb.cpp:80
Subsets::show
static void show(std::ostream &o, const Subset &a)
Definition
comb.cpp:203
Subsets::mMaxSubsetSize
size_t mMaxSubsetSize
Definition
comb.hpp:127
range_safe_add
ulong range_safe_add(ulong a, ulong b)
Definition
comb.cpp:9
ulong
unsigned long int ulong
Definition
comb.cpp:7
Subset
std::vector< size_t > Subset
Definition
comb.hpp:58
comb.hpp
Subsets — combinatorial-number-system encoding of p-subsets of {0,...,n-1}.
p
int p
Definition
godboltTest.cpp:36
freemem
void freemem(void *s)
Definition
m2-mem.cpp:103
s
void size_t s
Definition
m2-mem.cpp:271
result
VALGRIND_MAKE_MEM_DEFINED & result(result)
newarray
#define newarray(T, len)
Definition
newdelete.hpp:82
newarray_atomic
#define newarray_atomic(T, len)
Definition
newdelete.hpp:91
emit_line
void emit_line(const char *s)
Definition
text-io.cpp:47
text-io.hpp
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.
Macaulay2
e
comb.cpp
Generated on
for Macaulay2 Engine by
1.15.0