Orbiter 2022
Combinatorial Objects
action_global.cpp
Go to the documentation of this file.
1// action_global.cpp
2//
3// Anton Betten
4// October 10, 2013
5
7#include "group_actions.h"
8
9using namespace std;
10
11
12namespace orbiter {
13namespace layer3_group_actions {
14namespace actions {
15
16
19{
20 if (a == unknown_symmetry_group_t) {
21 ost << "unknown_symmetry_group_t";
22 }
23 else if (a == matrix_group_t) {
24 ost << "matrix_group_t";
25 }
26 else if (a == perm_group_t) {
27 ost << "perm_group_t";
28 }
29 else if (a == wreath_product_t) {
30 ost << "wreath_product_t";
31 }
32 else if (a == direct_product_t) {
33 ost << "direct_product_t";
34 }
35 else if (a == permutation_representation_t) {
36 ost << "permutation_representation_t";
37 }
38 else if (a == action_on_sets_t) {
39 ost << "action_on_sets_t";
40 }
41 else if (a == action_on_set_partitions_t) {
42 ost << "action_on_set_partitions_t";
43 }
44 else if (a == action_on_subgroups_t) {
45 ost << "action_on_subgroups_t";
46 }
47 else if (a == action_on_pairs_t) {
48 ost << "action_on_pairs_t";
49 }
50 else if (a == action_on_ordered_pairs_t) {
51 ost << "action_on_ordered_pairs_t";
52 }
53 else if (a == base_change_t) {
54 ost << "base_change_t";
55 }
56 else if (a == product_action_t) {
57 ost << "product_action_t";
58 }
60 ost << "action_by_right_multiplication_t";
61 }
62 else if (a == action_by_restriction_t) {
63 ost << "action_by_restriction_t";
64 }
65 else if (a == action_by_conjugation_t) {
66 ost << "action_by_conjugation_t";
67 }
68 else if (a == action_by_representation_t) {
69 ost << "action_by_representation_t";
70 }
71 else if (a == action_by_subfield_structure_t) {
72 ost << "action_by_subfield_structure_t";
73 }
74 else if (a == action_on_determinant_t) {
75 ost << "action_on_determinant_t";
76 }
77 else if (a == action_on_galois_group_t) {
78 ost << "action_on_galois_group_t";
79 }
80 else if (a == action_on_sign_t) {
81 ost << "action_on_sign_t";
82 }
83 else if (a == action_on_grassmannian_t) {
84 ost << "action_on_grassmannian_t";
85 }
86 else if (a == action_on_spread_set_t) {
87 ost << "action_on_spread_set_t";
88 }
89 else if (a == action_on_cosets_t) {
90 ost << "action_on_cosets_t";
91 }
92 else if (a == action_on_factor_space_t) {
93 ost << "action_on_factor_space_t";
94 }
95 else if (a == action_on_wedge_product_t) {
96 ost << "action_on_wedge_product_t";
97 }
98 else if (a == action_on_bricks_t) {
99 ost << "action_on_bricks_t";
100 }
101 else if (a == action_on_andre_t) {
102 ost << "action_on_andre_t";
103 }
104 else if (a == action_on_orthogonal_t) {
105 ost << "action_on_orthogonal_t";
106 }
107 else if (a == action_on_orbits_t) {
108 ost << "action_on_orbits_t";
109 }
110 else if (a == action_on_flags_t) {
111 ost << "action_on_flags_t";
112 }
114 ost << "action_on_homogeneous_polynomials_t";
115 }
116 else if (a == action_on_k_subsets_t) {
117 ost << "action_on_k_subsets_t";
118 }
120 ost << "action_on_interior_direct_product_t";
121 }
122 else {
123 ost << "unknown symmetry_group_type" << endl;
124 }
125}
126
127
129 action *A_PGL_n_q, action *A_PGL_k_q,
130 int k,
131 data_structures_groups::vector_ge *gens, int verbose_level)
132// used in semifield.cpp
133// does not include the swap
134{
135 int f_v = (verbose_level >= 1);
136 int f_vv = (verbose_level >= 2);
137 int *Q;
138 int *Elt1;
139 int *Zero;
140 int *Id;
141 int *Center;
142 int *minusId;
143 int n, i, len;
144 int *P;
147 int minus_one, alpha;
148 groups::strong_generators *gens_PGL_k;
149 //vector_ge *gens_PGL_k;
150
151
152 if (f_v) {
153 cout << "action_global::make_generators_stabilizer_of_two_components" << endl;
154 }
155 n = 2 * k;
156
157 Zero = NEW_int(k * k);
158 Id = NEW_int(k * k);
159 Center = NEW_int(k * k);
160 minusId = NEW_int(k * k);
161 Q = NEW_int(n * n + 1);
162 Elt1 = NEW_int(A_PGL_n_q->elt_size_in_int);
163
164
165 Mtx = A_PGL_k_q->G.matrix_grp;
166 Fq = Mtx->GFq;
167 minus_one = Fq->negate(1);
168 alpha = Fq->primitive_root();
169
170 Int_vec_zero(Zero, k * k);
171 Int_vec_zero(Id, k * k);
172 Int_vec_zero(Center, k * k);
173 Int_vec_zero(minusId, k * k);
174 for (i = 0; i < k; i++) {
175 Id[i * k + i] = 1;
176 }
177 for (i = 0; i < k; i++) {
178 Center[i * k + i] = alpha;
179 }
180 for (i = 0; i < k; i++) {
181 minusId[i * k + i] = minus_one;
182 }
183
184 gens_PGL_k = A_PGL_k_q->Strong_gens;
185 //gens_PGL_k = A_PGL_k_q->strong_generators;
186
187 len = gens_PGL_k->gens->len;
188 //len = gens_PGL_k->len;
189
190 int *Data;
191 int new_len, sz, idx, h;
192
193 new_len = 2 * len + 2;
194 sz = n * n;
195 if (Mtx->f_semilinear) {
196 sz++;
197 }
198
199
200 Data = NEW_int(new_len * sz);
201 idx = 0;
202 for (h = 0; h < 2 * len; h++) {
203
204 P = gens_PGL_k->gens->ith(h / 2);
205 //P = gens_PGL_k->ith(h / 2);
206
207 if (EVEN(h)) {
208 // Q := diag(P,Id)
210 }
211 else {
212 // Q := diag(Id,P)
214 }
215 if (Mtx->f_semilinear) {
216 Q[n * n] = P[k * k];
217 }
218 Int_vec_copy(Q, Data + idx * sz, sz);
219 idx++;
220 }
221
222#if 0
223 // Q := matrix(0,I,I,0):
224 int_matrix_make_block_matrix_2x2(Q, k, Zero, Id, Id, Zero);
225 if (Mtx->f_semilinear) {
226 Q[n * n] = 0;
227 }
228 int_vec_copy(Q, Data + idx * sz, sz);
229 idx++;
230#endif
231
232 // Q := matrix(Center,0,0,I):
234 if (Mtx->f_semilinear) {
235 Q[n * n] = 0;
236 }
237 Int_vec_copy(Q, Data + idx * sz, sz);
238 idx++;
239
240 // Q := matrix(I,0,0,Center):
242 if (Mtx->f_semilinear) {
243 Q[n * n] = 0;
244 }
245 Int_vec_copy(Q, Data + idx * sz, sz);
246 idx++;
247
248
249 if (idx != new_len) {
250 cout << "action_global::make_generators_stabilizer_of_two_components "
251 "idx != new_len" << endl;
252 exit(1);
253 }
254
255
256
257 gens->init(A_PGL_n_q, verbose_level - 2);
258 gens->allocate(new_len, verbose_level - 2);
259 for (h = 0; h < new_len; h++) {
260 A_PGL_n_q->make_element(Elt1, Data + h * sz, 0);
261 if (f_vv) {
262 cout << "action_global::make_generators_stabilizer_of_two_components "
263 "after make_element generator " << h << " : " << endl;
264 A_PGL_n_q->print_quick(cout, Elt1);
265 }
266 A_PGL_n_q->move(Elt1, gens->ith(h));
267 }
268
269
270 FREE_int(Data);
271
272 FREE_int(Zero);
273 FREE_int(Id);
274 FREE_int(Center);
275 FREE_int(minusId);
276 FREE_int(Q);
277 FREE_int(Elt1);
278 if (f_v) {
279 cout << "action_global::make_generators_stabilizer_of_two_components done" << endl;
280 }
281}
282
283
285 action *A_PGL_n_q, action *A_PGL_k_q,
286 int k,
287 data_structures_groups::vector_ge *gens, int verbose_level)
288{
289 int f_v = (verbose_level >= 1);
290 int f_vv = (verbose_level >= 2);
291 int *Q;
292 int *Elt1;
293 int *Zero;
294 int *Id;
295 int *minusId;
296 int n, i, len;
297 int *P;
300 int minus_one;
301 groups::strong_generators *gens_PGL_k;
302
303 if (f_v) {
304 cout << "action_global::make_generators_stabilizer_of_three_components" << endl;
305 }
306 n = 2 * k;
307
308 Zero = NEW_int(k * k);
309 Id = NEW_int(k * k);
310 minusId = NEW_int(k * k);
311 Q = NEW_int(n * n + 1);
312 Elt1 = NEW_int(A_PGL_n_q->elt_size_in_int);
313
314
315 Mtx = A_PGL_k_q->G.matrix_grp;
316 Fq = Mtx->GFq;
317 minus_one = Fq->negate(1);
318
319
320 Int_vec_zero(Zero, k * k);
321 Int_vec_zero(Id, k * k);
322 Int_vec_zero(minusId, k * k);
323 for (i = 0; i < k; i++) {
324 Id[i * k + i] = 1;
325 }
326 for (i = 0; i < k; i++) {
327 minusId[i * k + i] = minus_one;
328 }
329
330 gens_PGL_k = A_PGL_k_q->Strong_gens;
331 //gens_PGL_k = A_PGL_k_q->strong_generators;
332
333 len = gens_PGL_k->gens->len;
334 //len = gens_PGL_k->len;
335
336 int *Data;
337 int new_len, sz, idx, h;
338
339 new_len = len + 2;
340 sz = n * n;
341 if (Mtx->f_semilinear) {
342 sz++;
343 }
344
345
346 Data = NEW_int(new_len * sz);
347 idx = 0;
348 for (h = 0; h < len; h++) {
349
350 P = gens_PGL_k->gens->ith(h);
351 //P = gens_PGL_k->ith(h);
352
353 // Q := diag(P,P)
355 if (Mtx->f_semilinear) {
356 Q[n * n] = P[k * k];
357 }
358 Int_vec_copy(Q, Data + idx * sz, sz);
359 idx++;
360 }
361
362 // Q := matrix(0,I,I,0):
364 if (Mtx->f_semilinear) {
365 Q[n * n] = 0;
366 }
367 Int_vec_copy(Q, Data + idx * sz, sz);
368 idx++;
369
370 // Q := matrix(0,I,-I,-I):
371 orbiter_kernel_system::Orbiter->Int_vec->matrix_make_block_matrix_2x2(Q, k, Zero, Id, minusId, minusId);
372 if (Mtx->f_semilinear) {
373 Q[n * n] = 0;
374 }
375 Int_vec_copy(Q, Data + idx * sz, sz);
376 idx++;
377
378
379 if (idx != new_len) {
380 cout << "action_global::make_generators_stabilizer_of_three_components "
381 "idx != new_len" << endl;
382 exit(1);
383 }
384
385
386
387 gens->init(A_PGL_n_q, verbose_level - 2);
388 gens->allocate(new_len, verbose_level - 2);
389 for (h = 0; h < new_len; h++) {
390 A_PGL_n_q->make_element(Elt1, Data + h * sz, 0);
391 if (f_vv) {
392 cout << "action_global::make_generators_stabilizer_of_three_components "
393 "after make_element generator " << h << " : " << endl;
394 A_PGL_n_q->print_quick(cout, Elt1);
395 }
396 A_PGL_n_q->move(Elt1, gens->ith(h));
397 }
398
399
400 FREE_int(Data);
401
402 FREE_int(Zero);
403 FREE_int(Id);
404 FREE_int(minusId);
405 FREE_int(Q);
406 FREE_int(Elt1);
407 if (f_v) {
408 cout << "action_global::make_generators_stabilizer_of_three_components done" << endl;
409 }
410}
411
413 int &nb_gens, int &elt_size, int n,
416 int verbose_level)
417{
418 int f_v = (verbose_level >= 1);
419 int f_vv = (verbose_level >= 2);
420 action *A;
422 int *Elt;
423 int h, i, l, alpha;
424
425 if (f_v) {
426 cout << "action_global::compute_generators_GL_n_q" << endl;
427 }
428 A = NEW_OBJECT(action);
429
430 A->init_projective_group(n, F,
431 FALSE /* f_semilinear */,
432 TRUE /* f_basis */, TRUE /* f_init_sims */,
433 nice_gens,
434 verbose_level - 2);
435
436 gens = A->Strong_gens->gens;
437
438 l = gens->len;
439 nb_gens = l + 1;
440 elt_size = n * n;
441 Gens = NEW_int(nb_gens * elt_size);
442 for (h = 0; h < nb_gens; h++) {
443 if (h < l) {
444 Elt = gens->ith(h);
445 for (i = 0; i < n * n; i++) {
446 Gens[h * elt_size + i] = Elt[i];
447 }
448 }
449 else {
450 for (i = 0; i < n * n; i++) {
451 Gens[h * elt_size + i] = 0;
452 }
453 alpha = F->primitive_root();
454 for (i = 0; i < n; i++) {
455 Gens[h * elt_size + i * n + i] = alpha;
456 }
457 }
458 }
459 if (f_vv) {
460 for (h = 0; h < nb_gens; h++) {
461 cout << "Generator " << h << ":" << endl;
462 Int_matrix_print(Gens + h * elt_size, n, n);
463 }
464
465 }
466 FREE_OBJECT(A);
467 if (f_v) {
468 cout << "action_global::compute_generators_GL_n_q done" << endl;
469 }
470}
471
472
473
474// callbacks for Schreier Sims:
475
476
481
482
484 int f_reflection,
485 int f_similarity,
486 int f_semisimilarity)
487{
491 f_generator_orthogonal_semisimilarity = f_semisimilarity;
492}
493
495{
497}
498
499
500
501#if 0
502void test_matrix_group(int k, int q, int f_semilinear, int verbose_level)
503{
504 action A;
505 finite_field *F;
506 int f_basis = TRUE;
507 vector_ge *nice_gens;
508
509 F = NEW_OBJECT(finite_field);
510 F->init(q, 0);
511 A.init_projective_group(k, F, f_semilinear, f_basis, TRUE /* f_init_sims */,
512 nice_gens,
513 verbose_level);
514 FREE_OBJECT(nice_gens);
515 FREE_OBJECT(F);
516}
517#endif
518
523 int verbose_level)
524{
525 int f_v = (verbose_level >= 1);
526 int f_vv = (verbose_level >= 2);
527 int *EltQ;
528 int *Eltq;
529 int *Mtx;
530 int nb_gens, m, t;
531
532
533 if (f_v) {
534 cout << "action_global::lift_generators" << endl;
535 }
536
537 nb_gens = gens_in->len;
538
539 m = n / S->s;
540
542
543 Eltq = NEW_int(Aq->elt_size_in_int);
544 Mtx = NEW_int(n * n);
545
546 if (f_v) {
547 cout << "action_global::lift_generators lifting generators" << endl;
548 }
549 gens_out->init(Aq, verbose_level - 2);
550 gens_out->allocate(nb_gens, verbose_level - 2);
551 for (t = 0; t < nb_gens; t++) {
552 if (f_vv) {
553 cout << "lift_generators " << t << " / " << nb_gens << endl;
554 }
555 EltQ = gens_in->ith(t);
556 S->lift_matrix(EltQ, m, Mtx, 0 /* verbose_level */);
557 if (f_vv) {
558 cout << "action_global::lift_generators lifted matrix:" << endl;
559 Int_matrix_print(Mtx, n, n);
560 }
561 Aq->make_element(Eltq, Mtx, 0 /*verbose_level - 4 */);
562 if (f_vv) {
563 cout << "action_global::lift_generators after make_element:" << endl;
564 Aq->element_print_quick(Eltq, cout);
565 }
566 Aq->element_move(Eltq, gens_out->ith(t), 0);
567 if (f_vv) {
568 cout << "action_global::lift_generators " << t << " / "
569 << nb_gens << " done" << endl;
570 }
571 }
572 FREE_int(Eltq);
573 FREE_int(Mtx);
574 if (f_v) {
575 cout << "action_global::lift_generators done" << endl;
576 }
577}
578
583 int verbose_level)
584{
585 int f_v = (verbose_level >= 1);
586 int f_vv = (verbose_level >= 2);
587 int *EltQ;
588 int *Eltq;
589 int *Mtx;
590 int nb_gens, m, t;
591
592
593 if (f_v) {
594 cout << "action_global::retract_generators" << endl;
595 }
596
597 nb_gens = gens_in->len;
598
599 m = n / S->s;
600
602
603 EltQ = NEW_int(AQ->elt_size_in_int);
604 Mtx = NEW_int(m * m);
605
606 if (f_v) {
607 cout << "action_global::retract_generators retracting generators" << endl;
608 }
609 gens_out->init(AQ, verbose_level - 2);
610 gens_out->allocate(nb_gens, verbose_level - 2);
611 for (t = 0; t < nb_gens; t++) {
612 if (f_vv) {
613 cout << "action_global::retract_generators " << t
614 << " / " << nb_gens << endl;
615 }
616 Eltq = gens_in->ith(t);
617 S->retract_matrix(Eltq, n, Mtx, m, 0 /* verbose_level */);
618 if (f_vv) {
619 cout << "action_global::retract_generators retracted matrix:" << endl;
620 Int_matrix_print(Mtx, m, m);
621 }
622 AQ->make_element(EltQ, Mtx, 0 /*verbose_level - 4*/);
623 if (f_vv) {
624 cout << "action_global::retract_generators after make_element:" << endl;
625 AQ->element_print_quick(EltQ, cout);
626 }
627 AQ->element_move(EltQ, gens_out->ith(t), 0);
628 if (f_vv) {
629 cout << "action_global::retract_generators " << t
630 << " / " << nb_gens << " done" << endl;
631 }
632 }
633 FREE_int(EltQ);
634 FREE_int(Mtx);
635 if (f_v) {
636 cout << "action_global::retract_generators done" << endl;
637 }
638}
639
641 int n, int s,
643 action *Aq, action *AQ,
644 groups::strong_generators *&Strong_gens,
645 int verbose_level)
646{
647 int f_v = (verbose_level >= 1);
648 int f_vv = (verbose_level >= 2);
649 int q, Q, m;
651 //finite_field *FQ;
652 groups::sims *Sims;
654
655 if (f_v) {
656 cout << "action_global::lift_generators_to_subfield_structure" << endl;
657 }
658 Fq = S->Fq;
659 //FQ = S->FQ;
660 q = Fq->q;
661 Q = NT.i_power_j(q, s);
662 m = n / s;
663 if (m * s != n) {
664 cout << "action_global::lift_generators_to_subfield_structure "
665 "s must divide n" << endl;
666 exit(1);
667 }
668 if (f_v) {
669 cout << "action_global::lift_generators_to_subfield_structure "
670 "creating subfield structure" << endl;
671 }
672 if (f_v) {
673 cout << "n=" << n << endl;
674 cout << "s=" << s << endl;
675 cout << "m=" << m << endl;
676 cout << "q=" << q << endl;
677 cout << "Q=" << Q << endl;
678 }
679
683 int r;
684
685 AQ->group_order(order_GLmQ);
686
687
688 if (f_v) {
689 cout << "action_global::lift_generators_to_subfield_structure "
690 "order of GL(m,Q) = " << order_GLmQ << endl;
691 }
692 D.integral_division_by_int(order_GLmQ,
693 q - 1, target_go, r);
694 if (f_v) {
695 cout << "action_global::lift_generators_to_subfield_structure "
696 "target_go = " << target_go << endl;
697 }
698
699
700
703
704
705 gens = AQ->Strong_gens->gens;
706
707
708 if (f_v) {
709 cout << "action_global::lift_generators_to_subfield_structure "
710 "before lift_generators" << endl;
711 }
712 lift_generators(gens, gens1, Aq, S, n, verbose_level);
713
714 if (f_v) {
715 cout << "action_global::lift_generators_to_subfield_structure "
716 "after lift_generators" << endl;
717 }
718
719
720 if (f_v) {
721 cout << "action_global::lift_generators_to_subfield_structure "
722 "creating lifted group:" << endl;
723 }
724 //Aq->group_order(target_go);
726 gens1,
727 target_go,
728 0 /* verbose_level */);
729
730#if 0
731 Sims = A1->create_sims_from_generators_without_target_group_order(
732 gens1, MINIMUM(2, verbose_level - 3));
733#endif
734
735 if (f_v) {
736 cout << "action_global::lift_generators_to_subfield_structure "
737 "creating lifted group done" << endl;
738 }
739
741
742 Sims->group_order(go);
743
744 if (f_v) {
745 cout << "go=" << go << endl;
746 }
747
748
750
751 Strong_gens->init_from_sims(Sims, 0 /* verbose_level */);
752 if (f_vv) {
753 cout << "action_global::lift_generators_to_subfield_structure "
754 "strong generators are:" << endl;
755 Strong_gens->print_generators(cout);
756 }
757
758
759 FREE_OBJECT(gens1);
760 FREE_OBJECT(Sims);
761 if (f_v) {
762 cout << "action_global::lift_generators_to_subfield_structure done" << endl;
763 }
764}
765
766
768 int degree, int *perm, int verbose_level)
769{
771 degree, perm, 0, FALSE, TRUE, verbose_level);
772}
773
775 int degree, int *perm, int offset,
776 int f_do_it_anyway_even_for_big_degree,
777 int f_print_cycles_of_length_one, int verbose_level)
778{
779 int nb_gens = 1;
780 int i;
782 action *A;
783 int f_v = (verbose_level >= 1);
784 int f_vv = (verbose_level >= 2);
785 int f_big = FALSE;
786 int f_doit = TRUE;
787
788 if (f_v) {
789 cout << "action_global::perm_print_cycles_sorted_by_length, "
790 "degree=" << degree << endl;
791 }
792
793 if (degree > 500) {
794 f_big = TRUE;
795 }
796 A = NEW_OBJECT(action);
797 int f_no_base = FALSE;
798
799 A->init_permutation_group(degree, f_no_base, 0/*verbose_level*/);
800 Gens.init(A, verbose_level - 2);
801 Gens.allocate(nb_gens, verbose_level - 2);
802 for (i = 0; i < nb_gens; i++) {
803 Gens.copy_in(i, perm + i * degree);
804 }
805 if (f_vv) {
806 Gens.print(cout);
807 }
808
810
811 S.init(A, verbose_level - 2);
812 S.init_generators(Gens, verbose_level - 2);
813 S.compute_all_point_orbits(verbose_level);
814 if (f_v) {
815 cout << "after S.compute_all_point_orbits, "
816 "nb_orbits=" << S.nb_orbits << endl;
817 }
818 //S.print_orbit_lengths(cout);
819 //S.print_orbit_length_distribution(ost);
820
821 int j, f, l, length, F, L, h, a, b, m, orbit_idx;
822 int *orbit_len_sorted;
823 int *sorting_perm;
824 int *sorting_perm_inv;
825 int nb_types;
826 int *type_first;
827 int *type_len;
829
830 Sorting.int_vec_classify(S.nb_orbits, S.orbit_len, orbit_len_sorted,
831 sorting_perm, sorting_perm_inv,
832 nb_types, type_first, type_len);
833
834#if 0
835 ost << "permutation of degree " << degree << " with "
836 << S.nb_orbits << " orbits: " << endl;
837 for (i = 0; i < nb_types; i++) {
838 f = type_first[i];
839 l = type_len[i];
840 length = orbit_len_sorted[f];
841 if (l > 1) {
842 ost << l << " \\times ";
843 }
844 ost << length;
845 if (i < nb_types - 1)
846 ost << ", ";
847 }
848 ost << endl;
849 ost << "cycles in increasing length:" << endl;
850#endif
851 if (f_big) {
852 for (i = 0; i < nb_types; i++) {
853 f = type_first[i];
854 l = type_len[i];
855 length = orbit_len_sorted[f];
856 ost << l << " cycles of length " << length << endl;
857 }
858 }
859 if (f_big && !f_do_it_anyway_even_for_big_degree) {
860 f_doit = FALSE;
861 }
862 if (f_doit) {
863 for (i = 0; i < nb_types; i++) {
864 f = type_first[i];
865 l = type_len[i];
866 length = orbit_len_sorted[f];
867 if (length == 1 && !f_print_cycles_of_length_one) {
868 continue;
869 }
870 for (j = 0; j < l; j++) {
871 orbit_idx = sorting_perm_inv[f + j];
872 //ost << "orbit " << orbit_idx << ": ";
873 F = S.orbit_first[orbit_idx];
874 L = S.orbit_len[orbit_idx];
875 m = S.orbit[F];
876 for (h = 1; h < L; h++) {
877 if (S.orbit[F + h] < m)
878 m = S.orbit[F + h];
879 }
880 // now m is the least lement in the orbit
881 ost << "(";
882 a = m;
883 ost << (a + offset);
884 while (TRUE) {
885 b = perm[a];
886 if (b == m)
887 break;
888 ost << ", " << (b + offset);
889 a = b;
890 }
891 ost << ")";
892 if (length > 20) {
893 //ost << endl;
894 }
895 } // next j
896 //ost << endl;
897 } // next i
898 } // if
899 //ost << "done" << endl;
900
901#if 0
902 classify C;
903
904 C.init(S.orbit_len, S.nb_orbits, FALSE, 0);
905 ost << " cycle type: ";
906 C.print_file(ost, TRUE /* f_backwards */);
907#endif
908
909 FREE_int(orbit_len_sorted);
910 FREE_int(sorting_perm);
911 FREE_int(sorting_perm_inv);
912 FREE_int(type_first);
913 FREE_int(type_len);
914
915 FREE_OBJECT(A);
916}
917
918
919
921 groups::matrix_group *M1, groups::matrix_group *M2, int verbose_level)
922{
923 int f_v = (verbose_level >= 1);
924 action *A_direct_product;
925 action *Adp;
927 long int *points;
928 int nb_points;
929 int i;
930
931 if (f_v) {
932 cout << "action_global::init_direct_product_group_and_restrict" << endl;
933 cout << "M1=" << M1->label << endl;
934 cout << "M2=" << M2->label << endl;
935 }
936 A_direct_product = NEW_OBJECT(action);
937 A_direct_product = init_direct_product_group(M1, M2, verbose_level);
938 if (f_v) {
939 cout << "action_global::init_direct_product_group_and_restrict "
940 "after A_direct_product->init_direct_product_group" << endl;
941 }
942
943 P = A_direct_product->G.direct_product_group;
944 nb_points = P->degree_of_product_action;
945 points = NEW_lint(nb_points);
946 for (i = 0; i < nb_points; i++) {
947 points[i] = P->perm_offset_i[2] + i;
948 }
949
950 if (f_v) {
951 cout << "action_global::init_direct_product_group_and_restrict "
952 "before A_direct_product->restricted_action" << endl;
953 }
954 Adp = A_direct_product->restricted_action(points, nb_points,
955 verbose_level);
956 Adp->f_is_linear = FALSE;
957
958
959 if (f_v) {
960 cout << "action_global::init_direct_product_group_and_restrict "
961 "after A_direct_product->restricted_action" << endl;
962 }
963 return Adp;
964}
965
968 int verbose_level)
969{
970 int f_v = (verbose_level >= 1);
972 action *A;
973
974 if (f_v) {
975 cout << "action_global::init_direct_product_group" << endl;
976 cout << "M1=" << M1->label << endl;
977 cout << "M2=" << M2->label << endl;
978 }
979
980 A = NEW_OBJECT(action);
982
983
984
986 A->G.direct_product_group = P;
987 A->f_allocated = TRUE;
988
989 if (f_v) {
990 cout << "action_global::init_direct_product_group "
991 "before P->init" << endl;
992 }
993 P->init(M1, M2, verbose_level);
994 if (f_v) {
995 cout << "action_global::init_direct_product_group "
996 "after P->init" << endl;
997 }
998
999 A->f_is_linear = FALSE;
1000 A->dimension = 0;
1001
1002
1003 A->low_level_point_size = 0;
1004 if (f_v) {
1005 cout << "action_global::init_direct_product_group low_level_point_size="
1006 << A->low_level_point_size<< endl;
1007 }
1008
1009 A->label.assign(P->label);
1010 A->label_tex.assign(P->label_tex);
1011
1012
1013 if (f_v) {
1014 cout << "action_global::init_direct_product_group "
1015 "label=" << A->label << endl;
1016 }
1017
1018 A->degree = P->degree_overall;
1020
1023
1027
1028
1029
1030
1031 A->degree = P->degree_overall;
1032 if (f_v) {
1033 cout << "action_global::init_direct_product_group "
1034 "degree=" << A->degree << endl;
1035 }
1036
1038 A->Stabilizer_chain->allocate_base_data(A, P->base_length, verbose_level);
1039
1040 if (f_v) {
1041 cout << "action_global::init_direct_product_group "
1042 "base_len=" << A->base_len() << endl;
1043 }
1044
1045
1046 Lint_vec_copy(P->the_base, A->get_base(), A->base_len());
1048 A->get_transversal_length(), A->base_len());
1049
1050 int *gens_data;
1051 int gens_size;
1052 int gens_nb;
1053
1054 if (f_v) {
1055 cout << "action_global::init_direct_product_group "
1056 "before W->make_strong_generators_data" << endl;
1057 }
1058 P->make_strong_generators_data(gens_data,
1059 gens_size, gens_nb, verbose_level - 1);
1060 if (f_v) {
1061 cout << "action_global::init_direct_product_group "
1062 "after W->make_strong_generators_data" << endl;
1063 }
1065 if (f_v) {
1066 cout << "action_global::init_direct_product_group "
1067 "before A->Strong_gens->init_from_data" << endl;
1068 }
1069
1071
1073 gens_data, gens_nb, gens_size,
1075 nice_gens,
1076 verbose_level - 1);
1077 if (f_v) {
1078 cout << "action_global::init_direct_product_group "
1079 "after A->Strong_gens->init_from_data" << endl;
1080 }
1081 FREE_OBJECT(nice_gens);
1083 FREE_int(gens_data);
1084
1085 groups::sims *S;
1086
1088
1089 S->init(A, verbose_level - 2);
1090 if (f_v) {
1091 cout << "action_global::init_direct_product_group "
1092 "before S->init_generators" << endl;
1093 }
1094 S->init_generators(*A->Strong_gens->gens, verbose_level);
1095 if (f_v) {
1096 cout << "action_global::init_direct_product_group "
1097 "after S->init_generators" << endl;
1098 }
1099 if (f_v) {
1100 cout << "action_global::init_direct_product_group "
1101 "before S->compute_base_orbits_known_length" << endl;
1102 }
1104 if (f_v) {
1105 cout << "action_global::init_direct_product_group "
1106 "after S->compute_base_orbits_known_length" << endl;
1107 }
1108
1109
1110 if (f_v) {
1111 cout << "action_global::init_direct_product_group "
1112 "before init_sims_only" << endl;
1113 }
1114
1115 A->init_sims_only(S, verbose_level);
1116
1117 if (f_v) {
1118 cout << "action_global::init_direct_product_group "
1119 "after init_sims_only" << endl;
1120 }
1121
1122 A->compute_strong_generators_from_sims(0/*verbose_level - 2*/);
1123
1124 if (f_v) {
1125 cout << "action_global::init_direct_product_group, finished setting up "
1126 << A->label;
1127 cout << ", a permutation group of degree " << A->degree << " ";
1128 cout << "and of order ";
1129 A->print_group_order(cout);
1130 cout << endl;
1131 //cout << "make_element_size=" << make_element_size << endl;
1132 //cout << "base_len=" << base_len << endl;
1133 //cout << "f_semilinear=" << f_semilinear << endl;
1134 }
1135 return A;
1136}
1137
1138
1139
1144 data_structures::partitionstack *&Stack, int verbose_level)
1145{
1146 int f_v = (verbose_level >= 1);
1147
1148 if (f_v) {
1149 cout << "action_global::compute_decomposition_based_on_orbits" << endl;
1150 }
1151
1154
1155
1158
1159 if (f_v) {
1160 cout << "action_global::compute_decomposition_based_on_orbits "
1161 "before S1->allocate" << endl;
1162 }
1163 S1->allocate(P->N_points, 0 /* verbose_level */);
1164 S2->allocate(P->N_lines, 0 /* verbose_level */);
1165
1166 if (f_v) {
1167 cout << "action_global::compute_decomposition_based_on_orbits "
1168 "before Sch1->get_orbit_partition" << endl;
1169 }
1170 Sch1->get_orbit_partition(*S1, 0 /*verbose_level*/);
1171 if (f_v) {
1172 cout << "action_global::compute_decomposition_based_on_orbits "
1173 "before Sch2->get_orbit_partition" << endl;
1174 }
1175 Sch2->get_orbit_partition(*S2, 0 /*verbose_level*/);
1176 if (f_v) {
1177 cout << "action_global::compute_decomposition_based_on_orbits "
1178 "after Sch2->get_orbit_partition" << endl;
1179 }
1180
1181
1182
1183
1184 if (f_v) {
1185 cout << "action_global::compute_decomposition_based_on_orbits "
1186 "before P->compute_decomposition" << endl;
1187 }
1188 P->compute_decomposition(S1, S2, Inc, Stack, verbose_level);
1189
1190 FREE_OBJECT(S1);
1191 FREE_OBJECT(S2);
1192
1193 if (f_v) {
1194 cout << "action_global::compute_decomposition_based_on_orbits done" << endl;
1195 }
1196}
1197
1198
1203 data_structures::partitionstack *&Stack, int verbose_level)
1204{
1205 int f_v = (verbose_level >= 1);
1206
1207 if (f_v) {
1208 cout << "action_global::compute_decomposition_based_on_orbit_length" << endl;
1209 }
1210
1211 int *L1, *L2;
1212
1213 Sch1->get_orbit_length(L1, 0 /* verbose_level */);
1214 Sch2->get_orbit_length(L2, 0 /* verbose_level */);
1215
1217
1218 T1.init(L1, Sch1->A->degree, FALSE, 0);
1219
1220 T2.init(L2, Sch2->A->degree, FALSE, 0);
1221
1222
1223
1224 if (f_v) {
1225 cout << "action_global::compute_decomposition_based_on_orbit_length "
1226 "before P->compute_decomposition" << endl;
1227 }
1228 P->compute_decomposition_based_on_tally(&T1, &T2, Inc, Stack, verbose_level);
1229
1230
1231 FREE_int(L1);
1232 FREE_int(L2);
1233
1234 if (f_v) {
1235 cout << "action_global::compute_decomposition_based_on_orbit_length done" << endl;
1236 }
1237}
1238
1239
1240
1241
1242
1244 int *Elt, void *data, int verbose_level)
1245{
1246 //verbose_level += 5;
1247 int f_v = (verbose_level >= 1);
1248
1249 if (f_v) {
1250 cout << "action_global::callback_choose_random_generator_orthogonal "
1251 "iteration=" << iteration << endl;
1252 }
1253
1255 action *A = ss->GA;
1256 action *subaction = ss->KA;
1258#if 0
1259 int f_siegel = TRUE;
1260 int f_reflection = TRUE;
1261 int f_similarity = TRUE;
1262 int f_semisimilarity = TRUE;
1263#endif
1264
1267
1268 AO = A->G.AO;
1269 O = AO->O;
1270
1271 M = subaction->G.matrix_grp;
1272 if (f_v) {
1273 cout << "action_global::callback_choose_random_generator_orthogonal "
1274 "iteration=" << iteration
1275 << " before M->orthogonal_group_random_generator"
1276 << endl;
1277 }
1283 Elt, verbose_level - 2);
1284 //M->GL_invert_internal(Elt, Elt + M->elt_size_int_half, 0);
1285 if (f_v) {
1286 cout << "action_global::callback_choose_random_generator_orthogonal "
1287 "iteration=" << iteration
1288 << " after M->orthogonal_group_random_generator"
1289 << endl;
1290 }
1291
1292 if (f_v) {
1293 cout << "action_global::callback_choose_random_generator_orthogonal "
1294 "iteration=" << iteration << " done" << endl;
1295 }
1296}
1297
1298
1299}}}
1300
void matrix_make_block_matrix_2x2(int *Mtx, int k, int *A, int *B, int *C, int *D)
Definition: int_vec.cpp:885
data structure for set partitions following Jeffrey Leon
a collection of functions related to sorted vectors
void int_vec_classify(int length, int *the_vec, int *&the_vec_sorted, int *&sorting_perm, int *&sorting_perm_inv, int &nb_types, int *&type_first, int *&type_len)
Definition: sorting.cpp:1503
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 finite field as a vector space over a subfield
void retract_matrix(int *Mq, int n, int *MQ, int m, int verbose_level)
void lift_matrix(int *MQ, int m, int *Mq, int verbose_level)
interface for various incidence geometries
Definition: geometry.h:1099
projective space PG(n,q) of dimension n over Fq
Definition: geometry.h:1916
void compute_decomposition_based_on_tally(data_structures::tally *T1, data_structures::tally *T2, incidence_structure *&Inc, data_structures::partitionstack *&Stack, int verbose_level)
void compute_decomposition(data_structures::partitionstack *S1, data_structures::partitionstack *S2, incidence_structure *&Inc, data_structures::partitionstack *&Stack, int verbose_level)
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
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
void make_generators_stabilizer_of_three_components(action *A_PGL_n_q, action *A_PGL_k_q, int k, data_structures_groups::vector_ge *gens, int verbose_level)
void retract_generators(data_structures_groups::vector_ge *gens_in, data_structures_groups::vector_ge *&gens_out, action *AQ, field_theory::subfield_structure *S, int n, int verbose_level)
void set_orthogonal_group_type(int f_siegel, int f_reflection, int f_similarity, int f_semisimilarity)
action * init_direct_product_group(groups::matrix_group *M1, groups::matrix_group *M2, int verbose_level)
void action_print_symmetry_group_type(std::ostream &ost, symmetry_group_type a)
void compute_decomposition_based_on_orbits(geometry::projective_space *P, groups::schreier *Sch1, groups::schreier *Sch2, geometry::incidence_structure *&Inc, data_structures::partitionstack *&Stack, int verbose_level)
void perm_print_cycles_sorted_by_length_offset(std::ostream &ost, int degree, int *perm, int offset, int f_do_it_anyway_even_for_big_degree, int f_print_cycles_of_length_one, int verbose_level)
void lift_generators(data_structures_groups::vector_ge *gens_in, data_structures_groups::vector_ge *&gens_out, action *Aq, field_theory::subfield_structure *S, int n, int verbose_level)
action * init_direct_product_group_and_restrict(groups::matrix_group *M1, groups::matrix_group *M2, int verbose_level)
void make_generators_stabilizer_of_two_components(action *A_PGL_n_q, action *A_PGL_k_q, int k, data_structures_groups::vector_ge *gens, int verbose_level)
void perm_print_cycles_sorted_by_length(std::ostream &ost, int degree, int *perm, int verbose_level)
void lift_generators_to_subfield_structure(int n, int s, field_theory::subfield_structure *S, action *Aq, action *AQ, groups::strong_generators *&Strong_gens, int verbose_level)
void compute_decomposition_based_on_orbit_length(geometry::projective_space *P, groups::schreier *Sch1, groups::schreier *Sch2, geometry::incidence_structure *&Inc, data_structures::partitionstack *&Stack, int verbose_level)
void compute_generators_GL_n_q(int *&Gens, int &nb_gens, int &elt_size, int n, field_theory::finite_field *F, data_structures_groups::vector_ge *&nice_gens, int verbose_level)
interface to the implementation functions for group actions
Definition: actions.h:1081
a permutation group in a fixed action.
Definition: actions.h:99
action * restricted_action(long int *points, int nb_points, int verbose_level)
void element_print_quick(void *elt, std::ostream &ost)
Definition: action_cb.cpp:353
void print_quick(std::ostream &ost, void *elt)
Definition: action_cb.cpp:137
groups::strong_generators * Strong_gens
Definition: actions.h:130
void init_sims_only(groups::sims *G, int verbose_level)
Definition: action.cpp:709
void compute_strong_generators_from_sims(int verbose_level)
Definition: action.cpp:750
void init_projective_group(int n, field_theory::finite_field *F, int f_semilinear, int f_basis, int f_init_sims, data_structures_groups::vector_ge *&nice_gens, int verbose_level)
stabilizer_chain_base_data * Stabilizer_chain
Definition: actions.h:178
void make_element(int *Elt, int *data, int verbose_level)
Definition: action.cpp:1875
void element_move(void *a, void *b, int verbose_level)
Definition: action_cb.cpp:335
void init_permutation_group(int degree, int f_no_base, int verbose_level)
void group_order(ring_theory::longinteger_object &go)
Definition: action.cpp:2223
groups::sims * create_sims_from_generators_with_target_group_order(data_structures_groups::vector_ge *gens, ring_theory::longinteger_object &target_go, int verbose_level)
the transversals in the stabilizer subgroup chain (Sims chain)
Definition: actions.h:1214
void init(actions::action *A, int verbose_level)
Definition: vector_ge.cpp:55
the direct product of two matrix groups in product action
Definition: groups.h:26
void init(matrix_group *M1, matrix_group *M2, int verbose_level)
void make_strong_generators_data(int *&data, int &size, int &nb_gens, int verbose_level)
a matrix group over a finite field in projective, vector space or affine action
Definition: groups.h:318
void orthogonal_group_random_generator(actions::action *A, orthogonal_geometry::orthogonal *O, int f_siegel, int f_reflection, int f_similarity, int f_semisimilarity, int *Elt, int verbose_level)
Schreier Sims algorithm to create the stabilizer chain of a permutation group.
Definition: groups.h:1188
Schreier trees for orbits of groups on points.
Definition: groups.h:839
void compute_all_point_orbits(int verbose_level)
Definition: schreier.cpp:988
void get_orbit_length(int *&orbit_length, int verbose_level)
Definition: schreier.cpp:2751
void init_generators(data_structures_groups::vector_ge &generators, int verbose_level)
Definition: schreier.cpp:373
void init(actions::action *A, int verbose_level)
Definition: schreier.cpp:308
void get_orbit_partition(data_structures::partitionstack &S, int verbose_level)
Definition: schreier.cpp:2112
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 compute_base_orbits_known_length(int *tl, int verbose_level)
Definition: sims_main.cpp:57
void init_generators(data_structures_groups::vector_ge &generators, int verbose_level)
Definition: sims.cpp:660
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
void init_from_data(actions::action *A, int *data, int nb_elements, int elt_size, int *transversal_length, data_structures_groups::vector_ge *&nice_gens, int verbose_level)
void init_from_sims(groups::sims *S, int verbose_level)
data_structures_groups::vector_ge * gens
Definition: groups.h:1708
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define MINIMUM(x, y)
Definition: foundations.h:216
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define 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 EVEN(x)
Definition: foundations.h:221
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define NEW_lint(n)
Definition: foundations.h:628
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
void callback_choose_random_generator_orthogonal(int iteration, int *Elt, void *data, int verbose_level)
symmetry_group_type
enumeration to distinguish between the various types of group actions
the orbiter library for the classification of combinatorial objects
induced_actions::action_on_orthogonal * AO