Skip to content

Commit 18bf8d8

Browse files
Merge pull request #2417 from fredrik-johansson/irred
Generating minimal irreducible polynomials over GF(p)
2 parents a45e8d0 + a617915 commit 18bf8d8

File tree

10 files changed

+1849
-29
lines changed

10 files changed

+1849
-29
lines changed

dev/check_examples.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ then
239239
echo "PASS"
240240
exit 0
241241

242+
elif test "$1" = "minimal_irreducibles";
243+
then
244+
echo "minimal_irreducibles....SKIPPED"
242245
elif test "$1" = "multi_crt";
243246
then
244247
echo "multi_crt....SKIPPED"

doc/source/fq_nmod.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,25 @@ Context Management
3434

3535
Initialises the context for prime `p` and extension degree `d`,
3636
with name ``var`` for the generator. By default, it will try
37-
use a Conway polynomial; if one is not available, a random
37+
use a Conway polynomial; if one is not available, a minimal weight
3838
irreducible polynomial will be used.
3939

4040
Assumes that `p` is a prime.
4141

4242
Assumes that the string ``var`` is a null-terminated string
4343
of length at least one.
4444

45+
.. function:: fq_nmod_ctx_init_minimal_weight_ui(fq_nmod_ctx_t ctx, ulong p, slong d, const char * var)
46+
47+
Initialises the context for prime `p` and extension degree `d`,
48+
with name ``var`` for the generator, choosing a modulus polynomial
49+
with minimal number of nonzero terms for efficient arithmetic.
50+
51+
Assumes that `p` is a prime.
52+
53+
Assumes that the string ``var`` is a null-terminated string
54+
of length at least one.
55+
4556
.. function:: int _fq_nmod_ctx_init_conway_ui(fq_nmod_ctx_t ctx, ulong p, slong d, const char * var)
4657

4758
Attempts to initialise the context for prime `p` and extension

doc/source/nmod_poly.rst

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,47 @@ Randomization
222222

223223
Generates a random polynomial with length up to ``len``.
224224

225-
.. function:: void nmod_poly_randtest_irreducible(nmod_poly_t poly, flint_rand_t state, slong len)
226-
227-
Generates a random irreducible polynomial with length up to ``len``.
228-
229225
.. function:: void nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len)
230226

231227
Generates a random monic polynomial with length ``len``.
232228

229+
.. function:: void nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len)
230+
231+
Generates a random monic trinomial of length ``len``.
232+
233+
.. function:: void nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len)
234+
235+
Generates a random monic pentomial of length ``len``.
236+
237+
Construction of irreducible polynomials
238+
--------------------------------------------------------------------------------
239+
240+
The following functions assume a prime modulus.
241+
242+
.. function:: void nmod_poly_minimal_irreducible(nmod_poly_t res, ulong n)
243+
244+
Generates a monic irreducible polynomial of degree ``n`` with minimal
245+
weight (minimal number of nonzero terms). We generate a binomial
246+
if possible, otherwise a trinomial, etc.
247+
It is conjectured that one never needs more than a pentanomial
248+
modulo `p = 2` and a tetranomial modulo `p > 2`.
249+
250+
More specifically, this function returns the first among all minimal-weight
251+
polynomials in the following ordering.
252+
Firstly, for trinomials, `x^n + a x^k + b` comes before
253+
its monic reversal `x^n + a' x^{n-k} + b'` if `k < n - k`.
254+
Secondly, writing
255+
`f = x^n + a_1 x^{k_1} + a_2 x^{k_2} + \ldots + a_t x^{k_t}`
256+
with `n > k_1 > k_2 \ldots > k_t`, we order tuples
257+
`(a_1, \ldots, a_{t}, k_1, \ldots, k_t)` lexicographically.
258+
We thus favor polynomials with smaller coefficients
259+
(all 1 if possible), and secondly with smaller degrees for the
260+
middle terms.
261+
262+
.. function:: void nmod_poly_randtest_irreducible(nmod_poly_t poly, flint_rand_t state, slong len)
263+
264+
Generates a random irreducible polynomial with length up to ``len``.
265+
233266
.. function:: void nmod_poly_randtest_monic_irreducible(nmod_poly_t poly, flint_rand_t state, slong len)
234267

