Orbiter 2022
Combinatorial Objects
semifield_substructure.cpp
Go to the documentation of this file.
1/*
2 * semifield_substructure.cpp
3 *
4 * Created on: May 15, 2019
5 * Author: betten
6 */
7
8
9
10
11
12
13#include "orbiter.h"
14
15using namespace std;
16
17namespace orbiter {
18namespace layer5_applications {
19namespace semifields {
20
21
22
24{
25 SCWS = NULL;
26 SC = NULL;
27 L3 = NULL;
28 Gr3 = NULL;
29 Gr2 = NULL;
32
33 Need_orbits_fst = NULL;
34 Need_orbits_len = NULL;
35
36 TR = NULL;
37 N = 0;
38 N2 = 0;
39 f = 0;
40 Data = NULL;
41 nb_solutions = 0;
42 data_size = 0;
43 start_column = 0;
44 FstLen = NULL;
45 Len = NULL;
47 nb_orb_total = 0;
48 All_Orbits = NULL;
49 Nb_orb = NULL;
50 Orbit_idx = NULL;
51 Position = NULL;
52 Fo_first = NULL;
54 Flag_orbits = NULL;
55 data1 = NULL;
56 data2 = NULL;
57 Basis1 = NULL;
58 Basis2 = NULL;
59 //Basis3 = NULL;
60 B = NULL;
61 v1 = NULL;
62 v2 = NULL;
63 v3 = NULL;
64 transporter1 = NULL;
65 transporter2 = NULL;
66 transporter3 = NULL;
67 Elt1 = NULL;
68 coset_reps = NULL;
69
70}
71
73{
74
75}
76
78// allocates the arrays and matrices
79{
80 Basis1 = NEW_int(SC->k * SC->k2);
81 Basis2 = NEW_int(SC->k * SC->k2);
82 //Basis3 = NEW_int(SC->k * SC->k2);
83 B = NEW_int(SC->k2);
89
90
91 Gr3->init(SC->k, 3, SC->Mtx->GFq, 0 /* verbose_level */);
92 N = Gr3->nb_of_subspaces(0 /* verbose_level */);
93 Gr2->init(SC->k, 2, SC->Mtx->GFq, 0 /* verbose_level */);
94 N2 = Gr2->nb_of_subspaces(0 /* verbose_level */);
95 data1 = NEW_lint(SC->k);
96 data2 = NEW_lint(SC->k);
97 v1 = NEW_int(SC->k);
98 v2 = NEW_int(SC->k);
99 v3 = NEW_int(SC->k);
101}
102
104 int nb_non_unique_cases,
105 int *Non_unique_cases, long int *Non_unique_cases_go,
106 int verbose_level)
107{
108 int f_v = (verbose_level >= 1);
109 int i, a, sum;
110
111 if (f_v) {
112 cout << "computing non-unique cases with non-trivial group:" << endl;
113 }
114
117 for (i = 0; i < nb_non_unique_cases; i++) {
118 a = Non_unique_cases[i];
119 if (Non_unique_cases_go[i] > 1) {
122 }
123 }
124 if (f_v) {
125 cout << "There are " << nb_non_unique_cases_with_non_trivial_group
126 << " cases with more than one solution and with a "
127 "non-trivial group" << endl;
128 cout << "They are:" << endl;
131 }
132
133
136 for (i = 0; i < nb_non_unique_cases_with_non_trivial_group; i++) {
138 Need_orbits_fst[i] = FstLen[2 * a + 0];
139 Need_orbits_len[i] = FstLen[2 * a + 1];
140 }
141
142
143 sum = 0;
144 for (i = 0; i < nb_non_unique_cases_with_non_trivial_group; i++) {
145 sum += Need_orbits_len[i];
146 }
147 {
149
152 0);
153 if (f_v) {
154 cout << "classification of Len amongst the need orbits cases:" << endl;
155 C.print_naked(TRUE);
156 cout << endl;
157 }
158 }
159 if (f_v) {
160 cout << "For a total of " << sum << " semifields" << endl;
161 }
162}
163
164
166 int verbose_level)
167{
168 int f_v = (verbose_level >= 1);
169 int f_vv = (verbose_level >= 2);
170 int f_vvv = (verbose_level >= 3);
171 int a, o, fst, len;
172
173 if (f_v) {
174 cout << "semifield_substructure::compute_orbits" << endl;
175 }
176 if (f_v) {
177 cout << "computing all orbits:" << endl;
178 }
179
180
181
182 All_Orbits =
187
188 nb_orb_total = 0;
189 for (o = 0; o < nb_non_unique_cases_with_non_trivial_group; o++) {
190
191
192
194
195 fst = Need_orbits_fst[o];
196 len = Need_orbits_len[o];
197
198 All_Orbits[o] = new orbit_of_subspaces *[len];
199
200 if (f_v) {
201 cout << "case " << o << " / "
203 << " with " << len
204 << " semifields" << endl;
205 }
206
207 int *f_reached;
208 int *position;
209 int *orbit_idx;
210
211 f_reached = NEW_int(len);
212 position = NEW_int(len);
213 orbit_idx = NEW_int(len);
214
215 Int_vec_zero(f_reached, len);
217
218 int cnt, f;
219
220 cnt = 0;
221
222 for (f = 0; f < len; f++) {
223 if (f_reached[f]) {
224 continue;
225 }
227 long int *input_data;
228
229
230 input_data = Data + (fst + f) * data_size + start_column;
231
232 if (f_vvv) {
233 cout << "case " << o << " / "
235 << " is original case " << a << " at "
236 << fst << " with " << len
237 << " semifields. Computing orbit of "
238 "semifield " << f << " / " << len << endl;
239 cout << "Orbit rep "
240 << f << ":" << endl;
241 Lint_vec_print(cout, input_data, SC->k);
242 cout << endl;
243 }
244 if (FALSE) {
245 cout << "The stabilizer is:" << endl;
247 }
248
249 SC->compute_orbit_of_subspaces(input_data,
250 &L3->Stabilizer_gens[a],
251 Orb,
252 verbose_level - 4);
253 if (f_vv) {
254 cout << "case " << o << " / "
256 << " is original case " << a << " at "
257 << fst << " with " << len
258 << " semifields. Orbit of semifield " << f << " / "
259 << len << " has length "
260 << Orb->used_length << endl;
261 }
262
263 int idx, g, c;
264
265 c = 0;
266 for (g = 0; g < len; g++) {
267 if (f_reached[g]) {
268 continue;
269 }
270 if (FALSE) {
271 cout << "testing subspace " << g << " / " << len << ":" << endl;
272 }
273 if (Orb->find_subspace_lint(
274 Data + (fst + g) * data_size + start_column,
275 idx, 0 /*verbose_level*/)) {
276 f_reached[g] = TRUE;
277 position[g] = idx;
278 orbit_idx[g] = cnt;
279 c++;
280 }
281 }
282 if (c != Orb->used_length) {
283 cout << "c != Orb->used_length" << endl;
284 cout << "Orb->used_length=" << Orb->used_length << endl;
285 cout << "c=" << c << endl;
286 exit(1);
287 }
288 All_Orbits[o][cnt] = Orb;
289
290 cnt++;
291
292 }
293
294 if (f_vv) {
295 cout << "case " << o << " / "
297 << " with " << len << " semifields done, there are "
298 << cnt << " orbits in this case." << endl;
299 }
300
301 Nb_orb[o] = cnt;
302 nb_orb_total += cnt;
303
304 Position[o] = position;
305 Orbit_idx[o] = orbit_idx;
306
307 FREE_int(f_reached);
308
309
310
311 }
312
313 if (f_v) {
314 cout << "Number of orbits:" << endl;
315 for (o = 0; o < nb_non_unique_cases_with_non_trivial_group; o++) {
316 cout << o << " : " << Nb_orb[o] << endl;
317 }
318 cout << "Total number of orbits = " << nb_orb_total << endl;
319 }
320 if (f_v) {
321 cout << "semifield_substructure::compute_orbits done" << endl;
322 }
323}
324
325
327// initializes Fo_first and Flag_orbits
328{
329 int f_v = (verbose_level >= 1);
330 int f_vv = (verbose_level >= 2);
331 //int f_vvv = (verbose_level >= 3);
332 int o, idx, h, fst, g;
334
335 if (f_v) {
336 cout << "semifield_substructure::compute_flag_orbits" << endl;
337 }
338 if (f_v) {
339 cout << "Counting number of flag orbits:" << endl;
340 }
341 nb_flag_orbits = 0;
342 for (o = 0; o < nb_orbits_at_level_3; o++) {
343
344 if (FALSE) {
345 cout << "orbit " << o << " number of semifields = "
346 << Len[o] << " group order = "
347 << L3->Stabilizer_gens[o].group_order_as_lint() << endl;
348 }
349 if (Len[o] == 0) {
350 }
351 else if (Len[o] == 1) {
352 nb_flag_orbits += 1;
353 }
354 else if (L3->Stabilizer_gens[o].group_order_as_lint() == 1) {
355 nb_flag_orbits += Len[o];
356 }
357 else {
358 if (!Sorting.int_vec_search(
361 cout << "cannot find orbit " << o
362 << " in the list " << endl;
363 exit(1);
364 }
365 if (f_vv) {
366 cout << "Found orbit " << o
367 << " at position " << idx << endl;
368 }
369 nb_flag_orbits += Nb_orb[idx];
370 }
371
372 } // next o
373 if (f_v) {
374 cout << "nb_flag_orbits = " << nb_flag_orbits << endl;
375 }
376
377
378 if (f_v) {
379 cout << "Computing Flag_orbits:" << endl;
380 }
381
382
384
387 SC->A, SC->AS,
388 nb_orbits_at_level_3 /* nb_primary_orbits_lower */,
389 SC->k /* pt_representation_sz */,
390 nb_flag_orbits /* nb_flag_orbits */,
391 1 /* upper_bound_for_number_of_traces */, // ToDo
392 NULL /* void (*func_to_free_received_trace)(void *trace_result, void *data, int verbose_level) */,
393 NULL /* void (*func_latex_report_trace)(std::ostream &ost, void *trace_result, void *data, int verbose_level)*/,
394 NULL /* void *free_received_trace_data */,
395 verbose_level);
396
397
398 h = 0;
399 for (o = 0; o < nb_orbits_at_level_3; o++) {
400
401 long int *data;
402
403 Fo_first[o] = h;
404 fst = FstLen[2 * o + 0];
405
406 if (Len[o] == 0) {
407 // nothing to do here
408 }
409 else if (Len[o] == 1) {
410 data = Data +
411 (fst + 0) * data_size + start_column;
414 h /* flag_orbit_index */,
415 o /* downstep_primary_orbit */,
416 0 /* downstep_secondary_orbit */,
417 1 /* downstep_orbit_len */,
418 FALSE /* f_long_orbit */,
419 data /* int *pt_representation */,
420 &L3->Stabilizer_gens[o],
421 0 /*verbose_level - 2 */);
422 h++;
423 }
424 else if (L3->Stabilizer_gens[o].group_order_as_lint() == 1) {
425 for (g = 0; g < Len[o]; g++) {
426 data = Data +
427 (fst + g) * data_size + start_column;
430 h /* flag_orbit_index */,
431 o /* downstep_primary_orbit */,
432 g /* downstep_secondary_orbit */,
433 1 /* downstep_orbit_len */,
434 FALSE /* f_long_orbit */,
435 data /* int *pt_representation */,
436 &L3->Stabilizer_gens[o],
437 0 /*verbose_level - 2*/);
438 h++;
439 }
440 }
441 else {
442 if (!Sorting.int_vec_search(
445 cout << "cannot find orbit " << o << " in the list " << endl;
446 exit(1);
447 }
448 if (FALSE) {
449 cout << "Found orbit " << o
450 << " at position " << idx << endl;
451 }
452 for (g = 0; g < Nb_orb[idx]; g++) {
456
457 Orb = All_Orbits[idx][g];
460 gens = Orb->stabilizer_orbit_rep(
461 go /* full_group_order */, 0 /*verbose_level - 1*/);
464 h /* flag_orbit_index */,
465 o /* downstep_primary_orbit */,
466 g /* downstep_secondary_orbit */,
467 Orb->used_length /* downstep_orbit_len */,
468 FALSE /* f_long_orbit */,
469 data /* int *pt_representation */,
470 gens,
471 0 /*verbose_level - 2*/);
472 h++;
473 }
474 }
475
476
477 }
478 if (h != nb_flag_orbits) {
479 cout << "h != nb_flag_orbits" << endl;
480 exit(1);
481 }
482 if (f_v) {
483 cout << "Finished initializing flag orbits. "
484 "Number of flag orbits = " << nb_flag_orbits << endl;
485 }
486 if (f_v) {
487 cout << "semifield_substructure::compute_flag_orbits done" << endl;
488 }
489}
490
491
493{
494 int f_v = (verbose_level >= 1);
496
497 if (f_v) {
498 cout << "semifield_substructure::do_classify" << endl;
499 }
500 if (f_v) {
501 cout << "Computing classification:" << endl;
502 }
503
504 //int depth0 = 3;
505
506
507
508
509
510 int po, so;
512 int f_skip = FALSE;
513 int i;
514
515
516
517 int *f_processed; // [nb_flag_orbits]
518 int nb_processed;
519
520
521 f_processed = NEW_int(nb_flag_orbits);
522 Int_vec_zero(f_processed, nb_flag_orbits);
523 nb_processed = 0;
524
525
526
527
528 SC->A->group_order(go);
529
530 SCWS->Semifields->init(SC->A, SC->AS,
531 nb_flag_orbits, SC->k, go, verbose_level);
532
533
535
536 for (f = 0; f < nb_flag_orbits; f++) {
537
538
539 double progress;
540
541 if (f_processed[f]) {
542 continue;
543 }
544
545 progress = ((double) nb_processed * 100. ) /
546 (double) nb_flag_orbits;
547
548 if (f_v) {
549 Os.time_check(cout, SCWS->t0);
550 cout << " : Defining new orbit "
552 << " from flag orbit " << f << " / "
553 << nb_flag_orbits << " progress="
554 << progress << "% "
555 "nb semifields = " << Flag_orbits->nb_primary_orbits_upper << endl;
556
557 }
560
561
562
565 if (f_v) {
566 cout << "po=" << po << " so=" << so << endl;
567 }
570 data1, SC->k);
571 if (f_v) {
572 cout << "data1=";
573 Lint_vec_print(cout, data1, SC->k);
574 cout << endl;
575 }
576
579
582 coset_reps->init(SC->A, verbose_level - 2);
583
584
585 for (i = 0; i < SC->k; i++) {
586 SC->matrix_unrank(data1[i], Basis1 + i * SC->k2);
587 }
588 if (f_v) {
589 cout << "Basis1=" << endl;
592 }
593 f_skip = FALSE;
594 for (i = 0; i < SC->k; i++) {
595 v3[i] = Basis1[2 * SC->k2 + i * SC->k + 0];
596 }
597 if (!SC->Mtx->GFq->Linear_algebra->is_unit_vector(v3, SC->k, SC->k - 1)) {
598 cout << "flag orbit " << f << " / "
600 << " 1st col of third matrix is = ";
601 Int_vec_print(cout, v3, SC->k);
602 cout << " which is not the (k-1)-th unit vector, "
603 "so we skip" << endl;
604 f_skip = TRUE;
605 }
606
607 if (f_skip) {
608 if (f_v) {
609 cout << "flag orbit " << f << " / "
611 << ", first vector is not the unit vector, "
612 "so we skip" << endl;
613 }
614 f_processed[f] = TRUE;
615 nb_processed++;
616 continue;
617 }
618 if (f_v) {
619 cout << "flag orbit " << f << " / " << nb_flag_orbits
620 << ", looping over the " << N << " subspaces" << endl;
621 }
622
624
625
626 if (f_v) {
627 Os.time_check(cout, SCWS->t0);
628 cout << " : flag orbit " << f << " / " << nb_flag_orbits
629 << ", looping over the " << N << " subspaces, "
630 "before loop_over_all_subspaces" << endl;
631 }
632
633
634 loop_over_all_subspaces(f_processed, nb_processed,
635 verbose_level - 3);
636
637
638 if (f_v) {
639 cout << "flag orbit " << f << " / " << nb_flag_orbits
640 << ", looping over the " << N << " subspaces, "
641 "after loop_over_all_subspaces" << endl;
642 }
643
644
646 TR,
649 f, po, so, N);
650
651
653
654 int cl;
655 ring_theory::longinteger_object go1, Cl, ago, ago1;
657
658 Aut_gens->group_order(go);
659 cl = coset_reps->len;
660 Cl.create(cl, __FILE__, __LINE__);
661 D.mult(go, Cl, ago);
662 if (f_v) {
663 cout << "Semifield "
665 << ", Ago = starter * number of cosets = " << ago
666 << " = " << go << " * " << Cl
667 << " created from flag orbit " << f << " / "
668 << nb_flag_orbits << " progress="
669 << progress << "%" << endl;
670 }
671
673
675 if (f_v) {
676 cout << "flag orbit " << f << " / " << nb_flag_orbits
677 << ", semifield isotopy class "
679 "computing stabilizer" << endl;
680 }
681 Stab->init_group_extension(Aut_gens,
682 coset_reps, cl /* index */,
683 verbose_level);
684 Stab->group_order(ago1);
685 if (f_v) {
686 cout << "flag orbit " << f << " / " << nb_flag_orbits
687 << ", semifield isotopy class "
689 " computing stabilizer done, order = " << ago1 << endl;
690 }
691
692
696 Stab, data1, NULL /* extra_data */, verbose_level);
697
698 FREE_OBJECT(Aut_gens);
699
700 f_processed[f] = TRUE;
701 nb_processed++;
703
704
705
706 } // next f
707
708 FREE_int(f_processed);
709
710
712
713
714 if (f_v) {
715 cout << "Computing classification done, we found "
717 << " semifields" << endl;
718 Os.time_check(cout, SCWS->t0);
719 cout << endl;
720 }
721 if (f_v) {
722 cout << "semifield_substructure::do_classify done" << endl;
723 }
724}
725
727 int *f_processed, int &nb_processed, int verbose_level)
728{
729 int f_v = (verbose_level >= 1);
730 int f_vv = (verbose_level >= 2);
731 int f_vvv = (verbose_level >= 3);
733 int rk, i, f2;
734 int k, k2;
735 int f_skip;
736 int trace_po;
737 int ret;
739
740
741#if 0
742 if (f == 1) {
743 verbose_level += 10;
744 f_v = f_vv = f_vvv = TRUE;
745 cout << "CASE 1, STARTS HERE" << endl;
746 }
747#endif
748
749 if (f_v) {
750 cout << "loop_over_all_subspaces" << endl;
751 }
752
753
754 k = SC->k;
755 k2 = SC->k2;
756 F = SC->Mtx->GFq;
757
758 for (rk = 0; rk < N; rk++) {
759
760 trace_record *T;
761
762 T = TR + rk;
763
764 T->coset = rk;
765
766
767 if (f_vv) {
768 cout << "flag orbit " << f << " / "
769 << nb_flag_orbits << ", subspace "
770 << rk << " / " << N << ":" << endl;
771 }
772
773 for (i = 0; i < k; i++) {
774 SC->matrix_unrank(data1[i], Basis1 + i * k2);
775 }
776 if (f_vvv) {
777 SC->basis_print(Basis1, k);
778 }
779
780
781 // unrank the subspace:
783 0 /* verbose_level */);
784
785 // multiply the matrices to get the matrices
786 // adapted to the subspace:
787 // the first three matrices are the generators
788 // for the subspace.
790 0 /* verbose_level */);
791
792
793 if (f_vvv) {
794 cout << "base change matrix B=" << endl;
796
797 cout << "Basis2 = B * Basis1 (before trace)=" << endl;
799 SC->basis_print(Basis2, k);
800 }
801
802
803 if (f_vv) {
804 cout << "before trace_to_level_three" << endl;
805 }
807 Basis2,
808 k /* basis_sz */,
810 trace_po,
811 verbose_level - 3);
812
813 f_skip = FALSE;
814
815 if (ret == FALSE) {
816 cout << "flag orbit " << f << " / "
817 << nb_flag_orbits << ", subspace "
818 << rk << " / " << N
819 << " : trace_to_level_three return FALSE" << endl;
820
821 f_skip = TRUE;
822 }
823
824 T->trace_po = trace_po;
825
826 if (f_vvv) {
827 cout << "After trace, trace_po = "
828 << trace_po << endl;
829 cout << "Basis2 (after trace)=" << endl;
831 SC->basis_print(Basis2, k);
832 }
833
834
835 for (i = 0; i < k; i++) {
836 v1[i] = Basis2[0 * k2 + i * k + 0];
837 }
838 for (i = 0; i < k; i++) {
839 v2[i] = Basis2[1 * k2 + i * k + 0];
840 }
841 for (i = 0; i < k; i++) {
842 v3[i] = Basis2[2 * k2 + i * k + 0];
843 }
844 if (f_skip == FALSE) {
845 if (!F->Linear_algebra->is_unit_vector(v1, k, 0) ||
846 !F->Linear_algebra->is_unit_vector(v2, k, 1) ||
847 !F->Linear_algebra->is_unit_vector(v3, k, k - 1)) {
848 f_skip = TRUE;
849 }
850 }
851 T->f_skip = f_skip;
852
853 if (f_skip) {
854 if (f_vv) {
855 cout << "skipping this case " << trace_po
856 << " because pivot is not "
857 "in the last row." << endl;
858 }
859 }
860 else {
861
863 Basis2 + 3 * k2,
864 FALSE /* f_special */,
865 TRUE /* f_complete */,
866 SC->desired_pivots + 3,
867 k - 3 /* nb_pivots */,
868 k - 3, k2,
869 0 /*verbose_level - 2*/);
870 if (f_vvv) {
871 cout << "Basis2 after RREF(2)=" << endl;
873 SC->basis_print(Basis2, k);
874 }
875
876 for (i = 0; i < k; i++) {
877 data2[i] = SC->matrix_rank(Basis2 + i * k2);
878 }
879 if (f_vvv) {
880 cout << "data2=";
881 Lint_vec_print(cout, data2, k);
882 cout << endl;
883 }
884
885 int solution_idx;
886
887 if (f_vvv) {
888 cout << "before find_semifield_in_table" << endl;
889 }
891 trace_po,
892 data2 /* given_data */,
893 solution_idx,
894 verbose_level)) {
895
896 cout << "flag orbit " << f << " / "
897 << nb_flag_orbits << ", subspace "
898 << rk << " / " << N << ":" << endl;
899
900 cout << "find_semifield_in_table returns FALSE" << endl;
901
902 cout << "trace_po=" << trace_po << endl;
903 cout << "data2=";
904 Lint_vec_print(cout, data2, k);
905 cout << endl;
906
907 cout << "Basis2 after RREF(2)=" << endl;
909 SC->basis_print(Basis2, k);
910
911 exit(1);
912 }
913
914
915 T->solution_idx = solution_idx;
916 T->nb_sol = Len[trace_po];
917
918 if (f_vvv) {
919 cout << "solution_idx=" << solution_idx << endl;
920 }
921
922 long int go;
923 go = L3->Stabilizer_gens[trace_po].group_order_as_lint();
924
925 T->go = go;
926 T->pos = -1;
927 T->so = -1;
928 T->orbit_len = -1;
929 T->f2 = -1;
930
931 if (f_vv) {
932 cout << "flag orbit " << f << " / "
933 << nb_flag_orbits << ", subspace "
934 << rk << " / " << N << " trace_po="
935 << trace_po << " go=" << go
936 << " solution_idx=" << solution_idx << endl;
937 }
938
939
940 if (go == 1) {
941 if (f_vv) {
942 cout << "This starter case has a trivial "
943 "group order" << endl;
944 }
945
946 f2 = Fo_first[trace_po] + solution_idx;
947
948 T->so = solution_idx;
949 T->orbit_len = 1;
950 T->f2 = f2;
951
952 if (f2 == f) {
953 if (f_vv) {
954 cout << "We found an automorphism" << endl;
955 }
956 coset_reps->append(transporter1, verbose_level - 2);
957 }
958 else {
959 if (!f_processed[f2]) {
960 if (f_vv) {
961 cout << "We are identifying with "
962 "flag orbit " << f2 << ", which is "
963 "po=" << trace_po << " so="
964 << solution_idx << endl;
965 }
969 = TRUE;
971 = f;
977 0);
978 f_processed[f2] = TRUE;
979 nb_processed++;
980 if (f_vv) {
981 cout << "Flag orbit f2 = " << f2
982 << " has been fused with flag orbit "
983 << f << endl;
984 }
985 }
986 else {
987 if (f_vv) {
988 cout << "Flag orbit f2 = " << f2
989 << " has already been processed, "
990 "nothing to do here" << endl;
991 }
992 }
993 }
994 }
995 else {
996 if (Len[trace_po] == 1) {
997 if (f_vv) {
998 cout << "This starter case has only "
999 "one solution" << endl;
1000 }
1001 f2 = Fo_first[trace_po] + 0;
1002
1003 T->pos = -1;
1004 T->so = 0;
1005 T->orbit_len = 1;
1006 T->f2 = f2;
1007
1008
1009 if (f2 == f) {
1010 if (f_vv) {
1011 cout << "We found an automorphism" << endl;
1012 }
1013 coset_reps->append(transporter1, verbose_level - 2);
1014 }
1015 else {
1016 if (!f_processed[f2]) {
1017 if (f_vv) {
1018 cout << "We are identifying with po="
1019 << trace_po << " so=" << 0
1020 << ", which is flag orbit "
1021 << f2 << endl;
1022 }
1026 = TRUE;
1028 = f;
1033 0);
1034 f_processed[f2] = TRUE;
1035 nb_processed++;
1036 if (f_vv) {
1037 cout << "Flag orbit f2 = " << f2
1038 << " has been fused with "
1039 "flag orbit " << f << endl;
1040 }
1041 }
1042 else {
1043 if (f_vv) {
1044 cout << "Flag orbit f2 = " << f2
1045 << " has already been processed, "
1046 "nothing to do here" << endl;
1047 }
1048 }
1049 }
1050 }
1051 else {
1052 // now we have a starter_case with more
1053 // than one solution and
1054 // with a non-trivial group.
1055 // Those cases are collected in
1056 // Non_unique_cases_with_non_trivial_group
1057 // [nb_non_unique_cases_with_non_trivial_group];
1058
1059 int non_unique_case_idx, orbit_idx, position;
1060 orbit_of_subspaces *Orb;
1061
1062 if (!Sorting.int_vec_search(
1065 trace_po, non_unique_case_idx)) {
1066 cout << "cannot find in Non_unique_cases_with_"
1067 "non_trivial_group array" << endl;
1068 exit(1);
1069 }
1070 orbit_idx = Orbit_idx[non_unique_case_idx][solution_idx];
1071 position = Position[non_unique_case_idx][solution_idx];
1072 Orb = All_Orbits[non_unique_case_idx][orbit_idx];
1073 f2 = Fo_first[trace_po] + orbit_idx;
1074
1075
1076
1077 T->pos = position;
1078 T->so = orbit_idx;
1079 T->orbit_len = Orb->used_length;
1080 T->f2 = f2;
1081
1082
1083
1084 if (f_vv) {
1085 cout << "orbit_idx = " << orbit_idx
1086 << " position = " << position
1087 << " f2 = " << f2 << endl;
1088 }
1089 Orb->get_transporter(position, transporter2,
1090 0 /*verbose_level */);
1093 transporter3, 0);
1094
1095 if (f2 == f) {
1096 if (f_vv) {
1097 cout << "We found an automorphism" << endl;
1098 }
1099 coset_reps->append(transporter3, verbose_level - 2);
1100 }
1101 else {
1102 if (!f_processed[f2]) {
1103 if (f_vv) {
1104 cout << "We are identifying with po="
1105 << trace_po << " so=" << solution_idx
1106 << ", which is flag orbit "
1107 << f2 << endl;
1108 }
1112 = TRUE;
1114 = f;
1119 0);
1120 f_processed[f2] = TRUE;
1121 nb_processed++;
1122 if (f_vv) {
1123 cout << "Flag orbit f2 = " << f2
1124 << " has been fused with flag "
1125 "orbit " << f << endl;
1126 }
1127 }
1128 else {
1129 if (f_vv) {
1130 cout << "Flag orbit f2 = " << f2
1131 << " has already been processed, "
1132 "nothing to do here" << endl;
1133 }
1134 }
1135 }
1136
1137 }
1138 }
1139 } // if !f_skip
1140 } // next rk
1141 if (f_v) {
1142 cout << "loop_over_all_subspaces done" << endl;
1143 }
1144
1145}
1146
1148 int *Trace_po, int verbose_level)
1149// input is in data1[]
1150// Trace_po[N2]
1151{
1152 int f_v = (verbose_level >= 1);
1153 int f_vv = (verbose_level >= 2);
1154 int f_vvv = (verbose_level >= 3);
1156 int rk, i;
1157 int k, k2;
1158 int trace_po;
1160
1161
1162
1163 if (f_v) {
1164 cout << "semifield_substructure::all_two_dimensional_subspaces" << endl;
1165 }
1166
1167
1168 k = SC->k;
1169 k2 = SC->k2;
1170 F = SC->Mtx->GFq;
1171
1172 for (rk = 0; rk < N2; rk++) {
1173
1174
1175 if (f_vv) {
1176 cout << "semifield_substructure::all_two_dimensional_subspaces "
1177 "subspace "
1178 << rk << " / " << N2 << ":" << endl;
1179 }
1180
1181 for (i = 0; i < k; i++) {
1182 SC->matrix_unrank(data1[i], Basis1 + i * k2);
1183 }
1184 if (f_vvv) {
1185 SC->basis_print(Basis1, k);
1186 }
1187
1188
1189 // unrank the subspace:
1191 0 /* verbose_level */);
1192
1193 // multiply the matrices to get the matrices
1194 // adapted to the subspace:
1195 // the first three matrices are the generators
1196 // for the subspace.
1198 0 /* verbose_level */);
1199
1200
1201 if (f_vvv) {
1202 cout << "base change matrix B=" << endl;
1204
1205 cout << "Basis2 = B * Basis1 (before trace)=" << endl;
1207 SC->basis_print(Basis2, k);
1208 }
1209
1210
1211 if (f_vv) {
1212 cout << "before trace_to_level_two" << endl;
1213 }
1214
1216 Basis2,
1217 k /* basis_sz */,
1218 //Basis3,
1220 trace_po,
1221 verbose_level - 3);
1222
1223 Trace_po[rk] = trace_po;
1224
1225 if (f_vvv) {
1226 cout << "After trace, trace_po = "
1227 << trace_po << endl;
1228 //cout << "Basis3 (after trace)=" << endl;
1229 //int_matrix_print_bitwise(Basis3, k, k2);
1230 //SC->basis_print(Basis3, k);
1231 }
1232 }
1233 if (f_v) {
1234 cout << "semifield_substructure::all_two_dimensional_subspaces "
1235 "done" << endl;
1236 }
1237}
1238
1239
1241 int &rk, int &trace_po, int &fo, int &po,
1242 int *transporter,
1243 int verbose_level)
1244{
1245 int f_v = (verbose_level >= 1);
1246 int f_vv = (verbose_level >= 2);
1247 int f_vvv = (verbose_level >= 3);
1249 int i, f2;
1250 int k, k2;
1251 int f_skip;
1252 //int trace_po;
1253 int ret;
1255 int solution_idx;
1256
1257
1258
1259 if (f_v) {
1260 cout << "semifield_substructure::identify" << endl;
1261 }
1262
1263
1264 k = SC->k;
1265 k2 = SC->k2;
1266 F = SC->Mtx->GFq;
1267
1268 for (rk = 0; rk < N; rk++) {
1269
1270 for (i = 0; i < k; i++) {
1271 SC->matrix_unrank(data[i], Basis1 + i * k2);
1272 }
1273 if (f_vvv) {
1274 SC->basis_print(Basis1, k);
1275 }
1276
1277
1278 // unrank the subspace:
1280 0 /* verbose_level */);
1281
1282 // multiply the matrices to get the matrices
1283 // adapted to the subspace:
1284 // the first three matrices are the generators
1285 // for the subspace.
1287 0 /* verbose_level */);
1288
1289
1290 if (f_vvv) {
1291 cout << "semifield_substructure::identify "
1292 "base change matrix B=" << endl;
1294
1295 cout << "semifield_substructure::identify "
1296 "Basis2 = B * Basis1 (before trace)=" << endl;
1298 SC->basis_print(Basis2, k);
1299 }
1300
1301
1302 if (f_vv) {
1303 cout << "semifield_substructure::identify "
1304 "before trace_to_level_three" << endl;
1305 }
1306 ret = L3->trace_to_level_three(
1307 Basis2,
1308 k /* basis_sz */,
1310 trace_po,
1311 verbose_level - 3);
1312
1313 f_skip = FALSE;
1314
1315 if (ret == FALSE) {
1316 cout << "semifield_substructure::identify "
1317 "trace_to_level_three return FALSE" << endl;
1318
1319 f_skip = TRUE;
1320 }
1321
1322
1323 if (f_vvv) {
1324 cout << "semifield_substructure::identify "
1325 "After trace, trace_po = "
1326 << trace_po << endl;
1327 cout << "semifield_substructure::identify "
1328 "Basis2 (after trace)=" << endl;
1330 SC->basis_print(Basis2, k);
1331 }
1332
1333
1334 for (i = 0; i < k; i++) {
1335 v1[i] = Basis2[0 * k2 + i * k + 0];
1336 }
1337 for (i = 0; i < k; i++) {
1338 v2[i] = Basis2[1 * k2 + i * k + 0];
1339 }
1340 for (i = 0; i < k; i++) {
1341 v3[i] = Basis2[2 * k2 + i * k + 0];
1342 }
1343 if (f_skip == FALSE) {
1344 if (!F->Linear_algebra->is_unit_vector(v1, k, 0) ||
1345 !F->Linear_algebra->is_unit_vector(v2, k, 1) ||
1346 !F->Linear_algebra->is_unit_vector(v3, k, k - 1)) {
1347 f_skip = TRUE;
1348 }
1349 }
1350
1351 if (f_skip) {
1352 if (f_vv) {
1353 cout << "semifield_substructure::identify "
1354 "skipping this case " << trace_po
1355 << " because pivot is not "
1356 "in the last row." << endl;
1357 }
1358 }
1359 else {
1360
1362 Basis2 + 3 * k2,
1363 FALSE /* f_special */,
1364 TRUE /* f_complete */,
1365 SC->desired_pivots + 3,
1366 k - 3 /* nb_pivots */,
1367 k - 3, k2,
1368 0 /*verbose_level - 2*/);
1369 if (f_vvv) {
1370 cout << "semifield_substructure::identify "
1371 "Basis2 after RREF(2)=" << endl;
1373 SC->basis_print(Basis2, k);
1374 }
1375
1376 for (i = 0; i < k; i++) {
1377 data2[i] = SC->matrix_rank(Basis2 + i * k2);
1378 }
1379 if (f_vvv) {
1380 cout << "semifield_substructure::identify data2=";
1381 Lint_vec_print(cout, data2, k);
1382 cout << endl;
1383 }
1384
1385 if (f_vvv) {
1386 cout << "semifield_substructure::identify "
1387 "before find_semifield_in_table" << endl;
1388 }
1390 trace_po,
1391 data2 /* given_data */,
1392 solution_idx,
1393 verbose_level)) {
1394
1395 cout << "semifield_substructure::identify "
1396 "find_semifield_in_table returns FALSE" << endl;
1397
1398 cout << "semifield_substructure::identify "
1399 "trace_po=" << trace_po << endl;
1400 cout << "semifield_substructure::identify data2=";
1401 Lint_vec_print(cout, data2, k);
1402 cout << endl;
1403
1404 cout << "semifield_substructure::identify "
1405 "Basis2 after RREF(2)=" << endl;
1407 SC->basis_print(Basis2, k);
1408
1409 return FALSE;
1410 }
1411
1412 long int go;
1413 go = L3->Stabilizer_gens[trace_po].group_order_as_lint();
1414
1415 //T->solution_idx = solution_idx;
1416 //T->nb_sol = Len[trace_po];
1417 if (go == 1) {
1418 if (f_vv) {
1419 cout << "This starter case has a trivial "
1420 "group order" << endl;
1421 }
1422
1423 f2 = Fo_first[trace_po] + solution_idx;
1424
1429 transporter,
1430 0);
1431 }
1432 else {
1433 fo = f2;
1435 transporter,
1436 0);
1437 }
1438 }
1439 else if (Len[trace_po] == 1) {
1440 f2 = Fo_first[trace_po] + 0;
1445 transporter,
1446 0);
1447 }
1448 else {
1449 fo = f2;
1451 transporter,
1452 0);
1453 }
1454 }
1455 else {
1456 // now we have a starter_case with more
1457 // than one solution and
1458 // with a non-trivial group.
1459 // Those cases are collected in
1460 // Non_unique_cases_with_non_trivial_group
1461 // [nb_non_unique_cases_with_non_trivial_group];
1462
1463 int non_unique_case_idx, orbit_idx, position;
1464 orbit_of_subspaces *Orb;
1465
1466 if (!Sorting.int_vec_search(
1469 trace_po, non_unique_case_idx)) {
1470 cout << "semifield_substructure::identify "
1471 "cannot find in Non_unique_cases_with_"
1472 "non_trivial_group array" << endl;
1473 exit(1);
1474 }
1475 orbit_idx = Orbit_idx[non_unique_case_idx][solution_idx];
1476 position = Position[non_unique_case_idx][solution_idx];
1477 Orb = All_Orbits[non_unique_case_idx][orbit_idx];
1478 f2 = Fo_first[trace_po] + orbit_idx;
1479
1480 if (f_vv) {
1481 cout << "orbit_idx = " << orbit_idx
1482 << " position = " << position
1483 << " f2 = " << f2 << endl;
1484 }
1485 Orb->get_transporter(position, transporter2,
1486 0 /*verbose_level */);
1489 transporter3, 0);
1491 transporter1, 0);
1496 transporter,
1497 0);
1498 }
1499 else {
1500 fo = f2;
1502 transporter,
1503 0);
1504 }
1505
1506 } // go != 1
1507
1509
1510
1511 if (f_vvv) {
1512 cout << "semifield_substructure::identify done "
1513 "solution_idx=" << solution_idx
1514 << "trace_po=" << trace_po
1515 << "f2=" << f2
1516 << "fo=" << fo
1517 << "po=" << po
1518 << endl;
1519 }
1520 return TRUE;
1521 } // end else
1522
1523
1524 } // next rk
1525
1526 if (f_v) {
1527 cout << "semifield_substructure::identify done" << endl;
1528 }
1529 return FALSE;
1530}
1531
1533 int po,
1534 long int *given_data,
1535 int &idx,
1536 int verbose_level)
1537{
1538 int f_v = (verbose_level >= 1);
1539 int fst, len, g;
1541
1542
1543 if (f_v) {
1544 cout << "find_semifield_in_table" << endl;
1545 }
1546
1547 idx = -1;
1548
1549 if (f_v) {
1550 cout << "searching for: ";
1551 Lint_vec_print(cout, given_data, SC->k);
1552 cout << endl;
1553 }
1554 fst = FstLen[2 * po + 0];
1555 len = FstLen[2 * po + 1];
1556 if (f_v) {
1557 cout << "find_semifield_in_table po = " << po
1558 << " len = " << len << endl;
1559 }
1560 // make sure that the first three integers
1561 // agree with what is stored
1562 // in the table for orbit po:
1563 if (len == 0) {
1564 cout << "find_semifield_in_table len == 0" << endl;
1565 return FALSE;
1566 }
1567
1568 if (Sorting.lint_vec_compare(Data + fst * data_size + start_column,
1569 given_data, 3)) {
1570 cout << "find_semifield_in_table the first three entries "
1571 "of given_data do not match with what "
1572 "is in Data" << endl;
1573 exit(1);
1574 }
1575
1576 if (len == 1) {
1577 if (Sorting.lint_vec_compare(Data + fst * data_size + start_column,
1578 given_data, SC->k)) {
1579 cout << "find_semifield_in_table len is 1 and the first six "
1580 "entries of given_data do not match with what "
1581 "is in Data" << endl;
1582 exit(1);
1583 }
1584 idx = 0;
1585 }
1586 else {
1587 for (g = 0; g < len; g++) {
1588 if (Sorting.lint_vec_compare(Data + (fst + g) * data_size + start_column,
1589 given_data, SC->k) == 0) {
1590 idx = g;
1591 break;
1592 }
1593 }
1594 if (g == len) {
1595 cout << "find_semifield_in_table cannot find the "
1596 "semifield in the table" << endl;
1597 for (g = 0; g < len; g++) {
1598 cout << g << " : " << fst + g << " : ";
1599 Lint_vec_print(cout,
1600 Data + (fst + g) * data_size + start_column,
1601 SC->k);
1602 cout << " : ";
1603 cout << Sorting.lint_vec_compare(
1604 Data + (fst + g) * data_size + start_column,
1605 given_data, SC->k);
1606 cout << endl;
1607 }
1608 return FALSE;
1609 }
1610 }
1611
1612 if (f_v) {
1613 cout << "find_semifield_in_table done, idx = " << idx << endl;
1614 }
1615 return TRUE;
1616}
1617
1618
1619
1620}}}
1621
1622
a collection of functions related to sorted vectors
int int_vec_search(int *v, int len, int a, int &idx)
Definition: sorting.cpp:1094
int lint_vec_compare(long int *p, long int *q, int len)
Definition: sorting.cpp:2326
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
to rank and unrank subspaces of a fixed dimension in F_q^n
Definition: geometry.h:892
long int nb_of_subspaces(int verbose_level)
Definition: grassmann.cpp:113
void init(int n, int k, field_theory::finite_field *F, int verbose_level)
Definition: grassmann.cpp:70
void unrank_lint_here_and_extend_basis(int *Mtx, long int rk, int verbose_level)
Definition: grassmann.cpp:946
void mult_matrix_matrix(int *A, int *B, int *C, int m, int n, int o, int verbose_level)
int Gauss_int_with_given_pivots(int *A, int f_special, int f_complete, int *pivots, int nb_pivots, int m, int n, int verbose_level)
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
void mult(longinteger_object &a, longinteger_object &b, longinteger_object &c)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
void create(long int i, const char *file, int line)
void element_mult(void *a, void *b, void *ab, int verbose_level)
Definition: action_cb.cpp:315
void element_invert(void *a, void *av, int verbose_level)
Definition: action_cb.cpp:322
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(actions::action *A, int verbose_level)
Definition: vector_ge.cpp:55
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
void init_group_extension(strong_generators *subgroup, int *data, int index, int verbose_level)
void group_order(ring_theory::longinteger_object &go)
void init(actions::action *A, actions::action *A2, int max_orbits, int representation_sz, ring_theory::longinteger_object &go, int verbose_level)
void init(flag_orbits *Flag_orbits, int flag_orbit_index, int downstep_primary_orbit, int downstep_secondary_orbit, int downstep_orbit_len, int f_long_orbit, long int *pt_representation, groups::strong_generators *Strong_gens, int verbose_level)
stores the set of flag orbits; related to the class classification_step
Definition: classify.h:75
void init(actions::action *A, actions::action *A2, int nb_primary_orbits_lower, int pt_representation_sz, int nb_flag_orbits, int upper_bound_for_number_of_traces, void(*func_to_free_received_trace)(void *trace_result, void *data, int verbose_level), void(*func_latex_report_trace)(std::ostream &ost, void *trace_result, void *data, int verbose_level), void *free_received_trace_data, int verbose_level)
Definition: flag_orbits.cpp:75
void init(classification_step *C, int orbit_index, groups::strong_generators *gens, long int *Rep, void *extra_data, int verbose_level)
Definition: orbit_node.cpp:41
orbit of subspaces using a Schreier tree
Definition: orbits.h:175
groups::strong_generators * stabilizer_orbit_rep(ring_theory::longinteger_object &full_group_order, int verbose_level)
int find_subspace_lint(long int *subspace_ranks, int &idx, int verbose_level)
void get_transporter(int idx, int *transporter, int verbose_level)
void compute_orbit_of_subspaces(long int *input_data, groups::strong_generators *stabilizer_gens, orbit_of_subspaces *&Orb, int verbose_level)
void trace_to_level_two(int *input_basis, int basis_sz, int *transporter, int &trace_po, int verbose_level)
int trace_to_level_three(int *input_basis, int basis_sz, int *transporter, int &trace_po, int verbose_level)
int find_semifield_in_table(int po, long int *given_data, int &idx, int verbose_level)
int identify(long int *data, int &rk, int &trace_po, int &fo, int &po, int *transporter, int verbose_level)
void compute_cases(int nb_non_unique_cases, int *Non_unique_cases, long int *Non_unique_cases_go, int verbose_level)
void loop_over_all_subspaces(int *f_processed, int &nb_processed, int verbose_level)
to record the result of isomorphism testing
Definition: semifields.h:857
#define Lint_vec_copy(A, B, C)
Definition: foundations.h:694
#define FREE_OBJECTS(p)
Definition: foundations.h:652
#define Int_matrix_print_bitwise(A, B, C)
Definition: foundations.h:710
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_pint(n)
Definition: foundations.h:627
#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 NEW_OBJECTS(type, n)
Definition: foundations.h:639
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
void save_trace_record(trace_record *T, int f_trace_record_prefix, std::string &trace_record_prefix, int iso, int f, int po, int so, int N)
the orbiter library for the classification of combinatorial objects