1163 lines
40 KiB
C
1163 lines
40 KiB
C
|
/*=============================================================================
|
||
|
|
||
|
This file is part of FLINT.
|
||
|
|
||
|
FLINT is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
FLINT is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with FLINT; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
|
||
|
=============================================================================*/
|
||
|
/******************************************************************************
|
||
|
|
||
|
Copyright (C) 2007, David Howden
|
||
|
Copyright (C) 2010, 2011 William Hart
|
||
|
Copyright (C) 2011 Sebastian Pancratz
|
||
|
Copyright (C) 2011 Fredrik Johansson
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
#ifndef NMOD_POLY_H
|
||
|
#define NMOD_POLY_H
|
||
|
|
||
|
#undef ulong
|
||
|
#define ulong ulongxx /* interferes with system includes */
|
||
|
#include <stdio.h>
|
||
|
#undef ulong
|
||
|
#include <gmp.h>
|
||
|
#define ulong mp_limb_t
|
||
|
|
||
|
#include "flint.h"
|
||
|
#include "nmod_vec.h"
|
||
|
#include "nmod_mat.h"
|
||
|
#include "ulong_extras.h"
|
||
|
#include "fmpz.h"
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
#define NMOD_DIVREM_DIVCONQUER_CUTOFF 300
|
||
|
#define NMOD_DIV_DIVCONQUER_CUTOFF 300 /* Must be <= NMOD_DIVREM_DIVCONQUER_CUTOFF */
|
||
|
|
||
|
#define NMOD_POLY_HGCD_CUTOFF 100 /* HGCD: Basecase -> Recursion */
|
||
|
#define NMOD_POLY_GCD_CUTOFF 340 /* GCD: Euclidean -> HGCD */
|
||
|
#define NMOD_POLY_SMALL_GCD_CUTOFF 200 /* GCD (small n): Euclidean -> HGCD */
|
||
|
|
||
|
static __inline__
|
||
|
slong NMOD_DIVREM_BC_ITCH(slong lenA, slong lenB, nmod_t mod)
|
||
|
{
|
||
|
const mp_bitcnt_t bits =
|
||
|
2 * (FLINT_BITS - mod.norm) + FLINT_BIT_COUNT(lenA - lenB + 1);
|
||
|
|
||
|
if (bits <= FLINT_BITS)
|
||
|
return lenA;
|
||
|
else if (bits <= 2 * FLINT_BITS)
|
||
|
return 2*(lenA + lenB - 1);
|
||
|
else
|
||
|
return 3*(lenA + lenB - 1);
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
slong NMOD_DIV_BC_ITCH(slong lenA, slong lenB, nmod_t mod)
|
||
|
{
|
||
|
const mp_bitcnt_t bits =
|
||
|
2 * (FLINT_BITS - mod.norm) + FLINT_BIT_COUNT(lenA - lenB + 1);
|
||
|
|
||
|
if (bits <= FLINT_BITS)
|
||
|
return lenA - lenB + 1;
|
||
|
else if (bits <= 2 * FLINT_BITS)
|
||
|
return 2*lenA;
|
||
|
else
|
||
|
return 3*lenA;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
slong NMOD_DIVREM_DC_ITCH(slong lenB, nmod_t mod)
|
||
|
{
|
||
|
slong i = 0;
|
||
|
|
||
|
while (lenB > NMOD_DIVREM_DIVCONQUER_CUTOFF + i)
|
||
|
{
|
||
|
lenB = (lenB + 1)/2;
|
||
|
i++;
|
||
|
}
|
||
|
if (lenB > NMOD_DIVREM_DIVCONQUER_CUTOFF)
|
||
|
lenB = NMOD_DIVREM_DIVCONQUER_CUTOFF;
|
||
|
|
||
|
return NMOD_DIVREM_BC_ITCH(2*lenB - 1, lenB, mod) + 2*lenB - 1;
|
||
|
}
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
mp_ptr coeffs;
|
||
|
slong alloc;
|
||
|
slong length;
|
||
|
nmod_t mod;
|
||
|
} nmod_poly_struct;
|
||
|
|
||
|
typedef nmod_poly_struct nmod_poly_t[1];
|
||
|
|
||
|
/* zn_poly helper functions ************************************************
|
||
|
|
||
|
Copyright (C) 2007, 2008 David Harvey
|
||
|
|
||
|
*/
|
||
|
|
||
|
static __inline__
|
||
|
int signed_mpn_sub_n(mp_ptr res, mp_srcptr op1, mp_srcptr op2, slong n)
|
||
|
{
|
||
|
if (mpn_cmp(op1, op2, n) >= 0)
|
||
|
{
|
||
|
mpn_sub_n(res, op1, op2, n);
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mpn_sub_n(res, op2, op1, n);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Memory management ********************************************************/
|
||
|
|
||
|
void nmod_poly_init(nmod_poly_t poly, mp_limb_t n);
|
||
|
|
||
|
void nmod_poly_init_preinv(nmod_poly_t poly, mp_limb_t n, mp_limb_t ninv);
|
||
|
|
||
|
void nmod_poly_init2(nmod_poly_t poly, mp_limb_t n, slong alloc);
|
||
|
|
||
|
void nmod_poly_init2_preinv(nmod_poly_t poly,
|
||
|
mp_limb_t n, mp_limb_t ninv, slong alloc);
|
||
|
|
||
|
void nmod_poly_realloc(nmod_poly_t poly, slong alloc);
|
||
|
|
||
|
void nmod_poly_clear(nmod_poly_t poly);
|
||
|
|
||
|
void nmod_poly_fit_length(nmod_poly_t poly, slong alloc);
|
||
|
|
||
|
static __inline__
|
||
|
void _nmod_poly_set_length(nmod_poly_t poly, slong len)
|
||
|
{
|
||
|
poly->length = len;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
void _nmod_poly_normalise(nmod_poly_t poly)
|
||
|
{
|
||
|
while (poly->length && (poly->coeffs[poly->length - 1] == WORD(0)))
|
||
|
poly->length--;
|
||
|
}
|
||
|
|
||
|
/* Polynomial parameters ****************************************************/
|
||
|
|
||
|
static __inline__
|
||
|
slong nmod_poly_length(const nmod_poly_t poly)
|
||
|
{
|
||
|
return poly->length;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
slong nmod_poly_degree(const nmod_poly_t poly)
|
||
|
{
|
||
|
return poly->length - 1;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
mp_limb_t nmod_poly_modulus(const nmod_poly_t poly)
|
||
|
{
|
||
|
return poly->mod.n;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
mp_bitcnt_t nmod_poly_max_bits(const nmod_poly_t poly)
|
||
|
{
|
||
|
return _nmod_vec_max_bits(poly->coeffs, poly->length);
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
mp_ptr nmod_poly_lead(const nmod_poly_t poly)
|
||
|
{
|
||
|
if (poly->length)
|
||
|
return poly->coeffs + (poly->length - 1);
|
||
|
else
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/* Assignment and basic manipulation ****************************************/
|
||
|
|
||
|
static __inline__
|
||
|
void nmod_poly_set(nmod_poly_t a, const nmod_poly_t b)
|
||
|
{
|
||
|
if (a != b)
|
||
|
{
|
||
|
nmod_poly_fit_length(a, b->length);
|
||
|
flint_mpn_copyi(a->coeffs, b->coeffs, b->length);
|
||
|
a->length = b->length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
void nmod_poly_swap(nmod_poly_t poly1, nmod_poly_t poly2)
|
||
|
{
|
||
|
slong t;
|
||
|
mp_ptr tp;
|
||
|
|
||
|
t = poly1->alloc;
|
||
|
poly1->alloc = poly2->alloc;
|
||
|
poly2->alloc = t;
|
||
|
|
||
|
t = poly1->length;
|
||
|
poly1->length = poly2->length;
|
||
|
poly2->length = t;
|
||
|
|
||
|
tp = poly1->coeffs;
|
||
|
poly1->coeffs = poly2->coeffs;
|
||
|
poly2->coeffs = tp;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
void nmod_poly_zero(nmod_poly_t res)
|
||
|
{
|
||
|
res->length = 0;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
void nmod_poly_one(nmod_poly_t res)
|
||
|
{
|
||
|
nmod_poly_fit_length(res, 1);
|
||
|
res->length = 1;
|
||
|
res->coeffs[0] = 1;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
void nmod_poly_truncate(nmod_poly_t poly, slong len)
|
||
|
{
|
||
|
if (poly->length > len)
|
||
|
{
|
||
|
poly->length = len;
|
||
|
_nmod_poly_normalise(poly);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void _nmod_poly_reverse(mp_ptr output, mp_srcptr input, slong len, slong m);
|
||
|
|
||
|
void nmod_poly_reverse(nmod_poly_t output, const nmod_poly_t input, slong m);
|
||
|
|
||
|
/* Comparison ***************************************************************/
|
||
|
|
||
|
static __inline__
|
||
|
int nmod_poly_equal(const nmod_poly_t a, const nmod_poly_t b)
|
||
|
{
|
||
|
if (a->length != b->length)
|
||
|
return 0;
|
||
|
|
||
|
if (a != b)
|
||
|
if (!_nmod_vec_equal(a->coeffs, b->coeffs, a->length))
|
||
|
return 0;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
int nmod_poly_is_zero(const nmod_poly_t poly)
|
||
|
{
|
||
|
return (poly->length == 0);
|
||
|
}
|
||
|
|
||
|
static __inline__ int
|
||
|
nmod_poly_is_one(const nmod_poly_t poly)
|
||
|
{
|
||
|
return (poly->length == 1) && (poly->coeffs[0] == 1);
|
||
|
}
|
||
|
|
||
|
/* Randomisation ************************************************************/
|
||
|
|
||
|
void nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len);
|
||
|
|
||
|
static __inline__ void
|
||
|
nmod_poly_randtest_not_zero(nmod_poly_t poly, flint_rand_t state, slong len)
|
||
|
{
|
||
|
do {
|
||
|
nmod_poly_randtest(poly, state, len);
|
||
|
} while (nmod_poly_is_zero(poly));
|
||
|
}
|
||
|
|
||
|
void
|
||
|
nmod_poly_randtest_irreducible(nmod_poly_t poly, flint_rand_t state, slong len);
|
||
|
|
||
|
void
|
||
|
nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len);
|
||
|
|
||
|
void
|
||
|
nmod_poly_randtest_monic_irreducible(nmod_poly_t poly, flint_rand_t state, slong len);
|
||
|
|
||
|
void
|
||
|
nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len);
|
||
|
|
||
|
int
|
||
|
nmod_poly_randtest_trinomial_irreducible(nmod_poly_t poly, flint_rand_t state,
|
||
|
slong len, slong max_attempts);
|
||
|
|
||
|
void
|
||
|
nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len);
|
||
|
|
||
|
int
|
||
|
nmod_poly_randtest_pentomial_irreducible(nmod_poly_t poly, flint_rand_t state,
|
||
|
slong len, slong max_attempts);
|
||
|
|
||
|
void
|
||
|
nmod_poly_randtest_sparse_irreducible(nmod_poly_t poly, flint_rand_t state, slong len);
|
||
|
|
||
|
/* Getting and setting coefficients *****************************************/
|
||
|
|
||
|
static __inline__
|
||
|
ulong nmod_poly_get_coeff_ui(const nmod_poly_t poly, slong j)
|
||
|
{
|
||
|
return (j >= poly->length) ? 0 : poly->coeffs[j];
|
||
|
}
|
||
|
|
||
|
void nmod_poly_set_coeff_ui(nmod_poly_t poly, slong j, ulong c);
|
||
|
|
||
|
/* Input and output *********************************************************/
|
||
|
|
||
|
char * nmod_poly_get_str(const nmod_poly_t poly);
|
||
|
|
||
|
int nmod_poly_set_str(nmod_poly_t poly, const char * s);
|
||
|
|
||
|
static __inline__
|
||
|
int nmod_poly_print(const nmod_poly_t a)
|
||
|
{
|
||
|
size_t r;
|
||
|
slong i;
|
||
|
|
||
|
r = flint_printf("%wd %wu", a->length, a->mod.n);
|
||
|
|
||
|
if (a->length == 0)
|
||
|
return r;
|
||
|
else
|
||
|
if (r > 0)
|
||
|
r = flint_printf(" ");
|
||
|
|
||
|
for (i = 0; (r > 0) && (i < a->length); i++)
|
||
|
r = flint_printf(" %wu", a->coeffs[i]);
|
||
|
|
||
|
return (int) r;
|
||
|
}
|
||
|
|
||
|
int nmod_poly_fread(FILE * f, nmod_poly_t poly);
|
||
|
|
||
|
static __inline__
|
||
|
int nmod_poly_fprint(FILE * f, const nmod_poly_t poly)
|
||
|
{
|
||
|
char *s;
|
||
|
int r;
|
||
|
|
||
|
s = nmod_poly_get_str(poly);
|
||
|
r = fputs(s, f);
|
||
|
flint_free(s);
|
||
|
|
||
|
return (r < 0) ? r : 1;
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
int nmod_poly_read(nmod_poly_t poly)
|
||
|
{
|
||
|
return nmod_poly_fread(stdin, poly);
|
||
|
}
|
||
|
|
||
|
/* Shifting *****************************************************************/
|
||
|
|
||
|
void _nmod_poly_shift_left(mp_ptr res, mp_srcptr poly, slong len, slong k);
|
||
|
|
||
|
void nmod_poly_shift_left(nmod_poly_t res, const nmod_poly_t poly, slong k);
|
||
|
|
||
|
void _nmod_poly_shift_right(mp_ptr res, mp_srcptr poly, slong len, slong k);
|
||
|
|
||
|
void nmod_poly_shift_right(nmod_poly_t res, const nmod_poly_t poly, slong k);
|
||
|
|
||
|
/* Addition and subtraction *************************************************/
|
||
|
|
||
|
void _nmod_poly_add(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_add(nmod_poly_t res, const nmod_poly_t poly1,
|
||
|
const nmod_poly_t poly2);
|
||
|
|
||
|
void _nmod_poly_sub(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_sub(nmod_poly_t res, const nmod_poly_t poly1,
|
||
|
const nmod_poly_t poly2);
|
||
|
|
||
|
void nmod_poly_neg(nmod_poly_t res, const nmod_poly_t poly1);
|
||
|
|
||
|
/* Scalar multiplication and division ***************************************/
|
||
|
|
||
|
void nmod_poly_scalar_mul_nmod(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, mp_limb_t c);
|
||
|
|
||
|
void _nmod_poly_make_monic(mp_ptr output,
|
||
|
mp_srcptr input, slong len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_make_monic(nmod_poly_t output, const nmod_poly_t input);
|
||
|
|
||
|
/* Bit packing and unpacking aand reduction **********************************/
|
||
|
|
||
|
void _nmod_poly_KS2_pack1(mp_ptr res, mp_srcptr op, slong n, slong s,
|
||
|
ulong b, ulong k, slong r);
|
||
|
|
||
|
void _nmod_poly_KS2_pack(mp_ptr res, mp_srcptr op, slong n, slong s,
|
||
|
ulong b, ulong k, slong r);
|
||
|
|
||
|
void _nmod_poly_KS2_unpack1(mp_ptr res, mp_srcptr op, slong n, ulong b,
|
||
|
ulong k);
|
||
|
|
||
|
void _nmod_poly_KS2_unpack2(mp_ptr res, mp_srcptr op, slong n, ulong b,
|
||
|
ulong k);
|
||
|
|
||
|
void _nmod_poly_KS2_unpack3(mp_ptr res, mp_srcptr op, slong n, ulong b,
|
||
|
ulong k);
|
||
|
|
||
|
void _nmod_poly_KS2_unpack(mp_ptr res, mp_srcptr op, slong n, ulong b,
|
||
|
ulong k);
|
||
|
|
||
|
void _nmod_poly_KS2_reduce(mp_ptr res, slong s, mp_srcptr op,
|
||
|
slong n, ulong w, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_KS2_recover_reduce1(mp_ptr res, slong s, mp_srcptr op1,
|
||
|
mp_srcptr op2, slong n, ulong b, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_KS2_recover_reduce1(mp_ptr res, slong s, mp_srcptr op1,
|
||
|
mp_srcptr op2, slong n, ulong b, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_KS2_recover_reduce2(mp_ptr res, slong s, mp_srcptr op1,
|
||
|
mp_srcptr op2, slong n, ulong b, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_KS2_recover_reduce2b(mp_ptr res, slong s, mp_srcptr op1,
|
||
|
mp_srcptr op2, slong n, ulong b, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_KS2_recover_reduce(mp_ptr res, slong s, mp_srcptr op1,
|
||
|
mp_srcptr op2, slong n, ulong b, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_bit_pack(mp_ptr res, mp_srcptr poly,
|
||
|
slong len, mp_bitcnt_t bits);
|
||
|
|
||
|
void _nmod_poly_bit_unpack(mp_ptr res, slong len,
|
||
|
mp_srcptr mpn, mp_bitcnt_t bits, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_bit_pack(fmpz_t f, const nmod_poly_t poly,
|
||
|
mp_bitcnt_t bit_size);
|
||
|
|
||
|
void
|
||
|
nmod_poly_bit_unpack(nmod_poly_t poly, const fmpz_t f, mp_bitcnt_t bit_size);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_KS2_pack(mp_ptr res, mp_srcptr op, slong n, slong s,
|
||
|
ulong b, ulong k, slong r);
|
||
|
|
||
|
/* Multiplication ***********************************************************/
|
||
|
|
||
|
void _nmod_poly_mul_classical(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mul_classical(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2);
|
||
|
|
||
|
void _nmod_poly_mullow_classical(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, slong trunc, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mullow_classical(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, slong trunc);
|
||
|
|
||
|
void _nmod_poly_mulhigh_classical(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, slong start, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mulhigh_classical(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, slong start);
|
||
|
|
||
|
void _nmod_poly_mul_KS(mp_ptr out, mp_srcptr in1, slong len1,
|
||
|
mp_srcptr in2, slong len2, mp_bitcnt_t bits, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mul_KS(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, mp_bitcnt_t bits);
|
||
|
|
||
|
void _nmod_poly_mul_KS2(mp_ptr res, mp_srcptr op1, slong n1,
|
||
|
mp_srcptr op2, slong n2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mul_KS2(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2);
|
||
|
|
||
|
void _nmod_poly_mul_KS4(mp_ptr res, mp_srcptr op1, slong n1,
|
||
|
mp_srcptr op2, slong n2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mul_KS4(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2);
|
||
|
|
||
|
void _nmod_poly_mullow_KS(mp_ptr out, mp_srcptr in1, slong len1,
|
||
|
mp_srcptr in2, slong len2, mp_bitcnt_t bits, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mullow_KS(nmod_poly_t res, const nmod_poly_t poly1,
|
||
|
const nmod_poly_t poly2, mp_bitcnt_t bits, slong n);
|
||
|
|
||
|
void _nmod_poly_mul(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mul(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2);
|
||
|
|
||
|
void _nmod_poly_mullow(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, slong trunc, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mullow(nmod_poly_t res, const nmod_poly_t poly1,
|
||
|
const nmod_poly_t poly2, slong trunc);
|
||
|
|
||
|
void _nmod_poly_mulhigh(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mulhigh(nmod_poly_t res, const nmod_poly_t poly1,
|
||
|
const nmod_poly_t poly2, slong n);
|
||
|
|
||
|
void _nmod_poly_mulmod(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, mp_srcptr f,
|
||
|
slong lenf, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_mulmod(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t f);
|
||
|
|
||
|
void _nmod_poly_mulmod_preinv(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, mp_srcptr f,
|
||
|
slong lenf, mp_srcptr finv, slong lenfinv, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_mulmod_preinv(nmod_poly_t res, const nmod_poly_t poly1,
|
||
|
const nmod_poly_t poly2, const nmod_poly_t f,
|
||
|
const nmod_poly_t finv);
|
||
|
|
||
|
int _nmod_poly_invmod(mp_limb_t *A,
|
||
|
const mp_limb_t *B, slong lenB,
|
||
|
const mp_limb_t *P, slong lenP, const nmod_t mod);
|
||
|
|
||
|
int nmod_poly_invmod(nmod_poly_t A,
|
||
|
const nmod_poly_t B, const nmod_poly_t P);
|
||
|
|
||
|
/* Powering *****************************************************************/
|
||
|
|
||
|
void _nmod_poly_pow_binexp(mp_ptr res,
|
||
|
mp_srcptr poly, slong len, ulong e, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_pow_binexp(nmod_poly_t res, const nmod_poly_t poly, ulong e);
|
||
|
|
||
|
void _nmod_poly_pow(mp_ptr res, mp_srcptr poly, slong len, ulong e, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_pow(nmod_poly_t res, const nmod_poly_t poly, ulong e);
|
||
|
|
||
|
void _nmod_poly_pow_trunc_binexp(mp_ptr res, mp_srcptr poly,
|
||
|
ulong e, slong trunc, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_pow_trunc_binexp(nmod_poly_t res,
|
||
|
const nmod_poly_t poly, ulong e, slong trunc);
|
||
|
|
||
|
void _nmod_poly_pow_trunc(mp_ptr res, mp_srcptr poly,
|
||
|
ulong e, slong trunc, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_pow_trunc(nmod_poly_t res,
|
||
|
const nmod_poly_t poly, ulong e, slong trunc);
|
||
|
|
||
|
void
|
||
|
nmod_poly_powmod_ui_binexp(nmod_poly_t res,
|
||
|
const nmod_poly_t poly, ulong e,
|
||
|
const nmod_poly_t f);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_powmod_ui_binexp(mp_ptr res, mp_srcptr poly,
|
||
|
ulong e, mp_srcptr f, slong lenf, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_powmod_mpz_binexp(mp_ptr res, mp_srcptr poly,
|
||
|
mpz_srcptr e, mp_srcptr f,
|
||
|
slong lenf, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_powmod_mpz_binexp(nmod_poly_t res,
|
||
|
const nmod_poly_t poly, mpz_srcptr e,
|
||
|
const nmod_poly_t f);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_powmod_ui_binexp_preinv (mp_ptr res, mp_srcptr poly,
|
||
|
ulong e, mp_srcptr f, slong lenf,
|
||
|
mp_srcptr finv, slong lenfinv, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_powmod_ui_binexp_preinv(nmod_poly_t res,
|
||
|
const nmod_poly_t poly, ulong e,
|
||
|
const nmod_poly_t f, const nmod_poly_t finv);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_powmod_x_ui_preinv (mp_ptr res, ulong e, mp_srcptr f, slong lenf,
|
||
|
mp_srcptr finv, slong lenfinv, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_powmod_x_ui_preinv(nmod_poly_t res, ulong e, const nmod_poly_t f,
|
||
|
const nmod_poly_t finv);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_powmod_mpz_binexp_preinv (mp_ptr res, mp_srcptr poly,
|
||
|
mpz_srcptr e, mp_srcptr f, slong lenf,
|
||
|
mp_srcptr finv, slong lenfinv, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_powmod_mpz_binexp_preinv(nmod_poly_t res,
|
||
|
const nmod_poly_t poly, mpz_srcptr e,
|
||
|
const nmod_poly_t f, const nmod_poly_t finv);
|
||
|
|
||
|
/* Division *****************************************************************/
|
||
|
|
||
|
void _nmod_poly_divrem_basecase(mp_ptr Q, mp_ptr R, mp_ptr W,
|
||
|
mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_divrem_basecase(nmod_poly_t Q, nmod_poly_t R,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_divrem_divconquer_recursive(mp_ptr Q, mp_ptr BQ, mp_ptr W,
|
||
|
mp_ptr V, mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_divrem_divconquer(mp_ptr Q, mp_ptr R,
|
||
|
mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_divrem_divconquer(nmod_poly_t Q, nmod_poly_t R,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_divrem_q0(mp_ptr Q, mp_ptr R,
|
||
|
mp_srcptr A, mp_srcptr B, slong lenA, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_divrem_q1(mp_ptr Q, mp_ptr R,
|
||
|
mp_srcptr A, slong lenA, mp_srcptr B, slong lenB,
|
||
|
nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_divrem(mp_ptr Q, mp_ptr R, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_divrem(nmod_poly_t Q, nmod_poly_t R,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_div_basecase(mp_ptr Q, mp_ptr W, mp_srcptr A, slong A_len,
|
||
|
mp_srcptr B, slong B_len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_div_basecase(nmod_poly_t Q, const nmod_poly_t A,
|
||
|
const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_div_divconquer_recursive(mp_ptr Q, mp_ptr W, mp_ptr V,
|
||
|
mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_div_divconquer(mp_ptr Q, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_div_divconquer(nmod_poly_t Q,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_div(mp_ptr Q, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_div(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_rem_basecase(mp_ptr R, mp_ptr W, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_rem_basecase(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_rem_q1(mp_ptr R,
|
||
|
mp_srcptr A, slong lenA, mp_srcptr B, slong lenB,
|
||
|
nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_rem(mp_ptr R, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_rem(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_inv_series_basecase(mp_ptr Qinv,
|
||
|
mp_srcptr Q, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_inv_series_basecase(nmod_poly_t Qinv,
|
||
|
const nmod_poly_t Q, slong n);
|
||
|
|
||
|
void _nmod_poly_inv_series_newton(mp_ptr Qinv,
|
||
|
mp_srcptr Q, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_inv_series_newton(nmod_poly_t Qinv,
|
||
|
const nmod_poly_t Q, slong n);
|
||
|
|
||
|
static __inline__
|
||
|
void _nmod_poly_inv_series(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod)
|
||
|
{
|
||
|
_nmod_poly_inv_series_newton(Qinv, Q, n, mod);
|
||
|
}
|
||
|
|
||
|
static __inline__
|
||
|
void nmod_poly_inv_series(nmod_poly_t Qinv, const nmod_poly_t Q, slong n)
|
||
|
{
|
||
|
nmod_poly_inv_series_newton(Qinv, Q, n);
|
||
|
}
|
||
|
|
||
|
void _nmod_poly_div_series(mp_ptr Q, mp_srcptr A, mp_srcptr B,
|
||
|
slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_div_series(nmod_poly_t Q, const nmod_poly_t A,
|
||
|
const nmod_poly_t B, slong n);
|
||
|
|
||
|
void _nmod_poly_div_newton(mp_ptr Q, mp_srcptr A, slong Alen,
|
||
|
mp_srcptr B, slong Blen, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_div_newton(nmod_poly_t Q, const nmod_poly_t A,
|
||
|
const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_divrem_newton(mp_ptr Q, mp_ptr R,
|
||
|
mp_srcptr A, slong Alen, mp_srcptr B, slong Blen, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_divrem_newton(nmod_poly_t Q, nmod_poly_t R,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
void _nmod_poly_div_newton_n_preinv (mp_ptr Q, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, mp_srcptr Binv, slong lenBinv, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_div_newton_n_preinv (nmod_poly_t Q, const nmod_poly_t A,
|
||
|
const nmod_poly_t B, const nmod_poly_t Binv);
|
||
|
|
||
|
void _nmod_poly_divrem_newton_n_preinv (mp_ptr Q, mp_ptr R, mp_srcptr A,
|
||
|
slong lenA, mp_srcptr B, slong lenB, mp_srcptr Binv, slong lenBinv, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_divrem_newton_n_preinv(nmod_poly_t Q, nmod_poly_t R,
|
||
|
const nmod_poly_t A, const nmod_poly_t B, const nmod_poly_t Binv);
|
||
|
|
||
|
mp_limb_t
|
||
|
_nmod_poly_div_root(mp_ptr Q, mp_srcptr A, slong len, mp_limb_t c, nmod_t mod);
|
||
|
|
||
|
mp_limb_t
|
||
|
nmod_poly_div_root(nmod_poly_t Q, const nmod_poly_t A, mp_limb_t c);
|
||
|
|
||
|
/* Derivative ***************************************************************/
|
||
|
|
||
|
void _nmod_poly_derivative(mp_ptr x_prime, mp_srcptr x, slong len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_derivative(nmod_poly_t x_prime, const nmod_poly_t x);
|
||
|
|
||
|
void _nmod_poly_integral(mp_ptr x_int, mp_srcptr x, slong len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_integral(nmod_poly_t x_int, const nmod_poly_t x);
|
||
|
|
||
|
/* Evaluation ***************************************************************/
|
||
|
void
|
||
|
_nmod_poly_evaluate_fmpz(fmpz_t rop, const mp_srcptr poly, const slong len, const fmpz_t c);
|
||
|
|
||
|
void
|
||
|
nmod_poly_evaluate_fmpz(fmpz_t rop, const nmod_poly_t poly, const fmpz_t c);
|
||
|
|
||
|
mp_limb_t _nmod_poly_evaluate_nmod(mp_srcptr poly,
|
||
|
slong len, mp_limb_t c, nmod_t mod);
|
||
|
|
||
|
mp_limb_t nmod_poly_evaluate_nmod(const nmod_poly_t poly, mp_limb_t c);
|
||
|
|
||
|
void _nmod_poly_evaluate_nmod_vec(mp_ptr ys, mp_srcptr coeffs, slong len,
|
||
|
mp_srcptr xs, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_evaluate_nmod_vec(mp_ptr ys,
|
||
|
const nmod_poly_t poly, mp_srcptr xs, slong n);
|
||
|
|
||
|
void nmod_poly_evaluate_nmod_vec(mp_ptr ys, const nmod_poly_t poly,
|
||
|
mp_srcptr xs, slong n);
|
||
|
|
||
|
void _nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys, mp_srcptr coeffs, slong len,
|
||
|
mp_srcptr xs, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys,
|
||
|
const nmod_poly_t poly, mp_srcptr xs, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_evaluate_nmod_vec_fast_precomp(mp_ptr vs, mp_srcptr poly,
|
||
|
slong plen, const mp_ptr * tree, slong len, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys, mp_srcptr coeffs, slong len,
|
||
|
mp_srcptr xs, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys,
|
||
|
const nmod_poly_t poly, mp_srcptr xs, slong n);
|
||
|
|
||
|
/* Subproduct tree **********************************************************/
|
||
|
|
||
|
mp_ptr * _nmod_poly_tree_alloc(slong len);
|
||
|
|
||
|
void _nmod_poly_tree_free(mp_ptr * tree, slong len);
|
||
|
|
||
|
void _nmod_poly_tree_build(mp_ptr * tree, mp_srcptr roots,
|
||
|
slong len, nmod_t mod);
|
||
|
|
||
|
/* Interpolation ************************************************************/
|
||
|
|
||
|
void _nmod_poly_interpolate_nmod_vec_newton(mp_ptr poly, mp_srcptr xs,
|
||
|
mp_srcptr ys, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_interpolate_nmod_vec_newton(nmod_poly_t poly,
|
||
|
mp_srcptr xs, mp_srcptr ys, slong n);
|
||
|
|
||
|
void _nmod_poly_interpolate_nmod_vec_barycentric(mp_ptr poly, mp_srcptr xs,
|
||
|
mp_srcptr ys, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_interpolate_nmod_vec_barycentric(nmod_poly_t poly,
|
||
|
mp_srcptr xs, mp_srcptr ys, slong n);
|
||
|
|
||
|
void _nmod_poly_interpolate_nmod_vec(mp_ptr poly, mp_srcptr xs,
|
||
|
mp_srcptr ys, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_interpolate_nmod_vec(nmod_poly_t poly,
|
||
|
mp_srcptr xs, mp_srcptr ys, slong n);
|
||
|
|
||
|
void nmod_poly_interpolate_nmod_vec_fast(nmod_poly_t poly,
|
||
|
mp_srcptr xs, mp_srcptr ys, slong n);
|
||
|
|
||
|
void _nmod_poly_interpolate_nmod_vec_fast(mp_ptr poly,
|
||
|
mp_srcptr xs, mp_srcptr ys, slong len, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_interpolate_nmod_vec_fast_precomp(mp_ptr poly, mp_srcptr ys,
|
||
|
const mp_ptr * tree, mp_srcptr weights, slong len, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_interpolation_weights(mp_ptr w, const mp_ptr * tree,
|
||
|
slong len, nmod_t mod);
|
||
|
|
||
|
/* Composition **************************************************************/
|
||
|
|
||
|
void _nmod_poly_compose_horner(mp_ptr res, mp_srcptr poly1,
|
||
|
slong len1, mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_compose_horner(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2);
|
||
|
|
||
|
void _nmod_poly_compose_divconquer(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
void nmod_poly_compose_divconquer(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2);
|
||
|
|
||
|
void _nmod_poly_compose(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_compose(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2);
|
||
|
|
||
|
/* Taylor shift *************************************************************/
|
||
|
|
||
|
void _nmod_poly_taylor_shift_horner(mp_ptr poly, mp_limb_t c,
|
||
|
slong len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_taylor_shift_horner(nmod_poly_t g,
|
||
|
const nmod_poly_t f, mp_limb_t c);
|
||
|
|
||
|
void _nmod_poly_taylor_shift_convolution(mp_ptr poly, mp_limb_t c,
|
||
|
slong len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_taylor_shift_convolution(nmod_poly_t g,
|
||
|
const nmod_poly_t f, mp_limb_t c);
|
||
|
|
||
|
void _nmod_poly_taylor_shift(mp_ptr poly, mp_limb_t c, slong len, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_taylor_shift(nmod_poly_t g, const nmod_poly_t f, mp_limb_t c);
|
||
|
|
||
|
/* Modular composition ******************************************************/
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_mod_brent_kung(mp_ptr res, mp_srcptr f, slong lenf,
|
||
|
mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_compose_mod_brent_kung(nmod_poly_t res,
|
||
|
const nmod_poly_t f, const nmod_poly_t g,
|
||
|
const nmod_poly_t h);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_reduce_matrix_mod_poly (nmod_mat_t A, const nmod_mat_t B,
|
||
|
const nmod_poly_t f);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_precompute_matrix (nmod_mat_t A, mp_srcptr poly1, mp_srcptr poly2,
|
||
|
slong len2, mp_srcptr poly2inv, slong len2inv, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_precompute_matrix (nmod_mat_t A, const nmod_poly_t poly1,
|
||
|
const nmod_poly_t poly2, const nmod_poly_t poly2inv);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_mod_brent_kung_precomp_preinv(mp_ptr res, mp_srcptr poly1,
|
||
|
slong len1, const nmod_mat_t A, mp_srcptr poly3,
|
||
|
slong len3, mp_srcptr poly3inv, slong len3inv,
|
||
|
nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_compose_mod_brent_kung_precomp_preinv(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_mat_t A,
|
||
|
const nmod_poly_t poly3, const nmod_poly_t poly3inv);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_mod_brent_kung_preinv(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, mp_srcptr poly3, slong len3,
|
||
|
mp_srcptr poly3inv, slong len3inv, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_compose_mod_brent_kung_preinv(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2,
|
||
|
const nmod_poly_t poly3, const nmod_poly_t poly3inv);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_mod_horner(mp_ptr res,
|
||
|
mp_srcptr f, slong lenf, mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_compose_mod_horner(nmod_poly_t res,
|
||
|
const nmod_poly_t f, const nmod_poly_t g,
|
||
|
const nmod_poly_t h);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_mod(mp_ptr res, mp_srcptr f, slong lenf,
|
||
|
mp_srcptr g,
|
||
|
mp_srcptr h, slong lenh, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_compose_mod(nmod_poly_t res,
|
||
|
const nmod_poly_t f, const nmod_poly_t g,
|
||
|
const nmod_poly_t h);
|
||
|
|
||
|
/* Power series composition and reversion ************************************/
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_series_horner(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, slong n, nmod_t mod);
|
||
|
void
|
||
|
nmod_poly_compose_series_horner(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_series_brent_kung(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, slong n, nmod_t mod);
|
||
|
void
|
||
|
nmod_poly_compose_series_brent_kung(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_series(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, slong n, nmod_t mod);
|
||
|
void
|
||
|
nmod_poly_compose_series(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_revert_series_lagrange(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_revert_series_lagrange(nmod_poly_t Qinv,
|
||
|
const nmod_poly_t Q, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_revert_series_lagrange_fast(mp_ptr Qinv, mp_srcptr Q,
|
||
|
slong n, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_revert_series_lagrange_fast(nmod_poly_t Qinv,
|
||
|
const nmod_poly_t Q, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_revert_series_newton(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_revert_series_newton(nmod_poly_t Qinv,
|
||
|
const nmod_poly_t Q, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_revert_series(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_revert_series(nmod_poly_t Qinv,
|
||
|
const nmod_poly_t Q, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_compose_series_divconquer(mp_ptr res, mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2,
|
||
|
slong N, nmod_t mod);
|
||
|
|
||
|
void
|
||
|
nmod_poly_compose_series_divconquer(nmod_poly_t res,
|
||
|
const nmod_poly_t poly1, const nmod_poly_t poly2, slong N);
|
||
|
|
||
|
/* Greatest common divisor **************************************************/
|
||
|
|
||
|
slong _nmod_poly_gcd_euclidean(mp_ptr G,
|
||
|
mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_gcd_euclidean(nmod_poly_t G,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
slong _nmod_poly_hgcd(mp_ptr *M, slong *lenM,
|
||
|
mp_ptr A, slong *lenA, mp_ptr B, slong *lenB,
|
||
|
mp_srcptr a, slong lena, mp_srcptr b, slong lenb,
|
||
|
nmod_t mod);
|
||
|
|
||
|
slong _nmod_poly_gcd_hgcd(mp_ptr G, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_gcd_hgcd(nmod_poly_t G, const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
slong _nmod_poly_gcd(mp_ptr G, mp_srcptr A, slong lenA,
|
||
|
mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_gcd(nmod_poly_t G, const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
slong _nmod_poly_xgcd_euclidean(mp_ptr res, mp_ptr s, mp_ptr t,
|
||
|
mp_srcptr poly1, slong len1, mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_xgcd_euclidean(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
slong _nmod_poly_xgcd_hgcd(mp_ptr G, mp_ptr S, mp_ptr T,
|
||
|
mp_srcptr A, slong lenA, mp_srcptr B, slong lenB,
|
||
|
nmod_t mod);
|
||
|
|
||
|
void nmod_poly_xgcd_hgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
slong _nmod_poly_xgcd(mp_ptr G, mp_ptr S, mp_ptr T,
|
||
|
mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_xgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
mp_limb_t
|
||
|
_nmod_poly_resultant_euclidean(mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod);
|
||
|
|
||
|
mp_limb_t
|
||
|
nmod_poly_resultant_euclidean(const nmod_poly_t f, const nmod_poly_t g);
|
||
|
|
||
|
static __inline__ mp_limb_t
|
||
|
_nmod_poly_resultant(mp_srcptr poly1, slong len1,
|
||
|
mp_srcptr poly2, slong len2, nmod_t mod)
|
||
|
{
|
||
|
return _nmod_poly_resultant_euclidean(poly1, len1, poly2, len2, mod);
|
||
|
}
|
||
|
|
||
|
static __inline__ mp_limb_t
|
||
|
nmod_poly_resultant(const nmod_poly_t f, const nmod_poly_t g)
|
||
|
{
|
||
|
return nmod_poly_resultant_euclidean(f, g);
|
||
|
}
|
||
|
|
||
|
slong _nmod_poly_gcdinv(mp_limb_t *G, mp_limb_t *S,
|
||
|
const mp_limb_t *A, slong lenA,
|
||
|
const mp_limb_t *B, slong lenB,
|
||
|
const nmod_t mod);
|
||
|
|
||
|
void nmod_poly_gcdinv(nmod_poly_t G, nmod_poly_t S,
|
||
|
const nmod_poly_t A, const nmod_poly_t B);
|
||
|
|
||
|
/* Square roots **************************************************************/
|
||
|
|
||
|
void _nmod_poly_invsqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_invsqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_sqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
|
||
|
void nmod_poly_sqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
int _nmod_poly_sqrt(mp_ptr s, mp_srcptr p, slong len, nmod_t mod);
|
||
|
|
||
|
int nmod_poly_sqrt(nmod_poly_t b, const nmod_poly_t a);
|
||
|
|
||
|
/* Transcendental functions **************************************************/
|
||
|
|
||
|
void _nmod_poly_atan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_atan_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_tan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_tan_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_asin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_asin_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_sin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_sin_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_cos_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_cos_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_asinh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_asinh_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_atanh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_atanh_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_sinh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_sinh_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_cosh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_cosh_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_tanh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_tanh_series(nmod_poly_t g, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_log_series_monomial_ui(mp_ptr res, mp_limb_t coeff,
|
||
|
ulong power, slong n, nmod_t mod);
|
||
|
void nmod_poly_log_series_monomial_ui(nmod_poly_t res, mp_limb_t coeff,
|
||
|
ulong power, slong n);
|
||
|
|
||
|
void _nmod_poly_log_series(mp_ptr res, mp_srcptr f, slong n, nmod_t mod);
|
||
|
void nmod_poly_log_series(nmod_poly_t res, const nmod_poly_t f, slong n);
|
||
|
|
||
|
void _nmod_poly_exp_series_monomial_ui(mp_ptr res, mp_limb_t coeff,
|
||
|
ulong power, slong n, nmod_t mod);
|
||
|
void nmod_poly_exp_series_monomial_ui(nmod_poly_t res, mp_limb_t coeff,
|
||
|
ulong power, slong n);
|
||
|
|
||
|
|
||
|
void
|
||
|
_nmod_poly_exp_series_basecase(mp_ptr f, mp_srcptr h,
|
||
|
slong hlen, slong n, nmod_t mod);
|
||
|
void nmod_poly_exp_series_basecase(nmod_poly_t f, const nmod_poly_t h, slong n);
|
||
|
|
||
|
void _nmod_poly_exp_expinv_series(mp_ptr f, mp_ptr g, mp_srcptr h, slong n, nmod_t mod);
|
||
|
|
||
|
void _nmod_poly_exp_series(mp_ptr f, mp_srcptr h, slong n, nmod_t mod);
|
||
|
void nmod_poly_exp_series(nmod_poly_t f, const nmod_poly_t h, slong n);
|
||
|
|
||
|
/* Products *****************************************************************/
|
||
|
|
||
|
void
|
||
|
nmod_poly_product_roots_nmod_vec(nmod_poly_t poly, mp_srcptr xs, slong n);
|
||
|
|
||
|
void
|
||
|
_nmod_poly_product_roots_nmod_vec(mp_ptr poly,
|
||
|
mp_srcptr xs, slong n, nmod_t mod);
|
||
|
|
||
|
/* Inflation and deflation ***************************************************/
|
||
|
|
||
|
ulong nmod_poly_deflation(const nmod_poly_t input);
|
||
|
|
||
|
void nmod_poly_deflate(nmod_poly_t result, const nmod_poly_t input,
|
||
|
ulong deflation);
|
||
|
|
||
|
void nmod_poly_inflate(nmod_poly_t result, const nmod_poly_t input,
|
||
|
ulong inflation);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#include "nmod_poly_factor.h"
|
||
|
|
||
|
#endif
|