235268
Generates a random monic irreducible polynomial with length ``len``.
@@ -239,11 +272,6 @@ Randomization
239272
Generates a random monic irreducible primitive polynomial with
240273
length ``len``.
241274

242-
243-
.. function:: void nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len)
244-
245-
Generates a random monic trinomial of length ``len``.
246-
247275
.. function:: int nmod_poly_randtest_trinomial_irreducible(nmod_poly_t poly, flint_rand_t state, slong len, slong max_attempts)
248276

249277
Attempts to set ``poly`` to a monic irreducible trinomial of
@@ -253,10 +281,6 @@ Randomization
253281
trinomials until an irreducible one is found. Returns `1` if one
254282
is found and `0` otherwise.
255283

256-
.. function:: void nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len)
257-
258-
Generates a random monic pentomial of length ``len``.
259-
260284
.. function:: int nmod_poly_randtest_pentomial_irreducible(nmod_poly_t poly, flint_rand_t state, slong len, slong max_attempts)
261285

262286
Attempts to set ``poly`` to a monic irreducible pentomial of

examples/minimal_irreducibles.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
Generate irreducible polynomial of minimal weight over GF(p)
3+
for degrees nmin <= n <= nmax.
4+
5+
This file is public domain. Author: Fredrik Johansson.
6+
*/
7+
8+
#include <stdio.h>
9+
#include <string.h>
10+
#include <stdlib.h>
11+
#include "flint/thread_support.h"
12+
#include "flint/ulong_extras.h"
13+
#include "flint/nmod_poly.h"
14+
#include "flint/nmod_poly_factor.h"
15+
#include "flint/profiler.h"
16+
17+
typedef struct
18+
{
19+
nmod_poly_struct * f;
20+
ulong nstart;
21+
}
22+
workinfo_t;
23+
24+
void
25+
worker(slong i, void * work)
26+
{
27+
nmod_poly_struct * f = ((workinfo_t *) work)->f;
28+
ulong nstart = ((workinfo_t *) work)->nstart;
29+
nmod_poly_minimal_irreducible(f + i, nstart + i);
30+
}
31+
32+
int
33+
main(int argc, char * argv[])
34+
{
35+
slong i;
36+
int num_threads = 1;
37+
ulong p, n, na, nb, nmin, nmax;
38+
slong batch_size;
39+
workinfo_t work;
40+
41+
if (argc < 4)
42+
{
43+
flint_printf("usage: minimal_irreducibles [-threads t] p nmin nmax\n");
44+
return 1;
45+
}
46+
47+
p = 0;
48+
nmin = 0;
49+
nmax = 0;
50+
51+
for (i = 1; i < argc; i++)
52+
{
53+
if (!strcmp(argv[i], "-threads"))
54+
{
55+
num_threads = atoi(argv[i+1]);
56+
flint_set_num_threads(num_threads);
57+
i++;
58+
}
59+
else if (i == argc - 3)
60+
p = atol(argv[i]);
61+
else if (i == argc - 2)
62+
nmin = atol(argv[i]);
63+
else if (i == argc - 1)
64+
nmax = atol(argv[i]);
65+
}
66+
67+
flint_printf("p = %wu, nmin = %wu, nmax = %wu\n", p, nmin, nmax);
68+
69+
if (!n_is_prime(p))
70+
flint_throw(FLINT_ERROR, "p = %wu is not prime\n", p);
71+
72+
if (num_threads == 1)
73+
batch_size = 1;
74+
else
75+
batch_size = FLINT_MIN(10 * num_threads, nmax - nmin + 1);
76+
work.f = flint_malloc(sizeof(nmod_poly_struct) * batch_size);
77+
for (i = 0; i < batch_size; i++)
78+
nmod_poly_init(work.f + i, p);
79+
80+
TIMEIT_ONCE_START
81+
na = nmin;
82+
while (1)
83+
{
84+
work.nstart = na;
85+
nb = FLINT_MIN(na + batch_size - 1, nmax);
86+
flint_parallel_do(worker, &work, nb - na + 1, 0, 0);
87+
for (n = na; n <= nb; n++)
88+
flint_printf("%{nmod_poly}\n", work.f + n - na);
89+
na = nb + 1;
90+
if (na > nmax)
91+
break;
92+
}
93+
TIMEIT_ONCE_STOP
94+
SHOW_MEMORY_USAGE
95+
96+
for (i = 0; i < batch_size; i++)
97+
nmod_poly_clear(work.f + i);
98+
flint_free(work.f);
99+
100+
flint_cleanup_master();
101+
return 0;
102+
}
103+

