/*
Copyright (C) 2020 Daniel Schultz
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See .
*/
#ifndef N_POLY_H
#define N_POLY_H
#ifdef N_POLY_INLINES_C
#define N_POLY_INLINE FLINT_DLL
#else
#define N_POLY_INLINE static __inline__
#endif
#undef ulong
#define ulong ulongxx /* interferes with system includes */
#include
#undef ulong
#include
#define ulong mp_limb_t
#include "nmod_poly.h"
#include "fq_nmod_poly.h"
#ifdef __cplusplus
extern "C" {
#endif
/* arrays of ulong */
typedef struct
{
mp_limb_t * coeffs;
slong alloc;
slong length;
} n_poly_struct;
typedef n_poly_struct n_poly_t[1];
typedef n_poly_struct n_fq_poly_struct;
typedef n_poly_t n_fq_poly_t;
/* arrays of arrays of ulong */
typedef struct
{
n_poly_struct * coeffs;
slong alloc;
slong length;
} n_bpoly_struct;
typedef n_bpoly_struct n_bpoly_t[1];
typedef n_bpoly_struct n_fq_bpoly_struct;
typedef n_bpoly_t n_fq_bpoly_t;
/* arrays of arrays of arrays of ulong */
typedef struct
{
n_bpoly_struct * coeffs;
slong alloc;
slong length;
} n_tpoly_struct;
typedef n_tpoly_struct n_tpoly_t[1];
typedef n_tpoly_struct n_fq_tpoly_struct;
typedef n_tpoly_t n_fq_tpoly_t;
/* sparse arrays of ulong */
typedef struct
{
ulong * exps;
mp_limb_t * coeffs;
slong length;
slong alloc;
} n_polyu_struct;
typedef n_polyu_struct n_polyu_t[1];
typedef n_polyu_struct n_fq_polyu_struct;
typedef n_polyu_t n_fq_polyu_t;
/*
sparse arrays of arrays of ulong
n_polyu1n => one exponent is in the exps[i]
n_polyu2n => two exponents are packed into the exps[i]
...
*/
typedef struct
{
n_poly_struct * coeffs;
ulong * exps;
slong length;
slong alloc;
} n_polyun_struct;
typedef n_polyun_struct n_polyun_t[1];
typedef n_polyun_struct n_fq_polyun_struct;
typedef n_polyun_t n_fq_polyun_t;
/* n_poly stack */
typedef struct
{
n_poly_struct ** array;
slong alloc;
slong top;
} n_poly_stack_struct;
typedef n_poly_stack_struct n_poly_stack_t[1];
/* n_bpoly stack */
typedef struct
{
n_bpoly_struct ** array;
slong alloc;
slong top;
} n_bpoly_stack_struct;
typedef n_bpoly_stack_struct n_bpoly_stack_t[1];
typedef struct {
n_poly_stack_t poly_stack;
n_bpoly_stack_t bpoly_stack;
} n_poly_bpoly_stack_struct;
typedef n_poly_bpoly_stack_struct n_poly_bpoly_stack_t[1];
/* n_polyun stack */
typedef struct
{
n_polyun_struct ** array;
slong alloc;
slong top;
} n_polyun_stack_struct;
typedef n_polyun_stack_struct n_polyun_stack_t[1];
typedef struct {
n_poly_stack_t poly_stack;
n_polyun_stack_t polyun_stack;
} n_poly_polyun_stack_struct;
typedef n_poly_polyun_stack_struct n_poly_polyun_stack_t[1];
/*****************************************************************************/
N_POLY_INLINE
void n_poly_init(n_poly_t A)
{
A->length = 0;
A->alloc = 0;
A->coeffs = NULL;
}
N_POLY_INLINE
void n_poly_init2(n_poly_t A, slong alloc)
{
A->length = 0;
A->alloc = alloc;
A->coeffs = NULL;
if (alloc > 0)
A->coeffs = (mp_limb_t *) flint_malloc(alloc*sizeof(mp_limb_t));
}
N_POLY_INLINE
void n_poly_clear(n_poly_t A)
{
FLINT_ASSERT(A->alloc != 0 || A->coeffs == NULL);
if (A->alloc > 0)
flint_free(A->coeffs);
}
FLINT_DLL int n_poly_is_canonical(const n_poly_t A);
FLINT_DLL void n_poly_realloc(n_poly_t A, slong len);
FLINT_DLL void n_poly_print_pretty(const n_poly_t A, const char * x);
N_POLY_INLINE
void n_poly_fit_length(n_poly_t A, slong len)
{
if (len > A->alloc)
n_poly_realloc(A, len);
}
N_POLY_INLINE
void nmod_poly_mock(nmod_poly_t a, const n_poly_t b, nmod_t mod)
{
a->coeffs = b->coeffs;
a->length = b->length;
a->alloc = b->alloc;
a->mod = mod;
}
N_POLY_INLINE
void n_poly_mock(n_poly_t a, const nmod_poly_t b)
{
a->coeffs = b->coeffs;
a->length = b->length;
a->alloc = b->alloc;
}
N_POLY_INLINE
void n_poly_set(n_poly_t A, const n_poly_t B)
{
n_poly_fit_length(A, B->length);
flint_mpn_copyi(A->coeffs, B->coeffs, B->length);
A->length = B->length;
}
N_POLY_INLINE
void n_poly_swap(n_poly_t A, n_poly_t B)
{
n_poly_struct t = *B;
*B = *A;
*A = t;
}
N_POLY_INLINE
void _n_poly_normalise(n_poly_t A)
{
while (A->length > 0 && A->coeffs[A->length - 1] == 0)
A->length--;
}
N_POLY_INLINE
slong n_poly_degree(const n_poly_t A)
{
FLINT_ASSERT(A->length >= 0);
return A->length - 1;
}
N_POLY_INLINE
int n_poly_is_one(const n_poly_t A)
{
return A->length == 1 && A->coeffs[0] == 1;
}
N_POLY_INLINE
mp_limb_t n_poly_lead(const n_poly_t A)
{
FLINT_ASSERT(A->length > 0);
return A->coeffs[A->length - 1];
}
N_POLY_INLINE
void n_poly_one(n_poly_t A)
{
n_poly_fit_length(A, 1);
A->length = 1;
A->coeffs[0] = 1;
}
N_POLY_INLINE
void n_poly_set_ui(n_poly_t A, mp_limb_t c)
{
n_poly_fit_length(A, 1);
A->coeffs[0] = c;
A->length = (c != 0);
}
N_POLY_INLINE
int n_poly_is_zero(const n_poly_t poly)
{
return poly->length == 0;
}
N_POLY_INLINE
void n_poly_zero(n_poly_t res)
{
res->length = 0;
}
N_POLY_INLINE
int n_poly_equal(const n_poly_t a, const n_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;
}
/*****************************************************************************/
FLINT_DLL int n_poly_mod_is_canonical(const n_poly_t A, nmod_t mod);
N_POLY_INLINE
void n_poly_mod_make_monic(n_poly_t A, const n_poly_t B, nmod_t mod)
{
FLINT_ASSERT(B->length > 0);
n_poly_fit_length(A, B->length);
A->length = B->length;
_nmod_poly_make_monic(A->coeffs, B->coeffs, B->length, mod);
}
N_POLY_INLINE
void n_poly_mod_taylor_shift(n_poly_t g, mp_limb_t c, nmod_t mod)
{
_nmod_poly_taylor_shift(g->coeffs, c, g->length, mod);
}
N_POLY_INLINE
ulong n_poly_get_coeff(const n_poly_t poly, slong j)
{
return (j >= poly->length) ? 0 : poly->coeffs[j];
}
N_POLY_INLINE
void n_poly_set_coeff_nonzero(n_poly_t A, slong j, ulong c)
{
FLINT_ASSERT(c != 0);
if (j >= A->length)
{
n_poly_fit_length(A, j + 1);
flint_mpn_zero(A->coeffs + A->length, j - A->length);
A->length = j + 1;
}
A->coeffs[j] = c;
}
FLINT_DLL void n_poly_set_coeff(n_poly_t A, slong e, ulong c);
FLINT_DLL void n_poly_mod_set_coeff_ui(n_poly_t A, slong j, ulong c, nmod_t mod);
N_POLY_INLINE
void n_poly_set_nmod_poly(n_poly_t a, const nmod_poly_t b)
{
n_poly_fit_length(a, b->length);
flint_mpn_copyi(a->coeffs, b->coeffs, b->length);
a->length = b->length;
}
N_POLY_INLINE
void nmod_poly_set_n_poly(nmod_poly_t a, const n_poly_t b)
{
nmod_poly_fit_length(a, b->length);
flint_mpn_copyi(a->coeffs, b->coeffs, b->length);
a->length = b->length;
}
N_POLY_INLINE
void n_poly_shift_left(n_poly_t A, const n_poly_t B, slong k)
{
n_poly_fit_length(A, B->length + k);
_nmod_poly_shift_left(A->coeffs, B->coeffs, B->length, k);
A->length = B->length + k;
}
N_POLY_INLINE
void n_poly_shift_right(n_poly_t res, const n_poly_t poly, slong k)
{
if (k >= poly->length)
{
res->length = 0;
}
else
{
const slong len = poly->length - k;
n_poly_fit_length(res, len);
_nmod_poly_shift_right(res->coeffs, poly->coeffs, len, k);
res->length = len;
}
}
N_POLY_INLINE
void n_poly_truncate(n_poly_t poly, slong len)
{
if (poly->length > len)
{
poly->length = len;
_n_poly_normalise(poly);
}
}
N_POLY_INLINE
void _n_poly_mod_scalar_mul_nmod(n_poly_t A, const n_poly_t B, mp_limb_t c,
nmod_t mod)
{
FLINT_ASSERT(B->length <= B->alloc);
n_poly_fit_length(A, B->length);
_nmod_vec_scalar_mul_nmod(A->coeffs, B->coeffs, B->length, c, mod);
A->length = B->length;
}
N_POLY_INLINE
void _n_poly_mod_scalar_mul_nmod_inplace(n_poly_t A, mp_limb_t c, nmod_t mod)
{
_nmod_vec_scalar_mul_nmod(A->coeffs, A->coeffs, A->length, c, mod);
}
FLINT_DLL void n_poly_mod_scalar_mul_ui(n_poly_t A, const n_poly_t B,
mp_limb_t c, nmod_t ctx);
FLINT_DLL mp_limb_t n_poly_mod_eval_step2(n_poly_t Acur, const n_poly_t Ainc,
nmod_t mod);
N_POLY_INLINE
mp_limb_t n_poly_mod_evaluate_nmod(const n_poly_t A, mp_limb_t c, nmod_t mod)
{
return _nmod_poly_evaluate_nmod(A->coeffs, A->length, c, mod);
}
N_POLY_INLINE
void n_poly_mod_neg(n_poly_t A, const n_poly_t B, nmod_t mod)
{
n_poly_fit_length(A, B->length);
_nmod_vec_neg(A->coeffs, B->coeffs, B->length, mod);
A->length = B->length;
}
N_POLY_INLINE
void n_poly_mod_add(n_poly_t A, const n_poly_t B, const n_poly_t C, nmod_t mod)
{
slong Alen = FLINT_MAX(B->length, C->length);
n_poly_fit_length(A, Alen);
_nmod_poly_add(A->coeffs, B->coeffs, B->length, C->coeffs, C->length, mod);
A->length = Alen;
_n_poly_normalise(A);
}
FLINT_DLL void n_poly_mod_add_ui(n_poly_t res, const n_poly_t poly, ulong c, nmod_t ctx);
N_POLY_INLINE
void n_poly_mod_sub(n_poly_t A, const n_poly_t B, const n_poly_t C, nmod_t mod)
{
slong Alen = FLINT_MAX(B->length, C->length);
n_poly_fit_length(A, Alen);
_nmod_poly_sub(A->coeffs, B->coeffs, B->length, C->coeffs, C->length, mod);
A->length = Alen;
_n_poly_normalise(A);
}
N_POLY_INLINE
void n_poly_mod_product_roots_nmod_vec(n_poly_t A, mp_srcptr r, slong n, nmod_t mod)
{
n_poly_fit_length(A, n + 1);
A->length = n + 1;
_nmod_poly_product_roots_nmod_vec(A->coeffs, r, n, mod);
}
FLINT_DLL void n_poly_mod_shift_left_scalar_addmul(n_poly_t A, slong k,
mp_limb_t c, nmod_t mod);
FLINT_DLL void n_poly_mod_addmul_linear(n_poly_t A, const n_poly_t B,
const n_poly_t C, mp_limb_t d1, mp_limb_t d0, nmod_t mod);
FLINT_DLL void n_poly_mod_scalar_addmul_nmod(n_poly_t A, const n_poly_t B,
const n_poly_t C, mp_limb_t d0, nmod_t ctx);
FLINT_DLL mp_limb_t _n_poly_eval_pow(n_poly_t P, n_poly_t alphapow, int nlimbs,
nmod_t ctx);
FLINT_DLL mp_limb_t n_poly_mod_eval_pow(n_poly_t P, n_poly_t alphapow,
nmod_t ctx);
FLINT_DLL void n_poly_mod_eval2_pow(mp_limb_t * vp, mp_limb_t * vm,
const n_poly_t P, n_poly_t alphapow, nmod_t ctx);
FLINT_DLL mp_limb_t n_poly_mod_div_root(n_poly_t Q,
const n_poly_t A, mp_limb_t c, nmod_t ctx);
N_POLY_INLINE
void _n_poly_mod_mul(n_poly_t A, const n_poly_t B, const n_poly_t C, nmod_t ctx)
{
slong Blen = B->length;
slong Clen = C->length;
slong Alen = Blen + Clen - 1;
FLINT_ASSERT(A != B);
FLINT_ASSERT(A != C);
if (Clen < 1 || Blen < 1)
{
A->length = 0;
return;
}
n_poly_fit_length(A, Alen);
A->length = Alen;
if (Blen >= Clen)
_nmod_poly_mul(A->coeffs, B->coeffs, Blen, C->coeffs, Clen, ctx);
else
_nmod_poly_mul(A->coeffs, C->coeffs, Clen, B->coeffs, Blen, ctx);
}
N_POLY_INLINE
void _n_poly_mod_div(n_poly_t Q, const n_poly_t A, const n_poly_t B, nmod_t mod)
{
const slong lenA = A->length, lenB = B->length;
FLINT_ASSERT(lenB > 0);
FLINT_ASSERT(Q != A && Q != B);
if (lenA < lenB)
{
n_poly_zero(Q);
return;
}
n_poly_fit_length(Q, lenA - lenB + 1);
_nmod_poly_div(Q->coeffs, A->coeffs, lenA, B->coeffs, lenB, mod);
Q->length = lenA - lenB + 1;
}
N_POLY_INLINE
void _n_poly_mod_rem(n_poly_t R, const n_poly_t A, const n_poly_t B, nmod_t mod)
{
const slong lenA = A->length, lenB = B->length;
FLINT_ASSERT(R != A && R != B);
FLINT_ASSERT(lenB > 0);
if (lenA < lenB)
{
n_poly_set(R, A);
return;
}
n_poly_fit_length(R, lenB - 1);
_nmod_poly_rem(R->coeffs, A->coeffs, lenA, B->coeffs, lenB, mod);
R->length = lenB - 1;
_n_poly_normalise(R);
}
N_POLY_INLINE
void _n_poly_mod_divrem(n_poly_t Q, n_poly_t R, const n_poly_t A,
const n_poly_t B, nmod_t mod)
{
const slong lenA = A->length, lenB = B->length;
FLINT_ASSERT(lenB > 0);
FLINT_ASSERT(Q != A && Q != B);
FLINT_ASSERT(R != A && R != B);
if (lenA < lenB)
{
n_poly_set(R, A);
n_poly_zero(Q);
return;
}
n_poly_fit_length(Q, lenA - lenB + 1);
n_poly_fit_length(R, lenB - 1);
_nmod_poly_divrem(Q->coeffs, R->coeffs, A->coeffs, lenA, B->coeffs, lenB, mod);
Q->length = lenA - lenB + 1;
R->length = lenB - 1;
_n_poly_normalise(R);
}
FLINT_DLL ulong n_poly_mod_remove(n_poly_t f, const n_poly_t p, nmod_t ctx);
FLINT_DLL void n_poly_mod_pow(n_poly_t res, const n_poly_t poly, ulong e,
nmod_t ctx);
FLINT_DLL void n_poly_mod_mul(n_poly_t A, const n_poly_t B, const n_poly_t C,
nmod_t mod);
FLINT_DLL void n_poly_mod_mullow(n_poly_t A, const n_poly_t B,
const n_poly_t C, slong n, nmod_t mod);
FLINT_DLL void n_poly_mod_div(n_poly_t Q, const n_poly_t A, const n_poly_t B,
nmod_t mod);
FLINT_DLL void n_poly_mod_rem(n_poly_t R, const n_poly_t A, const n_poly_t B,
nmod_t mod);
FLINT_DLL void n_poly_mod_divrem(n_poly_t Q, n_poly_t R, const n_poly_t A,
const n_poly_t B, nmod_t mod);
FLINT_DLL void n_poly_mod_mulmod(n_poly_t res, const n_poly_t poly1,
const n_poly_t poly2, const n_poly_t f, nmod_t mod);
FLINT_DLL int n_poly_mod_invmod(n_poly_t A, const n_poly_t B, const n_poly_t P,
nmod_t mod);
FLINT_DLL void n_poly_mod_gcd(n_poly_t G, const n_poly_t A, const n_poly_t B,
nmod_t mod);
FLINT_DLL void n_poly_mod_xgcd(n_poly_t G, n_poly_t S, n_poly_t T,
const n_poly_t A, const n_poly_t B, nmod_t mod);
FLINT_DLL void n_poly_mod_inv_series(n_poly_t Qinv, const n_poly_t Q, slong n,
nmod_t mod);
FLINT_DLL void n_poly_mod_div_series(n_poly_t Q, const n_poly_t A,
const n_poly_t B, slong order, nmod_t ctx);
FLINT_DLL void n_poly_reverse(n_poly_t output, const n_poly_t input, slong m);
FLINT_DLL void n_poly_mod_mulmod_preinv(n_poly_t A, const n_poly_t B,
const n_poly_t C, const n_poly_t M, const n_poly_t Minv, nmod_t ctx);
/*****************************************************************************/
N_POLY_INLINE
nmod_t fq_nmod_ctx_mod(const fq_nmod_ctx_t ctx)
{
return ctx->modulus->mod;
}
N_POLY_INLINE
int _n_fq_is_zero(const mp_limb_t * a, slong d)
{
do {
if (a[--d] != 0)
return 0;
} while (d > 0);
return 1;
}
N_POLY_INLINE
void _n_fq_zero(mp_limb_t * a, slong d)
{
slong i;
for (i = 0; i < d; i++)
a[i] = 0;
}
N_POLY_INLINE
int _n_fq_is_one(const mp_limb_t * a, slong d)
{
slong i;
if (a[0] != 1)
return 0;
for (i = 1; i < d; i++)
if (a[i] != 0)
return 0;
return 1;
}
N_POLY_INLINE
int _n_fq_is_ui(const mp_limb_t * a, slong d)
{
slong i;
for (i = 1; i < d; i++)
if (a[i] != 0)
return 0;
return 1;
}
N_POLY_INLINE
int n_fq_is_one(const mp_limb_t * a, const fq_nmod_ctx_t ctx)
{
return _n_fq_is_one(a, fq_nmod_ctx_degree(ctx));
}
N_POLY_INLINE
void _n_fq_one(mp_limb_t * a, slong d)
{
slong i;
a[0] = 1;
for (i = 1; i < d; i++)
a[i] = 0;
}
N_POLY_INLINE
void _n_fq_set_nmod(mp_limb_t * a, mp_limb_t b, slong d)
{
slong i;
a[0] = b;
for (i = 1; i < d; i++)
a[i] = 0;
}
FLINT_DLL void n_fq_gen(
mp_limb_t * a,
const fq_nmod_ctx_t ctx);
N_POLY_INLINE
void _n_fq_set(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
slong d)
{
slong i = 0;
do {
a[i] = b[i];
i++;
} while (i < d);
}
N_POLY_INLINE
void _n_fq_swap(
mp_limb_t * a, /* length d */
mp_limb_t * b, /* length d */
slong d)
{
slong i = 0;
do {
MP_LIMB_SWAP(a[i], b[i]);
i++;
} while (i < d);
}
N_POLY_INLINE
int _n_fq_equal(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
slong d)
{
slong i = 0;
do {
if (a[i] != b[i])
return 0;
} while (++i < d);
return 1;
}
FLINT_DLL int n_fq_equal_fq_nmod(
const mp_limb_t * a,
const fq_nmod_t b,
const fq_nmod_ctx_t ctx);
FLINT_DLL int n_fq_is_canonical(
const mp_limb_t * a,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_randtest_not_zero(
mp_limb_t * a,
flint_rand_t state,
const fq_nmod_ctx_t ctx);
FLINT_DLL char * n_fq_get_str_pretty(
const mp_limb_t * a,
const fq_nmod_ctx_t ctx);
FLINT_DLL int n_fq_fprint_pretty(
FILE * file,
const mp_limb_t * a,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_print_pretty(
const mp_limb_t * a,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_get_fq_nmod(
fq_nmod_t a,
const mp_limb_t * b,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_set_fq_nmod(
mp_limb_t * a,
const fq_nmod_t b,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_get_n_poly(
n_poly_t a,
const mp_limb_t * b,
const fq_nmod_ctx_t ctx);
FLINT_DLL void _n_fq_set_n_poly(
mp_limb_t * a,
const mp_limb_t * bcoeffs, slong blen,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_add_si(
mp_limb_t * a,
const mp_limb_t * b,
slong c,
const fq_nmod_ctx_t ctx);
N_POLY_INLINE
void n_fq_add(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
const fq_nmod_ctx_t ctx)
{
slong d = fq_nmod_ctx_degree(ctx);
FLINT_ASSERT(d > 0);
_nmod_vec_add(a, b, c, d, ctx->modulus->mod);
}
void n_fq_add_fq_nmod(
mp_limb_t * a,
const mp_limb_t * b,
const fq_nmod_t c,
const fq_nmod_ctx_t ctx);
void n_fq_sub_fq_nmod(
mp_limb_t * a,
const mp_limb_t * b,
const fq_nmod_t c,
const fq_nmod_ctx_t ctx);
N_POLY_INLINE
void n_fq_sub(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
const fq_nmod_ctx_t ctx)
{
slong d = fq_nmod_ctx_degree(ctx);
FLINT_ASSERT(d > 0);
_nmod_vec_sub(a, b, c, d, ctx->modulus->mod);
}
N_POLY_INLINE
void _n_fq_add(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d,
nmod_t mod)
{
FLINT_ASSERT(d > 0);
_nmod_vec_add(a, b, c, d, mod);
}
N_POLY_INLINE
void _n_fq_sub(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d,
nmod_t mod)
{
FLINT_ASSERT(d > 0);
_nmod_vec_sub(a, b, c, d, mod);
}
N_POLY_INLINE
void _n_fq_neg(
mp_limb_t * a,
const mp_limb_t * b,
slong d,
nmod_t mod)
{
FLINT_ASSERT(d > 0);
_nmod_vec_neg(a, b, d, mod);
}
N_POLY_INLINE
void _n_fq_mul_ui(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
mp_limb_t c,
slong d,
nmod_t mod)
{
if (c >= mod.n)
NMOD_RED(c, c, mod);
_nmod_vec_scalar_mul_nmod(a, b, d, c, mod);
}
FLINT_DLL void _n_fq_madd2(
mp_limb_t * a, /* length 2d-1 */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
const fq_nmod_ctx_t ctx,
mp_limb_t * t); /* length 2d */
FLINT_DLL void _n_fq_mul2(
mp_limb_t * t, /* length 2d-1 */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
const fq_nmod_ctx_t ctx);
#define N_FQ_REDUCE_ITCH 2
FLINT_DLL void _n_fq_reduce(
mp_limb_t * a,
mp_limb_t * b, slong blen,
const fq_nmod_ctx_t ctx,
mp_limb_t * t);
/* same itch as reduce */
N_POLY_INLINE
void _n_fq_reduce2(
mp_limb_t * a, /* length d */
mp_limb_t * b, /* length 2d-1 */
const fq_nmod_ctx_t ctx,
mp_limb_t * t) /* length 2d */
{
slong blen = 2*fq_nmod_ctx_degree(ctx) - 1;
FLINT_ASSERT(a != b);
while (blen > 0 && b[blen - 1] == 0)
blen--;
_n_fq_reduce(a, b, blen, ctx, t);
}
#define N_FQ_MUL_ITCH 4
N_POLY_INLINE
void _n_fq_mul(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
const fq_nmod_ctx_t ctx,
mp_limb_t * t) /* length 4d */
{
slong d = fq_nmod_ctx_degree(ctx);
_n_fq_mul2(t, b, c, ctx);
_n_fq_reduce2(a, t, ctx, t + 2*d);
}
N_POLY_INLINE
void _n_fq_addmul(
mp_limb_t * a, /* length d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
const mp_limb_t * e, /* length d */
const fq_nmod_ctx_t ctx,
mp_limb_t * t) /* length 4d */
{
slong d = fq_nmod_ctx_degree(ctx);
_n_fq_mul2(t, c, e, ctx);
_nmod_vec_add(t, t, b, d, ctx->mod);
_n_fq_reduce2(a, t, ctx, t + 2*d);
}
#define N_FQ_LAZY_ITCH 6
FLINT_DLL int _n_fq_dot_lazy_size(slong len, const fq_nmod_ctx_t ctx);
FLINT_DLL void _n_fq_reduce2_lazy1(
mp_limb_t * a, /* length 6d, 2d used */
slong d,
nmod_t ctx);
FLINT_DLL void _n_fq_madd2_lazy1(
mp_limb_t * a, /* length 6d, 2d used */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d);
FLINT_DLL void _n_fq_mul2_lazy1(
mp_limb_t * a, /* length 6d, 2d used */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d);
FLINT_DLL void _n_fq_reduce2_lazy2(
mp_limb_t * a, /* length 6d, 4d used */
slong d,
nmod_t ctx);
FLINT_DLL void _n_fq_madd2_lazy2(
mp_limb_t * a, /* length 6d, 4d used */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d);
FLINT_DLL void _n_fq_mul2_lazy2(
mp_limb_t * a, /* length 6d, 4d used */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d);
FLINT_DLL void _n_fq_reduce2_lazy3(
mp_limb_t * a, /* length 6d */
slong d,
nmod_t ctx);
FLINT_DLL void _n_fq_madd2_lazy3(
mp_limb_t * a, /* length 6d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d);
FLINT_DLL void _n_fq_mul2_lazy3(
mp_limb_t * a, /* length 6d */
const mp_limb_t * b, /* length d */
const mp_limb_t * c, /* length d */
slong d);
#define N_FQ_INV_ITCH 1
FLINT_DLL void _n_fq_inv(
mp_limb_t * a,
const mp_limb_t * b,
const fq_nmod_ctx_t ctx,
mp_limb_t * t);
#define N_FQ_MUL_INV_ITCH FLINT_MAX(N_FQ_MUL_ITCH, N_FQ_INV_ITCH)
FLINT_DLL void _n_fq_pow_ui(
mp_limb_t * a,
const mp_limb_t * b,
ulong e,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_pow_fmpz(
mp_limb_t * a,
const mp_limb_t * b,
const fmpz_t e,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_mul(
mp_limb_t * a,
const mp_limb_t * b,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_mul_fq_nmod(
mp_limb_t * a,
const mp_limb_t * b,
const fq_nmod_t c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_addmul(
mp_limb_t * a,
const mp_limb_t * b,
const mp_limb_t * c,
const mp_limb_t * d,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_inv(
mp_limb_t * a,
const mp_limb_t * b,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_pow_ui(
mp_limb_t * a,
const mp_limb_t * b,
ulong e,
const fq_nmod_ctx_t ctx);
/*****************************************************************************/
#define N_FQ_POLY_DIVREM_DIVCONQUER_CUTOFF 20
#define n_fq_poly_init n_poly_init
#define n_fq_poly_clear n_poly_clear
#define n_fq_poly_degree n_poly_degree
#define n_fq_poly_zero n_poly_zero
#define n_fq_poly_is_zero n_poly_is_zero
#define n_fq_poly_swap n_poly_swap
#define n_fq_bpoly_init n_bpoly_init
#define n_fq_bpoly_clear n_bpoly_clear
#define n_fq_bpoly_zero n_bpoly_zero
#define n_fq_bpoly_fit_length n_bpoly_fit_length
#define n_fq_bpoly_normalise n_bpoly_normalise
#define n_fq_polyun_init n_polyun_init
#define n_fq_polyun_clear n_polyun_clear
#define n_fq_bpoly_degree1 n_bpoly_degree1
#define n_fq_bpoly_degree0 n_bpoly_degree0
FLINT_DLL void n_fq_poly_init2(n_fq_poly_t A, slong alloc, const fq_nmod_ctx_t ctx);
FLINT_DLL void _n_fq_poly_one(n_fq_poly_t A, slong d);
N_POLY_INLINE
void n_fq_poly_one(n_fq_poly_t A, const fq_nmod_ctx_t ctx)
{
_n_fq_poly_one(A, fq_nmod_ctx_degree(ctx));
}
FLINT_DLL int n_fq_poly_is_one(n_fq_poly_t A, const fq_nmod_ctx_t ctx);
FLINT_DLL int n_fq_poly_is_canonical(
const n_fq_poly_t a,
const fq_nmod_ctx_t ctx);
N_POLY_INLINE
void _n_fq_poly_normalise(n_fq_poly_t A, slong d)
{
while (A->length > 0 && _n_fq_is_zero(A->coeffs + d*(A->length - 1), d))
A->length--;
}
FLINT_DLL void n_fq_poly_print_pretty(
const n_fq_poly_t A,
const char * x,
const fq_nmod_ctx_t ctx);
FLINT_DLL int n_fq_poly_equal(
const n_fq_poly_t A,
const n_fq_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_set(
n_fq_poly_t A,
const n_fq_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_randtest(
n_fq_poly_t A,
flint_rand_t state,
slong len,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_make_monic(
n_fq_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_get_coeff_n_fq(
mp_limb_t * c,
const n_poly_t A,
slong e,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_get_coeff_fq_nmod(
fq_nmod_t c,
const n_poly_t A,
slong e,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_set_coeff_n_fq(
n_poly_t A,
slong j,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_set_coeff_fq_nmod(
n_poly_t A,
slong j,
const fq_nmod_t c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_scalar_mul_n_fq(
n_poly_t A,
const n_poly_t B,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_scalar_mul_ui(
n_poly_t A,
const n_poly_t B,
ulong c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_scalar_addmul_n_fq(
n_fq_poly_t A,
const n_fq_poly_t B,
const n_fq_poly_t C,
const mp_limb_t * d,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_shift_left_scalar_submul(
n_poly_t A,
slong k,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_evaluate_fq_nmod(
fq_nmod_t e,
const n_poly_t A,
const fq_nmod_t c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_evaluate_n_fq(
mp_limb_t * e,
const n_poly_t A,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_get_fq_nmod_poly(
fq_nmod_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_set_fq_nmod_poly(
n_poly_t A,
const fq_nmod_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_set_n_fq(
n_poly_t A,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_set_fq_nmod(
n_poly_t A,
const fq_nmod_t c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_shift_right(
n_poly_t A,
const n_poly_t B,
slong n,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_shift_left(
n_poly_t A,
const n_poly_t B,
slong n,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_truncate(
n_poly_t A,
slong len,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_add(
n_poly_t A,
const n_poly_t B,
const n_poly_t C,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_sub(
n_poly_t A,
const n_poly_t B,
const n_poly_t C,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_neg(
n_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_add_si(
n_poly_t A,
const n_poly_t B,
slong c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void _n_fq_poly_mul_(
mp_limb_t * A,
const mp_limb_t * B, slong Blen,
const mp_limb_t * C, slong Clen,
const fq_nmod_ctx_t ctx,
n_poly_stack_t St);
FLINT_DLL void n_fq_poly_mul_(
n_poly_t A,
const n_poly_t B,
const n_poly_t C,
const fq_nmod_ctx_t ctx,
n_poly_stack_t St);
FLINT_DLL void n_fq_poly_mul(
n_poly_t A,
const n_poly_t B,
const n_poly_t C,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_pow(
n_poly_t A,
const n_poly_t B,
ulong e,
const fq_nmod_ctx_t ctx);
FLINT_DLL ulong n_fq_poly_remove(
n_poly_t f,
const n_poly_t g,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_divrem_divconquer_(
n_poly_t Q,
n_poly_t R,
const n_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx,
n_poly_stack_t St);
N_POLY_INLINE
void n_fq_poly_divrem_(
n_poly_t Q,
n_poly_t R,
const n_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx,
n_poly_stack_t St)
{
n_fq_poly_divrem_divconquer_(Q, R, A, B, ctx, St);
}
FLINT_DLL void n_fq_poly_divrem(
n_poly_t Q,
n_poly_t R,
const n_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_gcd(
n_poly_t G,
const n_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_gcd_(
n_poly_t G,
const n_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx,
n_poly_stack_t St);
FLINT_DLL void n_fq_poly_xgcd(
n_poly_t G,
n_poly_t S,
n_poly_t T,
const n_poly_t B,
const n_poly_t C,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_mulmod(
n_poly_t A,
const n_poly_t B,
const n_poly_t C,
const n_poly_t M,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_rem(
n_poly_t R,
const n_poly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_mullow(
n_poly_t A,
const n_poly_t B,
const n_poly_t C,
slong order,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_inv_series(
n_poly_t A,
const n_poly_t B,
slong order,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_poly_eval_pow(
mp_limb_t * ev,
const n_fq_poly_t A,
n_fq_poly_t alphapow,
const fq_nmod_ctx_t ctx);
/*****************************************************************************/
N_POLY_INLINE
void n_bpoly_init(n_bpoly_t A)
{
A->coeffs = NULL;
A->alloc = 0;
A->length = 0;
}
FLINT_DLL void n_bpoly_clear(n_bpoly_t A);
N_POLY_INLINE
void n_bpoly_swap(n_bpoly_t A, n_bpoly_t B)
{
n_bpoly_struct t = *A;
*A = *B;
*B = t;
}
FLINT_DLL void n_bpoly_print_pretty(const n_bpoly_t A,
const char * xvar, const char * yvar);
N_POLY_INLINE
void n_bpoly_normalise(n_bpoly_t A)
{
while (A->length > 0 && n_poly_is_zero(A->coeffs + A->length - 1))
A->length--;
}
FLINT_DLL void n_bpoly_realloc(n_bpoly_t A, slong len);
N_POLY_INLINE
void n_bpoly_fit_length(n_bpoly_t A, slong len)
{
if (len > A->alloc)
n_bpoly_realloc(A, len);
}
N_POLY_INLINE
void n_bpoly_zero(n_bpoly_t A)
{
A->length = 0;
}
N_POLY_INLINE
int n_bpoly_is_zero(const n_bpoly_t A)
{
return A->length == 0;
}
FLINT_DLL void _n_bpoly_set(n_bpoly_t A, const n_bpoly_t B);
N_POLY_INLINE
void n_bpoly_set(n_bpoly_t A, const n_bpoly_t B)
{
if (A != B)
_n_bpoly_set(A, B);
}
FLINT_DLL void n_bpoly_one(n_bpoly_t A);
FLINT_DLL int n_bpoly_equal(const n_bpoly_t A, const n_bpoly_t B);
FLINT_DLL void n_bpoly_set_coeff(n_bpoly_t A, slong e0, slong e1, mp_limb_t c);
FLINT_DLL void n_bpoly_set_coeff_nonzero(n_bpoly_t A, slong e0, slong e1,
mp_limb_t c);
FLINT_DLL void n_bpoly_mod_derivative_gen0(n_bpoly_t A, const n_bpoly_t B,
nmod_t ctx);
N_POLY_INLINE
mp_limb_t n_bpoly_get_coeff(const n_bpoly_t A, slong e0, slong e1)
{
if (e0 >= A->length)
return 0;
else
return n_poly_get_coeff(A->coeffs + e0, e1);
}
N_POLY_INLINE
slong n_bpoly_degree0(const n_bpoly_t A)
{
return A->length - 1;
}
FLINT_DLL slong n_bpoly_degree1(const n_bpoly_t A);
FLINT_DLL void n_bpoly_set_poly_gen1(n_bpoly_t A, const n_poly_t B);
FLINT_DLL void n_bpoly_set_poly_gen0(n_bpoly_t A, const n_poly_t B);
/*****************************************************************************/
FLINT_DLL int n_bpoly_mod_is_canonical(const n_bpoly_t A, nmod_t mod);
N_POLY_INLINE
ulong n_bpoly_bidegree(const n_bpoly_t A)
{
ulong x, y;
FLINT_ASSERT(A->length > 0);
x = A->length - 1;
y = A->coeffs[x].length - 1;
return (x << (FLINT_BITS/2)) + y;
}
FLINT_DLL void n_bpoly_scalar_mul_nmod(n_bpoly_t A, mp_limb_t c, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_content_last(n_poly_t g, const n_bpoly_t A, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_divexact_last(n_bpoly_t A, const n_poly_t b, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_mul_last(n_bpoly_t A, const n_poly_t b, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_taylor_shift_gen1(n_bpoly_t A, const n_bpoly_t B,
mp_limb_t c, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_taylor_shift_gen0(n_bpoly_t A, mp_limb_t c,
nmod_t ctx);
FLINT_DLL void n_bpoly_mod_add(n_bpoly_t A, const n_bpoly_t B,
const n_bpoly_t C, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_sub(n_bpoly_t A, const n_bpoly_t B,
const n_bpoly_t C, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_make_primitive(n_poly_t g, n_bpoly_t A, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_mul(n_bpoly_t A, const n_bpoly_t B,
const n_bpoly_t C, nmod_t ctx);
FLINT_DLL int n_bpoly_mod_divides(n_bpoly_t Q, const n_bpoly_t A,
const n_bpoly_t B, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_mul_series(n_bpoly_t A, const n_bpoly_t B,
const n_bpoly_t C, slong order, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_divrem_series(n_bpoly_t Q, n_bpoly_t R,
const n_bpoly_t A, const n_bpoly_t B, slong order, nmod_t ctx);
FLINT_DLL void n_bpoly_mod_interp_reduce_2sm_poly(n_poly_t Ap, n_poly_t Am,
const n_bpoly_t A, n_poly_t alphapow, nmod_t mod);
FLINT_DLL void n_bpoly_mod_interp_lift_2sm_poly(slong * deg1, n_bpoly_t T,
const n_poly_t A, const n_poly_t B, mp_limb_t alpha, nmod_t mod);
FLINT_DLL int n_bpoly_mod_interp_crt_2sm_poly(slong * deg1, n_bpoly_t F,
n_bpoly_t T, n_poly_t A, n_poly_t B, const n_poly_t modulus,
n_poly_t alphapow, nmod_t mod);
FLINT_DLL int n_bpoly_mod_gcd_brown_smprime(n_bpoly_t G, n_bpoly_t Abar,
n_bpoly_t Bbar, n_bpoly_t A, n_bpoly_t B,
nmod_t ctx, n_poly_bpoly_stack_t Sp);
FLINT_DLL int n_polyu1n_mod_gcd_brown_smprime(n_polyun_t G, n_polyun_t Abar,
n_polyun_t Bbar,n_polyun_t A, n_polyun_t B,
nmod_t ctx, n_poly_polyun_stack_t St);
/*****************************************************************************/
FLINT_DLL int n_fq_bpoly_equal(
const n_bpoly_t A,
const n_bpoly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_get_coeff_n_fq(
mp_limb_t * c,
const n_bpoly_t A,
slong e0,
slong e1,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_set_coeff_n_fq(
n_fq_bpoly_t A,
slong e0,
slong e1,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_get_coeff_fq_nmod(
fq_nmod_t c,
const n_bpoly_t A,
slong e0,
slong e1,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_set_fq_nmod_poly_gen0(
n_bpoly_t A,
const fq_nmod_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_set_n_fq_poly_gen0(
n_bpoly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_set_n_fq_poly_gen1(
n_bpoly_t A,
const n_poly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_derivative_gen0(
n_bpoly_t A,
const n_bpoly_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_scalar_mul_n_fq(
n_fq_bpoly_t A,
const mp_limb_t * c,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_taylor_shift_gen1_fq_nmod(
n_bpoly_t A,
const n_bpoly_t B,
const fq_nmod_t c_,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_taylor_shift_gen0_fq_nmod(
n_bpoly_t A,
const fq_nmod_t alpha,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_taylor_shift_gen0_n_fq(
n_fq_bpoly_t A,
const mp_limb_t * alpha,
const fq_nmod_ctx_t ctx);
FLINT_DLL int n_fq_bpoly_gcd_brown_smprime(
n_fq_bpoly_t G,
n_fq_bpoly_t Abar,
n_fq_bpoly_t Bbar,
n_fq_bpoly_t A,
n_fq_bpoly_t B,
const fq_nmod_ctx_t ctx,
n_poly_bpoly_stack_t Sp);
FLINT_DLL void n_fq_bpoly_print_pretty(
const n_fq_bpoly_t A,
const char * xvar,
const char * yvar,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_one(n_fq_bpoly_t A, const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_bpoly_set(n_fq_bpoly_t A, const n_fq_bpoly_t B, const fq_nmod_ctx_t ctx);
FLINT_DLL int n_fq_bpoly_is_canonical(const n_fq_bpoly_t A, const fq_nmod_ctx_t ctx);
/*****************************************************************************/
N_POLY_INLINE
void n_tpoly_init(n_tpoly_t A)
{
A->coeffs = NULL;
A->alloc = 0;
A->length = 0;
}
N_POLY_INLINE
void n_tpoly_swap(n_tpoly_t A, n_tpoly_t B)
{
n_tpoly_struct t = *A;
*A = *B;
*B = t;
}
FLINT_DLL void n_tpoly_fit_length(n_tpoly_t A, slong len);
FLINT_DLL void n_tpoly_clear(n_tpoly_t A);
/*****************************************************************************/
N_POLY_INLINE
void n_polyu_init(n_polyu_t A)
{
A->coeffs = NULL;
A->exps = NULL;
A->length = 0;
A->alloc = 0;
}
FLINT_DLL void n_polyu_clear(n_polyu_t A);
FLINT_DLL void n_polyu_realloc(n_polyu_t A, slong len);
N_POLY_INLINE
void n_polyu_fit_length(n_polyu_t A, slong len)
{
FLINT_ASSERT(A->alloc >= 0);
if (len > A->alloc)
n_polyu_realloc(A, len);
}
N_POLY_INLINE
void n_polyu_swap(n_polyu_t A, n_polyu_t B)
{
n_polyu_struct T = *B;
*B = *A;
*A = T;
}
FLINT_DLL void n_polyu3_print_pretty(const n_polyu_t A, const char * gen0,
const char * gen1, const char * var2);
FLINT_DLL void n_polyu3_degrees(slong * deg0, slong * deg1, slong * deg2,
const n_polyu_t A);
/*****************************************************************************/
FLINT_DLL void nmod_pow_cache_start(mp_limb_t b, n_poly_t pos_direct, n_poly_t pos_bin,
n_poly_t neg_direct);
FLINT_DLL mp_limb_t nmod_pow_cache_mulpow_ui(mp_limb_t a, ulong e, n_poly_t pos_direct,
n_poly_t pos_bin, n_poly_t neg_direct, nmod_t ctx);
FLINT_DLL mp_limb_t nmod_pow_cache_mulpow_neg_ui(mp_limb_t a, ulong e, n_poly_t pos_direct,
n_poly_t pos_bin, n_poly_t neg_direct, nmod_t ctx);
FLINT_DLL mp_limb_t nmod_pow_cache_mulpow_fmpz(mp_limb_t a, const fmpz_t e, n_poly_t pos_direct,
n_poly_t pos_bin, n_poly_t neg_direct, nmod_t ctx);
FLINT_DLL void n_fq_pow_cache_start_n_fq(
const mp_limb_t * b,
n_poly_t pos_direct,
n_poly_t pos_bin,
n_poly_t neg_direct,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_pow_cache_start_fq_nmod(
const fq_nmod_t b,
n_poly_t pos_direct,
n_poly_t pos_bin,
n_poly_t neg_direct,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_pow_cache_mulpow_ui(
mp_limb_t * r,
const mp_limb_t * a,
ulong e,
n_poly_t pos_direct,
n_poly_t pos_bin,
n_poly_t neg_direct,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_pow_cache_mulpow_neg_ui(
mp_limb_t * r,
const mp_limb_t * a,
ulong e,
n_poly_t pos_direct,
n_poly_t pos_bin,
n_poly_t neg_direct,
const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_pow_cache_mulpow_fmpz(
mp_limb_t * r,
const mp_limb_t * a,
const fmpz_t e,
n_poly_t pos_direct,
n_poly_t pos_bin,
n_poly_t neg_direct,
const fq_nmod_ctx_t ctx);
/*****************************************************************************/
typedef struct {
mp_limb_t * M;
mp_limb_t * T;
mp_limb_t * Q;
mp_limb_t * array;
slong alloc;
slong d;
slong radix;
mp_limb_t w;
} nmod_eval_interp_struct;
typedef nmod_eval_interp_struct nmod_eval_interp_t[1];
FLINT_DLL void nmod_eval_interp_init(nmod_eval_interp_t E);
FLINT_DLL void nmod_eval_interp_clear(nmod_eval_interp_t E);
FLINT_DLL int nmod_eval_interp_set_degree_modulus(
nmod_eval_interp_t E,
slong deg,
nmod_t ctx);
N_POLY_INLINE slong nmod_eval_interp_eval_length(nmod_eval_interp_t E)
{
return 1 + E->radix*E->d;
}
FLINT_DLL void nmod_eval_interp_to_coeffs_poly(
n_poly_t a,
const n_poly_t v,
nmod_eval_interp_t E,
nmod_t ctx);
FLINT_DLL void nmod_eval_interp_from_coeffs_poly(
n_poly_t v,
const n_poly_t a,
nmod_eval_interp_t E,
nmod_t ctx);
FLINT_DLL void nmod_eval_interp_to_coeffs_n_fq_poly(
n_fq_poly_t a,
const n_fq_poly_t v,
nmod_eval_interp_t E,
const fq_nmod_ctx_t ctx);
FLINT_DLL void nmod_eval_interp_from_coeffs_n_fq_poly(
n_fq_poly_t v,
const n_fq_poly_t a,
nmod_eval_interp_t E,
const fq_nmod_ctx_t ctx);
N_POLY_INLINE void nmod_evals_zero(n_poly_t a)
{
a->length = 0;
}
FLINT_DLL void nmod_evals_add_inplace(n_poly_t a, n_poly_t b, slong len,
nmod_t ctx);
FLINT_DLL void nmod_evals_mul(n_poly_t a, n_poly_t b, n_poly_t c, slong len,
nmod_t ctx);
FLINT_DLL void nmod_evals_addmul(n_poly_t a, n_poly_t b, n_poly_t c, slong len,
nmod_t ctx);
FLINT_DLL void nmod_evals_fmma(n_poly_t a, n_poly_t b, n_poly_t c,
n_poly_t d, n_poly_t e, slong len, nmod_t ctx);
N_POLY_INLINE void n_fq_evals_zero(n_fq_poly_t a)
{
a->length = 0;
}
FLINT_DLL void n_fq_evals_add_inplace(n_fq_poly_t a, n_fq_poly_t b,
slong len, const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_evals_mul(n_fq_poly_t a, n_fq_poly_t b, n_fq_poly_t c,
slong len, const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_evals_addmul(n_fq_poly_t a, n_fq_poly_t b, n_fq_poly_t c,
slong len, const fq_nmod_ctx_t ctx);
FLINT_DLL void n_fq_evals_fmma(n_fq_poly_t a, n_fq_poly_t b, n_fq_poly_t c,
n_fq_poly_t f, n_fq_poly_t e, slong len, const fq_nmod_ctx_t ctx);
/*****************************************************************************/
N_POLY_INLINE
void n_polyun_init(n_polyun_t A)
{
A->coeffs = NULL;
A->exps = NULL;
A->length = 0;
A->alloc = 0;
}
FLINT_DLL int n_polyun_is_canonical(const n_polyun_t A);
FLINT_DLL void n_polyun_clear(n_polyun_t A);
FLINT_DLL void n_polyun_realloc(n_polyun_t A, slong len);
N_POLY_INLINE
void n_polyun_fit_length(n_polyun_t A, slong len)
{
if (len > A->alloc)
n_polyun_realloc(A, len);
}
FLINT_DLL int n_polyun_mod_is_canonical(const n_polyun_t A, nmod_t mod);
N_POLY_INLINE
void n_polyun_swap(n_polyun_t A, n_polyun_t B)
{
n_polyun_struct t = *B;
*B = *A;
*A = t;
}
FLINT_DLL void n_polyun_set(n_polyun_t A, const n_polyun_t B);
FLINT_DLL void n_polyu1n_print_pretty(const n_polyun_t A,
const char * var0, const char * varlast);
FLINT_DLL void n_polyu2n_print_pretty(const n_polyun_t A, const char * gen0,
const char * gen1, const char * varlast);
FLINT_DLL void n_polyu3n_print_pretty(const n_polyun_t A, const char * gen0,
const char * gen1, const char * var2, const char * varlast);
FLINT_DLL void n_fq_polyun_set(n_fq_polyun_t A, const n_fq_polyun_t B,
const fq_nmod_ctx_t ctx);
FLINT_DLL int n_polyun_equal(const n_polyun_t A, const n_polyun_t B);
N_POLY_INLINE
void n_polyun_one(n_polyun_t A)
{
n_polyun_fit_length(A, 1);
A->length = 1;
A->exps[0] = 0;
n_poly_one(A->coeffs + 0);
}
N_POLY_INLINE
ulong n_polyu1n_bidegree(n_polyun_t A)
{
ulong x = A->exps[0];
ulong y = A->coeffs[0].length - 1;
return (x << (FLINT_BITS/2)) + y;
}
/*****************************************************************************/
FLINT_DLL void n_fq_poly_product_roots_n_fq(n_poly_t M, const mp_limb_t * H,
slong length, const fq_nmod_ctx_t ctx, n_poly_stack_t St);
FLINT_DLL slong n_polyun_product_roots(n_polyun_t M, const n_polyun_t H,
nmod_t ctx);
FLINT_DLL slong n_fq_polyun_product_roots(n_fq_polyun_t M,
const n_fq_polyun_t H, const fq_nmod_ctx_t ctx, n_poly_stack_t St);
FLINT_DLL mp_limb_t _nmod_zip_eval_step(mp_limb_t * cur,
const mp_limb_t * inc, const mp_limb_t * coeffs,
slong length, nmod_t ctx);
FLINT_DLL void _n_fq_zip_eval_step(mp_limb_t * res, mp_limb_t * cur,
const mp_limb_t * inc, const mp_limb_t * coeffs,
slong length, const fq_nmod_ctx_t ctx);
FLINT_DLL void _n_fqp_zip_eval_step(mp_limb_t * res, mp_limb_t * cur,
const mp_limb_t * inc, const mp_limb_t * coeffs,
slong length, slong d, nmod_t mod);
FLINT_DLL int _nmod_zip_vand_solve(mp_limb_t * coeffs,
const mp_limb_t * monomials, slong mlength,
const mp_limb_t * evals, slong elength,
const mp_limb_t * master, mp_limb_t * scratch, nmod_t ctx);
FLINT_DLL int _n_fq_zip_vand_solve(mp_limb_t * coeffs,
const mp_limb_t * monomials, slong mlength,
const mp_limb_t * evals, slong elength,
const mp_limb_t * master, mp_limb_t * scratch,
const fq_nmod_ctx_t ctx);
FLINT_DLL int _n_fqp_zip_vand_solve(mp_limb_t * coeffs,
const mp_limb_t * monomials, slong mlength,
const mp_limb_t * evals, slong elength,
const mp_limb_t * master, mp_limb_t * scratch,
const fq_nmod_ctx_t ctx);
/*****************************************************************************/
FLINT_DLL void n_poly_stack_init(n_poly_stack_t S);
FLINT_DLL void n_poly_stack_clear(n_poly_stack_t S);
FLINT_DLL n_poly_struct ** n_poly_stack_fit_request(n_poly_stack_t S, slong k);
N_POLY_INLINE
mp_limb_t * n_poly_stack_vec_init(n_poly_stack_t S, slong len)
{
n_poly_struct * poly_top;
poly_top = n_poly_stack_fit_request(S, 1)[0];
S->top += 1;
n_poly_fit_length(poly_top, len);
return poly_top->coeffs;
}
N_POLY_INLINE
void n_poly_stack_vec_clear(n_poly_stack_t S)
{
FLINT_ASSERT(S->top >= 1);
S->top -= 1;
}
N_POLY_INLINE
n_poly_struct ** n_poly_stack_request(n_poly_stack_t S, slong k)
{
n_poly_struct ** poly_top;
poly_top = n_poly_stack_fit_request(S, k);
S->top += k;
return poly_top;
}
N_POLY_INLINE
n_poly_struct * n_poly_stack_take_top(n_poly_stack_t S)
{
/* assume the request for 1 has already been fitted */
n_poly_struct ** poly_top;
FLINT_ASSERT(S->top + 1 <= S->alloc);
poly_top = S->array + S->top;
S->top += 1;
return poly_top[0];
}
N_POLY_INLINE
void n_poly_stack_give_back(n_poly_stack_t S, slong k)
{
FLINT_ASSERT(S->top >= k);
S->top -= k;
}
N_POLY_INLINE
slong n_poly_stack_size(const n_poly_stack_t S)
{
return S->top;
}
/*****************************************************************************/
FLINT_DLL void n_bpoly_stack_init(n_bpoly_stack_t S);
FLINT_DLL void n_bpoly_stack_clear(n_bpoly_stack_t S);
FLINT_DLL n_bpoly_struct ** n_bpoly_stack_fit_request(n_bpoly_stack_t S, slong k);
N_POLY_INLINE
n_bpoly_struct ** n_bpoly_stack_request(n_bpoly_stack_t S, slong k)
{
n_bpoly_struct ** bpoly_top;
bpoly_top = n_bpoly_stack_fit_request(S, k);
S->top += k;
return bpoly_top;
}
N_POLY_INLINE
n_bpoly_struct * n_bpoly_stack_take_top(n_bpoly_stack_t S)
{
/* assume the request for 1 has already been fitted */
n_bpoly_struct ** bpoly_top;
FLINT_ASSERT(S->top + 1 <= S->alloc);
bpoly_top = S->array + S->top;
S->top += 1;
return bpoly_top[0];
}
N_POLY_INLINE
void n_bpoly_stack_give_back(n_bpoly_stack_t S, slong k)
{
FLINT_ASSERT(S->top >= k);
S->top -= k;
}
N_POLY_INLINE
slong n_bpoly_stack_size(const n_bpoly_stack_t S)
{
return S->top;
}
/*****************************************************************************/
FLINT_DLL void n_polyun_stack_init(n_polyun_stack_t S);
FLINT_DLL void n_polyun_stack_clear(n_polyun_stack_t S);
FLINT_DLL n_polyun_struct ** n_polyun_stack_fit_request(n_polyun_stack_t S, slong k);
N_POLY_INLINE
n_polyun_struct ** n_polyun_stack_request(n_polyun_stack_t S, slong k)
{
n_polyun_struct ** polyun_top;
polyun_top = n_polyun_stack_fit_request(S, k);
S->top += k;
return polyun_top;
}
N_POLY_INLINE
n_polyun_struct * n_polyun_stack_take_top(n_polyun_stack_t S)
{
/* assume the request for 1 has already been fitted */
n_polyun_struct ** polyun_top;
FLINT_ASSERT(S->top + 1 <= S->alloc);
polyun_top = S->array + S->top;
S->top += 1;
return polyun_top[0];
}
N_POLY_INLINE
void n_polyun_stack_give_back(n_polyun_stack_t S, slong k)
{
FLINT_ASSERT(S->top >= k);
S->top -= k;
}
N_POLY_INLINE
slong n_polyun_stack_size(const n_polyun_stack_t S)
{
return S->top;
}
#ifdef __cplusplus
}
#endif
#endif