Orbiter 2022
Combinatorial Objects
schreier.cpp
Go to the documentation of this file.
1// schreier.cpp
2//
3// Anton Betten
4// December 9, 2003
5
7#include "group_actions.h"
8#include "shallow_schreier_ai.h"
9
10using namespace std;
11
12
13
14namespace orbiter {
15namespace layer3_group_actions {
16namespace groups {
17
18
20{
21 A = NULL;
23 degree = 0;
24 nb_images = 0;
25 images = NULL;
26 orbit = NULL;
27 orbit_inv = NULL;
28 prev = NULL;
29 label = NULL;
30 orbit_first = NULL;
31 orbit_len = NULL;
32 Elt1 = NULL;
33 Elt2 = NULL;
34 Elt3 = NULL;
35 schreier_gen = NULL;
36 schreier_gen1 = NULL;
37 cosetrep = NULL;
38 cosetrep_tmp = NULL;
40 print_function = NULL;
42 nb_orbits = 0;
43
48 // for compute_all_point_orbits
49
50}
51
52schreier::schreier(actions::action *A, int verbose_level)
53{
54 init(A, verbose_level);
55}
56
58{
59 //cout << "in ~schreier()" << endl;
60 freeself();
61 //cout << "~schreier() finished" << endl;
62}
63
65{
66 //cout << "deleting A" << endl;
67 if (A) {
68 //cout << "deleting orbit" << endl;
70 //cout << "deleting orbit_inv" << endl;
72 //cout << "deleting prev" << endl;
74 //cout << "deleting label" << endl;
76 //cout << "deleting orbit_first" << endl;
78 //cout << "deleting orbit_len" << endl;
80 //cout << "deleting Elt1" << endl;
82 //cout << "deleting Elt2" << endl;
84 //cout << "deleting Elt3" << endl;
86 //cout << "deleting schreier_gen" << endl;
88 //cout << "deleting schreier_gen1" << endl;
90 //cout << "deleting cosetrep" << endl;
92 //cout << "deleting cosetrep_tmp" << endl;
94 //cout << "A = NULL" << endl;
95 A = NULL;
96 }
97 //cout << "deleting images" << endl;
99}
100
102{
103 int i;
104
105 if (images) {
106 for (i = 0; i < nb_images; i++) {
107 FREE_int(images[i]);
108 }
110 images = NULL;
111 nb_images = 0;
112 }
113}
114
116 void (*preferred_choice_function)(int pt, int &pt_pref, schreier *Sch, void *data, int data2, int verbose_level),
117 void *preferred_choice_function_data,
118 int preferred_choice_function_data2,
119 int verbose_level)
120{
121 int f_v = (verbose_level >= 1);
122
123 if (f_v) {
124 cout << "schreier::init_preferred_choice_function" << endl;
125 }
130 if (f_v) {
131 cout << "schreier::init_preferred_choice_function done" << endl;
132 }
133}
134
135
136void schreier::init_images(int nb_images, int verbose_level)
137{
138 int f_v = (verbose_level >= 1);
139 long int i, j;
140
141 if (f_v) {
142 cout << "schreier::init_images" << endl;
143 }
144#if 0
145 if (A == NULL) {
146 cout << "schreier::init_images action is NULL" << endl;
147 exit(1);
148 }
149#endif
153 for (i = 0; i < nb_images; i++) {
154 if (f_v) {
155 cout << "schreier::init_images allocating images[i], i=" << i << endl;
156 }
157 images[i] = NEW_int(2 * degree);
158 for (j = 0; j < 2 * degree; j++) {
159 images[i][j] = -1;
160 }
161 }
162 if (f_v) {
163 cout << "schreier::init_images done" << endl;
164 }
165}
166
167void schreier::init_images_only(int nb_images,
168 long int degree, int *images, int verbose_level)
169{
170 int f_v = (verbose_level >= 1);
171 int i;
173
174 if (f_v) {
175 cout << "schreier::init_images_only" << endl;
176 }
182 for (i = 0; i < nb_images; i++) {
183 if (f_v) {
184 cout << "schreier::init_images_only allocating images[i], i=" << i << endl;
185 }
189 }
191 if (f_v) {
192 cout << "schreier::init_images_only done" << endl;
193 }
194}
195
196
198 int **old_images, int idx_deleted_generator,
199 int verbose_level)
200{
201 int f_v = (verbose_level >= 1);
202 long int i, j;
203
204 if (f_v) {
205 cout << "schreier::init_images_recycle" << endl;
206 }
207#if 0
208 if (A == NULL) {
209 cout << "schreier::init_images_recycle action is NULL" << endl;
210 exit(1);
211 }
212#endif
216 for (i = 0; i < nb_images; i++) {
217 if (f_v) {
218 cout << "schreier::init_images_recycle allocating images[i], i=" << i << endl;
219 }
220 images[i] = NEW_int(2 * degree);
221 if (i == idx_deleted_generator) {
222 for (j = 0; j < 2 * degree; j++) {
223 images[i][j] = -1;
224 }
225 }
226 else {
227 if (old_images[i]) {
228 Int_vec_copy(old_images[i], images[i], 2 * degree);
229 }
230 else {
231 for (j = 0; j < 2 * degree; j++) {
232 images[i][j] = -1;
233 }
234 }
235 }
236 }
237
238 if (f_v) {
239 cout << "schreier::init_images_recycle done" << endl;
240 }
241}
242
243
244
246 int **old_images, int verbose_level)
247{
248 int f_v = (verbose_level >= 1);
249 long int i, j;
250
251 if (f_v) {
252 cout << "schreier::init_images_recycle" << endl;
253 }
254#if 0
255 if (A == NULL) {
256 cout << "schreier::init_images_recycle action is NULL" << endl;
257 exit(1);
258 }
259#endif
263 for (i = 0; i < nb_images; i++) {
264 if (f_v) {
265 cout << "schreier::init_images_recycle allocating images[i], i=" << i << endl;
266 }
267 images[i] = NEW_int(2 * degree);
268 if (old_images[i]) {
269 Int_vec_copy(old_images[i], images[i], 2 * degree);
270 }
271 else {
272 for (j = 0; j < 2 * degree; j++) {
273 images[i][j] = -1;
274 }
275 }
276 }
277
278 if (f_v) {
279 cout << "schreier::init_images_recycle done" << endl;
280 }
281}
282
283
284
285void schreier::images_append(int verbose_level)
286{
287 int f_v = (verbose_level >= 1);
288
289 if (f_v) {
290 cout << "schreier::images_append" << endl;
291 }
292
293 int **new_images = NEW_pint(nb_images + 1);
294 int i, j;
295
296 new_images[nb_images] = NEW_int(2 * degree);
297 for (j = 0; j < 2 * degree; j++) {
298 new_images[nb_images][j] = -1;
299 }
300 for (i = 0; i < nb_images; i++) {
301 new_images[i] = images[i];
302 }
304 images = new_images;
305 nb_images++;
306}
307
308void schreier::init(actions::action *A, int verbose_level)
309{
310 schreier::A = A;
311 degree = A->degree;
312
313 if (degree > INT_MAX) {
314 cout << "schreier::init degree > INT_MAX" << endl;
315 exit(1);
316 }
318 gens.init(A, verbose_level - 2);
319 gens_inv.init(A, verbose_level - 2);
321 init2();
322}
323
325{
332}
333
335{
343}
344
346{
348 long int i;
349
350 nb_orbits = 0;
351 Combi.perm_identity(orbit, degree);
353 orbit_first[0] = 0;
354 for (i = 0; i < degree; i++) {
355 prev[i] = -1;
356 label[i] = -1;
357 }
358}
359
360void schreier::init_single_generator(int *elt, int verbose_level)
361{
362 int f_v = (verbose_level >= 1);
363
364 if (f_v) {
365 cout << "schreier::init_single_generator" << endl;
366 }
367 init_generators(1, elt, verbose_level);
368 if (f_v) {
369 cout << "schreier::init_single_generator done" << endl;
370 }
371}
372
374 data_structures_groups::vector_ge &generators, int verbose_level)
375{
376 int f_v = (verbose_level >= 1);
377
378 if (f_v) {
379 cout << "schreier::init_generators" << endl;
380 }
381 if (generators.len) {
382 init_generators(generators.len,
383 generators.ith(0), verbose_level);
384 }
385 else {
386 init_generators(generators.len, NULL, verbose_level);
387 }
388 if (f_v) {
389 cout << "schreier::init_generators done" << endl;
390 }
391}
392
395 int **old_images,
396 int idx_generator_to_delete, int verbose_level)
397{
398 int f_v = (verbose_level >= 1);
399
400 if (f_v) {
401 cout << "schreier::init_generators_recycle_images" << endl;
402 }
403 if (generators.len) {
405 generators.ith(0), old_images, idx_generator_to_delete);
406 }
407 else {
409 NULL, old_images, idx_generator_to_delete);
410 }
411 if (f_v) {
412 cout << "schreier::init_generators_recycle_images done" << endl;
413 }
414}
415
417 data_structures_groups::vector_ge &generators, int **old_images, int verbose_level)
418{
419 int f_v = (verbose_level >= 1);
420
421 if (f_v) {
422 cout << "schreier::init_generators_recycle_images" << endl;
423 }
424 if (generators.len) {
426 generators.ith(0), old_images, verbose_level);
427 }
428 else {
429 init_generators_recycle_images(generators.len, NULL, old_images, verbose_level);
430 }
431 if (f_v) {
432 cout << "schreier::init_generators_recycle_images done" << endl;
433 }
434}
435
436void schreier::init_generators(int nb, int *elt, int verbose_level)
437// elt must point to nb * A->elt_size_in_int
438// int's that are
439// group elements in int format
440{
441 int i;
442 int f_v = (verbose_level >= 1);
443
444 if (f_v) {
445 cout << "schreier::init_generators, nb=" << nb << endl;
446 }
447
448 gens.allocate(nb, verbose_level - 2);
449 gens_inv.allocate(nb, verbose_level - 2);
450 for (i = 0; i < nb; i++) {
451 if (f_v) {
452 cout << "schreier::init_generators i = " << i << " / " << nb << endl;
453 }
454 gens.copy_in(i, elt + i * A->elt_size_in_int);
455 A->element_invert(elt + i * A->elt_size_in_int, gens_inv.ith(i), 0);
456 }
457 if (f_v) {
458 cout << "schreier::init_generators, before init_images" << endl;
459 }
460 init_images(nb, 0 /* verbose_level */);
461 if (f_v) {
462 cout << "schreier::init_generators, after init_images" << endl;
463 }
464 if (f_v) {
465 cout << "schreier::init_generators done" << endl;
466 }
467}
468
470 int **old_images, int idx_generator_to_delete, int verbose_level)
471// elt must point to nb * A->elt_size_in_int
472// int's that are
473// group elements in int format
474{
475 int i;
476 int f_v = (verbose_level >= 1);
477
478 if (f_v) {
479 cout << "schreier::init_generators_recycle_images" << endl;
480 }
481
482 gens.allocate(nb, verbose_level - 2);
483 gens_inv.allocate(nb, verbose_level - 2);
484 for (i = 0; i < nb; i++) {
485 //cout << "schreier::init_generators i = " << i << endl;
486 gens.copy_in(i, elt + i * A->elt_size_in_int);
487 A->element_invert(elt + i * A->elt_size_in_int,
488 gens_inv.ith(i), 0);
489 }
490 init_images_recycle(nb, old_images,
491 idx_generator_to_delete, 0 /* verbose_level */);
492 if (f_v) {
493 cout << "schreier::init_generators_recycle_images done" << endl;
494 }
495}
496
497
498
500 int *elt, int **old_images, int verbose_level)
501// elt must point to nb * A->elt_size_in_int
502// int's that are
503// group elements in int format
504{
505 int i;
506
507 int f_v = (verbose_level >= 1);
508
509 if (f_v) {
510 cout << "schreier::init_generators_recycle_images" << endl;
511 }
512 gens.allocate(nb, verbose_level - 2);
513 gens_inv.allocate(nb, verbose_level - 2);
514 for (i = 0; i < nb; i++) {
515 //cout << "schreier::init_generators i = " << i << endl;
516 gens.copy_in(i, elt + i * A->elt_size_in_int);
517 A->element_invert(elt + i * A->elt_size_in_int,
518 gens_inv.ith(i), 0);
519 }
520 init_images_recycle(nb, old_images, verbose_level - 2);
521 if (f_v) {
522 cout << "schreier::init_generators_recycle_images done" << endl;
523 }
524}
525
526
527
528
530 int *gen_hdl, int verbose_level)
531{
532 int f_v = (verbose_level >= 1);
533 int f_vv = (verbose_level >= 2);
534 int i;
535
536 if (f_v) {
537 cout << "schreier::init_generators_by_hdl" << endl;
538 cout << "nb_gen = " << nb_gen << endl;
539 cout << "degree = " << degree << endl;
540 }
541
542 gens.allocate(nb_gen, verbose_level - 2);
543 gens_inv.allocate(nb_gen, verbose_level - 2);
544 for (i = 0; i < nb_gen; i++) {
545 //cout << "schreier::init_generators_by_hdl "
546 // "i = " << i << endl;
547 A->element_retrieve(gen_hdl[i], gens.ith(i), 0);
548
549 //cout << "schreier::init_generators_by_hdl "
550 // "generator i = " << i << ":" << endl;
551 //A->element_print_quick(gens.ith(i), cout);
552
553 A->element_invert(gens.ith(i), gens_inv.ith(i), 0);
554 }
555 if (f_vv) {
556 cout << "schreier::init_generators_by_hdl "
557 "generators:" << endl;
558 gens.print(cout);
559 }
560 if (f_v) {
561 cout << "schreier::init_generators_by_hdl "
562 "before init_images()" << endl;
563 }
564 init_images(nb_gen, verbose_level);
565 if (f_v) {
566 cout << "schreier::init_generators_by_hdl "
567 "done" << endl;
568 }
569}
570
571void schreier::init_generators_by_handle(std::vector<int> &gen_hdl, int verbose_level)
572{
573 int f_v = (verbose_level >= 1);
574 int f_vv = (verbose_level >= 2);
575 int i;
576 int nb_gen;
577
578 if (f_v) {
579 cout << "schreier::init_generators_by_handle" << endl;
580 cout << "degree = " << degree << endl;
581 }
582
583 nb_gen = gen_hdl.size();
584
585 gens.allocate(nb_gen, verbose_level - 2);
586 gens_inv.allocate(nb_gen, verbose_level - 2);
587 for (i = 0; i < nb_gen; i++) {
588 //cout << "schreier::init_generators_by_hdl "
589 // "i = " << i << endl;
590 A->element_retrieve(gen_hdl[i], gens.ith(i), 0);
591
592 //cout << "schreier::init_generators_by_hdl "
593 // "generator i = " << i << ":" << endl;
594 //A->element_print_quick(gens.ith(i), cout);
595
596 A->element_invert(gens.ith(i), gens_inv.ith(i), 0);
597 }
598 if (f_vv) {
599 cout << "schreier::init_generators_by_handle "
600 "generators:" << endl;
601 gens.print(cout);
602 }
603 if (f_v) {
604 cout << "schreier::init_generators_by_handle "
605 "before init_images()" << endl;
606 }
607 init_images(nb_gen, verbose_level);
608 if (f_v) {
609 cout << "schreier::init_generators_by_handle "
610 "done" << endl;
611 }
612}
613
614
615long int schreier::get_image(long int i, int gen_idx, int verbose_level)
616{
617 int f_v = (verbose_level >= 1);
618 long int a;
619
620 if (f_v) {
621 cout << "schreier::get_image computing image of point "
622 << i << " under generator " << gen_idx << endl;
623 }
624 if (images == NULL) {
625 if (f_v) {
626 cout << "schreier::get_image not using image table" << endl;
627 }
628 if (f_images_only) {
629 cout << "schreier::get_image images == NULL "
630 "and f_images_only" << endl;
631 exit(1);
632 }
633 if (f_v) {
634 cout << "schreier::get_image before A->element_image_of" << endl;
635 }
636 a = A->element_image_of(
637 i,
638 gens.ith(gen_idx),
639 0 /*verbose_level - 2*/);
640 if (f_v) {
641 cout << "schreier::get_image after A->element_image_of" << endl;
642 }
643 //cout << "schreier::get_image"
644 // "images == NULL" << endl;
645 //exit(1);
646 }
647 else {
648 if (f_v) {
649 cout << "schreier::get_image using image table" << endl;
650 }
651 a = images[gen_idx][i];
652 if (a == -1) {
653 if (f_images_only) {
654 cout << "schreier::get_image a == -1 "
655 "is not allowed if f_images_only is TRUE" << endl;
656 exit(1);
657 }
658 if (f_v) {
659 cout << "schreier::get_image before A->element_image_of" << endl;
660 }
661 a = A->element_image_of(i, gens.ith(gen_idx), verbose_level - 2);
662 if (f_v) {
663 cout << "schreier::get_image image of "
664 "i=" << i << " is " << a << endl;
665 }
666 images[gen_idx][i] = a;
667 images[gen_idx][A->degree + a] = i;
668 }
669 }
670 if (f_v) {
671 cout << "schreier::get_image image of point "
672 << i << " under generator " << gen_idx
673 << " is " << a << endl;
674 }
675 return a;
676}
677
678void schreier::swap_points(int i, int j, int verbose_level)
679{
680 int f_v = (verbose_level >= 1);
681 int pi, pj;
682
683 if (f_v) {
684 cout << "schreier::swap_points i=" << i << " j=" << j << endl;
685 }
686 pi = orbit[i];
687 pj = orbit[j];
688 orbit[i] = pj;
689 orbit[j] = pi;
690 orbit_inv[pi] = j;
691 orbit_inv[pj] = i;
692 if (f_v) {
693 cout << "schreier::swap_points done" << endl;
694 }
695}
696
697void schreier::move_point_here(int here, int pt)
698{
699 int a, loc;
700 if (orbit[here] == pt) {
701 return;
702 }
703 a = orbit[here];
704 loc = orbit_inv[pt];
705 orbit[here] = pt;
706 orbit[loc] = a;
707 orbit_inv[a] = loc;
708 orbit_inv[pt] = here;
709}
710
712{
713 int j;
714
715 while (TRUE) {
716 j = orbit_inv[pt];
717 if (prev[j] == -1) {
718 return pt;
719 }
720 pt = prev[j];
721 }
722}
723
725// j is a coset, not a point
726{
727 if (prev[j] == -1) {
728 return 0;
729 }
730 else {
731 return depth_in_tree(orbit_inv[prev[j]]) + 1;
732 }
733}
734
736 int &orbit_idx, int *Elt, int verbose_level)
737{
738 int f_v = (verbose_level >= 1);
739 int pos;
740
741 if (f_v) {
742 cout << "schreier::transporter_from_orbit_rep_to_point" << endl;
743 }
744 if (f_images_only) {
745 cout << "schreier::transporter_from_orbit_rep_to_point is not "
746 "allowed if f_images_only is TRUE" << endl;
747 exit(1);
748 }
749 pos = orbit_inv[pt];
750 orbit_idx = orbit_number(pt); //orbit_no[pos];
751 //cout << "lies in orbit " << orbit_idx << endl;
752 coset_rep(pos, verbose_level - 1);
753 A->element_move(cosetrep, Elt, 0);
754 if (f_v) {
755 cout << "schreier::transporter_from_orbit_"
756 "rep_to_point done" << endl;
757 }
758}
759
761 int &orbit_idx, int *Elt, int verbose_level)
762{
763 int f_v = (verbose_level >= 1);
764 int pos;
765
766 if (f_v) {
767 cout << "schreier::transporter_from_point_"
768 "to_orbit_rep" << endl;
769 }
770 if (f_images_only) {
771 cout << "schreier::transporter_from_point_to_orbit_rep is not "
772 "allowed if f_images_only is TRUE" << endl;
773 exit(1);
774 }
775 pos = orbit_inv[pt];
776 orbit_idx = orbit_number(pt); //orbit_no[pos];
777 //cout << "lies in orbit " << orbit_idx << endl;
778 coset_rep_with_verbosity(pos, verbose_level - 1);
779 A->element_invert(cosetrep, Elt, 0);
780 //A->element_move(cosetrep, Elt, 0);
781 if (f_v) {
782 cout << "schreier::transporter_from_point_to_orbit_rep "
783 "done" << endl;
784 }
785}
786
787void schreier::coset_rep(int j, int verbose_level)
788// j is a coset, not a point
789// result is in cosetrep
790// determines an element in the group
791// that moves the orbit representative
792// to the j-th point in the orbit.
793{
794 int f_v = (verbose_level >= 1);
795 int *gen;
796
797 if (f_v) {
798 cout << "schreier::coset_rep coset j=" << j << " pt=" << orbit[j] << endl;
799 }
800 if (f_images_only) {
801 cout << "schreier::coset_rep is not "
802 "allowed if f_images_only is TRUE" << endl;
803 exit(1);
804 }
805 if (prev[j] != -1) {
806 if (f_v) {
807 cout << "schreier::coset_rep j=" << j << " pt=" << orbit[j];
808 cout << " prev[j]=" << prev[j] << " orbit_inv[prev[j]]=";
809 cout << orbit_inv[prev[j]] << " label[j]=" << label[j] << endl;
810 }
811 coset_rep(orbit_inv[prev[j]], verbose_level);
812 gen = gens.ith(label[j]);
815 }
816 else {
818 }
819 if (f_v) {
820 cout << "schreier::coset_rep j=" << j << " pt=" << orbit[j]<< " done" << endl;
821 }
822}
823
824void schreier::coset_rep_with_verbosity(int j, int verbose_level)
825// j is a coset, not a point
826// result is in cosetrep
827// determines an element in the group
828// that moves the orbit representative
829// to the j-th point in the orbit.
830{
831 int f_v = (verbose_level >= 1);
832 int *gen;
833
834 if (f_v) {
835 cout << "schreier::coset_rep_with_verbosity j="
836 << j << " orbit[j]=" << orbit[j] << endl;
837 }
838 if (f_images_only) {
839 cout << "schreier::coset_rep_with_verbosity is not "
840 "allowed if f_images_only is TRUE" << endl;
841 exit(1);
842 }
843 if (prev[j] != -1) {
844 if (f_v) {
845 cout << "schreier::coset_rep_with_verbosity j=" << j
846 << " label[j]=" << label[j]
847 << " orbit_inv[prev[j]]="
848 << orbit_inv[prev[j]] << endl;
849 }
850 coset_rep_with_verbosity(orbit_inv[prev[j]], verbose_level);
851 gen = gens.ith(label[j]);
854 }
855 else {
857 }
858 if (f_v) {
859 cout << "schreier::coset_rep_with_verbosity "
860 "j=" << j << " done" << endl;
861 }
862}
863
864void schreier::coset_rep_inv(int j, int verbose_level)
865// j is a coset, not a point
866// result is in cosetrep
867{
868 int f_v = (verbose_level >= 1);
869 int *gen;
870
871 if (f_v) {
872 cout << "schreier::coset_rep_inv j=" << j << endl;
873 }
874 if (f_images_only) {
875 cout << "schreier::coset_rep_inv is not "
876 "allowed if f_images_only is TRUE" << endl;
877 exit(1);
878 }
879 if (prev[j] != -1) {
880 if (f_v) {
881 cout << "schreier::coset_rep_inv j=" << j << " orbit_inv[prev[j]]=" << orbit_inv[prev[j]] << " label[j]=" << label[j] << endl;
882 }
883 coset_rep_inv(orbit_inv[prev[j]], verbose_level);
884 gen = gens_inv.ith(label[j]);
887 }
888 else {
890 }
891 if (f_v) {
892 cout << "schreier::coset_rep_inv j=" << j << " done" << endl;
893 }
894}
895
896
897
898
899
900
901void schreier::extend_orbit(int *elt, int verbose_level)
902{
903 int f_v = (verbose_level >= 1);
904 int f_vv = (verbose_level >= 3);
905 int cur, total0, total, cur_pt;
906 int gen_first, i, next_pt, next_pt_loc;
907
908 if (f_v) {
909 cout << "schreier::extend_orbit" << endl;
910 }
911 if (f_vv) {
912 cout << "schreier::extend_orbit extending orbit "
913 << nb_orbits - 1 << " of length "
914 << orbit_len[nb_orbits - 1] << endl;
915 }
916
917 gens.append(elt, verbose_level - 2);
918 A->element_invert(elt, A->Elt1, FALSE);
919 gens_inv.append(A->Elt1, verbose_level - 2);
920 images_append(verbose_level - 2);
921
922 cur = orbit_first[nb_orbits - 1];
923 total = total0 = orbit_first[nb_orbits];
924 while (cur < total) {
925 cur_pt = orbit[cur];
926 if (FALSE) {
927 cout << "schreier::extend_orbit "
928 "applying generator to " << cur_pt << endl;
929 }
930#if 0
931 if (cur < total0)
932 gen_first = gens.len - 1;
933 else
934 gen_first = 0;
935#endif
936 gen_first = 0;
937 for (i = gen_first; i < gens.len; i++) {
938 next_pt = get_image(cur_pt, i, 0/*verbose_level - 3*/);
939 // A->element_image_of(cur_pt, gens.ith(i), FALSE);
940 next_pt_loc = orbit_inv[next_pt];
941 if (FALSE) {
942 cout << "schreier::extend_orbit generator "
943 << i << " maps " << cur_pt
944 << " to " << next_pt << endl;
945 }
946 if (next_pt_loc < total) {
947 continue;
948 }
949 if (FALSE) {
950 cout << "schreier::extend_orbit n e w pt "
951 << next_pt << " reached from "
952 << cur_pt << " under generator " << i << endl;
953 }
954 swap_points(total, next_pt_loc, 0 /*verbose_level*/);
955 prev[total] = cur_pt;
956 label[total] = i;
957 total++;
958 if (FALSE) {
959 cout << "cur = " << cur << endl;
960 cout << "total = " << total << endl;
961 print_orbit(cur, total - 1);
962 }
963 }
964 cur++;
965 }
966 orbit_first[nb_orbits] = total;
967 orbit_len[nb_orbits - 1] = total - orbit_first[nb_orbits - 1];
968 if (f_v) {
969 cout << "schreier::extend_orbit orbit extended to length "
970 << orbit_len[nb_orbits - 1] << endl;
971 }
972 if (FALSE) {
973 cout << "{ ";
974 for (i = orbit_first[nb_orbits - 1];
975 i < orbit_first[nb_orbits]; i++) {
976 cout << orbit[i];
977 if (i < orbit_first[nb_orbits] - 1) {
978 cout << ", ";
979 }
980 }
981 cout << " }" << endl;
982 }
983 if (f_v) {
984 cout << "schreier::extend_orbit done" << endl;
985 }
986}
987
989{
990 int pt, pt_loc, cur, pt0;
991 int f_v = (verbose_level >= 1);
992 int f_vv = (verbose_level >= 2);
993
994 if (f_v) {
995 cout << "schreier::compute_all_point_orbits "
996 "verbose_level=" << verbose_level << endl;
997 }
998 if (degree > ONE_MILLION) {
999 f_vv = FALSE;
1000 }
1002 for (pt0 = 0, pt = 0; pt < degree; pt++) {
1003 pt_loc = orbit_inv[pt];
1004 cur = orbit_first[nb_orbits];
1005 if (pt_loc < cur) {
1006 continue;
1007 }
1008
1009 int pt_pref;
1010
1012
1013 if (TRUE) {
1014 cout << "schreier::compute_all_point_orbits "
1015 "before preferred_choice_function, pt=" << pt << endl;
1016 }
1017 (*preferred_choice_function)(pt, pt_pref,
1018 this,
1021 verbose_level);
1022 if (TRUE) {
1023 cout << "schreier::compute_all_point_orbits "
1024 "before preferred_choice_function, pt=" << pt << " pt_pref=" << pt_pref << endl;
1025 }
1026
1027 if (orbit_inv[pt_pref] < cur) {
1028 cout << "schreier::compute_all_point_orbits preferred point is already in some other orbit" << endl;
1029 exit(1);
1030 }
1031
1032 }
1033 else {
1034 pt_pref = pt;
1035 }
1036
1037 //int f_preferred_choice_function;
1038 //void (*preferred_choice_function)(int pt, int &pt_pref, void *data);
1039 //void *preferred_choice_function_data;
1040
1041
1042 if (f_vv) {
1043 cout << "schreier::compute_all_point_orbits pt = "
1044 << pt << " / " << degree
1045 << " nb_orbits=" << nb_orbits
1046 << " cur=" << cur
1047 << ", computing orbit of pt_pref=" << pt_pref << endl;
1048 }
1049 if (degree > ONE_MILLION && (pt - pt0) > 50000) {
1050 cout << "schreier::compute_all_point_orbits pt = "
1051 << pt << " / " << degree
1052 << " nb_orbits=" << nb_orbits
1053 << " cur=" << cur
1054 << ", computing orbit of pt_pref=" << pt_pref << endl;
1055 pt0 = pt;
1056 }
1057 compute_point_orbit(pt_pref, verbose_level - 2);
1058 }
1059 if (f_v) {
1060 cout << "schreier::compute_all_point_orbits found "
1061 << nb_orbits << " orbits" << endl;
1063
1064 Cl.init(orbit_len, nb_orbits, FALSE, 0);
1065 cout << "The distribution of orbit lengths is: ";
1066 Cl.print(FALSE);
1067 }
1068}
1069
1071 int *prefered_reps, int nb_prefered_reps,
1072 int verbose_level)
1073{
1074 int i, pt, pt_loc, cur;
1075 int f_v = (verbose_level >= 1);
1076
1077 if (f_v) {
1078 cout << "schreier::compute_all_point_orbits_with_prefered_reps" << endl;
1079 }
1081 for (i = 0; i < nb_prefered_reps; i++) {
1082 pt = prefered_reps[i];
1083 pt_loc = orbit_inv[pt];
1084 cur = orbit_first[nb_orbits];
1085 if (pt_loc < cur) {
1086 continue;
1087 }
1088 compute_point_orbit(pt, verbose_level - 1);
1089 }
1090 for (pt = 0; pt < degree; pt++) {
1091 pt_loc = orbit_inv[pt];
1092 cur = orbit_first[nb_orbits];
1093 if (pt_loc < cur) {
1094 continue;
1095 }
1096 compute_point_orbit(pt, verbose_level - 1);
1097 }
1098 if (f_v) {
1099 cout << "found " << nb_orbits << " orbits";
1100 cout << " on points" << endl;
1101 }
1102}
1103
1105 long int *preferred_labels, int verbose_level)
1106{
1107 int pt, pt_loc, cur, a, i;
1108 int f_v = (verbose_level >= 1);
1109 int *labels, *perm, *perm_inv;
1111
1112 if (f_v) {
1113 cout << "schreier::compute_all_point_orbits_with_"
1114 "preferred_labels" << endl;
1115 //cout << "preferred_labels :";
1116 //int_vec_print(cout, preferred_labels, degree);
1117 //cout << endl;
1118 cout << "degree = " << degree << endl;
1119 }
1120 if (f_v) {
1121 cout << "schreier::compute_all_point_orbits_with_"
1122 "preferred_labels allocating tables" << endl;
1123 }
1125 labels = NEW_int(degree);
1126 perm = NEW_int(degree);
1127 perm_inv = NEW_int(degree);
1128 for (i = 0; i < degree; i++) {
1129 labels[i] = preferred_labels[i];
1130 }
1131 if (f_v) {
1132 cout << "schreier::compute_all_point_orbits_"
1133 "with_preferred_labels allocating tables done, "
1134 "sorting" << endl;
1135 }
1136 Sorting.int_vec_sorting_permutation(labels, degree,
1137 perm, perm_inv, TRUE /* f_increasingly */);
1138
1139 if (f_v) {
1140 cout << "schreier::compute_all_point_orbits_"
1141 "with_preferred_labels sorting done" << endl;
1142 }
1143
1144 for (a = 0; a < degree; a++) {
1145 pt = perm_inv[a];
1146 pt_loc = orbit_inv[pt];
1147 cur = orbit_first[nb_orbits];
1148 if (pt_loc < cur) {
1149 continue;
1150 }
1151 // now we need to make sure that the point pt
1152 // is moved to position cur:
1153 // actually this is not needed as the
1154 // function compute_point_orbit does this, too.
1155 swap_points(cur, pt_loc, 0 /*verbose_level*/);
1156
1157 if (f_v) {
1158 cout << "schreier::compute_all_point_orbits_with_"
1159 "preferred_labels computing orbit of point "
1160 << pt << " = " << a << " / " << degree << endl;
1161 }
1162 compute_point_orbit(pt, verbose_level - 2);
1163 if (f_v) {
1164 cout << "schreier::compute_all_point_orbits_with_"
1165 "preferred_labels computing orbit of point "
1166 << pt << " done, found an orbit of length "
1167 << orbit_len[nb_orbits - 1]
1168 << " nb_orbits = " << nb_orbits << endl;
1169 }
1170 }
1171 if (f_v) {
1172 cout << "found " << nb_orbits << " orbit";
1173 if (nb_orbits != 1)
1174 cout << "s";
1175 cout << " on points" << endl;
1176 }
1177 FREE_int(labels);
1178 FREE_int(perm);
1179 FREE_int(perm_inv);
1180 if (f_v) {
1181 cout << "schreier::compute_all_point_orbits_with_"
1182 "preferred_labels done" << endl;
1183 }
1184}
1185
1187 int len, long int *subset, int verbose_level)
1188{
1189 int f_v = (verbose_level >= 1);
1190 int i, f;
1191
1192 if (f_v) {
1193 cout << "schreier::compute_all_orbits_on_invariant_subset" << endl;
1194 cout << "computing orbits on a set of size " << len << endl;
1195 }
1197 for (i = 0; i < len; i++) {
1198 move_point_here(i, subset[i]);
1199 }
1200 while (TRUE) {
1202 if (f >= len) {
1203 break;
1204 }
1205 compute_point_orbit(orbit[f], 0 /* verbose_level */);
1206 }
1207 if (f > len) {
1208 cout << "schreier::compute_all_orbits_on_invariant_subset "
1209 "the set is not G-invariant" << endl;
1210 exit(1);
1211 }
1212 if (f_v) {
1213 cout << "found " << nb_orbits << " orbits" << endl;
1215 }
1216 if (f_v) {
1217 cout << "schreier::compute_all_orbits_on_invariant_subset done" << endl;
1218 }
1219}
1220
1222 int len, long int *subset, int verbose_level)
1223{
1224 int f_v = (verbose_level >= 1);
1225 int i, f;
1226
1227 if (f_v) {
1228 cout << "schreier::compute_all_orbits_on_invariant_subset" << endl;
1229 cout << "computing orbits on a set of size " << len << endl;
1230 }
1232 for (i = 0; i < len; i++) {
1233 move_point_here(i, subset[i]);
1234 }
1235 while (TRUE) {
1237 if (f >= len) {
1238 break;
1239 }
1240 compute_point_orbit(orbit[f], 0 /* verbose_level */);
1241 }
1242 if (f > len) {
1243 cout << "schreier::compute_all_orbits_on_invariant_subset "
1244 "the set is not G-invariant" << endl;
1245 exit(1);
1246 }
1247 if (f_v) {
1248 cout << "found " << nb_orbits << " orbits" << endl;
1250 }
1251 if (f_v) {
1252 cout << "schreier::compute_all_orbits_on_invariant_subset done" << endl;
1253 }
1254}
1255
1256void schreier::compute_point_orbit(int pt, int verbose_level)
1257{
1258 int pt_loc, cur, cur_pt, total, i, next_pt;
1259 int next_pt_loc, total1, cur1;
1260 int f_v = (verbose_level >= 1);
1261 int f_vv = FALSE; //(verbose_level >= 2);
1262 int f_vvv = FALSE; //(verbose_level >= 3);
1263
1264 if (f_v) {
1265 cout << "schreier::compute_point_orbit" << endl;
1266 cout << "computing orbit of point " << pt;
1267 if (f_images_only) {
1268 cout << " in no action, using table of images only" << endl;
1269 }
1270 else {
1271 cout << " in action " << A->label << endl;
1272 }
1273 }
1274 //exit(1);
1275 pt_loc = orbit_inv[pt];
1276 cur = orbit_first[nb_orbits];
1277 if (pt_loc < cur) {
1278 cout << "schreier::compute_point_orbit "
1279 "i < orbit_first[nb_orbits]" << endl;
1280 exit(1);
1281 }
1282 if (f_v) {
1283 cout << "schreier::compute_point_orbit "
1284 "computing orbit of pt " << pt << " cur=" << cur << endl;
1285 cout << "schreier::compute_point_orbit "
1286 "nb_orbits=" << nb_orbits << endl;
1287 cout << "schreier::compute_point_orbit "
1288 "pt_loc=" << pt_loc << endl;
1289 }
1290 if (pt_loc > orbit_first[nb_orbits]) {
1291 swap_points(orbit_first[nb_orbits], pt_loc, 0 /* verbose_level */);
1292 }
1293 //orbit_no[orbit_first[nb_orbits]] = nb_orbits;
1294 total = cur + 1;
1295 while (cur < total) {
1296 if (FALSE) {
1297 cout << "schreier::compute_point_orbit cur=" << cur << " total=" << total << endl;
1298 }
1299
1300 cur_pt = orbit[cur];
1301 if (f_vv) {
1302 cout << "schreier::compute_point_orbit "
1303 "expanding point " << cur_pt << endl;
1304 }
1305 for (i = 0; i < nb_images /* gens.len*/; i++) {
1306 if (f_vv) {
1307 cout << "schreier::compute_point_orbit "
1308 "expanding point " << cur_pt
1309 << " using generator " << i << endl;
1310 }
1311
1312 next_pt = get_image(cur_pt, i, verbose_level);
1313
1314
1315 // A->element_image_of(cur_pt, gens.ith(i), FALSE);
1316 next_pt_loc = orbit_inv[next_pt];
1317
1318 if (f_vv) {
1319 cout << "schreier::compute_point_orbit " << cur_pt
1320 << " -> " << next_pt << endl;
1321 }
1322
1323 if (next_pt_loc < total) {
1324 continue;
1325 }
1326 if (f_vv) {
1327 cout << "schreier::compute_point_orbit expanding: "
1328 << cur_pt << ", " << next_pt << ", " << i << endl;
1329 }
1330 swap_points(total, next_pt_loc, 0 /*verbose_level*/);
1331 prev[total] = cur_pt;
1332 label[total] = i;
1333 //orbit_no[total] = nb_orbits;
1334 total++;
1335 total1 = total - orbit_first[nb_orbits];
1336 cur1 = cur - orbit_first[nb_orbits];
1337 if ((total1 % 10000) == 0 ||
1338 (cur1 > 0 && (cur1 % 10000) == 0)) {
1339 cout << "schreier::compute_point_orbit degree = "
1340 << degree << " length = " << total1
1341 << " processed = " << cur1 << " nb_orbits="
1342 << nb_orbits << " cur_pt=" << cur_pt << " next_pt="
1343 << next_pt << " orbit_first[nb_orbits]="
1344 << orbit_first[nb_orbits] << endl;
1345 }
1346 if (f_vv) {
1347 cout << "cur = " << cur << endl;
1348 cout << "total = " << total << endl;
1349 //print_orbit(cur, total - 1);
1350 }
1351 }
1352 if (f_vv) {
1353 cout << "schreier::compute_point_orbit cur_pt " << cur_pt
1354 << " has been expanded" << endl;
1355 cout << "cur=" << cur << " total = " << total << endl;
1356 }
1357 cur++;
1358 }
1359 orbit_first[nb_orbits + 1] = total;
1361 if (f_v) {
1362 cout << "found orbit of length " << orbit_len[nb_orbits]
1363 << " total length " << total
1364 << " degree=" << degree << endl;
1365 }
1366 if (f_vvv) {
1367 cout << "{ ";
1368 for (i = orbit_first[nb_orbits];
1369 i < orbit_first[nb_orbits + 1]; i++) {
1370 cout << orbit[i];
1371 if (i < orbit_first[nb_orbits + 1] - 1)
1372 cout << ", ";
1373 }
1374 cout << " }" << endl;
1375 }
1376 if (FALSE) {
1377 cout << "coset reps:" << endl;
1378 for (i = orbit_first[nb_orbits];
1379 i < orbit_first[nb_orbits + 1]; i++) {
1380 cout << i << " : " << endl;
1381 coset_rep(i, verbose_level - 1);
1382 A->element_print(cosetrep, cout);
1383 cout << "image = " << orbit[i] << " = "
1384 << A->element_image_of(pt, cosetrep, 0) << endl;
1385 cout << endl;
1386
1387 }
1388 }
1389 nb_orbits++;
1390 if (f_v) {
1391 cout << "schreier::compute_point_orbit done" << endl;
1392 }
1393}
1394
1396 int pt, int max_depth, int verbose_level)
1397{
1398 int pt_loc, cur, cur_pt, total, i, next_pt;
1399 int next_pt_loc, total1, cur1;
1400 int *depth;
1401 int f_v = (verbose_level >= 1);
1402 int f_vv = FALSE; // (verbose_level >= 5);
1403 //int f_vvv = FALSE; //(verbose_level >= 3);
1404
1405 if (f_v) {
1406 cout << "schreier::compute_point_orbit_with_limited_depth" << endl;
1407 cout << "computing orbit of point " << pt
1408 << " in action " << A->label << endl;
1409 }
1410 depth = NEW_int(A->degree);
1411 Int_vec_zero(depth, A->degree);
1412 pt_loc = orbit_inv[pt];
1413 cur = orbit_first[nb_orbits];
1414 if (pt_loc < cur) {
1415 cout << "schreier::compute_point_orbit_with_limited_depth "
1416 "i < orbit_first[nb_orbits]" << endl;
1417 exit(1);
1418 }
1419 if (f_v) {
1420 cout << "schreier::compute_point_orbit_with_limited_depth "
1421 "computing orbit of pt " << pt << endl;
1422 }
1423 if (pt_loc > orbit_first[nb_orbits]) {
1424 swap_points(orbit_first[nb_orbits], pt_loc, 0 /*verbose_level*/);
1425 }
1426 depth[cur] = 0;
1427 total = cur + 1;
1428 while (cur < total) {
1429 cur_pt = orbit[cur];
1430 if (depth[cur] > max_depth) {
1431 break;
1432 }
1433 if (f_vv) {
1434 cout << "schreier::compute_point_orbit_with_limited_depth cur="
1435 << cur << " total=" << total
1436 << " applying generators to " << cur_pt << endl;
1437 }
1438 for (i = 0; i < nb_images /* gens.len */; i++) {
1439 if (f_vv) {
1440 cout << "schreier::compute_point_orbit_with_limited_depth "
1441 "applying generator "
1442 << i << " to point " << cur_pt << endl;
1443 }
1444 next_pt = get_image(cur_pt, i,
1445 0 /*verbose_level - 5*/); // !!
1446 // A->element_image_of(cur_pt, gens.ith(i), FALSE);
1447 next_pt_loc = orbit_inv[next_pt];
1448 if (f_vv) {
1449 cout << "schreier::compute_point_orbit_with_limited_depth "
1450 "generator "
1451 << i << " maps " << cur_pt
1452 << " to " << next_pt << endl;
1453 }
1454 if (next_pt_loc < total) {
1455 continue;
1456 }
1457 if (f_vv) {
1458 cout << "schreier::compute_point_orbit_with_limited_depth "
1459 "n e w pt "
1460 << next_pt << " reached from "
1461 << cur_pt << " under generator " << i << endl;
1462 }
1463 swap_points(total, next_pt_loc, 0 /*verbose_level*/);
1464 depth[total] = depth[cur] + 1;
1465 prev[total] = cur_pt;
1466 label[total] = i;
1467 total++;
1468 total1 = total - orbit_first[nb_orbits];
1469 cur1 = cur - orbit_first[nb_orbits];
1470 if ((total1 % 10000) == 0 ||
1471 (cur1 > 0 && (cur1 % 10000) == 0)) {
1472 cout << "schreier::compute_point_orbit_with_limited_depth "
1473 "degree = "
1474 << A->degree << " length = " << total1
1475 << " processed = " << cur1 << " nb_orbits="
1476 << nb_orbits << " cur_pt=" << cur_pt << " next_pt="
1477 << next_pt << " orbit_first[nb_orbits]="
1478 << orbit_first[nb_orbits] << endl;
1479 }
1480 if (FALSE) {
1481 cout << "cur = " << cur << endl;
1482 cout << "total = " << total << endl;
1483 print_orbit(cur, total - 1);
1484 }
1485 }
1486 cur++;
1487 }
1488 orbit_first[nb_orbits + 1] = total;
1490 if (f_v) {
1491 cout << "schreier::compute_point_orbit_with_limited_depth "
1492 "found an incomplete orbit of length "
1494 << " total length " << total
1495 << " degree=" << A->degree << endl;
1496 }
1497 FREE_int(depth);
1498 nb_orbits++;
1499 if (f_v) {
1500 cout << "schreier::compute_point_orbit_with_limited_depth done" << endl;
1501 }
1502}
1503
1504
1506{
1507 int i, l, N;
1508
1509 N = 0;
1510 for (i = 0; i < nb_orbits; i++) {
1511 l = orbit_len[i];
1512 N += l;
1513 }
1514 return N;
1515}
1516
1518 actions::action *A_original, int *Elt, int verbose_level)
1519// computes non trivial random Schreier generator into schreier_gen
1520// non-trivial is with respect to A_original
1521{
1522 int f_v = (verbose_level >= 1);
1523 int f_vv = (verbose_level >= 2);
1524 int f_vvv = FALSE; //(verbose_level >= 3);
1525 int f_v4 = FALSE; //(verbose_level >= 4);
1526 int cnt = 0;
1527
1528 if (f_v) {
1529 cout << "schreier::non_trivial_random_schreier_generator "
1530 "verbose_level=" << verbose_level << endl;
1531 }
1532 if (f_images_only) {
1533 cout << "schreier::non_trivial_random_schreier_generator is not "
1534 "allowed if f_images_only is TRUE" << endl;
1535 exit(1);
1536 }
1537 while (TRUE) {
1538 if (f_v) {
1539 cout << "schreier::non_trivial_random_schreier_generator "
1540 "calling random_schreier_generator "
1541 "(cnt=" << cnt << ")" << endl;
1542 }
1543 random_schreier_generator(Elt, verbose_level - 1);
1544 cnt++;
1545 if (!A_original->element_is_one(schreier_gen, verbose_level - 5)) {
1546 if (f_vv) {
1547 cout << "schreier::non_trivial_random_schreier_generator "
1548 "found a non-trivial random Schreier generator in "
1549 << cnt << " trials" << endl;
1550 }
1551 if (f_vvv) {
1552 A->element_print(Elt, cout);
1553 cout << endl;
1554 }
1555 return;
1556 }
1557 else {
1558 if (f_v4) {
1559 A->element_print(Elt, cout);
1560 cout << endl;
1561 }
1562 if (f_vv) {
1563 cout << "schreier::non_trivial_random_schreier_generator "
1564 "the element is the identity in action "
1565 << A_original->label << ", trying again" << endl;
1566 }
1567 }
1568 }
1569 if (f_v) {
1570 cout << "schreier::non_trivial_random_schreier_generator done" << endl;
1571 }
1572}
1573
1575 int *Elt,
1576 int orbit_no, int verbose_level)
1577// computes random Schreier generator for the orbit orbit_no into Elt
1578{
1579 int first, len, r1, r2, pt, pt2, pt2_coset;
1580 int *gen;
1581 int f_v = (verbose_level >= 1);
1582 int f_vv = FALSE; //(verbose_level >= 2);
1583 int f_vvv = FALSE; //(verbose_level >= 3);
1585
1586 if (f_v) {
1587 cout << "schreier::random_schreier_generator_ith_orbit, "
1588 "orbit " << orbit_no << " action=" << A->label << endl;
1589 }
1590 if (f_images_only) {
1591 cout << "schreier::random_schreier_generator_ith_orbit is not "
1592 "allowed if f_images_only is TRUE" << endl;
1593 exit(1);
1594 }
1595 if (f_vvv) {
1596 cout << "schreier::random_schreier_generator_ith_orbit generators are:" << endl;
1597 gens.print(cout);
1598 }
1599 first = orbit_first[orbit_no];
1600 len = orbit_len[orbit_no];
1601 pt = orbit[first];
1602 if (f_vv) {
1603 cout << "schreier::random_schreier_generator_ith_orbit pt=" << pt << endl;
1604 cout << "schreier::random_schreier_generator_ith_orbit orbit_first[orbit_no]=" << orbit_first[orbit_no] << endl;
1605 cout << "schreier::random_schreier_generator_ith_orbit orbit_len[orbit_no]=" << orbit_len[orbit_no] << endl;
1606 cout << "schreier::random_schreier_generator_ith_orbit gens.len=" << gens.len << endl;
1607 }
1608
1609 // get a random coset:
1610 r1 = Os.random_integer(orbit_len[orbit_no]);
1611 if (f_vv) {
1612 cout << "schreier::random_schreier_generator_ith_orbit r1=" << r1 << endl;
1613 }
1614 //pt1 = orbit[r1];
1615 coset_rep(orbit_first[orbit_no] + r1, verbose_level - 1);
1616 // coset rep now in cosetrep
1617 if (f_vvv) {
1618 cout << "schreier::random_schreier_generator_ith_orbit cosetrep " << orbit_first[orbit_no] + r1 << endl;
1620 if (A->degree < 100) {
1622 cout << endl;
1623 }
1624 }
1625
1626 // get a random generator:
1627 r2 = Os.random_integer(gens.len);
1628 if (f_vv) {
1629 cout << "schreier::random_schreier_generator_ith_orbit r2=" << r2 << endl;
1630 }
1631 gen = gens.ith(r2);
1632 if (f_vvv) {
1633 cout << "schreier::random_schreier_generator_ith_orbit generator " << r2 << endl;
1634 A->element_print(gen, cout);
1635 if (A->degree < 100) {
1636 A->element_print_as_permutation(gen, cout);
1637 cout << endl;
1638 }
1639 }
1640 if (f_vv) {
1641 cout << "schreier::random_schreier_generator_ith_orbit random coset " << r1
1642 << ", random generator " << r2 << endl;
1643 }
1644
1646 if (f_vvv) {
1647 cout << "schreier::random_schreier_generator_ith_orbit cosetrep * generator " << endl;
1649 if (A->degree < 100) {
1651 cout << endl;
1652 }
1653 }
1654 pt2 = A->element_image_of(pt, schreier_gen1, 0);
1655 if (f_vv) {
1656 //cout << "pt2=" << pt2 << endl;
1657 cout << "schreier::random_schreier_generator_ith_orbit maps " << pt << " to " << pt2 << endl;
1658 }
1659 pt2_coset = orbit_inv[pt2];
1660 if (f_vv) {
1661 cout << "schreier::random_schreier_generator_ith_orbit pt2_coset=" << pt2_coset << endl;
1662 }
1663 if (pt2_coset < first) {
1664 cout << "schreier::random_schreier_generator_ith_orbit "
1665 "pt2_coset < first" << endl;
1666 exit(1);
1667 }
1668 if (pt2_coset >= first + len) {
1669 cout << "schreier::random_schreier_generator_ith_orbit "
1670 "pt2_coset >= first + len" << endl;
1671 exit(1);
1672 }
1673
1674 coset_rep_inv(pt2_coset, verbose_level - 1);
1675 // coset rep now in cosetrep
1676 if (f_vvv) {
1677 cout << "schreier::random_schreier_generator_ith_orbit cosetrep (inverse) " << pt2_coset << endl;
1679 if (A->degree < 100) {
1681 cout << endl;
1682 }
1683 }
1684
1686 if (A->element_image_of(pt, Elt, 0) != pt) {
1687 cout << "schreier::random_schreier_generator_ith_orbit "
1688 "fatal: schreier generator does not stabilize pt" << endl;
1689 exit(1);
1690 }
1691 if (f_vv) {
1692 cout << "schreier::random_schreier_generator_ith_orbit "
1693 "done" << endl;
1694 }
1695 if (f_vvv) {
1696 A->element_print_quick(Elt, cout);
1697 cout << endl;
1698 if (A->degree < 100) {
1699 A->element_print_as_permutation(Elt, cout);
1700 cout << endl;
1701 }
1702 }
1703 if (f_v) {
1704 cout << "schreier::random_schreier_generator_ith_orbit, "
1705 "orbit " << orbit_no << " done" << endl;
1706 }
1707}
1708
1709void schreier::random_schreier_generator(int *Elt, int verbose_level)
1710// computes random Schreier generator for the first orbit into Elt
1711{
1712 int f_v = (verbose_level >= 1);
1713 int f_vv = (verbose_level >= 2);
1714 int r1, r2, pt, pt2, pt2b, pt2_coset;
1715 int *gen;
1716 int pt1, pt1b;
1718
1719 if (f_v) {
1720 cout << "schreier::random_schreier_generator orbit_len = "
1721 << orbit_len[0] << " nb generators = "
1722 << gens.len << " in action " << A->label << endl;
1723 }
1724 if (f_images_only) {
1725 cout << "schreier::random_schreier_generator is not "
1726 "allowed if f_images_only is TRUE" << endl;
1727 exit(1);
1728 }
1729 pt = orbit[0];
1730 if (f_vv) {
1731 cout << "schreier::random_schreier_generator pt=" << pt << endl;
1732 }
1733
1734 // get a random coset:
1735 r1 = Os.random_integer(orbit_len[0]);
1736 pt1 = orbit[r1];
1737
1738 coset_rep(r1, verbose_level - 1);
1739 // coset rep now in cosetrep
1740 pt1b = A->element_image_of(pt, cosetrep, 0);
1741 if (f_vv) {
1742 cout << "schreier::random_schreier_generator random coset " << r1 << endl;
1743 cout << "schreier::random_schreier_generator pt1=" << pt1 << endl;
1744 cout << "schreier::random_schreier_generator cosetrep:" << endl;
1746 cout << "schreier::random_schreier_generator image of pt under cosetrep = " << pt1b << endl;
1747 }
1748 if (pt1b != pt1) {
1749 cout << "schreier::random_schreier_generator fatal: "
1750 "cosetrep does not work" << endl;
1751 cout << "pt=" << pt << endl;
1752 cout << "random coset " << r1 << endl;
1753 cout << "pt1=" << pt1 << endl;
1754 cout << "cosetrep:" << endl;
1756 cout << "image of pt under cosetrep = " << pt1b << endl;
1757 A->element_image_of(pt, cosetrep, 10);
1758 exit(1);
1759 }
1760
1761 // get a random generator:
1762 r2 = Os.random_integer(gens.len);
1763 gen = gens.ith(r2);
1764 if (f_vv) {
1765 cout << "schreier::random_schreier_generator random coset " << r1 << ", "
1766 "schreier::random_schreier_generator random generator " << r2 << endl;
1767 cout << "schreier::random_schreier_generator generator:" << endl;
1768 A->element_print_quick(gen, cout);
1769 cout << "schreier::random_schreier_generator image of pt1 under generator = pt2 = "
1770 << A->element_image_of(pt1, gen, 0) << endl;
1771 }
1772 pt2b = A->element_image_of(pt1, gen, 0);
1773
1775 if (f_vv) {
1776 cout << "schreier::random_schreier_generator cosetrep * gen=" << endl;
1778 }
1779 pt2 = A->element_image_of(pt, schreier_gen1, 0);
1780 if (f_vv) {
1781 cout << "schreier::random_schreier_generator image of pt under cosetrep*gen = " << pt2 << endl;
1782 }
1783 if (pt2 != pt2b) {
1784 cout << "schreier::random_schreier_generator "
1785 "something is wrong! " << endl;
1786 cout << "pt2=" << pt2 << " = image of pt "
1787 "under cosetrep * gen" << endl;
1788 cout << "pt2b=" << pt2b << " = image of pt1 "
1789 "under gen" << endl;
1790 cout << "cosetrep:" << endl;
1792 cout << "generator:" << endl;
1793 A->element_print_quick(gen, cout);
1794 cout << "cosetrep * gen=" << endl;
1796 cout << "pt=" << pt << endl;
1797 cout << "pt1=" << pt1 << endl;
1798 cout << "pt1b=" << pt1b << endl;
1799 cout << "pt2=" << pt2 << endl;
1800 cout << "pt2b=" << pt2b << endl;
1801
1802 cout << "repeat 1" << endl;
1803 cout << "repeating pt1b = A->element_image_of(pt, "
1804 "cosetrep, 0):" << endl;
1805 pt1b = A->element_image_of(pt, cosetrep, verbose_level + 3);
1806 cout << "pt1b = " << pt1b << endl;
1807
1808 cout << "repeat 2" << endl;
1809 cout << "repeating pt2b = A->element_image_of(pt1, "
1810 "gen, 0):" << endl;
1811 pt2b = A->element_image_of(pt1, gen, verbose_level + 3);
1812
1813 cout << "repeat 3" << endl;
1814 cout << "repeating pt2 = A->element_image_of(pt, "
1815 "schreier_gen1, 0):" << endl;
1816 pt2 = A->element_image_of(pt, schreier_gen1, verbose_level + 3);
1817
1818
1819 exit(1);
1820 }
1821 //cout << "maps " << pt << " to " << pt2 << endl;
1822 pt2_coset = orbit_inv[pt2];
1823
1824 coset_rep_inv(pt2_coset, verbose_level - 1);
1825 // coset rep now in cosetrep
1826 if (f_vv) {
1827 cout << "schreier::random_schreier_generator cosetrep:" << endl;
1829 cout << "schreier::random_schreier_generator image of pt2 under cosetrep = "
1830 << A->element_image_of(pt2, cosetrep, 0) << endl;
1831 }
1832
1834 if (f_vv) {
1835 cout << "schreier::random_schreier_generator Elt=cosetrep*gen*cosetrep:" << endl;
1836 A->element_print_quick(Elt, cout);
1837 cout << "schreier::random_schreier_generator image of pt under Elt = "
1838 << A->element_image_of(pt, Elt, 0) << endl;
1839 }
1840 int pt3;
1841 pt3 = A->element_image_of(pt, Elt, 0);
1842 if (pt3 != pt) {
1843 cout << "schreier::random_schreier_generator "
1844 "fatal: schreier generator does not stabilize pt" << endl;
1845 cout << "pt=" << pt << endl;
1846 cout << "pt image=" << pt3 << endl;
1847 cout << "r1=" << r1 << endl;
1848 cout << "pt1=" << pt1 << endl;
1849
1850 cout << "r2=" << r2 << endl;
1851 cout << "schreier::random_schreier_generator generator r2:" << endl;
1852 A->element_print_quick(gen, cout);
1853
1854 cout << "schreier::random_schreier_generator cosetrep * gen=" << endl;
1856
1857 cout << "pt2=" << pt2 << endl;
1858 cout << "pt2_coset=" << pt2_coset << endl;
1859
1860 cout << "schreier::random_schreier_generator coset_rep_inv=" << endl;
1862
1863 cout << "schreier::random_schreier_generator cosetrep * gen * coset_rep_inv=" << endl;
1864 A->element_print_quick(Elt, cout);
1865
1866
1867 cout << "schreier::random_schreier_generator recomputing original cosetrep" << endl;
1868 coset_rep(pt2_coset, verbose_level + 5);
1869 cout << "schreier::random_schreier_generator original cosetrep=" << endl;
1871
1872
1873 cout << "schreier::random_schreier_generator recomputing original cosetrep inverse" << endl;
1874 coset_rep_inv(pt2_coset, verbose_level + 5);
1875 cout << "schreier::random_schreier_generator original cosetrep_inv=" << endl;
1877
1878 cout << "redoing the multiplication, schreier_gen1 * cosetrep=" << endl;
1879 cout << "in action " << A->label << endl;
1881 A->element_print_quick(Elt, cout);
1882
1883
1884 exit(1);
1885 }
1886 if (FALSE) {
1887 cout << "schreier::random_schreier_generator random Schreier generator:" << endl;
1888 A->element_print(Elt, cout);
1889 cout << endl;
1890 }
1891 if (f_v) {
1892 cout << "schreier::random_schreier_generator done" << endl;
1893 }
1894}
1895
1896void schreier::trace_back(int *path, int i, int &j)
1897{
1898 int ii = orbit_inv[i];
1899
1900 if (prev[ii] == -1) {
1901 if (path) {
1902 path[0] = i;
1903 }
1904 j = 1;
1905 }
1906 else {
1907 trace_back(path, prev[ii], j);
1908 if (path) {
1909 path[j] = i;
1910 }
1911 j++;
1912 }
1913}
1914
1916 int len, int *intersection_cnt)
1917// intersection_cnt[nb_orbits]
1918{
1919 int i, pt, o;
1920
1921 for (i = 0; i < nb_orbits; i++) {
1922 intersection_cnt[i] = 0;
1923 }
1924 for (i = 0; i < len; i++) {
1925 pt = set[i];
1926 o = orbit_number(pt);
1927 intersection_cnt[o]++;
1928 }
1929}
1930
1932 int len, int *subset, int verbose_level)
1933{
1934 int i, p, j;
1935 int f_v = (verbose_level >= 1);
1936 //int f_vv = (verbose_level >= 2);
1937 int f_vvv = (verbose_level >= 3);
1938
1939 if (f_v) {
1940 cout << "schreier::orbits_on_invariant_subset_fast "
1941 "computing orbits on invariant subset "
1942 "of size " << len;
1943 if (f_images_only) {
1944 cout << " using images only" << endl;
1945 }
1946 else {
1947 cout << " in action " << A->label << endl;
1948 //A->print_info();
1949 }
1950 }
1951
1952 for (i = 0; i < len; i++) {
1953 p = subset[i];
1954 j = orbit_inv[p];
1955 if (j >= orbit_first[nb_orbits]) {
1956 if (f_vvv) {
1957 cout << "schreier::orbits_on_invariant_subset_fast computing orbit no " << nb_orbits << endl;
1958 }
1959 compute_point_orbit(p, 0);
1960 }
1961 }
1962#if 0
1963 if (orbit_first[nb_orbits] != len) {
1964 cout << "schreier::orbits_on_invariant_subset_"
1965 "fast orbit_first[nb_orbits] != len" << endl;
1966 cout << "orbit_first[nb_orbits] = "
1967 << orbit_first[nb_orbits] << endl;
1968 cout << "len = " << len << endl;
1969 cout << "subset:" << endl;
1970 int_vec_print(cout, subset, len);
1971 cout << endl;
1972 print_tables(cout, FALSE);
1973 exit(1);
1974 }
1975#endif
1976 if (f_v) {
1977 cout << "schreier::orbits_on_invariant_subset_fast "
1978 "found " << nb_orbits
1979 << " orbits on the invariant subset of size " << len << endl;
1980 }
1981}
1982
1984 int len, long int *subset, int verbose_level)
1985{
1986 int i, p, j;
1987 int f_v = (verbose_level >= 1);
1988 //int f_vv = (verbose_level >= 2);
1989 int f_vvv = (verbose_level >= 3);
1990
1991 if (f_v) {
1992 cout << "schreier::orbits_on_invariant_subset_fast_lint "
1993 "computing orbits on invariant subset "
1994 "of size " << len;
1995 if (f_images_only) {
1996 cout << " using images only" << endl;
1997 }
1998 else {
1999 cout << " in action " << A->label << endl;
2000 //A->print_info();
2001 }
2002 }
2003
2004 for (i = 0; i < len; i++) {
2005 p = subset[i];
2006 j = orbit_inv[p];
2007 if (j >= orbit_first[nb_orbits]) {
2008 if (f_vvv) {
2009 cout << "schreier::orbits_on_invariant_subset_fast_lint computing orbit no " << nb_orbits << endl;
2010 }
2011 compute_point_orbit(p, 0);
2012 }
2013 }
2014#if 0
2015 if (orbit_first[nb_orbits] != len) {
2016 cout << "schreier::orbits_on_invariant_subset_"
2017 "fast orbit_first[nb_orbits] != len" << endl;
2018 cout << "orbit_first[nb_orbits] = "
2019 << orbit_first[nb_orbits] << endl;
2020 cout << "len = " << len << endl;
2021 cout << "subset:" << endl;
2022 int_vec_print(cout, subset, len);
2023 cout << endl;
2024 print_tables(cout, FALSE);
2025 exit(1);
2026 }
2027#endif
2028 if (f_v) {
2029 cout << "schreier::orbits_on_invariant_subset_fast_lint "
2030 "found " << nb_orbits
2031 << " orbits on the invariant subset of size " << len << endl;
2032 }
2033}
2034
2035void schreier::orbits_on_invariant_subset(int len, int *subset,
2036 int &nb_orbits_on_subset,
2037 int *&orbit_perm, int *&orbit_perm_inv)
2038{
2039 int i, j, a, pos;
2040
2042 nb_orbits_on_subset = 0;
2043 orbit_perm = NEW_int(nb_orbits);
2044 orbit_perm_inv = NEW_int(nb_orbits);
2045 for (i = 0; i < nb_orbits; i++) {
2046 orbit_perm_inv[i] = -1;
2047 }
2048 for (i = 0; i < nb_orbits; i++) {
2049 j = orbit_first[i];
2050 a = orbit[j];
2051 for (pos = 0; pos < len; pos++) {
2052 if (subset[pos] == a) {
2053 orbit_perm[nb_orbits_on_subset] = i;
2054 orbit_perm_inv[i] = nb_orbits_on_subset;
2055 nb_orbits_on_subset++;
2056 break;
2057 }
2058 }
2059 }
2060 j = nb_orbits_on_subset;
2061 for (i = 0; i < nb_orbits; i++) {
2062 if (orbit_perm_inv[i] == -1) {
2063 orbit_perm[j] = i;
2064 orbit_perm_inv[i] = j;
2065 j++;
2066 }
2067 }
2068}
2069
2071 data_structures::partitionstack &S, int verbose_level)
2072{
2073 int first_column_element, pos, first_column_orbit, i, j, f, l, a;
2074 int f_v = (verbose_level >= 1);
2075
2076 if (f_v) {
2077 cout << "schreier::get_orbit_partition_"
2078 "of_points_and_lines" << endl;
2079 }
2080 first_column_element = S.startCell[1];
2081 if (f_v) {
2082 cout << "first_column_element = "
2083 << first_column_element << endl;
2084 }
2085 pos = orbit_inv[first_column_element];
2086 first_column_orbit = orbit_number(first_column_element);
2087
2088 for (i = first_column_orbit - 1; i > 0; i--) {
2089 f = orbit_first[i];
2090 l = orbit_len[i];
2091 for (j = 0; j < l; j++) {
2092 pos = f + j;
2093 a = orbit[pos];
2094 S.subset[j] = a;
2095 }
2096 S.subset_size = l;
2097 S.split_cell(FALSE);
2098 }
2099 for (i = nb_orbits - 1; i > first_column_orbit; i--) {
2100 f = orbit_first[i];
2101 l = orbit_len[i];
2102 for (j = 0; j < l; j++) {
2103 pos = f + j;
2104 a = orbit[pos];
2105 S.subset[j] = a;
2106 }
2107 S.subset_size = l;
2108 S.split_cell(FALSE);
2109 }
2110}
2111
2113 int verbose_level)
2114{
2115 int pos, i, j, f, l, a;
2116 int f_v = (verbose_level >= 1);
2117
2118 if (f_v) {
2119 cout << "schreier::get_orbit_partition" << endl;
2120 }
2121 for (i = nb_orbits - 1; i > 0; i--) {
2122 f = orbit_first[i];
2123 l = orbit_len[i];
2124 for (j = 0; j < l; j++) {
2125 pos = f + j;
2126 a = orbit[pos];
2127 S.subset[j] = a;
2128 }
2129 S.subset_size = l;
2130 S.split_cell(FALSE);
2131 }
2132}
2133
2134void schreier::get_orbit_in_order(std::vector<int> &Orb,
2135 int orbit_idx, int verbose_level)
2136{
2137 int f, l, j, a, pos;
2138
2139 f = orbit_first[orbit_idx];
2140 l = orbit_len[orbit_idx];
2141 for (j = 0; j < l; j++) {
2142 pos = f + j;
2143 a = orbit[pos];
2144 Orb.push_back(a);
2145 }
2146}
2147
2149 actions::action *default_action,
2150 ring_theory::longinteger_object &full_group_order,
2151 int pt, data_structures_groups::vector_ge *&cosets,
2152 int verbose_level)
2153{
2154 int f_v = (verbose_level >= 1);
2155 strong_generators *gens0;
2157 int orbit_index;
2158 int orbit_index1;
2159 int *transporter;
2160 int *transporter1;
2161 int i, fst, len;
2162
2163 if (f_v) {
2164 cout << "schreier::stabilizer_any_point_plus_cosets" << endl;
2165 }
2166 if (f_images_only) {
2167 cout << "schreier::stabilizer_any_point_plus_cosets is not "
2168 "allowed if f_images_only is TRUE" << endl;
2169 exit(1);
2170 }
2171
2173 cosets->init(A, verbose_level - 2);
2174 transporter = NEW_int(A->elt_size_in_int);
2175 transporter1 = NEW_int(A->elt_size_in_int);
2176
2177 orbit_index = orbit_number(pt);
2178
2179 gens0 = stabilizer_orbit_rep(default_action,
2180 full_group_order, orbit_index, 0 /* verbose_level */);
2181
2182 fst = orbit_first[orbit_index];
2183 len = orbit_len[orbit_index];
2184 cosets->allocate(len, verbose_level - 2);
2185
2187 orbit_index1, transporter, 0 /* verbose_level */);
2188
2189 if (orbit_index1 != orbit_index) {
2190 cout << "schreier::stabilizer_any_point_plus_cosets "
2191 "orbit_index1 != orbit_index" << endl;
2192 exit(1);
2193 }
2194
2196
2197
2198 if (f_v) {
2199 cout << "schreier::stabilizer_any_point_plus_cosets before "
2200 "gens->init_generators_for_the_conjugate_group_aGav" << endl;
2201 }
2202 gens->init_generators_for_the_conjugate_group_aGav(gens0,
2203 transporter, verbose_level);
2204 if (f_v) {
2205 cout << "schreier::stabilizer_any_point_plus_cosets after "
2206 "gens->init_generators_for_the_conjugate_group_aGav" << endl;
2207 }
2208
2209 if (f_v) {
2210 cout << "schreier::stabilizer_any_point_plus_cosets computing "
2211 "coset representatives" << endl;
2212 }
2213 for (i = 0; i < len; i++) {
2215 orbit_index1, transporter1, 0 /* verbose_level */);
2216 A->element_mult(transporter, transporter1, cosets->ith(i), 0);
2217 }
2218 if (f_v) {
2219 cout << "schreier::stabilizer_any_point_plus_cosets computing "
2220 "coset representatives done" << endl;
2221 }
2222
2223 FREE_int(transporter);
2224 FREE_int(transporter1);
2225
2226 if (f_v) {
2227 cout << "schreier::stabilizer_any_point_plus_cosets done" << endl;
2228 }
2229 FREE_OBJECT(gens0);
2230 return gens;
2231}
2232
2234 actions::action *default_action,
2235 ring_theory::longinteger_object &full_group_order, int pt,
2236 int verbose_level)
2237{
2238 int f_v = (verbose_level >= 1);
2239 strong_generators *gens0;
2241 int orbit_index;
2242 int orbit_index1;
2243 int *transporter;
2244
2245 if (f_v) {
2246 cout << "schreier::stabilizer_any_point" << endl;
2247 }
2248 if (f_images_only) {
2249 cout << "schreier::stabilizer_any_point is not "
2250 "allowed if f_images_only is TRUE" << endl;
2251 exit(1);
2252 }
2253
2254 transporter = NEW_int(A->elt_size_in_int);
2255
2256 orbit_index = orbit_number(pt);
2257
2258 gens0 = stabilizer_orbit_rep(default_action,
2259 full_group_order, orbit_index, 0 /* verbose_level */);
2260
2262 orbit_index1, transporter, 0 /* verbose_level */);
2263
2264 if (orbit_index1 != orbit_index) {
2265 cout << "schreier::stabilizer_any_point "
2266 "orbit_index1 != orbit_index" << endl;
2267 exit(1);
2268 }
2269
2271
2272
2273 if (f_v) {
2274 cout << "schreier::stabilizer_any_point "
2275 "before gens->init_generators_"
2276 "for_the_conjugate_group_aGav" << endl;
2277 }
2278 gens->init_generators_for_the_conjugate_group_aGav(gens0,
2279 transporter, verbose_level);
2280 if (f_v) {
2281 cout << "schreier::stabilizer_any_point "
2282 "after gens->init_generators_"
2283 "for_the_conjugate_group_aGav" << endl;
2284 }
2285
2286 FREE_int(transporter);
2287
2288 if (f_v) {
2289 cout << "schreier::stabilizer_any_point done" << endl;
2290 }
2291 FREE_OBJECT(gens0);
2292 return gens;
2293}
2294
2295
2297 ring_theory::longinteger_object &full_group_order,
2298 int orbit_idx, int verbose_level)
2299{
2302 long int *Set;
2303
2304 if (f_images_only) {
2305 cout << "schreier::get_orbit_rep is not "
2306 "allowed if f_images_only is TRUE" << endl;
2307 exit(1);
2308 }
2310 SG = stabilizer_orbit_rep(default_action,
2311 full_group_order, orbit_idx, verbose_level);
2312 Set = NEW_lint(1);
2313 Set[0] = orbit[orbit_first[orbit_idx]];
2314 SaS->init_everything(default_action, A, Set, 1 /* set_sz */,
2315 SG, verbose_level);
2316 return SaS;
2317}
2318
2320 ring_theory::longinteger_object &full_group_order,
2321 int orbit_idx,
2323 int verbose_level)
2324{
2325 //set_and_stabilizer *SaS;
2327 long int *Set;
2328
2329 if (f_images_only) {
2330 cout << "schreier::get_orbit_rep is not "
2331 "allowed if f_images_only is TRUE" << endl;
2332 exit(1);
2333 }
2334 //SaS = NEW_OBJECT(set_and_stabilizer);
2335 SG = stabilizer_orbit_rep(default_action,
2336 full_group_order, orbit_idx, verbose_level);
2337 Set = NEW_lint(1);
2338 Set[0] = orbit[orbit_first[orbit_idx]];
2339 Rep->init_everything(default_action, A, Set, 1 /* set_sz */,
2340 SG, verbose_level);
2341 //return SaS;
2342}
2343
2344
2346 actions::action *default_action,
2347 ring_theory::longinteger_object &full_group_order, int orbit_idx,
2348 int verbose_level)
2349{
2350 int f_v = (verbose_level >= 1);
2352 sims *Stab;
2353
2354 if (f_v) {
2355 cout << "schreier::stabilizer_orbit_rep" << endl;
2356 cout << "default_action=" << default_action->label << endl;
2357 }
2358 if (f_images_only) {
2359 cout << "schreier::stabilizer_orbit_rep is not "
2360 "allowed if f_images_only is TRUE" << endl;
2361 exit(1);
2362 }
2363
2364
2365 point_stabilizer(default_action, full_group_order,
2366 Stab, orbit_idx, verbose_level);
2367
2369
2370 Stab->group_order(stab_order);
2371 if (f_v) {
2372 cout << "schreier::stabilizer_orbit_rep "
2373 "found a stabilizer group "
2374 "of order " << stab_order << endl;
2375 }
2376
2378 gens->init(A);
2379 gens->init_from_sims(Stab, verbose_level);
2380
2381 FREE_OBJECT(Stab);
2382 if (f_v) {
2383 cout << "schreier::stabilizer_orbit_rep done" << endl;
2384 }
2385 return gens;
2386}
2387
2390 groups::sims *&Stab, int orbit_no,
2391 int verbose_level)
2392// this function allocates a sims structure into Stab.
2393{
2394 ring_theory::longinteger_object cur_go, target_go;
2396 int len, r, cnt = 0, f_added, drop_out_level, image;
2397 int *residue;
2398 int f_v = (verbose_level >= 1);
2399 int f_vv = (verbose_level >= 2);
2400 int f_vvv = (verbose_level >= 3);
2401 int f_v4 = (verbose_level >= 4);
2402 int *Elt;
2403 int *Elt1;
2404
2405
2406 if (f_v) {
2407 cout << "schreier::point_stabilizer" << endl;
2408 cout << "default_action=" << default_action->label << endl;
2409 cout << "default_action->elt_size_in_int=" << default_action->elt_size_in_int << endl;
2410 }
2411 if (f_images_only) {
2412 cout << "schreier::point_stabilizer is not "
2413 "allowed if f_images_only is TRUE" << endl;
2414 exit(1);
2415 }
2416
2417 Elt = NEW_int(default_action->elt_size_in_int);
2419
2420 // the schreier generator must be computed in the action
2421 // attached to the this instance of the schreier class
2422 // the assumption is that this could be a longer representation,
2423 // and that the representation of the element in default_action
2424 // is at the beginning of the longer representation.
2425 // This is true for permutation_representation.
2426
2427
2428 residue = NEW_int(default_action->elt_size_in_int);
2429
2430 Stab = NEW_OBJECT(sims);
2431
2432 if (f_v) {
2433 cout << "schreier::point_stabilizer "
2434 "computing stabilizer of representative of orbit "
2435 << orbit_no << " inside a group of "
2436 "order " << go << " in action ";
2437 default_action->print_info();
2438 cout << endl;
2439 }
2440 len = orbit_len[orbit_no];
2441 D.integral_division_by_int(go, len, target_go, r);
2442 if (r) {
2443 cout << "schreier::point_stabilizer orbit length does not divide group order" << endl;
2444 exit(1);
2445 }
2446 if (f_vv) {
2447 cout << "schreier::point_stabilizer expecting group of order " << target_go << endl;
2448 }
2449
2450 if (f_vv) {
2451 cout << "schreier::point_stabilizer before Stab->init" << endl;
2452 }
2453 Stab->init(default_action, verbose_level);
2454 if (f_vv) {
2455 cout << "schreier::point_stabilizer after Stab->init" << endl;
2456 }
2457 if (f_vv) {
2458 cout << "schreier::point_stabilizer before Stab->init_trivial_group" << endl;
2459 }
2460 Stab->init_trivial_group(verbose_level - 1);
2461 if (f_vv) {
2462 cout << "schreier::point_stabilizer after Stab->init_trivial_group" << endl;
2463 }
2464
2465
2466 if (f_vv) {
2467 cout << "schreier::point_stabilizer Stab->my_base_len=" << Stab->my_base_len << endl;
2468 }
2469
2470 while (TRUE) {
2471
2472 if (f_vv) {
2473 cout << "schreier::point_stabilizer cnt=" << cnt << endl;
2474 }
2475 if (f_vv) {
2476 cout << "schreier::point_stabilizer Stab->my_base_len=" << Stab->my_base_len << endl;
2477 }
2478
2479 Stab->group_order(cur_go);
2480 if (D.compare(cur_go, target_go) == 0) {
2481 break;
2482 }
2483 if (cnt % 2 || Stab->nb_gen[0] == 0) {
2484 if (f_vv) {
2485 cout << "schreier::point_stabilizer "
2486 "before random_schreier_generator_ith_orbit" << endl;
2487 cout << "schreier::point_stabilizer Stab->my_base_len=" << Stab->my_base_len << endl;
2488 }
2490 verbose_level - 5);
2491
2492 // this creates a schreier generator in action A,
2493 // not in default_action
2494
2495
2496 if (f_vv) {
2497 cout << "schreier::point_stabilizer "
2498 "after random_schreier_generator_ith_orbit" << endl;
2499 cout << "schreier::point_stabilizer Stab->my_base_len=" << Stab->my_base_len << endl;
2500 }
2501
2502 // and now we copy over the part of Elt1 that belongs to default_action:
2503
2504 default_action->element_move(Elt1, Elt, 0);
2505
2506
2507 if (f_vvv) {
2508 cout << "schreier::point_stabilizer "
2509 "random Schreier generator from the orbit:" << endl;
2510 default_action->element_print_quick(Elt, cout);
2511 }
2512 }
2513 else {
2514 if (f_vv) {
2515 cout << "schreier::point_stabilizer "
2516 "before Stab->random_schreier_generator" << endl;
2517 cout << "schreier::point_stabilizer Stab->my_base_len=" << Stab->my_base_len << endl;
2518 }
2519 Stab->random_schreier_generator(Elt, verbose_level - 5);
2520 if (f_vv) {
2521 cout << "schreier::point_stabilizer "
2522 "after Stab->random_schreier_generator" << endl;
2523 cout << "schreier::point_stabilizer Stab->my_base_len=" << Stab->my_base_len << endl;
2524 }
2525 if (f_v4) {
2526 cout << "schreier::point_stabilizer "
2527 "random schreier generator from sims:" << endl;
2528 default_action->element_print_quick(Elt, cout);
2529 }
2530 }
2531
2532
2533
2534 if (f_vv) {
2535 cout << "schreier::point_stabilizer before Stab->strip" << endl;
2536 }
2537 if (f_vv) {
2538 cout << "schreier::point_stabilizer Stab->my_base_len=" << Stab->my_base_len << endl;
2539 }
2540 if (Stab->strip(Elt, residue,
2541 drop_out_level, image, verbose_level - 5)) {
2542 if (f_vv) {
2543 cout << "schreier::point_stabilizer "
2544 "element strips through" << endl;
2545 if (f_v4) {
2546 cout << "schreier::point_stabilizer residue:" << endl;
2547 A->element_print_quick(residue, cout);
2548 cout << endl;
2549 }
2550 }
2551 f_added = FALSE;
2552 }
2553 else {
2554 f_added = TRUE;
2555 if (f_vv) {
2556 cout << "schreier::point_stabilizer "
2557 "element needs to be inserted at level = "
2558 << drop_out_level << " with image " << image << endl;
2559 if (FALSE) {
2560 A->element_print_quick(residue, cout);
2561 cout << endl;
2562 }
2563 }
2564 if (f_vv) {
2565 cout << "schreier::point_stabilizer "
2566 "before Stab->add_generator_at_level, drop_out_level=" << drop_out_level << endl;
2567 }
2568 Stab->add_generator_at_level(residue,
2569 drop_out_level, verbose_level - 1);
2570 if (f_vv) {
2571 cout << "schreier::point_stabilizer "
2572 "after Stab->add_generator_at_level, drop_out_level=" << drop_out_level << endl;
2573 }
2574 }
2575 if (f_vv) {
2576 cout << "schreier::point_stabilizer "
2577 "before Stab->group_order" << endl;
2578 }
2579 Stab->group_order_verbose(cur_go, verbose_level);
2580
2581 if ((f_vv && f_added) || f_vvv) {
2582 cout << "schreier::point_stabilizer "
2583 "iteration " << cnt
2584 << " the n e w group order is " << cur_go
2585 << " expecting a group of order "
2586 << target_go << endl;
2587 }
2588 cnt++;
2589 }
2590 FREE_int(Elt);
2591 FREE_int(Elt1);
2592 FREE_int(residue);
2593 if (f_v) {
2594 cout << "schreier::point_stabilizer finished" << endl;
2595 }
2596}
2597
2598void schreier::get_orbit(int orbit_idx, long int *set, int &len,
2599 int verbose_level)
2600{
2601 int f, i;
2602
2603 f = orbit_first[orbit_idx];
2604 len = orbit_len[orbit_idx];
2605 for (i = 0; i < len; i++) {
2606 set[i] = orbit[f + i];
2607 }
2608}
2609
2610void schreier::compute_orbit_statistic(int *set, int set_size,
2611 int *orbit_count, int verbose_level)
2612// orbit_count[nb_orbits]
2613{
2614 int f_v = (verbose_level >= 1);
2615 int i, a, o;
2616
2617 if (f_v) {
2618 cout << "schreier::compute_orbit_statistic" << endl;
2619 }
2620 Int_vec_zero(orbit_count, nb_orbits);
2621 for (i = 0; i < set_size; i++) {
2622 a = set[i];
2623 o = orbit_number(a);
2624 orbit_count[o]++;
2625 }
2626 if (f_v) {
2627 cout << "schreier::compute_orbit_statistic done" << endl;
2628 }
2629}
2630
2631void schreier::compute_orbit_statistic_lint(long int *set, int set_size,
2632 int *orbit_count, int verbose_level)
2633// orbit_count[nb_orbits]
2634{
2635 int f_v = (verbose_level >= 1);
2636 int i, a, o;
2637
2638 if (f_v) {
2639 cout << "schreier::compute_orbit_statistic_lint" << endl;
2640 }
2641 Int_vec_zero(orbit_count, nb_orbits);
2642 for (i = 0; i < set_size; i++) {
2643 a = set[i];
2644 o = orbit_number(a);
2645 orbit_count[o]++;
2646 }
2647 if (f_v) {
2648 cout << "schreier::compute_orbit_statistic_lint done" << endl;
2649 }
2650}
2651
2652
2654 data_structures::set_of_sets *&S, int verbose_level)
2655{
2656 int f_v = (verbose_level >= 1);
2657 int *Sz;
2658 int i, j, a, f, l;
2659
2660 if (f_v) {
2661 cout << "schreier::orbits_as_set_of_sets" << endl;
2662 }
2664 Sz = NEW_int(nb_orbits);
2665 for (i = 0; i < nb_orbits; i++) {
2666 l = orbit_len[i];
2667 Sz[i] = l;
2668 }
2669
2670 S->init_basic_with_Sz_in_int(degree /* underlying_set_size */,
2671 nb_orbits, Sz, 0 /* verbose_level */);
2672 for (i = 0; i < nb_orbits; i++) {
2673 f = orbit_first[i];
2674 l = orbit_len[i];
2675 for (j = 0; j < l; j++) {
2676 a = orbit[f + j];
2677 S->Sets[i][j] = a;
2678 }
2679 }
2680 FREE_int(Sz);
2681 if (f_v) {
2682 cout << "schreier::orbits_as_set_of_sets done" << endl;
2683 }
2684}
2685
2687 int &nb_reps, int verbose_level)
2688{
2689 int f_v = (verbose_level >= 1);
2690 int i, a, f;
2691
2692 if (f_v) {
2693 cout << "schreier::get_orbit_reps" << endl;
2694 }
2695 nb_reps = nb_orbits;
2696 Reps = NEW_int(nb_reps);
2697 for (i = 0; i < nb_reps; i++) {
2698 f = orbit_first[i];
2699 a = orbit[f];
2700 Reps[i] = a;
2701 }
2702 if (f_v) {
2703 cout << "schreier::get_orbit_reps done" << endl;
2704 }
2705}
2706
2708{
2709 int l_min = 0, l, i;
2710 int idx_min = -1;
2711 int f_is_unique = TRUE;
2712
2713 for (i = 0; i < nb_orbits; i++) {
2714 l = orbit_len[i];
2715 if (idx_min == -1) {
2716 l_min = l;
2717 idx_min = i;
2718 f_is_unique = TRUE;
2719 }
2720 else if (l < l_min) {
2721 l_min = l;
2722 idx_min = i;
2723 f_is_unique = TRUE;
2724 }
2725 else if (l_min == l) {
2726 f_is_unique = FALSE;
2727 }
2728 }
2729 idx = idx_min;
2730 return f_is_unique;
2731}
2732
2734 int *orb, int &nb, int verbose_level)
2735{
2736 int f_v = (verbose_level >= 1);
2737 int idx, f;
2738
2739 if (f_v) {
2740 cout << "schreier::elements_in_orbit_of" << endl;
2741 }
2742 idx = orbit_number(pt);
2743 f = orbit_first[idx];
2744 nb = orbit_len[idx];
2745 Int_vec_copy(orbit + f, orb, nb);
2746 if (f_v) {
2747 cout << "schreier::elements_in_orbit_of done" << endl;
2748 }
2749}
2750
2751void schreier::get_orbit_length(int *&orbit_length, int verbose_level)
2752{
2753 int f_v = (verbose_level >= 1);
2754 int I, f, l, h, a;
2755
2756 if (f_v) {
2757 cout << "schreier::get_orbit_length" << endl;
2758 }
2759 orbit_length = NEW_int(A->degree);
2760 for (I = 0; I < nb_orbits; I++) {
2761 f = orbit_first[I];
2762 l = orbit_len[I];
2763 for (h = 0; h < l; h++) {
2764 a = orbit[f + h];
2765 orbit_length[a] = l;
2766 }
2767 }
2768 if (f_v) {
2769 cout << "schreier::get_orbit_length done" << endl;
2770 }
2771}
2772
2774 int *&orbit_lengths, int &nb_orbit_lengths)
2775{
2776 int *val, *mult, len;
2777
2779 //int_distribution_print(ost, val, mult, len);
2780 //ost << endl;
2781
2782 nb_orbit_lengths = len;
2783
2784 orbit_lengths = NEW_int(nb_orbit_lengths);
2785
2786 Int_vec_copy(val, orbit_lengths, nb_orbit_lengths);
2787
2788 FREE_int(val);
2789 FREE_int(mult);
2790}
2791
2792
2794{
2795 int pos;
2796 int idx;
2798
2799 pos = orbit_inv[pt];
2800 if (Sorting.int_vec_search(orbit_first, nb_orbits, pos, idx)) {
2801 ;
2802 }
2803 else {
2804 if (idx == 0) {
2805 cout << "schreier::orbit_number idx == 0" << endl;
2806 exit(1);
2807 }
2808 idx--;
2809 }
2810 if (orbit_first[idx] <= pos &&
2811 pos < orbit_first[idx] + orbit_len[idx]) {
2812 return idx;
2813 }
2814 else {
2815 cout << "schreier::orbit_number something is wrong, "
2816 "perhaps the orbit of the point has not yet "
2817 "been computed" << endl;
2818 exit(1);
2819 }
2820}
2821
2822void schreier::get_orbit_number_and_position(int pt, int &orbit_idx, int &orbit_pos, int verbose_level)
2823{
2824 int f_v = (verbose_level >= 1);
2825 int pos;
2827
2828 if (f_v) {
2829 cout << "schreier::get_orbit_number_and_position" << endl;
2830 }
2831 pos = orbit_inv[pt];
2832 if (Sorting.int_vec_search(orbit_first, nb_orbits, pos, orbit_idx)) {
2833 ;
2834 }
2835 else {
2836 if (orbit_idx == 0) {
2837 cout << "schreier::get_orbit_number_and_position orbit_idx == 0" << endl;
2838 exit(1);
2839 }
2840 orbit_idx--;
2841 }
2842 if (orbit_first[orbit_idx] <= pos &&
2843 pos < orbit_first[orbit_idx] + orbit_len[orbit_idx]) {
2844 orbit_pos = pos - orbit_first[orbit_idx];
2845 }
2846 else {
2847 cout << "schreier::get_orbit_number_and_position something is wrong, "
2848 "perhaps the orbit of the point has not yet "
2849 "been computed" << endl;
2850 exit(1);
2851 }
2852 if (f_v) {
2853 cout << "schreier::get_orbit_number_and_position done" << endl;
2854 }
2855}
2856
2857
2859 int *Adj, int n, int *&Decomp_scheme,
2860 int verbose_level)
2861{
2862 int f_v = (verbose_level >= 1);
2863 int I, J;
2864 int f1, l1;
2865 int f2, l2;
2866 int i, j, r, r0, a, b;
2867
2868 if (f_v) {
2869 cout << "schreier::get_orbit_decomposition_"
2870 "scheme_of_graph" << endl;
2871 }
2872 Decomp_scheme = NEW_int(nb_orbits * nb_orbits);
2873 Int_vec_zero(Decomp_scheme, nb_orbits * nb_orbits);
2874 for (I = 0; I < nb_orbits; I++) {
2875 f1 = orbit_first[I];
2876 l1 = orbit_len[I];
2877 if (FALSE) {
2878 cout << "I = " << I << " f1 = " << f1
2879 << " l1 = " << l1 << endl;
2880 }
2881 for (J = 0; J < nb_orbits; J++) {
2882 r0 = 0;
2883 f2 = orbit_first[J];
2884 l2 = orbit_len[J];
2885 if (FALSE) {
2886 cout << "J = " << J << " f2 = " << f2
2887 << " l2 = " << l2 << endl;
2888 }
2889 for (i = 0; i < l1; i++) {
2890 a = orbit[f1 + i];
2891 r = 0;
2892 for (j = 0; j < l2; j++) {
2893 b = orbit[f2 + j];
2894 if (Adj[a * n + b]) {
2895 r++;
2896 }
2897 }
2898 if (i == 0) {
2899 r0 = r;
2900 }
2901 else {
2902 if (r0 != r) {
2903 cout << "schreier::get_orbit_decomposition_"
2904 "scheme_of_graph not tactical" << endl;
2905 cout << "I=" << I << endl;
2906 cout << "J=" << J << endl;
2907 cout << "r0=" << r0 << endl;
2908 cout << "r=" << r << endl;
2909 exit(1);
2910 }
2911 }
2912 }
2913 if (FALSE) {
2914 cout << "I = " << I << " J = " << J << " r = " << r0 << endl;
2915 }
2916 Decomp_scheme[I * nb_orbits + J] = r0;
2917 }
2918 }
2919 if (f_v) {
2920 cout << "Decomp_scheme = " << endl;
2921 Int_matrix_print(Decomp_scheme, nb_orbits, nb_orbits);
2922 }
2923 if (f_v) {
2924 cout << "schreier::get_orbit_decomposition_"
2925 "scheme_of_graph done" << endl;
2926 }
2927}
2928
2929
2930
2932 int *&point_list, int &point_list_length)
2933{
2934 int i, j, k, f, l, ff, p;
2936
2937 point_list_length = 0;
2938 for (k = 0; k < nb_orbits; k++) {
2939 point_list_length += orbit_len[k];
2940 }
2941 point_list = NEW_int(point_list_length);
2942
2943 ff = 0;
2944 for (k = 0; k < nb_orbits; k++) {
2945 f = orbit_first[k];
2946 l = orbit_len[k];
2947 for (j = 0; j < l; j++) {
2948 i = f + j;
2949 p = orbit[i];
2950 point_list[ff + j] = p;
2951 }
2952 ff += l;
2953 }
2954 if (ff != point_list_length) {
2955 cout << "schreier::get_schreier_vector_compact "
2956 "ff != point_list_length" << endl;
2957 exit(1);
2958 }
2959 Sorting.int_vec_heapsort(point_list, point_list_length);
2960}
2961
2963 int f_randomized,
2964 schreier *&shallow_tree,
2965 int verbose_level)
2966{
2967 int f_v = (verbose_level >= 1);
2968 int fst, len, root, cnt, l;
2969 int i, j, a, f, o;
2970 int *Elt1, *Elt2;
2971 int *candidates;
2972 int nb_candidates;
2974
2975 if (f_v) {
2976 cout << "schreier::shallow_tree_generators " << endl;
2977 cout << "computing shallow tree for orbit " << orbit_idx
2978 << " in action " << A->label << endl;
2979 }
2980 fst = orbit_first[orbit_idx];
2981 len = orbit_len[orbit_idx];
2982 root = orbit[fst];
2983
2985
2986 candidates = NEW_int(len);
2987
2990
2992
2993 gens->init(A, verbose_level - 2);
2994 cnt = 0;
2995 while (TRUE) {
2996 if (f_v) {
2997 cout << "schreier::shallow_tree_generators "
2998 "iteration " << cnt << ":" << endl;
2999 }
3000 schreier *S;
3001
3002 S = NEW_OBJECT(schreier);
3003 S->init(A, verbose_level - 2);
3004 S->init_generators(*gens, verbose_level - 2);
3005 if (f_v) {
3006 cout << "schreier::shallow_tree_generators "
3007 "iteration " << cnt
3008 << " before compute_point_orbit:" << endl;
3009 }
3011 gens->len, 0 /*verbose_level*/);
3012 //S->compute_point_orbit(root, 0 /*verbose_level*/);
3013 l = S->orbit_len[0];
3014 if (f_v) {
3015 cout << "schreier::shallow_tree_generators "
3016 "iteration " << cnt
3017 << " after compute_point_orbit, "
3018 "found an orbit of length " << l << endl;
3019 }
3020 if (l == len) {
3021 shallow_tree = S;
3022 break;
3023 }
3024
3025 // find an element that belongs to the original orbit
3026 // (i.e., the bad Schreier tree) but not
3027 // to the new orbit (the good Schreier tree).
3028 // When l < len, such an element must exist.
3029 nb_candidates = 0;
3030 f = S->orbit_first[0];
3031 for (i = 0; i < len; i++) {
3032 a = orbit[fst + i];
3033 j = S->orbit_inv[a];
3034 if (j >= f + l) {
3035 candidates[nb_candidates++] = a;
3036 }
3037 }
3038
3039 if (nb_candidates == 0) {
3040 cout << "schreier::shallow_tree_generators "
3041 "did not find element in orbit" << endl;
3042 exit(1);
3043 }
3044 if (f_v) {
3045 cout << "schreier::shallow_tree_generators "
3046 "found " << nb_candidates
3047 << " candidates of points outside the orbit" << endl;
3048 }
3049 if (f_randomized) {
3050 j = Os.random_integer(nb_candidates);
3051 }
3052 else {
3053 j = 0;
3054 }
3055
3056 if (f_v) {
3057 cout << "schreier::shallow_tree_generators "
3058 "picking random candidate " << j << " / "
3059 << nb_candidates << endl;
3060 }
3061 a = candidates[j];
3062 if (f_v) {
3063 cout << "schreier::shallow_tree_generators "
3064 "found point " << a << " outside of orbit" << endl;
3065 }
3066 // our next generator will be the transporter from
3067 // the root node to the node we just found in the
3068 // old (bad) Schreier tree:
3070 o, Elt1, 0 /*verbose_level*/);
3071 if (f_v) {
3072 cout << "schreier::shallow_tree_generators "
3073 "new generator is:" << endl;
3074 A->element_print_quick(Elt1, cout);
3075 int o;
3076
3077 o = A->element_order(Elt1);
3078 cout << "The order of the element is: " << o << endl;
3079 }
3080 A->element_invert(Elt1, Elt2, 0);
3081 // append the generator and its inverse to the generating set:
3082 gens->append(Elt1, verbose_level - 2);
3083 gens->append(Elt2, verbose_level - 2);
3084 FREE_OBJECT(S);
3085 cnt++;
3086
3087 }
3088 if (f_v) {
3089 cout << "schreier::shallow_tree_generators cnt=" << cnt
3090 << " number of generators=" << gens->len << endl;
3091 cout << "done" << endl;
3092 }
3093
3094 FREE_int(candidates);
3096 FREE_int(Elt1);
3097 FREE_int(Elt2);
3098
3099 if (f_v) {
3100 cout << "schreier::shallow_tree_generators " << endl;
3101 cout << "done" << endl;
3102 }
3103}
3104
3105#if 0
3106schreier_vector *schreier::get_schreier_vector(
3107 int gen_hdl_first, int nb_gen, int verbose_level)
3108{
3109 int f_v = (verbose_level >= 1);
3110
3111 if (f_v) {
3112 cout << "schreier::get_schreier_vector" << endl;
3113 }
3114 //int *sv;
3115 schreier_vector * Schreier_vector;
3116 int f_trivial_group = FALSE;
3117
3118 if (nb_gen == 0) {
3119 f_trivial_group = TRUE;
3120 }
3121
3122 Schreier_vector = NEW_OBJECT(schreier_vector);
3123 //get_schreier_vector_compact(sv, f_trivial_group);
3124 Schreier_vector->init(gen_hdl_first, nb_gen, NULL, verbose_level - 1);
3125
3126#if 1
3127 Schreier_vector->init_from_schreier(this,
3128 f_trivial_group, verbose_level);
3129#else
3130 Schreier_vector->init_shallow_schreier_forest(this,
3131 f_trivial_group, verbose_level);
3132#endif
3133
3134 if (nb_gen) {
3135 Schreier_vector->init_local_generators(
3136 &gens,
3137 0 /*verbose_level */);
3138 }
3139
3140 if (f_v) {
3141 cout << "schreier::get_schreier_vector done" << endl;
3142 }
3143 return Schreier_vector;
3144}
3145#else
3147 int gen_hdl_first, int nb_gen,
3148 enum shallow_schreier_tree_strategy Shallow_schreier_tree_strategy,
3149 int verbose_level)
3150{
3151 int f_v = (verbose_level >= 1);
3152
3153 if (f_v) {
3154 cout << "schreier::get_schreier_vector" << endl;
3155 }
3156//int *sv;
3158 int f_trivial_group = FALSE;
3159
3160 if (nb_gen == 0) {
3161 f_trivial_group = TRUE;
3162 }
3163
3165 //get_schreier_vector_compact(sv, f_trivial_group);
3166 Schreier_vector->init(gen_hdl_first, nb_gen, NULL, verbose_level - 1);
3167
3168
3169
3170 switch (Shallow_schreier_tree_strategy) {
3171
3173
3174 if (f_v) {
3175 cout << "schreier::get_schreier_vector "
3176 "shallow_schreier_tree_standard" << endl;
3177 }
3178
3179 Schreier_vector->init_from_schreier(this, f_trivial_group, verbose_level);
3180
3181 if (nb_gen) {
3182 Schreier_vector->init_local_generators(&gens, 0 /*verbose_level */);
3183 }
3184
3185 break;
3186
3187
3189
3190 if (f_v) {
3191 cout << "schreier::get_schreier_vector "
3192 "shallow_schreier_tree_Seress" << endl;
3193 }
3194
3195 Schreier_vector->init_shallow_schreier_forest(this,
3196 f_trivial_group,
3197 FALSE /* f_randomized*/,
3198 verbose_level);
3199 if (f_v) {
3200 cout << "schreier::get_schreier_vector after "
3201 "Schreier_vector->init_shallow_schreier_forest, nb "
3202 "local gens in Schreier_vector = "
3203 << Schreier_vector->local_gens->len << endl;
3204 cout << "f_has_local_generators=" <<
3205 Schreier_vector->f_has_local_generators << endl;
3206 }
3207 //Schreier_vector->init_from_schreier(this, f_trivial_group, verbose_level);
3208
3209 break;
3210
3211
3213
3214 if (f_v) {
3215 cout << "schreier::get_schreier_vector "
3216 "shallow_schreier_tree_Seress" << endl;
3217 }
3218
3219 Schreier_vector->init_shallow_schreier_forest(this,
3220 f_trivial_group,
3221 TRUE /* f_randomized*/,
3222 verbose_level);
3223 if (f_v) {
3224 cout << "schreier::get_schreier_vector after Schreier_vector->"
3225 "init_shallow_schreier_forest, nb local gens in "
3226 "Schreier_vector = " << Schreier_vector->local_gens->len
3227 << endl;
3228 cout << "f_has_local_generators="
3229 << Schreier_vector->f_has_local_generators << endl;
3230 }
3231 //Schreier_vector->init_from_schreier(this, f_trivial_group, verbose_level);
3232
3233 break;
3234
3235
3237
3238 if (f_v) {
3239 cout << "schreier::get_schreier_vector "
3240 "shallow_schreier_tree_Sajeeb" << endl;
3241 }
3242
3243 shallow_schreier_ai shallow_tree;
3244 shallow_tree.generate_shallow_tree(*this, verbose_level);
3245 shallow_tree.get_degree_sequence(*this, verbose_level);
3246 shallow_tree.print_degree_sequence();
3247
3248
3249
3250 Schreier_vector->init_from_schreier(this, f_trivial_group, verbose_level);
3251
3252 if (nb_gen) {
3253 Schreier_vector->init_local_generators(&gens, 0 /*verbose_level */);
3254 }
3255
3256 break;
3257
3258
3259 }
3260
3261
3262
3263 if (f_v) {
3264 cout << "nb_times_image_of_called=" << A->ptr->nb_times_image_of_called << endl;
3265 }
3266
3267 if (f_v) {
3268 cout << "schreier::get_schreier_vector done" << endl;
3269 }
3270 return Schreier_vector;
3271}
3272#endif
3273
3274
3275
3277 // This function returns the number of points in the schreier forest
3278
3279 int total_points_in_forest = 0;
3280
3281 for (int orbit_idx = 0; orbit_idx < nb_orbits; orbit_idx++) {
3282 total_points_in_forest += this->orbit_len[orbit_idx];
3283 }
3284
3285 return total_points_in_forest;
3286}
3287
3289 // This function returns the average word length of the forest.
3290
3291 double avgwl = 0.0;
3292 int total_points_in_forest = get_num_points();
3293
3294 for (int orbit_idx = 0; orbit_idx < nb_orbits; orbit_idx++) {
3295 avgwl += get_average_word_length(orbit_idx) * orbit_len[orbit_idx]
3296 / total_points_in_forest;
3297 }
3298
3299 return avgwl;
3300}
3301
3303{
3304 int fst = orbit_first[orbit_idx];
3305 //int len = orbit_len[orbit_idx];
3306 //int root = orbit[fst];
3307 int l;
3308
3309 // Average and optimal word lengths of old tree
3310 int last = orbit_first[orbit_idx + 1];
3311 int L = 0, N = last - fst;
3312 for (int j = 0; j < last; j++) {
3313 trace_back(NULL, orbit[j], l);
3314 L += l;
3315 }
3316
3317 return L / double(N);
3318}
3319
3320void schreier::compute_orbit_invariant(int *&orbit_invariant,
3321 int (*compute_orbit_invariant_callback)(schreier *Sch,
3322 int orbit_idx, void *data, int verbose_level),
3323 void *compute_orbit_invariant_data,
3324 int verbose_level)
3325{
3326 int f_v = (verbose_level >= 1);
3327 int orbit_idx;
3328
3329 if (f_v) {
3330 cout << "schreier::compute_orbit_invariant" << endl;
3331 }
3332 orbit_invariant = NEW_int(nb_orbits);
3333 for (orbit_idx = 0; orbit_idx < nb_orbits; orbit_idx++) {
3334 orbit_invariant[orbit_idx] = (*compute_orbit_invariant_callback)
3335 (this, orbit_idx, compute_orbit_invariant_data, verbose_level - 2);
3336 }
3337 if (f_v) {
3338 cout << "schreier::compute_orbit_invariant done" << endl;
3339 }
3340}
3341
3342void schreier::print_TDA(std::ostream &ost,
3345 int verbose_level)
3346{
3347 int f_v = (verbose_level >= 1);
3348
3349 if (f_v) {
3350 cout << "schreier::print_TDA" << endl;
3351 }
3352
3353 //print_tex(ost);
3354
3355 if (Report_options->f_show_incidence_matrices) {
3357
3358 OwCF->encode_incma(Enc, verbose_level);
3359
3360 latex_TDA(ost, Enc, verbose_level);
3361 ost << "\\\\" << endl;
3362
3363 FREE_OBJECT(Enc);
3364 }
3365
3366 if (f_v) {
3367 cout << "schreier::print_TDA done" << endl;
3368 }
3369}
3370
3371void schreier::latex_TDA(std::ostream &ost,
3373 int verbose_level)
3374{
3375 int f_v = (verbose_level >= 1);
3376
3377 if (f_v) {
3378 cout << "schreier::latex_TDA" << endl;
3379 }
3380
3381 if (f_v) {
3382 cout << "schreier::latex_TDA before Enc->latex_TDA" << endl;
3383 }
3384 Enc->latex_TDA_with_labels(ost,
3386 verbose_level);
3387 ost << "\\\\" << endl;
3388 if (f_v) {
3389 cout << "schreier::latex_TDA after Enc->latex_TDA" << endl;
3390 }
3391
3392
3393 if (f_v) {
3394 cout << "schreier::latex_TDA done" << endl;
3395 }
3396}
3397
3398
3399}}}
3400
options for the report for a classification of combinatorial objects
encoding of combinatorial object for use with nauty
void latex_TDA_with_labels(std::ostream &ost, int nb_orbits, int *orbit_first, int *orbit_len, int *orbit, int verbose_level)
void distribution(int *v, int len_v, int *&val, int *&mult, int &len)
Definition: int_vec.cpp:387
data structure for set partitions following Jeffrey Leon
void init_basic_with_Sz_in_int(int underlying_set_size, int nb_sets, int *Sz, int verbose_level)
a collection of functions related to sorted vectors
int int_vec_search(int *v, int len, int a, int &idx)
Definition: sorting.cpp:1094
void int_vec_sorting_permutation(int *v, int len, int *perm, int *perm_inv, int f_increasingly)
Definition: sorting.cpp:830
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
a combinatorial object for which a canonical form can be computed using Nauty
Definition: geometry.h:1487
void encode_incma(combinatorics::encoded_combinatorial_object *&Enc, int verbose_level)
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
int compare(longinteger_object &a, longinteger_object &b)
void integral_division_by_int(longinteger_object &a, int b, longinteger_object &q, int &r)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
a permutation group in a fixed action.
Definition: actions.h:99
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 element_retrieve(int hdl, void *elt, int verbose_level)
Definition: action_cb.cpp:301
void element_mult(void *a, void *b, void *ab, int verbose_level)
Definition: action_cb.cpp:315
int element_is_one(void *elt, int verbose_level)
Definition: action_cb.cpp:248
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
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
long int element_image_of(long int a, void *elt, int verbose_level)
Definition: action_cb.cpp:198
void init_from_schreier(groups::schreier *S, int f_trivial_group, int verbose_level)
void init_shallow_schreier_forest(groups::schreier *S, int f_trivial_group, int f_randomized, int verbose_level)
void init(int gen_hdl_first, int nb_gen, int *sv, 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)
void init(actions::action *A, int verbose_level)
Definition: vector_ge.cpp:55
Schreier trees for orbits of groups on points.
Definition: groups.h:839
void init_generators_recycle_images(data_structures_groups::vector_ge &generators, int **old_images, int idx_generator_to_delete, int verbose_level)
Definition: schreier.cpp:393
void get_orbit_decomposition_scheme_of_graph(int *Adj, int n, int *&Decomp_scheme, int verbose_level)
Definition: schreier.cpp:2858
void compute_orbit_invariant(int *&orbit_invariant, int(*compute_orbit_invariant_callback)(schreier *Sch, int orbit_idx, void *data, int verbose_level), void *compute_orbit_invariant_data, int verbose_level)
Definition: schreier.cpp:3320
void shallow_tree_generators(int orbit_idx, int f_randomized, schreier *&shallow_tree, int verbose_level)
Definition: schreier.cpp:2962
void compute_point_orbit_with_limited_depth(int pt, int max_depth, int verbose_level)
Definition: schreier.cpp:1395
void compute_all_point_orbits(int verbose_level)
Definition: schreier.cpp:988
void init_images_only(int nb_images, long int degree, int *images, int verbose_level)
Definition: schreier.cpp:167
void elements_in_orbit_of(int pt, int *orb, int &nb, int verbose_level)
Definition: schreier.cpp:2733
void orbits_as_set_of_sets(data_structures::set_of_sets *&S, int verbose_level)
Definition: schreier.cpp:2653
void orbits_on_invariant_subset_fast(int len, int *subset, int verbose_level)
Definition: schreier.cpp:1931
void compute_all_orbits_on_invariant_subset_lint(int len, long int *subset, int verbose_level)
Definition: schreier.cpp:1221
void get_orbit_number_and_position(int pt, int &orbit_idx, int &orbit_pos, int verbose_level)
Definition: schreier.cpp:2822
void coset_rep_with_verbosity(int j, int verbose_level)
Definition: schreier.cpp:824
void orbits_on_invariant_subset(int len, int *subset, int &nb_orbits_on_subset, int *&orbit_perm, int *&orbit_perm_inv)
Definition: schreier.cpp:2035
void get_orbit_partition_of_points_and_lines(data_structures::partitionstack &S, int verbose_level)
Definition: schreier.cpp:2070
void print_TDA(std::ostream &ost, geometry::object_with_canonical_form *OwCF, combinatorics::classification_of_objects_report_options *Report_options, int verbose_level)
Definition: schreier.cpp:3342
void random_schreier_generator(int *Elt, int verbose_level)
Definition: schreier.cpp:1709
void compute_orbit_statistic_lint(long int *set, int set_size, int *orbit_count, int verbose_level)
Definition: schreier.cpp:2631
void random_schreier_generator_ith_orbit(int *Elt, int orbit_no, int verbose_level)
Definition: schreier.cpp:1574
void swap_points(int i, int j, int verbose_level)
Definition: schreier.cpp:678
void init_generators_by_handle(std::vector< int > &gen_hdl, int verbose_level)
Definition: schreier.cpp:571
void extend_orbit(int *elt, int verbose_level)
Definition: schreier.cpp:901
void compute_all_point_orbits_with_preferred_labels(long int *preferred_labels, int verbose_level)
Definition: schreier.cpp:1104
data_structures_groups::vector_ge gens_inv
Definition: groups.h:846
void(* preferred_choice_function)(int pt, int &pt_pref, schreier *Sch, void *data, int data2, int verbose_level)
Definition: groups.h:883
void init_single_generator(int *elt, int verbose_level)
Definition: schreier.cpp:360
void get_orbit_length(int *&orbit_length, int verbose_level)
Definition: schreier.cpp:2751
void(* print_function)(std::ostream &ost, int pt, void *data)
Definition: groups.h:879
void init_images(int nb_images, int verbose_level)
Definition: schreier.cpp:136
void init_preferred_choice_function(void(*preferred_choice_function)(int pt, int &pt_pref, schreier *Sch, void *data, int data2, int verbose_level), void *preferred_choice_function_data, int preferred_choice_function_data2, int verbose_level)
Definition: schreier.cpp:115
void orbits_on_invariant_subset_fast_lint(int len, long int *subset, int verbose_level)
Definition: schreier.cpp:1983
void transporter_from_orbit_rep_to_point(int pt, int &orbit_idx, int *Elt, int verbose_level)
Definition: schreier.cpp:735
strong_generators * stabilizer_orbit_rep(actions::action *default_action, ring_theory::longinteger_object &full_group_order, int orbit_idx, int verbose_level)
Definition: schreier.cpp:2345
void init_generators(data_structures_groups::vector_ge &generators, int verbose_level)
Definition: schreier.cpp:373
void transporter_from_point_to_orbit_rep(int pt, int &orbit_idx, int *Elt, int verbose_level)
Definition: schreier.cpp:760
void compute_point_orbit(int pt, int verbose_level)
Definition: schreier.cpp:1256
data_structures_groups::set_and_stabilizer * get_orbit_rep(actions::action *default_action, ring_theory::longinteger_object &full_group_order, int orbit_idx, int verbose_level)
Definition: schreier.cpp:2296
void print_orbit_length_distribution(std::ostream &ost)
void compute_all_point_orbits_with_prefered_reps(int *prefered_reps, int nb_prefered_reps, int verbose_level)
Definition: schreier.cpp:1070
void point_stabilizer(actions::action *default_action, ring_theory::longinteger_object &go, groups::sims *&Stab, int orbit_no, int verbose_level)
Definition: schreier.cpp:2388
void compute_orbit_statistic(int *set, int set_size, int *orbit_count, int verbose_level)
Definition: schreier.cpp:2610
void get_orbit_reps(int *&Reps, int &nb_reps, int verbose_level)
Definition: schreier.cpp:2686
void create_point_list_sorted(int *&point_list, int &point_list_length)
Definition: schreier.cpp:2931
void init_images_recycle(int nb_images, int **old_images, int idx_deleted_generator, int verbose_level)
Definition: schreier.cpp:197
long int get_image(long int i, int gen_idx, int verbose_level)
Definition: schreier.cpp:615
void intersection_vector(int *set, int len, int *intersection_cnt)
Definition: schreier.cpp:1915
data_structures_groups::vector_ge gens
Definition: groups.h:845
void init(actions::action *A, int verbose_level)
Definition: schreier.cpp:308
void get_orbit(int orbit_idx, long int *set, int &len, int verbose_level)
Definition: schreier.cpp:2598
void get_orbit_rep_to(actions::action *default_action, ring_theory::longinteger_object &full_group_order, int orbit_idx, data_structures_groups::set_and_stabilizer *Rep, int verbose_level)
Definition: schreier.cpp:2319
void coset_rep_inv(int j, int verbose_level)
Definition: schreier.cpp:864
strong_generators * stabilizer_any_point_plus_cosets(actions::action *default_action, ring_theory::longinteger_object &full_group_order, int pt, data_structures_groups::vector_ge *&cosets, int verbose_level)
Definition: schreier.cpp:2148
void compute_all_orbits_on_invariant_subset(int len, long int *subset, int verbose_level)
Definition: schreier.cpp:1186
void get_orbit_in_order(std::vector< int > &Orb, int orbit_idx, int verbose_level)
Definition: schreier.cpp:2134
data_structures_groups::schreier_vector * get_schreier_vector(int gen_hdl_first, int nb_gen, enum shallow_schreier_tree_strategy Shallow_schreier_tree_strategy, int verbose_level)
Definition: schreier.cpp:3146
void non_trivial_random_schreier_generator(actions::action *A_original, int *Elt, int verbose_level)
Definition: schreier.cpp:1517
void get_orbit_lengths_once_each(int *&orbit_lengths, int &nb_orbit_lengths)
Definition: schreier.cpp:2773
void trace_back(int *path, int i, int &j)
Definition: schreier.cpp:1896
void get_orbit_partition(data_structures::partitionstack &S, int verbose_level)
Definition: schreier.cpp:2112
strong_generators * stabilizer_any_point(actions::action *default_action, ring_theory::longinteger_object &full_group_order, int pt, int verbose_level)
Definition: schreier.cpp:2233
void coset_rep(int j, int verbose_level)
Definition: schreier.cpp:787
void print_tables(std::ostream &ost, int f_with_cosetrep)
void latex_TDA(std::ostream &ost, combinatorics::encoded_combinatorial_object *Enc, int verbose_level)
Definition: schreier.cpp:3371
void init_generators_by_hdl(int nb_gen, int *gen_hdl, int verbose_level)
Definition: schreier.cpp:529
a permutation group represented via a stabilizer chain
Definition: groups.h:1273
void init(actions::action *A, int verbose_level)
Definition: sims.cpp:289
void group_order(ring_theory::longinteger_object &go)
Definition: sims.cpp:951
void init_trivial_group(int verbose_level)
Definition: sims.cpp:584
void group_order_verbose(ring_theory::longinteger_object &go, int verbose_level)
Definition: sims.cpp:964
void add_generator_at_level(int *elt, int lvl, int verbose_level)
Definition: sims_main.cpp:543
void random_schreier_generator(int *Elt, int verbose_level)
Definition: sims.cpp:1803
int strip(int *elt, int *residue, int &drop_out_level, int &image, int verbose_level)
Definition: sims_main.cpp:433
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define ONE_MILLION
Definition: foundations.h:226
#define NEW_pint(n)
Definition: foundations.h:627
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define NEW_lint(n)
Definition: foundations.h:628
#define FREE_pint(p)
Definition: foundations.h:641
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
shallow_schreier_tree_strategy
the strategy which is employed to create shallow Schreier trees
the orbiter library for the classification of combinatorial objects