Orbiter 2022
Combinatorial Objects
poset_classification.cpp
Go to the documentation of this file.
1// poset_classification.cpp
2//
3// Anton Betten
4// December 29, 2003
5
7#include "discreta/discreta.h"
10
11using namespace std;
12
13namespace orbiter {
14namespace layer4_classification {
15namespace poset_classification {
16
17poset_of_orbits *poset_classification::get_Poo()
18{
19 return Poo;
20}
21
22std::string &poset_classification::get_problem_label_with_path()
23{
24 return problem_label_with_path;
25}
26
27std::string &poset_classification::get_problem_label()
28{
29 return problem_label;
30}
31
32int poset_classification::first_node_at_level(int i)
33{
34 return Poo->first_node_at_level(i);
35}
36
37poset_orbit_node *poset_classification::get_node(int node_idx)
38{
39 return Poo->get_node(node_idx);
40}
41
42data_structures_groups::vector_ge *poset_classification::get_transporter()
43{
44 return transporter;
45}
46
47long int *poset_classification::get_S()
48{
49 return set_S;
50}
51
52long int *poset_classification::get_set_i(int i)
53{
54 return set[i];
55}
56
57long int *poset_classification::get_set0()
58{
59 return Poo->get_set0();
60}
61
62long int *poset_classification::get_set1()
63{
64 return Poo->get_set1();
65}
66
67long int *poset_classification::get_set3()
68{
69 return Poo->get_set3();
70}
71
72int *poset_classification::get_Elt1()
73{
74 return Elt1;
75}
76
77int *poset_classification::get_Elt2()
78{
79 return Elt2;
80}
81
82long int *poset_classification::get_tmp_set_apply_fusion()
83{
84 return tmp_set_apply_fusion;
85}
86
87int poset_classification::allowed_to_show_group_elements()
88{
89 return f_allowed_to_show_group_elements;
90}
91
92int poset_classification::do_group_extension_in_upstep()
93{
94 return f_do_group_extension_in_upstep;
95}
96
97poset_with_group_action *poset_classification::get_poset()
98{
99 return Poset;
100}
101
102poset_classification_control *poset_classification::get_control()
103{
104 return Control;
105}
106
107actions::action *poset_classification::get_A()
108{
109 return Poset->A;
110}
111
112actions::action *poset_classification::get_A2()
113{
114 return Poset->A2;
115}
116
117algebra::vector_space *poset_classification::get_VS()
118{
119 return Poset->VS;
120}
121
122data_structures_groups::schreier_vector_handler *poset_classification::get_schreier_vector_handler()
123{
124 return Schreier_vector_handler;
125}
126
127int poset_classification::has_base_case()
128{
129 return f_base_case;
130}
131
132int poset_classification::has_invariant_subset_for_root_node()
133{
134 return f_has_invariant_subset_for_root_node;
135}
136
137int poset_classification::size_of_invariant_subset_for_root_node()
138{
139 return invariant_subset_for_root_node_size;
140}
141
142int *poset_classification::get_invariant_subset_for_root_node()
143{
144 return invariant_subset_for_root_node;
145}
146
147
148
149classification_base_case *poset_classification::get_Base_case()
150{
151 return Base_case;
152}
153
154int poset_classification::node_has_schreier_vector(int node_idx)
155{
156 if (Poo->get_node(node_idx)->has_Schreier_vector()) {
157 return TRUE;
158 }
159 else {
160 return FALSE;
161 }
162}
163
164int poset_classification::max_number_of_orbits_to_print()
165{
166 return downstep_orbits_print_max_orbits;
167}
168
169int poset_classification::max_number_of_points_to_print_in_orbit()
170{
171 return downstep_orbits_print_max_points_per_orbit;
172}
173
174void poset_classification::invoke_early_test_func(
175 long int *the_set, int lvl,
176 long int *candidates,
177 int nb_candidates,
178 long int *good_candidates,
179 int &nb_good_candidates,
180 int verbose_level)
181{
182 Poset->early_test_func(
183 the_set, lvl,
184 candidates,
185 nb_candidates,
186 good_candidates,
187 nb_good_candidates,
188 verbose_level - 2);
189
190}
191
192int poset_classification::nb_orbits_at_level(int level)
193{
194 return Poo->nb_orbits_at_level(level);
195}
196
197long int poset_classification::nb_flag_orbits_up_at_level(int level)
198{
199 return Poo->nb_flag_orbits_up_at_level(level);
200}
201
202poset_orbit_node *poset_classification::get_node_ij(int level, int node)
203{
204 return Poo->get_node_ij(level, node);
205}
206
207int poset_classification::poset_structure_is_contained(
208 long int *set1, int sz1, long int *set2, int sz2,
209 int verbose_level)
210{
211 int f_v = (verbose_level >= 1);
212 int f_vv = (verbose_level >= 2);
213 int f_contained;
214 int i, rk1, rk2;
216
217 if (f_v) {
218 cout << "poset_classification::poset_structure_is_contained" << endl;
219 }
220 if (f_vv) {
221 cout << "set1: ";
222 Lint_vec_print(cout, set1, sz1);
223 cout << " ; ";
224 cout << "set2: ";
225 Lint_vec_print(cout, set2, sz2);
226 cout << endl;
227 }
228 if (sz1 > sz2) {
229 f_contained = FALSE;
230 }
231 else {
232 if (Poset->f_subspace_lattice) {
233 int *B1, *B2;
234 int dim = Poset->VS->dimension;
235
236 B1 = NEW_int(sz1 * dim);
237 B2 = NEW_int((sz1 + sz2) * dim);
238
239 for (i = 0; i < sz1; i++) {
240 unrank_point(B1 + i * dim, set1[i]);
241 }
242 for (i = 0; i < sz2; i++) {
243 unrank_point(B2 + i * dim, set2[i]);
244 }
245
246 rk1 = Poset->VS->F->Linear_algebra->Gauss_easy(B1, sz1, dim);
247 if (rk1 != sz1) {
248 cout << "poset_classification::poset_structure_is_contained "
249 "rk1 != sz1" << endl;
250 exit(1);
251 }
252
253 rk2 = Poset->VS->F->Linear_algebra->Gauss_easy(B2, sz2, dim);
254 if (rk2 != sz2) {
255 cout << "poset_classification::poset_structure_is_contained "
256 "rk2 != sz2" << endl;
257 exit(1);
258 }
259 Int_vec_copy(B1,
260 B2 + sz2 * dim,
261 sz1 * dim);
262 rk2 = Poset->VS->F->Linear_algebra->Gauss_easy(B2, sz1 + sz2, dim);
263 if (rk2 > sz2) {
264 f_contained = FALSE;
265 }
266 else {
267 f_contained = TRUE;
268 }
269
270 FREE_int(B1);
271 FREE_int(B2);
272 }
273 else {
274 f_contained = Sorting.lint_vec_sort_and_test_if_contained(
275 set1, sz1, set2, sz2);
276 }
277 }
278 return f_contained;
279}
280
281data_structures_groups::orbit_transversal *poset_classification::get_orbit_transversal(
282 int level, int verbose_level)
283{
284 int f_v = (verbose_level >= 1);
286 int orbit_at_level;
287
288 if (f_v) {
289 cout << "poset_classification::get_orbit_transversal" << endl;
290 }
292 T->A = Poset->A;
293 T->A2 = Poset->A2;
294
295
296 T->nb_orbits = nb_orbits_at_level(level);
297
298
299 if (f_v) {
300 cout << "poset_classification::get_orbit_transversal "
301 "processing " << T->nb_orbits
302 << " orbit representatives" << endl;
303 }
304
305
307
308 for (orbit_at_level = 0;
309 orbit_at_level < T->nb_orbits;
310 orbit_at_level++) {
311
313
314 SaS = get_set_and_stabilizer(level,
315 orbit_at_level, verbose_level);
316
317
318
319 T->Reps[orbit_at_level].init_everything(
320 Poset->A, Poset->A2, SaS->data, level,
321 SaS->Strong_gens, 0 /* verbose_level */);
322
323 SaS->data = NULL;
324 SaS->Strong_gens = NULL;
325
326 FREE_OBJECT(SaS);
327
328 }
329
330
331
332 if (f_v) {
333 cout << "poset_classification::get_orbit_transversal done" << endl;
334 }
335 return T;
336}
337
338int poset_classification::test_if_stabilizer_is_trivial(
339 int level, int orbit_at_level, int verbose_level)
340{
342
343 O = get_node_ij(level, orbit_at_level);
345}
346
347data_structures_groups::set_and_stabilizer *poset_classification::get_set_and_stabilizer(
348 int level, int orbit_at_level, int verbose_level)
349{
350 int f_v = (verbose_level >= 1);
352
353 if (f_v) {
354 cout << "poset_classification::get_set_and_stabilizer" << endl;
355 }
356
358
359 SaS->init(Poset->A, Poset->A2, 0 /*verbose_level */);
360
361 SaS->allocate_data(level, 0 /* verbose_level */);
362
363 get_set_by_level(level, orbit_at_level, SaS->data);
364
366 level, orbit_at_level, 0 /* verbose_level */);
367
369
370 SaS->Stab = SaS->Strong_gens->create_sims(0 /*verbose_level*/);
371 if (f_v) {
372 cout << "poset_classification::get_set_and_stabilizer done" << endl;
373 }
374 return SaS;
375}
376
377void poset_classification::get_set_by_level(
378 int level, int node, long int *set)
379{
380 int size;
382
383 O = get_node_ij(level, node);
384 size = O->depth_of_node(this);
385 if (size != level) {
386 cout << "poset_classification::get_set_by_level "
387 "size != level" << endl;
388 exit(1);
389 }
390 //root[n].store_set_to(this, size - 1, set);
391 O->store_set_to(this, size - 1, set);
392}
393
394void poset_classification::get_set(
395 int node, long int *set, int &size)
396{
397 Poo->get_set(node, set, size);
398}
399
400void poset_classification::get_set(
401 int level, int orbit, long int *set, int &size)
402{
403 Poo->get_set(level, orbit, set, size);
404}
405
406int poset_classification::find_poset_orbit_node_for_set(
407 int len,
408 long int *set, int f_tolerant, int verbose_level)
409// finds the node that represents s_0,...,s_{len - 1}
410{
411 int f_v = (verbose_level >= 1);
412 int ret;
413
414 if (f_v) {
415 cout << "poset_classification::find_poset_orbit_node_for_set ";
416 Lint_vec_print(cout, set, len);
417 cout << endl;
418 }
419 if (f_base_case) {
420 int i, j, h;
421 if (len < Base_case->size) {
422 cout << "poset_classification::find_poset_orbit_node_for_set "
423 "len < starter_size" << endl;
424 cout << "len=" << len << endl;
425 exit(1);
426 }
427 for (i = 0; i < Base_case->size; i++) {
428 for (j = i; j < len; j++) {
429 if (set[j] == Base_case->orbit_rep[i]) {
430 if (f_v) {
431 cout << "found " << i << "-th element "
432 "of the starter which is " << Base_case->orbit_rep[i]
433 << " at position " << j << endl;
434 }
435 break;
436 }
437 }
438 if (j == len) {
439 cout << "poset_classification::find_poset_orbit_node_for_set "
440 "did not find " << i << "-th element "
441 "of the starter" << endl;
442 }
443 for (h = j; h > i; h--) {
444 set[h] = set[h - 1];
445 }
446 set[i] = Base_case->orbit_rep[i];
447 }
448 int from = Base_case->size;
449 int node = Base_case->size;
451 node, len, set, f_tolerant, verbose_level);
452 }
453 else {
454 int from = 0;
455 int node = 0;
457 node, len, set, f_tolerant, verbose_level);
458 }
459 if (ret == -1) {
460 if (f_tolerant) {
461 if (f_v) {
462 cout << "poset_classification::find_poset_orbit_node_for_set ";
463 Lint_vec_print(cout, set, len);
464 cout << " extension not found, "
465 "we are tolerant, returnning -1" << endl;
466 }
467 return -1;
468 }
469 else {
470 cout << "poset_classification::find_poset_orbit_node_for_set "
471 "we should not be here" << endl;
472 exit(1);
473 }
474 }
475 return ret;
476
477}
478
479int poset_classification::find_poset_orbit_node_for_set_basic(
480 int from,
481 int node, int len, long int *set, int f_tolerant,
482 int verbose_level)
483{
484 int i, j;
485 long int pt;
486 int f_v = (verbose_level >= 1);
487 int f_vv = (verbose_level >= 1);
488
489 if (f_vv) {
490 cout << "poset_classification::"
491 "find_poset_orbit_node_for_set_basic "
492 "looking for set ";
493 Lint_vec_print(cout, set, len);
494 cout << endl;
495 cout << "node=" << node << endl;
496 cout << "from=" << from << endl;
497 cout << "len=" << len << endl;
498 cout << "f_tolerant=" << f_tolerant << endl;
499 }
500 for (i = from; i < len; i++) {
501 pt = set[i];
502 if (f_vv) {
503 cout << "pt=" << pt << endl;
504 cout << "calling root[node].find_extension_from_point" << endl;
505 }
507 node, pt, 0 /* verbose_level */);
508
509 //j = root[node].find_extension_from_point(this, pt, FALSE);
510
511 if (j == -1) {
512 if (f_v) {
513 cout << "poset_classification::"
514 "find_poset_orbit_node_for_set_basic "
515 "depth " << i << " no extension for point "
516 << pt << " found" << endl;
517 }
518 if (f_tolerant) {
519 if (f_v) {
520 cout << "poset_classification::"
521 "find_poset_orbit_node_for_set_basic "
522 "since we are tolerant, we return -1" << endl;
523 }
524 return -1;
525 }
526 else {
527 cout << "poset_classification::"
528 "find_poset_orbit_node_for_set_basic "
529 "failure in find_extension_from_point" << endl;
530 Lint_vec_print(cout, set, len);
531 cout << endl;
532 cout << "node=" << node << endl;
533 cout << "from=" << from << endl;
534 cout << "i=" << i << endl;
535 cout << "pt=" << pt << endl;
536 Poo->get_node(node)->print_extensions(this);
537 exit(1);
538 }
539 }
540 if (Poo->get_node(node)->get_E(j)->get_pt() != pt) {
541 cout << "poset_classification::"
542 "find_poset_orbit_node_for_set_basic "
543 "root[node].E[j].pt != pt" << endl;
544 exit(1);
545 }
546 if (Poo->get_node(node)->get_E(j)->get_type() != EXTENSION_TYPE_EXTENSION &&
547 Poo->get_node(node)->get_E(j)->get_type() != EXTENSION_TYPE_PROCESSING) {
548 cout << "poset_classification::"
549 "find_poset_orbit_node_for_set_basic "
550 "root[node].get_E(j)->type != "
551 "EXTENSION_TYPE_EXTENSION" << endl;
552 cout << "root[node].get_E(j)->type="
553 << Poo->get_node(node)->get_E(j)->get_type() << " = ";
554 print_extension_type(cout, Poo->get_node(node)->get_E(j)->get_type());
555 cout << endl;
556 cout << "poset_classification::"
557 "find_poset_orbit_node_for_set_basic "
558 "looking for set ";
559 Lint_vec_print(cout, set, len);
560 cout << endl;
561 cout << "node=" << node << endl;
562 cout << "from=" << from << endl;
563 cout << "i=" << i << endl;
564 cout << "node=" << node << endl;
565 cout << "f_tolerant=" << f_tolerant << endl;
566 cout << "node=" << node << endl;
567 cout << "pt=" << pt << endl;
568 cout << "j=" << j << endl;
569 exit(1);
570 }
571 node = Poo->get_node(node)->get_E(j)->get_data();
572 if (f_v) {
573 cout << "depth " << i << " extension " << j
574 << " n e w node " << node << endl;
575 }
576 }
577 return node;
578}
579
580
581long int poset_classification::count_extension_nodes_at_level(int lvl)
582{
583 return Poo->count_extension_nodes_at_level(lvl);
584}
585
586double poset_classification::level_progress(int lvl)
587{
588 return Poo->level_progress(lvl);
589}
590
591
592
593void poset_classification::count_automorphism_group_orders(
594 int lvl, int &nb_agos,
595 ring_theory::longinteger_object *&agos, int *&multiplicities,
596 int verbose_level)
597{
598 int f_v = (verbose_level >= 1);
599 int i, l, j, c, h, f_added;
602 int *tmp_multiplicities;
604
605 l = nb_orbits_at_level(lvl);
606 if (f_v) {
607 cout << "collecting the automorphism group orders of "
608 << l << " orbits" << endl;
609 }
610 nb_agos = 0;
611 agos = NULL;
612 multiplicities = NULL;
613 for (i = 0; i < l; i++) {
614 get_stabilizer_order(lvl, i, ago);
615 f_added = FALSE;
616 for (j = 0; j < nb_agos; j++) {
617 c = D.compare_unsigned(ago, agos[j]);
618 //cout << "comparing " << ago << " with " << agos[j]
619 // << " yields " << c << endl;
620 if (c >= 0) {
621 if (c == 0) {
622 multiplicities[j]++;
623 }
624 else {
625 tmp_agos = agos;
626 tmp_multiplicities = multiplicities;
627 agos = NEW_OBJECTS(ring_theory::longinteger_object, nb_agos + 1);
628 multiplicities = NEW_int(nb_agos + 1);
629 for (h = 0; h < j; h++) {
630 tmp_agos[h].swap_with(agos[h]);
631 multiplicities[h] = tmp_multiplicities[h];
632 }
633 ago.swap_with(agos[j]);
634 multiplicities[j] = 1;
635 for (h = j; h < nb_agos; h++) {
636 tmp_agos[h].swap_with(agos[h + 1]);
637 multiplicities[h + 1] = tmp_multiplicities[h];
638 }
639 nb_agos++;
640 if (tmp_agos) {
641 FREE_OBJECTS(tmp_agos);
642 FREE_int(tmp_multiplicities);
643 }
644 }
645 f_added = TRUE;
646 break;
647 }
648 }
649 if (!f_added) {
650 // add at the end (including the case that the list is empty)
651 tmp_agos = agos;
652 tmp_multiplicities = multiplicities;
653 agos = NEW_OBJECTS(ring_theory::longinteger_object, nb_agos + 1);
654 multiplicities = NEW_int(nb_agos + 1);
655 for (h = 0; h < nb_agos; h++) {
656 tmp_agos[h].swap_with(agos[h]);
657 multiplicities[h] = tmp_multiplicities[h];
658 }
659 ago.swap_with(agos[nb_agos]);
660 multiplicities[nb_agos] = 1;
661 nb_agos++;
662 if (tmp_agos) {
663 FREE_OBJECTS(tmp_agos);
664 FREE_int(tmp_multiplicities);
665 }
666 }
667 }
668}
669
670void poset_classification::compute_and_print_automorphism_group_orders(
671 int lvl, ostream &ost)
672{
673
674 int j, nb_agos;
676 int *multiplicities;
677 int N, r, h;
680
681 count_automorphism_group_orders(lvl, nb_agos, agos,
682 multiplicities, FALSE);
683 S.create(0, __FILE__, __LINE__);
684 N = 0;
685 for (j = 0; j < nb_agos; j++) {
686 N += multiplicities[j];
687 for (h = 0; h < multiplicities[j]; h++) {
688 D.add(S, agos[j], S1);
689 S1.assign_to(S);
690 }
691 }
692 D.integral_division_by_int(S, N, Q, r);
693
694
695 ost << "(";
696 for (j = 0; j < nb_agos; j++) {
697 ost << agos[j];
698 if (multiplicities[j] == 1) {
699 }
700 else if (multiplicities[j] >= 10) {
701 ost << "^{" << multiplicities[j] << "}";
702 }
703 else {
704 ost << "^" << multiplicities[j];
705 }
706 if (j < nb_agos - 1) {
707 ost << ", ";
708 }
709 }
710 ost << ") average is " << Q << " + " << r << " / " << N << endl;
711 if (nb_agos) {
712 FREE_OBJECTS(agos);
713 FREE_int(multiplicities);
714 }
715}
716
717void poset_classification::stabilizer_order(int node, ring_theory::longinteger_object &go)
718{
719#if 0
720 if (root[node].get_nb_strong_generators()) {
721 go.create_product(Poset->A->base_len(), root[node].tl);
722 }
723 else {
724 go.create(1, __FILE__, __LINE__);
725 }
726#else
727 Poo->get_node(node)->get_stabilizer_order(this, go);
728#endif
729}
730
731
732void poset_classification::orbit_length(int orbit_at_level,
733 int level, ring_theory::longinteger_object &len)
734// uses poset_classification::go for the group order
735{
737 ring_theory::longinteger_object stab_order, quo, rem;
738
739 get_stabilizer_order(level, orbit_at_level, stab_order);
740 D.integral_division(Poset->go, stab_order, len, rem, 0);
741 if (!rem.is_zero()) {
742 cout << "poset_classification::orbit_length stabilizer order does "
743 "not divide group order" << endl;
744 exit(1);
745 }
746}
747
748void poset_classification::get_orbit_length_and_stabilizer_order(
749 int node,
750 int level, ring_theory::longinteger_object &stab_order,
752// uses poset_classification::go for the group order
753{
756
757 get_stabilizer_order(level, node, stab_order);
758 D.integral_division(Poset->go, stab_order, len, rem, 0);
759 if (!rem.is_zero()) {
760 cout << "poset_classification::orbit_length "
761 "stabilizer order "
762 "does not divide group order" << endl;
763 exit(1);
764 }
765}
766
767int poset_classification::orbit_length_as_int(
768 int orbit_at_level, int level)
769{
771
772 orbit_length(orbit_at_level, level, len);
773 return len.as_int();
774
775}
776
777
778void poset_classification::recreate_schreier_vectors_up_to_level(
779 int lvl,
780 int verbose_level)
781{
782 int f_v = (verbose_level >= 1);
783 int i;
784
785 if (f_v) {
786 cout << "poset_classification::recreate_"
787 "schreier_vectors_up_to_level "
788 "creating Schreier vectors up to "
789 "level " << lvl << endl;
790 }
791 for (i = 0; i <= lvl; i++) {
792 if (f_v) {
793 cout << "poset_classification::recreate_"
794 "schreier_vectors_up_to_level "
795 "creating Schreier vectors at "
796 "level " << i << endl;
797 }
798 recreate_schreier_vectors_at_level(i, 0 /*verbose_level*/);
799 }
800}
801
802void poset_classification::recreate_schreier_vectors_at_level(
803 int i,
804 int verbose_level)
805{
806 int f_v = (verbose_level >= 1);
807 int f_vv = FALSE;//(verbose_level >= 2);
808 int f_vvv = FALSE;//(verbose_level >= 3);
809 int f, cur, l, prev, u;
810 int f_recreate_extensions = FALSE;
811 int f_dont_keep_sv = FALSE;
812
813 if (f_v) {
814 cout << "poset_classification::recreate_schreier_vectors_at_level" << endl;
815 }
816 f = Poo->first_node_at_level(i);
817 cur = Poo->first_node_at_level(i + 1);
818 l = cur - f;
819
820 if (f_vv) {
821 cout << "creating Schreier vectors at depth " << i
822 << " for " << l << " orbits" << endl;
823 }
824 if (f_vv) {
825 cout << "poset_classification::recreate_schreier_vectors_at_level "
826 "Testing if a schreier vector file exists" << endl;
827 }
828 if (test_sv_level_file_binary(i, problem_label_with_path)) {
829
830 if (f_vv) {
831 cout << "poset_classification::recreate_schreier_vectors_at_level "
832 "Yes, a schreier vector file exists. "
833 "We will read this file" << endl;
834 }
835
836 read_sv_level_file_binary(i, problem_label_with_path, FALSE, 0, 0,
837 f_recreate_extensions, f_dont_keep_sv,
838 verbose_level);
839 if (f_vv) {
840 cout << "read Schreier vectors at depth " << i
841 << " from file" << endl;
842 }
843 return;
844 }
845
846
847 if (f_vv) {
848 cout << "poset_classification::recreate_schreier_vectors_at_level "
849 "No, a schreier vector file does not exists. "
850 "We will create such a file now" << endl;
851 }
852
853
854
855 for (u = 0; u < l; u++) {
856
857 prev = f + u;
858
859 if (f_vv && !f_vvv) {
860 cout << ".";
861 if (((u + 1) % 50) == 0) {
862 cout << "; " << u + 1 << " / " << l << endl;
863 }
864 if (((u + 1) % 1000) == 0) {
865 cout << " " << u + 1 << endl;
866 }
867 }
868 else if (f_vvv) {
869 cout << "poset_classification::recreate_"
870 "schreier_vectors_at_level "
871 << i << " node " << u << " / " << l << endl;
872 }
873
874 Poo->get_node(prev)->compute_schreier_vector(this, i,
875 0 /*verbose_level - 1*/);
876 }
877 write_sv_level_file_binary(i, problem_label_with_path, FALSE, 0, 0, verbose_level);
878 if (f_vv) {
879 cout << "poset_classification::recreate_schreier_vectors_at_level "
880 "Written a file with Schreier "
881 "vectors at depth " << i << endl;
882 }
883 if (f_vv) {
884 cout << endl;
885 }
886 if (f_v) {
887 cout << "poset_classification::recreate_schreier_vectors_at_level done" << endl;
888 }
889}
890
891
892void poset_classification::find_node_by_stabilizer_order(
893 int level, int order, int verbose_level)
894{
895 int f_v = (verbose_level >= 1);
896 int nb_nodes, node, i, j, elt_order;
898 long int set[300];
899
900 if (f_v) {
901 cout << "poset_classification::find_node_by_stabilizer_order" << endl;
902 }
903 nb_nodes = nb_orbits_at_level(level);
904 for (i = 0; i < nb_nodes; i++) {
905 node = Poo->first_node_at_level(level) + i;
906
907 Poo->get_node(node)->get_stabilizer_order(this, ago);
908
909 if (ago.as_int() == order) {
910 cout << "found a node whose automorphism group is order "
911 << order << endl;
912 cout << "the node is # " << i << " at level "
913 << level << endl;
914 get_set(Poo->first_node_at_level(level) + i,
915 set, level);
916 Lint_vec_print(cout, set, level);
917 cout << endl;
918
919 groups::strong_generators *Strong_gens;
920
921 get_stabilizer_generators(Strong_gens,
922 level, i, 0 /* verbose_level */);
923
924 for (j = 0; j < Strong_gens->gens->len; j++) {
925 elt_order = Poset->A->element_order(Strong_gens->gens->ith(j));
926 cout << "poset_classification " << j << " of order "
927 << elt_order << ":" << endl;
928 if (order == elt_order) {
929 cout << "CYCLIC" << endl;
930 }
931 Poset->A->element_print(
932 Strong_gens->gens->ith(j), cout);
934 Strong_gens->gens->ith(j), cout);
935 }
936 FREE_OBJECT(Strong_gens);
937 }
938 }
939}
940
941void poset_classification::get_all_stabilizer_orders_at_level(int level, long int *&Ago, int &nb)
942{
943 int i;
944
945 nb = nb_orbits_at_level(level);
946 Ago = NEW_lint(nb);
947 for (i = 0; i < nb; i++) {
948 Ago[i] = get_stabilizer_order_lint(level, i);
949 }
950}
951
952void poset_classification::get_stabilizer_order(int level,
953 int orbit_at_level, ring_theory::longinteger_object &go)
954{
956
957 O = get_node_ij(level, orbit_at_level);
958
959
960#if 0
961 if (O->nb_strong_generators == 0) {
962 go.create(1, __FILE__, __LINE__);
963 }
964 else {
965 longinteger_domain D;
966
967 D.multiply_up(go, O->tl, Poset->A->base_len(), 0 /* verbose_level */);
968 }
969#else
970 O->get_stabilizer_order(this, go);
971#endif
972}
973
974long int poset_classification::get_stabilizer_order_lint(int level,
975 int orbit_at_level)
976{
978
979 O = get_node_ij(level, orbit_at_level);
980 return O->get_stabilizer_order_lint(this);
981}
982
983void poset_classification::get_stabilizer_group(
985 int level, int orbit_at_level,
986 int verbose_level)
987{
988 int f_v = (verbose_level >= 1);
989 //int f_vv = (verbose_level >= 2);
991 //int node;
992
993 if (f_v) {
994 cout << "poset_classification::get_stabilizer_group level=" << level
995 << " orbit_at_level=" << orbit_at_level << endl;
996 }
997
998 O = get_node_ij(level, orbit_at_level);
999
1000
1001#if 0
1002 G = NEW_OBJECT(group);
1003 //node = first_poset_orbit_node_at_level[level] + orbit_at_level;
1004 //O = root + node;
1005
1006 G->init(Poset->A, verbose_level - 2);
1007 if (f_vv) {
1008 cout << "poset_classification::"
1009 "get_stabilizer_group before "
1010 "G->init_strong_generators_by_hdl" << endl;
1011 }
1012 G->init_strong_generators_by_hdl(O->nb_strong_generators,
1013 O->hdl_strong_generators, O->tl, FALSE);
1014 G->schreier_sims(0);
1015#else
1017
1019 O->get_stabilizer(
1020 this,
1021 *G, go,
1022 verbose_level - 2);
1023#endif
1024
1025 if (f_v) {
1026 cout << "poset_classification::get_stabilizer_group level=" << level
1027 << " orbit_at_level=" << orbit_at_level
1028 << " done" << endl;
1029 }
1030}
1031
1032void poset_classification::get_stabilizer_generators_cleaned_up(
1034 int level, int orbit_at_level, int verbose_level)
1035{
1036 int f_v = (verbose_level >= 1);
1037
1038 if (f_v) {
1039 cout << "poset_classification::"
1040 "get_stabilizer_generators_cleaned_up level=" << level
1041 << " orbit_at_level=" << orbit_at_level << endl;
1042 }
1044
1046 level, orbit_at_level, verbose_level - 1);
1047
1049
1050 gens->init_from_sims(G->S, 0 /* verbose_level */);
1051 FREE_OBJECT(G);
1052 if (f_v) {
1053 cout << "poset_classification::"
1054 "get_stabilizer_generators_cleaned_up level=" << level
1055 << " orbit_at_level=" << orbit_at_level
1056 << " done" << endl;
1057 }
1058
1059}
1060
1061void poset_classification::get_stabilizer_generators(
1063 int level, int orbit_at_level, int verbose_level)
1064{
1065 int f_v = (verbose_level >= 1);
1066
1067 if (f_v) {
1068 cout << "poset_classification::get_stabilizer_generators level=" << level
1069 << " orbit_at_level=" << orbit_at_level << endl;
1070 }
1071
1073 //int node;
1074
1075 //node = first_poset_orbit_node_at_level[level] + orbit_at_level;
1076 //O = root + node;
1077 O = get_node_ij(level, orbit_at_level);
1078
1079 O->get_stabilizer_generators(this, gens, verbose_level);
1080
1081 if (f_v) {
1082 cout << "poset_classification::get_stabilizer_generators level=" << level
1083 << " orbit_at_level=" << orbit_at_level
1084 << " done" << endl;
1085 }
1086}
1087
1088
1089
1090void poset_classification::orbit_element_unrank(
1091 int depth,
1092 int orbit_idx, long int rank, long int *set,
1093 int verbose_level)
1094{
1095 int f_v = (verbose_level >= 1);
1096 int *Elt1;
1097 int *Elt2;
1098 long int *the_set;
1100
1101
1102 if (f_v) {
1103 cout << "poset_classification::orbit_element_unrank "
1104 "depth=" << depth
1105 << " orbit_idx=" << orbit_idx
1106 << " rank=" << rank << endl;
1107 }
1108
1109 Elt1 = NEW_int(Poset->A->elt_size_in_int);
1110 Elt2 = NEW_int(Poset->A->elt_size_in_int);
1111 the_set = NEW_lint(depth);
1112
1113 //O = &root[first_poset_orbit_node_at_level[depth] + orbit_idx];
1114 O = get_node_ij(depth, orbit_idx);
1115 coset_unrank(depth, orbit_idx, rank, Elt1, 0 /*verbose_level*/);
1116
1117 Poset->A->element_invert(Elt1, Elt2, 0);
1118 O->store_set_to(this, depth - 1, the_set);
1119 Poset->A2->map_a_set(the_set, set, depth, Elt2, 0 /*verbose_level*/);
1120
1121 FREE_lint(the_set);
1122 FREE_int(Elt1);
1123 FREE_int(Elt2);
1124 if (f_v) {
1125 cout << "poset_classification::orbit_element_unrank ";
1126 Lint_vec_print(cout, set, depth);
1127 cout << endl;
1128 }
1129}
1130
1131void poset_classification::orbit_element_rank(
1132 int depth,
1133 int &orbit_idx, long int &rank, long int *set,
1134 int verbose_level)
1135{
1136 int f_v = (verbose_level >= 1);
1137 int f_vv = (verbose_level >= 2);
1138 int *Elt1;
1139 long int *the_set;
1140 long int *canonical_set;
1141 int i;
1142
1143
1144 if (f_v) {
1145 cout << "poset_classification::orbit_element_rank "
1146 "depth=" << depth << " ";
1147 Lint_vec_print(cout, set, depth);
1148 cout << endl;
1149 }
1150
1151 Elt1 = NEW_int(Poset->A->elt_size_in_int);
1152 the_set = NEW_lint(depth);
1153 canonical_set = NEW_lint(depth);
1154 for (i = 0; i < depth; i++) {
1155 the_set[i] = set[i];
1156 }
1157
1158 orbit_idx = trace_set(the_set, depth, depth,
1159 canonical_set, Elt1,
1160 verbose_level - 3);
1161
1162 // now Elt1 is the transporter element that moves
1163 // the given set to the orbit representative
1164
1165 if (f_vv) {
1166 cout << "poset_classification::orbit_element_rank "
1167 "after trace_set, "
1168 "orbit_idx = " << orbit_idx << endl;
1169 cout << "transporter:" << endl;
1170 Poset->A->element_print_quick(Elt1, cout);
1171 cout << "as permutation:" << endl;
1172 Poset->A2->element_print_as_permutation(Elt1, cout);
1173 }
1174 if (f_v) {
1175 cout << "calling coset_rank" << endl;
1176 }
1177 rank = coset_rank(depth, orbit_idx, Elt1, verbose_level);
1178 if (f_v) {
1179 cout << "after coset_rank, rank=" << rank << endl;
1180 }
1181
1182 FREE_int(Elt1);
1183 FREE_lint(the_set);
1184 FREE_lint(canonical_set);
1185 if (f_v) {
1186 cout << "poset_classification::orbit_element_rank "
1187 "orbit_idx="
1188 << orbit_idx << " rank=" << rank << endl;
1189 }
1190}
1191
1192void poset_classification::coset_unrank(
1193 int depth, int orbit_idx,
1194 long int rank, int *Elt, int verbose_level)
1195{
1196 int f_v = (verbose_level >= 1);
1197 long int *the_set;
1199 int *Elt_gk;
1200 ring_theory::longinteger_object G_order, U_order;
1201 poset_orbit_node *O1, *O2;
1202
1203 if (f_v) {
1204 cout << "poset_classification::coset_unrank "
1205 "depth=" << depth
1206 << " orbit_idx=" << orbit_idx << endl;
1207 cout << "action A:" << endl;
1208 Poset->A->print_info();
1209 cout << "action A2:" << endl;
1210 Poset->A2->print_info();
1211 }
1212
1213 //O1 = &root[0];
1214 //O2 = &root[first_poset_orbit_node_at_level[depth] + orbit_idx];
1215 O1 = get_node_ij(0, 0);
1216 O2 = get_node_ij(depth, orbit_idx);
1217
1218
1219
1222 the_set = NEW_lint(depth);
1223 Elt_gk = NEW_int(Poset->A->elt_size_in_int);
1224
1225 O2->store_set_to(this, depth - 1, the_set);
1226
1227 if (f_v) {
1228 cout << "the set representing orbit " << orbit_idx
1229 << " at level " << depth << " is ";
1230 Lint_vec_print(cout, the_set, depth);
1231 cout << endl;
1232 }
1233
1234 O1->get_stabilizer(this, *G1, G_order, verbose_level - 2);
1235 O2->get_stabilizer(this, *G2, U_order, verbose_level - 2);
1236
1237
1238 Poset->A->coset_unrank(G1->S, G2->S, rank, Elt, verbose_level);
1239
1240 FREE_OBJECT(G1);
1241 FREE_OBJECT(G2);
1242 FREE_lint(the_set);
1243 FREE_int(Elt_gk);
1244
1245}
1246
1247long int poset_classification::coset_rank(
1248 int depth, int orbit_idx,
1249 int *Elt, int verbose_level)
1250{
1251 int f_v = (verbose_level >= 1);
1252 long int rank;
1253 long int *the_set;
1255 int *Elt_gk;
1256 ring_theory::longinteger_object G_order, U_order;
1257 poset_orbit_node *O1, *O2;
1258
1259 if (f_v) {
1260 cout << "poset_classification::coset_rank "
1261 "depth=" << depth
1262 << " orbit_idx=" << orbit_idx << endl;
1263 cout << "action A:" << endl;
1264 Poset->A->print_info();
1265 cout << "action A2:" << endl;
1266 Poset->A2->print_info();
1267 }
1268
1269 //O1 = &root[0];
1270 //O2 = &root[first_poset_orbit_node_at_level[depth] + orbit_idx];
1271 O1 = get_node_ij(0, 0);
1272 O2 = get_node_ij(depth, orbit_idx);
1273
1274
1275
1278 the_set = NEW_lint(depth);
1279 Elt_gk = NEW_int(Poset->A->elt_size_in_int);
1280
1281 O2->store_set_to(this, depth - 1, the_set);
1282
1283 if (f_v) {
1284 cout << "the set representing orbit " << orbit_idx
1285 << " at level " << depth << " is ";
1286 Lint_vec_print(cout, the_set, depth);
1287 cout << endl;
1288 }
1289
1290 O1->get_stabilizer(this, *G1, G_order, verbose_level - 2);
1291 O2->get_stabilizer(this, *G2, U_order, verbose_level - 2);
1292
1293
1294 rank = Poset->A->coset_rank(G1->S, G2->S, Elt, verbose_level);
1295
1296 FREE_OBJECT(G1);
1297 FREE_OBJECT(G2);
1298 FREE_lint(the_set);
1299 FREE_int(Elt_gk);
1300
1301 return rank;
1302}
1303
1304void poset_classification::list_all_orbits_at_level(
1305 int depth,
1306 int f_has_print_function,
1307 void (*print_function)(ostream &ost,
1308 int len, long int *S, void *data),
1309 void *print_function_data,
1310 int f_show_orbit_decomposition, int f_show_stab,
1311 int f_save_stab, int f_show_whole_orbit)
1312{
1313 int l, i;
1314
1315 l = nb_orbits_at_level(depth);
1316
1317 cout << "poset_classification::list_all_orbits_at_level "
1318 "listing all orbits "
1319 "at depth " << depth << ":" << endl;
1320 for (i = 0; i < l; i++) {
1321 cout << "poset_classification::list_all_orbits_at_level "
1322 "listing orbit "
1323 << i << " / " << l << endl;
1324 list_whole_orbit(depth, i,
1325 f_has_print_function, print_function, print_function_data,
1326 f_show_orbit_decomposition, f_show_stab,
1327 f_save_stab, f_show_whole_orbit);
1328 }
1329}
1330
1331void poset_classification::compute_integer_property_of_selected_list_of_orbits(
1332 int depth,
1333 int nb_orbits, int *Orbit_idx,
1334 int (*compute_function)(int len, long int *S, void *data),
1335 void *compute_function_data,
1336 int *&Data)
1337{
1338 int l, i, j, d;
1339 long int *set;
1340
1341 set = NEW_lint(depth);
1342 l = nb_orbits_at_level(depth);
1343
1344 Data = NEW_int(nb_orbits);
1345
1346 cout << "computing integer property for a set of "
1347 << nb_orbits << " orbits at depth " << depth << ":" << endl;
1348 for (j = 0; j < nb_orbits; j++) {
1349 i = Orbit_idx[j];
1350 if (i >= l) {
1351 cout << "orbit idx is out of range" << endl;
1352 exit(1);
1353 }
1354 cout << "Orbit " << j << " / " << nb_orbits
1355 << " which is no " << i << ":" << endl;
1356
1357 get_set_by_level(depth, i, set);
1358
1359 d = (*compute_function)(depth, set, compute_function_data);
1360 Data[j] = d;
1361 }
1362
1363 FREE_lint(set);
1364}
1365
1366void poset_classification::list_selected_set_of_orbits_at_level(
1367 int depth,
1368 int nb_orbits, int *Orbit_idx,
1369 int f_has_print_function,
1370 void (*print_function)(ostream &ost,
1371 int len, long int *S, void *data),
1372 void *print_function_data,
1373 int f_show_orbit_decomposition, int f_show_stab,
1374 int f_save_stab, int f_show_whole_orbit)
1375{
1376 int l, i, j;
1377
1378 l = nb_orbits_at_level(depth);
1379
1380 cout << "listing a set of " << nb_orbits
1381 << " orbits at depth " << depth << ":" << endl;
1382 for (j = 0; j < nb_orbits; j++) {
1383 i = Orbit_idx[j];
1384 if (i >= l) {
1385 cout << "orbit idx is out of range" << endl;
1386 exit(1);
1387 }
1388 cout << "Orbit " << j << " / " << nb_orbits
1389 << " which is no " << i << ":" << endl;
1390 list_whole_orbit(depth, i,
1391 f_has_print_function, print_function, print_function_data,
1392 f_show_orbit_decomposition, f_show_stab,
1393 f_save_stab, f_show_whole_orbit);
1394 }
1395}
1396
1397void poset_classification::test_property(int depth,
1398 int (*test_property_function)(int len, long int *S, void *data),
1399 void *test_property_data,
1400 int &nb, int *&Orbit_idx)
1401{
1402 int N, i;
1403 long int *set;
1404
1405 set = NEW_lint(depth);
1406 N = nb_orbits_at_level(depth);
1407 Orbit_idx = NEW_int(N);
1408 nb = 0;
1409 for (i = 0; i < N; i++) {
1410 get_set_by_level(depth, i, set);
1411 if ((*test_property_function)(depth, set, test_property_data)) {
1412 Orbit_idx[nb++] = i;
1413 }
1414 }
1415 FREE_lint(set);
1416}
1417
1418#if 0
1419void poset_classification::print_schreier_vectors_at_depth(
1420 int depth, int verbose_level)
1421{
1422 int i, l;
1423
1424 l = nb_orbits_at_level(depth);
1425 for (i = 0; i < l; i++) {
1426 print_schreier_vector(depth, i, verbose_level);
1427 }
1428}
1429
1430void poset_classification::print_schreier_vector(int depth,
1431 int orbit_idx, int verbose_level)
1432{
1433 int *set;
1434 int len;
1435 //strong_generators *Strong_gens;
1436 longinteger_object Len, L, go;
1437 //longinteger_domain D;
1438
1439 set = NEW_int(depth);
1440
1441 orbit_length(orbit_idx, depth, Len);
1442 len = orbit_length_as_int(orbit_idx, depth);
1443 L.create(len);
1444
1445 get_stabilizer_order(depth, orbit_idx, go);
1446
1447
1448 cout << "orbit " << orbit_idx << " / " << nb_orbits_at_level(depth)
1449 << " (=node " << first_poset_orbit_node_at_level[depth] + orbit_idx
1450 << ") at depth " << depth << " has length " << Len << " : ";
1451
1452 get_set_by_level(depth, orbit_idx, set);
1453 int_set_print(cout, set, depth);
1454 cout << "_" << go << endl;
1455
1456 cout << "schreier tree:" << endl;
1457
1458 int *sv;
1459
1460
1461 sv = root[first_poset_orbit_node_at_level[depth] + orbit_idx].sv;
1462
1463 if (sv == NULL) {
1464 cout << "No schreier vector available" << endl;
1465 }
1466
1467 schreier_vector_print_tree(sv, 0 /*verbose_level */);
1468}
1469#endif
1470
1471void poset_classification::list_whole_orbit(
1472 int depth, int orbit_idx,
1473 int f_has_print_function,
1474 void (*print_function)(ostream &ost,
1475 int len, long int *S, void *data),
1476 void *print_function_data,
1477 int f_show_orbit_decomposition, int f_show_stab,
1478 int f_save_stab, int f_show_whole_orbit)
1479{
1480 long int *set;
1481 int rank, len;
1482 groups::strong_generators *Strong_gens;
1485
1486 set = NEW_lint(depth);
1487
1488 orbit_length(orbit_idx, depth, Len);
1489 len = orbit_length_as_int(orbit_idx, depth);
1490 L.create(len, __FILE__, __LINE__);
1491
1492 get_stabilizer_order(depth, orbit_idx, go);
1493
1494
1495 cout << "poset_classification::list_whole_orbit "
1496 "depth " << depth
1497 << " orbit " << orbit_idx
1498 << " / " << nb_orbits_at_level(depth) << " (=node "
1499 << Poo->first_node_at_level(depth) + orbit_idx
1500 << ") at depth " << depth << " has length " << Len << " : ";
1501
1502 get_set_by_level(depth, orbit_idx, set);
1503 Lint_vec_print(cout, set, depth);
1504 cout << "_" << go << " ";
1505
1506 //print_lex_rank(set, depth);
1507 cout << endl;
1508
1509 if (f_has_print_function) {
1510 (*print_function)(cout, depth, set, print_function_data);
1511 }
1512
1513 get_stabilizer_generators(Strong_gens, depth, orbit_idx, 0 /* verbose_level*/);
1514
1515
1516 if (f_show_orbit_decomposition) {
1517 if (Poset->f_subset_lattice) {
1518 cout << "poset_classification::list_whole_orbit "
1519 "orbits on the set:" << endl;
1520
1521 // ToDo:
1522 //Strong_gens->compute_and_print_orbits_on_a_given_set(
1523 // Poset->A2, set, depth, 0 /* verbose_level*/);
1524 }
1525 else {
1526 cout << "subspace_lattice not yet implemented" << endl;
1527 }
1528
1529 cout << "poset_classification::list_whole_orbit "
1530 "orbits in the original "
1531 "action on the whole space:" << endl;
1532 Strong_gens->compute_and_print_orbits(Poset->A,
1533 0 /* verbose_level*/);
1534 }
1535
1536 if (f_show_stab) {
1537 cout << "The stabilizer is generated by:" << endl;
1538 Strong_gens->print_generators(cout);
1539 }
1540
1541 if (f_save_stab) {
1542 string fname;
1543 char str[1000];
1544
1545 fname.assign(problem_label_with_path);
1546 sprintf(str, "_stab_%d_%d.bin", depth, orbit_idx);
1547 fname.append(str);
1548
1549 cout << "saving stabilizer poset_classifications "
1550 "to file " << fname << endl;
1551 Strong_gens->write_file(fname, Control->verbose_level);
1552 }
1553
1554
1555 if (f_show_whole_orbit) {
1556 int max_len;
1557 if (len > 1000) {
1558 max_len = 10;
1559 }
1560 else {
1561 max_len = len;
1562 }
1563
1564 if (D.compare(L, Len) != 0) {
1565 cout << "orbit is too long to show" << endl;
1566 }
1567 else {
1568 for (rank = 0; rank < max_len; rank++) {
1569 orbit_element_unrank(depth, orbit_idx,
1570 rank, set, 0 /* verbose_level */);
1571 cout << setw(5) << rank << " : ";
1573 cout << endl;
1574 }
1575 if (max_len < len) {
1576 cout << "output truncated" << endl;
1577 }
1578 }
1579 }
1580
1581 FREE_lint(set);
1582 FREE_OBJECT(Strong_gens);
1583 cout << "poset_classification::list_whole_orbit done" << endl;
1584}
1585
1586void poset_classification::get_whole_orbit(
1587 int depth, int orbit_idx,
1588 long int *&Orbit, int &orbit_length, int verbose_level)
1589{
1590 int f_v = (verbose_level >= 1);
1591 long int rank;
1594
1595 if (f_v) {
1596 cout << "poset_classification::get_whole_orbit" << endl;
1597 }
1598 poset_classification::orbit_length(orbit_idx, depth, Len);
1599 orbit_length = orbit_length_as_int(orbit_idx, depth);
1600 L.create(orbit_length, __FILE__, __LINE__);
1601
1602 if (f_v) {
1603 cout << "poset_classification::get_whole_orbit orbit_length=" << orbit_length << endl;
1604 }
1605 if (D.compare(L, Len) != 0) {
1606 cout << "poset_classification::get_whole_orbit "
1607 "orbit is too long" << endl;
1608 exit(1);
1609 }
1610
1611 Orbit = NEW_lint(orbit_length * depth);
1612 for (rank = 0; rank < orbit_length; rank++) {
1613 if (f_v) {
1614 cout << "poset_classification::get_whole_orbit element " << rank << " / " << orbit_length << endl;
1615 }
1616 orbit_element_unrank(depth, orbit_idx,
1617 rank,
1618 Orbit + rank * depth,
1619 0 /* verbose_level */);
1620 }
1621 if (f_v) {
1622 cout << "poset_classification::get_whole_orbit done" << endl;
1623 }
1624}
1625
1626void poset_classification::map_to_canonical_k_subset(
1627 long int *the_set, int set_size,
1628 int subset_size, int subset_rk,
1629 long int *reduced_set, int *transporter, int &local_idx,
1630 int verbose_level)
1631// fills reduced_set[set_size - subset_size], transporter and local_idx
1632// local_idx is the index of the orbit that the subset belongs to
1633// (in the list of orbit of subsets of size subset_size)
1634{
1635 int f_v = (verbose_level >= 1);
1636 //int f_vv = (verbose_level >= 2);
1637
1638 if (f_v) {
1639 cout << "poset_classification::map_to_canonical_k_subset" << endl;
1640 }
1641 int *our_set;
1642 long int *subset;
1643 long int *canonical_subset;
1644 int *Elt1;
1645 int i; //, j, k;
1646 int reduced_set_size;
1648
1649 our_set = NEW_int(set_size);
1650 subset = NEW_lint(set_size);
1651 canonical_subset = NEW_lint(set_size);
1652 Elt1 = NEW_int(Poset->A->elt_size_in_int);
1653 reduced_set_size = set_size - subset_size;
1654
1655 // unrank the k-subset and its complement to our_set[set_size]:
1656 Combi.unrank_k_subset_and_complement(subset_rk,
1657 our_set, set_size, subset_size);
1658 if (f_v) {
1659 cout << "poset_classification::map_to_canonical_k_subset our_set=";
1660 Int_vec_print(cout, our_set, set_size);
1661 cout << endl;
1662 }
1663#if 0
1664 Combi.unrank_k_subset(subset_rk, our_set, set_size, subset_size);
1665 j = 0;
1666 k = 0;
1667 for (i = 0; i < set_size; i++) {
1668 if (j < subset_size && our_set[j] == i) {
1669 j++;
1670 continue;
1671 }
1672 our_set[subset_size + k] = i;
1673 k++;
1674 }
1675#endif
1676 for (i = 0; i < set_size; i++) {
1677 subset[i] = the_set[our_set[i]];
1678 set[0][i] = subset[i];
1679 }
1680 for (i = 0; i < sz; i++) {
1681 set[0][i] = subset[i];
1682 }
1683 if (f_v) {
1684 cout << "poset_classification::map_to_canonical_k_subset subset=";
1685 Lint_vec_print(cout, subset, set_size);
1686 cout << endl;
1687 }
1688
1689 Poset->A->element_one(poset_classification::transporter->ith(0), FALSE);
1690
1691
1692 // trace the subset:
1693
1694 if (f_v) {
1695 cout << "poset_classification::map_to_canonical_k_subset "
1696 "before trace_set" << endl;
1697 }
1698
1699 if (set_size > max_set_size) {
1700 cout << "poset_classification::map_to_canonical_k_subset set_size > max_set_size" << endl;
1701 cout << "poset_classification::map_to_canonical_k_subset set_size = " << set_size << endl;
1702 cout << "poset_classification::map_to_canonical_k_subset max_set_size = " << max_set_size << endl;
1703 exit(1);
1704 }
1705
1706 local_idx = trace_set(
1707 subset, set_size, subset_size,
1708 canonical_subset, Elt1,
1709 verbose_level);
1710 if (f_v) {
1711 cout << "poset_classification::"
1712 "map_to_canonical_k_subset "
1713 "after trace_set local_idx=" << local_idx << endl;
1714 cout << "poset_classification::map_to_canonical_k_subset canonical_subset=";
1715 Lint_vec_print(cout, canonical_subset, set_size);
1716 cout << endl;
1717 }
1718
1719
1720 if (f_v) {
1721 cout << "the transporter is" << endl;
1722 Poset->A->element_print(Elt1, cout);
1723 cout << endl;
1724 }
1725 Poset->A->element_move(Elt1, transporter, FALSE);
1726
1727 for (i = 0; i < reduced_set_size; i++) {
1728 reduced_set[i] = canonical_subset[subset_size + i];
1729 }
1730 if (f_v) {
1731 cout << "poset_classification::"
1732 "map_to_canonical_k_subset reduced set = ";
1733 Lint_vec_print(cout, reduced_set, reduced_set_size);
1734 cout << endl;
1735 }
1736 FREE_int(Elt1);
1737 FREE_int(our_set);
1738 FREE_lint(subset);
1739 FREE_lint(canonical_subset);
1740
1741 if (f_v) {
1742 cout << "poset_classification::"
1743 "map_to_canonical_k_subset done" << endl;
1744 }
1745}
1746
1747void poset_classification::get_representative_of_subset_orbit(
1748 long int *set, int size, int local_orbit_no,
1749 groups::strong_generators *&Strong_gens,
1750 int verbose_level)
1751{
1752 int f_v = (verbose_level >= 1);
1753 int f_vv = (verbose_level >= 2);
1754 int fst, node, sz;
1756
1757 if (f_v) {
1758 cout << "poset_classification::get_representative_of_subset_orbit "
1759 "verbose_level=" << verbose_level << endl;
1760 }
1761 fst = Poo->first_node_at_level(size);
1762 node = fst + local_orbit_no;
1763 if (f_vv) {
1764 cout << "poset_classification::get_representative_"
1765 "of_subset_orbit "
1766 "before get_set" << endl;
1767 }
1768 get_set(node, set, sz);
1769 if (sz != size) {
1770 cout << "get_representative_of_subset_orbit: "
1771 "sz != size" << endl;
1772 exit(1);
1773 }
1774 //O = root + node;
1775 O = get_node_ij(size, local_orbit_no);
1776 if (f_vv) {
1777 cout << "poset_classification::get_representative_"
1778 "of_subset_orbit "
1779 "before get_stabilizer_poset_classifications" << endl;
1780 }
1781 O->get_stabilizer_generators(this, Strong_gens, 0);
1782 if (f_v) {
1783 cout << "poset_classification::get_representative_of_subset_orbit done" << endl;
1784 }
1785}
1786
1787void poset_classification::find_interesting_k_subsets(
1788 long int *the_set, int n, int k,
1789 int *&interesting_sets, int &nb_interesting_sets,
1790 int &orbit_idx,
1791 int verbose_level)
1792{
1793 int f_v = (verbose_level >= 1);
1795 int j, t, f, l, l_min, t_min = 0;
1796
1797 if (f_v) {
1798 cout << "poset_classification::find_interesting_k_subsets "
1799 "n = " << n << " k = " << k << endl;
1800 }
1801
1802
1803 classify_k_subsets(the_set, n, k, C, verbose_level);
1804
1805
1806 if (f_v) {
1807 C->print_naked(FALSE);
1808 cout << endl;
1809 }
1810
1811 l_min = INT_MAX;
1812 f = 0;
1813 for (t = 0; t < C->nb_types; t++) {
1814 f = C->type_first[t];
1815 l = C->type_len[t];
1816 if (l < l_min) {
1817 l_min = l;
1818 t_min = t;
1819 }
1820 }
1821 interesting_sets = NEW_int(l_min);
1822 nb_interesting_sets = l_min;
1823 for (j = 0; j < l_min; j++) {
1824 interesting_sets[j] = C->sorting_perm_inv[f + j];
1825 }
1826 orbit_idx = C->data_sorted[f];
1827 if (f_v) {
1828 cout << "poset_classification::find_interesting_k_subsets "
1829 "l_min = " << l_min << " t_min = " << t_min
1830 << " orbit_idx = " << orbit_idx << endl;
1831 }
1832 if (f_v) {
1833 cout << "interesting set of size "
1834 << nb_interesting_sets << " : ";
1835 Int_vec_print(cout, interesting_sets, nb_interesting_sets);
1836 cout << endl;
1837 }
1838
1839 FREE_OBJECT(C);
1840
1841 if (f_v) {
1842 cout << "poset_classification::find_interesting_k_subsets "
1843 "n = " << n << " k = " << k << " done" << endl;
1844 }
1845}
1846
1847void poset_classification::classify_k_subsets(
1848 long int *the_set, int n, int k,
1849 data_structures::tally *&C, int verbose_level)
1850{
1851 int f_v = (verbose_level >= 1);
1852 //int f_vv = (verbose_level >= 2);
1853 int nCk;
1854 int *isotype;
1855
1856 if (f_v) {
1857 cout << "poset_classification::classify_k_subsets "
1858 "n = " << n << " k = " << k << endl;
1859 }
1860
1861 trace_all_k_subsets(the_set, n, k, nCk, isotype, verbose_level);
1862
1864
1865 C->init(isotype, nCk, FALSE, 0);
1866
1867 if (f_v) {
1868 cout << "poset_classification::classify_k_subsets "
1869 "n = " << n << " k = " << k << " done" << endl;
1870 }
1871}
1872
1873void poset_classification::trace_all_k_subsets_and_compute_frequencies(
1874 long int *the_set,
1875 int n, int k, int &nCk, int *&isotype, int *&orbit_frequencies, int &nb_orbits,
1876 int verbose_level)
1877{
1878 int f_v = (verbose_level >= 1);
1879 int i, a;
1880
1881
1882 if (f_v) {
1883 cout << "poset_classification::trace_all_k_subsets_and_compute_frequencies "
1884 "n = " << n << " k = " << k << " nCk=" << nCk << endl;
1885 }
1886
1888 the_set,
1889 n, k, nCk, isotype,
1890 verbose_level);
1891
1892 nb_orbits = nb_orbits_at_level(k);
1893 orbit_frequencies = NEW_int(nb_orbits);
1894 Int_vec_zero(orbit_frequencies, nb_orbits);
1895
1896 for (i = 0; i < nCk; i++) {
1897 a = isotype[i];
1898 orbit_frequencies[a]++;
1899 }
1900
1901 if (f_v) {
1902 cout << "poset_classification::trace_all_k_subsets_and_compute_frequencies done" << endl;
1903 }
1904}
1905
1906void poset_classification::trace_all_k_subsets(
1907 long int *the_set,
1908 int n, int k, int &nCk, int *&isotype,
1909 int verbose_level)
1910{
1911 int f_v = (verbose_level >= 1);
1912 //int f_vv = FALSE; //(verbose_level >= 2);
1913 int *index_set;
1914 long int *subset;
1915 long int *canonical_subset;
1916 int *Elt;
1917 long int subset_rk, local_idx, i;
1918 //int f_implicit_fusion = TRUE;
1920
1921 nCk = Combi.int_n_choose_k(n, k);
1922 if (f_v) {
1923 cout << "poset_classification::trace_all_k_subsets "
1924 "n = " << n << " k = " << k
1925 << " nCk = " << nCk << endl;
1926 }
1927
1928 Elt = NEW_int(Poset->A->elt_size_in_int);
1929
1930 index_set = NEW_int(k);
1931 subset = NEW_lint(k);
1932 canonical_subset = NEW_lint(k);
1933 isotype = NEW_int(nCk);
1934
1935 Int_vec_zero(isotype, nCk);
1936
1937 Combi.first_k_subset(index_set, n, k);
1938 subset_rk = 0;
1939
1940 while (TRUE) {
1941 if (TRUE && ((subset_rk % 10000) == 0)) {
1942 cout << "poset_classification::trace_all_k_subsets "
1943 "k=" << k
1944 << " testing set " << subset_rk << " / " << nCk
1945 << " = " << 100. * (double) subset_rk /
1946 (double) nCk << " % : ";
1947 Int_vec_print(cout, index_set, k);
1948 cout << endl;
1949 }
1950 for (i = 0; i < k; i++) {
1951 subset[i] = the_set[index_set[i]];
1952 }
1953 Lint_vec_copy(subset, set[0], k);
1954
1955 if (FALSE /*f_v2*/) {
1956 cout << "poset_classification::trace_all_k_subsets "
1957 "corresponding to set ";
1958 Lint_vec_print(cout, subset, k);
1959 cout << endl;
1960 }
1961 Poset->A->element_one(transporter->ith(0), 0);
1962
1963 if (k == 0) {
1964 isotype[0] = 0;
1965 }
1966 else {
1967
1968 if (FALSE) {
1969 cout << "poset_classification::trace_all_k_subsets "
1970 "before trace_set" << endl;
1971 }
1972 local_idx = trace_set(subset, k, k,
1973 canonical_subset, Elt,
1974 0 /*verbose_level - 3*/);
1975 if (FALSE) {
1976 cout << "poset_classification::trace_all_k_subsets "
1977 "after trace_set, local_idx = "
1978 << local_idx << endl;
1979 }
1980
1981 if (FALSE /*f_vvv*/) {
1982 cout << "poset_classification::trace_all_k_subsets "
1983 "local_idx=" << local_idx << endl;
1984 }
1985 isotype[subset_rk] = local_idx;
1986 if (FALSE) {
1987 cout << "poset_classification::trace_all_k_subsets "
1988 "the transporter is" << endl;
1989 Poset->A->element_print(Elt, cout);
1990 cout << endl;
1991 }
1992
1993 }
1994 subset_rk++;
1995 if (!Combi.next_k_subset(index_set, n, k)) {
1996 break;
1997 }
1998 }
1999 if (subset_rk != nCk) {
2000 cout << "poset_classification::trace_all_k_subsets "
2001 "subset_rk != nCk" << endl;
2002 exit(1);
2003 }
2004
2005
2006 FREE_int(index_set);
2007 FREE_lint(subset);
2008 FREE_lint(canonical_subset);
2009 FREE_int(Elt);
2010 if (f_v) {
2011 cout << "poset_classification::trace_all_k_subsets done" << endl;
2012 }
2013}
2014
2015void poset_classification::get_orbit_representatives(
2016 int level,
2017 int &nb_orbits, long int *&Orbit_reps, int verbose_level)
2018{
2019 int f_v = (verbose_level >= 1);
2020 int i;
2021
2022 if (f_v) {
2023 cout << "poset_classification::get_orbit_representatives" << endl;
2024 }
2025 nb_orbits = nb_orbits_at_level(level);
2026 if (f_v) {
2027 cout << "orbits_on_k_sets: we found " << nb_orbits
2028 << " orbits on " << level << "-sets" << endl;
2029 }
2030 Orbit_reps = NEW_lint(nb_orbits * level);
2031 for (i = 0; i < nb_orbits; i++) {
2032 get_set_by_level(level, i, Orbit_reps + i * level);
2033 }
2034
2035 if (f_v) {
2036 cout << "poset_classification::get_orbit_representatives done" << endl;
2037 }
2038}
2039
2040void poset_classification::unrank_point(int *v, long int rk)
2041{
2042 Poset->unrank_point(v, rk);
2043}
2044
2045long int poset_classification::rank_point(int *v)
2046{
2047 long int rk;
2048
2049 rk = Poset->rank_point(v);
2050 return rk;
2051}
2052
2053void poset_classification::unrank_basis(int *Basis, long int *S, int len)
2054{
2055 int i;
2056
2057 for (i = 0; i < len; i++) {
2058 unrank_point(Basis + i * Poset->VS->dimension, S[i]);
2059 }
2060}
2061
2062void poset_classification::rank_basis(int *Basis, long int *S, int len)
2063{
2064 int i;
2065
2066 for (i = 0; i < len; i++) {
2067 S[i] = rank_point(Basis + i * Poset->VS->dimension);
2068 }
2069}
2070
2071}}}
2072
2073
2074
2075
2076
finite dimensional vector space over a finite field
Definition: algebra.h:688
a collection of functions related to sorted vectors
int lint_vec_sort_and_test_if_contained(long int *v1, int len1, long int *v2, int len2)
Definition: sorting.cpp:235
a statistical analysis of data consisting of single integers
void init(int *data, int data_length, int f_second, int verbose_level)
Definition: tally.cpp:72
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
int compare(longinteger_object &a, longinteger_object &b)
void add(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void integral_division_by_int(longinteger_object &a, int b, longinteger_object &q, int &r)
void integral_division(longinteger_object &a, longinteger_object &b, longinteger_object &q, longinteger_object &r, int verbose_level)
int compare_unsigned(longinteger_object &a, longinteger_object &b)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
a permutation group in a fixed action.
Definition: actions.h:99
void coset_unrank(groups::sims *G, groups::sims *U, long int rank, int *Elt, int verbose_level)
void element_print_quick(void *elt, std::ostream &ost)
Definition: action_cb.cpp:353
void element_print(void *elt, std::ostream &ost)
Definition: action_cb.cpp:347
void map_a_set(long int *set, long int *image_set, int n, int *Elt, int verbose_level)
Definition: action.cpp:668
void element_invert(void *a, void *av, int verbose_level)
Definition: action_cb.cpp:322
void element_one(void *elt, int verbose_level)
Definition: action_cb.cpp:224
long int coset_rank(groups::sims *G, groups::sims *U, int *Elt, int verbose_level)
void element_move(void *a, void *b, int verbose_level)
Definition: action_cb.cpp:335
void element_print_as_permutation(void *elt, std::ostream &ost)
Definition: action_cb.cpp:421
void init_strong_generators_by_hdl(int nb_gen, int *gen_hdl, int *tl, int verbose_level)
a set of orbits using a vector of orbit representatives and stabilizers
void init(actions::action *A, actions::action *A2, int verbose_level)
void init_everything(actions::action *A, actions::action *A2, long int *Set, int set_sz, groups::strong_generators *gens, int verbose_level)
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
void compute_and_print_orbits(actions::action *A_given, int verbose_level)
void init_from_sims(groups::sims *S, int verbose_level)
void write_file(std::string &fname, int verbose_level)
data_structures_groups::vector_ge * gens
Definition: groups.h:1708
void group_order(ring_theory::longinteger_object &go)
represents a known classification with constructive recognition, to be used as base case for poset_cl...
to control the behavior of the poset classification algorithm
void classify_k_subsets(long int *the_set, int n, int k, data_structures::tally *&C, int verbose_level)
int trace_set(long int *set, int size, int level, long int *canonical_set, int *Elt_transporter, int verbose_level)
data_structures_groups::set_and_stabilizer * get_set_and_stabilizer(int level, int orbit_at_level, int verbose_level)
void list_whole_orbit(int depth, int orbit_idx, int f_has_print_function, void(*print_function)(std::ostream &ost, int len, long int *S, void *data), void *print_function_data, int f_show_orbit_decomposition, int f_show_stab, int f_save_stab, int f_show_whole_orbit)
void orbit_length(int orbit_at_level, int level, ring_theory::longinteger_object &len)
void orbit_element_unrank(int depth, int orbit_idx, long int rank, long int *set, int verbose_level)
void coset_unrank(int depth, int orbit_idx, long int rank, int *Elt, int verbose_level)
long int coset_rank(int depth, int orbit_idx, int *Elt, int verbose_level)
void get_stabilizer_group(data_structures_groups::group_container *&G, int level, int orbit_at_level, int verbose_level)
void read_sv_level_file_binary(int level, std::string &fname_base, int f_split, int split_mod, int split_case, int f_recreate_extensions, int f_dont_keep_sv, int verbose_level)
void get_stabilizer_generators(groups::strong_generators *&gens, int level, int orbit_at_level, int verbose_level)
void get_stabilizer_order(int level, int orbit_at_level, ring_theory::longinteger_object &go)
void write_sv_level_file_binary(int level, std::string &fname_base, int f_split, int split_mod, int split_case, int verbose_level)
int find_poset_orbit_node_for_set_basic(int from, int node, int len, long int *set, int f_tolerant, int verbose_level)
void trace_all_k_subsets(long int *the_set, int n, int k, int &nCk, int *&isotype, int verbose_level)
void count_automorphism_group_orders(int lvl, int &nb_agos, ring_theory::longinteger_object *&agos, int *&multiplicities, int verbose_level)
the data structure for the poset of orbits in the poset classification algorithm
int find_extension_from_point(int node_idx, long int pt, int verbose_level)
to represent one poset orbit; related to the class poset_classification
void compute_schreier_vector(poset_classification *gen, int lvl, int verbose_level)
void get_stabilizer_generators(poset_classification *PC, groups::strong_generators *&Strong_gens, int verbose_level)
void get_stabilizer_order(poset_classification *gen, ring_theory::longinteger_object &go)
void get_stabilizer(poset_classification *PC, data_structures_groups::group_container &G, ring_theory::longinteger_object &go_G, int verbose_level)
void store_set_to(poset_classification *gen, int i, long int *to)
void early_test_func(long int *S, int len, long int *candidates, int nb_candidates, long int *good_candidates, int &nb_good_candidates, int verbose_level)
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#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
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects
#define EXTENSION_TYPE_PROCESSING
#define EXTENSION_TYPE_EXTENSION