Orbiter 2022
Combinatorial Objects
finite_field_implementation_by_tables.cpp
Go to the documentation of this file.
1/*
2 * finite_field_implementation_by_tables.cpp
3 *
4 * Created on: Sep 5, 2021
5 * Author: betten
6 */
7
8
9
10
11
12
13#include "foundations.h"
14
15using namespace std;
16
17
18
19namespace orbiter {
20namespace layer1_foundations {
21namespace field_theory {
22
23
24
26{
27 F = NULL;
28
29 add_table = NULL;
30 mult_table = NULL;
31 // add_table and mult_table are needed in mindist
32
33 negate_table = NULL;
34 inv_table = NULL;
35 frobenius_table = NULL;
36 absolute_trace_table = NULL;
37 log_alpha_table = NULL;
38 // log_alpha_table[i] = the integer k s.t. alpha^k = i (if i > 0)
39 // log_alpha_table[0] = -1
40 alpha_power_table = NULL;
41 v1 = NULL;
42 v2 = NULL;
43 v3 = NULL;
44 f_has_quadratic_subfield = FALSE;
45 f_belongs_to_quadratic_subfield = NULL;
46
47 reordered_list_of_elements = NULL;
48 reordered_list_of_elements_inv = NULL;
49
50
51}
52
54{
55 if (add_table) {
56 FREE_int(add_table);
57 }
58 if (mult_table) {
59 FREE_int(mult_table);
60 }
61 if (negate_table) {
62 FREE_int(negate_table);
63 }
64 if (inv_table) {
65 FREE_int(inv_table);
66 }
67 //cout << "destroying frobenius_table" << endl;
68 if (frobenius_table) {
69 FREE_int(frobenius_table);
70 }
71 //cout << "destroying absolute_trace_table" << endl;
72 if (absolute_trace_table) {
73 FREE_int(absolute_trace_table);
74 }
75 //cout << "destroying log_alpha_table" << endl;
76 if (log_alpha_table) {
77 FREE_int(log_alpha_table);
78 }
79 //scout << "destroying alpha_power_table" << endl;
80 if (alpha_power_table) {
81 FREE_int(alpha_power_table);
82 }
83 if (v1) {
84 FREE_int(v1);
85 }
86 if (v2) {
87 FREE_int(v2);
88 }
89 if (v3) {
90 FREE_int(v3);
91 }
92 if (f_belongs_to_quadratic_subfield) {
93 FREE_int(f_belongs_to_quadratic_subfield);
94 }
95 if (reordered_list_of_elements) {
96 FREE_int(reordered_list_of_elements);
97 }
98 if (reordered_list_of_elements_inv) {
99 FREE_int(reordered_list_of_elements_inv);
100 }
101
102}
103
105{
106 int f_v = (verbose_level >= 1);
107
108 if (f_v) {
109 cout << "finite_field_implementation_by_tables::init" << endl;
110 }
111
112 finite_field_implementation_by_tables::F = F;
113
114
115 v1 = NEW_int(F->e);
116 v2 = NEW_int(F->e);
117 v3 = NEW_int(F->e);
118
119 if (f_v) {
120 cout << "finite_field_implementation_by_tables::init before create_alpha_table" << endl;
121 }
122 create_alpha_table(verbose_level);
123 if (f_v) {
124 cout << "finite_field_implementation_by_tables::init after create_alpha_table" << endl;
125 }
126
127
128
129
130 if (f_v) {
131 cout << "finite_field_implementation_by_tables::init before init_binary_operations" << endl;
132 }
133 init_binary_operations(0 /*verbose_level */);
134 if (f_v) {
135 cout << "finite_field_implementation_by_tables::init after init_binary_operations" << endl;
136 }
137
138 F->f_has_table = TRUE;
139 // do this so that finite_field_by_tables::mult_verbose does not complain
140 // after all, the multiplication table has been computed by now
141
142
143
144 if (f_v) {
145 cout << "finite_field_implementation_by_tables::init "
146 "before init_quadratic_subfield" << endl;
147 }
148 init_quadratic_subfield(verbose_level - 2);
149 if (f_v) {
150 cout << "finite_field_implementation_by_tables::init "
151 "after init_quadratic_subfield" << endl;
152 }
153
154 if (f_v) {
155 cout << "finite_field_implementation_by_tables::init "
156 "before init_frobenius_table" << endl;
157 }
158 init_frobenius_table(verbose_level);
159 if (f_v) {
160 cout << "finite_field_implementation_by_tables::init "
161 "after init_frobenius_table" << endl;
162 }
163
164 if (f_v) {
165 cout << "finite_field_implementation_by_tables::init "
166 "before init_absolute_trace_table" << endl;
167 }
168 init_absolute_trace_table(verbose_level);
169 if (f_v) {
170 cout << "finite_field_implementation_by_tables::init "
171 "after init_absolute_trace_table" << endl;
172 }
173
174
175 if (f_v) {
176 cout << "finite_field_implementation_by_tables::init field of order "
177 << F->q << " initialized" << endl;
178 if (f_v) {
179 if (FALSE) {
180 if (F->e > 1) {
182 }
183 else {
184 F->print_tables();
185 }
186 }
187 }
188 }
189
190
191
192 if (f_v) {
193 cout << "finite_field_implementation_by_tables::init done" << endl;
194 }
195}
196
198{
199 return add_table;
200}
201
203{
204 return mult_table;
205}
206
208{
209 return f_has_quadratic_subfield;
210}
211
213{
214 return f_belongs_to_quadratic_subfield[a];
215}
216
218{
219 int f_v = (verbose_level >= 1);
220
221 log_alpha_table = NEW_int(F->q);
222 alpha_power_table = NEW_int(F->q);
223
224 if (f_v) {
225 cout << "finite_field_implementation_by_tables::create_alpha_table q=" << F->q
226 << " p=" << F->p << " e=" << F->e << endl;
227 }
228 if (F->f_is_prime_field) {
229 if (f_v) {
230 cout << "finite_field_implementation_by_tables::create_alpha_table "
231 "before create_alpha_table_prime_field" << endl;
232 }
233 create_alpha_table_prime_field(verbose_level);
234 if (f_v) {
235 cout << "finite_field_implementation_by_tables::create_alpha_table "
236 "after create_alpha_table_prime_field" << endl;
237 }
238 }
239 else {
240 if (f_v) {
241 cout << "finite_field_implementation_by_tables::create_alpha_table "
242 "before create_alpha_table_extension_field" << endl;
243 }
245 if (f_v) {
246 cout << "finite_field_implementation_by_tables::create_alpha_table "
247 "after create_alpha_table_extension_field" << endl;
248 }
249 }
250 if (f_v) {
251 cout << "finite_field_implementation_by_tables::create_alpha_table done" << endl;
252 }
253}
254
256{
257 int f_v = (verbose_level >= 1);
258 int f_vv = FALSE; //(verbose_level >= 2);
259 int i, a;
261
262 if (f_v) {
263 cout << "finite_field_implementation_by_tables::create_alpha_table_prime_field, "
264 "q=" << F->q << " p=" << F->p << " e=" << F->e << endl;
265 }
266 F->alpha = NT.primitive_root(F->p, verbose_level);
267 if (f_v) {
268 cout << "finite_field_implementation_by_tables::create_alpha_table_prime_field "
269 "primitive element is alpha=" << F->alpha << endl;
270 }
271 for (i = 0; i < F->p; i++) {
272 log_alpha_table[i] = -1;
273 alpha_power_table[i] = -1;
274 }
275 log_alpha_table[0] = -1;
276 a = 1;
277 for (i = 0; i < F->p; i++) {
278 if (a < 0 || a >= F->q) {
279 cout << "finite_field_implementation_by_tables::create_alpha_table_prime_field "
280 "error: a = " << a << endl;
281 }
282 alpha_power_table[i] = a;
283 if (log_alpha_table[a] == -1) {
284 log_alpha_table[a] = i;
285 }
286
287 if (f_vv) {
288 cout << "finite_field_implementation_by_tables::create_alpha_table_prime_field "
289 "alpha_power_table[" << i << "]=" << a << endl;
290 }
291
292 a *= F->alpha;
293 a %= F->p;
294 }
295 if (f_v) {
296 cout << "finite_field_implementation_by_tables::create_alpha_table_prime_field "
297 "table, p=" << F->p << endl;
298 cout << "i : alpha_power_table[i] : log_alpha_table[i]" << endl;
299 for (i = 0; i < F->p; i++) {
300 cout << i << " : " << alpha_power_table[i] << " : "
301 << log_alpha_table[i] << endl;
302 }
303 }
304 if (f_v) {
305 cout << "finite_field_implementation_by_tables::create_alpha_table_prime_field done" << endl;
306 }
307}
308
310{
311 int f_v = (verbose_level >= 1);
312 int f_vv = (verbose_level >= 2);
313 int i, k;
314
315 if (f_v) {
316 cout << "finite_field_implementation_by_tables::create_alpha_table_extension_field "
317 "q=" << F->q << " p=" << F->p << " e=" << F->e << endl;
318 }
319
320
321 if (f_v) {
322 cout << "finite_field_implementation_by_tables::create_alpha_table_extension_field "
323 "before find_primitive_element" << endl;
324 }
325 F->alpha = F->find_primitive_element(verbose_level);
326 if (f_v) {
327 cout << "finite_field_implementation_by_tables::create_alpha_table_extension_field "
328 "after find_primitive_element" << endl;
329 }
330 if (f_v) {
331 cout << "finite_field_implementation_by_tables::create_alpha_table_extension_field "
332 "alpha = " << F->alpha << endl;
333 }
334 //alpha = p;
335 log_alpha_table[0] = -1;
336
337
338
340 GFp.finite_field_init(F->p, FALSE /* f_without_tables */, 0);
341
344
345 FX.create_object_by_rank_string(m, F->my_poly, 0 /*verbose_level - 2*/);
346 if (f_vv) {
347 cout << "m=";
348 FX.print_object(m, cout);
349 cout << endl;
350 }
351 {
352 ring_theory::unipoly_domain Fq(&GFp, m, verbose_level - 1);
353 ring_theory::unipoly_object a, c, Alpha;
354
355 Fq.create_object_by_rank(Alpha, F->alpha, __FILE__, __LINE__, 0 /*verbose_level - 2*/);
356 Fq.create_object_by_rank(a, 1, __FILE__, __LINE__, 0 /*verbose_level - 2*/);
357 Fq.create_object_by_rank(c, 1, __FILE__, __LINE__, 0 /*verbose_level - 2*/);
358
359 for (i = 0; i < F->q; i++) {
360
361 if (f_vv) {
362 cout << "i=" << i << endl;
363 }
364 k = Fq.rank(a);
365 if (f_vv) {
366 cout << "a=";
367 Fq.print_object(a, cout);
368 cout << " has rank " << k << endl;
369 }
370 if (k < 0 || k >= F->q) {
371 cout << "finite_field_implementation_by_tables::create_alpha_table_extension_field "
372 "error: k = " << k << endl;
373 }
374 if (k == 1 && i > 0 && i < F->q - 1) {
375 cout << "finite_field_implementation_by_tables::create_alpha_table_extension_field "
376 "the polynomial is not primitive" << endl;
377 cout << "k == 1 and i = " << i << endl;
378 exit(1);
379 }
380
381 alpha_power_table[i] = k;
382 if (i < F->q - 1) {
383 log_alpha_table[k] = i;
384 }
385
386 if (f_vv) {
387 cout << "alpha_power_table[" << i << "]=" << k << endl;
388 }
389
390 Fq.mult(a, Alpha, c, verbose_level - 1);
391 Fq.assign(c, a, verbose_level - 2);
392 }
393 Fq.delete_object(Alpha);
394 Fq.delete_object(a);
395 Fq.delete_object(c);
396 }
397 FX.delete_object(m);
398
399 if (f_v) {
400 cout << "finite_field_implementation_by_tables::create_alpha_table_extension_field done" << endl;
401 }
402}
403
405{
406 int f_v = (verbose_level >= 1);
407
408 if (f_v) {
409 cout << "finite_field_implementation_by_tables::init_binary_operations" << endl;
410 }
411
412 if (f_v) {
413 cout << "finite_field_implementation_by_tables::init_binary_operations "
414 "creating tables q=" << F->q << endl;
415 }
416
417 add_table = NEW_int(F->q * F->q);
418 mult_table = NEW_int(F->q * F->q);
419 negate_table = NEW_int(F->q);
420 inv_table = NEW_int(F->q);
421 reordered_list_of_elements = NEW_int(F->q);
422 reordered_list_of_elements_inv = NEW_int(F->q);
423
424 if (F->e == 1) {
425 if (f_v) {
426 cout << "finite_field_implementation_by_tables::init_binary_operations "
427 "before create_tables_prime_field" << endl;
428 }
429 create_tables_prime_field(verbose_level - 2);
430 if (f_v) {
431 cout << "finite_field_implementation_by_tables::init_binary_operations "
432 "after create_tables_prime_field" << endl;
433 }
434 }
435 else {
436 if (f_v) {
437 cout << "finite_field_implementation_by_tables::init_binary_operations "
438 "before create_tables_extension_field" << endl;
439 }
440 create_tables_extension_field(verbose_level - 2);
441 if (f_v) {
442 cout << "finite_field_implementation_by_tables::init_binary_operations "
443 "after create_tables_extension_field" << endl;
444 }
445 }
446 if (FALSE) {
448 }
449
450 if (f_v) {
451 cout << "finite_field_implementation_by_tables::init_binary_operations done" << endl;
452 }
453}
454
456// assumes that a primitive element F->alpha mod p has already been computed
457{
458 int f_v = (verbose_level >= 1);
459 int i, j, k, a;
460
461 if (f_v) {
462 cout << "finite_field_implementation_by_tables::create_tables_prime_field" << endl;
463 }
464
465 // compute addition table and negation table:
466
467 for (i = 0; i < F->q; i++) {
468 for (j = 0; j < F->q; j++) {
469 k = (i + j) % F->q;
470 add_table[i * F->q + j] = k;
471 if (k == 0) {
472 negate_table[i] = j;
473 }
474 }
475 }
476
477 // compute multiplication table and inverse table
478 // directly using mod p arithmetic:
479
480 for (i = 0; i < F->q; i++) {
481 for (j = 0; j < F->q; j++) {
482 if (i == 0 || j == 0) {
483 mult_table[i * F->q + j] = 0;
484 continue;
485 }
486 k = (i * j) % F->q;
487 mult_table[i * F->q + j] = k;
488 if (k == 1) {
489 inv_table[i] = j;
490 }
491 }
492 }
493 inv_table[0] = -999999999;
494
495 // compute reordered_list_of_elements[]
496 // and reordered_list_of_elements_inv[]:
497
498 reordered_list_of_elements[0] = 0;
499 reordered_list_of_elements[1] = 1;
500 if (F->q >= 2) {
501 reordered_list_of_elements[2] = F->alpha;
502 }
503 reordered_list_of_elements_inv[0] = 0;
504 reordered_list_of_elements_inv[F->alpha] = 1;
505
506 for (i = 3; i < F->q; i++) {
507 a = mult_table[reordered_list_of_elements[i - 1] * F->q + F->alpha];
508 reordered_list_of_elements[i] = a;
509 reordered_list_of_elements_inv[a] = i;
510 }
511
512 if (f_v) {
513 cout << "finite_field_implementation_by_tables::create_tables_prime_field finished" << endl;
514 }
515}
516
518// assumes that alpha_table and log_alpha_table have been computed already
519{
520 int f_v = (verbose_level >= 1);
521 long int i, j, l, k, ii, jj, kk, a;
523
524 if (f_v) {
525 cout << "finite_field_implementation_by_tables::create_tables_extension_field" << endl;
526 }
527
528 // compute addition table and negation table:
529
530 for (i = 0; i < F->q; i++) {
531 Gg.AG_element_unrank(F->p, v1, 1, F->e, i);
532 for (j = 0; j < F->q; j++) {
533 Gg.AG_element_unrank(F->p, v2, 1, F->e, j);
534 for (l = 0; l < F->e; l++) {
535 v3[l] = (v1[l] + v2[l]) % F->p;
536 }
537 k = Gg.AG_element_rank(F->p, v3, 1, F->e);
538 add_table[i * F->q + j] = k;
539 if (k == 0) {
540 negate_table[i] = j;
541 }
542 }
543 }
544
545 // compute multiplication table and inverse table
546 // using discrete logarithms:
547
548 for (i = 0; i < F->q; i++) {
549 mult_table[i * F->q + 0] = 0;
550 mult_table[0 * F->q + i] = 0;
551 }
552
553 for (i = 1; i < F->q; i++) {
554 ii = log_alpha_table[i];
555 for (j = 1; j < F->q; j++) {
556 jj = log_alpha_table[j];
557 kk = (ii + jj) % (F->q - 1);
558 k = alpha_power_table[kk];
559 mult_table[i * F->q + j] = k;
560 if (FALSE) {
561 cout << "finite_field_implementation_by_tables::create_tables_extension_field " << i << " * " << j << " = " << k << endl;
562 }
563 if (k == 1) {
564 inv_table[i] = j;
565 }
566 }
567 }
568
569 // compute reordered_list_of_elements[]
570 // and reordered_list_of_elements_inv[]:
571
572 reordered_list_of_elements[0] = 0;
573 reordered_list_of_elements[1] = F->p;
574 reordered_list_of_elements_inv[0] = 0;
575 reordered_list_of_elements_inv[F->p] = 1;
576
577 for (i = 2; i < F->q; i++) {
578 a = mult_table[reordered_list_of_elements[i - 1] * F->q + F->p];
579 reordered_list_of_elements[i] = a;
580 reordered_list_of_elements_inv[a] = i;
581 }
582
583 if (f_v) {
584 cout << "finite_field_implementation_by_tables::create_tables_extension_field finished" << endl;
585 }
586}
587
589{
590 ost << "addition table:" << endl;
591 Int_vec_print_integer_matrix_width(ost, add_table, F->q, F->q, F->q, F->log10_of_q + 1);
592 ost << endl;
593
594
595 ost << "multiplication table:" << endl;
596 Int_vec_print_integer_matrix_width(ost, mult_table, F->q, F->q, F->q, F->log10_of_q + 1);
597 ost << endl;
598}
599
601{
602
603 string fname;
604
605 fname.assign(fname_base);
606 fname.append(".cpp");
607
608 {
609 ofstream ost(fname);
610
611 ost << "//addition, multiplication, inversion and negation table:" << endl;
612 ost << "int add_table[] = ";
613 Int_vec_print_integer_matrix_in_C_source(ost, add_table, F->q, F->q);
614 ost << endl;
615
616
617 ost << "int mult_table[] = ";
618 Int_vec_print_integer_matrix_in_C_source(ost, mult_table, F->q, F->q);
619 ost << endl;
620
621 ost << "int inv_table[] = ";
622 Int_vec_print_integer_matrix_in_C_source(ost, inv_table, 1, F->q);
623 ost << endl;
624
625 ost << "int neg_table[] = ";
626 Int_vec_print_integer_matrix_in_C_source(ost, negate_table, 1, F->q);
627 ost << endl;
628 }
629
630}
631
632
634{
635 int f_v = (verbose_level >= 1);
636
637 if (f_v) {
638 cout << "finite_field_implementation_by_tables::init_quadratic_subfield" << endl;
639 }
640 f_belongs_to_quadratic_subfield = NEW_int(F->q);
641 Int_vec_zero(f_belongs_to_quadratic_subfield, F->q);
642
643 if (EVEN(F->e)) {
644 int i, a, b, idx, sqrt_q;
646
647
648 f_has_quadratic_subfield = TRUE;
649 sqrt_q = NT.i_power_j(F->p, F->e >> 1);
650 idx = (F->q - 1) / (sqrt_q - 1);
651 f_belongs_to_quadratic_subfield[0] = TRUE;
652 for (i = 0; i < sqrt_q - 1; i++) {
653 a = idx * i;
654 b = F->alpha_power(a);
655 f_belongs_to_quadratic_subfield[b] = TRUE;
656 }
657 }
658 else {
659 f_has_quadratic_subfield = FALSE;
660 }
661 if (f_v) {
662 cout << "finite_field_implementation_by_tables::init_quadratic_subfield done" << endl;
663 }
664}
665
667{
668 int f_v = (verbose_level >= 1);
669 int i;
670
671 if (f_v) {
672 cout << "finite_field_implementation_by_tables::init_frobenius_table" << endl;
673 }
674
675 frobenius_table = NEW_int(F->q);
676
677 if (F->e == 1) {
678 for (i = 0; i < F->q; i++) {
679 frobenius_table[i] = i;
680 }
681 }
682 else {
683
684 for (i = 0; i < F->q; i++) {
685 frobenius_table[i] = F->power_verbose(i, F->p, 0 /* verbose_level */);
686 if (f_v) {
687 cout << "finite_field_implementation_by_tables::init_frobenius_table frobenius_table[" << i << "]="
688 << frobenius_table[i] << endl;
689 }
690 }
691 }
692
693 if (f_v) {
694 cout << "finite_field_implementation_by_tables::init_frobenius_table done" << endl;
695 }
696}
697
699{
700 int f_v = (verbose_level >= 1);
701 int i;
702
703 if (f_v) {
704 cout << "finite_field_implementation_by_tables::init_absolute_trace_table" << endl;
705 }
706
707
708 absolute_trace_table = NEW_int(F->q);
709 if (F->e == 1) {
710 for (i = 0; i < F->q; i++) {
711 absolute_trace_table[i] = 0;
712 }
713 }
714 else {
715 for (i = 0; i < F->q; i++) {
716 absolute_trace_table[i] = F->absolute_trace(i);
717 }
718 }
719
720 if (f_v) {
721 cout << "finite_field_implementation_by_tables::init_absolute_trace_table done" << endl;
722 }
723}
724
726{
727 int i, a, b, c, l;
728 int verbose_level = 0;
729
731 GFp.finite_field_init(F->p, FALSE /* f_without_tables */, 0);
732
735
736
737
738 FX.create_object_by_rank_string(m, poly, verbose_level);
739
740 ring_theory::unipoly_domain Fq(&GFp, m, 0 /* verbose_level */);
742
743
744
745 cout << "i : inverse(i) : frobenius_power(i, 1) : alpha_power(i) : "
746 "log_alpha(i) : elt[i]" << endl;
747 for (i = 0; i < F->q; i++) {
748 if (i)
749 a = F->inverse(i);
750 else
751 a = -1;
752 if (i)
753 l = F->log_alpha(i);
754 else
755 l = -1;
756 b = F->frobenius_power(i, 1);
757 c = F->alpha_power(i);
758 cout << setw(4) << i << " : "
759 << setw(4) << a << " : "
760 << setw(4) << b << " : "
761 << setw(4) << c << " : "
762 << setw(4) << l << " : ";
763 Fq.create_object_by_rank(elt, i, __FILE__, __LINE__, verbose_level);
764 Fq.print_object(elt, cout);
765 cout << endl;
766 Fq.delete_object(elt);
767
768 }
769 // FX.delete_object(m); // this had to go, Anton Betten, Oct 30, 2011
770
771 //cout << "print_tables finished" << endl;
772#if 0
773 cout << "inverse table:" << endl;
774 cout << "{";
775 for (i = 1; i < q; i++) {
776 cout << inverse(i);
777 if (i < q - 1)
778 cout << ", ";
779 }
780 cout << "};" << endl;
781 cout << "frobenius_table:" << endl;
782 //print_integer_matrix(cout, frobenius_table, 1, q);
783 cout << "i : i^p" << endl;
784 for (i = 0; i < q; i++) {
785 cout << i << " : " << frobenius_table[i] << endl;
786 }
787
788
789 cout << "primitive element alpha = " << alpha << endl;
790 cout << "i : alpha^i" << endl;
791 for (i = 0; i < q; i++) {
792 //j = power(p, i);
793 cout << i << " : " << alpha_power_table[i] << endl;
794 }
795 cout << "i : log_alpha(i)" << endl;
796 for (i = 0; i < q; i++) {
797 cout << i << " : " << log_alpha_table[i] << endl;
798 }
799#endif
800
801 //cout << "alpha_power_table:" << endl;
802 //print_integer_matrix(cout, alpha_power_table, 1, q);
803 //cout << "log_alpha_table:" << endl;
804 //print_integer_matrix(cout, log_alpha_table, 1, q);
805}
806
808{
810
811 if (i < 0 || i >= F->q) {
812 cout << "finite_field_implementation_by_tables::add out of range, i = " << i << endl;
813 exit(1);
814 }
815 if (j < 0 || j >= F->q) {
816 cout << "finite_field_implementation_by_tables::add out of range, j = " << j << endl;
817 exit(1);
818 }
819
820 return add_table[i * F->q + j];
821}
822
824{
826
827 if (i < 0 || i >= F->q) {
828 cout << "finite_field_implementation_by_tables::add_without_table out of range, i = " << i << endl;
829 exit(1);
830 }
831 if (j < 0 || j >= F->q) {
832 cout << "finite_field_implementation_by_tables::add_without_table out of range, j = " << j << endl;
833 exit(1);
834 }
835
836 long int l, k;
837
838 Gg.AG_element_unrank(F->p, v1, 1, F->e, i);
839 Gg.AG_element_unrank(F->p, v2, 1, F->e, j);
840 for (l = 0; l < F->e; l++) {
841 v3[l] = (v1[l] + v2[l]) % F->p;
842 }
843 k = Gg.AG_element_rank(F->p, v3, 1, F->e);
844 return k;
845}
846
847int finite_field_implementation_by_tables::mult_verbose(int i, int j, int verbose_level)
848{
849 int f_v = (verbose_level >= 1);
850 int c;
851
852 if (f_v) {
853 cout << "finite_field_implementation_by_tables::mult_verbose" << endl;
854 }
855 if (i < 0 || i >= F->q) {
856 cout << "finite_field_implementation_by_tables::mult_verbose out of range, i = " << i << endl;
857 exit(1);
858 }
859 if (j < 0 || j >= F->q) {
860 cout << "finite_field_implementation_by_tables::mult_verbose out of range, j = " << j << endl;
861 exit(1);
862 }
863 if (f_v) {
864 cout << "finite_field_implementation_by_tables::mult_verbose with table" << endl;
865 }
866 c = mult_table[i * F->q + j];
867 if (f_v) {
868 cout << "finite_field_implementation_by_tables::mult_verbose " << i << " * " << j << " = " << c << endl;
869 }
870 return c;
871}
872
874{
875 int f_v = (verbose_level >= 1);
876 int c;
877
878 if (f_v) {
879 cout << "finite_field_implementation_by_tables::mult_using_discrete_log" << endl;
880 }
881 if (i < 0 || i >= F->q) {
882 cout << "finite_field_implementation_by_tables::mult_using_discrete_log "
883 "out of range, i = " << i << endl;
884 exit(1);
885 }
886 if (j < 0 || j >= F->q) {
887 cout << "finite_field_implementation_by_tables::mult_using_discrete_log "
888 "out of range, j = " << j << endl;
889 exit(1);
890 }
891 if (f_v) {
892 cout << "finite_field_implementation_by_tables::mult_using_discrete_log with table" << endl;
893 }
894
895 int ii, jj, kk;
896
897 if (f_v) {
898 cout << "finite_field_implementation_by_tables::mult_using_discrete_log without table" << endl;
899 }
900 if (i == 0 || j == 0) {
901 return 0;
902 }
903 ii = log_alpha_table[i];
904 if (f_v) {
905 cout << "finite_field_implementation_by_tables::mult_using_discrete_log ii = " << ii << endl;
906 }
907 jj = log_alpha_table[j];
908 if (f_v) {
909 cout << "finite_field_implementation_by_tables::mult_using_discrete_log jj = " << jj << endl;
910 }
911 kk = (ii + jj) % (F->q - 1);
912 if (f_v) {
913 cout << "finite_field_implementation_by_tables::mult_using_discrete_log kk = " << kk << endl;
914 }
915 c = alpha_power_table[kk];
916 if (f_v) {
917 cout << "finite_field_implementation_by_tables::mult_using_discrete_log c = " << c << endl;
918 }
919
920 if (f_v) {
921 cout << "finite_field_implementation_by_tables::mult_using_discrete_log done" << endl;
922 }
923 return c;
924}
925
927{
929
930 if (i < 0 || i >= F->q) {
931 cout << "finite_field_implementation_by_tables::negate out of range, i = " << i << endl;
932 exit(1);
933 }
934
935 return negate_table[i];
936}
937
939{
941
942 if (i < 0 || i >= F->q) {
943 cout << "finite_field_implementation_by_tables::negate_without_table out of range, i = " << i << endl;
944 exit(1);
945 }
946 long int l, k;
947
948 Gg.AG_element_unrank(F->p, v1, 1, F->e, i);
949 for (l = 0; l < F->e; l++) {
950 v2[l] = (F->p - v1[l]) % F->p;
951 }
952 k = Gg.AG_element_rank(F->p, v2, 1, F->e);
953 return k;
954}
955
956
957
959{
960 if (i <= 0 || i >= F->q) {
961 cout << "finite_field_implementation_by_tables::inverse out of range, i = " << i << endl;
962 exit(1);
963 }
964
965 return inv_table[i];
966}
967
969{
970 if (i <= 0 || i >= F->q) {
971 cout << "finite_field_implementation_by_tables::inverse_without_table out of range, i = " << i << endl;
972 exit(1);
973 }
974
975 int ii, jj, j;
976
977 ii = log_alpha_table[i];
978 jj = (F->q - 1 - ii) % (F->q - 1);
979 j = alpha_power_table[jj];
980 return j;
981}
982
984// computes a^p
985{
986 return frobenius_table[a];
987}
988
989
991// computes a^{p^frob_power}
992{
993 int j, b;
994
995
996 b = a;
997 for (j = 0; j < frob_power; j++) {
998 b = frobenius_table[b];
999 }
1000 return b;
1001}
1002
1004{
1005 return alpha_power_table[i];
1006}
1007
1009{
1010 return log_alpha_table[i];
1011}
1012
1014{
1015 int f_v = (verbose_level >= 1);
1016
1017 if (f_v) {
1018 cout << "finite_field_implementation_by_tables::addition_table_reordered_save_csv" << endl;
1019 }
1020 int i, j, a, b, c;
1021 int *M;
1023
1024 M = NEW_int(F->q * F->q);
1025 for (i = 0; i < F->q; i++) {
1026 a = reordered_list_of_elements[i];
1027 for (j = 0; j < F->q; j++) {
1028 b = reordered_list_of_elements[j];
1029 c = F->add(a, b);
1030 //k = reordered_list_of_elements_inv[c];
1031 M[i * F->q + j] = c;
1032 }
1033 }
1034
1035 Fio.int_matrix_write_csv(fname, M, F->q, F->q);
1036 if (f_v) {
1037 cout << "finite_field_implementation_by_tables::addition_table_reordered_save_csv Written file " << fname << " of size " << Fio.file_size(fname) << endl;
1038 }
1039 FREE_int(M);
1040}
1041
1043{
1044 int f_v = (verbose_level >= 1);
1045
1046 if (f_v) {
1047 cout << "finite_field_implementation_by_tables::multiplication_table_reordered_save_csv" << endl;
1048 }
1049 int i, j, a, b, c;
1050 int *M;
1052
1053 M = NEW_int(F->q * F->q);
1054 for (i = 1; i < F->q; i++) {
1055 a = reordered_list_of_elements[i];
1056 for (j = 1; j < F->q; j++) {
1057 b = reordered_list_of_elements[j];
1058 c = F->mult(a, b);
1059 //k = reordered_list_of_elements_inv[c];
1060 if (c == 0) {
1061 cout << "finite_field_implementation_by_tables::multiplication_table_reordered_save_csv c == 0" << endl;
1062 exit(1);
1063 }
1064 M[(i - 1) * (F->q - 1) + j - 1] = c;
1065 }
1066 }
1067
1068 Fio.int_matrix_write_csv(fname, M, F->q - 1, F->q - 1);
1069 if (f_v) {
1070 cout << "finite_field_implementation_by_tables::multiplication_table_reordered_save_csv Written file " << fname << " of size " << Fio.file_size(fname) << endl;
1071 }
1072 FREE_int(M);
1073}
1074
1075
1076
1077
1078
1079}}}
1080
1081
int power_verbose(int a, int n, 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)
void int_matrix_write_csv(std::string &fname, int *M, int m, int n)
Definition: file_io.cpp:1300
domain of polynomials in one variable over a finite field
Definition: ring_theory.h:691
void mult(unipoly_object a, unipoly_object b, unipoly_object &c, int verbose_level)
void create_object_by_rank(unipoly_object &p, long int rk, const char *file, int line, int verbose_level)
void create_object_by_rank_string(unipoly_object &p, std::string &rk, int verbose_level)
void assign(unipoly_object a, unipoly_object &b, int verbose_level)
void print_object(unipoly_object p, std::ostream &ost)
#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 Int_vec_print_integer_matrix_in_C_source(A, B, C, D)
Definition: foundations.h:726
#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 EVEN(x)
Definition: foundations.h:221
the orbiter library for the classification of combinatorial objects