Orbiter 2022
Combinatorial Objects
table_of_irreducible_polynomials.cpp
Go to the documentation of this file.
1/*
2 * table_of_irreducible_polynomials.cpp
3 *
4 * Created on: Apr 22, 2019
5 * Author: betten
6 */
7
8
9
10
11#include "foundations.h"
12
13
14using namespace std;
15
16
17namespace orbiter {
18namespace layer1_foundations {
19namespace ring_theory {
20
21static void make_linear_irreducible_polynomials(field_theory::finite_field *F, int &nb,
22 int *&table, int verbose_level);
23
25{
26 k = q = 0;
27 F = NULL;
28 nb_irred = 0;
29 Nb_irred = NULL;
30 First_irred = NULL;
31 Tables = NULL;
32 Degree = NULL;
33}
34
36{
37 int i;
38
39 if (Nb_irred) {
41 }
42 if (First_irred) {
44 }
45 if (Tables) {
46 for (i = 1; i <= k; i++) {
47 FREE_int(Tables[i]);
48 }
50 }
51 if (Degree) {
53 }
54}
55
57 field_theory::finite_field *F, int verbose_level)
58{
59 int f_v = (verbose_level >= 1);
60 int i, j, d;
62
63 if (f_v) {
64 cout << "table_of_irreducible_polynomials::init" << endl;
65 }
68 q = F->q;
69 if (f_v) {
70 cout << "table_of_irreducible_polynomials::init "
71 "k = " << k << " q = " << q << endl;
72 }
73
74 Nb_irred = NEW_int(k + 1);
75 First_irred = NEW_int(k + 1);
76 Tables = NEW_pint(k + 1);
77
78 nb_irred = 0;
79
80 First_irred[1] = 0;
81 if (f_v) {
82 cout << "table_of_irreducible_polynomials::init "
83 "before make_linear_irreducible_polynomials" << endl;
84 }
85 make_linear_irreducible_polynomials(F, Nb_irred[1],
86 Tables[1], verbose_level - 2);
87 if (f_v) {
88 cout << "table_of_irreducible_polynomials::init "
89 "after make_linear_irreducible_polynomials" << endl;
90 }
91 nb_irred += Nb_irred[1];
92 //First_irred[2] = First_irred[1] + Nb_irred[1];
93
94 for (d = 2; d <= k; d++) {
95 if (f_v) {
96 cout << "table_of_irreducible_polynomials::init "
97 "degree " << d << " / " << k << endl;
98 }
99 First_irred[d] = First_irred[d - 1] + Nb_irred[d - 1];
100
101 if (f_v) {
102 cout << "table_of_irreducible_polynomials::init before "
103 "R.make_all_irreducible_polynomials_of_degree_d"
104 << endl;
105 }
106
107 vector<vector<int>> T;
109
111 T, verbose_level - 2);
112
113 Nb_irred[d] = T.size();
114
115 Tables[d] = NEW_int(Nb_irred[d] * (d + 1));
116 for (i = 0; i < Nb_irred[d]; i++) {
117 for (j = 0; j <= d; j++) {
118 Tables[d][i * (d + 1) + j] = T[i][j];
119 }
120 }
121
122
123 if (f_v) {
124 cout << "table_of_irreducible_polynomials::init after "
125 "R.make_all_irreducible_polynomials_of_degree_d"
126 << endl;
127 }
128
129 nb_irred += Nb_irred[d];
130 if (f_v) {
131 cout << "table_of_irreducible_polynomials::init "
132 "Nb_irred[" << d << "]=" << Nb_irred[d] << endl;
133 }
134 }
135
136 if (f_v) {
137 cout << "table_of_irreducible_polynomials::init "
138 "k = " << k << " q = " << q
139 << " nb_irred = " << nb_irred << endl;
140 }
141
143
144 j = 0;
145 for (d = 1; d <= k; d++) {
146 for (i = 0; i < Nb_irred[d]; i++) {
147 Degree[j + i] = d;
148 }
149 j += Nb_irred[d];
150 }
151 if (f_v) {
152 cout << "table_of_irreducible_polynomials::init "
153 "k = " << k << " q = " << q << " Degree = ";
155 cout << endl;
156 }
157
158
159 print(cout);
160
161 {
162 unipoly_domain FX(F);
163
164 for (d = 1; d <= k; d++) {
165
166 for (i = 0; i < Nb_irred[d]; i++) {
167
168 unipoly_object poly;
169
171 poly, d, &Tables[d][i * (d + 1)]);
172
173 if (!is_irreducible(poly, verbose_level)) {
174 cout << "table_of_irreducible_polynomials::init "
175 "polynomial " << i << " among "
176 "the list of polynomials of degree " << d
177 << " is not irreducible" << endl;
178 exit(1);
179 }
180 }
181 }
182 }
183
184 if (f_v) {
185 cout << "table_of_irreducible_polynomials::init done" << endl;
186 }
187}
188
190{
191 int d, l, i, j;
192
193 cout << "table_of_irreducible_polynomials::print "
194 "table of all irreducible polynomials:" << endl;
195 j = 0;
196 for (d = 1; d <= k; d++) {
197 //f = First_irred[d];
198 l = Nb_irred[d];
199 ost << "There are " << l << " irreducible polynomials of "
200 "degree " << d << ":" << endl;
201 for (i = 0; i < l; i++) {
202 ost << j << " : " << i << " : ";
203 Int_vec_print(ost, Tables[d] + i * (d + 1), d + 1);
204 ost << endl;
205 j++;
206 }
207 }
208}
209
210
212{
213 int d, i, j;
214
215 for (d = 1; d <= k; d++) {
216 for (i = 0; i < Nb_irred[d]; i++) {
217 for (j = 0; j <= d; j++) {
218 ost << Tables[d][i * (d + 1) + j];
219 if (j < d) {
220 ost << ", ";
221 }
222 }
223 ost << endl;
224 }
225 }
226}
227
229 int *Select, int verbose_level)
230{
231 int f_v = (verbose_level >= 1);
232 int i, k1 = k, d, m;
233
234 if (f_v) {
235 cout << "table_of_irreducible_polynomials::select_polynomial_first" << endl;
236 }
237 Int_vec_zero(Select, nb_irred);
238 for (i = nb_irred - 1; i >= 0; i--) {
239 d = Degree[i];
240 m = k1 / d;
241 Select[i] = m;
242 k1 -= m * d;
243 if (k1 == 0) {
244 return TRUE;
245 }
246 }
247 if (k1 == 0) {
248 if (f_v) {
249 cout << "table_of_irreducible_polynomials::select_polynomial_first "
250 "returns TRUE" << endl;
251 }
252 return TRUE;
253 }
254 else {
255 if (f_v) {
256 cout << "table_of_irreducible_polynomials::select_polynomial_first "
257 "returns FALSE" << endl;
258 }
259 return FALSE;
260 }
261}
262
264 int *Select, int verbose_level)
265{
266 int f_v = (verbose_level >= 1);
267 int f_vv = (verbose_level >= 2);
268 int i, ii, k1, d, m;
269
270 if (f_v) {
271 cout << "table_of_irreducible_polynomials::select_polynomial_next" << endl;
272 }
273 k1 = Select[0] * Degree[0];
274 Select[0] = 0;
275 do {
276 for (i = 1; i < nb_irred; i++) {
277 m = Select[i];
278 if (m) {
279 k1 += Degree[i];
280 m--;
281 Select[i] = m;
282 break;
283 }
284 }
285 if (i == nb_irred) {
286 if (f_v) {
287 cout << "table_of_irreducible_polynomials::select_polynomial_next "
288 "return FALSE" << endl;
289 }
290 return FALSE;
291 }
292 if (f_vv) {
293 cout << "k1=" << k1 << endl;
294 }
295 for (ii = i - 1; ii >= 0; ii--) {
296 d = Degree[ii];
297 m = k1 / d;
298 Select[ii] = m;
299 k1 -= m * d;
300 if (f_vv) {
301 cout << "Select[" << ii << "]=" << m
302 << ", k1=" << k1 << endl;
303 }
304 if (k1 == 0) {
305 if (f_v) {
306 cout << "table_of_irreducible_polynomials::select_polynomial_next "
307 "return FALSE" << endl;
308 }
309 return TRUE;
310 }
311 }
312 k1 += Select[0] * Degree[0];
313 Select[0] = 0;
314 } while (k1);
315 if (f_v) {
316 cout << "table_of_irreducible_polynomials::select_polynomial_next "
317 "return FALSE" << endl;
318 }
319 return FALSE;
320}
321
323{
324 int f_v = (verbose_level >= 1);
325 int *Mult;
326 int f_is_irred;
327 int sum, i;
328
329 if (f_v) {
330 cout << "table_of_irreducible_polynomials::is_irreducible" << endl;
331 }
332 Mult = NEW_int(nb_irred);
333 factorize_polynomial(poly, Mult, verbose_level);
334 sum = 0;
335 for (i = 0; i < nb_irred; i++) {
336 sum += Mult[i];
337 }
338 FREE_int(Mult);
339 if (sum > 1) {
340 f_is_irred = FALSE;
341 }
342 else {
343 f_is_irred = TRUE;
344 }
345
346 if (f_v) {
347 cout << "table_of_irreducible_polynomials::is_irreducible done" << endl;
348 }
349 return f_is_irred;
350}
351
353 unipoly_object &poly, int *Mult, int verbose_level)
354{
355 int f_v = (verbose_level >= 1);
356 unipoly_domain U(F);
357 unipoly_object Poly, P, Q, R;
358 int i, d_poly, d, tt;
359
360 if (f_v) {
361 cout << "table_of_irreducible_polynomials::factorize_polynomial "
362 "k = " << k << " q = " << q << endl;
363 }
364 U.create_object_by_rank(Poly, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
365 U.create_object_by_rank(P, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
366 U.create_object_by_rank(Q, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
367 U.create_object_by_rank(R, 0, __FILE__, __LINE__, 0 /*verbose_level*/);
368 U.assign(poly, Poly, verbose_level);
369
370 if (f_v) {
371 cout << "table_of_irreducible_polynomials::factorize_polynomial "
372 "Poly = ";
373 U.print_object(Poly, cout);
374 cout << endl;
375 }
376
377
378 Int_vec_zero(Mult, nb_irred);
379 for (i = 0; i < nb_irred; i++) {
380
381 d_poly = U.degree(Poly);
382 d = Degree[i];
383
384 if (f_v) {
385 cout << "table_of_irreducible_polynomials::factorize_polynomial "
386 "trying irrducible poly " << i << " / " << nb_irred
387 << " of degree " << d << endl;
388 }
389
390 if (d > d_poly) {
391 continue;
392 }
393
394 tt = i - First_irred[d];
395 if (f_v) {
396 cout << "table_of_irreducible_polynomials::factorize_polynomial "
397 "tt=" << tt << endl;
398 }
399 if (f_v) {
400 cout << "table_of_irreducible_polynomials::factorize_polynomial "
401 "before U.delete_object" << endl;
402 }
403 U.delete_object(P);
404 if (f_v) {
405 cout << "table_of_irreducible_polynomials::factorize_polynomial "
406 "polynomial coefficients: ";
407 Int_vec_print(cout, Tables[d] + tt * (d + 1), d + 1);
408 cout << endl;
409 }
410 if (f_v) {
411 cout << "table_of_irreducible_polynomials::factorize_polynomial "
412 "before U.create_object_of_degree_with_coefficients" << endl;
413 }
415 Tables[d] + tt * (d + 1));
416
417 if (f_v) {
418 cout << "table_of_irreducible_polynomials::factorize_polynomial "
419 "trial division by = ";
420 U.print_object(P, cout);
421 cout << endl;
422 }
423 U.division_with_remainder(Poly, P, Q, R, verbose_level - 2);
424 if (f_v) {
425 cout << "table_of_irreducible_polynomials::factorize_polynomial "
426 "after U.division_with_remainder" << endl;
427 cout << "Q = ";
428 U.print_object(Q, cout);
429 cout << endl;
430 cout << "R = ";
431 U.print_object(R, cout);
432 cout << endl;
433 }
434
435 if (U.is_zero(R)) {
436 if (f_v) {
437 cout << "table_of_irreducible_polynomials::factorize_polynomial "
438 "the polynomial divides" << endl;
439 }
440 Mult[i]++;
441 i--; // subtract one so we will try the same polynomial again
442 if (f_v) {
443 cout << "table_of_irreducible_polynomials::factorize_polynomial "
444 "assigning Q to Poly" << endl;
445 }
446 U.assign(Q, Poly, verbose_level);
447 if (f_v) {
448 cout << "table_of_irreducible_polynomials::factorize_polynomial "
449 "after assigning Q to Poly" << endl;
450 }
451 if (f_v) {
452 cout << "table_of_irreducible_polynomials::factorize_polynomial "
453 "Poly = ";
454 U.print_object(Poly, cout);
455 cout << endl;
456 }
457 }
458 else {
459 if (f_v) {
460 cout << "table_of_irreducible_polynomials::factorize_polynomial "
461 "the polynomial does not divide" << endl;
462 }
463
464 }
465 }
466
467 if (f_v) {
468 cout << "table_of_irreducible_polynomials::factorize_polynomial "
469 "factorization: ";
470 Int_vec_print(cout, Mult, nb_irred);
471 cout << endl;
472 cout << "table_of_irreducible_polynomials::factorize_polynomial "
473 "remaining polynomial = ";
474 U.print_object(Poly, cout);
475 cout << endl;
476 //print(cout);
477 }
478
479 U.delete_object(Poly);
480 U.delete_object(P);
481 U.delete_object(Q);
482 U.delete_object(R);
483
484 if (f_v) {
485 cout << "table_of_irreducible_polynomials::factorize_polynomial "
486 "k = " << k << " q = " << q << " done" << endl;
487 }
488}
489
490//##############################################################################
491// global functions:
492//##############################################################################
493
494static void make_linear_irreducible_polynomials(field_theory::finite_field *F, int &nb,
495 int *&table, int verbose_level)
496{
497 int i;
498
499#if 0
500 if (f_no_eigenvalue_one) {
501 nb = q - 2;
502 table = NEW_int(nb * 2);
503 for (i = 0; i < nb; i++) {
504 table[i * 2 + 0] = F.negate(i + 2);
505 table[i * 2 + 1] = 1;
506 }
507 }
508 else {
509#endif
510 nb = F->q - 1;
511 table = NEW_int(nb * 2);
512 for (i = 0; i < nb; i++) {
513 table[i * 2 + 0] = F->negate(i + 1);
514 table[i * 2 + 1] = 1;
515 }
516#if 0
517 }
518#endif
519}
520
521
522
523}}}
524
525
526
527
void make_all_irreducible_polynomials_of_degree_d(field_theory::finite_field *F, int d, std::vector< std::vector< int > > &Table, int verbose_level)
void factorize_polynomial(unipoly_object &char_poly, int *Mult, int verbose_level)
domain of polynomials in one variable over a finite field
Definition: ring_theory.h:691
void create_object_of_degree_with_coefficients(unipoly_object &p, int d, int *coeff)
void division_with_remainder(unipoly_object a, unipoly_object b, unipoly_object &q, unipoly_object &r, int verbose_level)
void create_object_by_rank(unipoly_object &p, long int rk, const char *file, int line, 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_pint(n)
Definition: foundations.h:627
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define FREE_pint(p)
Definition: foundations.h:641
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
the orbiter library for the classification of combinatorial objects