Orbiter 2022
Combinatorial Objects
wreath_product.cpp
Go to the documentation of this file.
1// wreath_product.cpp
2//
3// Anton Betten
4//
5// started: August 2, 2018
6
7
8
9
11#include "group_actions.h"
12
13using namespace std;
14
15
16namespace orbiter {
17namespace layer3_group_actions {
18namespace groups {
19
20
21static void dimensions(int n, int &nb_rows, int &nb_cols);
22static void place_binary(long int h, int &i, int &j);
23
24
26{
27 M = NULL;
28 A_mtx = NULL;
29 F = NULL;
30 q = 0;
31 nb_factors = 0;
32
33 //label[0] = 0;
34 //label_tex[0] = 0;
35
43
44 P = NULL;
45 elt_size_int = 0;
46
47 perm_offset_i = NULL;
48 mtx_size = NULL;
49 index_set1 = NULL;
50 index_set2 = NULL;
51 u = NULL;
52 v = NULL;
53 w = NULL;
54 A1 = NULL;
55 A2 = NULL;
56 A3 = NULL;
57 tmp_Elt1 = NULL;
58 tmp_perm1 = NULL;
59 tmp_perm2 = NULL;
60 induced_perm = NULL;
62 bits_per_elt = 0;
63 char_per_elt = 0;
64
65 elt1 = NULL;
67 base_for_component = NULL;
68 tl_for_component = NULL;
69
70 base_length = 0;
71 the_base = NULL;
73
74 Elts = NULL;
75
76 rank_one_tensors = NULL;
79
81
82 TR = NULL;
83 Prev = NULL;
84
85
86 //null();
87}
88
90{
91 freeself();
92}
93
95{
96
97}
98
100{
101 int verbose_level = 0;
102 int f_v = (verbose_level >= 1);
103
104 if (f_v) {
105 cout << "wreath_product::freeself" << endl;
106 }
107 if (mtx_size) {
109 }
110 if (perm_offset_i) {
112 }
113 if (index_set1) {
115 }
116 if (index_set2) {
118 }
119 if (u) {
120 FREE_int(u);
121 }
122 if (v) {
123 FREE_int(v);
124 }
125 if (w) {
126 FREE_int(w);
127 }
128 if (A1) {
129 FREE_int(A1);
130 }
131 if (A2) {
132 FREE_int(A2);
133 }
134 if (A3) {
135 FREE_int(A3);
136 }
137 if (tmp_Elt1) {
139 }
140 if (tmp_perm1) {
142 }
143 if (tmp_perm2) {
145 }
146 if (induced_perm) {
148 }
149 if (P) {
150 FREE_OBJECT(P);
151 }
152 if (elt1) {
154 }
155 if (Elts) {
157 }
158 if (base_for_component) {
160 }
161 if (tl_for_component) {
163 }
164 if (the_base) {
166 }
169 }
170 if (rank_one_tensors) {
171 FREE_int((int *) rank_one_tensors);
172 }
175 }
178 }
179 if (TR) {
180 FREE_char(TR);
181 }
182 if (Prev) {
183 FREE_int((int *) Prev);
184 }
185 null();
186 if (f_v) {
187 cout << "wreath_product::freeself finished" << endl;
188 }
189}
190
192 actions::action *A_mtx, int nb_factors,
193 int verbose_level)
194{
195 int f_v = (verbose_level >= 1);
196 int i;
199
200 if (f_v) {
201 cout << "wreath_product::init_tensor_wreath_product" << endl;
202 }
203 if (M->f_projective) {
204 cout << "wreath_product::init_tensor_wreath_product "
205 "the input group must be of type general linear "
206 "(not projective)" << endl;
207 exit(1);
208 }
209 if (M->f_affine) {
210 cout << "wreath_product::init_tensor_wreath_product "
211 "the input group must be of type general linear "
212 "(not affine)" << endl;
213 exit(1);
214 }
218 F = M->GFq;
219 q = F->q;
220
222 if (f_v) {
223 cout << "wreath_product::init_tensor_wreath_product before P->init" << endl;
224 }
225 P->init(nb_factors, 10 /* page_length_log */, 0 /* verbose_level */);
226 if (f_v) {
227 cout << "wreath_product::init_tensor_wreath_product after P->init" << endl;
228 }
229
230 char str1[1000];
231 char str2[1000];
232
233 sprintf(str1, "_wreath_Sym%d", nb_factors);
234 sprintf(str2, " \\wr {\\rm Sym}(%d)", nb_factors);
235
236 label.assign(M->label);
237 label.append(str1);
238 label_tex.assign(M->label_tex);
239 label_tex.append(str2);
240
248 if (f_v) {
249 cout << "wreath_product::init_tensor_wreath_product "
250 "computing degree_of_tensor_action" << endl;
251 }
253 (NT.i_power_j_lint_safe(q, dimension_of_tensor_action, verbose_level) - 1) / (q - 1);
254 // warning: int overflow possible
255
256 if (f_v) {
257 cout << "wreath_product::init_tensor_wreath_product "
258 "degree_of_tensor_action = " << degree_of_tensor_action << endl;
259 }
262 if (f_v) {
263 cout << "wreath_product::init_tensor_wreath_product "
264 "degree_overall = " << degree_overall << endl;
265 }
266 if (f_v) {
267 cout << "wreath_product::init_tensor_wreath_product "
268 "degree_of_matrix_group = "
269 << degree_of_matrix_group << endl;
270 cout << "wreath_product::init_tensor_wreath_product "
271 "dimension_of_matrix_group = "
272 << dimension_of_matrix_group << endl;
273 cout << "wreath_product::init_tensor_wreath_product "
274 "low_level_point_size = "
275 << low_level_point_size << endl;
276 cout << "wreath_product::init_tensor_wreath_product "
277 "dimension_of_tensor_action = "
279 cout << "wreath_product::init_tensor_wreath_product "
280 "degree_of_tensor_action = "
281 << degree_of_tensor_action << endl;
282 cout << "wreath_product::init_tensor_wreath_product "
283 "degree_overall = " << degree_overall << endl;
284 }
286 // one more so it can also be used to indicate
287 // the start of the tensor product action also.
289 for (i = 1; i <= nb_factors; i++) {
290 // note equality here!
292 }
294 for (i = 0; i < nb_factors; i++) {
296 }
306 if (f_v) {
307 cout << "wreath_product::init_tensor_wreath_product "
308 "elt_size_int = " << elt_size_int << endl;
309 }
314
318 char_per_elt = nb_factors + ((bits_per_elt + 7) >> 3);
320 if (f_v) {
321 cout << "wreath_product::init_tensor_wreath_product "
322 "bits_per_digit = " << bits_per_digit << endl;
323 cout << "wreath_product::init_tensor_wreath_product "
324 "bits_per_elt = " << bits_per_elt << endl;
325 cout << "wreath_product::init_tensor_wreath_product "
326 "char_per_elt = " << char_per_elt << endl;
327 }
330 FALSE /*f_semilinear */, verbose_level - 1);
331 if (f_v) {
332 cout << "wreath_product::init_tensor_wreath_product "
333 "base_len_in_component = " << base_len_in_component << endl;
334 }
337
338
340
341
344 FALSE /* f_semilinear */,
347 verbose_level - 1);
348 if (f_v) {
349 cout << "wreath_product::init_tensor_wreath_product "
350 "base_for_component = ";
352 cout << endl;
353 cout << "wreath_product::init_tensor_wreath_product "
354 "tl_for_component = ";
356 cout << endl;
357 }
358
360 Elts->init(char_per_elt /* entry_size */,
361 10 /* page_length_log */, verbose_level);
362
363 if (f_v) {
364 cout << "wreath_product::init_tensor_wreath_product "
365 "before compute_base_and_transversals" << endl;
366 }
367 compute_base_and_transversals(verbose_level);
368 if (f_v) {
369 cout << "wreath_product::init_tensor_wreath_product "
370 "after compute_base_and_transversals" << endl;
371 }
372 if (f_v) {
373 cout << "wreath_product::init_tensor_wreath_product "
374 "the_base = ";
376 cout << endl;
377 cout << "wreath_product::init_tensor_wreath_product "
378 "the_transversal_length = ";
380 cout << endl;
381 }
382
383
384 if (f_v) {
385 cout << "wreath_product::init_tensor_wreath_product "
386 "before create_all_rank_one_tensors" << endl;
387 }
391 verbose_level);
392 if (f_v) {
393 cout << "wreath_product::init_tensor_wreath_product "
394 "after create_all_rank_one_tensors" << endl;
395 }
396
397 save_rank_one_tensors(verbose_level);
398
399
400
401 if (f_v) {
402 cout << "wreath_product::init_tensor_wreath_product done" << endl;
403 }
404}
405
407{
408 int f_v = (verbose_level >= 1);
409
410 if (f_v) {
411 cout << "wreath_product::compute_tensor_ranks" << endl;
412 }
413 compute_tensor_ranks(TR, Prev, verbose_level);
414}
415
416void wreath_product::unrank_point(long int a, int *v, int verbose_level)
417{
418 if (a < nb_factors) {
419 cout << "wreath_product::unrank_point "
420 "we are in the permutation, cannot unrank" << endl;
421 exit(1);
422 }
423 a -= nb_factors;
424 if (a < nb_factors * M->degree) {
425 cout << "wreath_product::unrank_point "
426 "we are in the projected components, cannot unrank" << endl;
427 exit(1);
428 }
429 a -= nb_factors * M->degree;
432}
433
434long int wreath_product::rank_point(int *v, int verbose_level)
435{
436 long int a, b;
437
438 a = nb_factors + nb_factors * M->degree;
441 a += b;
442 return a;
443}
444
445long int wreath_product::element_image_of(int *Elt, long int a, int verbose_level)
446{
447 int f_v = (verbose_level >= 1);
448 long int f, a0, b, c;
450
451 if (f_v) {
452 cout << "wreath_product::element_image_of" << endl;
453 }
454 a0 = a;
455 b = 0;
456 if (a < nb_factors) {
457 if (f_v) {
458 cout << "wreath_product::element_image_of "
459 "we are in the permutation" << endl;
460 }
461 b = Elt[a];
462 }
463 else {
464 a -= nb_factors;
465 b += nb_factors;
466 for (f = 0; f < nb_factors; f++) {
467 if (a < M->degree) {
468 if (f_v) {
469 cout << "wreath_product::element_image_of "
470 "we are in component " << f
471 << " reduced input a=" << a << endl;
472 }
473 Gg.AG_element_unrank(q, u, 1, M->n, a);
475 M->n, M->n);
476 c = Gg.AG_element_rank(q, v, 1, M->n);
477 if (f_v) {
478 cout << "wreath_product::element_image_of "
479 "we are in component " << f
480 << " reduced output c=" << c << endl;
481 }
482 b += c;
483 break;
484 }
485 else {
486 a -= M->degree;
487 b += M->degree;
488 }
489 } // next f
490 if (f == nb_factors) {
491 if (f_v) {
492 cout << "wreath_product::element_image_of "
493 "we are in the tensor product component "
494 "reduced input a = " << a << endl;
495 }
498 if (f_v) {
499 cout << "wreath_product::element_image_of "
500 "u = ";
502 cout << endl;
503 }
504 create_matrix(Elt, A3, 0 /* verbose_level */);
505 if (f_v) {
506 cout << "wreath_product::element_image_of "
507 "A3 = " << endl;
511 }
515 if (f_v) {
516 cout << "wreath_product::element_image_of "
517 "v = ";
519 cout << endl;
520 }
521 apply_permutation(Elt, v, w, verbose_level);
522 if (f_v) {
523 cout << "wreath_product::element_image_of "
524 "w = ";
526 cout << endl;
527 }
530 if (f_v) {
531 cout << "wreath_product::element_image_of "
532 "we are in tensor product component " << f
533 << " reduced output c=" << c << endl;
534 }
535 b += c;
536 if (f_v) {
537 cout << "wreath_product::element_image_of "
538 "we are in tensor product component " << f
539 << " output b=" << b << endl;
540 }
541 }
542 }
543 if (f_v) {
544 cout << "wreath_product::element_image_of " << a0
545 << " maps to " << b << endl;
546 }
547 return b;
548}
549
551 int *input, int *output, int verbose_level)
552// we assume that we are in the tensor product domain
553{
554 int f_v = (verbose_level >= 1);
555
556 if (f_v) {
557 cout << "wreath_product::element_image_of_low_level" << endl;
558 }
559 if (f_v) {
560 cout << "wreath_product::element_image_of_low_level "
561 "input = ";
563 cout << endl;
564 }
565 create_matrix(Elt, A3, 0 /* verbose_level */);
566 if (f_v) {
567 cout << "wreath_product::element_image_of_low_level "
568 "A3 = " << endl;
572 }
576 if (f_v) {
577 cout << "wreath_product::element_image_of_low_level "
578 "v = ";
580 cout << endl;
581 }
582 apply_permutation(Elt, v, output, verbose_level - 1);
583 if (f_v) {
584 cout << "wreath_product::element_image_of_low_level "
585 "output = ";
587 cout << endl;
588 }
589 if (f_v) {
590 cout << "wreath_product::element_image_of_low_level done" << endl;
591 }
592}
593
595{
596 int f;
597
598 P->one(Elt);
599 for (f = 0; f < nb_factors; f++) {
600 M->GL_one(Elt + offset_i(f));
601 }
602}
603
605{
606 int f; //, scalar;
607
608 if (!P->is_one(Elt)) {
609 return FALSE;
610 }
611 for (f = 0; f < nb_factors; f++) {
614 return FALSE;
615 }
616#if 0
617 if (!F->is_scalar_multiple_of_identity_matrix(
619 scalar)) {
620 return FALSE;
621 }
622#endif
623 }
624 return TRUE;
625}
626
627void wreath_product::element_mult(int *A, int *B, int *AB,
628 int verbose_level)
629{
630 int f_v = (verbose_level >= 1);
631 int f, g;
633
634 if (f_v) {
635 cout << "wreath_product::element_mult" << endl;
636 }
637 Combi.perm_mult(A, B, AB, nb_factors);
638 for (f = 0; f < nb_factors; f++) {
639 g = A[f];
640 M->GL_mult(A + offset_i(f),
641 B + offset_i(g),
642 AB + offset_i(f),
643 0 /* verbose_level */);
644 }
645 if (f_v) {
646 cout << "wreath_product::element_mult done" << endl;
647 }
648}
649
650void wreath_product::element_move(int *A, int *B, int verbose_level)
651{
652 int f_v = (verbose_level >= 1);
653
654 if (f_v) {
655 cout << "wreath_product::element_move" << endl;
656 }
658
659#if 0
660 if (f_v) {
661 element_print_easy(B, cout);
662 }
663#endif
664
665 if (f_v) {
666 cout << "wreath_product::element_move done" << endl;
667 }
668}
669
670void wreath_product::element_invert(int *A, int *Av, int verbose_level)
671{
672 int f_v = (verbose_level >= 1);
673 int f, g;
675
676 if (f_v) {
677 cout << "wreath_product::element_invert" << endl;
678 }
679 Combi.perm_inverse(A, Av, nb_factors);
680 for (f = 0; f < nb_factors; f++) {
681 g = A[f];
682 M->GL_invert(A + offset_i(f), Av + offset_i(g));
683 }
684 if (f_v) {
685 cout << "wreath_product::element_invert done" << endl;
686 }
687}
688
690{
691 int i, j, h, k, a;
693
694 for (i = 0; i < dimension_of_tensor_action; i++) {
696 index_set1, 1, nb_factors, i);
697 for (h = 0; h < nb_factors; h++) {
698 a = index_set1[h];
699 k = Elt[h];
700 index_set2[k] = a;
701 }
704 perm[i] = j;
705 }
706}
707
708
710 int *v_in, int *v_out, int verbose_level)
711{
712 int f_v = (verbose_level >= 1);
713 int i, j;
714
715 if (f_v) {
716 cout << "wreath_product::apply_permutation" << endl;
717 }
718 if (f_v) {
719 cout << "wreath_product::apply_permutation perm=";
720 Int_vec_print(cout, Elt, nb_factors);
721 cout << endl;
722 }
723 if (f_v) {
724 cout << "wreath_product::apply_permutation v_in=";
726 cout << endl;
727 }
729
730 //perm_inverse(Elt, tmp_perm1, nb_factors);
731
733 if (f_v) {
734 cout << "wreath_product::apply_permutation induced_perm=";
736 cout << endl;
737 }
738
739 for (i = 0; i < dimension_of_tensor_action; i++) {
740 j = induced_perm[i];
741 v_out[j] = v_in[i];
742 }
743
744 if (f_v) {
745 cout << "wreath_product::apply_permutation" << endl;
746
747 cout << "i : in[i] : perm[i] : out[i] " << endl;
748 for (i = 0; i < dimension_of_tensor_action; i++) {
749 cout << setw(3) << i << " & " << setw(3) << v_in[i]
750 << " & " << setw(3) << induced_perm[i]
751 << " & " << setw(3) << v_out[i] << endl;
752 }
753 }
754 if (f_v) {
755 cout << "wreath_product::apply_permutation v_out=";
757 cout << endl;
758 }
759 if (f_v) {
760 cout << "wreath_product::apply_permutation done" << endl;
761 }
762}
763
765{
766 return P->elt_size_int + f * M->elt_size_int;
767}
768
769void wreath_product::create_matrix(int *Elt, int *A, int verbose_level)
770{
771 int f_v = (verbose_level >= 1);
772 int f, N;
773
774 if (f_v) {
775 cout << "wreath_product::create_matrix" << endl;
776 }
777 for (f = 0; f < nb_factors; f++) {
778 if (f == 0) {
779 Int_vec_copy(Elt + offset_i(f), A1,
782 }
783 else {
785 A1, Elt + offset_i(f),
787 A2, N, 0 /* verbose_level */);
788 Int_vec_copy(A2, A1, N * N);
789 }
790 if (f_v) {
791 cout << "wreath_product::create_matrix "
792 "after step " << f << ":" << endl;
793 Int_matrix_print(A1, N, N);
794 }
795 }
796 Int_vec_copy(A1, A,
798 if (f_v) {
799 cout << "wreath_product::create_matrix done" << endl;
800 }
801}
802
804{
805 int i, j, f;
806
807 for (f = 0; f < nb_factors; f++) {
808 elt[f] = (uchar) Elt[f];
809 }
810 for (f = 0; f < nb_factors; f++) {
811 for (i = 0; i < dimension_of_matrix_group; i++) {
812 for (j = 0; j < dimension_of_matrix_group; j++) {
813 put_digit(elt, f, i, j,
814 (Elt + offset_i(f))[i * dimension_of_matrix_group + j]);
815 }
816 }
817 }
818}
819
821{
822 int i, j, f;
823 int *m;
824
825 for (f = 0; f < nb_factors; f++) {
826 Elt[f] = elt[f];
827 }
828 for (f = 0; f < nb_factors; f++) {
829 m = Elt + offset_i(f);
830 for (i = 0; i < dimension_of_matrix_group; i++) {
831 for (j = 0; j < dimension_of_matrix_group; j++) {
832 m[i * dimension_of_matrix_group + j] =
833 get_digit(elt, f, i, j);
834 }
835 }
837 0 /*verbose_level - 2*/);
838 }
839}
840
841void wreath_product::put_digit(uchar *elt, int f, int i, int j, int d)
842{
846 int h, h1, a;
847
848 for (h = 0; h < bits_per_digit; h++) {
849 h1 = h0 + h;
850
851 if (d & 1) {
852 a = 1;
853 }
854 else {
855 a = 0;
856 }
857 D.bitvector_m_ii(elt + nb_factors, h1, a);
858 d >>= 1;
859 }
860}
861
862int wreath_product::get_digit(uchar *elt, int f, int i, int j)
863{
867 int h, h1, a, d;
868
869 d = 0;
870 for (h = bits_per_digit - 1; h >= 0; h--) {
871 h1 = h0 + h;
872
873 a = D.bitvector_s_i(elt + nb_factors, h1);
874 d <<= 1;
875 if (a) {
876 d |= 1;
877 }
878 }
879 return d;
880}
881
883 int f, int *Elt_component)
884{
885 int g;
886
887 P->one(Elt);
888 for (g = 0; g < nb_factors; g++) {
889 if (g == f) {
890 M->GL_copy(Elt_component, Elt + offset_i(g));
891 }
892 else {
893 M->GL_one(Elt + offset_i(g));
894 }
895 }
896}
897
899{
900 int f;
901
902 for (f = 0; f < nb_factors; f++) {
903 Elt[f] = perm[f];
904 }
905 for (f = 0; f < nb_factors; f++) {
906 M->GL_one(Elt + offset_i(f));
907 }
908}
909
910void wreath_product::make_element(int *Elt, int *data, int verbose_level)
911{
912 int f_v = (verbose_level >= 1);
913 int f, offset;
914
915 if (f_v) {
916 cout << "wreath_product::make_element" << endl;
917 }
918 if (f_v) {
919 cout << "wreath_product::make_element data:" << endl;
920 Int_vec_print(cout, data, make_element_size);
921 cout << endl;
922 }
923 for (f = 0; f < nb_factors; f++) {
924 Elt[f] = data[f];
925 }
926 offset = nb_factors;
927 for (f = 0; f < nb_factors; f++) {
928 M->make_element(Elt + offset_i(f), data + offset,
929 0 /* verbose_level */);
930 offset += M->elt_size_int_half;
931 }
932 if (f_v) {
933 cout << "wreath_product::make_element created this element:" << endl;
934 element_print_easy(Elt, cout);
935 }
936 if (f_v) {
937 cout << "wreath_product::make_element done" << endl;
938 }
939}
940
942{
943 int f;
944
945 for (f = 0; f < nb_factors; f++) {
946 ost << Elt[f] << ",";
947 }
948 for (f = 0; f < nb_factors; f++) {
949 M->GL_print_for_make_element(Elt + offset_i(f), ost);
950 }
951}
952
953void wreath_product::element_print_easy(int *Elt, ostream &ost)
954{
955 int f;
956
957 ost << "begin element of wreath product: " << endl;
958 ost << "[";
959 for (f = 0; f < nb_factors; f++) {
960 ost << Elt[f];
961 if (f < nb_factors - 1) {
962 ost << ", ";
963 }
964 }
965 ost << "]" << endl;
966 for (f = 0; f < nb_factors; f++) {
967 ost << "factor " << f << ":" << endl;
968 M->GL_print_easy(Elt + offset_i(f), ost);
969 }
970 ost << "end element of wreath product" << endl;
971}
972
973void wreath_product::element_print_latex(int *Elt, ostream &ost)
974{
975 int f;
977
978 ost << "\\left(";
979 for (f = 0; f < nb_factors; f++) {
980 M->GL_print_latex(Elt + offset_i(f), ost);
981 }
982 ost << "; \\;" << endl;
983 Combi.perm_print(ost, Elt, nb_factors);
984#if 0
985 ost << "[";
986 for (f = 0; f < nb_factors; f++) {
987 ost << Elt[f];
988 if (f < nb_factors - 1) {
989 ost << ", ";
990 }
991 }
992 ost << "]";
993#endif
994 ost << "\\right)" << endl;
995}
996
998{
999 int f_v = (verbose_level >= 1);
1000 int i, f, h;
1001
1002 if (f_v) {
1003 cout << "wreath_product::compute_base_and_transversals" << endl;
1004 }
1005 base_length = 0;
1009
1010 h = 0;
1011 for (i = 0; i < nb_factors; i++, h++) {
1012 the_base[h] = i;
1013 }
1014 for (f = 0; f < nb_factors; f++) {
1015 for (i = 0; i < base_len_in_component; i++, h++) {
1017 }
1018 }
1019 if (h != base_length) {
1020 cout << "wreath_product::compute_base_and_transversals "
1021 "h != base_length (1)" << endl;
1022 exit(1);
1023 }
1025 h = 0;
1026 for (i = 0; i < nb_factors; i++, h++) {
1028 }
1029 for (f = 0; f < nb_factors; f++) {
1030 for (i = 0; i < base_len_in_component; i++, h++) {
1032 }
1033 }
1034 if (h != base_length) {
1035 cout << "wreath_product::compute_base_and_transversals "
1036 "h != base_length (2)" << endl;
1037 exit(1);
1038 }
1039 if (f_v) {
1040 cout << "wreath_product::compute_base_and_transversals done" << endl;
1041 }
1042}
1043
1045 int &size, int &nb_gens, int verbose_level)
1046{
1047 int f_v = (verbose_level >= 1);
1048 int *GL_data;
1049 int GL_size;
1050 int GL_nb_gens;
1051 int h, k, f, g;
1052 int *dat;
1054
1055 if (f_v) {
1056 cout << "wreath_product::make_strong_generators_data" << endl;
1057 }
1058 if (f_v) {
1059 cout << "wreath_product::make_strong_generators_data "
1060 "before strong_generators_for_general_linear_group" << endl;
1061 }
1062
1064
1065
1068 FALSE /*M->f_semilinear*/,
1069 GL_data, GL_size, GL_nb_gens,
1070 verbose_level - 1);
1071
1072 if (f_v) {
1073 cout << "wreath_product::make_strong_generators_data "
1074 "after strong_generators_for_general_linear_group" << endl;
1075 }
1076 nb_gens = nb_factors - 1 + nb_factors * GL_nb_gens;
1077 size = nb_factors + nb_factors *
1079 data = NEW_int(nb_gens * size);
1080 dat = NEW_int(size);
1081
1082 h = 0;
1083 // generators for the components:
1084 for (f = nb_factors - 1; f >= 0; f--) {
1085 for (g = 0; g < GL_nb_gens; g++) {
1086 Combi.perm_identity(dat, nb_factors);
1087 for (k = 0; k < nb_factors; k++) {
1088 if (k == f) {
1089 Int_vec_copy(GL_data + g * GL_size,
1090 dat + nb_factors + k * M->elt_size_int_half,
1091 GL_size);
1092 }
1093 else {
1095 dat + nb_factors + k * M->elt_size_int_half,
1097 }
1098 }
1099 Int_vec_copy(dat, data + h * size, size);
1100 h++;
1101 }
1102 }
1103#if 1
1104 // create the elementary swap permutations:
1105 for (k = nb_factors - 2; k >= 0; k--) {
1107 for (f = 0; f < nb_factors; f++) {
1110 }
1111 Int_vec_copy(dat, data + h * size, size);
1112 h++;
1113 }
1114#endif
1115 if (h != nb_gens) {
1116 cout << "h != nb_gens" << endl;
1117 exit(1);
1118 }
1119 FREE_int(dat);
1120 if (f_v) {
1121 cout << "wreath_product::make_strong_generators_data done" << endl;
1122 }
1123}
1125 ostream &ost, int verbose_level)
1126{
1127 verbose_level = 1;
1128 int f_v = (verbose_level >= 1);
1129 int f_vv = (verbose_level >= 2);
1134 int *coords;
1135 int *Proj;
1136 int *projections;
1137 int *projections1;
1138 int *tensor;
1139 int *T;
1140 int i, j, h, a, len, N;
1141 int nb_rows, nb_cols;
1142 uint32_t b;
1143
1144 if (f_v) {
1145 cout << "wreath_product::report_rank_one_tensors" << endl;
1146 cout << "wreath_product::report_rank_one_tensors "
1147 "dimension_of_tensor_action=" << dimension_of_tensor_action << endl;
1148 }
1149
1150
1151 dimensions(dimension_of_tensor_action, nb_rows, nb_cols);
1152 if (f_v) {
1153 cout << "wreath_product::report_rank_one_tensors nb_rows = " << nb_rows << endl;
1154 cout << "wreath_product::report_rank_one_tensors nb_cols = " << nb_cols << endl;
1155 }
1156
1157
1158 coords = NEW_int(nb_factors);
1159 Proj = NEW_int(nb_factors);
1166 if (f_v) {
1167 cout << "wreath_product::create_all_rank_one_tensors "
1168 "nb_rank_one_tensors = " << nb_rank_one_tensors << endl;
1169 }
1172
1173 ost << "{\\renewcommand{\\arraystretch}{1.1}" << endl;
1174 ost << "$$" << endl;
1175 ost << "\\begin{array}{|r|r|r|r|r|r|}" << endl;
1176 ost << "\\hline" << endl;
1177
1178 for (i = 0; i < nb_rank_one_tensors; i++) {
1179
1180 if (i && (i % 10) == 0) {
1181 ost << "\\end{array}" << endl;
1182 ost << "$$" << endl;
1183 ost << "$$" << endl;
1184 ost << "\\begin{array}{|r|r|r|r|r|r|}" << endl;
1185 ost << "\\hline" << endl;
1186 }
1187 ost << i;
1188
1189 Gg.AG_element_unrank(N, Proj, 1, nb_factors, i);
1190 for (j = 0; j < nb_factors; j++) {
1191 Gg.AG_element_unrank(q, projections + j * dimension_of_matrix_group,
1192 1, dimension_of_matrix_group, Proj[j] + 1);
1193 }
1195 projections, projections1, nb_factors,
1197
1198 ost << " & " << endl;
1199 Int_vec_print(ost, Proj, nb_factors);
1200 ost << " & " << endl;
1201
1202 ost << "\\left[" << endl;
1203 L.int_matrix_print_tex(ost, projections1,
1205 ost << "\\right]" << endl;
1206
1207
1208 if (f_vv) {
1209 cout << "wreath_product::create_all_rank_one_tensors " << i
1210 << " / " << nb_rank_one_tensors << ":" << endl;
1211 cout << "projections: ";
1212 for (j = 0; j < len; j++) {
1213 cout << projections[j] << " ";
1214 }
1215 cout << endl;
1216 }
1217
1219 for (j = 0; j < dimension_of_tensor_action; j++) {
1221 a = 1;
1222 for (h = 0; h < nb_factors; h++) {
1223 a = F->mult(a, projections[h * dimension_of_matrix_group + coords[h]]);
1224 }
1225 tensor[j] = a;
1226 if (a) {
1227 int u, v;
1228 place_binary(j, u, v);
1229 T[u * nb_cols + v] = 1;
1230 }
1231 }
1232 if (f_vv) {
1233 cout << "wreath_product::create_all_rank_one_tensors " << i
1234 << " / " << nb_rank_one_tensors << ":" << endl;
1235 cout << "tensor: ";
1236 for (j = 0; j < dimension_of_tensor_action; j++) {
1237 cout << tensor[j] << " ";
1238 }
1239 cout << endl;
1240 }
1241
1242
1243 b = tensor[dimension_of_tensor_action - 1];
1244 for (j = 1; j < dimension_of_tensor_action; j++) {
1245 b <<= 1;
1246 if (tensor[dimension_of_tensor_action - 1 - j]) {
1247 b++;
1248 }
1249 }
1250
1251 ost << " & " << endl;
1252 ost << "\\left[" << endl;
1253 L.int_matrix_print_tex(ost, T, nb_rows, nb_cols);
1254 ost << "\\right]" << endl;
1255
1256 ost << " & ";
1257 ost << b;
1258 //ost << rank_one_tensors[i];
1259 ost << " & ";
1260 ost << rank_one_tensors_in_PG[i];
1261 ost << "\\\\" << endl;
1262 ost << "\\hline" << endl;
1263 }
1264 ost << "\\end{array}" << endl;
1265 ost << "$$}" << endl;
1266
1267 FREE_int(coords);
1268 FREE_int(Proj);
1269 FREE_int(projections);
1270 FREE_int(projections1);
1271 FREE_int(tensor);
1272 FREE_int(T);
1273
1274}
1275
1276
1277static void dimensions(int n, int &nb_rows, int &nb_cols)
1278{
1279 int i, j;
1280
1281 place_binary(n - 1, i, j);
1282 nb_rows = i + 1;
1283 nb_cols = j + 1;
1284}
1285
1286static void place_binary(long int h, int &i, int &j)
1287{
1288 int o[2];
1289 int c;
1290
1291 o[0] = 1;
1292 o[1] = 0;
1293 i = 0;
1294 j = 0;
1295 for (c = 0; h; c++) {
1296 if (h % 2) {
1297 i += o[0];
1298 j += o[1];
1299 }
1300 h >>= 1;
1301 if (c % 2) {
1302 o[0] = o[1] << 1;
1303 o[1] = 0;
1304 }
1305 else {
1306 o[1] = o[0];
1307 o[0] = 0;
1308 }
1309 }
1310}
1311
1312
1313
1315 uint32_t *&rank_one_tensors,
1316 int &nb_rank_one_tensors, int verbose_level)
1317{
1318 int f_v = (verbose_level >= 1);
1319 int f_vv = (verbose_level >= 5);
1323 int *coords;
1324 int *Proj;
1325 int *projections;
1326 int *tensor;
1327 int i, j, h, a, len, N;
1328 uint32_t b;
1329
1330 if (f_v) {
1331 cout << "wreath_product::create_all_rank_one_tensors" << endl;
1332 }
1333 if (q != 2) {
1334 cout << "wreath_product::create_all_rank_one_tensors requires q == 2" << endl;
1335 exit(1);
1336 }
1337 coords = NEW_int(nb_factors);
1338 Proj = NEW_int(nb_factors);
1343 if (f_v) {
1344 cout << "wreath_product::create_all_rank_one_tensors "
1345 "nb_rank_one_tensors = " << nb_rank_one_tensors << endl;
1346 }
1349 for (i = 0; i < nb_rank_one_tensors; i++) {
1350
1351 Gg.AG_element_unrank(N, Proj, 1, nb_factors, i);
1352 for (j = 0; j < nb_factors; j++) {
1353 Gg.AG_element_unrank(q, projections + j * dimension_of_matrix_group,
1354 1, dimension_of_matrix_group, Proj[j] + 1);
1355 }
1356 if (f_vv) {
1357 cout << "wreath_product::create_all_rank_one_tensors " << i
1358 << " / " << nb_rank_one_tensors << ":" << endl;
1359 cout << "projections: ";
1360 for (j = 0; j < len; j++) {
1361 cout << projections[j] << " ";
1362 }
1363 cout << endl;
1364 }
1365
1366 for (j = 0; j < dimension_of_tensor_action; j++) {
1368 a = 1;
1369 for (h = 0; h < nb_factors; h++) {
1370 a = F->mult(a, projections[h * dimension_of_matrix_group + coords[h]]);
1371 }
1372 tensor[j] = a;
1373 }
1374 if (f_vv) {
1375 cout << "wreath_product::create_all_rank_one_tensors " << i
1376 << " / " << nb_rank_one_tensors << ":" << endl;
1377 cout << "tensor: ";
1378 for (j = 0; j < dimension_of_tensor_action; j++) {
1379 cout << tensor[j] << " ";
1380 }
1381 cout << endl;
1382 }
1383 b = tensor[dimension_of_tensor_action - 1];
1384 for (j = 1; j < dimension_of_tensor_action; j++) {
1385 b <<= 1;
1386 if (tensor[dimension_of_tensor_action - 1 - j]) {
1387 b++;
1388 }
1389 }
1390 rank_one_tensors[i] = b;
1391 }
1394 for (i = 0; i < nb_rank_one_tensors; i++) {
1396 }
1398
1400
1402
1403 FREE_int(coords);
1404 FREE_int(Proj);
1405 FREE_int(projections);
1406 FREE_int(tensor);
1407 if (f_v) {
1408 cout << "wreath_product::create_all_rank_one_tensors done" << endl;
1409 }
1410}
1411
1413{
1414 uint32_t b;
1415 int i;
1416
1417 b = tensor[dimension_of_tensor_action - 1];
1418 for (i = 1; i < dimension_of_tensor_action; i++) {
1419 b <<= 1;
1420 if (tensor[dimension_of_tensor_action - 1 - i]) {
1421 b++;
1422 }
1423 }
1424 return b;
1425}
1426
1427void wreath_product::tensor_affine_unrank(int *tensor, uint32_t rk)
1428{
1429 uint32_t b;
1430 int i;
1431
1433
1434 b = rk;
1435 for (i = 0; i < dimension_of_tensor_action; i++) {
1436 if (b % 2) {
1437 tensor[i] = 1;
1438 }
1439 b >>= 1;
1440 }
1441}
1442
1444{
1445 long int b;
1446
1448 return b;
1449}
1450
1451void wreath_product::tensor_PG_unrank(int *tensor, long int PG_rk)
1452{
1454}
1455
1456long int wreath_product::affine_rank_to_PG_rank(uint32_t affine_rk)
1457{
1458 long int b;
1459
1460 tensor_affine_unrank(u, affine_rk);
1462 return b;
1463}
1464
1466{
1467 uint32_t b;
1468
1470 b = tensor_affine_rank(u);
1471 return b;
1472}
1473
1475{
1476 int f_v = (verbose_level >= 1);
1477
1478 if (f_v) {
1479 cout << "wreath_product::save_rank_one_tensors" << endl;
1480 }
1481 char fname[1000];
1482
1483 sprintf(fname, "rank_one_tensors_q%d_f%d.txt", q, nb_factors);
1484 {
1485 ofstream fp(fname);
1486 int i;
1487
1488 fp << nb_rank_one_tensors << endl;
1489 for (i = 0; i < nb_rank_one_tensors; i++) {
1490 fp << rank_one_tensors[i] << " ";
1491 }
1492 fp << endl;
1493 fp << -1 << endl;
1494 }
1495 if (f_v) {
1496 cout << "wreath_product::save_rank_one_tensors done" << endl;
1497 }
1498}
1499
1500void wreath_product::compute_tensor_ranks(char *&TR, uint32_t *&Prev, int verbose_level)
1501{
1502 int f_v = (verbose_level >= 1);
1503 int f_vv = FALSE;
1504 long int i;
1505 int r;
1506 long int sz;
1507 long int nb_processed;
1508 std::deque<uint32_t> D;
1509 uint32_t a, b, c;
1510 long int one_percent;
1512
1513 if (f_v) {
1514 cout << "wreath_product::compute_tensor_ranks" << endl;
1515 }
1516
1517
1518 char fname1[1000];
1519 char fname2[1000];
1520
1521 sprintf(fname1, "tensor_q%d_w%d_ranks.bin", q, nb_factors);
1522 sprintf(fname2, "tensor_q%d_w%d_ranks_prev.bin", q, nb_factors);
1523
1524
1525 if (f_v) {
1526 cout << "wreath_product::compute_tensor_ranks nb_rank_one_tensors = " << nb_rank_one_tensors << endl;
1527 }
1528
1529
1530
1531
1532 Prev = (uint32_t *) NEW_int(degree_of_tensor_action + 1);
1534
1535
1536 if (Fio.file_size(fname1) > 0 && Fio.file_size(fname2) > 0) {
1537 cout << "reading tensor ranks from file" << endl;
1538
1539 {
1540 ifstream fp(fname1, ios::binary);
1541
1542 long int d;
1543
1544 fp.read((char *) &d, sizeof(long int));
1545 if (d != degree_of_tensor_action + 1) {
1546 cout << "d != degree_of_tensor_action + 1" << endl;
1547 exit(1);
1548 }
1549 for (i = 0; i < d; i++) {
1550 fp.read((char *) &TR [i], sizeof(char));
1551 }
1552 }
1553 cout << "reading tensor ranks from file done" << endl;
1554
1555 cout << "reading Prev from file:" << endl;
1556 {
1557 ifstream fp(fname2, ios::binary);
1558
1559 long int d;
1560
1561 fp.read((char *) &d, sizeof(long int));
1562 if (d != degree_of_tensor_action + 1) {
1563 cout << "d != degree_of_tensor_action + 1" << endl;
1564 exit(1);
1565 }
1566 for (i = 0; i < d; i++) {
1567 fp.read((char *) &Prev [i], sizeof(uint32_t));
1568 }
1569 }
1570 cout << "reading Prev from file done" << endl;
1571
1572 }
1573 else {
1574 cout << "computing tensor ranks:" << endl;
1575
1576 for (i = 0; i < degree_of_tensor_action + 1; i++) {
1577 TR[i] = -1;
1578 }
1579 D.push_back((uint32_t) 0);
1580 TR[0] = 0;
1581 Prev[0] = 0;
1582 sz = 1;
1583 nb_processed = 0;
1584
1585 one_percent = (int)((double)(degree_of_tensor_action + 1) / (double)100) + 1;
1586
1587 while (sz < degree_of_tensor_action + 1) {
1588 if (D.empty()) {
1589 cout << "wreath_product::compute_tensor_ranks sz < degree_of_tensor_action + 1 and D.empty()" << endl;
1590 cout << "sz=" << sz << endl;
1591 exit(1);
1592 }
1593 a = D.front();
1594 D.pop_front();
1595 r = TR[a];
1596 if (f_vv) {
1597 cout << "wreath_product::compute_tensor_ranks expanding " << a << " of rank " << r << ", sz=" << sz << endl;
1598 }
1599
1600 for (i = 0; i < nb_rank_one_tensors; i++) {
1601 b = rank_one_tensors[i];
1602 c = a ^ b;
1603 if (f_vv) {
1604 cout << "wreath_product::compute_tensor_ranks expanding generator " << i << " = " << b << " maps " << a << " to " << c << endl;
1605 }
1606 if (TR[c] == -1) {
1607 if (f_vv) {
1608 cout << "wreath_product::compute_tensor_ranks expanding generator setting tensor rank of " << c << " to " << r + 1 << endl;
1609 }
1610 TR[c] = r + 1;
1611 Prev[c] = a;
1612 sz++;
1613 D.push_back(c);
1614 if (sz % one_percent == 0) {
1615 cout << "wreath_product::compute_tensor_ranks "
1616 << sz / one_percent << " % of tree completed, size of "
1617 "queue is " << D.size() << " = "
1618 << (D.size() / (double)(degree_of_tensor_action + 1)) * 100. << " %" << endl;
1619 }
1620 }
1621 else {
1622 if (f_vv) {
1623 cout << "wreath_product::compute_tensor_ranks expanding generator setting tensor rank of " << c << " is " << (int) TR[c] << " skipping" << endl;
1624 }
1625
1626 }
1627 } // next i
1628 nb_processed++;
1629 if (nb_processed % one_percent == 0) {
1630 cout << "wreath_product::compute_tensor_ranks "
1631 << nb_processed / one_percent << " % processed, size of "
1632 "queue is " << D.size() << " = "
1633 << (D.size() / (double)(degree_of_tensor_action + 1)) * 100.
1634 << " % tree at " << sz / one_percent << " %" << endl;
1635 }
1636 }
1637 if (f_vv) {
1638 cout << "wreath_product::compute_tensor_ranks TR:" << endl;
1639 for (i = 0; i < degree_of_tensor_action + 1; i++) {
1640 cout << i << " : " << (int) TR[i] << endl;
1641 }
1642 }
1643
1644
1645 cout << "computing tensor ranks done." << endl;
1646
1647
1648 cout << "writing TR to file:" << endl;
1649 {
1650 ofstream fp(fname1, ios::binary);
1651
1652 long int d;
1653
1655 fp.write((char *) &d, sizeof(long int));
1656 for (i = 0; i < d; i++) {
1657 fp.write((char *) &TR [i], sizeof(char));
1658 }
1659 }
1660
1661 cout << "writing Prev to file:" << endl;
1662 {
1663 ofstream fp(fname2, ios::binary);
1664
1665 long int d;
1666
1668 fp.write((char *) &d, sizeof(long int));
1669 for (i = 0; i < d; i++) {
1670 fp.write((char *) &Prev [i], sizeof(uint32_t));
1671 }
1672 }
1673 }
1674
1675
1676 if (f_v) {
1677 cout << "computing maximum tensor rank:" << endl;
1678 }
1679 int m;
1680
1681 m = 0;
1682 for (i = 0; i < degree_of_tensor_action + 1; i++) {
1683 m = MAXIMUM(m, (int) TR[i]);
1684 }
1685 if (f_v) {
1686 cout << "wreath_product::compute_tensor_ranks max tensor rank = " << m << endl;
1687 }
1688 long int *Nb_by_rank;
1689
1690 if (f_v) {
1691 cout << "computing Nb_by_rank:" << endl;
1692 }
1693 Nb_by_rank = NEW_lint(m + 1);
1694 for (i = 0; i <= m; i++) {
1695 Nb_by_rank[i] = 0;
1696 }
1697 for (i = 0; i < degree_of_tensor_action + 1; i++) {
1698 r = (int) TR[i];
1699 Nb_by_rank[r]++;
1700 }
1701 if (f_v) {
1702 cout << "number of tensors by rank:" << endl;
1703 for (i = 0; i <= m; i++) {
1704 cout << i << " : " << Nb_by_rank[i] << endl;
1705 }
1706 }
1707
1708
1709
1710
1711 if (q == 2 && nb_factors == 5) {
1712
1713 if (f_v) {
1714 cout << "q == 2 && nb_factors == 5" << endl;
1715 }
1716
1718
1719
1721 int *R;
1722 int *L;
1723 uint32_t *S;
1724 uint32_t s;
1725 int len;
1726
1727 R = NEW_int(N);
1728 L = NEW_int(N);
1729 S = (uint32_t *) NEW_int(N);
1730 for (i = 0; i < N; i++) {
1731 a = K.tensor_orbits_rep(nb_factors, i)[1];
1732 len = K.tensor_orbits_rep(nb_factors, i)[2];
1733 //a = w5_reps[3 * i + 1];
1734 //len = w5_reps[3 * i + 2];
1736 S[i] = s;
1737 L[i] = len;
1738 R[i] = (int) TR[s];
1739 }
1740
1741 cout << "tensor ranks of orbit representatives:" << endl;
1742 cout << "i : orbit length[i] : PG rank of rep[i] : tensor rank [i] : affine rank of rep(i) : rank one decomposition" << endl;
1743 for (i = 0; i < N; i++) {
1744 a = K.tensor_orbits_rep(nb_factors, i)[1];
1745 //a = w5_reps[3 * i + 1];
1746 cout << i << " : " << L[i] << " : " << a << " : " << R[i] << " : " << S[i] << " : ";
1747 s = S[i];
1748 while (true) {
1749 cout << (Prev[s] ^ s);
1750 s = Prev[s];
1751 cout << ",";
1752 if (s == 0) {
1753 break;
1754 }
1755 else {
1756 }
1757 }
1758
1759 cout << endl;
1760 }
1761
1764 int *types;
1765 int nb_types;
1766
1767 C.init(R, N, FALSE, 0);
1768
1769 SoS = C.get_set_partition_and_types(types,
1770 nb_types, verbose_level);
1771
1772 cout << "classification of orbit reps by tensor rank:" << endl;
1773 C.print_naked(TRUE);
1774 cout << endl;
1775 for (int t = 0; t < nb_types; t++) {
1776 cout << "working on type " << t << " of value " << types[t] << ":" << endl;
1777 cout << "There are " << SoS->Set_size[t] << " orbits" << endl;
1778 int *L;
1779 int *Ago;
1780
1781 L = NEW_int(SoS->Set_size[t]);
1782 Ago = NEW_int(SoS->Set_size[t]);
1783 for (s = 0; s < SoS->Set_size[t]; s++) {
1784 a = SoS->Sets[t][s];
1785 L[s] = K.tensor_orbits_rep(nb_factors, a)[2];
1786 //L[s] = w5_reps[3 * a + 2];
1787 Ago[s] = 933120 / L[s];
1788 }
1791
1792 C1.init(L, SoS->Set_size[t], FALSE, 0);
1793 cout << "classification of orbit lengths for tensor rank " << types[t] << ":" << endl;
1794 C1.print_naked_tex(cout, TRUE);
1795 cout << endl;
1796
1797 C2.init(Ago, SoS->Set_size[t], FALSE, 0);
1798 cout << "classification of ago for tensor rank " << types[t] << ":" << endl;
1799 C2.print_naked_tex(cout, TRUE);
1800 cout << endl;
1801
1802 FREE_int(L);
1803 FREE_int(Ago);
1804
1805 }
1806
1807 FREE_int(v);
1808 }
1809
1810 else if (q == 2 && nb_factors == 4) {
1811
1812 if (f_v) {
1813 cout << "q == 2 && nb_factors == 4" << endl;
1814 }
1815
1818 int *R;
1819 int *L;
1820 uint32_t *S;
1821 uint32_t s;
1822 int len, ago;
1823
1824 R = NEW_int(N);
1825 L = NEW_int(N);
1826 S = (uint32_t *) NEW_int(N);
1827 for (i = 0; i < N; i++) {
1828 a = K.tensor_orbits_rep(nb_factors, i)[1];
1829 len = K.tensor_orbits_rep(nb_factors, i)[2];
1830 //a = w4_reps[3 * i + 1];
1831 //len = w4_reps[3 * i + 2];
1833 S[i] = s;
1834 L[i] = len;
1835 R[i] = (int) TR[s];
1836 cout << "R[i]=" << R[i] << endl;
1837 }
1838
1839 cout << "tensor ranks of orbit representatives:" << endl;
1840 cout << "i : orbit length[i] : ago : PG rank of rep[i] : tensor rank [i] : affine rank of rep(i) : rank one decomposition" << endl;
1841 for (i = 0; i < N; i++) {
1842 a = K.tensor_orbits_rep(nb_factors, i)[1];
1843 //a = w4_reps[3 * i + 1];
1844 ago = 31104 / L[i];
1845 cout << i << " : " << L[i] << " : " << ago << " : " << a << " : " << R[i] << " : " << S[i] << " : ";
1846 s = S[i];
1847 while (true) {
1848 cout << (Prev[s] ^ s);
1849 s = Prev[s];
1850 cout << ",";
1851 if (s == 0) {
1852 break;
1853 }
1854 else {
1855 }
1856 }
1857
1858 cout << endl;
1859 }
1860
1863 int *types;
1864 int nb_types;
1865
1866 C.init(R, N, FALSE, 0);
1867
1868 SoS = C.get_set_partition_and_types(types,
1869 nb_types, verbose_level);
1870
1871 cout << "classification of orbit reps by tensor rank:" << endl;
1872 C.print_naked(TRUE);
1873 cout << endl;
1874 for (int t = 0; t < nb_types; t++) {
1875 cout << "working on type " << t << " of value " << types[t] << ":" << endl;
1876 cout << "There are " << SoS->Set_size[t] << " orbits" << endl;
1877 int *L;
1878 int *Ago;
1879
1880 L = NEW_int(SoS->Set_size[t]);
1881 Ago = NEW_int(SoS->Set_size[t]);
1882 for (s = 0; s < SoS->Set_size[t]; s++) {
1883 a = SoS->Sets[t][s];
1884 L[s] = K.tensor_orbits_rep(nb_factors, a)[2];
1885 //L[s] = w4_reps[3 * a + 2];
1886 Ago[s] = 31104 / L[s];
1887 }
1890
1891 C1.init(L, SoS->Set_size[t], FALSE, 0);
1892 cout << "classification of orbit lengths for tensor rank " << types[t] << ":" << endl;
1893 C1.print_naked_tex(cout, TRUE);
1894 cout << endl;
1895
1896 C2.init(Ago, SoS->Set_size[t], FALSE, 0);
1897 cout << "classification of ago for tensor rank " << types[t] << ":" << endl;
1898 C2.print_naked_tex(cout, TRUE);
1899 cout << endl;
1900
1901 FREE_int(L);
1902 FREE_int(Ago);
1903
1904 }
1905
1906 FREE_int(v);
1907 }
1908
1909 //exit(1);
1910
1911
1912
1913 if (f_v) {
1914 cout << "wreath_product::compute_tensor_ranks done" << endl;
1915 }
1916}
1917
1918void wreath_product::report(ostream &ost, int verbose_level)
1919{
1920 int f_v = (verbose_level >= 1);
1921
1922 if (f_v) {
1923 cout << "wreath_product::report" << endl;
1924 }
1925 ost << "\\section*{Wreath product group}" << endl << endl;
1926
1927
1928 ost << "Group name: $" << label_tex << "$\\\\" << endl;
1929 ost << "Number of factors: " << nb_factors << "\\\\" << endl;
1930 ost << "Degree of matrix group: " << degree_of_matrix_group << "\\\\" << endl;
1931 ost << "Dimension of matrix group: " << dimension_of_matrix_group << "\\\\" << endl;
1932 ost << "Dimension of tensor action: " << dimension_of_tensor_action << "\\\\" << endl;
1933 ost << "Degree of tensor action: " << degree_of_tensor_action << "\\\\" << endl;
1934 ost << "Degree overall: " << degree_overall << "\\\\" << endl;
1935 ost << "Low level point size: " << low_level_point_size << "\\\\" << endl;
1936 ost << "Make element size: " << make_element_size << "\\\\" << endl;
1937 ost << "Number of rank one tensors: " << nb_rank_one_tensors << "\\\\" << endl;
1938
1939 ost << "\\bigskip" << endl << endl;
1940
1941 ost << "\\section*{Rank One Tensors}" << endl << endl;
1942
1943
1944#if 0
1945 //ost << "Rank one tensors: \\\\" << endl;
1946
1947 int i;
1948 uint32_t a, b;
1949 int *tensor;
1950
1952
1953 for (i = 0; i < nb_rank_one_tensors; i++) {
1954 a = rank_one_tensors[i];
1956 tensor_PG_unrank(tensor, b);
1957 ost << i << " : ";
1958 int_vec_print(ost, tensor, dimension_of_tensor_action);
1959 ost << " : " << a << " : " << b << "\\\\" << endl;
1960 }
1961
1962 FREE_int(tensor);
1963#endif
1964
1965
1966 report_rank_one_tensors(ost, verbose_level);
1967
1968 //ost << "\\subsection*{The underlying matrix group}" << endl << endl;
1969 //A_mtx->report(ost, verbose_level);
1970
1971
1972 if (f_v) {
1973 cout << "wreath_product::report done" << endl;
1974 }
1975}
1976
1979 actions::action *A,
1980 int*& result,
1981 int &nb_gens, int &degree,
1982 int nb_factors,
1983 int verbose_level)
1984{
1985 int f_v = (verbose_level >= 1);
1986
1987 int *generator_stack;
1988 int **generators_transposed;
1989 int *perms;
1990 int mtx_n;
1991 int mtx_n2;
1992 int h;
1993
1994 if (f_v) {
1995 cout << "wreath_product::compute_permutations_and_write_to_file" << endl;
1996 }
1997
1998 nb_gens = SG->gens->len;
1999 degree = degree_of_tensor_action;
2001 mtx_n2 = mtx_n * mtx_n;
2002
2003 generator_stack = NEW_int(SG->gens->len * mtx_n2);
2004 generators_transposed = NEW_pint(SG->gens->len);
2005 perms = NEW_int(SG->gens->len * mtx_n);
2006 for (h = 0; h < SG->gens->len; h++) {
2007 if (f_v) {
2008 cout << "generator " << h << " / "
2009 << SG->gens->len << " is: " << endl;
2010 A->element_print_quick(SG->gens->ith(h), cout);
2011 A->element_print_as_permutation(SG->gens->ith(h), cout);
2012 }
2013
2014 create_matrix(SG->gens->ith(h), generator_stack + h * mtx_n2,
2015 0 /* verbose_level */);
2016
2017 if (f_v) {
2018 cout << "wreath_product::compute_permutations_and_write_to_file matrix:" << endl;
2019 Int_matrix_print(generator_stack + h * mtx_n2, mtx_n, mtx_n);
2020 }
2021 generators_transposed[h] = NEW_int(mtx_n2);
2022
2024 generator_stack + h * mtx_n2,
2025 generators_transposed[h], mtx_n, mtx_n);
2026
2027 compute_induced_permutation(SG->gens->ith(h), perms + h * mtx_n);
2028 }
2029
2030 if (f_v) {
2031 cout << "wreath_product::compute_permutations_and_write_to_file generator_stack:" << endl;
2032 Int_matrix_print(generator_stack, SG->gens->len, mtx_n * mtx_n);
2033 }
2034
2035#if 0
2036 cout << "wreath_product::compute_permutations_and_write_to_file generators transposed:" << endl;
2037 for (size_t h = 0; h < SG->gens->len; h++) {
2038 int_matrix_print(generators_transposed[h], mtx_n, mtx_n);
2039 }
2040#endif
2041 if (f_v) {
2042 cout << "wreath_product::compute_permutations_and_write_to_file perms:" << endl;
2043 Int_matrix_print(perms, SG->gens->len, mtx_n);
2044 cout << "mtx_n=" << mtx_n << endl;
2045 cout << "SG->gens->len * mtx_n=" << SG->gens->len * mtx_n << endl;
2046 }
2047
2048#if 0
2049 linalg::Matrix<int> v (mtx_n, 1);
2050
2051
2052 // matrix N contains the matrices of all projectivities
2053 // which generate the group, stacked on top of each other.
2054 // So, N has size (SG->gens->len * mtx_n) x mtx_n
2055
2056
2057 vector<linalg::Matrix<char>> N (SG->gens->len);
2058 for (size_t h = 0; h < N.size(); ++h) {
2059 N[h].INIT(mtx_n, mtx_n);
2060
2061 for (size_t i=0; i < mtx_n; ++i)
2062 for (size_t j = 0; j < mtx_n; ++j) {
2063 N[h].matrix_[i*mtx_n+j] = generator_stack [h * mtx_n2 + i * mtx_n + j];
2064 }
2065
2066 }
2067
2068 // Print the matrices N
2069 for (size_t h=0; h<N.size(); ++h) {
2070 printf("=========================================================\n");
2071 printf("h = %ld\n", h);
2072 printf("=========================================================\n");
2073
2074 linalg::print(N[h]);
2075
2076 printf("=========================================================\n");
2077 }
2078#endif
2079
2080
2081 // result is the ranks of the images.
2082 // Each row of result is a permutation of the points of projective space
2083 // So, result is SG->gens->len x W->degree_of_tensor_action
2084
2085 //result = NEW_int(SG->gens->len * W->degree_of_tensor_action);
2086
2087 // perform the parallel matrix multiplication on the GPU:
2088
2089
2090// int* v = NEW_int (MN.ncols);
2091
2092 unsigned int w = (unsigned int) degree_of_tensor_action - 1;
2093 long int a;
2094 a = (long int) w;
2095 if (a != degree_of_tensor_action - 1) {
2096 cout << "W->degree_of_tensor_action - 1 does not fit into a unsigned int" << endl;
2097 exit(1);
2098 }
2099 else {
2100 if (f_v) {
2101 cout << "W->degree_of_tensor_action fits into a unsigned int, this is good" << endl;
2102 }
2103 }
2104
2105
2106
2107 int block_size = 1L << 28; // pow(2, 28) ints = 1024 MB
2108
2109 if (f_v) {
2110 cout << "wreath_product::compute_permutations_and_write_to_file block_size=" << block_size << endl;
2111 }
2112
2113 int nb_blocks = (degree_of_tensor_action + block_size - 1) / block_size;
2114
2115 if (f_v) {
2116 cout << "wreath_product::compute_permutations_and_write_to_file nb_blocks=" << nb_blocks << endl;
2117 }
2118
2119
2120 //cout << "allocating S, an unsigned int array of size " << W->degree_of_tensor_action << endl;
2121
2122 //unsigned int* S = new unsigned int [W->degree_of_tensor_action];
2123
2124 //for (unsigned int i=0; i<W->degree_of_tensor_action; ++i) S[i] = i;
2125
2126
2127 if (f_v) {
2128 cout << "wreath_product::compute_permutations_and_write_to_file before allocating T, "
2129 "an unsigned int array of size " << block_size << endl;
2130 }
2131
2132 unsigned int* T = new unsigned int [block_size];
2133
2134// memset(S, -1, sizeof(S)*W->degree_of_tensor_action);
2135 if (f_v) {
2136 cout << "wreath_product::compute_permutations_and_write_to_file after allocating T, "
2137 "an unsigned int array of size " << block_size << endl;
2138 }
2139
2140
2141
2142
2143 long int b;
2144
2145 for (b = 0; b < nb_blocks; ++b) {
2146 if (f_v) {
2147 cout << "wreath_product::compute_permutations_and_write_to_file block b=" << b << " / " << nb_blocks << endl;
2148 }
2149
2150
2151 long int l;
2152
2153 l = MINIMUM((b + 1) * block_size, degree_of_tensor_action) - b * block_size;
2154 if (f_v) {
2155 cout << "wreath_product::compute_permutations_and_write_to_file l=" << l << endl;
2156 }
2157
2158 //linalg::Matrix<char> M (l, mtx_n);
2159
2161
2163 M->init(mtx_n, l, 0 /*verbose_level*/);
2164
2165 if (f_v) {
2166 cout << "wreath_product::compute_permutations "
2167 "unranking the elements of the PG to the bitmatrix" << endl;
2168 }
2169 M->unrank_PG_elements_in_columns_consecutively(
2170 F, (long int) b * (long int) block_size,
2171 0 /* verbose_level */);
2172
2173
2174#if 0
2175 cout << "wreath_product::compute_permutations_and_write_to_file unranking the elements of the PG" << endl;
2176
2177 int l1 = l / 100;
2178 for (size_t i=0; i<l; ++i) {
2179 if ((i % l1) == 0) {
2180 cout << "block b=" << b << ", " << i / l1 << " % done unranking" << endl;
2181 }
2182 W->F->PG_element_unrank_modified_lint (v.matrix_, 1, mtx_n,
2183 (long int) b * (long int) block_size + (long int)i) ;
2184 for (size_t j=0; j<mtx_n; ++j)
2185 M(i,j) = v(j, 0);
2186 }
2187#endif
2188
2189 if (f_v) {
2190 cout << "wreath_product::compute_permutations_and_write_to_file "
2191 "unranking the elements of the PG done" << endl;
2192 }
2193
2194 //M->print();
2195
2196 //linalg::Matrix<char> MN (l, mtx_n);
2197
2199
2201 NM->init(mtx_n, l, 0 /*verbose_level*/);
2202
2203
2204 for (h = 0; h < SG->gens->len; ++h) {
2205 if (f_v) {
2206 cout << "wreath_product::compute_permutations_and_write_to_file "
2207 "generator h=" << h << " / " << SG->gens->len << endl;
2208 }
2209
2210
2211 if (!test_if_file_exists(nb_factors, h, b)) {
2212
2213
2214 // Matrix Multiply
2215 //MN.reset_entries();
2216 NM->zero_out();
2217
2218
2219
2220 //cout << "cuda multiplication" << endl;
2221 //linalg::cuda_mod_mat_mul (M, N[h], MN, W->q);
2222 //cout << "cuda multiplication done" << endl;
2223 //M.UninitializeOnGPU();
2224 //N[h].UninitializeOnGPU();
2225 //MN.UninitializeOnGPU();
2226
2227
2228 if (f_v) {
2229 cout << "wreath_product::compute_permutations_and_write_to_file "
2230 "before CPU multiplication" << endl;
2231 }
2232 int t0, t1, dt;
2234 t0 = Os.os_ticks();
2235 //linalg::cpu_mod_mat_mul_block_AB(M, N[h], MN, W->q);
2236 M->mult_int_matrix_from_the_left(
2237 generators_transposed[h], mtx_n, mtx_n,
2238 NM, verbose_level);
2239 if (f_v) {
2240 cout << "wreath_product::compute_permutations_and_write_to_file "
2241 "after CPU multiplication" << endl;
2242 t1 = Os.os_ticks();
2243 dt = t1 - t0;
2244 cout << "the multiplication took ";
2245 Os.time_check_delta(cout, dt);
2246 cout << endl;
2247 }
2248
2249 //cout << "NM:" << endl;
2250 //NM->print();
2251
2252
2253 if (f_v) {
2254 cout << "wreath_product::compute_permutations_and_write_to_file "
2255 "before ranking the elements of the PG" << endl;
2256 }
2258 F, perms + h * mtx_n, T,
2259 verbose_level);
2260
2261#if 0
2262 for (size_t i=0; i<l; ++i) {
2263 if ((i % l1) == 0) {
2264 cout << "h=" << h << ", b=" << b << ", " << i/l1 << " % done ranking" << endl;
2265 }
2266 for (size_t j=0; j<mtx_n; ++j) {
2267 int a = perms[h * mtx_n + j];
2268 v.matrix_[a*v.alloc_cols] = MN (i, j);
2269
2270 }
2271 long int res;
2272 W->F->PG_element_rank_modified_lint (v.matrix_, 1, mtx_n, res);
2273 T [i] = (unsigned int) res;
2274 }
2275#endif
2276 if (f_v) {
2277 cout << "wreath_product::compute_permutations_and_write_to_file "
2278 "after ranking the elements of the PG" << endl;
2279 }
2280
2281
2282 if (f_v) {
2283 cout << "wreath_product::compute_permutations_and_write_to_file "
2284 "writing to file:" << endl;
2285 }
2286 char fname[1000];
2287
2288 make_fname(fname, nb_factors, h, b);
2289 {
2290 ofstream fp(fname, ios::binary);
2291
2292 fp.write((char *) &l, sizeof(int));
2293 for (int i = 0; i < l; i++) {
2294 fp.write((char *) &T [i], sizeof(int));
2295 }
2296 }
2297 //file_io Fio;
2298
2299 if (f_v) {
2300 cout << "wreath_product::compute_permutations_and_write_to_file "
2301 "written file " << fname << endl;
2302 //" of size " << Fio.file_size(fname) << endl;
2303 }
2304
2305
2306 }
2307 else {
2308 if (f_v) {
2309 cout << "wreath_product::compute_permutations_and_write_to_file "
2310 "the case h=" << h << ", b=" << b
2311 << " has already been done" << endl;
2312 }
2313 }
2314
2315 } // next h
2316
2317 FREE_OBJECT(M);
2318 FREE_OBJECT(NM);
2319
2320
2321 } // next b
2322
2323#if 0
2324 int nb_orbits = 0;
2325 for (unsigned int i=0; i < W->degree_of_tensor_action; ++i) {
2326 if (S[i] == i) ++nb_orbits;
2327 }
2328 cout << "nb_orbits: " << nb_orbits << endl;
2329
2330 long int *orbit_length;
2331 long int *orbit_rep;
2332
2333 orbit_length = NEW_lint(nb_orbits);
2334 orbit_rep = NEW_lint(nb_orbits);
2335
2336 for (int i = 0; i < nb_orbits; i++) {
2337 orbit_length[i] = 0;
2338 }
2339 int j;
2340 j = 0;
2341 for (unsigned int i=0; i < W->degree_of_tensor_action; ++i) {
2342 if (S[i] == i) {
2343 orbit_rep[j++] = i;
2344 }
2345 }
2346
2347 cout << "the orbit representatives are: " << endl;
2348 for (int i = 0; i < nb_orbits; i++) {
2349 cout << i << " : " << orbit_rep[i] << endl;
2350 }
2351#endif
2352
2353
2354
2355// combinatorics_domain Combi;
2356//
2357// for (size_t i = 0; i < SG->gens->len; i++) {
2358// cout << "testing result " << i << " / " << SG->gens->len << ": ";
2359// if (Combi.is_permutation(
2360// result + i * W->degree_of_tensor_action,
2361// W->degree_of_tensor_action)) {
2362// cout << "OK" << endl;
2363// }
2364// else {
2365// cout << "not OK" << endl;
2366// }
2367// }
2368// cout << "We found " << SG->gens->len << " permutations of "
2369// "degree " << W->degree_of_tensor_action << endl;
2370//
2371//
2372// cout << __FILE__ << ":" << __LINE__ << endl;
2373// //exit(0);
2374//
2375// FREE_int(generator_stack);
2376// FREE_int(perms);
2377// cout << "wreath_product_orbits_CUDA done" << endl;
2378
2379
2380//#else
2381// nb_gens = 0;
2382// degree = 0;
2383//#endif
2384
2385 if (f_v) {
2386 cout << "wreath_product::compute_permutations done" << endl;
2387 }
2388
2389}
2390
2391void wreath_product::make_fname(char *fname, int nb_factors, int h, int b)
2392{
2393 sprintf(fname, "w%d_h%d_b%d.bin", nb_factors, h, b);
2394}
2395
2396int wreath_product::test_if_file_exists(int nb_factors, int h, int b)
2397{
2398 char fname[1000];
2400
2401 make_fname(fname, nb_factors, h, b);
2402 if (Fio.file_size(fname) > 0) {
2403 return TRUE;
2404 }
2405 else {
2406 return FALSE;
2407 }
2408}
2409
2412 actions::action *A,
2413 int*& result,
2414 int &nb_gens, int &degree,
2415 int nb_factors,
2416 int verbosity)
2417{
2418 int f_v = (verbosity >= 1);
2419
2420 if (f_v) {
2421 cout << "wreath_product::orbits_using_files_and_union_find" << endl;
2422 }
2423 long int i, b, h;
2424 long int j, r, orbit_idx, rep;
2425 long int nb_orbits = 0;
2427
2428 //int mtx_n;
2429
2430 nb_gens = SG->gens->len;
2431 degree = degree_of_tensor_action;
2432 //mtx_n = dimension_of_tensor_action;
2433
2434 int block_size = 1L << 28; // pow(2, 28) ints = 1024 MB
2435
2436 if (f_v) {
2437 cout << "block_size=" << block_size << endl;
2438 }
2439
2440 int nb_blocks = (degree_of_tensor_action + block_size - 1) / block_size;
2441
2442 if (f_v) {
2443 cout << "nb_blocks=" << nb_blocks << endl;
2444 }
2445
2446
2447 if (f_v) {
2448 cout << "allocating S, an unsigned int array of size "
2449 << degree_of_tensor_action << endl;
2450 }
2451
2452 unsigned int* S = new unsigned int [degree_of_tensor_action];
2453
2454 for (i = 0; i < degree_of_tensor_action; ++i) {
2455 S[i] = i;
2456 }
2457
2458
2459 if (f_v) {
2460 cout << "allocating T, an unsigned int array of size "
2461 << degree_of_tensor_action << endl;
2462 }
2463
2464 unsigned int* T = new unsigned int [degree_of_tensor_action];
2465
2466
2467
2468
2469
2470 for (h = 0; h < SG->gens->len; ++h) {
2471 if (f_v) {
2472 cout << "wreath_product::orbits_using_files_and_union_find "
2473 "generator h=" << h << " / " << SG->gens->len << endl;
2474 }
2475
2476 for (b = 0; b < nb_blocks; ++b) {
2477 if (f_v) {
2478 cout << "wreath_product::orbits_using_files_and_union_find "
2479 "block b=" << b << " / " << nb_blocks << endl;
2480 }
2481
2482
2483 long int l = MINIMUM((b + 1) * block_size, degree_of_tensor_action) - b * block_size;
2484 if (f_v) {
2485 cout << "wreath_product::orbits_using_files_and_union_find "
2486 "l=" << l << endl;
2487 }
2488
2489
2490
2491
2492 if (!test_if_file_exists(nb_factors, h, b)) {
2493 cout << "file does not exist h=" << h << " b=" << b << endl;
2494 exit(1);
2495 }
2496 else {
2497 char fname[1000];
2498
2499 make_fname(fname, nb_factors, h, b);
2500 if (f_v) {
2501 cout << "wreath_product::orbits_using_files_and_union_find "
2502 "reading from file " << fname << endl;
2503 }
2504 {
2505 ifstream fp(fname, ios::binary);
2506
2507 int l1;
2508 fp.read((char *) &l1, sizeof(int));
2509 if (l1 != l) {
2510 cout << "l1 != l" << endl;
2511 }
2512 for (int i = 0; i < l; i++) {
2513 fp.read((char *) &T [b * block_size + i], sizeof(int));
2514 }
2515 }
2516 //file_io Fio;
2517
2518 if (f_v) {
2519 cout << "wreath_product::orbits_using_files_and_union_find "
2520 "read file " << fname << endl;
2521 //" of size " << Fio.file_size(fname) << endl;
2522 }
2523
2524
2525 } // else
2526 } // next b
2527
2528 if (f_v) {
2529 cout << "wreath_product::orbits_using_files_and_union_find "
2530 "performing the union-find for generator " << h
2531 << " / " << SG->gens->len << ":" << endl;
2532 }
2533
2534
2535 for (i = 0; i < degree_of_tensor_action; ++i) {
2536 int l1;
2537
2538 l1 = degree_of_tensor_action / 100;
2539
2540 if ((i % l1) == 0) {
2541 cout << i/l1 << " % done with union-find" << endl;
2542 }
2543 int u = i;
2544 unsigned int t = T[i];
2545 unsigned int r1 = Algo.root_of_tree_uint32_t(S, u);
2546 unsigned int r2 = Algo.root_of_tree_uint32_t(S, t);
2547
2548 if (r1 != r2) {
2549 if (r1 < r2) {
2550 S[r2] = r1;
2551 }
2552 else {
2553 S[r1] = r2;
2554 }
2555 }
2556 } // next i
2557
2558 } // next h
2559
2560
2561 if (f_v) {
2562 cout << "wreath_product::orbits_using_files_and_union_find Done with the loop" << endl;
2563 cout << "wreath_product::orbits_using_files_and_union_find Computing the orbit representatives" << endl;
2564 }
2565
2566
2567 for (i = 0; i < degree_of_tensor_action; ++i) {
2568 if (S[i] == i) {
2569 nb_orbits++;
2570 }
2571 }
2572 if (f_v) {
2573 cout << "wreath_product::orbits_using_files_and_union_find nb_orbits: " << nb_orbits << endl;
2574 }
2575
2576 long int *orbit_length;
2577 long int *orbit_rep;
2578
2579 orbit_length = NEW_lint(nb_orbits);
2580 orbit_rep = NEW_lint(nb_orbits);
2581
2582 for (i = 0; i < nb_orbits; i++) {
2583 orbit_length[i] = 0;
2584 }
2585 j = 0;
2586 for (i = 0; i < degree_of_tensor_action; ++i) {
2587 if (S[i] == i) {
2588 orbit_rep[j++] = i;
2589 }
2590 }
2591
2592 if (f_v) {
2593 cout << "wreath_product::orbits_using_files_and_union_find the orbit representatives are: " << endl;
2594 for (int i = 0; i < nb_orbits; i++) {
2595 cout << i << ", " << orbit_rep[i] << ", " << endl;
2596 }
2597 }
2598 if (f_v) {
2599 cout << "wreath_product::orbits_using_files_and_union_find Path compression:" << endl;
2600 }
2601 for (i = 0; i < degree_of_tensor_action; ++i) {
2602 r = Algo.root_of_tree_uint32_t(S, i);
2603 S[i] = r;
2604 }
2605 if (f_v) {
2606 cout << "wreath_product::orbits_using_files_and_union_find Path compression done" << endl;
2607 }
2608
2609 uint32_t *Orbit;
2610 int goi;
2612
2613
2614 SG->group_order(go);
2615 goi = go.as_int();
2616
2617 if (f_v) {
2618 cout << "wreath_product::orbits_using_files_and_union_find "
2619 "goi=" << goi << endl;
2620 }
2621
2622
2623 Orbit = (uint32_t *) NEW_int(goi);
2624
2625 if (f_v) {
2626 cout << "wreath_product::orbits_using_files_and_union_find "
2627 "determining the orbits: " << endl;
2628 }
2629 for (orbit_idx = 0; orbit_idx < nb_orbits; orbit_idx++) {
2630
2631 rep = orbit_rep[orbit_idx];
2632 uint32_t len = 0;
2633
2634 if (f_v) {
2635 cout << "wreath_product::orbits_using_files_and_union_find "
2636 "determining orbit " << orbit_idx << " / " << nb_orbits
2637 << " with rep " << rep << endl;
2638 }
2639 for (j = 0; j < degree_of_tensor_action; ++j) {
2640 if (S[j] == rep) {
2641 Orbit[len++] = j;
2642 }
2643 }
2644 orbit_length[orbit_idx] = len;
2645 if (f_v) {
2646 cout << "wreath_product::orbits_using_files_and_union_find "
2647 "orbit " << orbit_idx << " / " << nb_orbits << " has length " << len << endl;
2648 }
2649 char fname_orbit[1000];
2650
2651 sprintf(fname_orbit, "wreath_q%d_w%d_orbit_%ld.bin", q, nb_factors, orbit_idx);
2652 if (f_v) {
2653 cout << "Writing the file " << fname_orbit << endl;
2654 }
2655 {
2656 ofstream fp(fname_orbit, ios::binary);
2657
2658 fp.write((char *) &len, sizeof(uint32_t));
2659 for (i = 0; i < (long int) len; i++) {
2660 fp.write((char *) &Orbit[i], sizeof(uint32_t));
2661 }
2662 }
2663 if (f_v) {
2664 cout << "We are done writing the file " << fname_orbit << endl;
2665 }
2666
2667 }
2668 FREE_int((int *) Orbit);
2669 if (f_v) {
2670 cout << "wreath_product::orbits_using_files_and_union_find the orbits are: " << endl;
2671 for (int orbit_idx = 0; orbit_idx < nb_orbits; orbit_idx++) {
2672 cout << orbit_idx << ", " << orbit_rep[orbit_idx] << ", " << orbit_length[orbit_idx] << ", " << endl;
2673 }
2674 }
2675
2676 if (f_v) {
2677 cout << "wreath_product::orbits_using_files_and_union_find done" << endl;
2678 }
2679}
2680
2681
2684 actions::action *A,
2685 int*& result,
2686 int &nb_gens, int &degree,
2687 int nb_factors,
2688 std::string &orbits_restricted_fname,
2689 int verbose_level)
2690{
2691 int f_v = (verbose_level >= 1);
2692
2693
2694 if (f_v) {
2695 cout << "wreath_product::orbits_restricted "
2696 "orbits_restricted_fname=" << orbits_restricted_fname << endl;
2697 }
2698
2701
2702 //int mtx_n;
2703 long int *Set;
2704 long int *Set_in_PG;
2705 int set_m, set_n;
2706 int nb_blocks;
2707 int *restr_first; // [nb_blocks]
2708 int *restr_length; // [nb_blocks]
2709 long int i, j, b, h;
2710
2711 Fio.lint_matrix_read_csv(orbits_restricted_fname,
2712 Set, set_m, set_n, verbose_level);
2713
2714 if (set_n != 1) {
2715 cout << "orbits_restricted set_n != 1" << endl;
2716 exit(1);
2717 }
2718 if (f_v) {
2719 cout << "Restricting to a set of size " << set_m << endl;
2720 cout << "converting points to PG point labels" << endl;
2721 }
2722
2723 int *v;
2724 long int s;
2726 Set_in_PG = NEW_lint(set_m);
2727 for (i = 0; i < set_m; i++) {
2728 s = affine_rank_to_PG_rank(Set[i]);
2729 Set_in_PG[i] = s;
2730 }
2731 //FREE_int(v);
2732 Sorting.lint_vec_heapsort(Set_in_PG, set_m);
2733 if (f_v) {
2734 cout << "after sorting, Set_in_PG:" << endl;
2735 for (i = 0; i < set_m; i++) {
2736 cout << i << " : " << Set_in_PG[i] << endl;
2737 }
2738 }
2739
2740
2741
2742 nb_gens = SG->gens->len;
2743 degree = degree_of_tensor_action;
2744 //mtx_n = dimension_of_tensor_action;
2745
2746 int block_size = 1L << 28; // pow(2, 28) ints = 1024 MB
2747
2748 if (f_v) {
2749 cout << "block_size=" << block_size << endl;
2750 }
2751
2752 nb_blocks = (degree_of_tensor_action + block_size - 1) / block_size;
2753
2754 if (f_v) {
2755 cout << "nb_blocks=" << nb_blocks << endl;
2756 }
2757
2758 restr_first = NEW_int(nb_blocks);
2759 restr_length = NEW_int(nb_blocks);
2760
2761 for (b = 0; b < nb_blocks; b++) {
2762
2763 if (f_v) {
2764 cout << "block b=" << b << " / " << nb_blocks << endl;
2765 }
2766
2767
2768 int idx;
2769 Sorting.lint_vec_search(Set_in_PG, set_m, (long int) b * block_size,
2770 idx, 0 /*verbose_level*/);
2771
2772 restr_first[b] = idx;
2773 }
2774
2775 for (b = 0; b < nb_blocks; b++) {
2776 cout << b << " : " << restr_first[b] << endl;
2777 }
2778
2779 for (b = nb_blocks - 1; b >= 0; b--) {
2780 if (f_v) {
2781 cout << "b=" << b << endl;
2782 }
2783 if (b == nb_blocks - 1) {
2784 restr_length[b] = set_m - restr_first[b];
2785 }
2786 else {
2787 restr_length[b] = restr_first[b + 1] - restr_first[b];
2788 }
2789 }
2790
2791 for (b = 0; b < nb_blocks; b++) {
2792 cout << b << " : " << restr_first[b] << " : " << restr_length[b] << endl;
2793 }
2794
2795 long int *Perms;
2796
2797 Perms = NEW_lint(set_m * SG->gens->len);
2798
2799
2800
2801 if (f_v) {
2802 cout << "allocating T, an unsigned int array of size " << block_size << endl;
2803 }
2804
2805 unsigned int* T = new unsigned int [block_size];
2806
2807
2808
2809
2810
2811 for (h = 0; h < SG->gens->len; ++h) {
2812 if (f_v) {
2813 cout << "generator h=" << h << " / " << SG->gens->len << endl;
2814 }
2815
2816 for (int b = 0; b < nb_blocks; ++b) {
2817 if (f_v) {
2818 cout << "block b=" << b << " / " << nb_blocks << endl;
2819 }
2820
2821
2822 long int l = MINIMUM((b + 1) * block_size, degree_of_tensor_action) - b * block_size;
2823 if (f_v) {
2824 cout << "l=" << l << endl;
2825 }
2826
2827
2828
2829
2830
2831 if (!test_if_file_exists(nb_factors, h, b)) {
2832 cout << "file does not exist h=" << h << " b=" << b << endl;
2833 exit(1);
2834 }
2835 char fname[1000];
2836
2837 make_fname(fname, nb_factors, h, b);
2838 if (f_v) {
2839 cout << "reading from file " << fname << endl;
2840 }
2841 {
2842 ifstream fp(fname, ios::binary);
2843
2844 int l1;
2845 fp.read((char *) &l1, sizeof(int));
2846 if (l1 != l) {
2847 cout << "l1 != l" << endl;
2848 }
2849 for (int i = 0; i < l; i++) {
2850 fp.read((char *) &T [i], sizeof(int));
2851 }
2852 }
2853 if (f_v) {
2854 cout << "read file " << fname << endl;
2855 //" of size " << Fio.file_size(fname) << endl;
2856 }
2857
2858 long int x, y;
2859 for (long int u = 0; u < restr_length[b]; u++) {
2860 i = restr_first[b] + u;
2861 x = Set_in_PG[i];
2862 if (x < b * block_size) {
2863 cout << "x < b * block_size" << endl;
2864 cout << "x=" << x << " b=" << b << endl;
2865 exit(1);
2866 }
2867 if (x >= (b + 1) * block_size) {
2868 cout << "x >= (b + 1) * block_size" << endl;
2869 cout << "x=" << x << " b=" << b << endl;
2870 exit(1);
2871 }
2872 y = T[x - b * block_size];
2873
2874 int idx;
2875 if (!Sorting.lint_vec_search(Set_in_PG, set_m, y, idx, 0 /*verbose_level*/)) {
2876 cout << "did not find element y=" << y << " in Set_in_PG "
2877 "under generator h=" << h << ", something is wrong" << endl;
2878 cout << "x=" << x << endl;
2879 tensor_PG_unrank(v, x);
2880 s = tensor_affine_rank(v);
2881 cout << "tensor=";
2883 cout << endl;
2884 cout << "affine rank s=" << s << endl;
2885
2886 cout << "y=" << y << endl;
2887 tensor_PG_unrank(v, y);
2888 s = tensor_affine_rank(v);
2889 cout << "tensor=";
2891 cout << endl;
2892 cout << "affine rank s=" << s << endl;
2893
2894 exit(1);
2895 }
2896 j = idx;
2897 Perms[i * SG->gens->len + h] = j;
2898 } // next u
2899
2900 } // next b
2901
2902 } // next h
2903
2904 string fname;
2906
2907 fname.assign(orbits_restricted_fname);
2908 ST.chop_off_extension(fname);
2909
2910 fname.append("_restricted_action.txt");
2911 Fio.lint_matrix_write_csv(fname, Perms, set_m, SG->gens->len);
2912
2913 if (f_v) {
2914 cout << "wreath_product::orbits_restricted done" << endl;
2915 }
2916}
2917
2920 actions::action *A,
2921 int*& result,
2922 int &nb_gens, int &degree,
2923 int nb_factors,
2924 std::string &orbits_restricted_fname,
2925 int verbose_level)
2926{
2927 int f_v = (verbose_level >= 1);
2928
2929 if (f_v) {
2930 cout << "wreath_product::orbits_restricted_compute "
2931 "orbits_restricted_fname=" << orbits_restricted_fname << endl;
2932 }
2933
2936
2937 long int *Set;
2938 long int *Set_in_PG;
2939 int set_m, set_n;
2940 int i;
2941
2942 Fio.lint_matrix_read_csv(orbits_restricted_fname,
2943 Set, set_m, set_n, verbose_level);
2944
2945 if (set_n != 1) {
2946 cout << "orbits_restricted set_n != 1" << endl;
2947 exit(1);
2948 }
2949 if (f_v) {
2950 cout << "Restricting to a set of size " << set_m << endl;
2951 cout << "converting points to PG point labels" << endl;
2952 }
2953
2954 //int *v;
2955 long int s;
2956 //v = NEW_int(dimension_of_tensor_action);
2957 Set_in_PG = NEW_lint(set_m);
2958 for (i = 0; i < set_m; i++) {
2959 s = affine_rank_to_PG_rank(Set[i]);
2960 Set_in_PG[i] = s;
2961 }
2962 //FREE_int(v);
2963 Sorting.lint_vec_heapsort(Set_in_PG, set_m);
2964 if (f_v) {
2965 cout << "after sorting, Set_in_PG:" << endl;
2966 }
2967#if 0
2968 for (i = 0; i < set_m; i++) {
2969 cout << i << " : " << Set_in_PG[i] << endl;
2970 }
2971#endif
2972
2973
2974
2975 nb_gens = SG->gens->len;
2976
2977
2978 string fname;
2980
2981 int *Perms;
2982 int perms_m, perms_n;
2983
2984 fname.assign(orbits_restricted_fname);
2985 ST.chop_off_extension(fname);
2986
2987 fname.append("_restricted_action.txt");
2988 Fio.int_matrix_read_csv(fname, Perms, perms_m, perms_n, verbose_level - 2);
2989 if (perms_n != SG->gens->len) {
2990 cout << "perms_n != SG->gens->len" << endl;
2991 exit(1);
2992 }
2993 if (perms_m != set_m) {
2994 cout << "perms_m != set_m" << endl;
2995 exit(1);
2996 }
2997
2998 degree = perms_m;
2999
3000
3001
3002
3003 actions::action *A_perm;
3004 actions::action *A_perm_matrix;
3005
3006 A_perm = NEW_OBJECT(actions::action);
3008 FALSE /* f_stay_in_the_old_action */,
3009 SG->gens,
3010 Perms, degree,
3011 verbose_level);
3012 if (f_v) {
3013 cout << "created A_perm = " << A_perm->label << endl;
3014 }
3015
3016 A_perm_matrix = NEW_OBJECT(actions::action);
3017 A_perm_matrix->init_permutation_representation(A,
3018 TRUE /* f_stay_in_the_old_action */,
3019 SG->gens,
3020 Perms, degree,
3021 verbose_level);
3022 if (f_v) {
3023 cout << "created A_perm_matrix = " << A_perm_matrix->label << endl;
3024 }
3025
3026 permutation_representation *Permutation_representation;
3027
3028 Permutation_representation = A_perm->G.Permutation_representation;
3029
3031
3033
3034 Gens->init(A_perm, verbose_level - 2);
3035 Gens->allocate(SG->gens->len, verbose_level - 2);
3036 for (i = 0; i < SG->gens->len; i++) {
3037 A_perm->element_move(
3038 Permutation_representation->Elts
3039 + i * A_perm->elt_size_in_int,
3040 Gens->ith(i),
3041 verbose_level);
3042 }
3043
3044 schreier *Sch;
3046 int orbit_idx;
3047
3048 Sch = NEW_OBJECT(schreier);
3049
3050 Sch->init(A_perm, verbose_level - 2);
3051 Sch->initialize_tables();
3052 Sch->init_generators(*Gens, verbose_level - 2);
3053
3054 if (f_v) {
3055 cout << "before Sch->compute_all_point_orbits" << endl;
3056 }
3057 Sch->compute_all_point_orbits(0 /*verbose_level - 5*/);
3058 if (f_v) {
3059 cout << "after Sch->compute_all_point_orbits" << endl;
3060 }
3061
3062 Sch->print_orbit_lengths_tex(cout);
3063 Sch->print_and_list_orbits_tex(cout);
3064
3066 Sch->orbits_as_set_of_sets(Orbits, verbose_level);
3067
3068 A->group_order(go);
3069 if (f_v) {
3070 cout << "Action " << A->label << endl;
3071 cout << "group order " << go << endl;
3072 cout << "computing stabilizers:" << endl;
3073 }
3074
3075 if (f_v) {
3076 cout << "wreath_product::orbits_restricted_compute looping over all orbits" << endl;
3077 }
3078
3079
3080 for (orbit_idx = 0; orbit_idx < Sch->nb_orbits; orbit_idx++) {
3081 if (f_v) {
3082 cout << "computing point stabilizer for orbit " << orbit_idx << ":" << endl;
3083 }
3084
3085 int orb_rep;
3086 long int orbit_rep_in_PG;
3087 uint32_t orbit_rep_in_PG_uint;
3088
3089 orb_rep = Sch->orbit[Sch->orbit_first[orbit_idx]];
3090
3091 orbit_rep_in_PG = Set_in_PG[orb_rep];
3092
3093 orbit_rep_in_PG_uint = PG_rank_to_affine_rank(orbit_rep_in_PG);
3094
3095 int *tensor;
3096
3098
3099 tensor_PG_unrank(tensor, orbit_rep_in_PG);
3100
3101 if (f_v) {
3102 cout << "orbit representative is " << orb_rep << " = " << orbit_rep_in_PG << " = " << orbit_rep_in_PG_uint << endl;
3103 cout << "tensor: ";
3105 cout << endl;
3106 }
3107 sims *Stab;
3108
3109 if (f_v) {
3110 cout << "before Sch->point_stabilizer in action " << A_perm_matrix->label << endl;
3111 }
3112 Sch->point_stabilizer(A_perm_matrix, go,
3113 Stab, orbit_idx, verbose_level - 5);
3114 if (f_v) {
3115 cout << "after Sch->point_stabilizer in action " << A_perm_matrix->label << endl;
3116 }
3117
3118 strong_generators *gens;
3119
3121 gens->init(A_perm_matrix);
3122 gens->init_from_sims(Stab, verbose_level);
3123
3124
3125 if (f_v) {
3126 gens->print_generators_tex(cout);
3127 }
3128
3129#if 1
3130 actions::action *A_on_orbit;
3131
3132 if (f_v) {
3133 cout << "computing restricted action on the orbit:" << endl;
3134 }
3135 A_on_orbit = A_perm->restricted_action(Orbits->Sets[orbit_idx] + 1, Orbits->Set_size[orbit_idx] - 1,
3136 verbose_level);
3137
3138 if (f_v) {
3139 cout << "generators restricted to the orbit of degree " << Orbits->Set_size[orbit_idx] - 1 << ":" << endl;
3140 gens->print_generators_MAGMA(A_on_orbit, cout);
3141 }
3142
3143
3144 sims *derived_group;
3146
3147 derived_group = NEW_OBJECT(sims);
3148
3149 if (f_v) {
3150 cout << "computing the derived subgroup:" << endl;
3151 }
3152
3153 derived_group->init(A_perm_matrix, verbose_level - 2);
3154 derived_group->init_trivial_group(verbose_level - 1);
3155 derived_group->build_up_subgroup_random_process(Stab,
3157 0 /*verbose_level*/);
3158
3159 derived_group->group_order(d_go);
3160 if (f_v) {
3161 cout << "the derived subgroup has order: " << d_go << endl;
3162 }
3163
3164 strong_generators *d_gens;
3165
3166 d_gens = NEW_OBJECT(strong_generators);
3167 d_gens->init(A_perm_matrix);
3168 d_gens->init_from_sims(derived_group, 0 /*verbose_level*/);
3169
3170
3171 d_gens->print_generators_tex(cout);
3172
3173 schreier *Sch_orbit;
3174
3175 Sch_orbit = NEW_OBJECT(schreier);
3176 if (f_v) {
3177 cout << "computing orbits of stabilizer on the rest of the orbit:" << endl;
3178 }
3179
3181 *Sch_orbit,
3182 gens,
3183 0 /* verbose_level */);
3184
3185 if (f_v) {
3186 cout << "Found " << Sch_orbit->nb_orbits << " orbits" << endl;
3187 Sch_orbit->print_orbit_lengths_tex(cout);
3188 Sch_orbit->print_and_list_orbits_tex(cout);
3189 }
3190#endif
3191
3192 FREE_OBJECT(gens);
3193 FREE_OBJECT(Stab);
3194 }
3195
3196
3197 if (f_v) {
3198 cout << "wreath_product::orbits_restricted_compute done" << endl;
3199 }
3200
3201}
3202
3203
3204
3205}}}
3206
generators for various classes of groups
Definition: algebra.h:286
void general_linear_matrix_group_base_and_transversal_length(int n, field_theory::finite_field *F, int f_semilinear, int base_len, int degree, long int *base, int *transversal_length, int verbose_level)
int matrix_group_base_len_general_linear_group(int n, int q, int f_semilinear, int verbose_level)
void strong_generators_for_general_linear_group(int n, field_theory::finite_field *F, int f_semilinear, int *&data, int &size, int &nb_gens, int verbose_level)
uint32_t root_of_tree_uint32_t(uint32_t *S, uint32_t i)
Definition: algorithms.cpp:156
matrices over GF(2) stored as bitvectors
void init(int m, int n, int verbose_level)
Definition: bitmatrix.cpp:35
void rank_PG_elements_in_columns(field_theory::finite_field *F, int *perms, unsigned int *PG_ranks, int verbose_level)
Definition: bitmatrix.cpp:93
a catch-all container class for everything related to data structures
bulk storage of group elements in compressed form
void init(int entry_size, int page_length_log, int verbose_level)
a collection of functions related to sorted vectors
int lint_vec_search(long int *v, int len, long int a, int &idx, int verbose_level)
Definition: sorting.cpp:1157
functions related to strings and character arrays
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
data_structures::set_of_sets * get_set_partition_and_types(int *&types, int &nb_types, int verbose_level)
Definition: tally.cpp:702
void print_naked_tex(std::ostream &ost, int f_backwards)
Definition: tally.cpp:413
void PG_element_unrank_modified_lint(int *v, int stride, int len, long int a)
void PG_element_rank_modified_lint(int *v, int stride, int len, long int &a)
various functions related to geometries
Definition: geometry.h:721
void AG_element_unrank(int q, int *v, int stride, int len, long int a)
long int AG_element_rank(int q, int *v, int stride, int len)
provides access to pre-computed combinatorial data in encoded form
void mult_vector_from_the_left(int *v, int *A, int *vA, int m, int n)
void transpose_matrix(int *A, int *At, int ma, int na)
void Kronecker_product_square_but_arbitrary(int *A, int *B, int na, int nb, int *AB, int &N, int verbose_level)
void lint_matrix_write_csv(std::string &fname, long int *M, int m, int n)
Definition: file_io.cpp:1323
void int_matrix_read_csv(std::string &fname, int *&M, int &m, int &n, int verbose_level)
Definition: file_io.cpp:1477
void lint_matrix_read_csv(std::string &fname, long int *&M, int &m, int &n, int verbose_level)
Definition: file_io.cpp:1558
void int_matrix_print_tex(std::ostream &ost, int *p, int m, int n)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
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 element_move(void *a, void *b, int verbose_level)
Definition: action_cb.cpp:335
void group_order(ring_theory::longinteger_object &go)
Definition: action.cpp:2223
void init_permutation_representation(action *A_original, int f_stay_in_the_old_action, data_structures_groups::vector_ge *gens, int *Perms, int degree, int verbose_level)
void all_point_orbits_from_generators(groups::schreier &Schreier, groups::strong_generators *SG, int verbose_level)
Definition: action.cpp:1254
void element_print_as_permutation(void *elt, std::ostream &ost)
Definition: action_cb.cpp:421
void init(actions::action *A, int verbose_level)
Definition: vector_ge.cpp:55
a matrix group over a finite field in projective, vector space or affine action
Definition: groups.h:318
void GL_print_easy(int *Elt, std::ostream &ost)
void GL_print_for_make_element(int *Elt, std::ostream &ost)
void GL_invert_internal(int *A, int *Ainv, int verbose_level)
void GL_mult(int *A, int *B, int *AB, int verbose_level)
void make_element(int *Elt, int *data, int verbose_level)
void GL_print_latex(int *Elt, std::ostream &ost)
a domain for permutation groups whose elements are given in the permutation representation
Definition: groups.h:715
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 orbits_as_set_of_sets(data_structures::set_of_sets *&S, int verbose_level)
Definition: schreier.cpp:2653
void init_generators(data_structures_groups::vector_ge &generators, int verbose_level)
Definition: schreier.cpp:373
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 init(actions::action *A, int verbose_level)
Definition: schreier.cpp:308
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 build_up_subgroup_random_process(sims *G, void(*choose_random_generator_for_subgroup)(sims *G, int *Elt, int verbose_level), int verbose_level)
Definition: sims2.cpp:53
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
void print_generators_MAGMA(actions::action *A, std::ostream &ost)
void init_from_sims(groups::sims *S, int verbose_level)
data_structures_groups::vector_ge * gens
Definition: groups.h:1708
void group_order(ring_theory::longinteger_object &go)
void create_matrix(int *Elt, int *A, int verbose_level)
void element_invert(int *A, int *Av, int verbose_level)
void element_print_easy(int *Elt, std::ostream &ost)
void put_digit(uchar *elt, int f, int i, int j, int d)
void report(std::ostream &ost, int verbose_level)
void unrank_point(long int a, int *v, int verbose_level)
data_structures::page_storage * Elts
Definition: groups.h:2156
void element_move(int *A, int *B, int verbose_level)
permutation_representation_domain * P
Definition: groups.h:2121
void orbits_restricted_compute(strong_generators *SG, actions::action *A, int *&result, int &nb_gens, int &degree, int nb_factors, std::string &orbits_restricted_fname, int verbose_level)
void element_print_latex(int *Elt, std::ostream &ost)
void init_tensor_wreath_product(matrix_group *M, actions::action *A_mtx, int nb_factors, int verbose_level)
long int element_image_of(int *Elt, long int a, int verbose_level)
int test_if_file_exists(int nb_factors, int h, int b)
void element_print_for_make_element(int *Elt, std::ostream &ost)
void make_element_from_one_component(int *Elt, int f, int *Elt_component)
void make_strong_generators_data(int *&data, int &size, int &nb_gens, int verbose_level)
void make_fname(char *fname, int nb_factors, int h, int b)
void apply_permutation(int *Elt, int *v_in, int *v_out, int verbose_level)
void create_all_rank_one_tensors(uint32_t *&rank_one_tensors, int &nb_rank_one_tensors, int verbose_level)
void report_rank_one_tensors(std::ostream &ost, int verbose_level)
void element_image_of_low_level(int *Elt, int *input, int *output, int verbose_level)
void make_element(int *Elt, int *data, int verbose_level)
void orbits_using_files_and_union_find(strong_generators *SG, actions::action *A, int *&result, int &nb_gens, int &degree, int nb_factors, int verbosity)
int get_digit(uchar *elt, int f, int i, int j)
void element_mult(int *A, int *B, int *AB, int verbose_level)
void compute_permutations_and_write_to_file(strong_generators *SG, actions::action *A, int *&result, int &nb_gens, int &degree, int nb_factors, int verbose_level)
void orbits_restricted(strong_generators *SG, actions::action *A, int *&result, int &nb_gens, int &degree, int nb_factors, std::string &orbits_restricted_fname, int verbose_level)
long int rank_point(int *v, int verbose_level)
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define NEW_uchar(n)
Definition: foundations.h:634
#define FREE_uchar(p)
Definition: foundations.h:647
#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
unsigned char uchar
Definition: foundations.h:204
#define NEW_pint(n)
Definition: foundations.h:627
#define NEW_char(n)
Definition: foundations.h:632
#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 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 FREE_char(p)
Definition: foundations.h:646
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define MAXIMUM(x, y)
Definition: foundations.h:217
void choose_random_generator_derived_group(sims *G, int *Elt, int verbose_level)
Definition: sims2.cpp:18
the orbiter library for the classification of combinatorial objects
groups::permutation_representation * Permutation_representation