Orbiter 2022
Combinatorial Objects
orbit_of_sets.cpp
Go to the documentation of this file.
1// orbit_of_sets.cpp
2//
3// Anton Betten
4// Feb 6, 2013
5//
6//
7//
8//
9//
10
12#include "discreta/discreta.h"
15
16using namespace std;
17
18namespace orbiter {
19namespace layer4_classification {
20
21
22
24{
25 A = NULL;
26 A2 = NULL;
27 gens = NULL;
28 set = NULL; // the set whose orbit we want to compute; it has size 'sz'
29 sz = 0;
30
31 position_of_original_set = 0; // = 0; never changes
32 allocation_length = 0; // number of entries allocated in Sets
33 old_length = 0;
34 used_length = 0; // number of sets currently stored in Sets
35 Sets = NULL;
36 // the sets ar stored in the order in which they
37 // are discovered and added to the tree
38 Extra = NULL;
39 cosetrep = NULL;
40 cosetrep_tmp = NULL;
41
42 //std::multimap<uint32_t, int> Hashing;
43 //null();
44}
45
47{
48 freeself();
49}
50
52{
53 //Sets = NULL;
54}
55
57{
58 int i;
59
60 if (Sets) {
61 for (i = 0; i < used_length; i++) {
62 FREE_lint(Sets[i]);
63 }
65 }
66 if (Extra) {
68 }
69 if (cosetrep) {
71 }
72 if (cosetrep_tmp) {
74 }
75 null();
76}
77
79 long int *set, int sz,
80 data_structures_groups::vector_ge *gens, int verbose_level)
81{
82 int f_v = (verbose_level >= 1);
83
84 if (f_v) {
85 cout << "orbit_of_sets::init" << endl;
86 }
92
95
96 compute(verbose_level);
97
98 if (f_v) {
99 cout << "orbit_of_sets::init done" << endl;
100 }
101}
102
103void orbit_of_sets::compute(int verbose_level)
104{
105 int f_v = (verbose_level >= 1);
106 int f_vv = FALSE;//(verbose_level >= 2);
107 int i, cur, j;
108 long int *cur_set;
109 long int *new_set;
110 long int *Q;
111 int Q_len;
113
114 if (f_v) {
115 cout << "orbit_of_sets::compute" << endl;
116 }
117 cur_set = NEW_lint(sz);
118 new_set = NEW_lint(sz);
119 allocation_length = 1000;
123 Sets[0] = NEW_lint(sz);
124 Lint_vec_copy(set, Sets[0], sz);
126 Sorting.lint_vec_heapsort(Sets[0], sz);
127
128 Extra[0 * 2 + 0] = -1;
129 Extra[0 * 2 + 1] = -1;
130
131
132 uint32_t h;
134
135 h = Data.lint_vec_hash(Sets[0], sz);
136 Hashing.insert(pair<uint32_t, int>(h, 0));
137
138 used_length = 1;
140 Q[0] = 0;
141 Q_len = 1;
142 while (Q_len) {
143 if (f_vv) {
144 cout << "Q_len = " << Q_len << " : used_length="
145 << used_length << " : ";
146 Lint_vec_print(cout, Q, Q_len);
147 cout << endl;
148 }
149 cur = Q[0];
150 for (i = 1; i < Q_len; i++) {
151 Q[i - 1] = Q[i];
152 }
153 Q_len--;
154 Lint_vec_copy(Sets[cur], cur_set, sz);
155
156 for (j = 0; j < gens->len; j++) {
157 if (f_vv) {
158 cout << "Q_len = " << Q_len << " : used_length="
159 << used_length << " : ";
160 cout << "applying generator " << j << endl;
161 }
162 A2->map_a_set(cur_set, new_set, sz, gens->ith(j),
163 0 /* verbose_level*/);
164 Sorting.lint_vec_heapsort(new_set, sz);
165 h = Data.lint_vec_hash(new_set, sz);
166
167 map<uint32_t, int>::iterator itr, itr1, itr2;
168 int pos, f_found;
169
170 itr1 = Hashing.lower_bound(h);
171 itr2 = Hashing.upper_bound(h);
172 f_found = FALSE;
173 for (itr = itr1; itr != itr2; ++itr) {
174 pos = itr->second;
175 if (Sorting.lint_vec_compare(new_set, Sets[pos], sz) == 0) {
176 f_found = TRUE;
177 break;
178 }
179 }
180 if (!f_found) {
181
183 int al2 = allocation_length + old_length;
184 long int **Sets2;
185 int *Extra2;
186 long int *Q2;
187 if (f_vv) {
188 cout << "reallocating to length " << al2 << endl;
189 }
190
191 // reallocate Sets:
192 Sets2 = NEW_plint(al2);
193 for (i = 0; i < allocation_length; i++) {
194 Sets2[i] = Sets[i];
195 }
197 Sets = Sets2;
198
199 // reallocate Extra:
200 if (f_vv) {
201 cout << "reallocate Extra" << endl;
202 }
203 Extra2 = NEW_int(al2 * 2);
206 Extra = Extra2;
207
208 // reallocate Q2:
209 if (f_vv) {
210 cout << "reallocate Q2" << endl;
211 }
212 Q2 = NEW_lint(al2);
213 Lint_vec_copy(Q, Q2, Q_len);
214 FREE_lint(Q);
215 Q = Q2;
216
218 allocation_length = al2;
219 if (f_vv) {
220 cout << "reallocating to length " << al2 << " done" << endl;
221 }
222 }
223
225 Lint_vec_copy(new_set, Sets[used_length], sz);
226 Extra[used_length * 2 + 0] = cur;
227 Extra[used_length * 2 + 1] = j;
228 used_length++;
229
230 if ((used_length % 10000) == 0) {
231 cout << "orbit_of_sets::compute " << used_length
232 << " Q_len=" << Q_len
233 << " allocation_length=" << allocation_length
234 << endl;
235 }
236
237 Q[Q_len++] = used_length - 1;
238 Hashing.insert(pair<uint32_t, int>(h, used_length - 1));
239
240 } // if (!f_found)
241
242
243 }
244 }
245
246
247#if 0
248 map<uint32_t, int>::iterator itr;
249 int pos;
250 //uint32_t h;
251
252 int cnt;
253
254 cout << "Testing hash values..." << endl;
255 for (itr = Hashing.begin(), cnt = 0; itr != Hashing.end(); ++itr, cnt++) {
256 //cout << cnt << " : " << itr->first << " : " << itr->second << endl;
257 pos = itr->second;
258 h = int_vec_hash(Sets[pos], sz);
259 if (h != itr->first) {
260 cout << "h != itr->first" << endl;
261 exit(1);
262 }
263 }
264 cout << "test 2..." << endl;
265 int p;
266 for (p = 0; p < used_length; p++) {
267 h = int_vec_hash(Sets[p], sz);
268 map<uint32_t, int>::iterator itr, itr1, itr2;
269 int pos, f_found;
270
271 itr1 = Hashing.lower_bound(h);
272 itr2 = Hashing.upper_bound(h);
273 f_found = FALSE;
274 for (itr = itr1; itr != itr2; ++itr) {
275 pos = itr->second;
276 if (p == pos) {
277 f_found = TRUE;
278 break;
279 }
280 }
281 if (!f_found) {
282 cout << "could not find entry " << p << " with hash " << h << endl;
284 cout << "could not find entry " << p << " with hash " << h << endl;
285 int_vec_print(cout, Sets[p], sz);
286 cout << endl;
287 h = int_vec_hash(Sets[p], sz);
288 cout << h << endl;
289 exit(1);
290 }
291 }
292#endif
293
294
295 if (f_v) {
296 cout << "orbit_of_sets::compute found an orbit of length "
297 << used_length << endl;
298 }
299
300
301 FREE_lint(Q);
302 if (f_v) {
303 cout << "orbit_of_sets::compute done" << endl;
304 }
305}
306
308{
309 map<uint32_t, int>::iterator itr;
310 int pos;
311 uint32_t h;
313
314 int cnt;
315
316 for (itr = Hashing.begin(), cnt = 0; itr != Hashing.end(); ++itr, cnt++) {
317 cout << cnt << " : " << itr->first << " : " << itr->second << endl;
318 pos = itr->second;
319 h = Data.lint_vec_hash(Sets[pos], sz);
320 if (h != itr->first) {
321 cout << "h != itr->first" << endl;
322 exit(1);
323 }
324 }
325
326}
327
329 int &orbit_length, int &set_size, int verbose_level)
330{
331 int f_v = (verbose_level >= 1);
332 int i, j;
333
334 set_size = sz;
335 orbit_length = used_length;
336 if (f_v) {
337 cout << "orbit_of_sets::get_table_of_orbits orbit_length="
338 << orbit_length << endl;
339 }
340 Table = NEW_lint(orbit_length * set_size);
341 for (i = 0; i < orbit_length; i++) {
342 for (j = 0; j < set_size; j++) {
343 Table[i * set_size + j] = Sets[i][j];
344 }
345 }
346 if (f_v) {
347 cout << "orbit_of_sets::get_table_of_orbits done" << endl;
348 }
349}
350
351
353 int &orbit_length, int &set_size, int verbose_level)
354{
355 int f_v = (verbose_level >= 1);
356 int i, j;
357 uint32_t h;
359
360 set_size = sz + 1;
361 orbit_length = used_length;
362 if (f_v) {
363 cout << "orbit_of_sets::get_table_of_orbits_and_hash_values orbit_length="
364 << orbit_length << endl;
365 }
366 Table = NEW_lint(orbit_length * set_size);
367 for (i = 0; i < orbit_length; i++) {
368
369 h = Data.lint_vec_hash(Sets[i], sz);
370
371 Table[i * set_size + 0] = h;
372 for (j = 1; j < set_size; j++) {
373 Table[i * set_size + j] = Sets[i][j - 1];
374 }
375 }
376 if (f_v) {
377 cout << "orbit_of_sets::get_table_of_orbits_and_hash_values done" << endl;
378 }
379}
380
382 data_structures_groups::vector_ge *&Coset_reps, int verbose_level)
383{
384 int f_v = (verbose_level >= 1);
385
386 if (f_v) {
387 cout << "orbit_of_sets::make_table_of_coset_reps" << endl;
388 }
389 int j, prev, label;
390
392 Coset_reps->init(A, 0);
393 Coset_reps->allocate(used_length, 0);
394 for (j = 0; j < used_length; j++) {
395 prev = Extra[2 * j + 0];
396 label = Extra[2 * j + 1];
397 if (prev == -1) {
398 A->element_one(Coset_reps->ith(j), 0);
399 }
400 else {
401 A->element_mult(Coset_reps->ith(prev), gens->ith(label), Coset_reps->ith(j), 0);
402 }
403 }
404 if (f_v) {
405 cout << "orbit_of_sets::make_table_of_coset_reps done" << endl;
406 }
407}
408
410// result is in cosetrep
411// determines an element in the group
412// that moves the orbit representative
413// to the j-th element in the orbit.
414{
415 int *gen;
416
417 if (Extra[2 * j + 0] != -1) {
418 coset_rep(Extra[2 * j + 0]);
419 gen = gens->ith(Extra[2 * j + 1]);
422 }
423 else {
425 }
426}
427
428void orbit_of_sets::get_orbit_of_points(std::vector<long int> &Orbit, int verbose_level)
429{
430 int f_v = (verbose_level >= 1);
431
432 if (f_v) {
433 cout << "orbit_of_sets::get_orbit_of_points" << endl;
434 }
435 int i;
436
437 for (i = 0; i < used_length; i++) {
438 Orbit.push_back(Sets[i][0]);
439 }
440 if (f_v) {
441 cout << "orbit_of_sets::get_orbit_of_points done" << endl;
442 }
443}
444
445void orbit_of_sets::get_prev(std::vector<int> &Prev, int verbose_level)
446{
447 int f_v = (verbose_level >= 1);
448
449 if (f_v) {
450 cout << "orbit_of_sets::get_prev" << endl;
451 }
452 int i;
453
454 for (i = 0; i < used_length; i++) {
455 Prev.push_back(Extra[2 * i + 0]);
456 }
457 if (f_v) {
458 cout << "orbit_of_sets::get_prev done" << endl;
459 }
460}
461
462void orbit_of_sets::get_label(std::vector<int> &Label, int verbose_level)
463{
464 int f_v = (verbose_level >= 1);
465
466 if (f_v) {
467 cout << "orbit_of_sets::get_label" << endl;
468 }
469 int i;
470
471 for (i = 0; i < used_length; i++) {
472 Label.push_back(Extra[2 * i + 1]);
473 }
474 if (f_v) {
475 cout << "orbit_of_sets::get_label done" << endl;
476 }
477}
478
479
480
481
482
483}}
484
485
a catch-all container class for everything related to data structures
a collection of functions related to sorted vectors
int lint_vec_compare(long int *p, long int *q, int len)
Definition: sorting.cpp:2326
a permutation group in a fixed action.
Definition: actions.h:99
void map_a_set(long int *set, long int *image_set, int n, int *Elt, int verbose_level)
Definition: action.cpp:668
void element_mult(void *a, void *b, void *ab, int verbose_level)
Definition: action_cb.cpp:315
void element_one(void *elt, int verbose_level)
Definition: action_cb.cpp:224
void element_move(void *a, void *b, int verbose_level)
Definition: action_cb.cpp:335
void init(actions::action *A, int verbose_level)
Definition: vector_ge.cpp:55
void make_table_of_coset_reps(data_structures_groups::vector_ge *&Coset_reps, int verbose_level)
void get_label(std::vector< int > &Label, int verbose_level)
void get_table_of_orbits_and_hash_values(long int *&Table, int &orbit_length, int &set_size, int verbose_level)
std::multimap< uint32_t, int > Hashing
Definition: orbits.h:130
data_structures_groups::vector_ge * gens
Definition: orbits.h:110
void get_orbit_of_points(std::vector< long int > &Orbit, int verbose_level)
void get_table_of_orbits(long int *&Table, int &orbit_length, int &set_size, int verbose_level)
void get_prev(std::vector< int > &Prev, int verbose_level)
void init(actions::action *A, actions::action *A2, long int *set, int sz, data_structures_groups::vector_ge *gens, int verbose_level)
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define NEW_plint(n)
Definition: foundations.h:629
#define FREE_int(p)
Definition: foundations.h:640
#define FREE_plint(p)
Definition: foundations.h:643
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
the orbiter library for the classification of combinatorial objects