Orbiter 2022
Combinatorial Objects
polar.cpp
Go to the documentation of this file.
1// polar.cpp
2//
3// Anton Betten
4// started: Feb 8, 2010
5// moved to DISCRETA: June 1, 2010
6//
7//
8//
9//
10
11#include "orbiter.h"
12
13using namespace std;
14
15namespace orbiter {
16namespace layer5_applications {
17namespace apps_geometry {
18
19
20static long int polar_callback_rank_point_func(int *v, void *data);
21static void polar_callback_unrank_point_func(int *v, long int rk, void *data);
22static void polar_callback_early_test_func(long int *S, int len,
23 long int *candidates, int nb_candidates,
24 long int *good_candidates, int &nb_good_candidates,
25 void *data, int verbose_level);
26
27
29{
30 epsilon = 0;
31 n = 0; // vector space dimension
32 k = 0;
33 q = 0;
34 depth = 0;
35
37
38 A = NULL; // the orthogonal action
39
40
41
42 Mtx = NULL; // only a copy of a pointer, not to be freed
43 O = NULL; // only a copy of a pointer, not to be freed
44 F = NULL; // only a copy of a pointer, not to be freed
45
46 tmp_M = NULL; // [n * n]
47 base_cols = NULL; // [n]
48
49 VS = NULL;
50 Control = NULL;
51 Poset = NULL;
52 Gen = NULL;
53
56 f_debug = FALSE;
57
60 Strong_gens = NULL;
61
62 first_node = 0;
63 nb_orbits = 0;
64 nb_elements = 0;
65}
66
68{
69 if (tmp_M) {
71 }
72 if (base_cols) {
74 }
75 if (VS) {
77 }
78 if (Control) {
80 }
81 if (Poset) {
83 }
84 if (Gen) {
86 }
89 if (Strong_gens) {
91 }
92 }
93}
94
96 int *group_generator_data, int group_generator_size,
97 int f_group_order_target, const char *group_order_target,
98 int verbose_level)
99{
100 int f_v = (verbose_level >= 1);
102
103 if (f_v) {
104 cout << "polar::init_group, calling "
105 "A->init_group_from_generators_by_base_images" << endl;
106 }
108 A->Sims,
109 group_generator_data, group_generator_size,
110 f_group_order_target, group_order_target,
111 &gens, Strong_gens,
112 verbose_level);
115}
116
118 int *group_generator_data, int group_generator_size,
119 int f_group_order_target, const char *group_order_target,
120 int verbose_level)
121{
122 int f_v = (verbose_level >= 1);
124
125 if (f_v) {
126 cout << "polar::init_group, calling "
127 "A->init_group_from_generators" << endl;
128 }
130 group_generator_data, group_generator_size,
131 f_group_order_target, group_order_target,
132 &gens, Strong_gens,
133 verbose_level);
136}
137
141 int epsilon, int n, int k, field_theory::finite_field *F,
142 int depth, int verbose_level)
143{
144 int f_v = (verbose_level >= 1);
145
147 polar::n = n;
148 polar::k = k;
149 polar::F = F;
150 polar::q = F->q;
152 polar::A = A;
153 polar::O = O;
154
155 if (f_v) {
156 cout << "polar::init n=" << n << " k=" << k << " q=" << q << endl;
157 }
158
159 //matrix_group *M;
160 //M = A->subaction->G.matrix_grp;
161 //O = M->O;
162
163
164
165
166 tmp_M = NEW_int(n * n);
168
169 //Gen->read_arguments(argc, argv, 0);
170
171 //Gen->prefix[0] = 0;
172 //sprintf(Gen->fname_base, "polar_%d_%d_%d_%d", epsilon, n, k, q);
173
174
175 //Gen->depth = depth;
176 //Gen->Control->verbose_level = verbose_level - 2;
177
178}
179
180void polar::init2(int depth, int verbose_level)
181{
182 int f_v = (verbose_level >= 1);
183 //int f_vv = (verbose_level >= 2);
184 //vector_ge *gens;
185 //int *transversal_lengths;
187
188 if (f_v) {
189 cout << "polar::init2" << endl;
190 }
192 if (f_v) {
193 cout << "initializing with strong generators" << endl;
194 }
195 gens = Strong_gens;
196 //gens = SG;
197 //transversal_lengths = tl;
198 }
199 else {
200 if (f_v) {
201 cout << "initializing full group" << endl;
202 }
203 gens = A->Strong_gens;
204 //gens = A->strong_generators;
205 //transversal_lengths = A->tl;
206 }
207
208 if (f_print_generators) {
209 int f_print_as_permutation = TRUE;
210 int f_offset = TRUE;
211 int offset = 1;
212 int f_do_it_anyway_even_for_big_degree = TRUE;
213 int f_print_cycles_of_length_one = FALSE;
214
215 cout << "printing generators for the group:" << endl;
216 gens->gens->print(cout, f_print_as_permutation,
217 f_offset, offset,
218 f_do_it_anyway_even_for_big_degree,
219 f_print_cycles_of_length_one);
220 }
222
223 VS->init(F, n /* dimension */,
224 verbose_level - 1);
226 polar_callback_rank_point_func,
227 polar_callback_unrank_point_func,
228 this,
229 verbose_level - 1);
230
234
235
236 char label[1000];
237
238 sprintf(label, "polar_%d_%d_%d_%d", epsilon, n, k, q); // ToDo
239
240
241
244 gens,
245 VS,
246 verbose_level);
247
249 polar_callback_early_test_func,
250 this /* void *data */,
251 verbose_level);
252
255 depth /* sz */, verbose_level);
256
257
258#if 0
259 Gen->f_print_function = TRUE;
260 Gen->print_function = print_set;
261 Gen->print_function_data = this;
262#endif
263
266 f_debug = FALSE;
267}
268
269void polar::compute_orbits(int t0, int verbose_level)
270{
271 int f_v = (verbose_level >= 1);
272
273 if (f_v) {
274 cout << "polar::compute_orbits calling generator_main" << endl;
275 cout << "A=";
276 Gen->get_A()->print_info();
277 cout << "A2=";
278 Gen->get_A2()->print_info();
279 }
280 Gen->main(t0,
283 f_debug,
284 verbose_level - 1);
285
286 if (f_v) {
287 cout << "done with generator_main" << endl;
288 }
291
292 int i;
293 nb_elements = 0;
294 for (i = 0; i < nb_orbits; i++) {
296 }
297 if (f_v) {
298 cout << "we found " << nb_orbits << " orbits containing "
299 << nb_elements << " elements at depth " << depth << endl;
300 }
301}
302
303void polar::compute_cosets(int depth, int orbit_idx, int verbose_level)
304{
305 int f_v = (verbose_level >= 1);
306 int f_vv = (verbose_level >= 2);
307 int f_vvv = (verbose_level >= 3);
308 int i, c, cc, node2, index_int;
309 long int *the_set1;
310 long int *the_set2;
311 int *M1;
312 int *M2;
313 int *Elt1, *Elt2;
315 ring_theory::longinteger_object go1, go2, index, rem, Rank;
317
318 if (f_v) {
319 cout << "polar::compute_cosets" << endl;
320 }
321 Elt1 = NEW_int(Gen->get_A()->elt_size_in_int);
322 Elt2 = NEW_int(Gen->get_A()->elt_size_in_int);
323 the_set1 = NEW_lint(depth);
324 the_set2 = NEW_lint(depth);
325 M1 = NEW_int(k * n);
326 M2 = NEW_int(k * n);
327
328 node2 = Gen->first_node_at_level(depth) + orbit_idx;
329 O2 = Gen->get_node(node2);
330
331 Gen->stabilizer_order(0, go1);
332 Gen->stabilizer_order(node2, go2);
333 D.integral_division(go1, go2, index, rem, 0);
334
335 index_int = index.as_int();
336 if (f_v) {
337 cout << "polar::compute_cosets index=" << index_int << endl;
338 }
339
340 O2->store_set_to(Gen, depth - 1, the_set1);
341
342 if (f_v) {
343 cout << "the set representing orbit " << orbit_idx
344 << " at level " << depth << " is ";
345 Lint_vec_print(cout, the_set1, depth);
346 cout << endl;
347 }
348 for (i = 0; i < k; i++) {
349 unrank_point(M1 + i * n, the_set1[i]);
350 //polar_callback_unrank_point_func(M1 + i * n, the_set1[i], this);
351 }
352 if (f_vv) {
353 cout << "corresponding to the subspace with basis:" << endl;
355 }
356
358
359 Grass.init(n, k, F, 0 /*verbose_level*/);
360 for (i = 0; i < k * n; i++) {
361 Grass.M[i] = M1[i];
362 }
363 Grass.rank_longinteger(Rank, 0/*verbose_level - 3*/);
364 cout << "Rank=" << Rank << endl;
365
366
367 for (c = 0; c < index_int; c++) {
368
369 //if (!(c == 2 || c == 4)) {continue;}
370 if (f_v) {
371 cout << "Coset " << c << endl;
372 }
373 Gen->coset_unrank(depth, orbit_idx, c, Elt1, 0/*verbose_level*/);
374
375 if (f_vvv) {
376 cout << "Left coset " << c << " is represented by" << endl;
377 Gen->get_A()->element_print_quick(Elt1, cout);
378 cout << endl;
379 }
380
381 Gen->get_A()->element_invert(Elt1, Elt2, 0);
382
383
384 if (f_vvv) {
385 cout << "Right coset " << c << " is represented by" << endl;
386 Gen->get_A()->element_print_quick(Elt2, cout);
387 cout << endl;
388 }
389
390 for (i = 0; i < k; i++) {
391 A->element_image_of_low_level(M1 + i * n, M2 + i * n,
392 Elt2, 0/* verbose_level*/);
393 }
394 if (f_vv) {
395 cout << "basis of subspace that is the image "
396 "under this element:" << endl;
398 }
399 for (i = 0; i < k * n; i++) {
400 Grass.M[i] = M2[i];
401 }
402 Grass.rank_longinteger(Rank, 0/*verbose_level - 3*/);
403 if (f_vv) {
404 cout << "Coset " << c << " Rank=" << Rank << endl;
405 }
406
407 cc = Gen->coset_rank(depth, orbit_idx, Elt1, 0/*verbose_level*/);
408 if (cc != c) {
409 cout << "error in polar::compute_cosets" << endl;
410 cout << "cc != c" << endl;
411 cout << "c=" << c << endl;
412 cout << "cc=" << cc << endl;
413 //cc = Gen->coset_rank(depth, orbit_idx, Elt1, verbose_level);
414 exit(1);
415 }
416 }
417 FREE_int(Elt1);
418 FREE_int(Elt2);
419 FREE_lint(the_set1);
420 FREE_lint(the_set2);
421 FREE_int(M1);
422 FREE_int(M2);
423}
424
425void polar::dual_polar_graph(int depth, int orbit_idx,
426 ring_theory::longinteger_object *&Rank_table, int &nb_maximals,
427 int verbose_level)
428{
429 int f_v = (verbose_level >= 1);
430 int f_vv = (verbose_level >= 2);
431 int i, c, node2, index_int;
432 long int *the_set1;
433 long int *the_set2;
434 int *M1;
435 int *M2;
436 int *Elt1, *Elt2;
438 ring_theory::longinteger_object go1, go2, index, rem, Rank;
440 int *Adj;
441 int **M;
442 int witt;
444
445 if (f_v) {
446 cout << "polar::dual_polar_graph" << endl;
447 }
448 Elt1 = NEW_int(Gen->get_A()->elt_size_in_int);
449 Elt2 = NEW_int(Gen->get_A()->elt_size_in_int);
450 the_set1 = NEW_lint(depth);
451 the_set2 = NEW_lint(depth);
452 M1 = NEW_int(k * n);
453 M2 = NEW_int(k * n);
454
455 witt = Gg.Witt_index(epsilon, n - 1);
456
457 node2 = Gen->first_node_at_level(depth) + orbit_idx;
458 O2 = Gen->get_node(node2);
459
460 Gen->stabilizer_order(0, go1);
461 Gen->stabilizer_order(node2, go2);
462 D.integral_division(go1, go2, index, rem, 0);
463
464 index_int = index.as_int();
465 if (f_v) {
466 cout << "polar::dual_polar_graph index=" << index_int << endl;
467 cout << "polar::dual_polar_graph witt=" << witt << endl;
468 }
469
470 nb_maximals = index_int;
471 Rank_table = NEW_OBJECTS(ring_theory::longinteger_object, index_int);
472 Adj = NEW_int(index_int * index_int);
473 M = NEW_pint(index_int);
474
475 for (i = 0; i < index_int; i++) {
476 M[i] = NEW_int(k * n);
477 }
478 for (i = 0; i < index_int * index_int; i++) {
479 Adj[i] = 0;
480 }
481
482 O2->store_set_to(Gen, depth - 1, the_set1);
483
484 if (f_v) {
485 cout << "the set representing orbit " << orbit_idx
486 << " at level " << depth << " is ";
487 Lint_vec_print(cout, the_set1, depth);
488 cout << endl;
489 }
490 for (i = 0; i < k; i++) {
491 unrank_point(M1 + i * n, the_set1[i]);
492 //polar_callback_unrank_point_func(M1 + i * n, the_set1[i], this);
493 }
494
495 if (f_v) {
496 cout << "corresponding to the subspace with basis:" << endl;
498 }
499
501
502 Grass.init(n, k, F, verbose_level - 2);
503 for (i = 0; i < k * n; i++) {
504 Grass.M[i] = M1[i];
505 }
506 Grass.rank_longinteger(Rank, 0/*verbose_level - 3*/);
507 cout << "Rank=" << Rank << endl;
508
509
510 for (c = 0; c < index_int; c++) {
511
512 //if (!(c == 2 || c == 4)) {continue;}
513
514 if (FALSE) {
515 cout << "Coset " << c << endl;
516 }
517 Gen->coset_unrank(depth, orbit_idx, c, Elt1, 0/*verbose_level*/);
518
519 if (FALSE) {
520 cout << "Left coset " << c << " is represented by" << endl;
521 Gen->get_A()->element_print_quick(Elt1, cout);
522 cout << endl;
523 }
524
525 Gen->get_A()->element_invert(Elt1, Elt2, 0);
526
527
528 if (FALSE) {
529 cout << "Right coset " << c
530 << " is represented by" << endl;
531 Gen->get_A()->element_print_quick(Elt2, cout);
532 cout << endl;
533 }
534
535 for (i = 0; i < k; i++) {
537 M2 + i * n, Elt2, 0/* verbose_level*/);
538 }
539
540 F->Linear_algebra->Gauss_easy(M2, k, n);
541
542 if (f_vv) {
543 cout << "subspace " << c << ":" << endl;
545 }
546
547
548
549
550 for (i = 0; i < k * n; i++) {
551 Grass.M[i] = M2[i];
552 }
553 Grass.rank_longinteger(Rank, 0/*verbose_level - 3*/);
554 if (f_vv) {
555 cout << "Coset " << c << " Rank=" << Rank << endl;
556 }
557
558 Rank.assign_to(Rank_table[c]);
559
560 for (i = 0; i < k * n; i++) {
561 M[c][i] = M2[i];
562 }
563
564 }
565
566 int c1, c2, rk, nb_e, e;
567 int *MM;
568 int *Inc;
569
570 MM = NEW_int(2 * k * n);
571
572 nb_e = 0;
573 for (c1 = 0; c1 < index_int; c1++) {
574 for (c2 = 0; c2 < index_int; c2++) {
575 for (i = 0; i < k * n; i++) {
576 MM[i] = M[c1][i];
577 }
578 for (i = 0; i < k * n; i++) {
579 MM[k * n + i] = M[c2][i];
580 }
582 2 * k, n, 0 /* verbose_level*/);
583 //rk1 = rk - k;
584 //Adj[c1 * index_int + c2] = rk1;
585 if (rk == k + 1) {
586 Adj[c1 * index_int + c2] = 1;
587 }
588 }
589 }
590
591 if (f_vv) {
592 cout << "adjacency matrix:" << endl;
594 index_int, index_int, index_int, 1);
595 }
596
597 if (f_vv) {
598 cout << "neighborhood lists:" << endl;
599 for (c1 = 0; c1 < index_int; c1++) {
600 cout << "N(" << c1 << ")={";
601 for (c2 = 0; c2 < index_int; c2++) {
602 if (Adj[c1 * index_int + c2]) {
603 cout << c2 << " ";
604 }
605 }
606 cout << "}" << endl;
607 }
608 }
609
610 nb_e = 0;
611 for (c1 = 0; c1 < index_int; c1++) {
612 for (c2 = c1 + 1; c2 < index_int; c2++) {
613 if (Adj[c1 * index_int + c2]) {
614 nb_e++;
615 }
616 }
617 }
618 if (f_vv) {
619 cout << "with " << nb_e << " edges" << endl;
620 }
621
622
623 Inc = NEW_int(index_int * nb_e);
624 for (i = 0; i < index_int * nb_e; i++) {
625 Inc[i] = 0;
626 }
627
628 e = 0;
629 for (c1 = 0; c1 < index_int; c1++) {
630 for (c2 = c1 + 1; c2 < index_int; c2++) {
631 if (Adj[c1 * index_int + c2]) {
632 Inc[c1 * nb_e + e] = 1;
633 Inc[c2 * nb_e + e] = 1;
634 e++;
635 }
636 }
637 }
638 if (f_vv) {
639 cout << "Incidence matrix:" << index_int
640 << " x " << nb_e << endl;
642 index_int, nb_e, nb_e, 1);
643 }
644
645 {
646 char fname[1000];
647
648 sprintf(fname, "dual_polar_graph_O_%d_%d_%d.inc", epsilon, n, q);
649 {
650 ofstream f(fname);
651 f << index_int << " " << nb_e << " " << 2 * nb_e << endl;
652 for (i = 0; i < index_int * nb_e; i++) {
653 if (Inc[i]) {
654 f << i << " ";
655 }
656 }
657 f << endl;
658 f << -1 << endl;
659 }
660
662
663 if (f_v) {
664 cout << "written file " << fname << " of size "
665 << Fio.file_size(fname) << endl;
666 }
667 }
668
669 FREE_int(Inc);
670 FREE_int(MM);
671
672
673 FREE_int(Elt1);
674 FREE_int(Elt2);
675 FREE_lint(the_set1);
676 FREE_lint(the_set2);
677 FREE_int(M1);
678 FREE_int(M2);
679 FREE_int(Adj);
680 for (i = 0; i < index_int; i++) {
681 FREE_int(M[i]);
682 }
683 FREE_pint(M);
684}
685
686void polar::show_stabilizer(int depth, int orbit_idx, int verbose_level)
687{
688 int *Elt;
689 long int goi, i, order;
691
692 Elt = NEW_int(A->elt_size_in_int);
693
695 depth, orbit_idx, 0 /* verbose_level*/);
696 //Gen->get_stabilizer(gens, tl, depth, orbit_idx, verbose_level);
697
698 groups::sims *S;
701 verbose_level);
703
704 S->group_order(go);
705 cout << "polar::show_stabilizer created group of order " << go << endl;
706 goi = go.as_int();
707 for (i = 0; i < goi; i++) {
708 S->element_unrank_lint(i, Elt);
709 order = A->element_order(Elt);
710 cout << "element " << i << " of order " << order << ":" << endl;
711 A->element_print_quick(Elt, cout);
713 cout << endl;
714 }
715
717 FREE_OBJECT(S);
718 FREE_int(Elt);
719}
720
721#if 0
722void polar::get_maximals(int depth, int orbit_idx, int verbose_level)
723{
724 int node2;
725 poset_orbit_node *O2;
726 vector_ge *gens;
727 int *tl;
728 int *Elt;
729 int goi, i, order;
730
731 gens = NEW_OBJECT(vector_ge);
732 tl = NEW_int(A->base_len);
733 Elt = NEW_int(A->elt_size_in_int);
734 node2 = Gen->first_poset_orbit_node_at_level[depth] + orbit_idx;
735 O2 = &Gen->root[node2];
736 Gen->get_stabilizer(gens, tl, depth, orbit_idx, verbose_level);
737
738 sims *S;
739 S = create_sims_from_generators_with_target_group_order_factorized(
740 A, gens, tl, A->base_len, verbose_level);
741 longinteger_object go;
742
743 S->group_order(go);
744 cout << "polar::show_stabilizer created group of order " << go << endl;
745 goi = go.as_int();
746 for (i = 0; i < goi; i++) {
747 S->element_unrank_int(i, Elt);
748 order = A->element_order(Elt);
749 cout << "element " << i << " of order " << order << ":" << endl;
750 A->element_print_quick(Elt, cout);
752 cout << endl;
753 }
754
755 FREE_OBJECT(S);
756 FREE_OBJECT(gens);
757 FREE_int(tl);
758 FREE_int(Elt);
759}
760#endif
761
762#if 0
763void polar::compute_Kramer_Mesner_matrix(int t, int k, int verbose_level)
764{
765 int f_v = (verbose_level >= 1);
766
767 if (f_v) {
768 cout << "compute_Kramer_Mesner_matrix t=" << t
769 << " k=" << k << ":" << endl;
770 }
771
772 // compute Kramer Mesner matrices
773 Vector V;
774 int i;
775
776 V.m_l(k);
777 for (i = 0; i < k; i++) {
778 V[i].change_to_matrix();
779 calc_Kramer_Mesner_matrix_neighboring(Gen, i,
780 V[i].as_matrix(), verbose_level - 2);
781 if (f_v) {
782 cout << "matrix level " << i << ":" << endl;
783 V[i].as_matrix().print(cout);
784 }
785 }
786
787 discreta_matrix Mtk, Mtk_inf;
788
789 Mtk_from_MM(V, Mtk, t, k, TRUE, q, verbose_level - 2);
790 cout << "M_{" << t << "," << k << "} sup:" << endl;
791 Mtk.print(cout);
792
793
794 Mtk_sup_to_inf(Gen, t, k, Mtk, Mtk_inf, verbose_level - 2);
795 cout << "M_{" << t << "," << k << "} inf:" << endl;
796 Mtk_inf.print(cout);
797
798}
799#endif
800
801
802#if 0
803int polar::test(int *S, int len, int verbose_level)
804// test if totally isotropic, i.e. contained in its own perp
805{
806 int f_v = (verbose_level >= 1);
807 int f_vv = (verbose_level >= 2);
808 int i, rk;
809 int f_OK = TRUE;
810
811 if (f_v) {
812 cout << "polar::test" << endl;
813 }
814 for (i = 0; i < len; i++) {
815 O->unrank_point(tmp_M + i * n, 1, S[i], 0);
816 //PG_element_unrank_modified(*P->F, tmp_M, 1, n, S[i]);
817 }
818 if (f_v) {
819 cout << "coordinate matrix:" << endl;
820 print_integer_matrix_width(cout, tmp_M, len, n, n, F->log10_of_q);
821 }
822 F->perp(n, k, tmp_M, O->Gram_matrix);
823 if (f_vv) {
824 cout << "after perp:" << endl;
825 print_integer_matrix_width(cout, tmp_M, n, n, n,
826 F->log10_of_q + 1);
827 }
828 rk = F->Gauss_simple(tmp_M,
829 len, n, base_cols, verbose_level - 2);
830 if (f_v) {
831 cout << "the matrix has rank " << rk << endl;
832 }
833 if (rk > n - len) {
834 f_OK = FALSE;
835 }
836 if (rk < n - len) {
837 cout << "polar::test rk < n - len, fatal. "
838 "This should not happen" << endl;
839 cout << "rk=" << rk << endl;
840 cout << "n=" << n << endl;
841 cout << "len=" << len << endl;
842 exit(1);
843 }
844 if (f_v) {
845 cout << "polar::test done, f_OK=" << f_OK << endl;
846 }
847 return f_OK;
848}
849#endif
850
851void polar::test_if_in_perp(long int *S, int len,
852 long int *candidates, int nb_candidates,
853 long int *good_candidates, int &nb_good_candidates,
854 int verbose_level)
855{
856 int f_v = (verbose_level >= 1);
857 int f_vv = (verbose_level >= 2);
858 int i, f, c;
859
860
861 if (f_v) {
862 cout << "polar::test_if_in_perp done for ";
864 cout << endl;
865 }
866 if (len == 0) {
867 for (i = 0; i < nb_candidates; i++) {
868 good_candidates[i] = candidates[i];
869 }
870 nb_good_candidates = nb_candidates;
871 return;
872 }
873
874 nb_good_candidates = 0;
875
876 O->unrank_point(tmp_M + 0 * n, 1, S[len - 1], 0);
877 for (i = 0; i < nb_candidates; i++) {
878 c = candidates[i];
879 O->unrank_point(tmp_M + 1 * n, 1, c, 0);
880 if (f_vv) {
881 cout << "candidate " << i << " = " << c << ":" << endl;
883 tmp_M, 2, n, n, F->log10_of_q);
884 }
885 f = O->evaluate_bilinear_form(tmp_M + 0 * n, tmp_M + 1 * n, 1);
886 if (f_vv) {
887 cout << "form value " << f << endl;
888 }
889 if (f == 0) {
890 good_candidates[nb_good_candidates++] = c;
891 }
892 }
893
894
895 if (f_v) {
896 cout << "polar::test_if_in_perp done for ";
898 cout << "; # of candidates reduced from " << nb_candidates
899 << " to " << nb_good_candidates << endl;
900 }
901 if (f_vv) {
902 cout << "good candidates: ";
903 Lint_vec_print(cout, good_candidates, nb_good_candidates);
904 cout << endl;
905 }
906}
907
909 int *candidates, int nb_candidates,
910 int *good_candidates, int &nb_good_candidates,
911 int verbose_level)
912{
913 int f_v = (verbose_level >= 1);
914 int f_vv = (verbose_level >= 2);
915 int i, j, h, c, d, y, f_OK, idx, nb, nb0;
916 int *M;
917 int *N0;
918 int *N;
919 int *v;
920 int *w;
921 int *candidates_expanded;
922 int nb_candidates_expanded;
923 int *tmp_candidates;
924 int nb_tmp_candidates;
927
928 if (f_v) {
929 cout << "polar::test_if_closed_under_cosets for ";
931 cout << endl;
932 cout << "verbose_level=" << verbose_level << endl;
933 cout << "candidates: ";
934 Int_vec_print(cout, candidates, nb_candidates);
935 cout << endl;
936 }
937 if (len == 0) {
938 for (i = 0; i < nb_candidates; i++) {
939 good_candidates[i] = candidates[i];
940 }
941 nb_good_candidates = nb_candidates;
942 return;
943 }
944
945 nb = Gg.nb_PG_elements(len - 1, F->q);
946 if (len >= 2) {
947 nb0 = Gg.nb_PG_elements(len - 2, F->q);
948 }
949 else {
950 nb0 = 1;
951 }
952 M = NEW_int(len * n);
953 N0 = NEW_int(nb0 * n);
954 N = NEW_int(nb * n);
955 v = NEW_int(n);
956 w = NEW_int(n);
957 candidates_expanded = NEW_int(2 * nb_candidates * (1 + nb0));
958 tmp_candidates = NEW_int(2 * nb_candidates * (1 + nb0));
959 for (i = 0; i < len; i++) {
960 O->unrank_point(M + i * n, 1, S[i], 0);
961 }
962 if (f_v) {
963 cout << "the basis is ";
964 Int_vec_print(cout, S, len);
965 cout << endl;
966 cout << "corresponding to the vectors:" << endl;
968 cout << "nb=" << nb << endl;
969 }
970 if (len >= 2) {
971 for (i = 0; i < nb0; i++) {
972 F->PG_element_unrank_modified(v, 1, len - 1, i);
973 F->Linear_algebra->mult_vector_from_the_left(v, M, N0 + i * n, len - 1, n);
974 }
975 if (f_v) {
976 cout << "the list of points N0:" << endl;
978 }
979 }
980 for (i = 0; i < nb; i++) {
981 F->PG_element_unrank_modified(v, 1, len, i);
982 F->Linear_algebra->mult_vector_from_the_left(v, M, N + i * n, len, n);
983 }
984 if (f_v) {
985 cout << "the list of points N:" << endl;
987 }
988 if (len >= 2) {
989 // the expand step:
990 if (f_v) {
991 cout << "expand:" << endl;
992 }
993 nb_candidates_expanded = 0;
994 for (i = 0; i < nb_candidates; i++) {
995 c = candidates[i];
996 candidates_expanded[nb_candidates_expanded++] = c;
997 if (Sorting.int_vec_search(S, len, c, idx)) {
998 continue;
999 }
1000 O->unrank_point(v, 1, c, 0);
1001 if (f_v) {
1002 cout << "i=" << i;
1003 Int_vec_print(cout, v, n);
1004 cout << endl;
1005 }
1006 for (j = 0; j < nb0; j++) {
1007 for (y = 1; y < F->q; y++) {
1008 for (h = 0; h < n; h++) {
1009 w[h] = F->add(v[h], F->mult(y, N0[j * n + h]));
1010 }
1011 if (f_v) {
1012 cout << "j=" << j << " y=" << y << " : w=";
1013 Int_vec_print(cout, w, n);
1014 cout << endl;
1015 }
1016 d = O->rank_point(w, 1, 0);
1017 if (f_v) {
1018 cout << "d=" << d << endl;
1019 }
1020 candidates_expanded[nb_candidates_expanded++] = d;
1021 } // next y
1022 } // next j
1023 } // next i
1024 if (f_v) {
1025 cout << "expanded candidate set:" << endl;
1026 Int_vec_print(cout,
1027 candidates_expanded, nb_candidates_expanded);
1028 cout << endl;
1029 }
1030 Sorting.int_vec_heapsort(candidates_expanded, nb_candidates_expanded);
1031 if (f_v) {
1032 cout << "expanded candidate set after sort:" << endl;
1033 Int_vec_print(cout, candidates_expanded, nb_candidates_expanded);
1034 cout << endl;
1035 }
1036 }
1037 else {
1038 nb_candidates_expanded = 0;
1039 for (i = 0; i < nb_candidates; i++) {
1040 c = candidates[i];
1041 candidates_expanded[nb_candidates_expanded++] = c;
1042 }
1043 }
1044
1045 // now we are doing the test if the full coset is present:
1046 nb_tmp_candidates = 0;
1047 for (i = 0; i < nb_candidates_expanded; i++) {
1048 c = candidates_expanded[i];
1049 if (Sorting.int_vec_search(S, len, c, idx)) {
1050 tmp_candidates[nb_tmp_candidates++] = c;
1051 continue;
1052 }
1053 O->unrank_point(v, 1, c, 0);
1054 if (f_v) {
1055 cout << "i=" << i;
1056 Int_vec_print(cout, v, n);
1057 cout << endl;
1058 }
1059 f_OK = TRUE;
1060 for (j = 0; j < nb; j++) {
1061 for (y = 1; y < F->q; y++) {
1062 for (h = 0; h < n; h++) {
1063 w[h] = F->add(v[h], F->mult(y, N[j * n + h]));
1064 }
1065 if (f_v) {
1066 cout << "j=" << j << " y=" << y << " : w=";
1067 Int_vec_print(cout, w, n);
1068 cout << endl;
1069 }
1070 d = O->rank_point(w, 1, 0);
1071 if (!Sorting.int_vec_search(candidates_expanded,
1072 nb_candidates_expanded, d, idx)) {
1073 if (f_vv) {
1074 cout << "polar::test_if_closed_under_cosets "
1075 "point " << c << " is ruled out, "
1076 "coset point " << d << " is not found "
1077 "j=" << j << " y=" << y << endl;
1078 }
1079 f_OK = FALSE;
1080 break;
1081 }
1082 }
1083 if (!f_OK) {
1084 break;
1085 }
1086 }
1087 if (f_OK) {
1088 tmp_candidates[nb_tmp_candidates++] = c;
1089 }
1090 }
1091 if (f_v) {
1092 cout << "tmp_candidates:" << endl;
1093 Int_vec_print(cout, tmp_candidates, nb_tmp_candidates);
1094 cout << endl;
1095 }
1096
1097 nb_good_candidates = 0;
1098 for (i = 0; i < nb_candidates; i++) {
1099 c = candidates[i];
1100 if (Sorting.int_vec_search(tmp_candidates, nb_tmp_candidates, c, idx)) {
1101 good_candidates[nb_good_candidates++] = c;
1102 continue;
1103 }
1104 }
1105
1106 if (f_v) {
1107 cout << "polar::test_if_closed_under_cosets for ";
1109 cout << "; # of candidates reduced from "
1110 << nb_candidates << " to " << nb_good_candidates << endl;
1111 }
1112 if (f_vv) {
1113 cout << "good candidates: ";
1114 Int_vec_print(cout, good_candidates, nb_good_candidates);
1115 cout << endl;
1116 }
1117 FREE_int(M);
1118 FREE_int(N0);
1119 FREE_int(N);
1120 FREE_int(v);
1121 FREE_int(w);
1122 FREE_int(candidates_expanded);
1123 FREE_int(tmp_candidates);
1124}
1125
1126
1127void polar::get_stabilizer(int orbit_idx,
1130{
1131 Gen->get_node(first_node + orbit_idx)->get_stabilizer(Gen,
1132 G, go_G, 0 /*verbose_level - 2*/);
1133}
1134
1135void polar::get_orbit_length(int orbit_idx,
1137{
1138 Gen->orbit_length(orbit_idx, depth, length);
1139}
1140
1142{
1143 return Gen->orbit_length_as_int(orbit_idx, depth);
1144}
1145
1147 long int rank, long int *set, int verbose_level)
1148{
1150 orbit_idx, rank, set, verbose_level);
1151}
1152
1153void polar::orbit_element_rank(int &orbit_idx,
1154 long int &rank, long int *set, int verbose_level)
1155{
1157 orbit_idx, rank, set, verbose_level);
1158}
1159
1160void polar::unrank_point(int *v, int rk)
1161{
1162 O->unrank_point(v, 1, rk, 0);
1163}
1164
1166{
1167 return O->rank_point(v, 1, 0);
1168}
1169
1171 int orbit_idx, int f_limit, int limit)
1172{
1173 long int *set;
1174 int ii;
1175 long int len, j, h, jj;
1178 int *M1;
1179 int *base_cols;
1180
1181 set = NEW_lint(depth);
1182 M1 = NEW_int(depth * n);
1183 base_cols = NEW_int(n);
1184 get_stabilizer(orbit_idx, G, go_G);
1185 cout << "the stabilizer of orbit rep " << orbit_idx
1186 << " has order " << go_G << endl;
1187
1188 len = get_orbit_length_as_int(orbit_idx);
1189
1190 cout << "the orbit length of orbit " << orbit_idx
1191 << " is " << len << endl;
1192 for (j = 0; j < len; j++) {
1193 //if (j != 2) continue;
1194
1195 if (f_limit && j >= limit) {
1196 cout << "..." << endl;
1197 break;
1198 }
1199 orbit_element_unrank(orbit_idx, j, set, 0/*verbose_level*/);
1200 cout << setw(4) << j << " : ";
1201 Lint_vec_print(cout, set, depth);
1202 cout << endl;
1203
1204 for (h = 0; h < depth; h++) {
1205 unrank_point(M1 + h * n, set[h]);
1206 }
1207 cout << "corresponding to the subspace with basis:" << endl;
1209
1210 F->Linear_algebra->Gauss_simple(M1, depth, n, base_cols, 0/* verbose_level*/);
1211
1212 cout << "basis in echelon form:" << endl;
1214
1215
1216
1217 geometry::grassmann Grass;
1218
1219 Grass.init(n, k, F, 0/*verbose_level*/);
1220 for (h = 0; h < k * n; h++) {
1221 Grass.M[h] = M1[h];
1222 }
1223 Grass.rank_longinteger(Rank, 0/*verbose_level - 3*/);
1224 cout << "Rank=" << Rank << endl;
1225
1226 orbit_element_rank(ii, jj, set, 0/*verbose_level*/);
1227 cout << setw(2) << ii << " : " << setw(4) << jj << endl;
1228 if (ii != orbit_idx) {
1229 cout << "polar::list_whole_orbit: "
1230 "fatal: ii != orbit_idx" << endl;
1231 exit(1);
1232 }
1233 if (jj != j) {
1234 cout << "polar::list_whole_orbit: "
1235 "fatal: jj != j" << endl;
1236 exit(1);
1237 }
1238 }
1239 FREE_lint(set);
1240 FREE_int(M1);
1242}
1243
1244
1245// #############################################################################
1246// global functions:
1247// #############################################################################
1248
1249long int static polar_callback_rank_point_func(int *v, void *data)
1250{
1251 polar *P = (polar *) data;
1252 //generator *gen = P->Gen;
1253 long int rk;
1254
1255 rk = P->O->rank_point(v, 1, 0);
1256 return rk;
1257}
1258
1259void static polar_callback_unrank_point_func(int *v, long int rk, void *data)
1260{
1261 polar *P = (polar *) data;
1262 //generator *gen = P->Gen;
1263
1264 P->O->unrank_point(v, 1, rk, 0);
1265 //PG_element_unrank_modified(*gen->F, v, 1,
1266 // gen->vector_space_dimension, rk);
1267}
1268
1269#if 0
1270int polar_callback_test_func(int len, int *S,
1271 void *data, int verbose_level)
1272{
1273 polar *P = (polar *) data;
1274 int f_OK = TRUE;
1275 int f_v = (verbose_level >= 1);
1276
1277 if (f_v) {
1278 cout << "checking set ";
1279 print_set(cout, len, S);
1280 }
1281 f_OK = P->test(S, len, verbose_level - 2);
1282 if (f_OK) {
1283 if (f_v) {
1284 cout << "OK" << endl;
1285 }
1286 return TRUE;
1287 }
1288 else {
1289 return FALSE;
1290 }
1291}
1292#endif
1293
1294void static polar_callback_early_test_func(long int *S, int len,
1295 long int *candidates, int nb_candidates,
1296 long int *good_candidates, int &nb_good_candidates,
1297 void *data, int verbose_level)
1298{
1299 polar *P = (polar *) data;
1300 int f_v = (verbose_level >= 1);
1301
1302 if (f_v) {
1303 cout << "polar_callback_early_test_func for set ";
1304 Lint_vec_print(cout, S, len);
1305 cout << endl;
1306 }
1307 P->test_if_in_perp(S, len,
1308 candidates, nb_candidates,
1309 good_candidates, nb_good_candidates,
1310 verbose_level - 2);
1311 if (f_v) {
1312 cout << "polar_callback_early_test_func done" << endl;
1313 }
1314}
1315
1316}}}
1317
1318
finite dimensional vector space over a finite field
Definition: algebra.h:688
void init(field_theory::finite_field *F, int dimension, int verbose_level)
void init_rank_functions(long int(*rank_point_func)(int *v, void *data), void(*unrank_point_func)(int *v, long int rk, void *data), void *data, int verbose_level)
void set_print(std::ostream &ost, int *v, int len)
Definition: int_vec.cpp:1043
a collection of functions related to sorted vectors
int int_vec_search(int *v, int len, int a, int &idx)
Definition: sorting.cpp:1094
void PG_element_unrank_modified(int *v, int stride, int len, int a)
various functions related to geometries
Definition: geometry.h:721
to rank and unrank subspaces of a fixed dimension in F_q^n
Definition: geometry.h:892
void rank_longinteger(ring_theory::longinteger_object &r, int verbose_level)
Definition: grassmann.cpp:764
void init(int n, int k, field_theory::finite_field *F, int verbose_level)
Definition: grassmann.cpp:70
void mult_vector_from_the_left(int *v, int *A, int *vA, int m, int n)
int rank_of_rectangular_matrix(int *A, int m, int n, int verbose_level)
int Gauss_simple(int *A, int m, int n, int *base_cols, int verbose_level)
long int rank_point(int *v, int stride, int verbose_level)
void unrank_point(int *v, int stride, long int rk, int verbose_level)
domain to compute with objects of type longinteger
Definition: ring_theory.h:240
void integral_division(longinteger_object &a, longinteger_object &b, longinteger_object &q, longinteger_object &r, int verbose_level)
a class to represent arbitrary precision integers
Definition: ring_theory.h:366
DISCRETA vector class for vectors of DISCRETA objects.
Definition: discreta.h:797
discreta_matrix & change_to_matrix()
Definition: discreta.h:424
std::ostream & print(std::ostream &)
a permutation group in a fixed action.
Definition: actions.h:99
void init_group_from_generators_by_base_images(groups::sims *S, int *group_generator_data, int group_generator_size, int f_group_order_target, const char *group_order_target, data_structures_groups::vector_ge *gens, groups::strong_generators *&Strong_gens_out, int verbose_level)
Definition: action.cpp:2136
void element_print_quick(void *elt, std::ostream &ost)
Definition: action_cb.cpp:353
groups::sims * create_sims_from_generators_with_target_group_order_factorized(data_structures_groups::vector_ge *gens, int *tl, int len, int verbose_level)
groups::strong_generators * Strong_gens
Definition: actions.h:130
void element_invert(void *a, void *av, int verbose_level)
Definition: action_cb.cpp:322
void element_image_of_low_level(int *input, int *output, void *elt, int verbose_level)
Definition: action_cb.cpp:209
void init_group_from_generators(int *group_generator_data, int group_generator_size, int f_group_order_target, const char *group_order_target, data_structures_groups::vector_ge *gens, groups::strong_generators *&Strong_gens, int verbose_level)
Definition: action.cpp:2059
void element_print_as_permutation(void *elt, std::ostream &ost)
Definition: action_cb.cpp:421
a permutation group represented via a stabilizer chain
Definition: groups.h:1273
void group_order(ring_theory::longinteger_object &go)
Definition: sims.cpp:951
void element_unrank_lint(long int rk, int *Elt, int verbose_level)
Definition: sims.cpp:1326
a strong generating set for a permutation group with respect to a fixed action
Definition: groups.h:1703
data_structures_groups::vector_ge * gens
Definition: groups.h:1708
to control the behavior of the poset classification algorithm
void initialize_and_allocate_root_node(poset_classification_control *PC_control, poset_with_group_action *Poset, int depth, int verbose_level)
int main(int t0, int schreier_depth, int f_use_invariant_subset_if_available, int f_debug, int verbose_level)
void stabilizer_order(int node, ring_theory::longinteger_object &go)
void orbit_length(int orbit_at_level, int level, ring_theory::longinteger_object &len)
void orbit_element_unrank(int depth, int orbit_idx, long int rank, long int *set, int verbose_level)
void coset_unrank(int depth, int orbit_idx, long int rank, int *Elt, int verbose_level)
long int coset_rank(int depth, int orbit_idx, int *Elt, int verbose_level)
void get_stabilizer_generators(groups::strong_generators *&gens, int level, int orbit_at_level, int verbose_level)
void orbit_element_rank(int depth, int &orbit_idx, long int &rank, long int *set, int verbose_level)
to represent one poset orbit; related to the class poset_classification
void get_stabilizer(poset_classification *PC, data_structures_groups::group_container &G, ring_theory::longinteger_object &go_G, int verbose_level)
void store_set_to(poset_classification *gen, int i, long int *to)
void init_subspace_lattice(actions::action *A, actions::action *A2, groups::strong_generators *Strong_gens, algebra::vector_space *VS, int verbose_level)
void add_testing_without_group(void(*func)(long int *S, int len, long int *candidates, int nb_candidates, long int *good_candidates, int &nb_good_candidates, void *data, int verbose_level), void *data, int verbose_level)
the polar space arising from an orthogonal geometry
Definition: tl_geometry.h:709
poset_classification::poset_classification_control * Control
Definition: tl_geometry.h:731
void init_group(int *group_generator_data, int group_generator_size, int f_group_order_target, const char *group_order_target, int verbose_level)
Definition: polar.cpp:117
void init(actions::action *A, orthogonal_geometry::orthogonal *O, int epsilon, int n, int k, field_theory::finite_field *F, int depth, int verbose_level)
Definition: polar.cpp:138
poset_classification::poset_with_group_action * Poset
Definition: tl_geometry.h:732
orthogonal_geometry::orthogonal * O
Definition: tl_geometry.h:724
void compute_cosets(int depth, int orbit_idx, int verbose_level)
Definition: polar.cpp:303
void dual_polar_graph(int depth, int orbit_idx, ring_theory::longinteger_object *&Rank_table, int &nb_maximals, int verbose_level)
Definition: polar.cpp:425
void init2(int depth, int verbose_level)
Definition: polar.cpp:180
void init_group_by_base_images(int *group_generator_data, int group_generator_size, int f_group_order_target, const char *group_order_target, int verbose_level)
Definition: polar.cpp:95
void list_whole_orbit(int depth, int orbit_idx, int f_limit, int limit)
Definition: polar.cpp:1170
void orbit_element_rank(int &orbit_idx, long int &rank, long int *set, int verbose_level)
Definition: polar.cpp:1153
void get_orbit_length(int orbit_idx, ring_theory::longinteger_object &length)
Definition: polar.cpp:1135
void show_stabilizer(int depth, int orbit_idx, int verbose_level)
Definition: polar.cpp:686
poset_classification::poset_classification * Gen
Definition: tl_geometry.h:733
void get_stabilizer(int orbit_idx, data_structures_groups::group_container &G, ring_theory::longinteger_object &go_G)
Definition: polar.cpp:1127
void compute_orbits(int t0, int verbose_level)
Definition: polar.cpp:269
void test_if_closed_under_cosets(int *S, int len, int *candidates, int nb_candidates, int *good_candidates, int &nb_good_candidates, int verbose_level)
Definition: polar.cpp:908
void orbit_element_unrank(int orbit_idx, long int rank, long int *set, int verbose_level)
Definition: polar.cpp:1146
void test_if_in_perp(long int *S, int len, long int *candidates, int nb_candidates, long int *good_candidates, int &nb_good_candidates, int verbose_level)
Definition: polar.cpp:851
#define FREE_int(p)
Definition: foundations.h:640
#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_vec_print_integer_matrix_width(A, B, C, D, E, F)
Definition: foundations.h:691
#define NEW_OBJECTS(type, n)
Definition: foundations.h:639
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define FREE_lint(p)
Definition: foundations.h:642
#define NEW_lint(n)
Definition: foundations.h:628
#define FREE_pint(p)
Definition: foundations.h:641
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects