Orbiter 2022
Combinatorial Objects
schreier_sims.cpp
Go to the documentation of this file.
1// schreier_sims.cpp
2//
3// Anton Betten
4// July 27, 2010
5
7#include "group_actions.h"
8
9using namespace std;
10
11
12
13namespace orbiter {
14namespace layer3_group_actions {
15namespace groups {
16
17
18
20{
21 GA = NULL;
22 G = NULL;
23
25 KA = NULL;
26 K = NULL;
27
28 //longinteger_object G_order, K_order, KG_order;
29
30 Elt1 = NULL;
31 Elt2 = NULL;
32 Elt3 = NULL;
33
35 //longinteger_object tgo;
36
38 external_gens = NULL;
39
43
45 old_G = NULL;
46
49 base_of_choice = NULL;
50
53
54 iteration = 0;
55 //null();
56}
57
59{
60 freeself();
61}
62
64{
65}
66
68{
69 if (Elt1) {
71 Elt1 = NULL;
72 }
73 if (Elt2) {
75 Elt1 = NULL;
76 }
77 if (Elt3) {
79 Elt1 = NULL;
80 }
81 if (G) {
83 G = NULL;
84 }
85 if (K) {
87 K = NULL;
88 }
91 external_gens = NULL;
92 }
93}
94
95void schreier_sims::init(actions::action *A, int verbose_level)
96{
97 int f_v = (verbose_level >= 1);
98
99 if (f_v) {
100 cout << "schreier_sims::init action:" << endl;
101 A->print_info();
102 }
107
108 G = NEW_OBJECT(sims);
109
110 //cout << "schreier_sims::init sims object " << G
111 // << " with action " << GA << "=" << GA->label << endl;
112
113 if (f_v) {
114 cout << "schreier_sims::init action A:" << endl;
115 A->print_info();
116 cout << "schreier_sims::init before G->init" << endl;
117 }
118 G->init(GA, verbose_level - 2);
119 if (f_v) {
120 cout << "schreier_sims::init after G->init" << endl;
121 }
122 if (f_v) {
123 cout << "schreier_sims::init before G->init_trivial_group" << endl;
124 }
125 G->init_trivial_group(0 /*verbose_level*/);
126 if (f_v) {
127 cout << "schreier_sims::init after G->init_trivial_group" << endl;
128 }
129 if (f_v) {
130 cout << "schreier_sims::init done" << endl;
131 }
132}
133
135 int verbose_level)
136{
137 int f_v = (verbose_level >= 1);
138
139 if (f_v) {
140 cout << "schreier_sims::interested_in_kernel "
141 "kernel action:" << endl;
142 KA->print_info();
143 }
145 K = NEW_OBJECT(sims);
146 K->init(KA, verbose_level - 2);
149}
150
151
153 ring_theory::longinteger_object &tgo, int verbose_level)
154{
155 int f_v = (verbose_level >= 1);
156
157 if (f_v) {
158 cout << "schreier_sims::init_target_group_order " << tgo << endl;
159 }
162}
163
165 data_structures_groups::vector_ge *gens, int verbose_level)
166{
167 int f_v = (verbose_level >= 1);
168
169 if (f_v) {
170 cout << "schreier_sims::init_generators " << endl;
171 }
172 if (f_v) {
173 cout << "schreier_sims::init_generators copying generators in" << endl;
174 }
175 gens->copy(external_gens, verbose_level);
176 //schreier_sims::gens = gens;
177 if (f_v) {
178 cout << "schreier_sims::init_generators generators are:" << endl;
179 gens->print(cout, TRUE /* f_print_as_permutation */,
180 TRUE /* f_offset */, 1 /* offset */,
181 TRUE /* f_do_it_anyway_even_for_big_degree */,
182 FALSE /* f_print_cycles_of_length_one*/);
183 gens->print_for_make_element(cout);
184 }
186}
187
189 void (*callback_choose_random_generator)(int iteration,
190 int *Elt, void *data, int verbose_level),
191 void *callback_choose_random_generator_data,
192 int verbose_level)
193{
194 int f_v = (verbose_level >= 1);
195
196 if (f_v) {
197 cout << "schreier_sims::init_random_process" << endl;
198 }
204}
205
206void schreier_sims::init_old_G(sims *old_G, int verbose_level)
207{
208 int f_v = (verbose_level >= 1);
209
210 if (f_v) {
211 cout << "schreier_sims::init_old_G" << endl;
212 }
215}
216
218 int base_of_choice_len, int *base_of_choice,
219 int verbose_level)
220{
221 int f_v = (verbose_level >= 1);
222
223 if (f_v) {
224 cout << "schreier_sims::init_base_of_choice" << endl;
225 }
229}
230
232 int (*choose_next_base_point_method)(actions::action *A,
233 int *Elt, int verbose_level),
234 int verbose_level)
235{
236 int f_v = (verbose_level >= 1);
237
238 if (f_v) {
239 cout << "schreier_sims::init_choose_next_base_point_method" << endl;
240 }
244}
245
247{
253 }
254 else {
256 }
257}
258
260{
261 cout << "current group order is " << G_order;
263 cout << " target group order is " << tgo;
264 }
265 cout << " : in log base 10: " << G_order.log10() << " / " << tgo.log10() << endl;
266}
267
269 int *Elt, int verbose_level)
270{
271 int f_v = (verbose_level >= 1);
272 //int f_vv = (verbose_level >= 2);
273 int f_vvv = (verbose_level >= 3);
274
275 if (f_v) {
276 cout << "schreier_sims::get_generator_internal "
277 "choosing random schreier generator" << endl;
278 cout << "verbose_level=" << verbose_level << endl;
279 }
280 G->random_schreier_generator(Elt, verbose_level - 3);
281 //GA->element_move(G->schreier_gen, Elt, 0);
282 if (f_vvv) {
283 cout << "schreier_sims::get_generator_internal "
284 "we picked the following random Schreier generator:" << endl;
285 GA->element_print_quick(Elt, cout);
286 cout << endl;
287 }
288}
289
291 int *Elt, int verbose_level)
292{
293 int f_v = (verbose_level >= 1);
294 //int f_vv = (verbose_level >= 2);
295 //int f_vvv = (verbose_level >= 3);
296
297 if (f_v) {
298 cout << "schreier_sims::get_generator_external" << endl;
299 }
300 if (f_from_generators) {
301 if (f_v) {
302 cout << "schreier_sims::get_generator_external before get_generator_external_from_generators" << endl;
303 }
304 get_generator_external_from_generators(Elt, verbose_level);
305 }
306 else if (f_from_random_process) {
307 if (f_v) {
308 cout << "schreier_sims::get_generator_external before get_generator_external_random_process" << endl;
309 }
310 get_generator_external_random_process(Elt, verbose_level);
311 }
312 else if (f_from_old_G) {
313 if (f_v) {
314 cout << "schreier_sims::get_generator_external before get_generator_external_old_G" << endl;
315 }
316 get_generator_external_old_G(Elt, verbose_level);
317 }
318 if (FALSE /*f_vvv*/) {
319 cout << "schreier_sims::get_generator_external "
320 "we have chosen the following generator" << endl;
321 //GA->element_print_quick(Elt, cout);
322 cout << endl;
323 }
324 if (f_v) {
325 cout << "schreier_sims::get_generator_external done" << endl;
326 }
327}
328
330 int *Elt, int verbose_level)
331{
332 int f_v = (verbose_level >= 1);
333 int r;
335
336 if (f_v) {
337 cout << "schreier_sims::get_generator_external_"
338 "from_generators" << endl;
339 }
340 if (external_gens->len) {
342 if (f_v) {
343 cout << "schreier_sims::get_generator_external_"
344 "from_generators choosing generator "
345 << r << " / " << external_gens->len << endl;
346 }
347 GA->element_move(external_gens->ith(r), Elt, 0);
348 }
349 else {
350 if (f_v) {
351 cout << "schreier_sims::get_generator_external_"
352 "from_generators gens->len == 0" << endl;
353 }
354 // no generators, we are creating the identity group:
355 GA->element_one(Elt, 0);
356 }
357 if (f_v) {
358 cout << "schreier_sims::get_generator_external_"
359 "from_generators done" << endl;
360 }
361}
362
364 int *Elt, int verbose_level)
365{
366 int f_v = (verbose_level >= 1);
367
368 if (f_v) {
369 cout << "schreier_sims::get_generator_external_"
370 "random_process" << endl;
371 }
372 (*callback_choose_random_generator)((iteration >> 1),
373 Elt, callback_choose_random_generator_data, verbose_level - 1);
374}
375
377 int *Elt, int verbose_level)
378{
379 int f_v = (verbose_level >= 1);
380 //int f_vv = (verbose_level >= 2);
381
382 if (FALSE) {
383 cout << "schreier_sims::get_generator_external_old_G" << endl;
384 }
385 old_G->random_element(Elt, verbose_level - 1);
386 if (f_v) {
387 cout << "schreier_sims::get_generator_external_old_G "
388 "random element chosen, path = ";
389 Int_vec_print(cout, old_G->path, old_G->A->base_len());
390 cout << endl;
391 }
392}
393
394void schreier_sims::get_generator(int *Elt, int verbose_level)
395{
396 int f_v = (verbose_level >= 1);
397
398 if (f_v) {
399 cout << "schreier_sims::get_generator" << endl;
400 }
401 if ((iteration % 2) == 0) {
402 if (f_v) {
403 cout << "schreier_sims::get_generator before get_generator_internal" << endl;
404 }
405 get_generator_internal(Elt, verbose_level);
406 if (f_v) {
407 cout << "schreier_sims::get_generator after get_generator_internal" << endl;
408 }
409 }
410 else if ((iteration % 2) == 1) {
411 if (f_v) {
412 cout << "schreier_sims::get_generator before get_generator_external" << endl;
413 }
414 get_generator_external(Elt, verbose_level);
415 if (f_v) {
416 cout << "schreier_sims::get_generator after get_generator_external" << endl;
417 }
418 }
419 if (f_v) {
420 cout << "schreier_sims::get_generator done" << endl;
421 }
422}
423
424void schreier_sims::closure_group(int verbose_level)
425{
426 int f_v = (verbose_level >= 1);
427 int f_vvv = (verbose_level >= 3);
430 int cnt = 0;
431
432 if (f_v) {
433 cout << "schreier_sims::closure_group" << endl;
434 }
435 D.integral_division(tgo, KG_order, quo, rem, 0);
436 while (!quo.is_zero() && !rem.is_zero()) {
437 if (f_vvv) {
438 cout << "schreier_sims::closure_group iteration "
439 << iteration << " cnt " << cnt
440 << ": remainder is not zero, "
441 "this is not a subgroup" << endl;
442 }
443 int nb_times = 30;
444
445 if (f_v) {
446 cout << "schreier_sims::closure_group "
447 "calling G->closure_group" << endl;
448 }
449 G->closure_group(nb_times, verbose_level - 3);
451 D.integral_division(tgo, KG_order, quo, rem, 0);
452 if (f_vvv) {
453 cout << "schreier_sims::closure_group iteration "
454 << iteration << " cnt " << cnt
455 << ": after closure_group: remaining factor: "
456 << quo << " remainder " << rem << endl;
457 }
458 cnt++;
459 if (cnt == 10) {
460 cout << "schreier_sims::closure_group cnt == 100, "
461 "KG_order=" << KG_order << ", we are breaking off" << endl;
462 break;
463 }
464 }
465 if (f_v) {
466 cout << "schreier_sims::closure_group done ";
468 }
469}
470
471void schreier_sims::create_group(int verbose_level)
472{
473 int f_v = (verbose_level >= 1);
474 int f_vv = (verbose_level >= 3);
475 int f_vvv = (verbose_level >= 4);
476 int f_vvvv = (verbose_level >= 5);
478 int drop_out_level, image, b, c, f_added, old_base_len;
479
480 if (f_v) {
481 cout << "schreier_sims::create_group" << endl;
483 cout << "schreier_sims::create_group target group order is " << tgo << endl;
484 }
485 else {
486 cout << "schreier_sims::create_group no target group order given" << endl;
487 }
488 }
490 cout << "schreier_sims::create_group target group order is 0" << endl;
491 exit(1);
492 }
494 if (f_v) {
496 }
497 iteration = 0;
498 while (TRUE) {
499
500 if (f_vv) {
501 cout << "schreier_sims::create_group "
502 "iteration " << iteration << endl;
504 }
505 if (f_has_target_group_order && iteration > 10000) {
506 cout << "schreier_sims::create_group iteration > 1000, "
507 "something seems to be wrong" << endl;
508 cout << "target group order = " << tgo << endl;
509 cout << "KG_order = " << KG_order << endl;
510 //test_if_subgroup(old_G, 2);
511 exit(1);
512 }
513
514 if (!f_has_target_group_order && iteration == 10000) {
515 if (f_v) {
516 cout << "schreier_sims::create_group "
517 "iteration == 1000, we seem to be done" << endl;
518 }
519 break;
520 }
521
522 if (f_vv) {
523 cout << "schreier_sims::create_group "
524 "iteration " << iteration
525 << " before get_generator" << endl;
526 //GA->element_print_quick(Elt1, cout);
527 }
528 get_generator(Elt1, verbose_level - 3);
529 if (f_vv) {
530 cout << "schreier_sims::create_group "
531 "iteration " << iteration
532 << " after get_generator" << endl;
533 }
534 if (f_vv) {
535 cout << "schreier_sims::create_group "
536 "iteration " << iteration
537 << " generator: " << endl;
539 }
540
541 if (f_vv) {
542 cout << "schreier_sims::create_group "
543 "calling strip:" << endl;
544 }
545 if (G->strip(Elt1, Elt2, drop_out_level,
546 image, 0 /*verbose_level - 2*/)) {
547 if (f_vv) {
548 cout << "schreier_sims::create_group: "
549 "element strips through" << endl;
550 if (f_vvvv) {
551 cout << "schreier_sims::create_group: "
552 "residue = " << endl;
554 cout << endl;
555 }
556 }
557 f_added = FALSE;
558 if (!GA->element_is_one(Elt2, 0)) {
559 if (f_vvv) {
560 cout << "schreier_sims::create_group: "
561 "the residue is not trivial, "
562 "we need to choose another base point" << endl;
563 }
565 if (f_vv) {
566 cout << "schreier_sims::create_group "
567 "before (*choose_next_base_point_method)" << endl;
568 }
569 b = (*choose_next_base_point_method)(GA,
570 Elt2, verbose_level - 5);
571 }
572 else {
573 if (f_vv) {
574 cout << "schreier_sims::create_group "
575 "before GA->choose_next_base_point_default_method" << endl;
576 }
578 Elt2, verbose_level - 5);
579 }
580
581 if (f_vv) {
582 cout << "schreier_sims::create_group: "
583 "next suggested base point is "
584 << b << endl;
585 }
586 if (b == -1) {
587 if (f_vv) {
588 cout << "schreier_sims::create_group: "
589 "cannot find next base point" << endl;
590 }
591 if (K->strip(Elt2, Elt3, drop_out_level,
592 image, 0/*verbose_level - 3*/)) {
593 if (f_vv) {
594 cout << "schreier_sims::create_group: "
595 "element strips through kernel" << endl;
596 if (f_vvvv) {
597 cout << "schreier_sims::create_group: "
598 "residue = " << endl;
599 //KA->element_print_quick(Elt3, cout);
600 cout << endl;
601 K->print(FALSE);
603 cout << "schreier_sims::create_group: "
604 "residue" << endl;
606 Elt3, KA->base_len(), KA->get_base());
607 cout << "schreier_sims::create_group: "
608 "Elt2" << endl;
610 Elt2, KA->base_len(), KA->get_base());
611 }
612 }
613 if (!KA->element_is_one(Elt3, 0)) {
614 cout << "schreier_sims::create_group: "
615 "element strips through kernel, "
616 "residue = " << endl;
617 cout << "but the element is not the "
618 "identity, something is wrong" << endl;
619 //GA->element_print(Elt3, cout);
620 cout << endl;
623
624 exit(1);
625 }
626 }
627 if (f_vv) {
628 cout << "schreier_sims::create_group: "
629 "before K->add_generator_at_level" << endl;
630 }
632 drop_out_level, verbose_level - 3);
633 if (f_vvv) {
634 cout << "schreier_sims::create_group: "
635 "the residue has been added as "
636 "kernel generator at level "
637 << drop_out_level << endl;
638 }
639 f_added = TRUE;
640 }
641 else {
642 if (f_vvv) {
643 cout << "schreier_sims::create_group: "
644 "choosing n e w base point " << b << endl;
645 }
646 old_base_len = GA->base_len();
648 if (f_vvv) {
649 //cout << "after reallocate_base 1" << endl;
650 }
651 G->reallocate_base(old_base_len, verbose_level - 1);
652 if (f_vvv) {
653 //cout << "after reallocate_base 2" << endl;
654 }
655 if (f_vv) {
656 cout << "schreier_sims::create_group: "
657 "n e w base point " << b
658 << " chosen, n e w base has length "
659 << GA->base_len() << endl;
660 cout << "schreier_sims::create_group: "
661 "calling add_generator_at_level" << endl;
662 }
664 GA->base_len() - 1, verbose_level - 3);
665 if (f_vv) {
666 cout << "schreier_sims::create_group: "
667 "the residue has been added "
668 "at level " << GA->base_len() - 1 << endl;
669 }
670 } // if b
671 } // if ! element is one
672 else {
673 if (f_vv) {
674 cout << "schreier_sims::create_group: "
675 "the residue is trivial" << endl;
676 }
677 }
678 //G->closure_group(10, verbose_level - 2);
679 }
680 else {
681 f_added = TRUE;
682 if (f_vv) {
683 cout << "schreier_sims::create_group: "
684 "element needs to be inserted at level = "
685 << drop_out_level << " with image "
686 << image << endl;
687 GA->element_print(Elt2, cout);
688 cout << endl;
689 }
691 drop_out_level, verbose_level - 3);
692 }
693
695
696
697 if ((f_v && f_added) || f_vv) {
698 cout << "schreier_sims::create_group: "
699 "n e w group order is ";
701 }
702 iteration++;
703
705 c = D.compare(tgo, KG_order);
706 if (c == 0) {
707 if (f_v) {
708 cout << "schreier_sims::create_group: "
709 "reached the full group after "
710 << iteration << " iterations" << endl;
711 }
712 break;
713 }
714 if (c < 0) {
715 if (TRUE) {
716 cout << "schreier_sims::create_group "
717 "overshooting the expected group after "
718 << iteration << " iterations" << endl;
720 if (KG_order.as_int() < 100) {
721 cout << "schreier_sims::create_group so far, "
722 "the group elements are:" << endl;
723 //G->print_all_group_elements();
724 }
725 }
726 //break;
727 exit(1);
728 }
729 else {
730 if (f_vv) {
731 cout << "schreier_sims::create_group: before closure_group" << endl;
732 }
733 closure_group(verbose_level - 2);
734 if (f_vv) {
735 cout << "schreier_sims::create_group: after closure_group" << endl;
736 }
737 }
738 }
739 else {
740 if (f_vv) {
741 cout << "schreier_sims::create_group: before closure_group" << endl;
742 }
743 closure_group(verbose_level - 2);
744 if (f_vv) {
745 cout << "schreier_sims::create_group: after closure_group" << endl;
746 }
747 }
748 }
749 if (f_v) {
750 cout << "schreier_sims::create_group finished:";
752
753 cout << "the n e w action has base ";
754 Lint_vec_print(cout, GA->get_base(), GA->base_len());
755 cout << " of length " << GA->base_len() << endl;
756 }
757}
758
759}}}
760
761
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
int compare(longinteger_object &a, longinteger_object &b)
void mult(longinteger_object &a, longinteger_object &b, longinteger_object &c)
void integral_division(longinteger_object &a, longinteger_object &b, longinteger_object &q, longinteger_object &r, int verbose_level)
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
int element_is_one(void *elt, int verbose_level)
Definition: action_cb.cpp:248
stabilizer_chain_base_data * Stabilizer_chain
Definition: actions.h:178
void element_one(void *elt, int verbose_level)
Definition: action_cb.cpp:224
void element_print_image_of_set(void *elt, int size, long int *set)
Definition: action_cb.cpp:558
int choose_next_base_point_default_method(int *Elt, int verbose_level)
void element_move(void *a, void *b, int verbose_level)
Definition: action_cb.cpp:335
void copy(vector_ge *&vector_copy, int verbose_level)
Definition: vector_ge.cpp:72
void get_generator_external_from_generators(int *Elt, int verbose_level)
void get_generator_internal(int *Elt, int verbose_level)
void get_generator(int *Elt, int verbose_level)
void init_base_of_choice(int base_of_choice_len, int *base_of_choice, int verbose_level)
void init(actions::action *A, int verbose_level)
void init_choose_next_base_point_method(int(*choose_next_base_point_method)(actions::action *A, int *Elt, int verbose_level), int verbose_level)
int(* choose_next_base_point_method)(actions::action *A, int *Elt, int verbose_level)
Definition: groups.h:1224
void get_generator_external_old_G(int *Elt, int verbose_level)
void get_generator_external(int *Elt, int verbose_level)
void init_old_G(sims *old_G, int verbose_level)
void init_generators(data_structures_groups::vector_ge *gens, int verbose_level)
ring_theory::longinteger_object K_order
Definition: groups.h:1198
void get_generator_external_random_process(int *Elt, int verbose_level)
data_structures_groups::vector_ge * external_gens
Definition: groups.h:1209
void(* callback_choose_random_generator)(int iteration, int *Elt, void *data, int verbose_level)
Definition: groups.h:1212
void interested_in_kernel(actions::action *KA, int verbose_level)
ring_theory::longinteger_object tgo
Definition: groups.h:1205
ring_theory::longinteger_object KG_order
Definition: groups.h:1198
void init_random_process(void(*callback_choose_random_generator)(int iteration, int *Elt, void *data, int verbose_level), void *callback_choose_random_generator_data, int verbose_level)
void init_target_group_order(ring_theory::longinteger_object &tgo, int verbose_level)
ring_theory::longinteger_object G_order
Definition: groups.h:1198
a permutation group represented via a stabilizer chain
Definition: groups.h:1273
void random_element(int *elt, int verbose_level)
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
int closure_group(int nb_times, int verbose_level)
Definition: sims_main.cpp:1353
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
void reallocate_base(int old_base_len, int verbose_level)
Definition: sims.cpp:445
int strip(int *elt, int *residue, int &drop_out_level, int &image, int verbose_level)
Definition: sims_main.cpp:433
#define FREE_int(p)
Definition: foundations.h:640
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define Lint_vec_print(A, B, C)
Definition: foundations.h:686
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
the orbiter library for the classification of combinatorial objects