src/fq_nmod.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern "C" {
3434
void fq_nmod_ctx_init_ui(fq_nmod_ctx_t ctx, ulong prime, slong deg, const char * var);
3535
int _fq_nmod_ctx_init_conway_ui(fq_nmod_ctx_t ctx, ulong prime, slong deg, const char * var);
3636
void fq_nmod_ctx_init_conway_ui(fq_nmod_ctx_t ctx, ulong prime, slong deg, const char * var);
37+
void fq_nmod_ctx_init_minimal_weight_ui(fq_nmod_ctx_t ctx, ulong prime, slong deg, const char * var);
3738
void fq_nmod_ctx_init_modulus(fq_nmod_ctx_t ctx, const nmod_poly_t modulus, const char * var);
3839

3940
void fq_nmod_ctx_init_randtest(fq_nmod_ctx_t ctx, flint_rand_t state, int type);

src/fq_nmod/ctx_init.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,27 @@ void fq_nmod_ctx_init_conway_ui(fq_nmod_ctx_t ctx, ulong p, slong d, const char
5151
ctx->is_conway = 1;
5252
}
5353

54+
void fq_nmod_ctx_init_minimal_weight_ui(fq_nmod_ctx_t ctx, ulong p, slong d, const char *var)
55+
{
56+
nmod_poly_t poly;
57+
58+
ctx->is_conway = 0;
59+
60+
nmod_poly_init2(poly, p, d + 1);
61+
nmod_poly_minimal_irreducible(poly, d);
62+
fq_nmod_ctx_init_modulus(ctx, poly, var);
63+
nmod_poly_clear(poly);
64+
}
65+
5466
void fq_nmod_ctx_init_ui(fq_nmod_ctx_t ctx, ulong p, slong d, const char *var)
5567
{
5668
if (_fq_nmod_ctx_init_conway_ui(ctx, p, d, var))
5769
{
5870
ctx->is_conway = 1;
59-
return;
6071
}
6172
else
6273
{
63-
flint_rand_t state;
64-
nmod_poly_t poly;
65-
66-
ctx->is_conway = 0;
67-
68-
flint_rand_init(state);
69-
70-
nmod_poly_init2(poly, p, d + 1);
71-
nmod_poly_randtest_sparse_irreducible(poly, state, d + 1);
72-
73-
fq_nmod_ctx_init_modulus(ctx, poly, var);
74-
75-
nmod_poly_clear(poly);
76-
flint_rand_clear(state);
74+
fq_nmod_ctx_init_minimal_weight_ui(ctx, p, d, var);
7775
}
7876
}
7977

src/nmod_poly.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ void nmod_poly_randtest_not_zero(nmod_poly_t poly, flint_rand_t state, slong len
223223
} while (nmod_poly_is_zero(poly));
224224
}
225225

226+
/* Construction of irreducibles *********************************************/
227+
228+
void nmod_poly_minimal_irreducible(nmod_poly_t res, ulong n);
229+
226230
void nmod_poly_randtest_irreducible(nmod_poly_t poly, flint_rand_t state, slong len);
227231

228232
void nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len);

0 commit comments

Comments
 (0)