Orbiter 2022
Combinatorial Objects
arc_basic.cpp
Go to the documentation of this file.
1/*
2 * arc_basic.cpp
3 *
4 * Created on: Nov 26, 2021
5 * Author: betten
6 */
7
8
9
10
11#include "foundations.h"
12
13
14using namespace std;
15
16
17
18namespace orbiter {
19namespace layer1_foundations {
20namespace geometry {
21
22
24{
25 F = NULL;
26
27}
28
30{
31
32}
33
35{
36 int f_v = (verbose_level >= 1);
37
38 if (f_v) {
39 cout << "arc_basic::init" << endl;
40 }
41
43
44 if (f_v) {
45 cout << "arc_basic::init done" << endl;
46 }
47}
48
50 long int *&Pts, int &nb_pts, int verbose_level)
51{
52 int f_v = (verbose_level >= 1);
53 int N = F->q + 2;
54 int i, t, a, t6;
55 int *Mtx;
56
57 if (f_v) {
58 cout << "arc_basic::Segre_hyperoval q=" << F->q << endl;
59 }
60 if (EVEN(F->e)) {
61 cout << "arc_basic::Segre_hyperoval needs e odd" << endl;
62 exit(1);
63 }
64
65 nb_pts = N;
66
67 Pts = NEW_lint(N);
68 Mtx = NEW_int(N * 3);
69 Int_vec_zero(Mtx, N * 3);
70 for (t = 0; t < F->q; t++) {
71 t6 = F->power(t, 6);
72 Mtx[t * 3 + 0] = 1;
73 Mtx[t * 3 + 1] = t;
74 Mtx[t * 3 + 2] = t6;
75 }
76 t = F->q;
77 Mtx[t * 3 + 0] = 0;
78 Mtx[t * 3 + 1] = 1;
79 Mtx[t * 3 + 2] = 0;
80 t = F->q + 1;
81 Mtx[t * 3 + 0] = 0;
82 Mtx[t * 3 + 1] = 0;
83 Mtx[t * 3 + 2] = 1;
84 for (i = 0; i < N; i++) {
85 F->PG_element_rank_modified(Mtx + i * 3, 1, 3, a);
86 Pts[i] = a;
87 }
88
89 FREE_int(Mtx);
90 if (f_v) {
91 cout << "arc_basic::Segre_hyperoval "
92 "q=" << F->q << " done" << endl;
93 }
94}
95
96
98 long int *&Pts, int &nb_pts, int verbose_level)
99{
100 int f_v = (verbose_level >= 1);
101 int N = F->q + 2;
102 int i, t, te, a;
103 int sigma, gamma = 0, Sigma, /*Gamma,*/ exponent;
104 int *Mtx;
106
107 if (f_v) {
108 cout << "arc_basic::GlynnI_hyperoval q=" << F->q << endl;
109 }
110 if (EVEN(F->e)) {
111 cout << "arc_basic::GlynnI_hyperoval needs e odd" << endl;
112 exit(1);
113 }
114
115 sigma = F->e - 1;
116 for (i = 0; i < F->e; i++) {
117 if (((i * i) % F->e) == sigma) {
118 gamma = i;
119 break;
120 }
121 }
122 if (i == F->e) {
123 cout << "arc_basic::GlynnI_hyperoval "
124 "did not find gamma" << endl;
125 exit(1);
126 }
127
128 cout << "arc_basic::GlynnI_hyperoval sigma = " << sigma
129 << " gamma = " << gamma << endl;
130 //Gamma = i_power_j(2, gamma);
131 Sigma = NT.i_power_j(2, sigma);
132
133 exponent = 3 * Sigma + 4;
134
135 nb_pts = N;
136
137 Pts = NEW_lint(N);
138 Mtx = NEW_int(N * 3);
139 Int_vec_zero(Mtx, N * 3);
140 for (t = 0; t < F->q; t++) {
141 te = F->power(t, exponent);
142 Mtx[t * 3 + 0] = 1;
143 Mtx[t * 3 + 1] = t;
144 Mtx[t * 3 + 2] = te;
145 }
146 t = F->q;
147 Mtx[t * 3 + 0] = 0;
148 Mtx[t * 3 + 1] = 1;
149 Mtx[t * 3 + 2] = 0;
150 t = F->q + 1;
151 Mtx[t * 3 + 0] = 0;
152 Mtx[t * 3 + 1] = 0;
153 Mtx[t * 3 + 2] = 1;
154 for (i = 0; i < N; i++) {
155 F->PG_element_rank_modified(Mtx + i * 3, 1, 3, a);
156 Pts[i] = a;
157 }
158
159 FREE_int(Mtx);
160 if (f_v) {
161 cout << "arc_basic::GlynnI_hyperoval "
162 "q=" << F->q << " done" << endl;
163 }
164}
165
167 long int *&Pts, int &nb_pts, int verbose_level)
168{
169 int f_v = (verbose_level >= 1);
170 int N = F->q + 2;
171 int i, t, te, a;
172 int sigma, gamma = 0, Sigma, Gamma, exponent;
173 int *Mtx;
175
176 if (f_v) {
177 cout << "arc_basic::GlynnII_hyperoval q=" << F->q << endl;
178 }
179 if (EVEN(F->e)) {
180 cout << "arc_basic::GlynnII_hyperoval "
181 "needs e odd" << endl;
182 exit(1);
183 }
184
185 sigma = F->e - 1;
186 for (i = 0; i < F->e; i++) {
187 if (((i * i) % F->e) == sigma) {
188 gamma = i;
189 break;
190 }
191 }
192 if (i == F->e) {
193 cout << "arc_basic::GlynnII_hyperoval "
194 "did not find gamma" << endl;
195 exit(1);
196 }
197
198 cout << "arc_basic::GlynnII_hyperoval "
199 "sigma = " << sigma << " gamma = " << i << endl;
200 Gamma = NT.i_power_j(2, gamma);
201 Sigma = NT.i_power_j(2, sigma);
202
203 exponent = Sigma + Gamma;
204
205 nb_pts = N;
206
207 Pts = NEW_lint(N);
208 Mtx = NEW_int(N * 3);
209 Int_vec_zero(Mtx, N * 3);
210 for (t = 0; t < F->q; t++) {
211 te = F->power(t, exponent);
212 Mtx[t * 3 + 0] = 1;
213 Mtx[t * 3 + 1] = t;
214 Mtx[t * 3 + 2] = te;
215 }
216 t = F->q;
217 Mtx[t * 3 + 0] = 0;
218 Mtx[t * 3 + 1] = 1;
219 Mtx[t * 3 + 2] = 0;
220 t = F->q + 1;
221 Mtx[t * 3 + 0] = 0;
222 Mtx[t * 3 + 1] = 0;
223 Mtx[t * 3 + 2] = 1;
224 for (i = 0; i < N; i++) {
225 F->PG_element_rank_modified(Mtx + i * 3, 1, 3, a);
226 Pts[i] = a;
227 }
228
229 FREE_int(Mtx);
230 if (f_v) {
231 cout << "arc_basic::GlynnII_hyperoval "
232 "q=" << F->q << " done" << endl;
233 }
234}
235
236
238 long int *&Pts, int &nb_pts, int f_short, int verbose_level)
239// following Payne, Penttila, Pinneri:
240// Isomorphisms Between Subiaco q-Clan Geometries,
241// Bull. Belg. Math. Soc. 2 (1995) 197-222.
242// formula (53)
243{
244 int f_v = (verbose_level >= 1);
245 int N = F->q + 1;
246 int i, t, a, b, h, k, top, bottom;
247 int omega, omega2;
248 int t2, t3, t4, sqrt_t;
249 int *Mtx;
250
251 if (f_v) {
252 cout << "arc_basic::Subiaco_oval "
253 "q=" << F->q << " f_short=" << f_short << endl;
254 }
255
256 nb_pts = N;
257 k = (F->q - 1) / 3;
258 if (k * 3 != F->q - 1) {
259 cout << "arc_basic::Subiaco_oval k * 3 != q - 1" << endl;
260 exit(1);
261 }
262 omega = F->power(F->alpha, k);
263 omega2 = F->mult(omega, omega);
264 if (F->add3(omega2, omega, 1) != 0) {
265 cout << "arc_basic::Subiaco_oval "
266 "add3(omega2, omega, 1) != 0" << endl;
267 exit(1);
268 }
269 Pts = NEW_lint(N);
270 Mtx = NEW_int(N * 3);
271 Int_vec_zero(Mtx, N * 3);
272 for (t = 0; t < F->q; t++) {
273 t2 = F->mult(t, t);
274 t3 = F->mult(t2, t);
275 t4 = F->mult(t2, t2);
276 sqrt_t = F->frobenius_power(t, F->e - 1);
277 if (F->mult(sqrt_t, sqrt_t) != t) {
278 cout << "arc_basic::Subiaco_oval "
279 "mult(sqrt_t, sqrt_t) != t" << endl;
280 exit(1);
281 }
282 bottom = F->add3(t4, F->mult(omega2, t2), 1);
283 if (f_short) {
284 top = F->mult(omega2, F->add(t4, t));
285 }
286 else {
287 top = F->add3(t3, t2, F->mult(omega2, t));
288 }
289 if (FALSE) {
290 cout << "t=" << t << " top=" << top
291 << " bottom=" << bottom << endl;
292 }
293 a = F->mult(top, F->inverse(bottom));
294 if (f_short) {
295 b = sqrt_t;
296 }
297 else {
298 b = F->mult(omega, sqrt_t);
299 }
300 h = F->add(a, b);
301 Mtx[t * 3 + 0] = 1;
302 Mtx[t * 3 + 1] = t;
303 Mtx[t * 3 + 2] = h;
304 }
305 t = F->q;
306 Mtx[t * 3 + 0] = 0;
307 Mtx[t * 3 + 1] = 1;
308 Mtx[t * 3 + 2] = 0;
309 for (i = 0; i < N; i++) {
310 F->PG_element_rank_modified(Mtx + i * 3, 1, 3, a);
311 Pts[i] = a;
312 }
313
314 FREE_int(Mtx);
315 if (f_v) {
316 cout << "arc_basic::Subiaco_oval "
317 "q=" << F->q << " done" << endl;
318 }
319}
320
321
322
323
325 long int *&Pts, int &nb_pts, int verbose_level)
326// email 12/27/2014
327//The o-polynomial of the Subiaco hyperoval is
328
329//t^{1/2}+(d^2t^4 + d^2(1+d+d^2)t^3
330// + d^2(1+d+d^2)t^2 + d^2t)/(t^4+d^2t^2+1)
331
332//where d has absolute trace 1.
333
334//Best,
335//Tim
336
337//absolute trace of 1/d is 1 not d...
338
339{
340 int f_v = (verbose_level >= 1);
341 int N = F->q + 2;
342 int i, t, d, dv, d2, one_d_d2, a, h;
343 int t2, t3, t4, sqrt_t;
344 int top1, top2, top3, top4, top, bottom;
345 int *Mtx;
346
347 if (f_v) {
348 cout << "arc_basic::Subiaco_hyperoval q=" << F->q << endl;
349 }
350
351 nb_pts = N;
352 for (d = 1; d < F->q; d++) {
353 dv = F->inverse(d);
354 if (F->absolute_trace(dv) == 1) {
355 break;
356 }
357 }
358 if (d == F->q) {
359 cout << "arc_basic::Subiaco_hyperoval "
360 "cannot find element d" << endl;
361 exit(1);
362 }
363 d2 = F->mult(d, d);
364 one_d_d2 = F->add3(1, d, d2);
365
366 Pts = NEW_lint(N);
367 Mtx = NEW_int(N * 3);
368 Int_vec_zero(Mtx, N * 3);
369 for (t = 0; t < F->q; t++) {
370 t2 = F->mult(t, t);
371 t3 = F->mult(t2, t);
372 t4 = F->mult(t2, t2);
373 sqrt_t = F->frobenius_power(t, F->e - 1);
374 if (F->mult(sqrt_t, sqrt_t) != t) {
375 cout << "arc_basic::Subiaco_hyperoval "
376 "mult(sqrt_t, sqrt_t) != t" << endl;
377 exit(1);
378 }
379
380
381 bottom = F->add3(t4, F->mult(d2, t2), 1);
382
383 //t^{1/2}+(d^2t^4 + d^2(1+d+d^2)t^3 +
384 // d^2(1+d+d^2)t^2 + d^2t)/(t^4+d^2t^2+1)
385
386 top1 = F->mult(d2,t4);
387 top2 = F->mult3(d2, one_d_d2, t3);
388 top3 = F->mult3(d2, one_d_d2, t2);
389 top4 = F->mult(d2, t);
390 top = F->add4(top1, top2, top3, top4);
391
392 if (f_v) {
393 cout << "t=" << t << " top=" << top
394 << " bottom=" << bottom << endl;
395 }
396 a = F->mult(top, F->inverse(bottom));
397 h = F->add(a, sqrt_t);
398 Mtx[t * 3 + 0] = 1;
399 Mtx[t * 3 + 1] = t;
400 Mtx[t * 3 + 2] = h;
401 }
402 t = F->q;
403 Mtx[t * 3 + 0] = 0;
404 Mtx[t * 3 + 1] = 1;
405 Mtx[t * 3 + 2] = 0;
406 t = F->q + 1;
407 Mtx[t * 3 + 0] = 0;
408 Mtx[t * 3 + 1] = 0;
409 Mtx[t * 3 + 2] = 1;
410 for (i = 0; i < N; i++) {
411 F->PG_element_rank_modified(Mtx + i * 3, 1, 3, a);
412 Pts[i] = a;
413 }
414
415 FREE_int(Mtx);
416 if (f_v) {
417 cout << "arc_basic::Subiaco_hyperoval "
418 "q=" << F->q << " done" << endl;
419 }
420}
421
422
423
424
425// From Bill Cherowitzo's web page:
426// In 1991, O'Keefe and Penttila [OKPe92]
427// by means of a detailed investigation
428// of the divisibility properties of the orders
429// of automorphism groups
430// of hypothetical hyperovals in this plane,
431// discovered a new hyperoval.
432// Its o-polynomial is given by:
433
434//f(x) = x4 + x16 + x28 + beta*11(x6 + x10 + x14 + x18 + x22 + x26)
435// + beta*20(x8 + x20) + beta*6(x12 + x24),
436//where ß is a primitive root of GF(32) satisfying beta^5 = beta^2 + 1.
437//The full automorphism group of this hyperoval has order 3.
438
440// needs the field generated by beta with beta^5 = beta^2+1
441// From Bill Cherowitzo's hyperoval page
442{
443 int *t_powers;
444 int a, b, c, d, e, beta6, beta11, beta20;
445
446 t_powers = NEW_int(31);
447
448 F->power_table(t, t_powers, 31);
449 a = F->add3(t_powers[4], t_powers[16], t_powers[28]);
450 b = F->add6(t_powers[6], t_powers[10], t_powers[14],
451 t_powers[18], t_powers[22], t_powers[26]);
452 c = F->add(t_powers[8], t_powers[20]);
453 d = F->add(t_powers[12], t_powers[24]);
454
455 beta6 = F->power(2, 6);
456 beta11 = F->power(2, 11);
457 beta20 = F->power(2, 20);
458
459 b = F->mult(b, beta11);
460 c = F->mult(c, beta20);
461 d = F->mult(d, beta6);
462
463 e = F->add4(a, b, c, d);
464
465 FREE_int(t_powers);
466 return e;
467}
468
469
470
472// needs the field generated by beta with beta^6 = beta+1
473// The first one from Bill Cherowitzo's hyperoval page
474{
475 int *t_powers;
476 int a, b, c, d, beta21, beta42;
477
478 t_powers = NEW_int(65);
479
480 F->power_table(t, t_powers, 65);
481 a = F->add6(t_powers[8], t_powers[12], t_powers[20],
482 t_powers[22], t_powers[42], t_powers[52]);
483 b = F->add6(t_powers[4], t_powers[10], t_powers[14],
484 t_powers[16], t_powers[30], t_powers[38]);
485 c = F->add6(t_powers[44], t_powers[48], t_powers[54],
486 t_powers[56], t_powers[58], t_powers[60]);
487 b = F->add3(b, c, t_powers[62]);
488 c = F->add7(t_powers[2], t_powers[6], t_powers[26],
489 t_powers[28], t_powers[32], t_powers[36], t_powers[40]);
490 beta21 = F->power(2, 21);
491 beta42 = F->mult(beta21, beta21);
492 d = F->add3(a, F->mult(beta21, b), F->mult(beta42, c));
493 FREE_int(t_powers);
494 return d;
495}
496
498// needs the field generated by beta with beta^6 = beta+1
499// The second one from Bill Cherowitzo's hyperoval page
500{
501 int *t_powers;
502 int a, b, c, d, beta21, beta42;
503
504 t_powers = NEW_int(65);
505
506 F->power_table(t, t_powers, 65);
507 a = F->add3(t_powers[24], t_powers[30], t_powers[62]);
508 b = F->add6(t_powers[4], t_powers[8], t_powers[10],
509 t_powers[14], t_powers[16], t_powers[34]);
510 c = F->add6(t_powers[38], t_powers[40], t_powers[44],
511 t_powers[46], t_powers[52], t_powers[54]);
512 b = F->add4(b, c, t_powers[58], t_powers[60]);
513 c = F->add5(t_powers[6], t_powers[12], t_powers[18],
514 t_powers[20], t_powers[26]);
515 d = F->add5(t_powers[32], t_powers[36], t_powers[42],
516 t_powers[48], t_powers[50]);
517 c = F->add(c, d);
518 beta21 = F->power(2, 21);
519 beta42 = F->mult(beta21, beta21);
520 d = F->add3(a, F->mult(beta21, b), F->mult(beta42, c));
521 FREE_int(t_powers);
522 return d;
523}
524
526// needs the field generated by beta with beta^6 = beta+1
527{
528 int *t_powers;
529 int a, b, c, d, beta21, beta42;
530
531 t_powers = NEW_int(65);
532
533 F->power_table(t, t_powers, 65);
534 a = F->add7(t_powers[4], t_powers[8], t_powers[14], t_powers[34],
535 t_powers[42], t_powers[48], t_powers[62]);
536 b = F->add8(t_powers[6], t_powers[16], t_powers[26], t_powers[28],
537 t_powers[30], t_powers[32], t_powers[40], t_powers[58]);
538 c = F->add8(t_powers[10], t_powers[18], t_powers[24], t_powers[36],
539 t_powers[44], t_powers[50], t_powers[52], t_powers[60]);
540 beta21 = F->power(2, 21);
541 beta42 = F->mult(beta21, beta21);
542 d = F->add3(a, F->mult(beta21, b), F->mult(beta42, c));
543 FREE_int(t_powers);
544 return d;
545}
546
547
548
549void arc_basic::LunelliSce(int *pts18, int verbose_level)
550{
551 int f_v = (verbose_level >= 1);
552 //const char *override_poly = "19";
553 //finite_field F;
554 //int n = 3;
555 //int q = 16;
556 int v[3];
557 //int w[3];
559
560 if (f_v) {
561 cout << "arc_basic::LunelliSce" << endl;
562 }
563 //F.init(q), verbose_level - 2);
564 //F.init_override_polynomial(q, override_poly, verbose_level);
565
566#if 0
567 int cubic1[100];
568 int cubic1_size = 0;
569 int cubic2[100];
570 int cubic2_size = 0;
571 int hoval[100];
572 int hoval_size = 0;
573#endif
574
575 int a, b, i, sz, N;
576
577 if (F->q != 16) {
578 cout << "arc_basic::LunelliSce "
579 "field order must be 16" << endl;
580 exit(1);
581 }
582 N = Gg.nb_PG_elements(2, 16);
583 sz = 0;
584 for (i = 0; i < N; i++) {
585 F->PG_element_unrank_modified(v, 1, 3, i);
586 //cout << "i=" << i << " v=";
587 //int_vec_print(cout, v, 3);
588 //cout << endl;
589
592
593 // form the symmetric difference of the two cubics:
594 if ((a == 0 && b) || (b == 0 && a)) {
595 pts18[sz++] = i;
596 }
597 }
598 if (sz != 18) {
599 cout << "sz != 18" << endl;
600 exit(1);
601 }
602 if (f_v) {
603 cout << "the size of the LinelliSce hyperoval is " << sz << endl;
604 cout << "the LinelliSce hyperoval is:" << endl;
605 Int_vec_print(cout, pts18, sz);
606 cout << endl;
607 }
608
609#if 0
610 cout << "the size of cubic1 is " << cubic1_size << endl;
611 cout << "the cubic1 is:" << endl;
612 int_vec_print(cout, cubic1, cubic1_size);
613 cout << endl;
614 cout << "the size of cubic2 is " << cubic2_size << endl;
615 cout << "the cubic2 is:" << endl;
616 int_vec_print(cout, cubic2, cubic2_size);
617 cout << endl;
618#endif
619
620}
621
623// computes X^3 + Y^3 + Z^3 + \eta^3 XYZ
624{
625 int a, b, c, d, e, eta3;
626
627 eta3 = F->power(2, 3);
628 //eta12 = power(2, 12);
629 a = F->power(v[0], 3);
630 b = F->power(v[1], 3);
631 c = F->power(v[2], 3);
632 d = F->product4(eta3, v[0], v[1], v[2]);
633 e = F->add4(a, b, c, d);
634 return e;
635}
636
638// computes X^3 + Y^3 + Z^3 + \eta^{12} XYZ
639{
640 int a, b, c, d, e, eta12;
641
642 //eta3 = power(2, 3);
643 eta12 = F->power(2, 12);
644 a = F->power(v[0], 3);
645 b = F->power(v[1], 3);
646 c = F->power(v[2], 3);
647 d = F->product4(eta12, v[0], v[1], v[2]);
648 e = F->add4(a, b, c, d);
649 return e;
650}
651
652}}}
653
654
655
int add5(int i1, int i2, int i3, int i4, int i5)
int add8(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8)
void PG_element_rank_modified(int *v, int stride, int len, int &a)
void PG_element_unrank_modified(int *v, int stride, int len, int a)
int add7(int i1, int i2, int i3, int i4, int i5, int i6, int i7)
int add6(int i1, int i2, int i3, int i4, int i5, int i6)
void power_table(int t, int *power_table, int len)
void GlynnI_hyperoval(long int *&Pts, int &nb_pts, int verbose_level)
Definition: arc_basic.cpp:97
void LunelliSce(int *pts18, int verbose_level)
Definition: arc_basic.cpp:549
void GlynnII_hyperoval(long int *&Pts, int &nb_pts, int verbose_level)
Definition: arc_basic.cpp:166
void Subiaco_hyperoval(long int *&Pts, int &nb_pts, int verbose_level)
Definition: arc_basic.cpp:324
void init(field_theory::finite_field *F, int verbose_level)
Definition: arc_basic.cpp:34
void Segre_hyperoval(long int *&Pts, int &nb_pts, int verbose_level)
Definition: arc_basic.cpp:49
void Subiaco_oval(long int *&Pts, int &nb_pts, int f_short, int verbose_level)
Definition: arc_basic.cpp:237
various functions related to geometries
Definition: geometry.h:721
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_int(n)
Definition: foundations.h:625
#define FALSE
Definition: foundations.h:234
#define EVEN(x)
Definition: foundations.h:221
#define NEW_lint(n)
Definition: foundations.h:628
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
the orbiter library for the classification of combinatorial objects