Orbiter 2022
Combinatorial Objects
subfield_structure.cpp
Go to the documentation of this file.
1// subfield_structure.cpp
2//
3// Anton Betten
4//
5// started: November 14, 2011
6
7
8
9
10#include "foundations.h"
11
12
13using namespace std;
14
15
16namespace orbiter {
17namespace layer1_foundations {
18namespace field_theory {
19
20
22{
23 FQ = NULL;
24 Fq = NULL;
25 Q = q = s = 0;
26 Basis = NULL;
27 embedding = NULL;
28 embedding_inv = NULL;
29 components = NULL;
30 FQ_embedding = NULL;
31 Fq_element = NULL;
32 v = NULL;
33 //null();
34}
35
36
37
39{
40 freeself();
41}
42
44{
45}
46
48{
49 if (Basis) {
51 }
52 if (embedding) {
54 }
55 if (embedding_inv) {
57 }
58 if (components) {
60 }
61 if (FQ_embedding) {
63 }
64 if (Fq_element) {
66 }
67 if (v) {
68 FREE_int(v);
69 }
70 null();
71}
72
74 finite_field *Fq, int verbose_level)
75{
76 int f_v = (verbose_level >= 1);
77 int alpha, omega, i;
78 int *my_basis;
79
80 if (f_v) {
81 cout << "subfield_structure::init" << endl;
82 }
85 Q = FQ->q;
86 q = Fq->q;
87 if (FQ->p != Fq->p) {
88 cout << "subfield_structure::init "
89 "different characteristics" << endl;
90 exit(1);
91 }
92 s = FQ->e / Fq->e;
93 if (Fq->e * s != FQ->e) {
94 cout << "Fq is not a subfield of FQ" << endl;
95 exit(1);
96 }
97 if (f_v) {
98 cout << "index = " << s << endl;
99 }
100
101
102 my_basis = NEW_int(s);
103 alpha = FQ->p; // the primitive element
104 omega = FQ->power(alpha, s);
105 for (i = 0; i < s; i++) {
106 my_basis[i] = FQ->power(omega, i);
107 }
108 init_with_given_basis(FQ, Fq, my_basis, verbose_level);
109
110 FREE_int(my_basis);
111
112 if (f_v) {
113 cout << "subfield_structure::init done" << endl;
114 }
115}
116
118 finite_field *FQ, finite_field *Fq, int *given_basis,
119 int verbose_level)
120{
121 int f_v = (verbose_level >= 1);
122 int /*alpha,*/ /*omega,*/ i, j, h;
124
125 if (f_v) {
126 cout << "subfield_structure::init_with_given_basis" << endl;
127 }
130 Q = FQ->q;
131 q = Fq->q;
132 if (FQ->p != Fq->p) {
133 cout << "subfield_structure::init_with_given_basis "
134 "different characteristics" << endl;
135 exit(1);
136 }
137 s = FQ->e / Fq->e;
138 if (Fq->e * s != FQ->e) {
139 cout << "Fq is not a subfield of FQ" << endl;
140 exit(1);
141 }
142 if (f_v) {
143 cout << "index = " << s << endl;
144 }
145 Basis = NEW_int(s);
148 components = NEW_int(Q * s);
151 v = NEW_int(s);
152
153 //alpha = FQ->p; // the primitive element
154 //omega = FQ->power(alpha, s);
155 for (i = 0; i < s; i++) {
156 Basis[i] = given_basis[i];
157 }
158 if (f_v) {
159 cout << "Field basis: ";
160 Int_vec_print(cout, Basis, s);
161 cout << endl;
162 }
163 for (i = 0; i < Q; i++) {
164 Fq_element[i] = -1;
165 }
166 for (i = 0; i < q; i++) {
167 j = FQ->embed(*Fq, s, i, 0 /* verbose_level */);
168 FQ_embedding[i] = j;
169 Fq_element[j] = i;
170 }
171
172 for (i = 0; i < Q; i++) {
173 Gg.AG_element_unrank(q, v, 1, s, i);
174 j = evaluate_over_Fq(v);
175 embedding[i] = j;
176 embedding_inv[j] = i;
177 for (h = 0; h < s; h++) {
178 components[j * s + h] = v[h];
179 }
180 }
181
182
183 if (f_v) {
184 cout << "subfield_structure::init_with_given_basis done" << endl;
185 }
186}
187
189{
190 long int i, j;
192
193 cout << "subfield_structure::print_embedding:" << endl;
194 cout << "i : vector over F_q : embedding" << endl;
195 for (i = 0; i < Q; i++) {
196 Gg.AG_element_unrank(q, v, 1, s, i);
197 j = evaluate_over_Fq(v);
198 cout << setw(4) << i << " : ";
199 Int_vec_print(cout, v, s);
200 cout << " : " << j << endl;
201 }
202 cout << "subfield_structure::print_embedding in reverse:" << endl;
203 cout << "element i in F_Q : vector over F_q : vector AG_rank" << endl;
204 for (i = 0; i < Q; i++) {
205 j = Gg.AG_element_rank(q, components + i * s, 1, s);
206 cout << setw(4) << i << " : ";
207 Int_vec_print(cout, components + i * s, s);
208 cout << " : " << j << endl;
209 }
210
211}
212
213void subfield_structure::report(std::ostream &ost)
214{
215 int i, j;
217
218
219 ost << "\\subsection*{The Subfield of Order $" << q << "$}" << endl;
220 ost << "Field basis:\\\\" << endl;
221 ost << "$$" << endl;
222 Int_vec_print(ost, Basis, s);
223 //cout << endl;
224 ost << "$$" << endl;
225 ost << "Embedding:\\\\" << endl;
226 ost << "$$" << endl;
227 ost << "\\begin{array}{|r|r|r|}" << endl;
228 ost << "\\hline" << endl;
229 for (i = 0; i < Q; i++) {
230 Gg.AG_element_unrank(q, v, 1, s, i);
231 j = evaluate_over_Fq(v);
232 ost << setw(4) << i << " & ";
233 Int_vec_print(ost, v, s);
234 ost << " & " << j << "\\\\" << endl;
235 }
236 ost << "\\hline" << endl;
237 ost << "\\end{array}" << endl;
238 ost << "$$" << endl;
239
240
241 ost << "In reverse:\\\\" << endl;
242 ost << "$$" << endl;
243 ost << "\\begin{array}{|r|r|r|}" << endl;
244 ost << "\\hline" << endl;
245 ost << "i \\in {\\mathbb F}_Q & \\mbox{vector} & \\mbox{rank}\\\\" << endl;
246 ost << "\\hline" << endl;
247 for (i = 0; i < Q; i++) {
248 j = Gg.AG_element_rank(q, components + i * s, 1, s);
249 ost << setw(4) << i << " & ";
250 Int_vec_print(ost, components + i * s, s);
251 ost << " & " << j << "\\\\" << endl;
252 }
253 ost << "\\hline" << endl;
254 ost << "\\end{array}" << endl;
255 ost << "$$" << endl;
256
257}
258
260{
261 int i, a, b;
262
263 a = 0;
264 for (i = 0; i < s; i++) {
265 b = FQ->mult(v[i], Basis[i]);
266 a = FQ->add(a, b);
267 }
268 return a;
269}
270
272{
273 int i, a, b, c;
274
275 a = 0;
276 for (i = 0; i < s; i++) {
277 c = FQ_embedding[v[i]];
278 b = FQ->mult(c, Basis[i]);
279 a = FQ->add(a, b);
280 }
281 return a;
282}
283
285 int m, int *Mq, int verbose_level)
286{
287 int f_v = (verbose_level >= 1);
288 int i, j, I, J, a, b, c, d, u, v, n;
289
290 if (f_v) {
291 cout << "subfield_structure::lift_matrix" << endl;
292 }
293 n = m * s;
294 for (i = 0; i < m; i++) {
295 for (j = 0; j < m; j++) {
296 a = MQ[i * m + j];
297 I = s * i;
298 J = s * j;
299 for (u = 0; u < s; u++) {
300 b = Basis[u];
301 c = FQ->mult(b, a);
302 for (v = 0; v < s; v++) {
303 d = components[c * s + v];
304 Mq[(I + u) * n + J + v] = d;
305 }
306 }
307 }
308 }
309
310 if (f_v) {
311 cout << "subfield_structure::lift_matrix done" << endl;
312 }
313}
314
316 int n, int *MQ, int m, int verbose_level)
317{
318 int f_v = (verbose_level >= 1);
319 int *vec;
320 long int i, j, I, J, u, v, d, b, bv, a, rk;
322
323 if (f_v) {
324 cout << "subfield_structure::retract_matrix" << endl;
325 }
326 if (m * s != n) {
327 cout << "subfield_structure::retract_matrix m * s != n" << endl;
328 exit(1);
329 }
330 vec = NEW_int(s);
331 for (i = 0; i < m; i++) {
332 for (j = 0; j < m; j++) {
333 I = s * i;
334 J = s * j;
335 for (u = 0; u < s; u++) {
336 for (v = 0; v < s; v++) {
337 vec[v] = Mq[(I + u) * n + J + v];
338 }
339 rk = Gg.AG_element_rank(q, vec, 1, s);
340 d = embedding[rk];
341 b = Basis[u];
342 bv = FQ->inverse(b);
343 a = FQ->mult(d, bv);
344 if (u == 0) {
345 MQ[i * m + j] = a;
346 }
347 else {
348 if (a != MQ[i * m + j]) {
349 cout << "subfield_structure::retract_matrix "
350 "a != MQ[i * m + j]" << endl;
351 exit(1);
352 }
353 }
354 }
355 }
356 }
357 FREE_int(vec);
358 if (f_v) {
359 cout << "subfield_structure::retract_matrix done" << endl;
360 }
361}
362
363
364
365//Date: Tue, 30 Dec 2014 21:08:19 -0700
366//From: Tim Penttila
367
368//To: "betten@math.colostate.edu" <betten@math.colostate.edu>
369//Subject: RE: Oops
370//Parts/Attachments:
371// 1 OK ~3 KB Text
372// 2 Shown ~4 KB Text
373//----------------------------------------
374//
375//Hi Anton,
376//
377//Friday is predicted to be 42 Celsius, here in Adelaide. So you are
378//right! (And I do like that!)
379//
380//Let b be an element of GF(q^2) of relative norm 1 over GF(q),i.e, b is
381//different from 1 but b^{q+1} = 1 . Consider the polynomial
382//
383//f(t) = (tr(b))^{−1}tr(b^{(q-1)/3})(t + 1) + (tr(b))^{−1}tr((bt +
384//b^q)^{(q-1)/3})(t + tr(b)t^{1/2}+ 1)^{1-(q-1)/3} + t^{1/2},
385//where tr(x) =x + x^q is the relative trace. When q = 2^h, with h even,
386//f(t) is an o-polynomial for the Adelaide hyperoval.
387//
388//Best,Tim
389
390
392 long int *&Pts, int &nb_pts, int verbose_level)
393{
394 int f_v = (verbose_level >= 1);
395
396 int q = Fq->q;
397 int e = Fq->e;
398 int N = q + 2;
399
400 int i, t, b, bq, bk, tr_b, tr_bk, tr_b_down, tr_bk_down, tr_b_down_inv;
401 int a, tr_a, tr_a_down, t_lift, alpha, k;
402 int sqrt_t, c, cv, d, f;
403 int top1, top2, u, v, w, r;
404 int *Mtx;
405
406 if (f_v) {
407 cout << "subfield_structure::Adelaide_hyperoval "
408 "q=" << q << endl;
409 }
410
411 if (ODD(e)) {
412 cout << "subfield_structure::Adelaide_hyperoval "
413 "need e even" << endl;
414 exit(1);
415 }
416 nb_pts = N;
417
418 k = (q - 1) / 3;
419 if (k * 3 != q - 1) {
420 cout << "subfield_structure::Adelaide_hyperoval "
421 "k * 3 != q - 1" << endl;
422 exit(1);
423 }
424
425 alpha = FQ->alpha;
426 b = FQ->power(alpha, q - 1);
427 if (FQ->power(b, q + 1) != 1) {
428 cout << "subfield_structure::Adelaide_hyperoval "
429 "FQ->power(b, q + 1) != 1" << endl;
430 exit(1);
431 }
432 bk = FQ->power(b, k);
433 bq = FQ->frobenius_power(b, e);
434 tr_b = FQ->add(b, bq);
435 tr_bk = FQ->add(bk, FQ->frobenius_power(bk, e));
436 tr_b_down = Fq_element[tr_b];
437 if (tr_b_down == -1) {
438 cout << "subfield_structure::Adelaide_hyperoval "
439 "tr_b_down == -1" << endl;
440 exit(1);
441 }
442 tr_bk_down = Fq_element[tr_bk];
443 if (tr_bk_down == -1) {
444 cout << "subfield_structure::Adelaide_hyperoval "
445 "tr_bk_down == -1" << endl;
446 exit(1);
447 }
448
449 tr_b_down_inv = Fq->inverse(tr_b_down);
450
451
452 Pts = NEW_lint(N);
453 Mtx = NEW_int(N * 3);
454 Int_vec_zero(Mtx, N * 3);
455 for (t = 0; t < q; t++) {
456
457 sqrt_t = Fq->frobenius_power(t, e - 1);
458 if (Fq->mult(sqrt_t, sqrt_t) != t) {
459 cout << "subfield_structure::Adelaide_hyperoval "
460 "Fq->mult(sqrt_t, sqrt_t) != t" << endl;
461 exit(1);
462 }
463
464
465 t_lift = FQ_embedding[t];
466 a = FQ->power(FQ->add(FQ->mult(b, t_lift), bq), k);
467 tr_a = FQ->add(a, FQ->frobenius_power(a, e));
468 tr_a_down = Fq_element[tr_a];
469 if (tr_a_down == -1) {
470 cout << "subfield_structure::Adelaide_hyperoval "
471 "tr_a_down == -1" << endl;
472 exit(1);
473 }
474
475 c = Fq->add3(t, Fq->mult(tr_b_down, sqrt_t), 1);
476 cv = Fq->inverse(c);
477 d = Fq->power(cv, k);
478 f = Fq->mult(c, d);
479
480 top1 = Fq->mult(tr_bk_down, Fq->add(t, 1));
481 u = Fq->mult(top1, tr_b_down_inv);
482
483 top2 = Fq->mult(tr_a_down, f);
484 v = Fq->mult(top2, tr_b_down_inv);
485
486
487 w = Fq->add3(u, v, sqrt_t);
488
489
490 Mtx[t * 3 + 0] = 1;
491 Mtx[t * 3 + 1] = t;
492 Mtx[t * 3 + 2] = w;
493 }
494 t = q;
495 Mtx[t * 3 + 0] = 0;
496 Mtx[t * 3 + 1] = 1;
497 Mtx[t * 3 + 2] = 0;
498 t = q + 1;
499 Mtx[t * 3 + 0] = 0;
500 Mtx[t * 3 + 1] = 0;
501 Mtx[t * 3 + 2] = 1;
502 for (i = 0; i < N; i++) {
503 Fq->PG_element_rank_modified(Mtx + i * 3, 1, 3, r);
504 Pts[i] = r;
505 }
506
507 FREE_int(Mtx);
508
509 if (f_v) {
510 cout << "subfield_structure::Adelaide_hyperoval "
511 "q=" << q << " done" << endl;
512 }
513
514}
515
517 std::string &fname, int &nb_pts, long int *&Pts,
518 int verbose_level)
519{
520 int f_v = (verbose_level >= 1);
521 finite_field *F = Fq;
522 int q = F->q;
524
525 if (f_v) {
526 cout << "subfield_structure::create_adelaide_hyperoval" << endl;
527 }
528
529 Adelaide_hyperoval(Pts, nb_pts, verbose_level);
530
531 char str[1000];
532 sprintf(str, "adelaide_hyperoval_q%d.txt", q);
533 fname.assign(str);
534
535
536 if (f_v) {
537 int i;
538 int n = 2, d = n + 1;
539 int *v;
541
542 v = NEW_int(d);
544
545
546 P->projective_space_init(n, F,
547 FALSE /* f_init_incidence_structure */,
548 verbose_level /*MINIMUM(verbose_level - 1, 3)*/);
549 cout << "i : point : projective rank" << endl;
550 for (i = 0; i < nb_pts; i++) {
551 P->unrank_point(v, Pts[i]);
552 if (f_v) {
553 cout << setw(4) << i << " : ";
554 Int_vec_print(cout, v, d);
555 cout << endl;
556 }
557 }
558 FREE_int(v);
559 FREE_OBJECT(P);
560 }
561
562 if (!Sorting.test_if_set_with_return_value_lint(Pts, nb_pts)) {
563 cout << "subfield_structure::create_adelaide_hyperoval "
564 "the set is not a set, "
565 "something is wrong" << endl;
566 exit(1);
567 }
568
569}
570
571
572void subfield_structure::field_reduction(int *input, int sz, int *output,
573 int verbose_level)
574// input[sz], output[(s * sz) * (s * sz * s)],
575{
576 int f_v = (verbose_level >= 1);
577 int i, j, a, b, c, t, J;
578 int n;
579 int *w;
581
582 if (f_v) {
583 cout << "subfield_structure::field_reduction" << endl;
584 }
585 n = sz * s;
586 w = NEW_int(sz);
587
588 if (f_v) {
589 cout << "input:" << endl;
590 Int_vec_print(cout, input, sz);
591 cout << endl;
592 }
593
594 Int_vec_zero(output, s * n);
595
596 for (i = 0; i < s; i++) {
597
598 if (f_v) {
599 cout << "i=" << i << " / " << s << endl;
600 }
601 // multiply by the i-th basis element,
602 // put into the vector w[m]
603 a = Basis[i];
604 for (j = 0; j < sz; j++) {
605 b = input[j];
606 if (FALSE) {
607 cout << "j=" << j << " / " << sz
608 << " a=" << a << " b=" << b << endl;
609 }
610 c = FQ->mult(b, a);
611 w[j] = c;
612 }
613 if (f_v) {
614 cout << "i=" << i << " / " << s << " w=";
615 Int_vec_print(cout, w, sz);
616 cout << endl;
617 }
618
619 for (j = 0; j < sz; j++) {
620 J = j * s;
621 b = w[j];
622 for (t = 0; t < s; t++) {
623 c = components[b * s + t];
624 output[i * n + J + t] = c;
625 }
626 }
627 if (f_v) {
628 cout << "output:" << endl;
629 Int_matrix_print(output, s, n);
630 }
631 }
632 FREE_int(w);
633
634 if (f_v) {
635 cout << "subfield_structure::field_reduction done" << endl;
636 }
637
638}
639
640
641}}}
642
643
644
645
a collection of functions related to sorted vectors
int test_if_set_with_return_value_lint(long int *set, int set_size)
Definition: sorting.cpp:586
void PG_element_rank_modified(int *v, int stride, int len, int &a)
int embed(finite_field &subfield, int index, int b, int verbose_level)
void retract_matrix(int *Mq, int n, int *MQ, int m, int verbose_level)
void Adelaide_hyperoval(long int *&Pts, int &nb_pts, int verbose_level)
void init(finite_field *FQ, finite_field *Fq, int verbose_level)
void create_adelaide_hyperoval(std::string &fname, int &nb_pts, long int *&Pts, int verbose_level)
void field_reduction(int *input, int sz, int *output, int verbose_level)
void init_with_given_basis(finite_field *FQ, finite_field *Fq, int *given_basis, int verbose_level)
void lift_matrix(int *MQ, int m, int *Mq, int verbose_level)
various functions related to geometries
Definition: geometry.h:721
void AG_element_unrank(int q, int *v, int stride, int len, long int a)
long int AG_element_rank(int q, int *v, int stride, int len)
projective space PG(n,q) of dimension n over Fq
Definition: geometry.h:1916
void projective_space_init(int n, field_theory::finite_field *F, int f_init_incidence_structure, int verbose_level)
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define FREE_OBJECT(p)
Definition: foundations.h:651
#define NEW_int(n)
Definition: foundations.h:625
#define Int_matrix_print(A, B, C)
Definition: foundations.h:707
#define FALSE
Definition: foundations.h:234
#define ODD(x)
Definition: foundations.h:222
#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