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