Orbiter 2022
Combinatorial Objects
buekenhout_metz.cpp
Go to the documentation of this file.
1// buekenhout_metz.cpp
2//
3// Anton Betten
4// 12/13/2010
5//
6// creates Buekenhout Metz unitals in PG(2,q^2).
7//
8//
9
10#include "foundations.h"
11
12using namespace std;
13
14
15namespace orbiter {
16namespace layer1_foundations {
17namespace geometry {
18
19
20
22{
23 null();
24}
25
27{
28 freeself();
29}
30
32{
33 f_Uab = FALSE;
34 P2 = NULL;
35 P3 = NULL;
36 FQ = NULL;
37 Fq = NULL;
38 v = NULL;
39 w1 = w2 = w3 = w4 = w5 = NULL;
41 ovoid = NULL;
42 U = NULL;
43 f_is_Baer = NULL;
44 idx_in_unital = NULL;
45 idx_in_secants = NULL;
47 f_is_tangent_line = NULL;
48 point_of_tangency = NULL;
49 Intersection_sets = NULL;
50 Design_blocks = NULL;
51 secant_lines = NULL;
52 tangent_lines = NULL;
53 components = NULL;
54 embedding = NULL;
55 pair_embedding = NULL;
56 v = w1 = w2 = w3 = w4 = w5 = NULL;
57 U = NULL;
58 ovoid = NULL;
59 P2 = P3 = NULL;
60 good_points = NULL;
61}
62
64{
65 if (f_is_Baer) {
67 }
68 if (idx_in_unital) {
70 }
71 if (idx_in_secants) {
73 }
76 }
79 }
82 }
85 }
86 if (Design_blocks) {
88 }
89 if (secant_lines) {
91 }
92 if (tangent_lines) {
94 }
95 if (components) {
97 }
98 if (embedding) {
100 }
101 if (pair_embedding) {
103 }
104 if (v) {
105 FREE_int(v);
106 FREE_int(w1);
107 FREE_int(w2);
108 FREE_int(w3);
109 FREE_int(w4);
110 FREE_int(w5);
111 }
112 if (U) {
113 FREE_lint(U);
114 }
115 if (ovoid) {
117 }
118#if 0
119 if (FQ) {
121 }
122 if (Fq) {
124 }
125#endif
126 if (P2) {
128 }
129 if (P3) {
131 }
132 if (good_points) {
134 }
135 null();
136}
137
140 int f_Uab, int a, int b,
141 int f_classical, int verbose_level)
142// creates P2 over FQ and P3 over Fq, calls FQ->subfield_embedding_2dimensional
143{
144 int f_v = (verbose_level >= 1);
145 int i;
146
147 if (f_v) {
148 cout << "buekenhout_metz::init q=" << q << " Q=" << Q << endl;
149 }
154 if (Q != q * q) {
155 cout << "buekenhout_metz::init Q != q * q" << endl;
156 exit(1);
157 }
162 Q = q * q;
163
164 if (f_v) {
165 cout << "buekenhout_metz::init f_Uab=" << f_Uab << endl;
166 if (f_Uab) {
167 cout << "buekenhout_metz::init a=" << parameter_a << endl;
168 cout << "buekenhout_metz::init b=" << parameter_b << endl;
169 }
170 cout << "buekenhout_metz::init f_classical=" << f_classical << endl;
171 }
172
175
176
177 P2->projective_space_init(2, FQ, TRUE, verbose_level);
178 P3->projective_space_init(3, Fq, TRUE, verbose_level);
179
180
181
182
183 Fq->init_symbol_for_print("\\beta");
184
185 alpha = FQ->p;
186 T0 = FQ->negate(FQ->N2(alpha));
187 T1 = FQ->T2(alpha);
188
189 if (f_v) {
190 cout << "buekenhout_metz::init "
191 "before FQ->subfield_embedding_2dimensional" << endl;
192 }
194 components, embedding, pair_embedding, verbose_level - 2);
195
196 // we think of FQ as two dimensional vector space
197 // over Fq with basis (1,alpha)
198 // for i,j \in Fq, with x = i + j * alpha \in FQ, we have
199 // pair_embedding[i * q + j] = x;
200 // also,
201 // components[x * 2 + 0] = i;
202 // components[x * 2 + 1] = j;
203 // also, for i \in Fq, embedding[i] is the element
204 // in FQ that corresponds to i
205
206 // components[Q * 2]
207 // embedding[q]
208 // pair_embedding[q * q]
209
210 e1 = embedding[1];
211 one_1 = components[e1 * 2 + 0];
212 one_2 = components[e1 * 2 + 1];
213
214 if (f_v) {
217
218 cout << "embedding table:" << endl;
221
222
223 cout << "buekenhout_metz::init e1=" << e1 << " one_1=" << one_1
224 << " one_2=" << one_2 << endl;
225 }
226
227 for (i = 0; i < q; i++) {
228 if (embedding[i] == T0) {
229 t0 = i;
230 }
231 if (embedding[i] == T1) {
232 t1 = i;
233 }
234 }
235 minus_t0 = Fq->negate(t0);
236 if (f_v) {
237 cout << "buekenhout_metz::init t0=" << t0 << " t1=" << t1
238 << " minus_t0=" << minus_t0 << endl;
239 }
240
241
242 v = NEW_int(3);
243 w1 = NEW_int(6);
244 w2 = NEW_int(6);
245 w3 = NEW_int(6);
246 w4 = NEW_int(6);
247 w5 = NEW_int(6);
248 if (f_v) {
249 cout << "buekenhout_metz::init done" << endl;
250 }
251}
252
253void buekenhout_metz::init_ovoid(int verbose_level)
254{
255 int f_v = (verbose_level >= 1);
256 int f_vv = (verbose_level >= 2);
258
259 if (f_v) {
260 cout << "buekenhout_metz::init_ovoid" << endl;
261 }
262 int X0, X1, Y1, Z, a;
263 long int i;
264
265 theta_3 = Gg.nb_PG_elements(3, q);
267 sz_ovoid = 0;
268 for (i = 0; i < theta_3; i++) {
270 if (f_vv) {
271 cout << "testing point " << i << endl;
272 }
273 X0 = w1[0];
274 X1 = w1[1];
275 Y1 = w1[2];
276 Z = w1[3];
277 if (f_classical) {
278#if 1
279 // works in general:
280 // X0^2 + t1*X0*X1 - t0*X1^2 + t1*Y1*Z:
281 a = Fq->add4(
282 Fq->mult(X0, X0),
283 Fq->product3(t1, X0, X1),
284 Fq->product3(minus_t0, X1, X1),
285 Fq->product3(t1, Y1, Z)
286 );
287#else
288 // works only for GF(16):
289 // 3 * X0^2 + X1^2 + Y1*Z + X0*X1 + 3*X0*Z + X1*Z
290 a = Fq->add6(
291 Fq->mult(3, Fq->mult(X0, X0)),
292 Fq->mult(X1, X1),
293 Fq->mult(Y1, Z),
294 Fq->mult(X0, X1),
295 Fq->mult(3, Fq->mult(X0, Z)),
296 Fq->mult(X1, Z)
297 );
298#endif
299 }
300 else {
301 // works only for GF(16):
302 // 2 * X0^2 + X1^2 + Y1*Z + X0*X1 + 2*X0*Z + X1*Z
303 a = Fq->add6(
304 Fq->mult(2, Fq->mult(X0, X0)),
305 Fq->mult(X1, X1),
306 Fq->mult(Y1, Z),
307 Fq->mult(X0, X1),
308 Fq->mult(2, Fq->mult(X0, Z)),
309 Fq->mult(X1, Z)
310 );
311 }
312 if (a == 0) {
313 ovoid[sz_ovoid++] = i;
314 }
315 }
316 if (f_v) {
317 cout << "found an ovoid of size " << sz_ovoid << ":" << endl;
319 cout << endl;
320 }
321 if (f_vv) {
323 }
324
325 if (sz_ovoid != q * q + 1) {
326 cout << "we need the ovoid to be of size q * q + 1" << endl;
327 exit(1);
328 }
329}
330
332 int a, int b, int verbose_level)
333{
334 int f_v = (verbose_level >= 1);
335
336 if (f_v) {
337 cout << "buekenhout_metz::init_ovoid_Uab_even" << endl;
338 }
339
340 if (Fq->p != 2) {
341 cout << "buekenhout_metz::init_ovoid_Uab_even, "
342 "characteristic must be even" << endl;
343 exit(1);
344 }
345
346 int X0, X1, Y1, Z, i, aa;
347 int a1, a2, /*b1,*/ b2, delta, delta2;
348 int lambda, lambda_big, c1, c2, c3;
350
351 a1 = components[a * 2 + 0];
352 a2 = components[a * 2 + 1];
353 //b1 = components[b * 2 + 0]; // b1 is unused
354 b2 = components[b * 2 + 1];
355 delta = 2;
356 delta2 = FQ->mult(delta, delta);
357 lambda_big = FQ->add(delta, delta2);
358 lambda = 0;
359 for (i = 0; i < q; i++) {
360 if (embedding[i] == lambda_big) {
361 lambda = i;
362 break;
363 }
364 }
365 c1 = Fq->add(a2, b2);
366 c2 = b2;
367 c3 = Fq->add3(a1, a2, Fq->mult(Fq->add(a2, b2), lambda));
368 if (f_v) {
369 cout << "buekenhout_metz::init_ovoid_Uab_even" << endl;
370 cout << "delta=" << delta << endl;
371 cout << "delta2=" << delta2 << endl;
372 cout << "lambda_big=" << lambda_big << endl;
373 cout << "lambda=" << lambda << endl;
374 cout << "c1=" << c1 << endl;
375 cout << "c2=" << c2 << endl;
376 cout << "c3=" << c3 << endl;
377 }
378
379 theta_3 = Gg.nb_PG_elements(3, q);
381 sz_ovoid = 0;
382 for (i = 0; i < theta_3; i++) {
384 if (f_v) {
385 cout << "testing point " << i << endl;
386 }
387 X0 = w1[0];
388 X1 = w1[1];
389 Y1 = w1[2];
390 Z = w1[3];
391
392 aa = Fq->add4(
393 Fq->product3(c1, X0, X0),
394 Fq->product3(c2, X0, X1),
395 Fq->product3(c3, X1, X1),
396 Fq->mult(Y1, Z)
397 );
398
399
400
401 if (aa == 0) {
402 ovoid[sz_ovoid++] = i;
403 }
404 }
405 cout << "found an ovoid of size " << sz_ovoid << ":" << endl;
407 cout << endl;
409
410 if (sz_ovoid != q * q + 1) {
411 cout << "we need the ovoid to be of size q * q + 1" << endl;
412 exit(1);
413 }
414}
415
416void buekenhout_metz::create_unital(int verbose_level)
417{
418 int f_v = (verbose_level >= 1);
419 int f_vv = (verbose_level >= 3);
420 int f_vvv = (verbose_level >= 4);
421 int i, j, a, c1, c2, h;
422 long int b;
423
424 if (f_v) {
425 cout << "buekenhout_metz::create_unital" << endl;
426 }
427
428 w1[0] = 0;
429 w1[1] = 0;
430 w1[2] = 1;
431 w1[3] = 0;
432 w1[4] = 0;
433
434 if (f_v) {
435 cout << "The vertex is:" << endl;
436 Int_vec_print(cout, w1, 5);
437 cout << endl;
438 }
439
440 U = NEW_lint(q * q * q + 1);
441 sz = 0;
442 for (i = 1; i < q * q + 1; i++) {
443 a = ovoid[i];
444 P3->unrank_point(w2, a);
445 if (f_vv) {
446 cout << i << "-th ovoidal point is " << a << " : ";
447 Int_vec_print(cout, w2, 4);
448 cout << endl;
449 }
450
451 if (w2[3] != 1) {
452 cout << "we need the Z coordinate to be one" << endl;
453 exit(1);
454 }
455
456 // Now, w2[4] is a point of the ovoid in PG(3,q)
457 // We will now create the generator in PG(4,q)
458 // This is just the line that joins the vertex to this point.
459
460 w3[0] = w2[0];
461 w3[1] = w2[1];
462 w3[2] = 0;
463 w3[3] = w2[2];
464 w3[4] = w2[3];
465 if (f_vv) {
466 cout << "after embedding:" << endl;
467 Int_vec_print(cout, w3, 5);
468 cout << endl;
469 }
470
471 for (j = 0; j < q; j++) {
472 if (f_vvv) {
473 cout << "j=" << j << " : ";
474 }
475 for (h = 0; h < 5; h++) {
476 w4[h] = Fq->mult(j, w1[h]);
477 }
478 if (f_vvv) {
479 cout << "w4:" << endl;
480 Int_vec_print(cout, w4, 5);
481 cout << endl;
482 }
483
484 for (h = 0; h < 5; h++) {
485 w5[h] = Fq->add(w4[h], w3[h]);
486 }
487 w5[5] = 0;
488 if (f_vvv) {
489 cout << "w5 (with added 0):" << endl;
490 Int_vec_print(cout, w5, 6);
491 cout << endl;
492 }
493
494
495
496 for (h = 0; h < 3; h++) {
497 c1 = w5[2 * h + 0];
498 c2 = w5[2 * h + 1];
499 v[h] = pair_embedding[c1 * q + c2];
500 }
501
502 if (f_vvv) {
503 cout << " : ";
504 Int_vec_print(cout, v, 3);
505 //cout << endl;
506 }
507
508 b = P2->rank_point(v);
509
510 if (f_vvv) {
511 cout << " : " << b << endl;
512 }
513 U[sz++] = b;
514 }
515 }
516
517 // the unique point (0,1,0) at infinity:
518 v[0] = 0;
519 v[1] = 1;
520 v[2] = 0;
521 b = P2->rank_point(v);
522 U[sz++] = b;
523
524 if (f_v) {
525 cout << "the Buekenhout Metz unital of size " << sz << " : ";
526 Lint_vec_print(cout, U, sz);
527 cout << endl;
528
529 for (i = 0; i < sz; i++) {
530 cout << U[i] << " ";
531 }
532 cout << endl;
533 P2->print_set(U, sz);
534 }
535
536
537}
538
540{
541 int f_v = (verbose_level >= 1);
542 //int f_vv = (verbose_level >= 3);
543 int i, j, a, /*b,*/ c1, c2, h;
544 string symbol;
545
546 if (f_v) {
547 cout << "buekenhout_metz::create_unital_tex" << endl;
548 }
549
550 symbol.assign("\\beta");
551
552 w1[0] = 0;
553 w1[1] = 0;
554 w1[2] = 1;
555 w1[3] = 0;
556 w1[4] = 0;
557
558
559 //cout << "The vertex is:" << endl;
560 //int_vec_print(cout, w1, 5);
561 //cout << endl;
562
563 //U = NEW_int(q * q * q + 1);
564 //sz = 0;
565 for (i = 1; i < q * q + 1; i++) {
566 a = ovoid[i];
567 P3->unrank_point(w2, a);
568 if (FALSE) {
569 cout << i << "-th ovoidal point is " << a << " : ";
570 Int_vec_print(cout, w2, 4);
571 cout << endl;
572 }
573
574 if (w2[3] != 1) {
575 cout << "we need the Z coordinate to be one" << endl;
576 exit(1);
577 }
578
579 w3[0] = w2[0];
580 w3[1] = w2[1];
581 w3[2] = 0;
582 w3[3] = w2[2];
583 w3[4] = w2[3];
584 if (FALSE) {
585 cout << "after embedding:" << endl;
586 Int_vec_print(cout, w3, 5);
587 cout << endl;
588 }
589 cout << "(";
591 TRUE /* f_exponential */, 8, symbol);
592 cout << ",";
594 TRUE /* f_exponential */, 8, symbol);
595 cout << ",*,";
597 TRUE /* f_exponential */, 8, symbol);
598 cout << ",";
600 TRUE /* f_exponential */, 8, symbol);
601 cout << ") ";
602
603
604 for (j = 0; j < q; j++) {
605 cout << " & ";
606 if (FALSE) {
607 cout << "j=" << j << " : ";
608 }
609 for (h = 0; h < 5; h++) {
610 w4[h] = Fq->mult(j, w1[h]);
611 }
612 if (FALSE) {
613 cout << "w4:" << endl;
614 Int_vec_print(cout, w4, 5);
615 cout << endl;
616 }
617
618 for (h = 0; h < 5; h++) {
619 w5[h] = Fq->add(w4[h], w3[h]);
620 }
621 w5[5] = 0;
622 if (FALSE) {
623 cout << "w5 (with added 0):" << endl;
624 Int_vec_print(cout, w5, 6);
625 cout << endl;
626 }
627
628
629
630 for (h = 0; h < 3; h++) {
631 c1 = w5[2 * h + 0];
632 c2 = w5[2 * h + 1];
633 v[h] = pair_embedding[c1 * q + c2];
634 }
635
636 if (FALSE) {
637 cout << " : ";
638 Int_vec_print(cout, v, 3);
639 //cout << endl;
640 }
642
643#if 0
644 cout << "(";
646 TRUE /* f_exponential */, 8, "\\alpha");
647 cout << ",";
649 TRUE /* f_exponential */, 8, "\\alpha");
650 cout << ",";
652 TRUE /* f_exponential */, 8, "\\alpha");
653 cout << ") ";
654#endif
655
656#if 0
657 int rk;
658
659 rk = P2->rank_point(v);
660
661 //cout << rk << " ";
662
663 int x, y, t1, t2, t3;
664 x = v[0];
665 t1 = FQ->mult(parameter_a, FQ->mult(x, x));
666 t2 = FQ->mult(parameter_b, FQ->power(x, q + 1));
667 t3 = embedding[j];
668 y = FQ->add3(
669 t1,
670 t2,
671 t3
672 );
673 if (y != v[1]) {
674 cout << "y != v[1]" << endl;
675 cout << "y = ";
677 TRUE /* f_exponential */, 8, "\\alpha");
678 cout << endl;
679 cout << "a*x^2 = ";
681 TRUE /* f_exponential */, 8, "\\alpha");
682 cout << endl;
683 cout << "b*x^(q+1) = ";
685 TRUE /* f_exponential */, 8, "\\alpha");
686 cout << endl;
687 cout << "r = ";
689 TRUE /* f_exponential */, 8, "\\alpha");
690 cout << endl;
691 //exit(1);
692 }
694 TRUE /* f_exponential */, 8, "\\alpha");
695
696 b = P2->rank_point(v);
697#endif
698 }
699
700 cout << "\\\\" << endl;
701 }
702}
703
705{
706 int f_v = (verbose_level >= 1);
707 //int f_vv = (verbose_level >= 3);
708 int i, r, x, y;
709 string symbol;
710
711 if (f_v) {
712 cout << "buekenhout_metz::create_unital_Uab_tex" << endl;
713 }
714
715 symbol.assign("\\beta");
716
717 for (r = 0; r < q; r++) {
718 cout << " & ";
720 TRUE /* f_exponential */, 8, symbol);
721 }
722 cout << "\\\\" << endl;
723 cout << "\\hline" << endl;
724 for (i = 0; i < q * q; i++) {
725
726 if (i == 0) {
727 x = 0;
728 }
729 else {
730 x = FQ->alpha_power(i - 1);
731 }
733 TRUE /* f_exponential */, 8, symbol);
734
735 for (r = 0; r < q; r++) {
736 cout << " & ";
737
738 int t1, t2, t3;
739
740 t1 = FQ->mult(parameter_a, FQ->mult(x, x));
741 t2 = FQ->mult(parameter_b, FQ->power(x, q + 1));
742 t3 = embedding[r];
743 y = FQ->add3(
744 t1,
745 t2,
746 t3
747 );
748
749 v[0] = x;
750 v[1] = y;
751 v[2] = 1;
752
753
755#if 0
756 cout << "(";
758 TRUE /* f_exponential */, 8, "\\alpha");
759 cout << ",";
761 TRUE /* f_exponential */, 8, "\\alpha");
762 cout << ",";
764 TRUE /* f_exponential */, 8, "\\alpha");
765 cout << ") ";
766#endif
767
768
769 int rk;
770
771 rk = P2->rank_point(v);
772
773 cout << " = P_{" << rk << "} ";
774
775#if 0
776 if (y != v[1]) {
777 cout << "y != v[1]" << endl;
778 cout << "y = ";
780 TRUE /* f_exponential */, 8, "\\alpha");
781 cout << endl;
782 cout << "a*x^2 = ";
784 TRUE /* f_exponential */, 8, "\\alpha");
785 cout << endl;
786 cout << "b*x^(q+1) = ";
788 TRUE /* f_exponential */, 8, "\\alpha");
789 cout << endl;
790 cout << "r = ";
792 TRUE /* f_exponential */, 8, "\\alpha");
793 cout << endl;
794 //exit(1);
795 }
796#endif
797 //FQ->print_element_with_symbol(cout, y,
798 // TRUE /* f_exponential */, 8, "\\alpha");
799
800 }
801
802 cout << "\\\\" << endl;
803 }
804}
805
807{
808 int f_v = (verbose_level >= 1);
809 int f_vv = (verbose_level >= 2);
810 int i, j, h, a, b;
812
813 if (f_v) {
814 cout << "buekenhout_metz::compute_the_design" << endl;
815 }
816
817
820 block = NEW_lint(q + 1);
821
822
823 P2->find_k_secant_lines(U, sz, q + 1,
824 secant_lines, nb_secant_lines, verbose_level - 1);
825
826 if (f_vv) {
827 cout << "There are " << nb_secant_lines
828 << " secant lines, they are:" << endl;
830 cout << endl;
831 }
832
834 tangent_lines, nb_tangent_lines, verbose_level - 1);
835
836 if (f_vv) {
837 cout << "There are " << nb_tangent_lines
838 << " tangent lines, they are:" << endl;
840 cout << endl;
841 }
842
843
844
848 for (i = 0; i < P2->N_points; i++) {
849 tangent_line_at_point[i] = -1;
850 }
851 for (i = 0; i < P2->N_lines; i++) {
853 point_of_tangency[i] = -1;
854 }
855 for (h = 0; h < nb_tangent_lines; h++) {
856 a = tangent_lines[h];
859 a /* line_rk */, block, block_size,
860 0 /* verbose_level*/);
861 //Sorting.int_vec_intersect(P2->Lines + a * P2->k, P2->k,
862 // U, sz, block, block_size);
863 if (block_size != 1) {
864 cout << "block_size != 1" << endl;
865 exit(1);
866 }
867 b = block[0];
868 if (f_vv) {
869 cout << "line " << a << " is tangent at point " << b << endl;
870 }
872 point_of_tangency[a] = b;
873 }
874 for (b = 0; b < P2->N_points; b++) {
875 if (tangent_line_at_point[b] == -1) {
876 continue;
877 }
878 if (f_vv) {
879 cout << "The tangent line at point " << b
880 << " is line " << tangent_line_at_point[b] << endl;
881 }
882 }
883
886 for (i = 0; i < P2->N_points; i++) {
887 idx_in_unital[i] = -1;
888 }
889 for (i = 0; i < P2->N_lines; i++) {
890 idx_in_secants[i] = -1;
891 }
892 for (i = 0; i < sz; i++) {
893 a = U[i];
894 idx_in_unital[a] = i;
895 }
896 for (i = 0; i < nb_secant_lines; i++) {
897 a = secant_lines[i];
898 idx_in_secants[a] = i;
899 }
900
903
904 for (h = 0; h < nb_secant_lines; h++) {
905 a = secant_lines[h];
907 a /* line_rk */, block, block_size,
908 0 /* verbose_level*/);
909 //Sorting.int_vec_intersect(P2->Lines + a * P2->k,
910 // P2->k, U, sz, block, block_size);
911 if (block_size != q + 1) {
912 cout << "block_size != q + 1" << endl;
913 exit(1);
914 }
915 for (j = 0; j < q + 1; j++) {
916 b = idx_in_unital[block[j]];
917 if (b == -1) {
918 cout << "b == -1" << endl;
919 exit(1);
920 }
921 Intersection_sets[h * (q + 1) + j] = block[j];
922 Design_blocks[h * (q + 1) + j] = b;
923 }
924 }
925
926 if (f_vv) {
927 cout << "The blocks of the design are:" << endl;
929 nb_secant_lines, q + 1, q + 1, 3);
930 }
931
932
934 for (j = 0; j < nb_secant_lines; j++) {
936 Intersection_sets + j * (q + 1), q + 1,
937 0 /*verbose_level - 1*/);
938 }
939
940 if (f_vv) {
941 cout << "The intersection sets are:" << endl;
942 cout << "i : line(i) : block(i) : is Baer" << endl;
943 for (i = 0; i < nb_secant_lines; i++) {
944 cout << setw(3) << i << " : ";
945 cout << setw(3) << secant_lines[i] << " : ";
946 Lint_vec_print(cout, Intersection_sets + i * (q + 1), q + 1);
947 cout << " : ";
948 cout << setw(3) << f_is_Baer[i] << endl;
949 }
950 }
951}
952
953#if 0
954void buekenhout_metz::compute_automorphism_group(int verbose_level)
955{
956 int f_v = (verbose_level >= 1);
957
958 if (f_v) {
959 cout << "buekenhout_metz::compute_automorphism_group" << endl;
960 cout << "computing the automorphism group of the design:" << endl;
961 }
962
963
964
965 A = create_automorphism_group_of_block_system(
966 sz /* nb_points */, nb_secant_lines /* nb_blocks */,
967 q + 1 /* block_size */,
968 Design_blocks /* Blocks */,
969 verbose_level - 2);
970 A->group_order(ago);
971
972 if (f_v) {
973 cout << "The automorphism group of the design "
974 "has order " << ago << endl;
975 }
976
977 if (f_v) {
978 cout << "Computing the automorphism group again" << endl;
979 }
980
981
982
983 get_name(fname_stab);
984 strcat(fname_stab, "_stab.txt");
985
986 if (file_size(fname_stab) <= 0) {
987
988 if (f_v) {
989 cout << "file " << fname_stab << " does not exist, "
990 "we will now compute the stabilizer" << endl;
991 }
992 S = create_sims_for_stabilizer(P2->A, U, sz, verbose_level - 1);
993 S->write_sgs(fname_stab, verbose_level - 1);
994 }
995 else {
996 vector_ge *SG;
997
998 if (f_v) {
999 cout << "file " << fname_stab << " exists, we will "
1000 "now read the stabilizer from file" << endl;
1001 }
1002 S = NEW_OBJECT(sims);
1003 S->init(P2->A);
1004 SG = NEW_OBJECT(vector_ge);
1005 S->read_sgs(fname_stab, SG, verbose_level);
1006 FREE_OBJECT(SG);
1007 }
1008
1009 S->group_order(ago2);
1010
1011 if (f_v) {
1012 cout << "The stabilizer of the unital has order " << ago2 << endl;
1013 }
1014
1015
1016 gens = NEW_OBJECT(vector_ge);
1017 tl = NEW_int(P2->A->base_len);
1018 S->extract_strong_generators_in_order(*gens, tl, verbose_level);
1019
1020 if (f_v) {
1021 cout << "strong generators for the stabilizer are:" << endl;
1022 gens->print(cout);
1023
1024 S->print_generators_tex(cout);
1025 }
1026}
1027
1028
1029void buekenhout_metz::compute_orbits(int verbose_level)
1030// Computes the orbits on points and on lines,
1031// then calls investigate_line_orbit for all line orbits
1032{
1033 int f_v = (verbose_level >= 1);
1034 int h;
1035
1036
1037 if (f_v) {
1038 cout << "buekenhout_metz::compute_orbits" << endl;
1039 cout << "computing orbits on points and on lines:" << endl;
1040 }
1041
1042
1043 Orb = NEW_OBJECT(schreier);
1044 Orb->init(P2->A);
1045 Orb->init_generators(*gens);
1046 Orb->compute_all_point_orbits(verbose_level - 2);
1047 if (f_v) {
1048 cout << "Orbits on points:" << endl;
1049 Orb->print_and_list_orbits(cout);
1050 }
1051
1052
1053 Orb2 = NEW_OBJECT(schreier);
1054 Orb2->init(P2->A2);
1055 Orb2->init_generators(*gens);
1056
1057 if (f_prefered_line_reps) {
1058 Orb2->compute_all_point_orbits_with_prefered_reps(
1059 prefered_line_reps, nb_prefered_line_reps, verbose_level - 2);
1060 }
1061 else {
1062 Orb2->compute_all_point_orbits(verbose_level - 2);
1063 }
1064 if (f_v) {
1065 cout << "Orbits on lines:" << endl;
1066 Orb2->print_and_list_orbits(cout);
1067 }
1068
1069
1070 for (h = 0; h < Orb2->nb_orbits; h++) {
1071
1072 if (f_v) {
1073 cout << "buekenhout_metz::compute_orbits "
1074 "before investigate_line_orbit " << h << endl;
1075 }
1076
1077 investigate_line_orbit(h, verbose_level);
1078
1079 if (f_v) {
1080 cout << "buekenhout_metz::compute_orbits "
1081 "after investigate_line_orbit " << h << endl;
1082 }
1083 }
1084
1085
1086}
1087
1088void buekenhout_metz::investigate_line_orbit(int h, int verbose_level)
1089// Investigates a secant line orbit
1090// We compute the stabilizer of the secant line.
1091// We compute the orbits of the stabilizer
1092// on pairs of points from the block.
1093// Let (PP1,PP2) be a pair
1094// Let (T1,T2) be the corresponding tangent lines
1095// Let Q be the intersection point of T1 and T2
1096// Let T1_set be the tangent lines on Q that do not pass through PP1 or PP2
1097// Finally, we compute the stabilizer of T1_set in the stabilizer of the pair.
1098// This is done in a rather crude way, namely by testing each group element.
1099{
1100 int f_v = (verbose_level >= 1);
1101 int f_vv = (verbose_level >= 2);
1102 int u;
1103
1104 if (f_v) {
1105 cout << "buekenhout_metz::investigate_line_orbit" << endl;
1106 }
1107 longinteger_object stab_order;
1108 int the_line;
1109 int idx, f_hit_favorite;
1110 int PP1, PP2, T1, T2, T, Q, PP, vv;
1111
1112
1113 the_line = Orb2->orbit[Orb2->orbit_first[h]];
1114
1115
1116 // make sure the line is a secant line:
1117 if (!int_vec_search_linear(secant_lines,
1118 nb_secant_lines, the_line, idx)) {
1119 if (f_v) {
1120 cout << "line-orbit " << h << " represented by line "
1121 << the_line << " does not consist of "
1122 "secant lines, skip" << endl;
1123 }
1124 return;
1125 }
1126
1127
1128
1129 if (f_v) {
1130 cout << "looking at secant line-orbit " << h
1131 << " represented by line " << the_line << ":" << endl;
1132 }
1133
1134
1135 int_vec_intersect(P2->Lines + the_line * P2->k,
1137
1138 if (f_v) {
1139 cout << "the block is ";
1140 int_vec_print(cout, good_points, nb_good_points);
1141 cout << endl;
1142 }
1143
1144 if (nb_good_points != q + 1) {
1145 cout << "nb_good_points != q + 1" << endl;
1146 exit(1);
1147 }
1148
1149 Orb2->point_stabilizer(P2->A /* default_action */, ago2,
1150 Stab, h /* orbit_no */, verbose_level);
1151
1152 Stab->group_order(stab_order);
1153 if (f_v) {
1154 cout << "stabilizer of orbit " << h
1155 << " has order " << stab_order << endl;
1156 }
1157
1158
1159 if (f_vv) {
1160 cout << "the stabilizer is generated by" << endl;
1161 Stab->print_generators();
1162 }
1163
1164 C = NEW_OBJECT(choose_points_or_lines);
1165
1166
1167 C->init("pairs", this /*void *data*/,
1168 P2->A, P2->A2,
1169 FALSE /* f_choose_lines */,
1170 2 /*nb_points_or_lines */,
1171 buekenhout_metz_check_good_points,
1172 t0,
1173 verbose_level - 1);
1174
1175 if (f_v) {
1176 cout << "computing orbits" << endl;
1177 }
1178 C->compute_orbits_from_sims(Stab, verbose_level - 1);
1179
1180 if (f_v) {
1181 cout << "We found " << C->nb_orbits
1182 << " orbits on 2-subsets" << endl;
1183 cout << "They are:" << endl;
1184 }
1185 for (u = 0; u < C->nb_orbits; u++) {
1186
1187 if (f_v) {
1188 cout << "choosing orbit rep " << u << endl;
1189 }
1190
1191 C->choose_orbit(u, f_hit_favorite, verbose_level);
1192
1193 if (f_v) {
1194 cout << "orbit rep " << u << " is" << endl;
1195 C->print_rep();
1196 cout << endl;
1197 }
1198#if 0
1199 if (f_vv) {
1200 cout << "with stabilizer tl=";
1201 int_vec_print(cout, C->stab_tl, C->A->base_len);
1202 cout << endl;
1203 cout << "generated by" << endl;
1204 C->stab_gens->print(cout);
1205 }
1206#endif
1207
1208
1209 PP1 = C->representative[0];
1210 PP2 = C->representative[1];
1212 T2 = tangent_line_at_point[PP2];
1213 Q = P2->line_intersection(T1, T2);
1214
1215 if (f_v) {
1216 cout << "P1=" << PP1 << " P2=" << PP2
1217 << " T1=" << T1 << " T2=" << T2 << " Q=" << Q << endl;
1218 }
1219
1220
1221
1222 int *T1_set;
1223 int T1_set_size;
1224
1225 T1_set = NEW_int(q + 1);
1226 T1_set_size = 0;
1227
1228 t1 = 0;
1229 for (vv = 0; vv < P2->r; vv++) {
1230 T = P2->Lines_on_point[Q * P2->r + vv];
1231 if (!f_is_tangent_line[T]) {
1232 continue;
1233 }
1234 PP = P2->line_intersection(T, the_line);
1235 if (PP == PP1 || PP == PP2) {
1236 }
1237 else {
1238 T1_set[T1_set_size++] = T;
1239 }
1240 if (int_vec_search_linear(good_points,
1241 nb_good_points, PP, idx)) {
1242 if (f_v) {
1243 cout << vv << "-th line " << T << " on Q is "
1244 "tangent line and intersects in "
1245 "good point " << PP << endl;
1246 }
1247 t1++;
1248 }
1249 else {
1250 if (f_v) {
1251 cout << vv << "-th line " << T << " on Q "
1252 "is tangent line and its point of tangency "
1253 "is " << point_of_tangency[T]
1254 << " which is not a good point" << endl;
1255 }
1256 }
1257 }
1258 if (f_v) {
1259 cout << "t1=" << t1 << endl;
1260 cout << "T1_set = ";
1261 int_vec_print(cout, T1_set, T1_set_size);
1262 cout << endl;
1263 }
1264
1265 longinteger_object go;
1266 int *Elt;
1267 int goi, go1, ii;
1268 sims *Stab0;
1269
1270 Stab0 = create_sims_from_generators_with_target_group_order_factorized(
1271 P2->A,
1272 C->Stab_Strong_gens->gens,
1273 C->Stab_Strong_gens->tl,
1274 P2->A->base_len,
1275 verbose_level - 2);
1276 if (f_v) {
1277 cout << "computing stabilizer of the line set" << endl;
1278 Stab0->group_order(go);
1279 cout << "in a group of order " << go << endl;
1280 }
1281 goi = go.as_int();
1282 go1 = 0;
1283 Elt = NEW_int(P2->A->elt_size_in_int);
1284
1285 for (ii = 0; ii < goi; ii++) {
1286 Stab0->element_unrank_int(ii, Elt);
1287 if (P2->A2->check_if_in_set_stabilizer(Elt,
1288 T1_set_size, T1_set, 0 /*verbose_level*/)) {
1289 if (f_vv) {
1290 cout << "element " << ii << " stabilizes the set" << endl;
1291 P2->A2->element_print_as_permutation(Elt, cout);
1292 cout << endl;
1293 }
1294 go1++;
1295 }
1296 }
1297 if (f_v) {
1298 cout << "stabilizer order " << go1 << endl;
1299 }
1300 FREE_int(Elt);
1301
1302#if 0
1303 int i;
1304 cout << "computing stabilizer using set stabilizer routine:" << endl;
1305 sims *T1_set_stab;
1306 T1_set_stab = create_sims_for_stabilizer_with_input_group(P2->A2,
1307 P2->A, C->stab_gens, C->stab_tl,
1308 T1_set, T1_set_size, verbose_level - 3);
1309 T1_set_stab->group_order(go);
1310 cout << "stabilizer order " << go << endl;
1311
1312 vector_ge *set_stab_gens;
1313 int *set_stab_tl;
1314
1315 set_stab_gens = NEW_OBJECT(vector_ge);
1316 set_stab_tl = NEW_int(P2->A->base_len);
1317 T1_set_stab->extract_strong_generators_in_order(
1318 *set_stab_gens, set_stab_tl, 0/*verbose_level*/);
1319 cout << "strong generators are:" << endl;
1320 for (i = 0; i < set_stab_gens->len; i++) {
1321 P2->A->element_print_quick(set_stab_gens->ith(i), cout);
1322 cout << endl;
1323 }
1324 FREE_OBJECT(T1_set_stab);
1325#endif
1326 } // next u
1327}
1328#endif
1329
1330
1332{
1333 string fname_unital;
1335
1336 get_name(fname_unital);
1337 fname_unital.append(".txt");
1338 Fio.write_set_to_file(fname_unital, U, sz, 0 /* verbose_level */);
1339 cout << "written file " << fname_unital << " of size "
1340 << Fio.file_size(fname_unital) << endl;
1341}
1342
1343
1344void buekenhout_metz::get_name(std::string &name)
1345{
1346 char str[1000];
1347
1348 if (f_Uab) {
1349 sprintf(str, "U_%d_%d_%d", parameter_a, parameter_b, q);
1350 }
1351 else {
1352 if (f_classical) {
1353 sprintf(str, "H%d", q);
1354 }
1355 else {
1356 sprintf(str, "BM%d", q);
1357 }
1358 }
1359 name.assign(str);
1360}
1361
1362#if 0
1363int buekenhout_metz_check_good_points(int len,
1364 int *S, void *data, int verbose_level)
1365// used in buekenhout_metz::investigate_line_orbit
1366{
1367 int i, a, idx;
1368 int f_v = FALSE;
1369 buekenhout_metz *BM = (buekenhout_metz *) data;
1370 sorting Sorting;
1371
1372 if (f_v) {
1373 cout << "buekenhout_metz_check_good_points checking the set ";
1374 Orbiter->Int_vec.print(cout, S, len);
1375 cout << endl;
1376 }
1377 for (i = 0; i < len; i++) {
1378 a = S[i];
1379 if (!Sorting.int_vec_search_linear(BM->good_points,
1380 BM->nb_good_points, a, idx)) {
1381 if (f_v) {
1382 cout << "The set is rejected" << endl;
1383 }
1384 return FALSE;
1385 }
1386 }
1387 if (f_v) {
1388 cout << "The set is accepted" << endl;
1389 }
1390 return TRUE;
1391}
1392#endif
1393
1394}}}
1395
1396
1397
void print(std::ostream &ost, std::vector< int > &v)
Definition: int_vec.cpp:413
a collection of functions related to sorted vectors
void print_embedding_tex(finite_field &subfield, int *components, int *embedding, int *pair_embedding)
void print_element_with_symbol(std::ostream &ost, int a, int f_exponential, int width, std::string &symbol)
void PG_element_unrank_modified(int *v, int stride, int len, int a)
void int_vec_print_field_elements(std::ostream &ost, int *v, int len)
void subfield_embedding_2dimensional(finite_field &subfield, int *&components, int *&embedding, int *&pair_embedding, int verbose_level)
void print_embedding(finite_field &subfield, int *components, int *embedding, int *pair_embedding)
int add6(int i1, int i2, int i3, int i4, int i5, int i6)
void init_ovoid_Uab_even(int a, int b, int verbose_level)
void init(field_theory::finite_field *Fq, field_theory::finite_field *FQ, int f_Uab, int a, int b, int f_classical, int verbose_level)
various functions related to geometries
Definition: geometry.h:721
projective space PG(n,q) of dimension n over Fq
Definition: geometry.h:1916
void find_k_secant_lines(long int *set, int set_size, int k, long int *secant_lines, int &nb_secant_lines, int verbose_level)
void line_intersection(int line_rank, long int *set, int set_size, std::vector< int > &point_indices, int verbose_level)
int is_contained_in_Baer_subline(long int *pts, int nb_pts, int verbose_level)
void intersect_with_line(long int *set, int set_sz, int line_rk, long int *intersection, int &sz, int verbose_level)
void projective_space_init(int n, field_theory::finite_field *F, int f_init_incidence_structure, int verbose_level)
void write_set_to_file(std::string &fname, long int *the_set, int set_size, int verbose_level)
Definition: file_io.cpp:2434
#define FREE_int(p)
Definition: foundations.h:640
#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 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 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