Orbiter 2022
Combinatorial Objects
schreier_io.cpp
Go to the documentation of this file.
1// schreier_io.cpp
2//
3// Anton Betten
4// moved here from schreier.cpp: November 3, 2018
5// originally started as schreier.cpp: December 9, 2003
6
8#include "group_actions.h"
9
10
11using namespace std;
12
13
14namespace orbiter {
15namespace layer3_group_actions {
16namespace groups {
17
18
19void schreier::latex(std::string &fname)
20{
21 int f_with_cosetrep = TRUE;
22
23 {
24 ofstream fp(fname);
26
27 L.head_easy(fp);
28
30
31 fp << "Orbit lengths: $";
33 fp << "$\\\\" << endl;
34
36
37 if (A->degree < 100) {
38 print_tables_latex(fp, f_with_cosetrep);
39 }
40
41 L.foot(fp);
42 }
43}
44
45
46void schreier::print_orbit_lengths(std::ostream &ost)
47{
48 int i, f, l, m;
49 int *orbit_len_sorted;
50 int *sorting_perm;
51 int *sorting_perm_inv;
52 int nb_types;
53 int *type_first;
54 int *type_len;
56
57 Sorting.int_vec_classify(nb_orbits, orbit_len, orbit_len_sorted,
58 sorting_perm, sorting_perm_inv,
59 nb_types, type_first, type_len);
60
61 ost << nb_orbits << " orbits: " << endl;
62 for (i = 0; i < nb_types; i++) {
63 f = type_first[i];
64 l = type_len[i];
65 m = orbit_len_sorted[f];
66 if (l > 1) {
67 cout << l << " \\times ";
68 }
69 cout << m;
70 if (i < nb_types - 1) {
71 cout << ", ";
72 }
73 }
74 ost << endl;
75 FREE_int(orbit_len_sorted);
76 FREE_int(sorting_perm);
77 FREE_int(sorting_perm_inv);
78 FREE_int(type_first);
79 FREE_int(type_len);
80
81}
82
83void schreier::print_orbit_lengths_tex(std::ostream &ost)
84{
85 int i, f, l, m;
86 int *orbit_len_sorted;
87 int *sorting_perm;
88 int *sorting_perm_inv;
89 int nb_types;
90 int *type_first;
91 int *type_len;
93
94 Sorting.int_vec_classify(nb_orbits, orbit_len, orbit_len_sorted,
95 sorting_perm, sorting_perm_inv,
96 nb_types, type_first, type_len);
97
98 ost << "There are " << nb_orbits << " orbits, the orbit lengths are $";
99 for (i = 0; i < nb_types; i++) {
100 f = type_first[i];
101 l = type_len[i];
102 m = orbit_len_sorted[f];
103 ost << m;
104 if (l > 1) {
105 ost << "^{" << l << "}";
106 }
107 if (i < nb_types - 1) {
108 ost << ", ";
109 }
110 }
111 ost << "$ \\\\" << endl;
112 FREE_int(orbit_len_sorted);
113 FREE_int(sorting_perm);
114 FREE_int(sorting_perm_inv);
115 FREE_int(type_first);
116 FREE_int(type_len);
117
118}
119
120void schreier::print_fixed_points_tex(std::ostream &ost)
121{
122 int i, f, l, m, idx, h, fst, j, a;
123 int *orbit_len_sorted;
124 int *sorting_perm;
125 int *sorting_perm_inv;
126 int nb_types;
127 int *type_first;
128 int *type_len;
130
131 Sorting.int_vec_classify(nb_orbits, orbit_len, orbit_len_sorted,
132 sorting_perm, sorting_perm_inv,
133 nb_types, type_first, type_len);
134
135 idx = -1;
136 for (i = 0; i < nb_types; i++) {
137 fst = type_first[i];
138 m = orbit_len_sorted[fst];
139 if (m == 1) {
140 idx = i;
141 }
142 }
143 if (idx >= 0) {
144 fst = type_first[idx];
145 l = type_len[idx];
146 ost << "There are " << l << " fixed elements, they are:\\\\";
147 for (h = 0; h < l; h++) {
148 j = sorting_perm_inv[fst + h];
149 f = orbit_first[j];
150 a = orbit[f];
151 ost << a << "\\\\" << endl;
152 }
153 }
154 FREE_int(orbit_len_sorted);
155 FREE_int(sorting_perm);
156 FREE_int(sorting_perm_inv);
157 FREE_int(type_first);
158 FREE_int(type_len);
159
160}
161
162
164{
165 int *val, *mult, len;
166
169 ost << endl;
170
171 FREE_int(val);
172 FREE_int(mult);
173}
174
175void schreier::print_orbit_reps(std::ostream &ost)
176{
177 int i, c, r;
178
179 ost << nb_orbits << " orbits" << endl;
180 ost << "orbits of a group with " << gens.len
181 << " generators:" << endl;
182 ost << "i : orbit_first[i] : orbit_len[i] : rep" << endl;
183 for (i = 0; i < nb_orbits; i++) {
184 ost << setw(3) << i << " : " << setw(6)
185 << orbit_first[i] << " : " << setw(6) << orbit_len[i];
186 c = orbit_first[i];
187 r = orbit[c];
188 ost << " : " << setw(6) << r << endl;
189 //<< " : ";
190 //print_orbit(ost, i);
191 //ost << endl;
192 }
193 ost << endl;
194}
195
196void schreier::print(std::ostream &ost)
197{
198 int i;
199
200 ost << nb_orbits << " orbits" << endl;
201 ost << "orbit group with " << gens.len << " generators:" << endl;
202 ost << "i : orbit_first[i] : orbit_len[i]" << endl;
203 for (i = 0; i < nb_orbits; i++) {
204 ost << i << " : " << orbit_first[i] << " : "
205 << orbit_len[i] << endl;
206 //<< " : ";
207 //print_orbit(ost, i);
208 //ost << endl;
209 }
210 ost << endl;
211}
212
215 void (*print_point)(ostream &ost, int pt, void *data),
216 void *data)
217{
218 int i;
219
220 ost << nb_orbits << " orbits" << endl;
221 ost << "orbit group with " << gens.len << " generators:" << endl;
222 ost << "i : orbit_first[i] : orbit_len[i]" << endl;
223 for (i = 0; i < nb_orbits; i++) {
224
225 sims *Stab;
227
228 ost << "Orbit " << i << " / " << nb_orbits
229 << " : of length " << orbit_len[i];
230 ost << " is:" << endl;
231 print_orbit(ost, i);
232 ost << endl;
233 ost << "Which is:" << endl;
234 print_orbit_using_callback(ost, i, print_point, data);
235 //ost << endl;
236 ost << "The stabilizer of the element "
237 << orbit[orbit_first[i]] << " is:" << endl;
238 point_stabilizer(default_action, go, Stab, i, 0 /* verbose_level */);
239
241
242 SG->init_from_sims(Stab, 0 /* verbose_level*/);
243 SG->print_generators(ost);
244 FREE_OBJECT(SG);
245 FREE_OBJECT(Stab);
246 }
247 ost << endl;
248}
249
250void schreier::print_and_list_orbits(std::ostream &ost)
251{
252 int i;
253
254 ost << nb_orbits << " orbits" << endl;
255 ost << "orbit group with " << gens.len << " generators:" << endl;
256 ost << "i : orbit_first[i] : orbit_len[i]" << endl;
257 for (i = 0; i < nb_orbits; i++) {
258 ost << " Orbit " << i << " / " << nb_orbits
259 << " : " << orbit_first[i] << " : " << orbit_len[i];
260 ost << " : ";
261 print_orbit(ost, i);
262 ost << endl;
263 }
264 ost << endl;
265}
266
268{
269 int i;
270
271 ost << nb_orbits << " orbits" << endl;
272 ost << "orbit group with " << gens.len << " generators:" << endl;
273 ost << "i : orbit_first[i] : orbit_len[i]" << endl;
274 for (i = 0; i < nb_orbits; i++) {
275 ost << " Orbit " << i << " / " << nb_orbits
276 << " : " << orbit_first[i] << " : " << orbit_len[i];
277 ost << " : ";
278 print_orbit(ost, i);
279 ost << endl;
280 }
281 ost << endl;
282
283}
284
285
287{
288 int orbit_no;
289
290 ost << nb_orbits << " orbits:\\\\" << endl;
291 ost << "orbits under a group with " << gens.len
292 << " generators acting on a set of size "
293 << A->degree << ":\\\\" << endl;
294 //ost << "i : orbit_first[i] : orbit_len[i]" << endl;
295 for (orbit_no = 0; orbit_no < nb_orbits; orbit_no++) {
296 print_and_list_orbit_tex(orbit_no, ost);
297 }
298 ost << endl;
299}
300
302 std::ostream &ost, actions::action *default_action, strong_generators *gens,
303 int verbose_level)
304{
305 int f_v = (verbose_level >= 1);
306 int i;
307
308 if (f_v) {
309 cout << "schreier::print_and_list_all_orbits_and_stabilizers_with_list_of_elements_tex" << endl;
310 }
311 for (i = 0; i < nb_orbits; i++) {
313 i, default_action,
314 gens, ost);
315 }
316}
317
318void schreier::make_orbit_trees(std::ostream &ost,
319 std::string &fname_mask,
321 int verbose_level)
322{
323 int f_v = (verbose_level >= 1);
325
326 if (f_v) {
327 cout << "schreier::make_orbit_trees" << endl;
328 }
329 int f_has_point_labels = FALSE;
330 long int *point_labels = NULL;
331
332 draw_forest(fname_mask,
333 Opt,
334 f_has_point_labels, point_labels,
335 verbose_level - 1);
336
337
338 int i;
339 for (i = 0; i < nb_orbits; i++) {
340 char fname[1000];
341
342 sprintf(fname, fname_mask.c_str(), i);
343 ost << "" << endl;
344 ost << "\\bigskip" << endl;
345 ost << "" << endl;
346 ost << "Orbit " << i << " consisting of the following "
347 << orbit_len[i]
348 << " half double sixes:" << endl;
349 ost << "$$" << endl;
350 L.int_set_print_tex(ost,
351 orbit + orbit_first[i], orbit_len[i]);
352 ost << "$$" << endl;
353 ost << "" << endl;
354 ost << "\\begin{center}" << endl;
355 ost << "\\input " << fname << endl;
356 ost << "\\end{center}" << endl;
357 ost << "" << endl;
358 }
359
360
361 if (f_v) {
362 cout << "schreier::make_orbit_trees" << endl;
363 }
364}
365
367{
368 int orbit_no;
369
370 ost << nb_orbits << " orbits:\\\\" << endl;
371 ost << "orbits under a group with " << gens.len
372 << " generators acting on a set of size "
373 << A->degree << ":\\\\" << endl;
374 //ost << "i : orbit_first[i] : orbit_len[i]" << endl;
375 for (orbit_no = 0; orbit_no < nb_orbits; orbit_no++) {
376 ost << " Orbit " << orbit_no << " / " << nb_orbits << " of size " << orbit_len[orbit_no] << " : ";
377 //print_and_list_orbit_tex(i, ost);
379 orbit_no, FALSE /* f_truncate */, 0 /* max_length*/);
380 ost << "\\\\" << endl;
381 }
382 ost << endl;
383}
384
385void schreier::print_and_list_orbit_tex(int i, std::ostream &ost)
386{
387 ost << " Orbit " << i << " / " << nb_orbits << " of size " << orbit_len[i] << " : ";
388 //print_orbit_tex(ost, i);
389 print_orbit_sorted_tex(ost, i, FALSE /* f_truncate */, 0 /* max_length*/);
390 ost << "\\\\" << endl;
391}
392
394 actions::action *default_action,
395 ring_theory::longinteger_object &full_group_order, std::ostream &ost)
396{
397 ost << " Orbit " << i << " / " << nb_orbits << " : ";
398 print_orbit_tex(ost, i);
399 ost << " of length " << orbit_len[i] << "\\\\" << endl;
400
402
403 gens = stabilizer_orbit_rep(default_action,
404 full_group_order, i, 0 /*verbose_level */);
405
407
409}
410
411void schreier::write_orbit_summary(std::string &fname,
412 actions::action *default_action,
413 ring_theory::longinteger_object &full_group_order,
414 int verbose_level)
415{
416 int f_v = (verbose_level >= 1);
417
418 if (f_v) {
419 cout << "schreier::write_orbit_summary" << endl;
420 }
421 long int *Rep;
422 long int *Stab_order;
423 long int *Orbit_length;
424 int orbit_no;
425
426 Rep = NEW_lint(nb_orbits);
427 Stab_order = NEW_lint(nb_orbits);
428 Orbit_length = NEW_lint(nb_orbits);
429
430 for (orbit_no = 0; orbit_no < nb_orbits; orbit_no++) {
431 Rep[orbit_no] = orbit[orbit_first[orbit_no]];
432 Orbit_length[orbit_no] = orbit_len[orbit_no];
433
435
436 gens = stabilizer_orbit_rep(default_action,
437 full_group_order, orbit_no, 0 /*verbose_level */);
438
439 Stab_order[orbit_no] = gens->group_order_as_lint();
440
441 }
442
444 long int *Vec[3];
445 const char *column_label[] = {"Rep", "StabOrder", "OrbitLength"};
446
447 Vec[0] = Rep;
448 Vec[1] = Stab_order;
449 Vec[2] = Orbit_length;
450
451 Fio.lint_vec_array_write_csv(3 /* nb_vecs */, Vec, nb_orbits,
452 fname, column_label);
453
454 if (f_v) {
455 cout << "Written file " << fname << " of size " << Fio.file_size(fname) << endl;
456 }
457
458
459 FREE_lint(Rep);
460 FREE_lint(Stab_order);
461 FREE_lint(Orbit_length);
462 if (f_v) {
463 cout << "schreier::write_orbit_summary done" << endl;
464 }
465}
466
468 int i, actions::action *default_action,
469 strong_generators *gens, std::ostream &ost)
470{
473 ring_theory::longinteger_object full_group_order;
474
475 gens->group_order(full_group_order);
476
477 ost << " Orbit " << i << " / " << nb_orbits << " : ";
478 print_orbit_tex(ost, i);
479 ost << " of length " << orbit_len[i] << "\\\\" << endl;
480
481 strong_generators *gens_stab;
482
483 gens_stab = stabilizer_orbit_rep(
484 default_action,
485 full_group_order, i, 0 /*verbose_level */);
486
487 gens_stab->print_generators_tex(ost);
488
489#if 0
490 long int *Subgroup_elements_by_index;
491 long int sz_subgroup;
492
493 sz_subgroup = gens_stab->group_order_as_lint();
494
495 if (sz_subgroup < 20) {
496 gens->list_of_elements_of_subgroup(gens_stab,
497 Subgroup_elements_by_index, sz_subgroup,
498 0 /* verbose_level */);
499
500 Sorting.lint_vec_heapsort(Subgroup_elements_by_index,
501 sz_subgroup);
502
503 ost << "The subgroup consists of the following "
504 << sz_subgroup << " elements:" << endl;
505 ost << "$$" << endl;
507 Subgroup_elements_by_index, sz_subgroup,
508 10 /* width */, TRUE /* f_tex */);
509 ost << "$$" << endl;
510
511 FREE_lint(Subgroup_elements_by_index);
512
513 }
514#endif
515
516 FREE_OBJECT(gens_stab);
517}
518
520 std::ostream &ost)
521{
523}
524
526 std::ostream &ost)
527{
529}
530
532 std::ostream &ost, int f_tex)
533{
534 int i, h;
535 int *Len;
536 int *Perm;
537 int *Perm_inv;
539
540 Len = NEW_int(nb_orbits);
541 Perm = NEW_int(nb_orbits);
542 Perm_inv = NEW_int(nb_orbits);
545 Perm, Perm_inv, TRUE /*f_increasingly*/);
546
547 ost << "There are " << nb_orbits
548 << " orbits under a group with "
549 << gens.len << " generators:";
550 if (f_tex) {
551 ost << "\\\\" << endl;
552 }
553 else {
554 ost << endl;
555 }
556 ost << "Orbit lengths: ";
558 if (f_tex) {
559 ost << "\\\\" << endl;
560 }
561 else {
562 ost << endl;
563 }
564 if (!f_tex) {
565 ost << "i : orbit_len[i]" << endl;
566 }
567 for (h = 0; h < nb_orbits; h++) {
568 i = Perm_inv[h];
569 if (f_tex) {
571 }
572 else {
573 ost << " Orbit " << h << " / " << nb_orbits
574 << " is " << i << " : " << orbit_len[i];
575 ost << " : ";
576 print_orbit(ost, i);
577 ost << endl;
578 }
579 }
580 ost << endl;
581
582 FREE_int(Len);
583 FREE_int(Perm);
584 FREE_int(Perm_inv);
585}
586
588 std::ostream &ost, int f_tex,
589 actions::action *default_action,
590 ring_theory::longinteger_object &full_group_order)
591{
592 int i, h;
593 int *Len;
594 int *Perm;
595 int *Perm_inv;
597
598 Len = NEW_int(nb_orbits);
599 Perm = NEW_int(nb_orbits);
600 Perm_inv = NEW_int(nb_orbits);
603 Perm, Perm_inv, TRUE /*f_increasingly*/);
604
605 ost << "There are " << nb_orbits << " orbits under a group with "
606 << gens.len << " generators:";
607 if (f_tex) {
608 ost << "\\\\" << endl;
609 }
610 else {
611 ost << endl;
612 }
613 ost << "Orbit lengths: ";
615 if (f_tex) {
616 ost << "\\\\" << endl;
617 }
618 else {
619 ost << endl;
620 }
621 if (!f_tex) {
622 ost << "i : orbit_len[i]" << endl;
623 }
624 for (h = 0; h < nb_orbits; h++) {
625 i = Perm_inv[h];
626 if (f_tex) {
628 default_action, full_group_order, ost);
629 }
630 else {
631 ost << " Orbit " << h << " / " << nb_orbits
632 << " is " << i << " : " << orbit_len[i];
633 ost << " : ";
634 print_orbit(ost, i);
635 ost << endl;
636 }
637 }
638 ost << endl;
639
640 FREE_int(Len);
641 FREE_int(Perm);
642 FREE_int(Perm_inv);
643}
644
646 std::ostream &ost, int f_tex,
647 actions::action *default_action,
648 strong_generators *gens_full_group)
649{
650 int i, h;
651 int *Len;
652 int *Perm;
653 int *Perm_inv;
654 ring_theory::longinteger_object full_group_order;
656
657 gens_full_group->group_order(full_group_order);
658 Len = NEW_int(nb_orbits);
659 Perm = NEW_int(nb_orbits);
660 Perm_inv = NEW_int(nb_orbits);
663 Perm, Perm_inv, TRUE /*f_increasingly*/);
664
665 ost << "There are " << nb_orbits << " orbits under a group with "
666 << gens.len << " generators:";
667 if (f_tex) {
668 ost << "\\\\" << endl;
669 }
670 else {
671 ost << endl;
672 }
673 ost << "Orbit lengths: ";
675 if (f_tex) {
676 ost << "\\\\" << endl;
677 }
678 else {
679 ost << endl;
680 }
681 if (!f_tex) {
682 ost << "i : orbit_len[i]" << endl;
683 }
684 for (h = 0; h < nb_orbits; h++) {
685 i = Perm_inv[h];
686 if (f_tex) {
687 //print_and_list_orbit_and_stabilizer_tex(
688 // i, default_action, full_group_order, ost);
690 i, default_action,
691 gens_full_group, ost);
692 }
693 else {
694 ost << " Orbit " << h << " / " << nb_orbits
695 << " is " << i << " : " << orbit_len[i];
696 ost << " : ";
697 print_orbit(ost, i);
698 ost << endl;
699 }
700 }
701 ost << endl;
702
703 FREE_int(Len);
704 FREE_int(Perm);
705 FREE_int(Perm_inv);
706}
707
709 std::ostream &ost, int len)
710{
711 int i;
712
713
714 ost << "Orbits of length " << len << ":" << endl;
715 cout << "i : orbit_len[i]" << endl;
716 for (i = 0; i < nb_orbits; i++) {
717 if (orbit_len[i] != len) {
718 continue;
719 }
720 ost << " Orbit " << i << " / "
721 << nb_orbits << " : " << orbit_len[i];
722 ost << " : ";
723 print_orbit(ost, i);
724 ost << endl;
725 }
726 ost << endl;
727}
728
730 std::ostream &ost, long int *labels)
731{
732 int i;
733
734 ost << nb_orbits << " orbits" << endl;
735 ost << "orbit group with " << gens.len << " generators:" << endl;
736 ost << "i : orbit_first[i] : orbit_len[i]" << endl;
737 for (i = 0; i < nb_orbits; i++) {
738 ost << i << " : " << orbit_first[i]
739 << " : " << orbit_len[i];
740 ost << " : ";
741 print_orbit_using_labels(ost, i, labels);
742 ost << endl;
743 }
744 ost << endl;
745}
746
747void schreier::print_tables(std::ostream &ost,
748 int f_with_cosetrep)
749{
750 int i;
751 int w; // j, k;
753
754#if 0
755 ost << gens.len << " generators:" << endl;
756 for (i = 0; i < A->degree; i++) {
757 ost << i;
758 for (j = 0; j < gens.len; j++) {
759 k = A->element_image_of(i, gens.ith(j), FALSE);
760 ost << " : " << k;
761 }
762 ost << endl;
763 }
764 ost << endl;
765#endif
766 w = NT.int_log10(A->degree) + 1;
767 ost << "i : orbit[i] : orbit_inv[i] : prev[i] : label[i]";
768 if (f_with_cosetrep)
769 ost << " : coset_rep";
770 ost << endl;
771
772 if (A->degree < 100) {
773 for (i = 0; i < A->degree; i++) {
774 coset_rep(i, 0 /* verbose_level */);
775 //coset_rep_inv(i);
776 ost << setw(w) << i << " : " << " : "
777 << setw(w) << orbit[i] << " : "
778 << setw(w) << orbit_inv[i] << " : "
779 << setw(w) << prev[i] << " : "
780 << setw(w) << label[i];
781 if (f_with_cosetrep) {
782 ost << " : ";
783 //A->element_print(Elt1, cout);
785 ost << endl;
787 }
788 ost << endl;
789 }
790 }
791 else {
792 cout << "too large to print" << endl;
793 }
794 ost << endl;
795}
796
797void schreier::print_tables_latex(std::ostream &ost,
798 int f_with_cosetrep)
799{
800 int i;
801 int w; // j, k;
803
804#if 0
805 ost << gens.len << " generators:" << endl;
806 for (i = 0; i < A->degree; i++) {
807 ost << i;
808 for (j = 0; j < gens.len; j++) {
809 k = A->element_image_of(i, gens.ith(j), FALSE);
810 ost << " : " << k;
811 }
812 ost << endl;
813 }
814 ost << endl;
815#endif
816 w = NT.int_log10(A->degree) + 1;
817 ost << "$$" << endl;
818 ost << "\\begin{array}{|c|c|c|c|c|" << endl;
819 if (f_with_cosetrep) {
820 ost << "c|";
821 }
822 ost << "}" << endl;
823 ost << "\\hline" << endl;
824 ost << "i & orbit & orbitinv & prev & label";
825 if (f_with_cosetrep) {
826 ost << "& cosetrep";
827 }
828 ost << "\\\\" << endl;
829 ost << "\\hline" << endl;
830 ost << "\\hline" << endl;
831 for (i = 0; i < A->degree; i++) {
832 coset_rep(i, 0 /* verbose_level */);
833 //coset_rep_inv(i);
834 ost << i << " & "
835 << setw(w) << orbit[i] << " & "
836 << setw(w) << orbit_inv[i] << " & "
837 << setw(w) << prev[i] << " & "
838 << setw(w) << label[i];
839 if (f_with_cosetrep) {
840 ost << " & ";
841 //A->element_print(Elt1, cout);
842 //A->element_print_as_permutation(cosetrep, ost);
843 //ost << endl;
845 }
846 ost << "\\\\" << endl;
847 ost << "\\hline" << endl;
848
849 if (((i + 1) % 10) == 0) {
850 ost << "\\end{array}" << endl;
851 ost << "$$" << endl;
852 ost << "$$" << endl;
853 ost << "\\begin{array}{|c|c|c|c|c|" << endl;
854 if (f_with_cosetrep) {
855 ost << "c|";
856 }
857 ost << "}" << endl;
858 ost << "\\hline" << endl;
859 ost << "i & orbit & orbitinv & prev & label";
860 if (f_with_cosetrep) {
861 ost << "& cosetrep";
862 }
863 ost << "\\\\" << endl;
864 ost << "\\hline" << endl;
865 ost << "\\hline" << endl;
866 }
867 }
868 ost << "\\end{array}" << endl;
869 ost << "$$" << endl;
870 ost << endl;
871}
872
874{
875 int j;
876
877 cout << gens.len << " generators in action "
878 << A->label << " of degree " << A->degree << ":" << endl;
879 for (j = 0; j < gens.len; j++) {
880 cout << "generator " << j << ":" << endl;
881 //A->element_print(gens.ith(j), cout);
882 A->element_print_quick(gens.ith(j), cout);
883 //A->element_print_as_permutation(gens.ith(j), cout);
884 if (j < gens.len - 1) {
885 cout << ", " << endl;
886 }
887 }
888}
889
890void schreier::print_generators_latex(std::ostream &ost)
891{
892 int j;
893
894 ost << gens.len << " generators in action $"
895 << A->label_tex << "$ of degree "
896 << A->degree << ":\\\\" << endl;
897 for (j = 0; j < gens.len; j++) {
898 ost << "generator " << j << ":" << endl;
899 //A->element_print(gens.ith(j), cout);
900 ost << "$$" << endl;
901 A->element_print_latex(gens.ith(j), ost);
902 //A->element_print_as_permutation(gens.ith(j), cout);
903 if (j < gens.len - 1) {
904 ost << ", " << endl;
905 }
906 ost << "$$" << endl;
907 }
908}
909
911{
912 int j;
913
914 cout << gens.len << " generators in action "
915 << A->label << " of degree "
916 << A->degree << ":" << endl;
917 for (j = 0; j < gens.len; j++) {
918 cout << "generator " << j << ":" << endl;
919 //A->element_print(gens.ith(j), cout);
920 A->element_print_quick(gens.ith(j), cout);
922 cout << endl;
923 if (j < gens.len - 1) {
924 cout << ", " << endl;
925 }
926 }
927}
928
929void schreier::print_orbit(int orbit_no)
930{
931 print_orbit(cout, orbit_no);
932}
933
935 int orbit_no, long int *labels)
936{
937 print_orbit_using_labels(cout, orbit_no, labels);
938}
939
940void schreier::print_orbit(std::ostream &ost, int orbit_no)
941{
942 int i, first, len;
943 long int *v;
944
945 first = orbit_first[orbit_no];
946 len = orbit_len[orbit_no];
947 v = NEW_lint(len);
948 for (i = 0; i < len; i++) {
949 v[i] = orbit[first + i];
950 }
951 //int_vec_print(ost, v, len);
952 //int_vec_heapsort(v, len);
953 Lint_vec_print_fully(ost, v, len);
954
955 FREE_lint(v);
956}
957
958void schreier::print_orbit_with_original_labels(std::ostream &ost, int orbit_no)
959{
960 int i, first, len;
961 long int *v;
962 long int *w;
963
964 first = orbit_first[orbit_no];
965 len = orbit_len[orbit_no];
966 v = NEW_lint(len);
967 for (i = 0; i < len; i++) {
968 v[i] = orbit[first + i];
969 }
970
971 A->original_point_labels(v, len, w, 0 /*verbose_level*/);
972
973
974 //int_vec_print(ost, v, len);
975 //int_vec_heapsort(v, len);
976 Lint_vec_print_fully(ost, w, len);
977
978 FREE_lint(v);
979 FREE_lint(w);
980}
981
982void schreier::print_orbit_tex(std::ostream &ost, int orbit_no)
983{
985 int i, first, len;
986 int *v;
988
989 first = orbit_first[orbit_no];
990 len = orbit_len[orbit_no];
991 v = NEW_int(len);
992 for (i = 0; i < len; i++) {
993 v[i] = orbit[first + i];
994 }
995 //int_vec_print(ost, v, len);
996 Sorting.int_vec_heapsort(v, len);
997 //int_vec_print_fully(ost, v, len);
998 L.int_set_print_tex(ost, v, len);
999
1000 FREE_int(v);
1001}
1002
1004 int orbit_no, int f_truncate, int max_length)
1005{
1007 int i, first, len;
1008 int *v;
1010
1011 first = orbit_first[orbit_no];
1012 len = orbit_len[orbit_no];
1013 v = NEW_int(len);
1014 for (i = 0; i < len; i++) {
1015 v[i] = orbit[first + i];
1016 }
1017 //int_vec_print(ost, v, len);
1018 Sorting.int_vec_heapsort(v, len);
1019 //int_vec_print_fully(ost, v, len);
1020 if (f_truncate && len > max_length) {
1021 L.int_set_print_tex(ost, v, max_length);
1022 ost << "truncated after " << max_length << " elements";
1023 }
1024 else {
1025 L.int_set_print_tex(ost, v, len);
1026 }
1027
1028 FREE_int(v);
1029}
1030
1032 int orbit_no, int f_truncate, int max_length)
1033{
1035 int i, first, len;
1036 long int *v;
1037 long int *w;
1039
1040 first = orbit_first[orbit_no];
1041 len = orbit_len[orbit_no];
1042 v = NEW_lint(len);
1043 for (i = 0; i < len; i++) {
1044 v[i] = orbit[first + i];
1045 }
1046
1047 //int_vec_print(ost, v, len);
1048 Sorting.lint_vec_heapsort(v, len);
1049 //int_vec_print_fully(ost, v, len);
1050
1051 A->original_point_labels(v, len, w, 0 /*verbose_level*/);
1052
1053 if (f_truncate && len > max_length) {
1054 L.lint_set_print_tex(ost, w, max_length);
1055 ost << "truncated after " << max_length << " elements";
1056 }
1057 else {
1058 L.lint_set_print_tex(ost, w, len);
1059 }
1060
1061 FREE_lint(v);
1062 FREE_lint(w);
1063}
1064
1065
1067 int orbit_no, long int *labels)
1068{
1069 int i, first, len;
1070 int *v;
1072
1073 first = orbit_first[orbit_no];
1074 len = orbit_len[orbit_no];
1075 v = NEW_int(len);
1076 for (i = 0; i < len; i++) {
1077 v[i] = labels[orbit[first + i]];
1078 }
1079 //int_vec_print(ost, v, len);
1080 Sorting.int_vec_heapsort(v, len);
1081 Int_vec_print_fully(ost, v, len);
1082
1083 FREE_int(v);
1084}
1085
1087 int orbit_no,
1088 void (*print_point)(ostream &ost, int pt, void *data),
1089 void *data)
1090{
1091 int i, first, len;
1092
1093 first = orbit_first[orbit_no];
1094 len = orbit_len[orbit_no];
1095 for (i = 0; i < len; i++) {
1096 ost << orbit[first + i] << " which is " << endl;
1097 (*print_point)(ost, orbit[first + i], data);
1098 }
1099}
1100
1101void schreier::print_orbit_type(int f_backwards)
1102{
1104
1105 C.init(orbit_len, nb_orbits, FALSE, 0);
1106 C.print_naked(f_backwards);
1107}
1108
1109void schreier::list_all_orbits_tex(std::ostream &ost)
1110{
1111 int i, j, f, l, a;
1112
1113 ost << "$";
1114 for (i = 0; i < nb_orbits; i++) {
1115 f = orbit_first[i];
1116 l = orbit_len[i];
1117 for (j = 0; j < l; j++) {
1118 a = orbit[f + j];
1119 ost << a;
1120 if (j < l - 1) {
1121 ost << ", ";
1122 }
1123 }
1124 if (i < nb_orbits - 1) {
1125 ost << " \\mid ";
1126 }
1127 }
1128 ost << "$";
1129}
1130
1132 int orbit_no, long int *point_labels)
1133{
1134 int i, first, len;
1135 long int *v;
1137
1138 first = orbit_first[orbit_no];
1139 len = orbit_len[orbit_no];
1140 v = NEW_lint(len);
1141 for (i = 0; i < len; i++) {
1142 v[i] = point_labels[orbit[first + i]];
1143 }
1144 Sorting.lint_vec_heapsort(v, len);
1145 Lint_vec_print_fully(ost, v, len);
1146 FREE_lint(v);
1147}
1148
1149void schreier::print_orbit_sorted(std::ostream &ost, int orbit_no)
1150{
1151 int i, len;
1152 int *v;
1154
1155 len = orbit_first[orbit_no + 1] - orbit_first[orbit_no];
1156 v = NEW_int(len);
1157 for (i = 0; i < len; i++) {
1158 v[i] = orbit[orbit_first[orbit_no] + i];
1159 }
1160 Sorting.int_vec_heapsort(v, len);
1161
1162 ost << "{ ";
1163 for (i = 0; i < len; i++) {
1164 if (f_print_function) {
1165 ost << v[i] << "=";
1166 (*print_function)(ost, v[i], print_function_data);
1167 }
1168 else {
1169 ost << v[i];
1170 }
1171 if (i < len - 1) {
1172 ost << ", ";
1173 }
1174 }
1175 ost << " }";
1176 FREE_int(v);
1177}
1178
1179void schreier::print_orbit(int cur, int last)
1180{
1181 int i;
1182
1183 cout << "schreier::print_orbit degree=" << A->degree << endl;
1184 cout << "i : orbit[i] : orbit_inv[i]" << endl;
1185 for (i = 0; i < A->degree; i++) {
1186 if (i == cur) {
1187 cout << ">";
1188 }
1189 if (i == last) {
1190 cout << ">";
1191 }
1192 cout << i << " : " << orbit[i]
1193 << " : " << orbit_inv[i] << endl;
1194 }
1195 cout << endl;
1196}
1197
1198void schreier::print_tree(int orbit_no)
1199{
1200 int *path;
1201 int i, j, l;
1202
1203 path = NEW_int(A->degree);
1204 i = orbit_first[orbit_no];
1205 while (i < orbit_first[orbit_no + 1]) {
1206 trace_back(path, orbit[i], l);
1207 // now l is the distance from the root
1208 cout << l;
1209 for (j = 0; j < l; j++) {
1210 cout << " " << path[j];
1211 }
1212 cout << " 0 ";
1213 if (label[i] != -1) {
1214 cout << " $s_{" << label[i] << "}$";
1215 }
1216 cout << endl;
1217 i++;
1218 }
1219 FREE_int(path);
1220}
1221
1222void schreier::draw_forest(std::string &fname_mask,
1224 int f_has_point_labels, long int *point_labels,
1225 int verbose_level)
1226{
1227 int f_v = (verbose_level >= 1);
1228 char str[1000];
1229 int i;
1230
1231 if (f_v) {
1232 cout << "schreier::draw_forest" << endl;
1233 }
1234 for (i = 0; i < nb_orbits; i++) {
1235 sprintf(str, fname_mask.c_str(), i);
1236 string fname;
1237
1238 fname.assign(str);
1239
1240 if (f_v) {
1241 cout << "schreier::draw_forest drawing orbit "
1242 << i << " / " << nb_orbits << endl;
1243 }
1244 draw_tree(fname,
1245 Opt,
1246 i /* orbit_no */,
1247 f_has_point_labels, point_labels,
1248 verbose_level);
1249 }
1250 if (f_v) {
1251 cout << "schreier::draw_forest done" << endl;
1252 }
1253}
1254
1256 std::string &fname_mask,
1257 int verbose_level)
1258{
1259 int f_v = (verbose_level >= 1);
1260 int f_vv = (verbose_level >= 2);
1261 int f_vvv = (verbose_level >= 3);
1262 int fst, len;
1263 int *depth;
1264 int *horizontal_position;
1265 int i, j, l, max_depth;
1266
1267 if (f_v) {
1268 cout << "schreier::export_tree_as_layered_graph" << endl;
1269 cout << "schreier::export_tree_as_layered_graph "
1270 "nb_gen = " << gens.len << endl;
1271 }
1272
1273 fst = orbit_first[orbit_no];
1274 len = orbit_len[orbit_no];
1275 depth = NEW_int(len);
1276 horizontal_position = NEW_int(len);
1277 max_depth = 0;
1278 for (j = 0; j < len; j++) {
1279 trace_back(NULL, orbit[fst + j], l);
1280 l--;
1281 depth[j] = l;
1282 max_depth = MAX(max_depth, l);
1283 }
1284 int nb_layers;
1285 nb_layers = max_depth + 1;
1286 int *Nb;
1287 int *Nb1;
1288 int **Node;
1289
1290
1291 //classify C;
1292 //C.init(depth, len, FALSE, 0);
1293 Nb = NEW_int(nb_layers);
1294 Nb1 = NEW_int(nb_layers);
1295 Int_vec_zero(Nb, nb_layers);
1296 Int_vec_zero(Nb1, nb_layers);
1297 for (j = 0; j < len; j++) {
1298 trace_back(NULL, orbit[fst + j], l);
1299 l--;
1300 horizontal_position[j] = Nb[l];
1301 Nb[l]++;
1302 }
1303 if (f_v) {
1304 cout << "schreier::export_tree_as_layered_graph" << endl;
1305 cout << "number of nodes at depth:" << endl;
1306 for (i = 0; i <= max_depth; i++) {
1307 cout << i << " : " << Nb[i] << endl;
1308 }
1309 }
1310 Node = NEW_pint(nb_layers);
1311 for (i = 0; i <= max_depth; i++) {
1312 Node[i] = NEW_int(Nb[i]);
1313 }
1314 for (j = 0; j < len; j++) {
1315 trace_back(NULL, orbit[fst + j], l);
1316 l--;
1317 Node[l][Nb1[l]] = j;
1318 Nb1[l]++;
1319 }
1320
1322 int n1, n2, j2;
1323
1325 if (f_v) {
1326 cout << "schreier::export_tree_as_layered_graph "
1327 "before LG->init" << endl;
1328 }
1329 //LG->add_data1(data1, 0/*verbose_level*/);
1330
1331 string dummy;
1332 dummy.assign("");
1333
1334 LG->init(nb_layers, Nb, dummy, verbose_level);
1335 if (f_v) {
1336 cout << "schreier::export_tree_as_layered_graph "
1337 "after LG->init" << endl;
1338 }
1339 LG->place(verbose_level);
1340 if (f_v) {
1341 cout << "schreier::export_tree_as_layered_graph "
1342 "after LG->place" << endl;
1343 }
1344 for (i = 0; i <= max_depth; i++) {
1345 if (f_vv) {
1346 cout << "schreier::export_tree_as_layered_graph "
1347 "adding edges at depth "
1348 "i=" << i << " / " << max_depth
1349 << " Nb[i]=" << Nb[i] << endl;
1350 }
1351 for (j = 0; j < Nb[i]; j++) {
1352 n1 = Node[i][j];
1353 if (f_vvv) {
1354 cout << "schreier::export_tree_as_layered_graph "
1355 "adding edges "
1356 "i=" << i << " / " << max_depth
1357 << " j=" << j << " n1=" << n1 << endl;
1358 }
1359 if (prev[fst + n1] != -1) {
1360 n2 = orbit_inv[prev[fst + n1]] - fst;
1361 j2 = horizontal_position[n2];
1362 if (f_vvv) {
1363 cout << "schreier::export_tree_as_layered_graph "
1364 "adding edges "
1365 "i=" << i << " / " << max_depth
1366 << " j=" << j << " n1=" << n1
1367 << " n2=" << n2 << " j2=" << j2 << endl;
1368 }
1369 if (f_vvv) {
1370 cout << "adding edge ("<< i - 1 << "," << j2 << ") "
1371 "-> (" << i << "," << j << ")" << endl;
1372 }
1373 LG->add_edge(i - 1, j2, i, j,
1374 0 /*verbose_level*/);
1375 }
1376 }
1377 }
1378 for (j = 0; j < len; j++) {
1379 char text[1000];
1380 int a;
1381
1382 a = orbit[fst + j];
1383 sprintf(text, "%d", a);
1384 trace_back(NULL, a, l);
1385 l--;
1386 LG->add_text(l, horizontal_position[j], text, 0/*verbose_level*/);
1387 LG->add_node_data1(l, horizontal_position[j], a, 0/*verbose_level*/);
1388 }
1389 char str[1000];
1390 string fname;
1391
1392 sprintf(str, fname_mask.c_str(), orbit_no);
1393 fname.assign(str);
1394 LG->write_file(fname, 0 /*verbose_level*/);
1395 FREE_OBJECT(LG);
1396
1397 FREE_int(Nb);
1398 FREE_int(Nb1);
1399 FREE_int(depth);
1400 FREE_int(horizontal_position);
1401
1402 if (f_v) {
1403 cout << "schreier::export_tree_as_layered_graph done" << endl;
1404 }
1405}
1406
1407void schreier::draw_tree(std::string &fname,
1409 int orbit_no,
1410 int f_has_point_labels, long int *point_labels,
1411 int verbose_level)
1412{
1413 int f_v = (verbose_level >= 1);
1414 int f_vv = (verbose_level >= 2);
1415 int *path;
1416 int *weight;
1417 int *placement_x;
1418 int i, j, last, max_depth = 0;
1419
1420
1421 if (f_v) {
1422 cout << "schreier::draw_tree" << endl;
1423 }
1424 if (f_v) {
1425 cout << "schreier::draw_tree Opt:" << endl;
1426 Opt->print();
1427 }
1428 path = NEW_int(A->degree);
1429 weight = NEW_int(A->degree);
1430 placement_x = NEW_int(A->degree);
1431
1432 i = orbit_first[orbit_no];
1433 last = orbit_first[orbit_no + 1];
1434
1435 for (j = 0; j < A->degree; j++) {
1436 weight[j] = 0;
1437 placement_x[j] = 0;
1438 }
1439 subtree_calc_weight(weight, max_depth, i, last);
1440 if (f_vv) {
1441 cout << "the weights: " << endl;
1442 for (j = i; j < last; j++) {
1443 cout << j << " : " << weight[j] << " : " << endl;
1444 }
1445 cout << endl;
1446 cout << "max_depth = " << max_depth << endl;
1447 }
1448 subtree_place(weight, placement_x, 0, Opt->xin, i, last);
1449 if (f_vv) {
1450 for (j = i; j < last; j++) {
1451 cout << j << " : " << placement_x[j] << endl;
1452 }
1453 cout << endl;
1454 }
1455#if 0
1456 if (orbit_len[orbit_no] > 100) {
1457 f_circletext = FALSE;
1458 }
1459#endif
1460
1461 draw_tree2(fname,
1462 Opt,
1463 //xmax, ymax, f_circletext,
1464 weight, placement_x, max_depth, i, last,
1465 //rad,
1466 //f_embedded, f_sideways,
1467 //scale, line_width,
1468 f_has_point_labels, point_labels,
1469 verbose_level - 2);
1470
1471 FREE_int(path);
1472 FREE_int(weight);
1473 FREE_int(placement_x);
1474 if (f_v) {
1475 cout << "schreier::draw_tree done" << endl;
1476 }
1477}
1478
1479static void calc_y_coordinate(int &y, int l, int max_depth, int y_max)
1480{
1481 int dy;
1482
1483 dy = (int)((double)y_max / (double)max_depth);
1484 //dy = (int)((double)1000000 / (double)max_depth);
1485 y = (int)(dy * ((double)l + 0.5));
1486 y = y_max - y;
1487}
1488
1489void schreier::draw_tree2(std::string &fname,
1491 int *weight, int *placement_x,
1492 int max_depth,
1493 int i,
1494 int last,
1495 int f_has_point_labels, long int *point_labels,
1496 int verbose_level)
1497{
1498 int f_v = (verbose_level >= 1);
1499 //int x_min = 0, x_max = Opt->xin;
1500 //int y_min = 0, y_max = Opt->yin;
1501 int factor_1000 = 1000;
1502 string fname_full;
1503
1504 if (f_v) {
1505 cout << "schreier::draw_tree2" << endl;
1506 }
1507
1508 fname_full.assign(fname);
1509 fname_full.append(".mp");
1510
1511 if (f_v) {
1512 cout << "schreier::draw_tree2 before creating G" << endl;
1513 }
1514
1516
1517 G.init(fname_full, Opt, verbose_level - 1);
1518
1519#if 0
1520 mp_graphics G(fname_full, x_min, y_min, x_max, y_max,
1521 Opt->f_embedded, Opt->f_sideways, verbose_level - 1);
1522 if (f_v) {
1523 cout << "schreier::draw_tree2 after creating G" << endl;
1524 }
1525 G.out_xmin() = 0;
1526 G.out_ymin() = 0;
1527 G.out_xmax() = Opt->xout;
1528 G.out_ymax() = Opt->yout;
1529 G.set_parameters(Opt->scale, Opt->line_width);
1530#endif
1531
1532 G.header();
1533 G.begin_figure(factor_1000);
1534
1535 int x = Opt->yin / 2;
1536 int y;
1537 if (f_v) {
1538 cout << "schreier::draw_tree2 before calc_y_coordinate" << endl;
1539 }
1540 calc_y_coordinate(y, 0, max_depth, Opt->yin);
1541 if (f_v) {
1542 cout << "schreier::draw_tree2 after calc_y_coordinate" << endl;
1543 }
1544
1545
1546 if (f_v) {
1547 cout << "schreier::draw_tree2 before subtree_draw_lines" << endl;
1548 }
1549 subtree_draw_lines(G, Opt,
1550 x, y, weight,
1551 placement_x, max_depth, i, last,
1552 Opt->yin,
1553 verbose_level);
1554 if (f_v) {
1555 cout << "schreier::draw_tree2 after subtree_draw_lines" << endl;
1556 }
1557
1558 if (f_v) {
1559 cout << "schreier::draw_tree2 before subtree_draw_vertices" << endl;
1560 }
1561 subtree_draw_vertices(G, Opt,
1562 x, y, weight,
1563 placement_x, max_depth, i, last,
1564 f_has_point_labels, point_labels,
1565 Opt->yin,
1566 verbose_level);
1567 if (f_v) {
1568 cout << "schreier::draw_tree2 after subtree_draw_vertices" << endl;
1569 }
1570
1571 int j, L, l, N;
1572 double avg;
1573
1574 N = last - i;
1575 L = 0;
1576 for (j = i; j < last; j++) {
1577 trace_back(NULL, orbit[j], l);
1578 L += l;
1579 }
1580 avg = (double) L / (double)N;
1581 // x = 500000;
1582 x = Opt->xin / 2;
1583 calc_y_coordinate(y, max_depth + 1, max_depth, Opt->yin);
1584 char str[1000];
1585 int nb_gens;
1586 double H; // entropy
1587
1588 nb_gens = gens.len;
1589 if (nb_gens) {
1590 H = log(N) / log(nb_gens);
1591 }
1592 else {
1593 H = 0.;
1594 }
1595 sprintf(str, "N=%d, avg=%lf, gens=%d, H=%lf", N, avg, nb_gens, H);
1596 G.aligned_text(x, y, "", str);
1597
1598
1599#if 0
1600 if (f_circletext) {
1601 G.circle_text(x, y, rad, "$\\emptyset$");
1602 }
1603 else {
1604 G.circle_text(x, y, rad, "");
1605 //G.circle(x, y, rad);
1606 }
1607#endif
1608
1609 G.end_figure();
1610 //print_and_list_orbits_tex(ostream &ost)
1611 G.footer();
1612 if (f_v) {
1613 cout << "schreier::draw_tree2 done" << endl;
1614 }
1615}
1616
1620 int parent_x, int parent_y, int *weight,
1621 int *placement_x, int max_depth, int i, int last,
1622 int y_max,
1623 int verbose_level)
1624{
1625 int f_v = (verbose_level >= 1);
1626 int pt = orbit[i];
1627 int x, y, l, ii;
1628 int Px[3], Py[3];
1629
1630 if (f_v) {
1631 cout << "schreier::subtree_draw_lines" << endl;
1632 }
1633 trace_back(NULL, pt, l);
1634 // l is 1 if pt is the root.
1635 x = placement_x[pt];
1636 calc_y_coordinate(y, l, max_depth, y_max);
1637
1638 //G.circle(x, y, 2000);
1639 Px[0] = parent_x;
1640 Py[0] = parent_y;
1641 Px[1] = x;
1642 Py[1] = y;
1643 Px[2] = (Px[0] + Px[1]) >> 1;
1644 Py[2] = (Py[0] + Py[1]) >> 1;
1645 //cout << "schreier::subtree_draw_lines "
1646 // << parent_x << "," << parent_y << " - "
1647 // << x << "," << y << endl;
1648
1649
1650#if 0
1651 int y1;
1652 calc_y_coordinate(y1, 0, max_depth);
1653 if (parent_x == 500000 && parent_y == y1) {
1654 }
1655 else {
1656 G.polygon2(Px, Py, 0, 1);
1657 }
1658#endif
1659
1660 if (l > 1) {
1661 G.polygon2(Px, Py, 0, 1);
1662 }
1663
1664 if (Opt->f_label_edges) {
1665 if (l > 1) {
1666 char str[1000];
1667 // if pt is not the root node:
1668 sprintf(str, "$\\alpha_{%d}$", label[i]);
1669 G.aligned_text(Px[2], Py[2], "", str);
1670 }
1671 }
1672
1673 for (ii = i + 1; ii < last; ii++) {
1674 if (prev[ii] == pt) {
1675 subtree_draw_lines(G, Opt,
1676 x, y, weight, placement_x,
1677 max_depth, ii, last,
1678 y_max,
1679 verbose_level);
1680 }
1681 }
1682
1683 if (f_v) {
1684 cout << "schreier::subtree_draw_lines done" << endl;
1685 }
1686}
1687
1691 int parent_x, int parent_y, int *weight,
1692 int *placement_x, int max_depth, int i, int last,
1693 int f_has_point_labels, long int *point_labels,
1694 int y_max,
1695 int verbose_level)
1696{
1697 int f_v = (verbose_level >= 1);
1698 int pt = orbit[i];
1699 int x, y, l, ii;
1700 //int Px[2], Py[2];
1701 char str[1000];
1702
1703 if (f_v) {
1704 cout << "schreier::subtree_draw_vertices" << endl;
1705 }
1706 trace_back(NULL, pt, l);
1707 x = placement_x[pt];
1708 calc_y_coordinate(y, l, max_depth, y_max);
1709
1710#if 0
1711 Px[0] = parent_x;
1712 Py[0] = parent_y;
1713 Px[1] = x;
1714 Py[1] = y;
1715 //cout << "schreier::subtree_draw_vertices "
1716 // << parent_x << "," << parent_y << " - " << x << "," << y << endl;
1717 //G.polygon2(Px, Py, 0, 1);
1718#endif
1719
1720 for (ii = i + 1; ii < last; ii++) {
1721 if (prev[ii] == pt) {
1722 subtree_draw_vertices(G, Opt,
1723 x, y, weight, placement_x,
1724 max_depth, ii, last,
1725 f_has_point_labels, point_labels,
1726 y_max,
1727 verbose_level);
1728 }
1729 }
1730#if 0
1731 if (pt == 169303 || pt == 91479) {
1732 G.circle(x, y, 4 * rad);
1733 }
1734#endif
1735 if (f_has_point_labels) {
1736 sprintf(str, "%ld", point_labels[pt]);
1737 }
1738 else {
1739 sprintf(str, "%d", pt);
1740 }
1741 if (Opt->f_nodes_empty) {
1742 G.circle_text(x, y, Opt->rad, "");
1743 //G.circle(x, y, rad);
1744 //G.aligned_text(Px, Py, 1, "tl", str);
1745 }
1746 else {
1747 G.circle_text(x, y, Opt->rad, str);
1748 }
1749 if (f_v) {
1750 cout << "schreier::subtree_draw_vertices done" << endl;
1751 }
1752}
1753
1754void schreier::subtree_place(int *weight, int *placement_x,
1755 int left, int right, int i, int last)
1756{
1757 int pt = orbit[i];
1758 int ii, l, w, w0, w1, lft, rgt, width;
1759 double dx;
1760
1761 placement_x[pt] = (left + right) >> 1;
1762 w = weight[pt];
1763 width = right - left;
1764 dx = width / (double) (w - 1);
1765 // the node itself counts for the weight, so we subtract one
1766 w0 = 0;
1767
1768 trace_back(NULL, pt, l);
1769 for (ii = i + 1; ii < last; ii++) {
1770 if (prev[ii] == pt) {
1771 w1 = weight[orbit[ii]];
1772 lft = left + (int)((double)w0 * dx);
1773 rgt = left + (int)((double)(w0 + w1) * dx);
1774 subtree_place(weight, placement_x, lft, rgt, ii, last);
1775 w0 += w1;
1776 }
1777 }
1778}
1779
1781 int &max_depth, int i, int last)
1782{
1783 int pt = orbit[i];
1784 int ii, l, w = 1, w1;
1785
1786 trace_back(NULL, pt, l);
1787 if (l > max_depth)
1788 max_depth = l;
1789 for (ii = i + 1; ii < last; ii++) {
1790 if (prev[ii] == pt) {
1791 w1 = subtree_calc_weight(weight, max_depth, ii, last);
1792 w += w1;
1793 }
1794 }
1795 weight[pt] = w;
1796 return w;
1797}
1798
1799int schreier::subtree_depth_first(std::ostream &ost,
1800 int *path, int i, int last)
1801{
1802 int pt = orbit[i];
1803 int ii, l, w = 1, w1;
1804
1805 for (ii = i + 1; ii < last; ii++) {
1806 if (prev[ii] == pt) {
1807
1808
1809 trace_back(path, orbit[ii], l);
1810 // now l is the distance from the root
1811 print_path(ost, path, l);
1812
1813 w1 = subtree_depth_first(ost, path, ii, last);
1814 w += w1;
1815 }
1816 }
1817 return w;
1818}
1819
1820void schreier::print_path(std::ostream &ost, int *path, int l)
1821{
1822 int j;
1823
1824 ost << l;
1825 for (j = 0; j < l; j++) {
1826 ost << " " << path[j];
1827 }
1828 ost << endl;
1829}
1830
1831void schreier::write_to_file_csv(std::string &fname_csv, int verbose_level)
1832{
1833 int f_v = (verbose_level >= 1);
1834
1835 if (f_v) {
1836 cout << "schreier::write_to_file_csv" << endl;
1837 }
1839
1840 int nb_rows;
1841 int nb_cols;
1842 int i;
1843
1844 nb_rows = 1 + nb_orbits;
1845 nb_cols = 6;
1846 S.init_empty_table(nb_rows, nb_cols);
1847
1848 std::string text;
1849 text.assign("OrbitNumber");
1850 S.fill_entry_with_text(0, 0, text);
1851 text.assign("OrbitLength");
1852 S.fill_entry_with_text(0, 1, text);
1853 text.assign("OrbitRep");
1854 S.fill_entry_with_text(0, 2, text);
1855 text.assign("OrbitElements");
1856 S.fill_entry_with_text(0, 3, text);
1857 text.assign("OrbitSVPrev");
1858 S.fill_entry_with_text(0, 4, text);
1859 text.assign("OrbitSVLabel");
1860 S.fill_entry_with_text(0, 5, text);
1861 for (i = 0; i < nb_orbits; i++) {
1862
1863 int len;
1864
1865 len = orbit_len[i];
1866
1867 S.set_entry_lint(1 + i, 0, i);
1868 S.set_entry_lint(1 + i, 1, len);
1869 S.set_entry_lint(1 + i, 2, orbit[orbit_first[i]]);
1870
1871 string str;
1872
1874 S.fill_entry_with_text(1 + i, 3, str);
1875
1876
1877 str.assign("");
1879 S.fill_entry_with_text(1 + i, 4, str);
1880
1881
1882 str.assign("");
1884 S.fill_entry_with_text(1 + i, 5, str);
1885
1886 }
1887 S.save(fname_csv, 0/* verbose_level*/);
1889
1890 if (f_v) {
1891 cout << "Written file " << fname_csv << " of size " << Fio.file_size(fname_csv) << endl;
1892 }
1893
1894 if (f_v) {
1895 cout << "schreier::write_to_file_csv done" << endl;
1896 }
1897}
1898
1899
1900void schreier::write_to_file_binary(std::ofstream &fp, int verbose_level)
1901{
1902 int f_v = (verbose_level >= 1);
1903 int i, a = 0, version = 1;
1904
1905 if (f_v) {
1906 cout << "schreier::write_to_file_binary" << endl;
1907 }
1908 fp.write((char *) &a, sizeof(int));
1909 fp.write((char *) &version, sizeof(int));
1910 fp.write((char *) &A->degree, sizeof(int));
1911 fp.write((char *) &nb_orbits, sizeof(int));
1912 for (i = 0; i < nb_orbits; i++) {
1913 fp.write((char *) &orbit_first[i], sizeof(int));
1914 fp.write((char *) &orbit_len[i], sizeof(int));
1915 }
1916 for (i = 0; i < A->degree; i++) {
1917 fp.write((char *) &orbit[i], sizeof(int));
1918 fp.write((char *) &prev[i], sizeof(int));
1919 fp.write((char *) &label[i], sizeof(int));
1920 //fp.write((char *) &orbit_no[i], sizeof(int));
1921 }
1922 gens.write_to_file_binary(fp, 0 /*verbose_level - 1*/);
1923 gens_inv.write_to_file_binary(fp, 0 /*verbose_level - 1*/);
1924 if (f_v) {
1925 cout << "schreier::write_to_file_binary done" << endl;
1926 }
1927}
1928
1929void schreier::read_from_file_binary(std::ifstream &fp, int verbose_level)
1930{
1931 int f_v = (verbose_level >= 1);
1932 int i, deg, dummy, a, version;
1934
1935 if (f_v) {
1936 cout << "schreier::read_from_file_binary" << endl;
1937 }
1938 init2();
1939 fp.read((char *) &a, sizeof(int));
1940 if (a == 0) {
1941 fp.read((char *) &version, sizeof(int));
1942 fp.read((char *) &deg, sizeof(int));
1943 }
1944 else {
1945 version = 0;
1946 deg = a;
1947 }
1948 //fp.read((char *) &deg, sizeof(int));
1949 fp.read((char *) &nb_orbits, sizeof(int));
1950 if (deg != A->degree) {
1951 cout << "schreier::read_from_file_binary "
1952 "deg != A->degree" << endl;
1953 }
1956 for (i = 0; i < nb_orbits; i++) {
1957 fp.read((char *) &orbit_first[i], sizeof(int));
1958 fp.read((char *) &orbit_len[i], sizeof(int));
1959 }
1960 orbit = NEW_int(A->degree);
1962 prev = NEW_int(A->degree);
1963 label = NEW_int(A->degree);
1964 //orbit_no = NEW_int(A->degree);
1965 for (i = 0; i < A->degree; i++) {
1966 fp.read((char *) &orbit[i], sizeof(int));
1967 fp.read((char *) &prev[i], sizeof(int));
1968 fp.read((char *) &label[i], sizeof(int));
1969 if (version == 0) {
1970 fp.read((char *) &dummy, sizeof(int));
1971 //fp.read((char *) &orbit_no[i], sizeof(int));
1972 }
1973 }
1975
1976 gens.init(A, 0 /*verbose_level - 1*/);
1977 gens.read_from_file_binary(fp, 0 /*verbose_level - 1*/);
1978 gens_inv.init(A, 0 /*verbose_level - 1*/);
1979 gens_inv.read_from_file_binary(fp, 0 /*verbose_level - 1*/);
1980 if (f_v) {
1981 cout << "schreier::read_from_file_binary done" << endl;
1982 }
1983}
1984
1985
1986void schreier::write_file_binary(std::string &fname, int verbose_level)
1987{
1988 int f_v = (verbose_level >= 1);
1990
1991 if (f_v) {
1992 cout << "schreier::write_file_binary" << endl;
1993 }
1994 {
1995 ofstream fp(fname, ios::binary);
1996
1997 write_to_file_binary(fp, verbose_level - 1);
1998 }
1999 cout << "schreier::write_file_binary Written file "
2000 << fname << " of size " << Fio.file_size(fname) << endl;
2001 if (f_v) {
2002 cout << "schreier::write_file_binary done" << endl;
2003 }
2004}
2005
2006void schreier::read_file_binary(std::string &fname, int verbose_level)
2007{
2008 int f_v = (verbose_level >= 1);
2010
2011 if (f_v) {
2012 cout << "schreier::read_file_binary reading file "
2013 << fname << " of size " << Fio.file_size(fname) << endl;
2014 }
2015 cout << "schreier::read_file_binary Reading file "
2016 << fname << " of size " << Fio.file_size(fname) << endl;
2017 {
2018 ifstream fp(fname, ios::binary);
2019
2020 read_from_file_binary(fp, verbose_level - 1);
2021 }
2022 if (f_v) {
2023 cout << "schreier::read_file_binary done" << endl;
2024 }
2025}
2026
2028{
2029 if (f_images_only) {
2030 cout << "schreier::list_elements_as_permutations_vertically is not "
2031 "allowed if f_images_only is TRUE" << endl;
2032 exit(1);
2033 }
2035}
2036
2037
2038}}}
2039
void distribution_print(std::ostream &ost, int *val, int *mult, int len)
Definition: int_vec.cpp:1021
void create_string_with_quotes(std::string &str, int *v, int len)
Definition: int_vec.cpp:1088
void distribution(int *v, int len_v, int *&val, int *&mult, int &len)
Definition: int_vec.cpp:387
a collection of functions related to sorted vectors
void int_vec_sorting_permutation(int *v, int len, int *perm, int *perm_inv, int f_increasingly)
Definition: sorting.cpp:830
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
void set_entry_lint(int row_idx, int col_idx, long int val)
void save(std::string &fname, int verbose_level)
void fill_entry_with_text(int row_idx, int col_idx, const char *text)
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 data structure to store layered graphs or Hasse diagrams
Definition: graph_theory.h:654
void add_text(int l, int n, const char *text, int verbose_level)
void write_file(std::string &fname, int verbose_level)
void add_node_data1(int l, int n, int data, int verbose_level)
void init(int nb_layers, int *Nb_nodes_layer, std::string &fname_base, int verbose_level)
void add_edge(int l1, int n1, int l2, int n2, int verbose_level)
options for drawing an object of type layered_graph
Definition: graphics.h:457
a general 2D graphical output interface (metapost, tikz, postscript)
Definition: graphics.h:545
void aligned_text(int x, int y, const char *alignment, const char *p)
void polygon2(int *Px, int *Py, int i1, int i2)
void init(std::string &file_name, layered_graph_draw_options *Draw_options, int verbose_level)
Definition: mp_graphics.cpp:71
void circle_text(int x, int y, int rad, const char *text)
void lint_vec_array_write_csv(int nb_vecs, long int **Vec, int len, std::string &fname, const char **column_label)
Definition: file_io.cpp:1270
void lint_vec_print_as_matrix(std::ostream &ost, long int *v, int len, int width, int f_tex)
void lint_set_print_tex(std::ostream &ost, long int *v, int len)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
a permutation group in a fixed action.
Definition: actions.h:99
void element_print_latex(void *elt, std::ostream &ost)
Definition: action_cb.cpp:364
void element_print_quick(void *elt, std::ostream &ost)
Definition: action_cb.cpp:353
void original_point_labels(long int *points, int nb_points, long int *&original_points, int verbose_level)
void element_print_as_permutation(void *elt, std::ostream &ost)
Definition: action_cb.cpp:421
long int element_image_of(long int a, void *elt, int verbose_level)
Definition: action_cb.cpp:198
void list_elements_as_permutations_vertically(data_structures_groups::vector_ge *gens, std::ostream &ost)
Definition: action_io.cpp:649
void write_to_file_binary(std::ofstream &fp, int verbose_level)
Definition: vector_ge.cpp:688
void init(actions::action *A, int verbose_level)
Definition: vector_ge.cpp:55
void print_generators_tex(ring_theory::longinteger_object &go, std::ostream &ost)
Definition: vector_ge.cpp:379
void read_from_file_binary(std::ifstream &fp, int verbose_level)
Definition: vector_ge.cpp:705
void draw_forest(std::string &fname_mask, graphics::layered_graph_draw_options *Opt, int f_has_point_labels, long int *point_labels, int verbose_level)
void print_and_list_orbits_and_stabilizer_sorted_by_length(std::ostream &ost, int f_tex, actions::action *default_action, ring_theory::longinteger_object &full_group_order)
void print_and_list_orbits_and_stabilizer(std::ostream &ost, actions::action *default_action, ring_theory::longinteger_object &go, void(*print_point)(std::ostream &ost, int pt, void *data), void *data)
void print_and_list_all_orbits_and_stabilizers_with_list_of_elements_tex(std::ostream &ost, actions::action *default_action, strong_generators *gens, int verbose_level)
void print_and_list_orbit_tex(int i, std::ostream &ost)
void write_orbit_summary(std::string &fname, actions::action *default_action, ring_theory::longinteger_object &full_group_order, int verbose_level)
int subtree_calc_weight(int *weight, int &max_depth, int i, int last)
void list_elements_as_permutations_vertically(std::ostream &ost)
void write_to_file_binary(std::ofstream &fp, int verbose_level)
void print_and_list_orbits_sorted_by_length(std::ostream &ost)
void read_from_file_binary(std::ifstream &fp, int verbose_level)
data_structures_groups::vector_ge gens_inv
Definition: groups.h:846
void print_path(std::ostream &ost, int *path, int l)
void print_orbit_tex(std::ostream &ost, int orbit_no)
void write_to_file_csv(std::string &fname_csv, int verbose_level)
void export_tree_as_layered_graph(int orbit_no, std::string &fname_mask, int verbose_level)
void write_file_binary(std::string &fname, int verbose_level)
void draw_tree(std::string &fname, graphics::layered_graph_draw_options *Opt, int orbit_no, int f_has_point_labels, long int *point_labels, int verbose_level)
strong_generators * stabilizer_orbit_rep(actions::action *default_action, ring_theory::longinteger_object &full_group_order, int orbit_idx, int verbose_level)
Definition: schreier.cpp:2345
void print_orbit_sorted(std::ostream &ost, int orbit_no)
void print_and_list_orbits_of_given_length(std::ostream &ost, int len)
void print_and_list_orbits_with_original_labels_tex(std::ostream &ost)
void print_and_list_orbit_and_stabilizer_with_list_of_elements_tex(int i, actions::action *default_action, strong_generators *gens, std::ostream &ost)
void print_orbit_length_distribution(std::ostream &ost)
void make_orbit_trees(std::ostream &ost, std::string &fname_mask, graphics::layered_graph_draw_options *Opt, int verbose_level)
void print_and_list_orbit_and_stabilizer_tex(int i, actions::action *default_action, ring_theory::longinteger_object &full_group_order, std::ostream &ost)
void print_fancy(std::ostream &ost, int f_tex, actions::action *default_action, strong_generators *gens_full_group)
int subtree_depth_first(std::ostream &ost, int *path, int i, int last)
void print_and_list_orbits_sorted_by_length_tex(std::ostream &ost)
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 subtree_place(int *weight, int *placement_x, int left, int right, int i, int last)
void print_orbit_using_callback(std::ostream &ost, int orbit_no, void(*print_point)(std::ostream &ost, int pt, void *data), void *data)
data_structures_groups::vector_ge gens
Definition: groups.h:845
void subtree_draw_vertices(graphics::mp_graphics &G, graphics::layered_graph_draw_options *Opt, int parent_x, int parent_y, int *weight, int *placement_x, int max_depth, int i, int last, int f_has_point_labels, long int *point_labels, int y_max, int verbose_level)
void print_orbit_through_labels(std::ostream &ost, int orbit_no, long int *point_labels)
void print_orbit_sorted_with_original_labels_tex(std::ostream &ost, int orbit_no, int f_truncate, int max_length)
void print_orbit_using_labels(int orbit_no, long int *labels)
void print_and_list_orbits_with_original_labels(std::ostream &ost)
void print_and_list_orbits_using_labels(std::ostream &ost, long int *labels)
void draw_tree2(std::string &fname, graphics::layered_graph_draw_options *Opt, int *weight, int *placement_x, int max_depth, int i, int last, int f_has_point_labels, long int *point_labels, int verbose_level)
void subtree_draw_lines(graphics::mp_graphics &G, graphics::layered_graph_draw_options *Opt, int parent_x, int parent_y, int *weight, int *placement_x, int max_depth, int i, int last, int y_max, int verbose_level)
void read_file_binary(std::string &fname, int verbose_level)
void print_orbit_with_original_labels(std::ostream &ost, int orbit_no)
void print_tables_latex(std::ostream &ost, int f_with_cosetrep)
void trace_back(int *path, int i, int &j)
Definition: schreier.cpp:1896
void print_orbit_sorted_tex(std::ostream &ost, int orbit_no, int f_truncate, int max_length)
void coset_rep(int j, int verbose_level)
Definition: schreier.cpp:787
void print_tables(std::ostream &ost, int f_with_cosetrep)
a permutation group represented via a stabilizer chain
Definition: groups.h:1273
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
void init_from_sims(groups::sims *S, int verbose_level)
void group_order(ring_theory::longinteger_object &go)
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define Int_vec_print_fully(A, B, C)
Definition: foundations.h:687
#define NEW_pint(n)
Definition: foundations.h:627
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define MAX(x, y)
Definition: foundations.h:219
#define Int_vec_copy(A, B, C)
Definition: foundations.h:693
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define Lint_vec_print_fully(A, B, C)
Definition: foundations.h:688
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects