17namespace layer1_foundations {
18namespace field_theory {
88 cout <<
"finite_field::print_call_stats" << endl;
89 cout <<
"nb_calls_to_mult_matrix_matrix="
91 cout <<
"nb_calls_to_PG_element_rank_modified="
93 cout <<
"nb_calls_to_PG_element_unrank_modified="
99 int f_v = (verbose_level >= 1);
102 cout <<
"finite_field::init" << endl;
105 cout <<
"finite_field::init !Descr->f_q" << endl;
120 cout <<
"finite_field::init before init_override_polynomial" << endl;
125 cout <<
"finite_field::init after init_override_polynomial" << endl;
132 cout <<
"finite_field::init before finite_field_init" << endl;
136 cout <<
"finite_field::init after finite_field_init" << endl;
141 cout <<
"finite_field::init done" << endl;
147 int f_v = (verbose_level >= 1);
152 cout <<
"finite_field::finite_field_init q=" <<
q <<
" verbose_level = " << verbose_level << endl;
175 cout <<
"finite_field::finite_field_init q=" <<
q <<
" before init_override_polynomial poly = " << poly << endl;
179 cout <<
"finite_field::finite_field_init q=" <<
q <<
" after init_override_polynomial" << endl;
186 cout <<
"finite_field::finite_field_init q=" <<
q <<
" before init_override_polynomial poly = " << poly << endl;
190 cout <<
"finite_field::finite_field_init q=" <<
q <<
" after init_override_polynomial" << endl;
196 sprintf(str,
"GF_%d",
q);
198 sprintf(str,
"{\\mathbb F}_{%d}",
q);
204 cout <<
"finite_field::finite_field_init done" << endl;
210 int f_v = (verbose_level >= 1);
215 cout <<
"finite_field::init_implementation" << endl;
219 if (f_without_tables) {
221 cout <<
"finite_field::init_implementation implementation without field tables" << endl;
228 cout <<
"finite_field::init_implementation before Iwo->init" << endl;
230 Iwo->
init(
this, verbose_level);
232 cout <<
"finite_field::init_implementation after Iwo->init" << endl;
237 cout <<
"finite_field::init_implementation implementation with field tables" << endl;
242 cout <<
"finite_field::init_implementation before T->init" << endl;
244 T->
init(
this, verbose_level);
246 cout <<
"finite_field::init_implementation after T->init" << endl;
253 cout <<
"finite_field::init_implementation done" << endl;
286 symbol_for_print.assign(symbol);
290 std::string &poly,
int f_without_tables,
int verbose_level)
292 int f_v = (verbose_level >= 1);
293 int f_vv = (verbose_level >= 2);
297 cout <<
"finite_field::init_override_polynomial "
298 "q=" <<
q <<
" verbose_level = " << verbose_level << endl;
305 cout <<
"finite_field::init_override_polynomial p=" <<
p << endl;
306 cout <<
"finite_field::init_override_polynomial e=" <<
e << endl;
316 if (poly.length() == 0) {
322 cout <<
"finite_field::init_override_polynomial, "
323 "using polynomial " <<
my_poly << endl;
327 cout <<
"finite_field::init_override_polynomial "
328 "using poly " <<
my_poly << endl;
335 cout <<
"finite_field::init_override_polynomial "
336 "GF(" <<
q <<
") = GF(" <<
p <<
"^" <<
e <<
")";
338 cout <<
", polynomial = ";
340 cout <<
" = " <<
my_poly << endl;
350 strcpy(polynomial,
my_poly.c_str());
355 sprintf(str,
"GF_%d",
q);
357 label.append(
"_poly");
360 sprintf(str,
"{\\mathbb F}_{%d,",
q);
367 cout <<
"finite_field::init_override_polynomial before init_implementation" << endl;
371 cout <<
"finite_field::init_override_polynomial after init_implementation" << endl;
375 cout <<
"finite_field::init_override_polynomial "
386 cout <<
"finite_field::has_quadratic_subfield !f_has_table" << endl;
403 cout <<
"finite_field::belongs_to_quadratic_subfield does not have a quadratic subfield" << endl;
407 cout <<
"finite_field::belongs_to_quadratic_subfield !f_has_table" << endl;
414 int f_latex, std::ostream &ost,
417 int f_v = (verbose_level >= 1);
418 int f_vv = (verbose_level >= 2);
419 int p1, e1, q1, i, j, jj, subgroup_index;
423 cout <<
"finite_field::compute_subfield_polynomial "
424 "for subfield of order " << order_subfield << endl;
428 cout <<
"finite_field::compute_subfield_polynomial "
429 "the subfield must have the same characteristic" << endl;
433 cout <<
"finite_field::compute_subfield_polynomial "
434 "is not a subfield" << endl;
451 int rk, kernel_m, kernel_n;
461 subgroup_index = (
q - 1) / (q1 - 1);
463 cout <<
"finite_field::compute_subfield_polynomial "
464 "subfield " <<
p <<
"^" << e1 <<
" : subgroup_index = "
465 << subgroup_index << endl;
467 for (i = 0; i <= e1; i++) {
468 j = i * subgroup_index;
476 cout << i <<
" : " << j <<
" : " << jj <<
" : ";
486 ost <<
"\\begin{array}{|c|c|c|c|}" << endl;
487 ost <<
"\\hline" << endl;
488 ost <<
"i & i\\cdot d & \\alpha^{id} & \\mbox{vector} \\\\" << endl;
489 ost <<
"\\hline" << endl;
493 for (i = 0; i <= e1; i++) {
496 j = i * subgroup_index;
503 for (h =
e - 1; h >= 0; h--) {
504 ost << M[h * (e1 + 1) + i];
510 ost <<
"\\\\" << endl;
514 ost <<
"\\hline" << endl;
515 ost <<
"\\end{array}" << endl;
521 cout <<
"finite_field::compute_subfield_polynomial M=" << endl;
523 e, e1 + 1, e1 + 1,
GFp.log10_of_q);
525 rk =
GFp.Linear_algebra->Gauss_simple(M,
e, e1 + 1,
528 cout <<
"finite_field::compute_subfield_polynomial after Gauss=" << endl;
530 e, e1 + 1, e1 + 1,
GFp.log10_of_q);
531 cout <<
"rk=" << rk << endl;
534 cout <<
"finite_field::compute_subfield_polynomial fatal: rk != e1" << endl;
535 cout <<
"rk=" << rk << endl;
539 GFp.Linear_algebra->matrix_get_kernel(M,
e, e1 + 1, base_cols, rk,
540 kernel_m, kernel_n, K, 0 );
543 cout <<
"kernel_m=" << kernel_m << endl;
544 cout <<
"kernel_n=" << kernel_n << endl;
547 cout <<
"kernel_n != 1" << endl;
551 cout <<
"K[e1] == 0" << endl;
555 a =
GFp.inverse(K[e1]);
556 for (i = 0; i < e1 + 1; i++) {
557 K[i] =
GFp.mult(a, K[i]);
561 ost <<
"Left nullspace generated by:\\\\" << endl;
568 cout <<
"finite_field::compute_subfield_polynomial the relation is " << endl;
579 cout <<
"finite_field::compute_subfield_polynomial "
581 <<
" : " << a <<
" = ";
595 int f_v = (verbose_level >= 1);
601 cout <<
"finite_field::compute_subfields" << endl;
603 cout <<
"subfields of F_{" <<
q <<
"}:" << endl;
616 for (e1 = 2; e1 <
e; e1++) {
628 poly, __FILE__, __LINE__, verbose_level);
629 cout <<
"subfield of order " << NT.
i_power_j(
p, e1)
630 <<
" : " << poly <<
" = ";
643 int f_v = (verbose_level >= 1);
647 cout <<
"finite_field::find_primitive_element" << endl;
649 for (i = 2; i <
q; i++) {
652 cout <<
"finite_field::find_primitive_element the order of " << i <<
" is " << ord << endl;
659 cout <<
"finite_field::find_primitive_element could not find a primitive element" << endl;
663 cout <<
"finite_field::find_primitive_element done" << endl;
671 int f_v = (verbose_level >= 1);
672 int f_vv = (verbose_level >= 2);
676 cout <<
"finite_field::compute_order_of_element "
677 "q=" <<
q <<
" p=" <<
p <<
" e=" <<
e <<
" elt=" << elt << endl;
701 for (i = 1; i <
q; i++) {
704 cout <<
"i=" << i << endl;
710 cout <<
" has rank " << k << endl;
712 if (k < 0 || k >=
q) {
713 cout <<
"finite_field::compute_order_of_element error: k = " << k << endl;
719 Fq.
mult(a, Alpha, c, verbose_level - 1);
720 Fq.
assign(c, a, verbose_level - 2);
729 cout <<
"finite_field::compute_order_of_element done "
730 "q=" <<
q <<
" p=" <<
p <<
" e=" <<
e <<
" order of " << elt <<
" is " << i << endl;
742 cout <<
"finite_field::private_add_table !f_has_table" << endl;
751 cout <<
"finite_field::private_mult_table !f_has_table" << endl;
799 int f_v = (verbose_level >= 1);
803 cout <<
"finite_field_by_tables::mult_verbose" << endl;
807 if (i < 0 || i >=
q) {
808 cout <<
"finite_field_by_tables::mult_verbose i = " << i << endl;
811 if (j < 0 || j >=
q) {
812 cout <<
"finite_field_by_tables::mult_verbose j = " << j << endl;
817 cout <<
"finite_field_by_tables::mult_verbose with table" << endl;
823 cout <<
"finite_field_by_tables::mult_verbose !f_has_table && Iwo == NULL" << endl;
826 c = Iwo->
mult(i, j, verbose_level);
836 cout <<
"finite_field::a_over_b b == 0" << endl;
924 for (i = 1; i < n; i++) {
948 return mult(four, a);
962 int verbose_level = 0;
963 int f_v = (verbose_level >= 1);
968 cout <<
"finite_field::add !f_has_table" << endl;
973 cout <<
"finite_field_by_tables::add with table" << endl;
979 cout <<
"finite_field_by_tables::add !f_has_table && Iwo == NULL" << endl;
982 c = Iwo->
add(i, j, verbose_level);
1044 int i6,
int i7,
int i8)
1060 int verbose_level = 0;
1061 int f_v = (verbose_level >= 1);
1064 if (i < 0 || i >=
q) {
1065 cout <<
"finite_field::negate i = " << i << endl;
1070 cout <<
"finite_field_by_tables::negate with table" << endl;
1076 cout <<
"finite_field_by_tables::negate !f_has_table && Iwo == NULL" << endl;
1079 c = Iwo->
negate(i, verbose_level);
1088 int verbose_level = 0;
1089 int f_v = (verbose_level >= 1);
1093 cout <<
"finite_field_by_tables::inverse with table" << endl;
1099 cout <<
"finite_field_by_tables::inverse !f_has_table && Iwo == NULL" << endl;
1102 c = Iwo->
inverse(i, verbose_level);
1116 int f_v = (verbose_level >= 1);
1120 cout <<
"finite_field::power_verbose a=" << a <<
" n=" << n << endl;
1126 cout <<
"finite_field::power_verbose n=" << n
1127 <<
" a=" << a <<
" b=" << b <<
" c=" << c << endl;
1140 cout <<
"finite_field::power_verbose a=" << a
1141 <<
" n=" << n <<
" c=" << c <<
" done" << endl;
1150 for (h = 0; h < len; h++) {
1159 for (h = 0; h < len; h++) {
1168 cout <<
"finite_field::frobenius_power !f_has_table" << endl;
1177 int j, ii = i, t = 0;
1180 cout <<
"finite_field::absolute_trace !f_has_table" << endl;
1183 for (j = 0; j <
e; j++) {
1191 cout <<
"finite_field::absolute_trace ii != i" << endl;
1192 cout <<
"i=" << i << endl;
1193 cout <<
"ii=" << ii << endl;
1195 for (j = 0; j <
e; j++) {
1197 cout <<
"j=" << j <<
" ii=" << ii << endl;
1206 int j, ii = i, t = 1;
1209 cout <<
"finite_field::absolute_norm !f_has_table" << endl;
1212 for (j = 0; j <
e; j++) {
1220 cout <<
"finite_field::absolute_norm ii != i" << endl;
1229 cout <<
"finite_field::alpha_power !f_has_table" << endl;
1238 cout <<
"finite_field::log_alpha !f_has_table" << endl;
1250 cout <<
"finite_field::multiplicative_order a == 0" << endl;
1255 order = (
q - 1) / g;
1285 roots2[1] =
negate(roots2[0]);
1309 cout <<
"finite_field::square_root not a square: " << i << endl;
1330 cout <<
"finite_field::N2 field does not have a "
1331 "quadratic subfield" << endl;
1346 cout <<
"finite_field::N3 field does not have a "
1347 "cubic subfield" << endl;
1364 cout <<
"finite_field::T2 field does not have a "
1365 "quadratic subfield" << endl;
1380 cout <<
"finite_field::T3 field does not have a "
1381 "cubic subfield" << endl;
1398 cout <<
"finite_field::bar field does not have a "
1399 "quadratic subfield" << endl;
1407 int &x,
int &y,
int verbose_level)
1412 int f_v = (verbose_level >= 1);
1416 cout <<
"finite_field::abc2xy q=" <<
q
1417 <<
" a=" << a <<
" b=" << b <<
" c=" << c << endl;
1419 for (x = 0; x <
q; x++) {
1421 for (y = 0; y <
q; y++) {
1426 cout <<
"finite_field::abc2xy q=" <<
q
1427 <<
" x=" << x <<
" y=" << y <<
" done" << endl;
1433 cout <<
"finite_field::abc2xy no solution" << endl;
1434 cout <<
"a=" << a << endl;
1435 cout <<
"b=" << b << endl;
1436 cout <<
"c=" << c << endl;
1441 int index,
int a,
int verbose_level)
1450 int index,
int *v_in,
int *v_out,
int len,
1453 int f_v = (verbose_level >= 1);
1454 int a, b, i, j, idx, m, n, k;
1458 cout <<
"finite_field::retract_int_vec index=" << index << endl;
1462 if (m != subfield.
q) {
1463 cout <<
"finite_field::retract_int_vec subfield "
1464 "order does not match" << endl;
1467 idx = (
q - 1) / (m - 1);
1469 cout <<
"finite_field::retract_int_vec "
1470 "subfield " <<
p <<
"^" << n <<
" = " << n << endl;
1471 cout <<
"idx = " << idx << endl;
1474 for (k = 0; k < len; k++) {
1482 cout <<
"finite_field::retract_int_vec index=" << index
1483 <<
" k=" << k <<
" a=" << a << endl;
1484 cout <<
"element does not lie in the subfield" << endl;
1492 cout <<
"finite_field::retract_int_vec done" << endl;
1497 int index,
int b,
int verbose_level)
1499 int f_v = (verbose_level >= 1);
1500 int a, i, j, idx, m, n;
1504 cout <<
"finite_field::embed index=" << index
1505 <<
" b=" << b << endl;
1514 if (m != subfield.
q) {
1515 cout <<
"finite_field::embed subfield order does not match" << endl;
1518 idx = (
q - 1) / (m - 1);
1520 cout <<
"subfield " <<
p <<
"^" << n <<
" = " << n << endl;
1521 cout <<
"idx = " << idx << endl;
1527 cout <<
"finite_field::embed index=" << index
1528 <<
" b=" << b <<
" a=" << a << endl;
1535 int *&components,
int *&embedding,
int *&pair_embedding,
1549 int f_v = (verbose_level >= 1);
1550 int f_vv = (verbose_level >= 1);
1551 int alpha, i, j, I, J, x,
q, Q;
1554 cout <<
"finite_field::subfield_embedding_2dimensional" << endl;
1563 for (i = 0; i <
q *
q; i++) {
1564 pair_embedding[i] = -1;
1566 for (i = 0; i < Q * 2; i++) {
1569 for (i = 1; i <
q; i++) {
1570 j =
embed(subfield, 2, i, verbose_level - 2);
1573 for (i = 0; i <
q; i++) {
1574 I =
embed(subfield, 2, i, verbose_level - 4);
1576 cout <<
"i=" << i <<
" I=" << I << endl;
1578 for (j = 0; j <
q; j++) {
1579 J =
embed(subfield, 2, j, verbose_level - 4);
1581 if (pair_embedding[i *
q + j] != -1) {
1582 cout <<
"error" << endl;
1583 cout <<
"element (" << i <<
"," << j <<
") embeds "
1584 "as (" << I <<
"," << J <<
") = " << x << endl;
1587 pair_embedding[i *
q + j] = x;
1588 components[x * 2 + 0] = i;
1589 components[x * 2 + 1] = j;
1591 cout <<
"element (" << i <<
"," << j <<
") embeds "
1592 "as (" << I <<
"," << J <<
") = " << x << endl;
1598 embedding, pair_embedding);
1601 cout <<
"finite_field::subfield_embedding_2dimensional "
1608 return nb_times_mult;
1613 return nb_times_add;
1618 int f_v = (verbose_level >= 1);
1622 cout <<
"finite_field::compute_nth_roots" << endl;
1626 cout <<
"finite_field::compute_nth_roots n does not divide q - 1" << endl;
1634 Nth_roots[1] = beta;
1635 for (i = 2; i < n; i++) {
1636 Nth_roots[i] =
mult(Nth_roots[i - 1], beta);
1641 cout <<
"finite_field::compute_nth_roots done" << endl;
description of a finite field
std::string override_polynomial
int f_override_polynomial
implementation of a finite Galois field Fq using tables
void init(finite_field *F, int verbose_level)
int mult_verbose(int i, int j, int verbose_level)
int frobenius_power(int a, int frob_power)
int frobenius_image(int a)
int has_quadratic_subfield()
int * private_add_table()
int belongs_to_quadratic_subfield(int a)
int * private_mult_table()
implementation of a finite Galois field Fq without any tables
int inverse(int i, int verbose_level)
void init(finite_field *F, int verbose_level)
int negate(int i, int verbose_level)
int add(int i, int j, int verbose_level)
int mult(int i, int j, int verbose_level)
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)
int add4(int i1, int i2, int i3, int i4)
int f_print_as_exponentials
void print_minimum_polynomial(int p, std::string &polynomial)
int power_verbose(int a, int n, int verbose_level)
void init(finite_field_description *Descr, int verbose_level)
int product5(int a1, int a2, int a3, int a4, int a5)
int * private_mult_table()
std::string override_poly
int nb_times_add_called()
long int nb_calls_to_PG_element_unrank_modified
int nb_times_mult_called()
long int nb_calls_to_PG_element_rank_modified
orthogonal_geometry::orthogonal_indexing * Orthogonal_indexing
void print_call_stats(std::ostream &ost)
int mult_verbose(int i, int j, int verbose_level)
int mult6(int a1, int a2, int a3, int a4, int a5, int a6)
int belongs_to_quadratic_subfield(int a)
void init_symbol_for_print(const char *symbol)
int mult3(int a1, int a2, int a3)
int multiplicative_order(int a)
void compute_nth_roots(int *&Nth_roots, int n, int verbose_level)
void retract_int_vec(finite_field &subfield, int index, int *v_in, int *v_out, int len, int verbose_level)
int product3(int a1, int a2, int a3)
int product_n(int *a, int n)
int product4(int a1, int a2, int a3, int a4)
int frobenius_power(int a, int frob_power)
int mult5(int a1, int a2, int a3, int a4, int a5)
int add3(int i1, int i2, int i3)
int a_over_b(int a, int b)
int add7(int i1, int i2, int i3, int i4, int i5, int i6, int i7)
void finite_field_init(int q, int f_without_tables, int verbose_level)
int compute_order_of_element(int elt, int verbose_level)
void init_implementation(int f_without_tables, int verbose_level)
void frobenius_power_vec(int *v, int len, int frob_power)
void init_override_polynomial(int q, std::string &poly, int f_without_tables, int verbose_level)
void set_default_symbol_for_print()
int find_primitive_element(int verbose_level)
void subfield_embedding_2dimensional(finite_field &subfield, int *&components, int *&embedding, int *&pair_embedding, int verbose_level)
int absolute_trace(int i)
int * private_add_table()
linear_algebra::linear_algebra * Linear_algebra
void print_embedding(finite_field &subfield, int *components, int *embedding, int *pair_embedding)
long int nb_calls_to_mult_matrix_matrix
void compute_subfields(int verbose_level)
int has_quadratic_subfield()
int retract(finite_field &subfield, int index, int a, int verbose_level)
int mult4(int a1, int a2, int a3, int a4)
void frobenius_power_vec_to_vec(int *v_in, int *v_out, int len, int frob_power)
void abc2xy(int a, int b, int c, int &x, int &y, int verbose_level)
void all_square_roots(int a, int &nb_roots, int *roots2)
long int compute_subfield_polynomial(int order_subfield, int f_latex, std::ostream &ost, int verbose_level)
int add6(int i1, int i2, int i3, int i4, int i5, int i6)
int embed(finite_field &subfield, int index, int b, int verbose_level)
various functions related to geometries
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)
provides access to pre-computed combinatorial data in encoded form
void get_primitive_polynomial(std::string &poly, int p, int e, int verbose_level)
linear algebra over a finite field
void init(field_theory::finite_field *F, int verbose_level)
basic number theoretic functions
long int gcd_lint(long int m, long int n)
int i_power_j(int i, int j)
void factor_prime_power(int q, int &p, int &e)
long int primitive_root(long int p, int verbose_level)
long int nb_times_finite_field_created
indexing of points in an orthogonal geometry O^epsilon(n,q)
void init(field_theory::finite_field *F, int verbose_level)
domain of polynomials in one variable over a finite field
void delete_object(unipoly_object &p)
void mult(unipoly_object a, unipoly_object b, unipoly_object &c, int verbose_level)
int rank(unipoly_object p)
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 Int_vec_zero(A, B)
#define Int_vec_print_integer_matrix_width(A, B, C, D, E, F)
#define Int_vec_print(A, B, C)
orbiter_kernel_system::orbiter_session * Orbiter
global Orbiter session
the orbiter library for the classification of combinatorial objects