1.. _fmpz-mod-poly:
2
3**fmpz_mod_poly.h** -- polynomials over integers mod n
4===============================================================================
5
6Description.
7
8Types, macros and constants
9-------------------------------------------------------------------------------
10
11.. type:: fmpz_mod_poly_struct
12
13.. type:: fmpz_mod_poly_t
14
15    Description.
16
17
18Memory management
19--------------------------------------------------------------------------------
20
21
22.. function:: void fmpz_mod_poly_init(fmpz_mod_poly_t poly, const fmpz_t p)
23
24    Initialises ``poly`` for use over `\mathbf{Z} / p \mathbf{Z}`,
25    setting its length to zero.
26
27    A corresponding call to :func:`fmpz_mod_poly_clear` must be made after
28    finishing with the :func:`fmpz_mod_poly_t` to free the memory used by
29    the polynomial.  The user is also responsible to clearing the
30    integer~`p`.
31
32.. function:: void fmpz_mod_poly_init2(fmpz_mod_poly_t poly, const fmpz_t p, slong alloc)
33
34    Initialises ``poly`` with space for at least ``alloc`` coefficients
35    and sets the length to zero.  The allocated coefficients are all set to
36    zero.
37
38.. function:: void fmpz_mod_poly_clear(fmpz_mod_poly_t poly)
39
40    Clears the given polynomial, releasing any memory used.  It must
41    be reinitialised in order to be used again.
42
43.. function:: void fmpz_mod_poly_realloc(fmpz_mod_poly_t poly, slong alloc)
44
45    Reallocates the given polynomial to have space for ``alloc``
46    coefficients.  If ``alloc`` is zero the polynomial is cleared
47    and then reinitialised.  If the current length is greater than
48    ``alloc`` the polynomial is first truncated to length ``alloc``.
49
50.. function:: void fmpz_mod_poly_fit_length(fmpz_mod_poly_t poly, slong len)
51
52    If ``len`` is greater than the number of coefficients currently
53    allocated, then the polynomial is reallocated to have space for at
54    least ``len`` coefficients.  No data is lost when calling this
55    function.
56
57    The function efficiently deals with the case where it is called
58    many times in small increments by at least doubling the number of
59    allocated coefficients when length is larger than the number of
60    coefficients currently allocated.
61
62.. function:: void _fmpz_mod_poly_normalise(fmpz_mod_poly_t poly)
63
64    Sets the length of ``poly`` so that the top coefficient is non-zero.
65    If all coefficients are zero, the length is set to zero.  This function
66    is mainly used internally, as all functions guarantee normalisation.
67
68.. function:: void _fmpz_mod_poly_set_length(fmpz_mod_poly_t poly, slong len)
69
70    Demotes the coefficients of ``poly`` beyond ``len`` and sets
71    the length of ``poly`` to ``len``.
72
73.. function:: void fmpz_mod_poly_truncate(fmpz_mod_poly_t poly, slong len)
74
75    If the current length of ``poly`` is greater than ``len``, it
76    is truncated to have the given length.  Discarded coefficients are
77    not necessarily set to zero.
78
79.. function:: void fmpz_mod_poly_set_trunc(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, slong n)
80
81    Notionally truncate ``poly`` to length `n` and set ``res`` to the
82    result. The result is normalised.
83
84
85Randomisation
86--------------------------------------------------------------------------------
87
88
89.. function:: void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len)
90
91    Sets the polynomial~`f` to a random polynomial of length up~``len``.
92
93.. function:: void fmpz_mod_poly_randtest_irreducible(fmpz_mod_poly_t f, flint_rand_t state, slong len)
94
95    Sets the polynomial~`f` to a random irreducible polynomial of length
96    up~``len``, assuming ``len`` is positive.
97
98.. function:: void fmpz_mod_poly_randtest_not_zero(fmpz_mod_poly_t f, flint_rand_t state, slong len)
99
100    Sets the polynomial~`f` to a random polynomial of length up~``len``,
101    assuming ``len`` is positive.
102
103.. function:: void fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t poly, flint_rand_t state, slong len)
104
105    Generates a random monic polynomial with length ``len``.
106
107.. function:: void fmpz_mod_poly_randtest_monic_irreducible(fmpz_mod_poly_t poly, flint_rand_t state, slong len)
108
109    Generates a random monic irreducible polynomial with length ``len``.
110
111.. function:: void fmpz_mod_poly_randtest_monic_primitive(fmpz_mod_poly_t poly, flint_rand_t state, slong len)
112
113    Generates a random monic irreducible primitive polynomial with
114    length ``len``.
115
116
117.. function:: void fmpz_mod_poly_randtest_trinomial(fmpz_mod_poly_t poly, flint_rand_t state, slong len)
118
119    Generates a random monic trinomial of length ``len``.
120
121.. function:: int fmpz_mod_poly_randtest_trinomial_irreducible(fmpz_mod_poly_t poly, flint_rand_t state, slong len, slong max_attempts)
122
123    Attempts to set ``poly`` to a monic irreducible trinomial of
124    length ``len``.  It will generate up to ``max_attempts``
125    trinomials in attempt to find an irreducible one.  If
126    ``max_attempts`` is ``0``, then it will keep generating
127    trinomials until an irreducible one is found.  Returns `1` if one
128    is found and `0` otherwise.
129
130.. function:: void fmpz_mod_poly_randtest_pentomial(fmpz_mod_poly_t poly, flint_rand_t state, slong len)
131
132    Generates a random monic pentomial of length ``len``.
133
134.. function:: int fmpz_mod_poly_randtest_pentomial_irreducible(fmpz_mod_poly_t poly, flint_rand_t state, slong len, slong max_attempts)
135
136    Attempts to set ``poly`` to a monic irreducible pentomial of
137    length ``len``.  It will generate up to ``max_attempts``
138    pentomials in attempt to find an irreducible one.  If
139    ``max_attempts`` is ``0``, then it will keep generating
140    pentomials until an irreducible one is found.  Returns `1` if one
141    is found and `0` otherwise.
142
143.. function:: void fmpz_mod_poly_randtest_sparse_irreducible(fmpz_mod_poly_t poly, flint_rand_t state, slong len)
144
145    Attempts to set ``poly`` to a sparse, monic irreducible polynomial
146    with length ``len``.  It attempts to find an irreducible
147    trinomial.  If that does not succeed, it attempts to find a
148    irreducible pentomial.  If that fails, then ``poly`` is just
149    set to a random monic irreducible polynomial.
150
151
152
153Attributes
154--------------------------------------------------------------------------------
155
156
157.. function:: fmpz * fmpz_mod_poly_modulus(const fmpz_mod_poly_t poly)
158
159    Returns the modulus of this polynomial.  This function is
160    implemented as a macro.
161
162.. function:: slong fmpz_mod_poly_degree(const fmpz_mod_poly_t poly)
163
164    Returns the degree of the polynomial.  The degree of the zero
165    polynomial is defined to be `-1`.
166
167.. function:: slong fmpz_mod_poly_length(const fmpz_mod_poly_t poly)
168
169    Returns the length of the polynomial, which is one more than
170    its degree.
171
172.. function:: fmpz * fmpz_mod_poly_lead(const fmpz_mod_poly_t poly)
173
174    Returns a pointer to the first leading coefficient of ``poly``
175    if this is non-zero, otherwise returns ``NULL``.
176
177
178Assignment and basic manipulation
179--------------------------------------------------------------------------------
180
181
182.. function:: void fmpz_mod_poly_set(fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
183
184    Sets the polynomial ``poly1`` to the value of ``poly2``.
185
186.. function:: void fmpz_mod_poly_swap(fmpz_mod_poly_t poly1, fmpz_mod_poly_t poly2)
187
188    Swaps the two polynomials.  This is done efficiently by swapping
189    pointers rather than individual coefficients.
190
191.. function:: void fmpz_mod_poly_zero(fmpz_mod_poly_t poly)
192
193    Sets ``poly`` to the zero polynomial.
194
195.. function:: void fmpz_mod_poly_one(fmpz_mod_poly_t poly)
196
197    Sets ``poly`` to the constant polynomial `1`.
198
199.. function:: void fmpz_mod_poly_zero_coeffs(fmpz_mod_poly_t poly, slong i, slong j)
200
201    Sets the coefficients of `X^k` for `k \in [i, j)` in the polynomial
202    to zero.
203
204.. function:: void fmpz_mod_poly_reverse(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, slong n)
205
206    This function considers the polynomial ``poly`` to be of length `n`,
207    notionally truncating and zero padding if required, and reverses
208    the result.  Since the function normalises its result ``res`` may be
209    of length less than `n`.
210
211
212Conversion
213--------------------------------------------------------------------------------
214
215
216.. function:: void fmpz_mod_poly_set_ui(fmpz_mod_poly_t f, ulong c)
217
218    Sets the polynomial `f` to the constant `c` reduced modulo `p`.
219
220.. function:: void fmpz_mod_poly_set_fmpz(fmpz_mod_poly_t f, const fmpz_t c)
221
222    Sets the polynomial `f` to the constant `c` reduced modulo `p`.
223
224.. function:: void fmpz_mod_poly_set_fmpz_poly(fmpz_mod_poly_t f, const fmpz_poly_t g)
225
226    Sets `f` to `g` reduced modulo `p`, where `p` is the modulus that
227    is part of the data structure of `f`.
228
229.. function:: void fmpz_mod_poly_get_fmpz_poly(fmpz_poly_t f, const fmpz_mod_poly_t g)
230
231    Sets `f` to `g`.  This is done simply by lifting the coefficients
232    of `g` taking representatives `[0, p) \subset \mathbf{Z}`.
233
234
235Comparison
236--------------------------------------------------------------------------------
237
238
239.. function:: int fmpz_mod_poly_equal(const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
240
241    Returns non-zero if the two polynomials are equal, otherwise returns zero.
242
243.. function:: int fmpz_mod_poly_equal_trunc(const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, slong n)
244
245    Notionally truncates the two polynomials to length `n` and returns non-zero
246    if the two polynomials are equal, otherwise returns zero.
247
248.. function:: int fmpz_mod_poly_is_zero(const fmpz_mod_poly_t poly)
249
250    Returns non-zero if the polynomial is zero.
251
252.. function:: int fmpz_mod_poly_is_one(const fmpz_mod_poly_t poly)
253
254    Returns non-zero if the polynomial is the constant `1`.
255
256.. function:: int fmpz_mod_poly_is_gen(const fmpz_mod_poly_t poly)
257
258    Returns non-zero if the polynomial is the degree `1` polynomial `x`.
259
260
261Getting and setting coefficients
262--------------------------------------------------------------------------------
263
264
265.. function:: void fmpz_mod_poly_set_coeff_fmpz(fmpz_mod_poly_t poly, slong n, const fmpz_t x)
266
267    Sets the coefficient of `X^n` in the polynomial to `x`,
268    assuming `n \geq 0`.
269
270.. function:: void fmpz_mod_poly_set_coeff_ui(fmpz_mod_poly_t poly, slong n, ulong x)
271
272    Sets the coefficient of `X^n` in the polynomial to `x`,
273    assuming `n \geq 0`.
274
275.. function:: void fmpz_mod_poly_get_coeff_fmpz(fmpz_t x, const fmpz_mod_poly_t poly, slong n)
276
277    Sets `x` to the coefficient of `X^n` in the polynomial,
278    assumng `n \geq 0`.
279
280.. function:: void fmpz_mod_poly_set_coeff_mpz(fmpz_mod_poly_t poly, slong n, const mpz_t x)
281
282    Sets the coefficient of `X^n` in the polynomial to `x`,
283    assuming `n \geq 0`.
284
285.. function:: void fmpz_mod_poly_get_coeff_mpz(mpz_t x, const fmpz_mod_poly_t poly, slong n)
286
287    Sets `x` to the coefficient of `X^n` in the polynomial,
288    assumng `n \geq 0`.
289
290
291Shifting
292--------------------------------------------------------------------------------
293
294
295.. function:: void _fmpz_mod_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n)
296
297    Sets ``(res, len + n)`` to ``(poly, len)`` shifted left by
298    `n` coefficients.
299
300    Inserts zero coefficients at the lower end.  Assumes that ``len``
301    and `n` are positive, and that ``res`` fits ``len + n`` elements.
302    Supports aliasing between ``res`` and ``poly``.
303
304.. function:: void fmpz_mod_poly_shift_left(fmpz_mod_poly_t f, const fmpz_mod_poly_t g, slong n)
305
306    Sets ``res`` to ``poly`` shifted left by `n` coeffs.  Zero
307    coefficients are inserted.
308
309.. function:: void _fmpz_mod_poly_shift_right(fmpz * res, const fmpz * poly, slong len, slong n)
310
311    Sets ``(res, len - n)`` to ``(poly, len)`` shifted right by
312    `n` coefficients.
313
314    Assumes that ``len`` and `n` are positive, that ``len > n``,
315    and that ``res`` fits ``len - n`` elements.  Supports aliasing
316    between ``res`` and ``poly``, although in this case the top
317    coefficients of ``poly`` are not set to zero.
318
319.. function:: void fmpz_mod_poly_shift_right(fmpz_mod_poly_t f, const fmpz_mod_poly_t g, slong n)
320
321    Sets ``res`` to ``poly`` shifted right by `n` coefficients.  If `n`
322    is equal to or greater than the current length of ``poly``, ``res``
323    is set to the zero polynomial.
324
325
326Addition and subtraction
327--------------------------------------------------------------------------------
328
329
330.. function:: void _fmpz_mod_poly_add(fmpz *res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p)
331
332    Sets ``res`` to the sum of ``(poly1, len1)`` and
333    ``(poly2, len2)``.  It is assumed that ``res`` has
334    sufficient space for the longer of the two polynomials.
335
336.. function:: void fmpz_mod_poly_add(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
337
338    Sets ``res`` to the sum of ``poly1`` and ``poly2``.
339
340.. function:: void fmpz_mod_poly_add_series(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, slong n)
341
342    Notionally truncate ``poly1`` and ``poly2`` to length `n` and set
343    ``res`` to the sum.
344
345.. function:: void _fmpz_mod_poly_sub(fmpz *res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p)
346
347    Sets ``res`` to ``(poly1, len1)`` minus ``(poly2, len2)``.  It
348    is assumed that ``res`` has sufficient space for the longer of the
349    two polynomials.
350
351.. function:: void fmpz_mod_poly_sub(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
352
353    Sets ``res`` to ``poly1`` minus ``poly2``.
354
355.. function:: void fmpz_mod_poly_sub_series(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, slong n)
356
357    Notionally truncate ``poly1`` and ``poly2`` to length `n` and set
358    ``res`` to the difference.
359
360.. function:: void _fmpz_mod_poly_neg(fmpz *res, const fmpz *poly, slong len, const fmpz_t p)
361
362    Sets ``(res, len)`` to the negative of ``(poly, len)``
363    modulo `p`.
364
365.. function:: void fmpz_mod_poly_neg(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly)
366
367    Sets ``res`` to the negative of ``poly`` modulo `p`.
368
369
370Scalar multiplication
371--------------------------------------------------------------------------------
372
373
374.. function:: void _fmpz_mod_poly_scalar_mul_fmpz(fmpz *res, const fmpz *poly, slong len, const fmpz_t x, const fmpz_t p)
375
376    Sets ``(res, len``) to ``(poly, len)`` multiplied by `x`,
377    reduced modulo `p`.
378
379.. function:: void fmpz_mod_poly_scalar_mul_fmpz(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, const fmpz_t x)
380
381    Sets ``res`` to ``poly`` multiplied by `x`.
382
383
384Scalar division
385--------------------------------------------------------------------------------
386
387
388.. function:: void _fmpz_mod_poly_scalar_div_fmpz(fmpz *res, const fmpz *poly, slong len, const fmpz_t x, const fmpz_t p)
389
390    Sets ``(res, len``) to ``(poly, len)`` divided by `x` (i.e.
391    multiplied by the inverse of `x \pmod{p}`). The result is reduced modulo
392    `p`.
393
394.. function:: void fmpz_mod_poly_scalar_div_fmpz(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, const fmpz_t x)
395
396    Sets ``res`` to ``poly`` divided by `x`, (i.e. multiplied by the
397    inverse of `x \pmod{p}`). The result is reduced modulo `p`.
398
399
400Multiplication
401--------------------------------------------------------------------------------
402
403
404.. function:: void _fmpz_mod_poly_mul(fmpz *res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p)
405
406    Sets ``(res, len1 + len2 - 1)`` to the product of ``(poly1, len1)``
407    and ``(poly2, len2)``.  Assumes ``len1 >= len2 > 0``.  Allows
408    zero-padding of the two input polynomials.
409
410.. function:: void fmpz_mod_poly_mul(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
411
412    Sets ``res`` to the product of ``poly1`` and ``poly2``.
413
414.. function:: void _fmpz_mod_poly_mullow(fmpz *res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p, slong n)
415
416    Sets ``(res, n)`` to the lowest `n` coefficients of the product of
417    ``(poly1, len1)`` and ``(poly2, len2)``.
418
419    Assumes ``len1 >= len2 > 0`` and ``0 < n <= len1 + len2 - 1``.
420    Allows for zero-padding in the inputs.  Does not support aliasing between
421    the inputs and the output.
422
423.. function:: void fmpz_mod_poly_mullow(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, slong n)
424
425    Sets ``res`` to the lowest `n` coefficients of the product of
426    ``poly1`` and ``poly2``.
427
428.. function:: void _fmpz_mod_poly_sqr(fmpz *res, const fmpz *poly, slong len, const fmpz_t p)
429
430    Sets ``res`` to the square of ``poly``.
431
432.. function:: void fmpz_mod_poly_sqr(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly)
433
434    Computes ``res`` as the square of ``poly``.
435
436.. function:: void _fmpz_mod_poly_mulmod(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, const fmpz * f, slong lenf, const fmpz_t p)
437
438    Sets ``res, len1 + len2 - 1`` to the remainder of the product of
439    ``poly1`` and ``poly2`` upon polynomial division by ``f``.
440
441    It is required that ``len1 + len2 - lenf > 0``, which is equivalent
442    to requiring that the result will actually be reduced. Otherwise, simply
443    use ``_fmpz_mod_poly_mul`` instead.
444
445    Aliasing of ``f`` and ``res`` is not permitted.
446
447.. function:: void fmpz_mod_poly_mulmod(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t f)
448
449    Sets ``res`` to the remainder of the product of ``poly1`` and
450    ``poly2`` upon polynomial division by ``f``.
451
452.. function:: void _fmpz_mod_poly_mulmod_preinv(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, const fmpz * f, slong lenf, const fmpz* finv, slong lenfinv, const fmpz_t p)
453
454    Sets ``res, len1 + len2 - 1`` to the remainder of the product of
455    ``poly1`` and ``poly2`` upon polynomial division by ``f``.
456
457    It is required that ``finv`` is the inverse of the reverse of ``f``
458    mod ``x^lenf``. It is required that ``len1 + len2 - lenf > 0``,
459    which is equivalent to requiring that the result will actually be reduced.
460    It is required that ``len1 < lenf`` and ``len2 < lenf``.
461    Otherwise, simply use ``_fmpz_mod_poly_mul`` instead.
462
463    Aliasing of ``f`` or ``finv`` and ``res`` is not permitted.
464
465.. function:: void fmpz_mod_poly_mulmod_preinv(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv)
466
467    Sets ``res`` to the remainder of the product of ``poly1`` and
468    ``poly2`` upon polynomial division by ``f``. ``finv`` is the
469    inverse of the reverse of ``f``. It is required that ``poly1`` and
470    ``poly2`` are reduced modulo ``f``.
471
472
473Products
474--------------------------------------------------------------------------------
475
476
477.. function:: void _fmpz_mod_poly_product_roots_fmpz_vec(fmpz * poly, const fmpz * xs, slong n, fmpz_t f)
478
479    Sets ``(poly, n + 1)`` to the monic polynomial which is the product
480    of `(x - x_0)(x - x_1) \cdots (x - x_{n-1})`, the roots `x_i` being
481    given by ``xs``. The coefficients reduced modulo ``f``.
482
483    Aliasing of the input and output is not allowed. It is required that
484    ``poly`` is reduced modulo ``f``.
485
486
487.. function:: void fmpz_mod_poly_product_roots_fmpz_vec(fmpz_poly_t poly, const fmpz * xs, slong n, fmpz_t f)
488
489    Sets ``poly`` to the monic polynomial which is the product
490    of `(x - x_0)(x - x_1) \cdots (x - x_{n-1})`, the roots `x_i` being
491    given by ``xs``. The coefficients reduced modulo ``f``.
492
493    It is required that ``poly`` is reduced modulo ``f``.
494
495
496.. function:: int fmpz_mod_poly_find_distinct_nonzero_roots(fmpz * roots, const fmpz_mod_poly_t A)
497
498    If ``A`` has `\deg(A)` distinct nonzero roots in `\mathbb{F}_p`, write these roots out to ``roots[0]`` to ``roots[deg(A) - 1]`` and return ``1``.
499    Otherwise, return ``0``. It is assumed that ``A`` is nonzero and that the modulus of ``A`` is prime.
500    This function uses Rabin's probabilistic method via gcd's with `(x + \delta)^{\frac{p-1}{2}} - 1`.
501
502
503Powering
504
505--------------------------------------------------------------------------------
506
507
508.. function:: void _fmpz_mod_poly_pow(fmpz *rop, const fmpz *op, slong len, ulong e, const fmpz_t p)
509
510    Sets ``rop = poly^e``, assuming that `e > 1` and ``elen > 0``,
511    and that ``res`` has space for ``e*(len - 1) + 1`` coefficients.
512    Does not support aliasing.
513
514.. function:: void fmpz_mod_poly_pow(fmpz_mod_poly_t rop, const fmpz_mod_poly_t op, ulong e)
515
516    Computes ``rop = poly^e``.  If `e` is zero, returns one,
517    so that in particular ``0^0 = 1``.
518
519.. function:: void _fmpz_mod_poly_pow_trunc(fmpz * res, const fmpz * poly, ulong e, slong trunc, const fmpz_t p)
520
521    Sets ``res`` to the low ``trunc`` coefficients of ``poly``
522    (assumed to be zero padded if necessary to length ``trunc``) to
523    the power ``e``. This is equivalent to doing a powering followed
524    by a truncation. We require that ``res`` has enough space for
525    ``trunc`` coefficients, that ``trunc > 0`` and that
526    ``e > 1``. Aliasing is not permitted.
527
528.. function:: void fmpz_mod_poly_pow_trunc(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, ulong e, slong trunc)
529
530    Sets ``res`` to the low ``trunc`` coefficients of ``poly``
531    to the power ``e``. This is equivalent to doing a powering
532    followed by a truncation.
533
534.. function:: void _fmpz_mod_poly_pow_trunc_binexp(fmpz * res, const fmpz * poly, ulong e, slong trunc, const fmpz_t p)
535
536    Sets ``res`` to the low ``trunc`` coefficients of ``poly``
537    (assumed to be zero padded if necessary to length ``trunc``) to
538    the power ``e``. This is equivalent to doing a powering followed
539    by a truncation. We require that ``res`` has enough space for
540    ``trunc`` coefficients, that ``trunc > 0`` and that
541    ``e > 1``. Aliasing is not permitted. Uses the binary
542    exponentiation method.
543
544.. function:: void fmpz_mod_poly_pow_trunc_binexp(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, ulong e, slong trunc)
545
546    Sets ``res`` to the low ``trunc`` coefficients of ``poly``
547    to the power ``e``. This is equivalent to doing a powering
548    followed by a truncation. Uses the binary exponentiation method.
549
550.. function:: void _fmpz_mod_poly_powmod_ui_binexp(fmpz * res, const fmpz * poly, ulong e, const fmpz * f, slong lenf, const fmpz_t p)
551
552    Sets ``res`` to ``poly`` raised to the power ``e``
553    modulo ``f``, using binary exponentiation. We require ``e > 0``.
554
555    We require ``lenf > 1``. It is assumed that ``poly`` is already
556    reduced modulo ``f`` and zero-padded as necessary to have length
557    exactly ``lenf - 1``. The output ``res`` must have room for
558    ``lenf - 1`` coefficients.
559
560.. function:: void fmpz_mod_poly_powmod_ui_binexp(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, ulong e, const fmpz_mod_poly_t f)
561
562    Sets ``res`` to ``poly`` raised to the power ``e``
563    modulo ``f``, using binary exponentiation. We require ``e >= 0``.
564
565.. function:: void _fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz * res, const fmpz * poly, ulong e, const fmpz * f, slong lenf, const fmpz * finv, slong lenfinv, const fmpz_t p)
566
567    Sets ``res`` to ``poly`` raised to the power ``e``
568    modulo ``f``, using binary exponentiation. We require ``e > 0``.
569    We require ``finv`` to be the inverse of the reverse of ``f``.
570
571    We require ``lenf > 1``. It is assumed that ``poly`` is already
572    reduced modulo ``f`` and zero-padded as necessary to have length
573    exactly ``lenf - 1``. The output ``res`` must have room for
574    ``lenf - 1`` coefficients.
575
576.. function:: void fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, ulong e, const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv)
577
578    Sets ``res`` to ``poly`` raised to the power ``e``
579    modulo ``f``, using binary exponentiation. We require ``e >= 0``.
580    We require ``finv`` to be the inverse of the reverse of ``f``.
581
582.. function:: void _fmpz_mod_poly_powmod_fmpz_binexp(fmpz * res, const fmpz * poly, const fmpz_t e, const fmpz * f, slong lenf, const fmpz_t p)
583
584    Sets ``res`` to ``poly`` raised to the power ``e``
585    modulo ``f``, using binary exponentiation. We require ``e > 0``.
586
587    We require ``lenf > 1``. It is assumed that ``poly`` is already
588    reduced modulo ``f`` and zero-padded as necessary to have length
589    exactly ``lenf - 1``. The output ``res`` must have room for
590    ``lenf - 1`` coefficients.
591
592.. function:: void fmpz_mod_poly_powmod_fmpz_binexp(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, const fmpz_t e, const fmpz_mod_poly_t f)
593
594    Sets ``res`` to ``poly`` raised to the power ``e``
595    modulo ``f``, using binary exponentiation. We require ``e >= 0``.
596
597.. function:: void _fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz * res, const fmpz * poly, const fmpz_t e, const fmpz * f, slong lenf, const fmpz* finv, slong lenfinv, const fmpz_t p)
598
599    Sets ``res`` to ``poly`` raised to the power ``e``
600    modulo ``f``, using binary exponentiation. We require ``e > 0``.
601    We require ``finv`` to be the inverse of the reverse of ``f``.
602
603    We require ``lenf > 1``. It is assumed that ``poly`` is already
604    reduced modulo ``f`` and zero-padded as necessary to have length
605    exactly ``lenf - 1``. The output ``res`` must have room for
606    ``lenf - 1`` coefficients.
607
608.. function:: void fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, const fmpz_t e, const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv)
609
610    Sets ``res`` to ``poly`` raised to the power ``e``
611    modulo ``f``, using binary exponentiation. We require ``e >= 0``.
612    We require ``finv`` to be the inverse of the reverse of ``f``.
613
614.. function:: void _fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz * res, const fmpz_t e, const fmpz * f, slong lenf, const fmpz* finv, slong lenfinv, const fmpz_t p)
615
616    Sets ``res`` to ``x`` raised to the power ``e`` modulo ``f``,
617    using sliding window exponentiation. We require ``e > 0``.
618    We require ``finv`` to be the inverse of the reverse of ``f``.
619
620    We require ``lenf > 2``. The output ``res`` must have room for
621    ``lenf - 1`` coefficients.
622
623.. function:: void fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz_mod_poly_t res, const fmpz_t e, const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv)
624
625    Sets ``res`` to ``x`` raised to the power ``e``
626    modulo ``f``, using sliding window exponentiation. We require
627    ``e >= 0``. We require ``finv`` to be the inverse of the reverse of
628    ``
629
630.. function:: void _fmpz_mod_poly_powers_mod_preinv_naive(fmpz ** res, const fmpz * f, slong flen, slong n, const fmpz * g, slong glen, const fmpz * ginv, slong ginvlen, const fmpz_t p)
631
632    Compute ``f^0, f^1, ..., f^(n-1) mod g``, where ``g`` has length ``glen``
633    and ``f`` is reduced mod ``g`` and has length ``flen`` (possibly zero
634    spaced). Assumes ``res`` is an array of ``n`` arrays each with space for
635    at least ``glen - 1`` coefficients and that ``flen > 0``. We require that
636    ``ginv`` of length ``ginvlen`` is set to the power series inverse of the
637    reverse of ``g``.
638
639.. function:: void fmpz_mod_poly_powers_mod_naive(fmpz_mod_poly_struct * res, const fmpz_mod_poly_t f, slong n, const fmpz_mod_poly_t g)
640
641    Set the entries of the array ``res`` to ``f^0, f^1, ..., f^(n-1) mod g``.
642    No aliasing is permitted between the entries of ``res`` and either of the
643    inputs.
644
645.. function:: void _fmpz_mod_poly_powers_mod_preinv_threaded_pool(fmpz ** res, const fmpz * f, slong flen, slong n, const fmpz * g, slong glen, const fmpz * ginv, slong ginvlen, const fmpz_t p, thread_pool_handle * threads, slong num_threads)
646
647    Compute ``f^0, f^1, ..., f^(n-1) mod g``, where ``g`` has length ``glen``
648    and ``f`` is reduced mod ``g`` and has length ``flen`` (possibly zero
649    spaced). Assumes ``res`` is an array of ``n`` arrays each with space for
650    at least ``glen - 1`` coefficients and that ``flen > 0``. We require that
651    ``ginv`` of length ``ginvlen`` is set to the power series inverse of the
652    reverse of ``g``.
653
654.. function:: void fmpz_mod_poly_powers_mod_bsgs(fmpz_mod_poly_struct * res, const fmpz_mod_poly_t f, slong n, const fmpz_mod_poly_t g)
655
656    Set the entries of the array ``res`` to ``f^0, f^1, ..., f^(n-1) mod g``.
657    No aliasing is permitted between the entries of ``res`` and either of the
658    inputs.
659
660.. function:: void fmpz_mod_poly_frobenius_powers_2exp_precomp( fmpz_mod_poly_frobenius_powers_2exp_t pow, const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv, ulong m)
661
662    If ``p = f->p``, compute `x^{(p^1)}`, `x^{(p^2)}`, `x^{(p^4)}`, ...,
663    `x^{(p^{(2^l)})} \pmod{f}` where `2^l` is the greatest power of `2` less than
664    or equal to `m`.
665
666    Allows construction of `x^{(p^k)}` for `k = 0`, `1`, ..., `x^{(p^m)} \pmod{f}`
667    using :func:`fmpz_mod_poly_frobenius_power`.
668
669    Requires precomputed inverse of `f`, i.e. newton inverse.
670
671.. function:: void fmpz_mod_poly_frobenius_powers_2exp_clear(fmpz_mod_poly_frobenius_powers_2exp_t pow)
672
673    Clear resources used by the ``fmpz_mod_poly_frobenius_powers_2exp_t``
674    struct.
675
676.. function:: void fmpz_mod_poly_frobenius_power(fmpz_mod_poly_t res, fmpz_mod_poly_frobenius_powers_2exp_t pow, const fmpz_mod_poly_t f, ulong m)
677
678    If ``p = f->p``, compute `x^{(p^m)} \pmod{f}`.
679
680    Requires precomputed frobenius powers supplied by
681    ``fmpz_mod_poly_frobenius_powers_2exp_precomp``.
682
683    If `m == 0` and `f` has degree `0` or `1`, this performs a division.
684    However an impossible inverse by the leading coefficient of `f` will have
685    been caught by ``fmpz_mod_poly_frobenius_powers_2exp_precomp``.
686
687.. function:: void fmpz_mod_poly_frobenius_powers_precomp(fmpz_mod_poly_frobenius_powers_t pow, const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv, ulong m)
688
689    If ``p = f->p``, compute `x^{(p^0)}`, `x^{(p^1)}`, `x^{(p^2)}`, `x^{(p^3)}`,
690    ..., `x^{(p^m)} \pmod{f}`.
691
692    Requires precomputed inverse of `f`, i.e. newton inverse.
693
694.. function:: void fmpz_mod_poly_frobenius_powers_clear(fmpz_mod_poly_frobenius_powers_t pow)
695
696    Clear resources used by the ``fmpz_mod_poly_frobenius_powers_t``
697    struct.
698
699
700Division
701--------------------------------------------------------------------------------
702
703
704.. function:: void _fmpz_mod_poly_divrem_basecase(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, const fmpz * B, slong lenB, const fmpz_t invB, const fmpz_t p)
705
706    Computes ``(Q, lenA - lenB + 1)``, ``(R, lenA)`` such that
707    `A = B Q + R` with `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
708
709    Assumes that the leading coefficient of `B` is invertible
710    modulo `p`, and that ``invB`` is the inverse.
711
712    Assumes that `\operatorname{len}(A), \operatorname{len}(B) > 0`.  Allows zero-padding in
713    ``(A, lenA)``.  `R` and `A` may be aliased, but apart from this no
714    aliasing of input and output operands is allowed.
715
716.. function:: void fmpz_mod_poly_divrem_basecase(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
717
718    Computes `Q`, `R` such that `A = B Q + R` with
719    `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
720
721    Assumes that the leading coefficient of `B` is invertible
722    modulo `p`.
723
724.. function:: void _fmpz_mod_poly_divrem_newton_n_preinv (fmpz* Q, fmpz* R, const fmpz* A, slong lenA, const fmpz* B, slong lenB, const fmpz* Binv, slong lenBinv, const fmpz_t mod)
725
726    Computes `Q` and `R` such that `A = BQ + R` with `\operatorname{len}(R)` less than
727    ``lenB``, where `A` is of length ``lenA`` and `B` is of length
728    ``lenB``. We require that `Q` have space for ``lenA - lenB + 1``
729    coefficients. Furthermore, we assume that `Binv` is the inverse of the
730    reverse of `B` mod `x^{\operatorname{len}(B)}`. The algorithm used is to call
731    :func:`div_newton_n_preinv` and then multiply out and compute
732    the remainder.
733
734.. function:: void fmpz_mod_poly_divrem_newton_n_preinv(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_poly_t Binv)
735
736    Computes `Q` and `R` such that `A = BQ + R` with `\operatorname{len}(R) < \operatorname{len}(B)`.
737    We assume `Binv` is the inverse of the reverse of `B` mod `x^{\operatorname{len}(B)}`.
738
739    It is required that the length of `A` is less than or equal to
740    2*the length of `B` - 2.
741
742    The algorithm used is to call :func:`div_newton_n` and then multiply out
743    and compute the remainder.
744
745.. function:: void _fmpz_mod_poly_div_basecase(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, const fmpz * B, slong lenB, const fmpz_t invB, const fmpz_t p)
746
747    Notationally, computes `Q`, `R` such that `A = B Q + R` with
748    `0 \leq \operatorname{len}(R) < \operatorname{len}(B)` but only sets ``(Q, lenA - lenB + 1)``.
749
750    Requires temporary space ``(R, lenA)``.  Allows aliasing
751    only between `A` and `R`.  Allows zero-padding in `A` but
752    not in `B`.  Assumes that the leading coefficient of `B`
753    is a unit modulo `p`.
754
755.. function:: void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
756
757    Notationally, computes `Q`, `R` such that `A = B Q + R` with
758    `0 \leq \operatorname{len}(R) < \operatorname{len}(B)` assuming that the leading term
759    of `B` is a unit.
760
761.. function:: void _fmpz_mod_poly_div_newton_n_preinv (fmpz* Q, const fmpz* A, slong lenA, const fmpz* B, slong lenB, const fmpz* Binv, slong lenBinv, const fmpz_t mod)
762
763    Notionally computes polynomials `Q` and `R` such that `A = BQ + R` with
764    `\operatorname{len}(R)` less than ``lenB``, where ``A`` is of length ``lenA``
765    and ``B`` is of length ``lenB``, but return only `Q`.
766
767    We require that `Q` have space for ``lenA - lenB + 1`` coefficients
768    and assume that the leading coefficient of `B` is a unit. Furthermore, we
769    assume that `Binv` is the inverse of the reverse of `B` mod `x^{\operatorname{len}(B)}`.
770
771    The algorithm used is to reverse the polynomials and divide the
772    resulting power series, then reverse the result.
773
774.. function:: void fmpz_mod_poly_div_newton_n_preinv(fmpz_mod_poly_t Q, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_poly_t Binv)
775
776    Notionally computes `Q` and `R` such that `A = BQ + R` with
777    `\operatorname{len}(R) < \operatorname{len}(B)`, but returns only `Q`.
778
779    We assume that the leading coefficient of `B` is a unit and that `Binv` is
780    the inverse of the reverse of `B` mod `x^{\operatorname{len}(B)}`.
781
782    It is required that the length of `A` is less than or equal to
783    2*the length of `B` - 2.
784
785    The algorithm used is to reverse the polynomials and divide the
786    resulting power series, then reverse the result.
787
788.. function:: ulong fmpz_mod_poly_remove(fmpz_mod_poly_t f, const fmpz_mod_poly_t g)
789
790    Removes the highest possible power of ``g`` from ``f`` and
791    returns the exponent.
792
793.. function:: void _fmpz_mod_poly_rem_basecase(fmpz * R, const fmpz * A, slong lenA, const fmpz * B, slong lenB, const fmpz_t invB, const fmpz_t p)
794
795    Notationally, computes `Q`, `R` such that `A = B Q + R` with
796    `0 \leq \operatorname{len}(R) < \operatorname{len}(B)` but only sets ``(R, lenB - 1)``.
797
798    Allows aliasing only between `A` and `R`.  Allows zero-padding
799    in `A` but not in `B`.  Assumes that the leading coefficient
800    of `B` is a unit modulo `p`.
801
802.. function:: void fmpz_mod_poly_rem_basecase(fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
803
804    Notationally, computes `Q`, `R` such that `A = B Q + R` with
805    `0 \leq \operatorname{len}(R) < \operatorname{len}(B)` assuming that the leading term
806    of `B` is a unit.
807
808.. function:: void _fmpz_mod_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W, const fmpz * A, const fmpz * B, slong lenB, const fmpz_t invB, const fmpz_t p)
809
810    Computes ``(Q, lenB)``, ``(BQ, 2 lenB - 1)`` such that
811    `BQ = B \times Q` and `A = B Q + R` where `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
812
813    Assumes that the leading coefficient of `B` is invertible
814    modulo `p`, and that ``invB`` is the inverse.
815
816    Assumes `\operatorname{len}(B) > 0`.  Allows zero-padding in ``(A, lenA)``.  Requires
817    a temporary array ``(W, 2 lenB - 1)``.  No aliasing of input and output
818    operands is allowed.
819
820    This function does not read the bottom `\operatorname{len}(B) - 1` coefficients from
821    `A`, which means that they might not even need to exist in allocated
822    memory.
823
824.. function:: void _fmpz_mod_poly_divrem_divconquer(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, const fmpz * B, slong lenB, const fmpz_t invB, const fmpz_t p)
825
826    Computes ``(Q, lenA - lenB + 1)``, ``(R, lenB - 1)`` such that
827    `A = B Q + R` and `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
828
829    Assumes that the leading coefficient of `B` is invertible
830    modulo `p`, and that ``invB`` is the inverse.
831
832    Assumes `\operatorname{len}(A) \geq \operatorname{len}(B) > 0`.  Allows zero-padding in
833    ``(A, lenA)``.  No aliasing of input and output operands is
834    allowed.
835
836.. function:: void fmpz_mod_poly_divrem_divconquer(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
837
838    Computes `Q`, `R` such that `A = B Q + R` and `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
839
840    Assumes that `B` is non-zero and that the leading coefficient
841    of `B` is invertible modulo `p`.
842
843.. function:: void _fmpz_mod_poly_divrem(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, const fmpz * B, slong lenB, const fmpz_t invB, const fmpz_t p)
844
845    Computes ``(Q, lenA - lenB + 1)``, ``(R, lenB - 1)`` such that
846    `A = B Q + R` and `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
847
848    Assumes that `B` is non-zero, that the leading coefficient
849    of `B` is invertible modulo `p` and that ``invB`` is
850    the inverse.
851
852    Assumes `\operatorname{len}(A) \geq \operatorname{len}(B) > 0`.  Allows zero-padding in
853    ``(A, lenA)``.  No aliasing of input and output operands is
854    allowed.
855
856.. function:: void fmpz_mod_poly_divrem(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
857
858    Computes `Q`, `R` such that `A = B Q + R` and
859    `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
860
861    Assumes that `B` is non-zero and that the leading coefficient
862    of `B` is invertible modulo `p`.
863
864.. function:: void fmpz_mod_poly_divrem_f(fmpz_t f, fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
865
866    Either finds a non-trivial factor~`f` of the modulus~`p`, or computes
867    `Q`, `R` such that `A = B Q + R` and `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`.
868
869    If the leading coefficient of `B` is invertible in `\mathbf{Z}/(p)`,
870    the division with remainder operation is carried out, `Q` and `R` are
871    computed correctly, and `f` is set to `1`.  Otherwise, `f` is set to
872    a non-trivial factor of `p` and `Q` and `R` are not touched.
873
874    Assumes that `B` is non-zero.
875
876.. function:: void _fmpz_mod_poly_rem(fmpz *R, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t invB, const fmpz_t p)
877
878    Notationally, computes ``(Q, lenA - lenB + 1)``, ``(R, lenB - 1)``
879    such that `A = B Q + R` and `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`, returning
880    only the remainder part.
881
882    Assumes that `B` is non-zero, that the leading coefficient
883    of `B` is invertible modulo `p` and that ``invB`` is
884    the inverse.
885
886    Assumes `\operatorname{len}(A) \geq \operatorname{len}(B) > 0`.  Allows zero-padding in
887    ``(A, lenA)``.  No aliasing of input and output operands is
888    allowed.
889
890.. function:: void _fmpz_mod_poly_rem_f(fmpz_t f, fmpz *R, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t invB, const fmpz_t p)
891
892    If `f` returns with the value `1` then the function operates as
893    ``_fmpz_mod_poly_rem``, otherwise `f` will be set to a nontrivial
894    factor of `p`.
895
896.. function:: void fmpz_mod_poly_rem(fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
897
898    Notationally, computes `Q`, `R` such that `A = B Q + R`
899    and `0 \leq \operatorname{len}(R) < \operatorname{len}(B)`, returning only the remainder
900    part.
901
902    Assumes that `B` is non-zero and that the leading coefficient
903    of `B` is invertible modulo `p`.
904
905
906Power series inversion
907--------------------------------------------------------------------------------
908
909
910.. function:: void _fmpz_mod_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n, const fmpz_t cinv, const fmpz_t p)
911
912    Sets ``(Qinv, n)`` to the inverse of ``(Q, n)`` modulo `x^n`,
913    where `n \geq 1`, assuming that the bottom coefficient of `Q` is
914    invertible modulo `p` and that its inverse is ``cinv``.
915
916.. function:: void fmpz_mod_poly_inv_series_newton(fmpz_mod_poly_t Qinv, const fmpz_mod_poly_t Q, slong n)
917
918    Sets ``Qinv`` to the inverse of ``Q`` modulo `x^n`,
919    where `n \geq 1`, assuming that the bottom coefficient of
920    `Q` is a unit.
921
922.. function:: void fmpz_mod_poly_inv_series_newton_f(fmpz_t f, fmpz_mod_poly_t Qinv, const fmpz_mod_poly_t Q, slong n)
923
924    Either sets `f` to a nontrivial factor of `p` with the value of
925    ``Qinv`` undefined, or sets ``Qinv`` to the inverse of ``Q``
926    modulo `x^n`, where `n \geq 1`.
927
928.. function:: void _fmpz_mod_poly_inv_series(fmpz * Qinv, const fmpz * Q, slong n, const fmpz_t cinv, const fmpz_t p)
929
930    Sets ``(Qinv, n)`` to the inverse of ``(Q, n)`` modulo `x^n`,
931    where `n \geq 1`, assuming that the bottom coefficient of `Q` is
932    invertible modulo `p` and that its inverse is ``cinv``.
933
934.. function:: void fmpz_mod_poly_inv_series(fmpz_mod_poly_t Qinv, const fmpz_mod_poly_t Q, slong n)
935
936    Sets ``Qinv`` to the inverse of ``Q`` modulo `x^n`,
937    where `n \geq 1`, assuming that the bottom coefficient of
938    `Q` is a unit.
939
940.. function:: void fmpz_mod_poly_inv_series_f(fmpz_t f, fmpz_mod_poly_t Qinv, const fmpz_mod_poly_t Q, slong n)
941
942    Either sets `f` to a nontrivial factor of `p` with the value of
943    ``Qinv`` undefined, or sets ``Qinv`` to the inverse of ``Q``
944    modulo `x^n`, where `n \geq 1`.
945
946
947Power series division
948--------------------------------------------------------------------------------
949
950
951.. function:: void _fmpz_mod_poly_div_series(fmpz * Q, const fmpz * A, slong Alen, const fmpz * B, slong Blen, const fmpz_t p, slong n)
952
953    Set ``(Q, n)`` to the quotient of the series ``(A, Alen``) and
954    ``(B, Blen)`` assuming ``Alen, Blen <= n``. We assume the bottom
955    coefficient of ``B`` is invertible modulo `p`.
956
957.. function:: void fmpz_mod_poly_div_series(fmpz_mod_poly_t Q, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, slong n)
958
959    Set `Q` to the quotient of the series `A` by `B`, thinking of the series as
960    though they were of length `n`. We assume that the bottom coefficient of
961    `B` is a unit.
962
963
964Greatest common divisor
965--------------------------------------------------------------------------------
966
967
968.. function:: void fmpz_mod_poly_make_monic(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly)
969
970    If ``poly`` is non-zero, sets ``res`` to ``poly`` divided
971    by its leading coefficient.  This assumes that the leading coefficient
972    of ``poly`` is invertible modulo `p`.
973
974    Otherwise, if ``poly`` is zero, sets ``res`` to zero.
975
976.. function:: void fmpz_mod_poly_make_monic_f(fmpz_t f, fmpz_mod_poly_t res, const fmpz_mod_poly_t poly)
977
978    Either set `f` to `1` and ``res`` to ``poly`` divided by its leading
979    coefficient or set `f` to a nontrivial factor of `p` and leave ``res``
980    undefined.
981
982.. function:: slong _fmpz_mod_poly_gcd_euclidean(fmpz *G, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t invB, const fmpz_t p)
983
984    Sets `G` to the greatest common divisor of `(A, \operatorname{len}(A))`
985    and `(B, \operatorname{len}(B))` and returns its length.
986
987    Assumes that `\operatorname{len}(A) \geq \operatorname{len}(B) > 0` and that the vector `G` has
988    space for sufficiently many coefficients.
989
990    Assumes that ``invB`` is the inverse of the leading coefficients
991    of `B` modulo the prime number `p`.
992
993.. function:: void fmpz_mod_poly_gcd_euclidean(fmpz_mod_poly_t G, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
994
995    Sets `G` to the greatest common divisor of `A` and `B`.
996
997    The algorithm used to compute `G` is the classical Euclidean
998    algorithm.
999
1000    In general, the greatest common divisor is defined in the polynomial
1001    ring `(\mathbf{Z}/(p \mathbf{Z}))[X]` if and only if `p` is a prime
1002    number.  Thus, this function assumes that `p` is prime.
1003
1004.. function:: slong _fmpz_mod_poly_gcd(fmpz *G, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t invB, const fmpz_t p)
1005
1006    Sets `G` to the greatest common divisor of `(A, \operatorname{len}(A))`
1007    and `(B, \operatorname{len}(B))` and returns its length.
1008
1009    Assumes that `\operatorname{len}(A) \geq \operatorname{len}(B) > 0` and that the vector `G` has
1010    space for sufficiently many coefficients.
1011
1012    Assumes that ``invB`` is the inverse of the leading coefficients
1013    of `B` modulo the prime number `p`.
1014
1015.. function:: void fmpz_mod_poly_gcd(fmpz_mod_poly_t G, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1016
1017    Sets `G` to the greatest common divisor of `A` and `B`.
1018
1019    In general, the greatest common divisor is defined in the polynomial
1020    ring `(\mathbf{Z}/(p \mathbf{Z}))[X]` if and only if `p` is a prime
1021    number.  Thus, this function assumes that `p` is prime.
1022
1023.. function:: slong _fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz *G, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t p)
1024
1025    Either sets `f = 1` and `G` to the greatest common divisor
1026    of `(A, \operatorname{len}(A))` and `(B, \operatorname{len}(B))` and returns its length,
1027    or sets `f \in (1,p)` to a non-trivial factor of `p` and
1028    leaves the contents of the vector `(G, lenB)` undefined.
1029
1030    Assumes that `\operatorname{len}(A) \geq \operatorname{len}(B) > 0` and that the vector `G` has
1031    space for sufficiently many coefficients.
1032
1033    Does not support aliasing of any of the input arguments
1034    with any of the output argument.
1035
1036.. function:: void fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1037
1038    Either sets `f = 1` and `G` to the greatest common divisor
1039    of `A` and `B`, or ` \in (1,p)` to a non-trivial factor of `p`.
1040
1041    In general, the greatest common divisor is defined in the polynomial
1042    ring `(\mathbf{Z}/(p \mathbf{Z}))[X]` if and only if `p` is a prime
1043    number.
1044
1045.. function:: slong _fmpz_mod_poly_gcd_f(fmpz_t f, fmpz *G, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t p)
1046
1047    Either sets `f = 1` and `G` to the greatest common divisor
1048    of `(A, \operatorname{len}(A))` and `(B, \operatorname{len}(B))` and returns its length,
1049    or sets `f \in (1,p)` to a non-trivial factor of `p` and
1050    leaves the contents of the vector `(G, lenB)` undefined.
1051
1052    Assumes that `\operatorname{len}(A) \geq \operatorname{len}(B) > 0` and that the vector `G` has
1053    space for sufficiently many coefficients.
1054
1055    Does not support aliasing of any of the input arguments
1056    with any of the output arguments.
1057
1058.. function:: void fmpz_mod_poly_gcd_f(fmpz_t f, fmpz_mod_poly_t G, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1059
1060    Either sets `f = 1` and `G` to the greatest common divisor
1061    of `A` and `B`, or `f \in (1,p)` to a non-trivial factor of `p`.
1062
1063    In general, the greatest common divisor is defined in the polynomial
1064    ring `(\mathbf{Z}/(p \mathbf{Z}))[X]` if and only if `p` is a prime
1065    number.
1066
1067.. function:: slong _fmpz_mod_poly_hgcd(fmpz **M, slong *lenM, fmpz *A, slong *lenA, fmpz *B, slong *lenB, const fmpz *a, slong lena, const fmpz *b, slong lenb, const fmpz_t mod)
1068
1069    Computes the HGCD of `a` and `b`, that is, a matrix~`M`, a sign~`\sigma`
1070    and two polynomials `A` and `B` such that
1071
1072    .. math ::
1073
1074
1075        (A,B)^t = \sigma M^{-1} (a,b)^t.
1076
1077
1078
1079    Assumes that `\operatorname{len}(a) > \operatorname{len}(b) > 0`.
1080
1081    Assumes that `A` and `B` have space of size at least `\operatorname{len}(a)`
1082    and `\operatorname{len}(b)`, respectively.  On exit, ``*lenA`` and ``*lenB``
1083    will contain the correct lengths of `A` and `B`.
1084
1085    Assumes that ``M[0]``, ``M[1]``, ``M[2]``, and ``M[3]``
1086    each point to a vector of size at least `\operatorname{len}(a)`.
1087
1088.. function:: slong _fmpz_mod_poly_gcd_hgcd(fmpz *G, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t mod)
1089
1090    Computes the monic GCD of `A` and `B`, assuming that
1091    `\operatorname{len}(A) \geq \operatorname{len}(B) > 0`.
1092
1093    Assumes that `G` has space for `\operatorname{len}(B)` coefficients and
1094    returns the length of `G` on output.
1095
1096.. function:: void fmpz_mod_poly_gcd_hgcd(fmpz_mod_poly_t G, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1097
1098    Computes the monic GCD of `A` and `B` using the HGCD algorithm.
1099
1100    As a special case, the GCD of two zero polynomials is defined to be
1101    the zero polynomial.
1102
1103    The time complexity of the algorithm is `\mathcal{O}(n \log^2 n)`
1104    ring operations. For further details, see [ThullYap1990]_.
1105
1106.. function:: slong _fmpz_mod_poly_xgcd_euclidean(fmpz *G, fmpz *S, fmpz *T, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t invB, const fmpz_t p)
1107
1108    Computes the GCD of `A` and `B` together with cofactors `S` and `T`
1109    such that `S A + T B = G`.  Returns the length of `G`.
1110
1111    Assumes that `\operatorname{len}(A) \geq \operatorname{len}(B) \geq 1` and
1112    `(\operatorname{len}(A),\operatorname{len}(B)) \neq (1,1)`.
1113
1114    No attempt is made to make the GCD monic.
1115
1116    Requires that `G` have space for `\operatorname{len}(B)` coefficients.  Writes
1117    `\operatorname{len}(B)-1` and `\operatorname{len}(A)-1` coefficients to `S` and `T`, respectively.
1118    Note that, in fact, `\operatorname{len}(S) \leq \max(\operatorname{len}(B) - \operatorname{len}(G), 1)` and
1119    `\operatorname{len}(T) \leq \max(\operatorname{len}(A) - \operatorname{len}(G), 1)`.
1120
1121    No aliasing of input and output operands is permitted.
1122
1123.. function:: slong _fmpz_mod_poly_xgcd_euclidean_f(fmpz_t f, fmpz *G, fmpz *S, fmpz *T, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t invB, const fmpz_t p)
1124
1125    If `f` returns with the value `1` then the function operates as per
1126    ``_fmpz_mod_poly_xgcd_euclidean``, otherwise `f` is set to a nontrivial
1127    factor of `p`.
1128
1129.. function:: void fmpz_mod_poly_xgcd_euclidean(fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1130
1131    Computes the GCD of `A` and `B`. The GCD of zero polynomials is
1132    defined to be zero, whereas the GCD of the zero polynomial and some other
1133    polynomial `P` is defined to be `P`. Except in the case where
1134    the GCD is zero, the GCD `G` is made monic.
1135
1136    Polynomials ``S`` and ``T`` are computed such that
1137    ``S*A + T*B = G``. The length of ``S`` will be at most
1138    ``lenB`` and the length of ``T`` will be at most ``lenA``.
1139
1140.. function:: void fmpz_mod_poly_xgcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1141
1142    If `f` returns with the value `1` then the function operates as per
1143    ``fmpz_mod_poly_xgcd_euclidean``, otherwise `f` is set to a nontrivial
1144    factor of `p`.
1145
1146.. function:: slong _fmpz_mod_poly_xgcd_hgcd(fmpz *G, fmpz *S, fmpz *T, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t mod)
1147
1148    Computes the GCD of `A` and `B`, where `\operatorname{len}(A) \geq \operatorname{len}(B) > 0`,
1149    together with cofactors `S` and `T` such that `S A + T B = G`. Returns
1150    the length of `G`.
1151
1152    No attempt is made to make the GCD monic.
1153
1154    Requires that `G` have space for `\operatorname{len}(B)` coefficients.  Writes
1155    `\operatorname{len}(B) - 1` and `\operatorname{len}(A) - 1` coefficients to `S` and `T`,
1156    respectively.  Note that, in fact, `\operatorname{len}(S) \leq \operatorname{len}(B) - \operatorname{len}(G)`
1157    and `\operatorname{len}(T) \leq \operatorname{len}(A) - \operatorname{len}(G)`.
1158
1159    Both `S` and `T` must have space for at least `2` coefficients.
1160
1161    No aliasing of input and output operands is permitted.
1162
1163.. function:: void fmpz_mod_poly_xgcd_hgcd(fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1164
1165    Computes the GCD of `A` and `B`. The GCD of zero polynomials is
1166    defined to be zero, whereas the GCD of the zero polynomial and some other
1167    polynomial `P` is defined to be `P`. Except in the case where
1168    the GCD is zero, the GCD `G` is made monic.
1169
1170    Polynomials ``S`` and ``T`` are computed such that
1171    ``S*A + T*B = G``. The length of ``S`` will be at most
1172    ``lenB`` and the length of ``T`` will be at most ``lenA``.
1173
1174.. function:: slong _fmpz_mod_poly_xgcd(fmpz *G, fmpz *S, fmpz *T, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t invB, const fmpz_t p)
1175
1176    Computes the GCD of `A` and `B` together with cofactors `S` and `T`
1177    such that `S A + T B = G`.  Returns the length of `G`.
1178
1179    Assumes that `\operatorname{len}(A) \geq \operatorname{len}(B) \geq 1` and
1180    `(\operatorname{len}(A),\operatorname{len}(B)) \neq (1,1)`.
1181
1182    No attempt is made to make the GCD monic.
1183
1184    Requires that `G` have space for `\operatorname{len}(B)` coefficients.  Writes
1185    `\operatorname{len}(B)-1` and `\operatorname{len}(A)-1` coefficients to `S` and `T`, respectively.
1186    Note that, in fact, `\operatorname{len}(S) \leq \max(\operatorname{len}(B) - \operatorname{len}(G), 1)` and
1187    `\operatorname{len}(T) \leq \max(\operatorname{len}(A) - \operatorname{len}(G), 1)`.
1188
1189    No aliasing of input and output operands is permitted.
1190
1191.. function:: void fmpz_mod_poly_xgcd(fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1192
1193    Computes the GCD of `A` and `B`. The GCD of zero polynomials is
1194    defined to be zero, whereas the GCD of the zero polynomial and some other
1195    polynomial `P` is defined to be `P`. Except in the case where
1196    the GCD is zero, the GCD `G` is made monic.
1197
1198    Polynomials ``S`` and ``T`` are computed such that
1199    ``S*A + T*B = G``. The length of ``S`` will be at most
1200    ``lenB`` and the length of ``T`` will be at most ``lenA``.
1201
1202.. function:: void fmpz_mod_poly_xgcd_f(fmpz_t f, fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1203
1204    If `f` returns with the value `1` then the function operates as per
1205    ``fmpz_mod_poly_xgcd``, otherwise `f` is set to a nontrivial
1206    factor of `p`.
1207
1208.. function:: slong _fmpz_mod_poly_gcdinv_euclidean(fmpz *G, fmpz *S, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t p)
1209
1210    Computes ``(G, lenA)``, ``(S, lenB-1)`` such that
1211    `G \cong S A \pmod{B}`, returning the actual length of `G`.
1212
1213    Assumes that `0 < \operatorname{len}(A) < \operatorname{len}(B)`.
1214
1215.. function:: void fmpz_mod_poly_gcdinv_euclidean(fmpz_mod_poly_t G, fmpz_mod_poly_t S, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1216
1217    Computes polynomials `G` and `S`, both reduced modulo~`B`,
1218    such that `G \cong S A \pmod{B}`, where `B` is assumed to
1219    have `\operatorname{len}(B) \geq 2`.
1220
1221    In the case that `A = 0 \pmod{B}`, returns `G = S = 0`.
1222
1223.. function:: slong _fmpz_mod_poly_gcdinv_euclidean_f(fmpz_t f, fmpz *G, fmpz *S, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t p)
1224
1225    If `f` returns with value `1` then the function operates as per
1226    :func:`_fmpz_mod_poly_gcdinv_euclidean`, otherwise `f` is set to a
1227    nontrivial factor of `p`.
1228
1229.. function:: void fmpz_mod_poly_gcdinv_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, fmpz_mod_poly_t S, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1230
1231    If `f` returns with value `1` then the function operates as per
1232    :func:`fmpz_mod_poly_gcdinv_euclidean`, otherwise `f` is set to a
1233    nontrivial factor of the modulus of `A`.
1234
1235.. function:: slong _fmpz_mod_poly_gcdinv(fmpz *G, fmpz *S, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t p)
1236
1237    Computes ``(G, lenA)``, ``(S, lenB-1)`` such that
1238    `G \cong S A \pmod{B}`, returning the actual length of `G`.
1239
1240    Assumes that `0 < \operatorname{len}(A) < \operatorname{len}(B)`.
1241
1242.. function:: slong _fmpz_mod_poly_gcdinv_f(fmpz_t f, fmpz *G, fmpz *S, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t p)
1243
1244    If `f` returns with value `1` then the function operates as per
1245    :func:`_fmpz_mod_poly_gcdinv`, otherwise `f` will be set to a nontrivial
1246    factor of `p`.
1247
1248.. function:: void fmpz_mod_poly_gcdinv(fmpz_mod_poly_t G, fmpz_mod_poly_t S, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1249
1250    Computes polynomials `G` and `S`, both reduced modulo~`B`,
1251    such that `G \cong S A \pmod{B}`, where `B` is assumed to
1252    have `\operatorname{len}(B) \geq 2`.
1253
1254    In the case that `A = 0 \pmod{B}`, returns `G = S = 0`.
1255
1256.. function:: void fmpz_mod_poly_gcdinv_f(fmpz_t f, fmpz_mod_poly_t G, fmpz_mod_poly_t S, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B)
1257
1258    If `f` returns with value `1` then the function operates as per
1259    :func:`fmpz_mod_poly_gcdinv`, otherwise `f` will be set to a nontrivial
1260    factor of `p`.
1261
1262.. function:: int _fmpz_mod_poly_invmod(fmpz *A, const fmpz *B, slong lenB, const fmpz *P, slong lenP, const fmpz_t p)
1263
1264    Attempts to set ``(A, lenP-1)`` to the inverse of ``(B, lenB)``
1265    modulo the polynomial ``(P, lenP)``.  Returns `1` if ``(B, lenB)``
1266    is invertible and `0` otherwise.
1267
1268    Assumes that `0 < \operatorname{len}(B) < \operatorname{len}(P)`, and hence also `\operatorname{len}(P) \geq 2`,
1269    but supports zero-padding in ``(B, lenB)``.
1270
1271    Does not support aliasing.
1272
1273    Assumes that `p` is a prime number.
1274
1275.. function:: int _fmpz_mod_poly_invmod_f(fmpz_t f, fmpz *A, const fmpz *B, slong lenB, const fmpz *P, slong lenP, const fmpz_t p)
1276
1277    If `f` returns with the value `1`, then the function operates as per
1278    :func:`_fmpz_mod_poly_invmod`. Otherwise `f` is set to a nontrivial
1279    factor of `p`.
1280
1281.. function:: int fmpz_mod_poly_invmod(fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_poly_t P)
1282
1283    Attempts to set `A` to the inverse of `B` modulo `P` in the polynomial
1284    ring `(\mathbf{Z}/p\mathbf{Z})[X]`, where we assume that `p` is a prime
1285    number.
1286
1287    If `\deg(P) < 2`, raises an exception.
1288
1289    If the greatest common divisor of `B` and `P` is~`1`, returns~`1` and
1290    sets `A` to the inverse of `B`.  Otherwise, returns~`0` and the value
1291    of `A` on exit is undefined.
1292
1293.. function:: int fmpz_mod_poly_invmod_f(fmpz_t f, fmpz_mod_poly_t A, const fmpz_mod_poly_t B, const fmpz_mod_poly_t P)
1294
1295    If `f` returns with the value `1`, then the function operates as per
1296    :func:`fmpz_mod_poly_invmod`. Otherwise `f` is set to a nontrivial
1297    factor of `p`.
1298
1299
1300Minpoly
1301--------------------------------------------------------------------------------
1302
1303
1304.. function:: slong _fmpz_mod_poly_minpoly_bm(fmpz* poly, const fmpz* seq, slong len, const fmpz_t p)
1305
1306    Sets ``poly`` to the coefficients of a minimal generating
1307    polynomial for sequence ``(seq, len)`` modulo `p`.
1308
1309    The return value equals the length of ``poly``.
1310
1311    It is assumed that `p` is prime and ``poly`` has space for at least
1312    `len+1` coefficients. No aliasing between inputs and outputs is
1313    allowed.
1314
1315.. function:: void fmpz_mod_poly_minpoly_bm(fmpz_mod_poly_t poly, const fmpz* seq, slong len)
1316
1317    Sets ``poly`` to a minimal generating polynomial for sequence
1318    ``seq`` of length ``len``.
1319
1320    Assumes that the modulus is prime.
1321
1322    This version uses the Berlekamp-Massey algorithm, whose running time
1323    is proportional to ``len`` times the size of the minimal generator.
1324
1325.. function:: slong _fmpz_mod_poly_minpoly_hgcd(fmpz* poly, const fmpz* seq, slong len, const fmpz_t p)
1326
1327    Sets ``poly`` to the coefficients of a minimal generating
1328    polynomial for sequence ``(seq, len)`` modulo `p`.
1329
1330    The return value equals the length of ``poly``.
1331
1332    It is assumed that `p` is prime and ``poly`` has space for at least
1333    `len+1` coefficients. No aliasing between inputs and outputs is
1334    allowed.
1335
1336.. function:: void fmpz_mod_poly_minpoly_hgcd(fmpz_mod_poly_t poly, const fmpz* seq, slong len)
1337
1338    Sets ``poly`` to a minimal generating polynomial for sequence
1339    ``seq`` of length ``len``.
1340
1341    Assumes that the modulus is prime.
1342
1343    This version uses the HGCD algorithm, whose running time is
1344    `O(n \log^2 n)` field operations, regardless of the actual size of
1345    the minimal generator.
1346
1347.. function:: slong _fmpz_mod_poly_minpoly(fmpz* poly, const fmpz* seq, slong len, const fmpz_t p)
1348
1349    Sets ``poly`` to the coefficients of a minimal generating
1350    polynomial for sequence ``(seq, len)`` modulo `p`.
1351
1352    The return value equals the length of ``poly``.
1353
1354    It is assumed that `p` is prime and ``poly`` has space for at least
1355    `len+1` coefficients. No aliasing between inputs and outputs is
1356    allowed.
1357
1358.. function:: void fmpz_mod_poly_minpoly(fmpz_mod_poly_t poly, const fmpz* seq, slong len)
1359
1360    Sets ``poly`` to a minimal generating polynomial for sequence
1361    ``seq`` of length ``len``.
1362
1363    A minimal generating polynomial is a monic polynomial
1364    `f = x^d + c_{d-1}x^{d-1} + \cdots + c_1 x + c_0`,
1365    of minimal degree `d`, that annihilates any consecutive `d+1` terms
1366    in ``seq``. That is, for any `i < len - d`,
1367
1368    `seq_i = -\sum_{j=0}^{d-1} seq_{i+j}*f_j.`
1369
1370    Assumes that the modulus is prime.
1371
1372    This version automatically chooses the fastest underlying
1373    implementation based on ``len`` and the size of the modulus.
1374
1375
1376
1377Resultant
1378--------------------------------------------------------------------------------
1379
1380
1381.. function:: void _fmpz_mod_poly_resultant_euclidean(fmpz_t res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t mod)
1382
1383    Sets `r` to the resultant of ``(poly1, len1)`` and
1384    ``(poly2, len2)`` using the Euclidean algorithm.
1385
1386    Assumes that ``len1 >= len2 > 0``.
1387
1388    Asumes that the modulus is prime.
1389
1390.. function:: void fmpz_mod_poly_resultant_euclidean(fmpz_t r, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g)
1391
1392    Computes the resultant of `f` and `g` using the Euclidean algorithm.
1393
1394    For two non-zero polynomials `f(x) = a_m x^m + \dotsb + a_0` and
1395    `g(x) = b_n x^n + \dotsb + b_0` of degrees `m` and `n`, the resultant
1396    is defined to be
1397
1398    .. math ::
1399
1400
1401            a_m^n b_n^m \prod_{(x, y) : f(x) = g(y) = 0} (x - y).
1402
1403
1404    For convenience, we define the resultant to be equal to zero if either
1405    of the two polynomials is zero.
1406
1407.. function:: void _fmpz_mod_poly_resultant_hgcd(fmpz_t res, const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t mod)
1408
1409    Sets ``res`` to the resultant of ``(A, lenA)`` and
1410    ``(B, lenB)`` using the half-gcd algorithm.
1411
1412    This algorithm computes the half-gcd as per
1413    :func:`_fmpz_mod_poly_gcd_hgcd`
1414    but additionally updates the resultant every time a division occurs. The
1415    half-gcd algorithm computes the GCD recursively. Given inputs `a` and `b`
1416    it lets ``m = len(a)/2`` and (recursively) performs all quotients in
1417    the Euclidean algorithm which do not require the low `m` coefficients of
1418    `a` and `b`.
1419
1420    This performs quotients in exactly the same order as the ordinary
1421    Euclidean algorithm except that the low `m` coefficients of the polynomials
1422    in the remainder sequence are not computed. A correction step after hgcd
1423    has been called computes these low `m` coefficients (by matrix
1424    multiplication by a transformation matrix also computed by hgcd).
1425
1426    This means that from the point of view of the resultant, all but the last
1427    quotient performed by a recursive call to hgcd is an ordinary quotient as
1428    per the usual Euclidean algorithm. However, the final quotient may give
1429    a remainder of less than `m + 1` coefficients, which won't be corrected
1430    until the hgcd correction step is performed afterwards.
1431
1432    To compute the adjustments to the resultant coming from this corrected
1433    quotient, we save the relevant information in an ``nmod_poly_res_t``
1434    struct at the time the quotient is performed so that when the correction
1435    step is performed later, the adjustments to the resultant can be computed
1436    at that time also.
1437
1438    The only time an adjustment to the resultant is not required after a
1439    call to hgcd is if hgcd does nothing (the remainder may already have had
1440    less than `m + 1` coefficients when hgcd was called).
1441
1442    Assumes that ``lenA >= lenB > 0``.
1443
1444    Asumes that the modulus is prime.
1445
1446.. function:: void fmpz_mod_poly_resultant_hgcd(fmpz_t res, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g)
1447
1448    Computes the resultant of `f` and `g` using the half-gcd algorithm.
1449
1450    For two non-zero polynomials `f(x) = a_m x^m + \dotsb + a_0` and
1451    `g(x) = b_n x^n + \dotsb + b_0` of degrees `m` and `n`, the resultant
1452    is defined to be
1453
1454    .. math ::
1455
1456
1457            a_m^n b_n^m \prod_{(x, y) : f(x) = g(y) = 0} (x - y).
1458
1459
1460    For convenience, we define the resultant to be equal to zero if either
1461    of the two polynomials is zero.
1462
1463.. function:: void _fmpz_mod_poly_resultant(fmpz_t res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t mod)
1464
1465    Returns the resultant of ``(poly1, len1)`` and
1466    ``(poly2, len2)``.
1467
1468    Assumes that ``len1 >= len2 > 0``.
1469
1470    Asumes that the modulus is prime.
1471
1472.. function:: void fmpz_mod_poly_resultant(fmpz_t res, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g)
1473
1474    Computes the resultant of $f$ and $g$.
1475
1476    For two non-zero polynomials `f(x) = a_m x^m + \dotsb + a_0` and
1477    `g(x) = b_n x^n + \dotsb + b_0` of degrees `m` and `n`, the resultant
1478    is defined to be
1479
1480    .. math ::
1481
1482
1483            a_m^n b_n^m \prod_{(x, y) : f(x) = g(y) = 0} (x - y).
1484
1485
1486    For convenience, we define the resultant to be equal to zero if either
1487    of the two polynomials is zero.
1488
1489
1490Discriminant
1491--------------------------------------------------------------------------------
1492
1493
1494.. function:: void _fmpz_mod_poly_discriminant(fmpz_t d, const fmpz *poly, slong len, const fmpz_t mod)
1495
1496    Set `d` to the discriminant of ``(poly, len)``. Assumes ``len > 1``.
1497
1498.. function:: void fmpz_mod_poly_discriminant(fmpz_t d, const fmpz_mod_poly_t f)
1499
1500    Set `d` to the discriminant of `f`.
1501    We normalise the discriminant so that
1502    `\operatorname{disc}(f) = (-1)^(n(n-1)/2) \operatorname{res}(f, f') /
1503    \operatorname{lc}(f)^(n - m - 2)`, where ``n = len(f)`` and
1504    ``m = len(f')``. Thus `\operatorname{disc}(f) =
1505    \operatorname{lc}(f)^(2n - 2) \prod_{i < j} (r_i - r_j)^2`, where
1506    `\operatorname{lc}(f)` is the leading coefficient of `f` and `r_i` are the
1507    roots of `f`.
1508
1509
1510Derivative
1511--------------------------------------------------------------------------------
1512
1513
1514.. function:: void _fmpz_mod_poly_derivative(fmpz *res, const fmpz *poly, slong len, const fmpz_t p)
1515
1516    Sets ``(res, len - 1)`` to the derivative of ``(poly, len)``.
1517    Also handles the cases where ``len`` is `0` or `1` correctly.
1518    Supports aliasing of ``res`` and ``poly``.
1519
1520.. function:: void fmpz_mod_poly_derivative(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly)
1521
1522    Sets ``res`` to the derivative of ``poly``.
1523
1524
1525Evaluation
1526--------------------------------------------------------------------------------
1527
1528
1529.. function:: void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, const fmpz_t a, const fmpz_t p)
1530
1531    Evaluates the polynomial ``(poly, len)`` at the integer `a` and sets
1532    ``res`` to the result.  Aliasing between ``res`` and `a` or any
1533    of the coefficients of ``poly`` is not supported.
1534
1535.. function:: void fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz_mod_poly_t poly, const fmpz_t a)
1536
1537    Evaluates the polynomial ``poly`` at the integer `a` and sets
1538    ``res`` to the result.
1539
1540    As expected, aliasing between ``res`` and `a` is supported.  However,
1541    ``res`` may not be aliased with a coefficient of ``poly``.
1542
1543
1544Multipoint evaluation
1545--------------------------------------------------------------------------------
1546
1547
1548.. function:: void _fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, const fmpz * coeffs, slong len, const fmpz * xs, slong n, const fmpz_t mod)
1549
1550    Evaluates (``coeffs``, ``len``) at the ``n`` values
1551    given in the vector ``xs``, writing the output values
1552    to ``ys``. The values in ``xs`` should be reduced
1553    modulo the modulus.
1554
1555    Uses Horner's method iteratively.
1556
1557.. function:: void fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, const fmpz_mod_poly_t poly, const fmpz * xs, slong n)
1558
1559    Evaluates ``poly`` at the ``n`` values given in the vector
1560    ``xs``, writing the output values to ``ys``. The values in
1561    ``xs`` should be reduced modulo the modulus.
1562
1563    Uses Horner's method iteratively.
1564
1565.. function:: void _fmpz_mod_poly_evaluate_fmpz_vec_fast_precomp(fmpz * vs, const fmpz * poly, slong plen, fmpz_poly_struct * const * tree, slong len, const fmpz_t mod)
1566
1567    Evaluates (``poly``, ``plen``) at the ``len`` values given by the precomputed subproduct tree ``tree``.
1568
1569.. function:: void _fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, const fmpz * poly, slong plen, const fmpz * xs, slong n, const fmpz_t mod)
1570
1571    Evaluates (``coeffs``, ``len``) at the ``n`` values
1572    given in the vector ``xs``, writing the output values
1573    to ``ys``. The values in ``xs`` should be reduced
1574    modulo the modulus.
1575
1576    Uses fast multipoint evaluation, building a temporary subproduct tree.
1577
1578.. function:: void fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, const fmpz_mod_poly_t poly, const fmpz * xs, slong n)
1579
1580    Evaluates ``poly`` at the ``n`` values given in the vector
1581    ``xs``, writing the output values to ``ys``. The values in
1582    ``xs`` should be reduced modulo the modulus.
1583
1584    Uses fast multipoint evaluation, building a temporary subproduct tree.
1585
1586.. function:: void _fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, const fmpz * coeffs, slong len, const fmpz * xs, slong n, const fmpz_t mod)
1587
1588    Evaluates (``coeffs``, ``len``) at the ``n`` values
1589    given in the vector ``xs``, writing the output values
1590    to ``ys``. The values in ``xs`` should be reduced
1591    modulo the modulus.
1592
1593.. function:: void fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, const fmpz_mod_poly_t poly, const fmpz * xs, slong n)
1594
1595    Evaluates ``poly`` at the ``n`` values given in the vector
1596    ``xs``, writing the output values to ``ys``. The values in
1597    ``xs`` should be reduced modulo the modulus.
1598
1599
1600Composition
1601--------------------------------------------------------------------------------
1602
1603
1604.. function:: void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p)
1605
1606    Sets ``res`` to the composition of ``(poly1, len1)`` and
1607    ``(poly2, len2)`` using Horner's algorithm.
1608
1609    Assumes that ``res`` has space for ``(len1-1)*(len2-1) + 1``
1610    coefficients, although in `\mathbf{Z}_p[X]` this might not actually
1611    be the length of the resulting polynomial when `p` is not a prime.
1612
1613    Assumes that ``poly1`` and ``poly2`` are non-zero polynomials.
1614    Does not support aliasing between any of the inputs and the output.
1615
1616.. function:: void fmpz_mod_poly_compose_horner(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
1617
1618    Sets ``res`` to the composition of ``poly1`` and ``poly2``
1619    using Horner's algorithm.
1620
1621    To be precise about the order of composition, denoting ``res``,
1622    ``poly1``, and ``poly2`` by `f`, `g`, and `h`, respectively,
1623    sets `f(t) = g(h(t))`.
1624
1625.. function:: void _fmpz_mod_poly_compose_divconquer(fmpz *res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p)
1626
1627    Sets ``res`` to the composition of ``(poly1, len1)`` and
1628    ``(poly2, len2)`` using a divide and conquer algorithm which
1629    takes out factors of ``poly2`` raised to `2^i` where possible.
1630
1631    Assumes that ``res`` has space for ``(len1-1)*(len2-1) + 1``
1632    coefficients, although in `\mathbf{Z}_p[X]` this might not actually
1633    be the length of the resulting polynomial when `p` is not a prime.
1634
1635    Assumes that ``poly1`` and ``poly2`` are non-zero polynomials.
1636    Does not support aliasing between any of the inputs and the output.
1637
1638.. function:: void fmpz_mod_poly_compose_divconquer(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
1639
1640    Sets ``res`` to the composition of ``poly1`` and ``poly2``
1641    using a divide and conquer algorithm which takes out factors of
1642    ``poly2`` raised to `2^i` where possible.
1643
1644    To be precise about the order of composition, denoting ``res``,
1645    ``poly1``, and ``poly2`` by `f`, `g`, and `h`, respectively,
1646    sets `f(t) = g(h(t))`.
1647
1648.. function:: void _fmpz_mod_poly_compose(fmpz *res, const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p)
1649
1650    Sets ``res`` to the composition of ``(poly1, len1)`` and
1651    ``(poly2, len2)``.
1652
1653    Assumes that ``res`` has space for ``(len1-1)*(len2-1) + 1``
1654    coefficients, although in `\mathbf{Z}_p[X]` this might not actually
1655    be the length of the resulting polynomial when `p` is not a prime.
1656
1657    Assumes that ``poly1`` and ``poly2`` are non-zero polynomials.
1658    Does not support aliasing between any of the inputs and the output.
1659
1660.. function:: void fmpz_mod_poly_compose(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2)
1661
1662    Sets ``res`` to the composition of ``poly1`` and ``poly2``.
1663
1664    To be precise about the order of composition, denoting ``res``,
1665    ``poly1``, and ``poly2`` by `f`, `g`, and `h`, respectively,
1666    sets `f(t) = g(h(t))`.
1667
1668
1669Modular composition
1670--------------------------------------------------------------------------------
1671
1672
1673.. function:: void _fmpz_mod_poly_compose_mod(fmpz * res, const fmpz * f, slong lenf, const fmpz * g, const fmpz * h, slong lenh, const fmpz_t p)
1674
1675    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1676    `h` is nonzero and that the length of `g` is one less than the
1677    length of `h` (possibly with zero padding). The output is not allowed
1678    to be aliased with any of the inputs.
1679
1680.. function:: void fmpz_mod_poly_compose_mod(fmpz_mod_poly_t res, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g, const fmpz_mod_poly_t h)
1681
1682    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1683    `h` is nonzero.
1684
1685.. function:: void _fmpz_mod_poly_compose_mod_horner(fmpz * res, const fmpz * f, slong lenf, const fmpz * g, const fmpz * h, slong lenh, const fmpz_t p)
1686
1687    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1688    `h` is nonzero and that the length of `g` is one less than the
1689    length of `h` (possibly with zero padding). The output is not allowed
1690    to be aliased with any of the inputs.
1691
1692    The algorithm used is Horner's rule.
1693
1694.. function:: void fmpz_mod_poly_compose_mod_horner(fmpz_mod_poly_t res, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g, const fmpz_mod_poly_t h)
1695
1696    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1697    `h` is nonzero. The algorithm used is Horner's rule.
1698
1699.. function:: void _fmpz_mod_poly_compose_mod_brent_kung(fmpz * res, const fmpz * f, slong len1, const fmpz * g, const fmpz * h, slong len3, const fmpz_t p)
1700
1701    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1702    `h` is nonzero and that the length of `g` is one less than the
1703    length of `h` (possibly with zero padding). We also require that
1704    the length of `f` is less than the length of `h`. The output is not
1705    allowed to be aliased with any of the inputs.
1706
1707    The algorithm used is the Brent-Kung matrix algorithm.
1708
1709.. function:: void fmpz_mod_poly_compose_mod_brent_kung( fmpz_mod_poly_t res, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g, const fmpz_mod_poly_t h)
1710
1711    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1712    `h` is nonzero and that `f` has smaller degree than `h`.
1713    The algorithm used is the Brent-Kung matrix algorithm.
1714
1715.. function:: void _fmpz_mod_poly_reduce_matrix_mod_poly (fmpz_mat_t A, const fmpz_mat_t B, const fmpz_mod_poly_t f)
1716
1717    Sets the ith row of ``A`` to the reduction of the ith row of `B` modulo
1718    `f` for `i=1,\ldots,\sqrt{\deg(f)}`. We require `B` to be at least
1719    a `\sqrt{\deg(f)}\times \deg(f)` matrix and `f` to be nonzero.
1720
1721.. function:: void _fmpz_mod_poly_precompute_matrix_worker(void * arg_ptr)
1722
1723    Worker function version of ``_fmpz_mod_poly_precompute_matrix``.
1724    Input/output is stored in ``fmpz_mod_poly_matrix_precompute_arg_t``.
1725
1726.. function:: void _fmpz_mod_poly_precompute_matrix (fmpz_mat_t A, const fmpz * f, const fmpz * g, slong leng, const fmpz * ginv, slong lenginv, const fmpz_t p)
1727
1728    Sets the ith row of ``A`` to `f^i` modulo `g` for
1729    `i=1,\ldots,\sqrt{\deg(g)}`. We require `A` to be
1730    a `\sqrt{\deg(g)}\times \deg(g)` matrix. We require
1731    ``ginv`` to be the inverse of the reverse of ``g`` and `g` to be
1732    nonzero. ``f`` has to be reduced modulo ``g`` and of length one less
1733    than ``leng`` (possibly with zero padding).
1734
1735.. function:: void fmpz_mod_poly_precompute_matrix(fmpz_mat_t A, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g, const fmpz_mod_poly_t ginv)
1736
1737    Sets the ith row of ``A`` to `f^i` modulo `g` for
1738    `i=1,\ldots,\sqrt{\deg(g)}`. We require `A` to be
1739    a `\sqrt{\deg(g)}\times \deg(g)` matrix. We require
1740    ``ginv`` to be the inverse of the reverse of ``g``.
1741
1742.. function:: void _fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv_worker(void * arg_ptr)
1743
1744    Worker function version of
1745    :func:`_fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv`.
1746    Input/output is stored in
1747    ``fmpz_mod_poly_compose_mod_precomp_preinv_arg_t``.
1748
1749.. function:: void _fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz * res, const fmpz * f, slong lenf, const fmpz_mat_t A, const fmpz * h, slong lenh, const fmpz * hinv, slong lenhinv, const fmpz_t p)
1750
1751    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1752    `h` is nonzero. We require that the ith row of `A` contains `g^i` for
1753    `i=1,\ldots,\sqrt{\deg(h)}`, i.e. `A` is a
1754    `\sqrt{\deg(h)}\times \deg(h)` matrix. We also require that
1755    the length of `f` is less than the length of `h`. Furthermore, we require
1756    ``hinv`` to be the inverse of the reverse of ``h``.
1757    The output is not allowed to be aliased with any of the inputs.
1758
1759    The algorithm used is the Brent-Kung matrix algorithm.
1760
1761.. function:: void fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz_mod_poly_t res, const fmpz_mod_poly_t f, const fmpz_mat_t A, const fmpz_mod_poly_t h, const fmpz_mod_poly_t hinv)
1762
1763    Sets ``res`` to the composition `f(g)` modulo `h`. We require that the
1764    ith row of `A` contains `g^i` for `i=1,\ldots,\sqrt{\deg(h)}`, i.e. `A` is
1765    a `\sqrt{\deg(h)}\times \deg(h)` matrix. We require that `h` is nonzero and
1766    that `f` has smaller degree than `h`. Furthermore, we require ``hinv``
1767    to be the inverse of the reverse of ``h``. This version of Brent-Kung
1768    modular composition is particularly useful if one has to perform several
1769    modular composition of the form `f(g)` modulo `h` for fixed `g` and `h`.
1770
1771.. function:: void _fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz * res, const fmpz * f, slong lenf, const fmpz * g, const fmpz * h, slong lenh, const fmpz * hinv, slong lenhinv, const fmpz_t p)
1772
1773    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1774    `h` is nonzero and that the length of `g` is one less than the
1775    length of `h` (possibly with zero padding). We also require that
1776    the length of `f` is less than the length of `h`. Furthermore, we require
1777    ``hinv`` to be the inverse of the reverse of ``h``.
1778    The output is not allowed to be aliased with any of the inputs.
1779
1780    The algorithm used is the Brent-Kung matrix algorithm.
1781
1782.. function:: void fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz_mod_poly_t res, const fmpz_mod_poly_t f, const fmpz_mod_poly_t g, const fmpz_mod_poly_t h, const fmpz_mod_poly_t hinv)
1783
1784    Sets ``res`` to the composition `f(g)` modulo `h`. We require that
1785    `h` is nonzero and that `f` has smaller degree than `h`. Furthermore,
1786    we require ``hinv`` to be the inverse of the reverse of ``h``.
1787    The algorithm used is the Brent-Kung matrix algorithm.
1788
1789.. function:: void _fmpz_mod_poly_compose_mod_brent_kung_vec_preinv(fmpz_mod_poly_struct * res, const fmpz_mod_poly_struct * polys, slong len1, slong l, const fmpz * g, slong glen, const fmpz * h, slong lenh, const fmpz * hinv, slong lenhinv, const fmpz_t p)
1790
1791    Sets ``res`` to the composition `f_i(g)` modulo `h` for `1\leq i \leq l`,
1792    where `f_i` are the ``l`` elements of ``polys``. We require that `h` is
1793    nonzero and that the length of `g` is less than the length of `h`. We
1794    also require that the length of `f_i` is less than the length of `h`. We
1795    require ``res`` to have enough memory allocated to hold ``l``
1796    ``fmpz_mod_poly_struct``'s. The entries of ``res`` need to be initialised
1797    and ``l`` needs to be less than ``len1`` Furthermore, we require ``hinv``
1798    to be the inverse of the reverse of ``h``. The output is not allowed to be
1799    aliased with any of the inputs.
1800
1801    The algorithm used is the Brent-Kung matrix algorithm.
1802
1803.. function:: void fmpz_mod_poly_compose_mod_brent_kung_vec_preinv(fmpz_mod_poly_struct * res, const fmpz_mod_poly_struct * polys, slong len1, slong n, const fmpz_mod_poly_t g, const fmpz_mod_poly_t h, const fmpz_mod_poly_t hinv)
1804
1805    Sets ``res`` to the composition `f_i(g)` modulo `h` for `1\leq i \leq n`
1806    where `f_i` are the ``n`` elements of ``polys``. We require ``res`` to
1807    have enough memory allocated to hold ``n`` ``fmpz_mod_poly_struct``'s.
1808    The entries of ``res`` need to be initialised and ``n`` needs to be less
1809    than ``len1``. We require that `h` is nonzero and that `f_i` and `g` have
1810    smaller degree than `h`. Furthermore, we require ``hinv`` to be the
1811    inverse of the reverse of ``h``. No aliasing of ``res`` and
1812    ``polys`` is allowed.
1813    The algorithm used is the Brent-Kung matrix algorithm.
1814
1815.. function:: void _fmpz_mod_poly_compose_mod_brent_kung_vec_preinv_threaded_pool(fmpz_mod_poly_struct * res, const fmpz_mod_poly_struct * polys, slong lenpolys, slong l, const fmpz * g, slong glen, const fmpz * poly, slong len, const fmpz * polyinv, slong leninv, const fmpz_t p, thread_pool_handle * threads, slong num_threads)
1816
1817    Multithreaded version of
1818    :func:`_fmpz_mod_poly_compose_mod_brent_kung_vec_preinv`. Distributing the
1819    Horner evaluations across :func:`flint_get_num_threads` threads.
1820
1821.. function:: void fmpz_mod_poly_compose_mod_brent_kung_vec_preinv_threaded_pool(fmpz_mod_poly_struct * res,const fmpz_mod_poly_struct * polys, slong len1, slong n, const fmpz_mod_poly_t g, const fmpz_mod_poly_t poly, const fmpz_mod_poly_t polyinv, thread_pool_handle * threads, slong num_threads)
1822
1823    Multithreaded version of
1824    :func:`fmpz_mod_poly_compose_mod_brent_kung_vec_preinv`. Distributing the
1825    Horner evaluations across :func:`flint_get_num_threads` threads.
1826
1827.. function:: void fmpz_mod_poly_compose_mod_brent_kung_vec_preinv_threaded(fmpz_mod_poly_struct * res, const fmpz_mod_poly_struct * polys, slong len1, slong n, const fmpz_mod_poly_t g, const fmpz_mod_poly_t poly, const fmpz_mod_poly_t polyinv)
1828
1829    Multithreaded version of
1830    :func:`fmpz_mod_poly_compose_mod_brent_kung_vec_preinv`. Distributing the
1831    Horner evaluations across :func:`flint_get_num_threads` threads.
1832
1833
1834Subproduct trees
1835--------------------------------------------------------------------------------
1836
1837
1838.. function:: fmpz_poly_struct ** _fmpz_mod_poly_tree_alloc(slong len)
1839
1840    Allocates space for a subproduct tree of the given length, having
1841    linear factors at the lowest level.
1842
1843.. function:: void _fmpz_mod_poly_tree_free(fmpz_poly_struct ** tree, slong len)
1844
1845    Free the allocated space for the subproduct.
1846
1847.. function:: void _fmpz_mod_poly_tree_build(fmpz_poly_struct ** tree, const fmpz * roots, slong len, const fmpz_t mod)
1848
1849    Builds a subproduct tree in the preallocated space from
1850    the ``len`` monic linear factors `(x-r_i)` where `r_i` are given by
1851    ``roots``. The top level product is not computed.
1852
1853
1854Radix conversion
1855--------------------------------------------------------------------------------
1856
1857The following functions provide the functionality to solve the
1858radix conversion problems for polynomials, which is to express
1859a polynomial `f(X)` with respect to a given radix `r(X)` as
1860
1861    .. math ::
1862
1863        f(X) = \sum_{i = 0}^{N} b_i(X) r(X)^i
1864
1865
1866where `N = \lfloor\deg(f) / \deg(r)\rfloor`.
1867The algorithm implemented here is a recursive one, which performs
1868Euclidean divisions by powers of `r` of the form `r^{2^i}`, and it
1869has time complexity `\Theta(\deg(f) \log \deg(f))`.
1870It facilitates the repeated use of precomputed data, namely the
1871powers of `r` and their power series inverses.  This data is stored
1872in objects of type ``fmpz_mod_poly_radix_t`` and it is computed
1873using the function :func:`fmpz_mod_poly_radix_init`, which only
1874depends on~`r` and an upper bound on the degree of~`f`.
1875
1876.. function:: void _fmpz_mod_poly_radix_init(fmpz **Rpow, fmpz **Rinv, const fmpz *R, slong lenR, slong k, const fmpz_t invL, const fmpz_t p)
1877
1878    Computes powers of `R` of the form `R^{2^i}` and their Newton inverses
1879    modulo `x^{2^{i} \deg(R)}` for `i = 0, \dotsc, k-1`.
1880
1881    Assumes that the vectors ``Rpow[i]`` and ``Rinv[i]`` have space
1882    for `2^i \deg(R) + 1` and `2^i \deg(R)` coefficients, respectively.
1883
1884    Assumes that the polynomial `R` is non-constant, i.e. `\deg(R) \geq 1`.
1885
1886    Assumes that the leading coefficient of `R` is a unit and that the
1887    argument ``invL`` is the inverse of the coefficient modulo~`p`.
1888
1889    The argument~`p` is the modulus, which in `p`-adic applications is
1890    typically a prime power, although this is not necessary.  Here, we
1891    only assume that `p \geq 2`.
1892
1893    Note that this precomputed data can be used for any `F` such that
1894    `\operatorname{len}(F) \leq 2^k \deg(R)`.
1895
1896.. function:: void fmpz_mod_poly_radix_init(fmpz_mod_poly_radix_t D, const fmpz_mod_poly_t R, slong degF)
1897
1898    Carries out the precomputation necessary to perform radix conversion
1899    to radix~`R` for polynomials~`F` of degree at most ``degF``.
1900
1901    Assumes that `R` is non-constant, i.e. `\deg(R) \geq 1`,
1902    and that the leading coefficient is a unit.
1903
1904.. function:: void _fmpz_mod_poly_radix(fmpz **B, const fmpz *F, fmpz **Rpow, fmpz **Rinv, slong degR, slong k, slong i, fmpz *W, const fmpz_t p)
1905
1906    This is the main recursive function used by the
1907    function :func:`fmpz_mod_poly_radix`.
1908
1909    Assumes that, for all `i = 0, \dotsc, N`, the vector
1910    ``B[i]`` has space for `\deg(R)` coefficients.
1911
1912    The variable `k` denotes the factors of `r` that have
1913    previously been counted for the polynomial `F`, which
1914    is assumed to have length `2^{i+1} \deg(R)`, possibly
1915    including zero-padding.
1916
1917    Assumes that `W` is a vector providing temporary space
1918    of length `\operatorname{len}(F) = 2^{i+1} \deg(R)`.
1919
1920    The entire computation takes place over `\mathbf{Z} / p \mathbf{Z}`,
1921    where `p \geq 2` is a natural number.
1922
1923    Thus, the top level call will have `F` as in the original
1924    problem, and `k = 0`.
1925
1926.. function:: void fmpz_mod_poly_radix(fmpz_mod_poly_struct **B, const fmpz_mod_poly_t F, const fmpz_mod_poly_radix_t D)
1927
1928    Given a polynomial `F` and the precomputed data `D` for the radix `R`,
1929    computes polynomials `B_0, \dotsc, B_N` of degree less than `\deg(R)`
1930    such that
1931
1932    .. math ::
1933
1934        F = B_0 + B_1 R + \dotsb + B_N R^N,
1935
1936
1937    where necessarily `N = \lfloor\deg(F) / \deg(R)\rfloor`.
1938
1939    Assumes that `R` is non-constant, i.e.\ `\deg(R) \geq 1`,
1940    and that the leading coefficient is a unit.
1941
1942
1943Input and output
1944--------------------------------------------------------------------------------
1945
1946The printing options supported by this module are very similar to
1947what can be found in the two related modules ``fmpz_poly`` and
1948``nmod_poly``.
1949Consider, for example, the polynomial `f(x) = 5x^3 + 2x + 1` in
1950`(\mathbf{Z}/6\mathbf{Z})[x]`.  Its simple string representation
1951is ``"4 6  1 2 0 5"``, where the first two numbers denote the
1952length of the polynomial and the modulus.  The pretty string
1953representation is ``"5*x^3+2*x+1"``.
1954
1955.. function:: int _fmpz_mod_poly_fprint(FILE * file, const fmpz *poly, slong len, const fmpz_t p)
1956
1957    Prints the polynomial ``(poly, len)`` to the stream ``file``.
1958
1959    In case of success, returns a positive value.  In case of failure,
1960    returns a non-positive value.
1961
1962.. function:: int fmpz_mod_poly_fprint(FILE * file, const fmpz_mod_poly_t poly)
1963
1964    Prints the polynomial to the stream ``file``.
1965
1966    In case of success, returns a positive value.  In case of failure,
1967    returns a non-positive value.
1968
1969.. function:: int fmpz_mod_poly_fprint_pretty(FILE * file, const fmpz_mod_poly_t poly, const char * x)
1970
1971    Prints the pretty representation of ``(poly, len)`` to the stream
1972    ``file``, using the string ``x`` to represent the indeterminate.
1973
1974    In case of success, returns a positive value.  In case of failure,
1975    returns a non-positive value.
1976
1977.. function:: int fmpz_mod_poly_print(const fmpz_mod_poly_t poly)
1978
1979    Prints the polynomial to ``stdout``.
1980
1981    In case of success, returns a positive value.  In case of failure,
1982    returns a non-positive value.
1983
1984.. function:: int fmpz_mod_poly_print_pretty(const fmpz_mod_poly_t poly, const char * x)
1985
1986    Prints the pretty representation of ``poly`` to ``stdout``,
1987    using the string ``x`` to represent the indeterminate.
1988
1989    In case of success, returns a positive value.  In case of failure,
1990    returns a non-positive value.
1991
1992Berlekamp-Massey Algorithm
1993--------------------------------------------------------------------------------
1994
1995    The fmpz_mod_berlekamp_massey_t manages an unlimited stream of points `a_1, a_2, \dots .`
1996    At any point in time, after, say, `n` points have been added, a call to :func:`fmpz_mod_berlekamp_massey_reduce` will
1997    calculate the polynomials `U`, `V` and `R` in the extended euclidean remainder sequence with
1998
1999    .. math ::
2000
2001        U*x^n + V*(a_1*x^{n-1} + \cdots + a_{n-1}*x + a_n) = R, \quad \deg(U) < \deg(V) \le n/2, \quad \deg(R) < n/2.
2002
2003    The polynomials `V` and `R` may be obtained with :func:`fmpz_mod_berlekamp_massey_V_poly` and :func:`fmpz_mod_berlekamp_massey_R_poly`.
2004    This class differs from :func:`fmpz_mod_poly_minpoly` in the following respect. Let `v_i` denote the coefficient of `x^i` in `V`.
2005    :func:`fmpz_mod_poly_minpoly` will return a polynomial `V` of lowest degree that annihilates the whole sequence `a_1, \dots, a_n` as
2006
2007    .. math ::
2008
2009        \sum_{i} v_i a_{j + i} = 0, \quad 1 \le j \le n - \deg(V).
2010
2011    The cost is that a polynomial of degree `n-1` might be returned and the return is not generally uniquely determined by the input sequence.
2012    For the fmpz_mod_berlekamp_massey_t we have
2013
2014    .. math ::
2015
2016        \sum_{i,j} v_i a_{j+i} x^{-j} = -U + \frac{R}{x^n}\text{,}
2017
2018    and it can be seen that `\sum_{i} v_i a_{j + i}` is zero for `1 \le j < n - \deg(R)`. Thus whether or not `V` has annihilated the whole sequence may be checked by comparing the degrees of `V` and `R`.
2019
2020.. function:: void fmpz_mod_berlekamp_massey_init(fmpz_mod_berlekamp_massey_t B, const fmpz_t p)
2021              void fmpz_mod_berlekamp_massey_init_ui(fmpz_mod_berlekamp_massey_t B, ulong p)
2022
2023    Initialize ``B`` in characteristic ``p`` with an empty stream.
2024
2025.. function:: void fmpz_mod_berlekamp_massey_clear(fmpz_mod_berlekamp_massey_t B)
2026
2027    Free any space used by ``B``.
2028
2029.. function:: void fmpz_mod_berlekamp_massey_start_over(fmpz_mod_berlekamp_massey_t B)
2030
2031    Empty the stream of points in ``B``.
2032
2033.. function:: void fmpz_mod_berlekamp_massey_set_prime(fmpz_mod_berlekamp_massey_t B, const fmpz_t p)
2034
2035    Set the characteristic of the field and empty the stream of points in ``B``.
2036
2037.. function:: void fmpz_mod_berlekamp_massey_add_points(fmpz_mod_berlekamp_massey_t B, const fmpz * a, slong count)
2038              void fmpz_mod_berlekamp_massey_add_zeros(fmpz_mod_berlekamp_massey_t B, slong count)
2039              void fmpz_mod_berlekamp_massey_add_point(fmpz_mod_berlekamp_massey_t B, const fmpz_t a)
2040
2041    Add point(s) to the stream processed by ``B``. The addition of any number of points will not update the `V` and `R` polynomial.
2042
2043.. function:: int fmpz_mod_berlekamp_massey_reduce(fmpz_mod_berlekamp_massey_t B)
2044
2045    Ensure that the polynomials `V` and `R` are up to date. The return value is ``1`` if this function changed `V` and ``0`` otherwise.
2046    For example, if this function is called twice in a row without adding any points in between, the return of the second call should be ``0``.
2047    As another example, suppose the object is emptied, the points `1, 1, 2, 3` are added, then reduce is called. This reduce should return ``1`` with `\deg(R) < \deg(V) = 2` because the Fibonacci sequence has been recognized. The further addition of the two points `5, 8` and a reduce will result in a return value of ``0``.
2048
2049.. function:: slong fmpz_mod_berlekamp_massey_point_count(const fmpz_mod_berlekamp_massey_t B)
2050
2051    Return the number of points stored in ``B``.
2052
2053.. function:: const fmpz * fmpz_mod_berlekamp_massey_points(const fmpz_mod_berlekamp_massey_t B)
2054
2055    Return a pointer the array of points stored in ``B``. This may be ``NULL`` if func::fmpz_mod_berlekamp_massey_point_count returns ``0``.
2056
2057.. function:: const fmpz_mod_poly_struct * fmpz_mod_berlekamp_massey_V_poly(const fmpz_mod_berlekamp_massey_t B)
2058
2059    Return the polynomial ``V`` in ``B``.
2060
2061.. function:: const fmpz_mod_poly_struct * fmpz_mod_berlekamp_massey_R_poly(const fmpz_mod_berlekamp_massey_t B)
2062
2063    Return the polynomial ``R`` in ``B``.
2064