File indexing completed on 2026-11-07 10:15:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef N_POLY_H
0013 #define N_POLY_H
0014
0015 #include "nmod_types.h"
0016 #include "nmod_vec.h"
0017 #include "nmod_poly.h"
0018 #include "fq_nmod_types.h"
0019 #include "n_poly_types.h"
0020
0021 #ifdef __cplusplus
0022 extern "C" {
0023 #endif
0024
0025 #if !defined(FQ_NMOD_H)
0026 # define fq_nmod_ctx_degree(ctx) ((ctx)->modulus->length - 1)
0027 #endif
0028
0029 typedef struct
0030 {
0031 n_polyun_struct ** array;
0032 slong alloc;
0033 slong top;
0034 } n_polyun_stack_struct;
0035
0036 typedef n_polyun_stack_struct n_polyun_stack_t[1];
0037
0038 typedef struct {
0039 n_poly_stack_t poly_stack;
0040 n_polyun_stack_t polyun_stack;
0041 } n_poly_polyun_stack_struct;
0042
0043 typedef n_poly_polyun_stack_struct n_poly_polyun_stack_t[1];
0044
0045
0046
0047 FLINT_FORCE_INLINE
0048 void n_poly_init(n_poly_t A)
0049 {
0050 A->length = 0;
0051 A->alloc = 0;
0052 A->coeffs = NULL;
0053 }
0054 FLINT_FORCE_INLINE
0055 void n_poly_init2(n_poly_t A, slong alloc)
0056 {
0057 A->length = 0;
0058 A->alloc = alloc;
0059 A->coeffs = NULL;
0060 if (alloc > 0)
0061 A->coeffs = (ulong *) flint_malloc(alloc*sizeof(ulong));
0062 }
0063 FLINT_FORCE_INLINE
0064 void n_poly_clear(n_poly_t A)
0065 {
0066 FLINT_ASSERT(A->alloc != 0 || A->coeffs == NULL);
0067 if (A->alloc > 0)
0068 flint_free(A->coeffs);
0069 }
0070 void n_poly_realloc(n_poly_t A, slong len);
0071 int n_poly_is_canonical(const n_poly_t A);
0072
0073 FLINT_FORCE_INLINE
0074 void n_poly_swap(n_poly_t A, n_poly_t B)
0075 {
0076 FLINT_SWAP(n_poly_struct, *A, *B);
0077 }
0078
0079 FLINT_FORCE_INLINE
0080 slong n_poly_degree(const n_poly_t A)
0081 {
0082 FLINT_ASSERT(A->length >= 0);
0083 return A->length - 1;
0084 }
0085
0086 FLINT_FORCE_INLINE
0087 void n_poly_fit_length(n_poly_t A, slong len)
0088 {
0089 if (len > A->alloc)
0090 n_poly_realloc(A, len);
0091 }
0092
0093 FLINT_FORCE_INLINE
0094 void _n_poly_normalise(n_poly_t A)
0095 {
0096 while (A->length > 0 && A->coeffs[A->length - 1] == 0)
0097 A->length--;
0098 }
0099
0100 FLINT_FORCE_INLINE
0101 void n_poly_truncate(n_poly_t poly, slong len)
0102 {
0103 if (poly->length > len)
0104 {
0105 poly->length = len;
0106 _n_poly_normalise(poly);
0107 }
0108 }
0109
0110 void n_poly_reverse(n_poly_t output, const n_poly_t input, slong m);
0111
0112 FLINT_FORCE_INLINE
0113 ulong n_poly_lead(const n_poly_t A)
0114 {
0115 FLINT_ASSERT(A->length > 0);
0116 return A->coeffs[A->length - 1];
0117 }
0118
0119 FLINT_FORCE_INLINE void n_poly_zero(n_poly_t res) { res->length = 0; }
0120 FLINT_FORCE_INLINE
0121 void n_poly_one(n_poly_t A)
0122 {
0123 n_poly_fit_length(A, 1);
0124 A->length = 1;
0125 A->coeffs[0] = 1;
0126 }
0127
0128 FLINT_FORCE_INLINE
0129 void n_poly_set_ui(n_poly_t A, ulong c)
0130 {
0131 n_poly_fit_length(A, 1);
0132 A->coeffs[0] = c;
0133 A->length = (c != 0);
0134 }
0135 FLINT_FORCE_INLINE
0136 void n_poly_set(n_poly_t A, const n_poly_t B)
0137 {
0138 n_poly_fit_length(A, B->length);
0139 _nmod_vec_set(A->coeffs, B->coeffs, B->length);
0140 A->length = B->length;
0141 }
0142
0143 FLINT_FORCE_INLINE
0144 int n_poly_is_zero(const n_poly_t poly) { return poly->length == 0; }
0145 FLINT_FORCE_INLINE
0146 int n_poly_is_one(const n_poly_t A) { return A->length == 1 && A->coeffs[0] == 1; }
0147 FLINT_FORCE_INLINE
0148 int n_poly_equal(const n_poly_t a, const n_poly_t b)
0149 {
0150 if (a->length != b->length)
0151 return 0;
0152 if (a != b && !_nmod_vec_equal(a->coeffs, b->coeffs, a->length))
0153 return 0;
0154 return 1;
0155 }
0156
0157 FLINT_FORCE_INLINE
0158 void nmod_poly_mock(nmod_poly_t a, const n_poly_t b, nmod_t mod)
0159 {
0160 a->coeffs = b->coeffs;
0161 a->length = b->length;
0162 a->alloc = b->alloc;
0163 a->mod = mod;
0164 }
0165
0166 FLINT_FORCE_INLINE
0167 void n_poly_mock(n_poly_t a, const nmod_poly_t b)
0168 {
0169 a->coeffs = b->coeffs;
0170 a->length = b->length;
0171 a->alloc = b->alloc;
0172 }
0173
0174 FLINT_FORCE_INLINE
0175 ulong n_poly_get_coeff(const n_poly_t poly, slong j)
0176 {
0177 return (j >= poly->length) ? 0 : poly->coeffs[j];
0178 }
0179
0180 FLINT_FORCE_INLINE
0181 void n_poly_set_coeff_nonzero(n_poly_t A, slong j, ulong c)
0182 {
0183 FLINT_ASSERT(c != 0);
0184 if (j >= A->length)
0185 {
0186 n_poly_fit_length(A, j + 1);
0187 _nmod_vec_zero(A->coeffs + A->length, j - A->length);
0188 A->length = j + 1;
0189 }
0190 A->coeffs[j] = c;
0191 }
0192
0193 void n_poly_set_coeff(n_poly_t A, slong e, ulong c);
0194
0195 FLINT_FORCE_INLINE
0196 void n_poly_set_nmod_poly(n_poly_t a, const nmod_poly_t b)
0197 {
0198 n_poly_fit_length(a, b->length);
0199 _nmod_vec_set(a->coeffs, b->coeffs, b->length);
0200 a->length = b->length;
0201 }
0202
0203 FLINT_FORCE_INLINE
0204 void nmod_poly_set_n_poly(nmod_poly_t a, const n_poly_t b)
0205 {
0206 nmod_poly_fit_length(a, b->length);
0207 _nmod_vec_set(a->coeffs, b->coeffs, b->length);
0208 a->length = b->length;
0209 }
0210
0211 FLINT_FORCE_INLINE
0212 void n_poly_shift_left(n_poly_t A, const n_poly_t B, slong k)
0213 {
0214 n_poly_fit_length(A, B->length + k);
0215 _nmod_poly_shift_left(A->coeffs, B->coeffs, B->length, k);
0216 A->length = B->length + k;
0217 }
0218 FLINT_FORCE_INLINE
0219 void n_poly_shift_right(n_poly_t res, const n_poly_t poly, slong k)
0220 {
0221 if (k >= poly->length)
0222 res->length = 0;
0223 else
0224 {
0225 const slong len = poly->length - k;
0226 n_poly_fit_length(res, len);
0227 _nmod_poly_shift_right(res->coeffs, poly->coeffs, len, k);
0228 res->length = len;
0229 }
0230 }
0231
0232 ulong _n_poly_eval_pow(n_poly_t P, n_poly_t alphapow, dot_params_t params, nmod_t ctx);
0233
0234 void n_poly_print_pretty(const n_poly_t A, const char * x);
0235
0236
0237
0238 int n_poly_mod_is_canonical(const n_poly_t A, nmod_t mod);
0239
0240 void n_poly_mod_set_coeff_ui(n_poly_t A, slong j, ulong c, nmod_t mod);
0241
0242 FLINT_FORCE_INLINE
0243 void n_poly_mod_make_monic(n_poly_t A, const n_poly_t B, nmod_t mod)
0244 {
0245 FLINT_ASSERT(B->length > 0);
0246 n_poly_fit_length(A, B->length);
0247 A->length = B->length;
0248 _nmod_poly_make_monic(A->coeffs, B->coeffs, B->length, mod);
0249 }
0250
0251 FLINT_FORCE_INLINE
0252 void n_poly_mod_taylor_shift(n_poly_t g, ulong c, nmod_t mod)
0253 {
0254 _nmod_poly_taylor_shift(g->coeffs, c, g->length, mod);
0255 }
0256
0257 FLINT_FORCE_INLINE
0258 void _n_poly_mod_scalar_mul_nmod(n_poly_t A, const n_poly_t B, ulong c, nmod_t mod)
0259 {
0260 FLINT_ASSERT(B->length <= B->alloc);
0261 n_poly_fit_length(A, B->length);
0262 _nmod_vec_scalar_mul_nmod(A->coeffs, B->coeffs, B->length, c, mod);
0263 A->length = B->length;
0264 }
0265
0266 FLINT_FORCE_INLINE
0267 void _n_poly_mod_scalar_mul_nmod_inplace(n_poly_t A, ulong c, nmod_t mod)
0268 {
0269 _nmod_vec_scalar_mul_nmod(A->coeffs, A->coeffs, A->length, c, mod);
0270 }
0271
0272 void n_poly_mod_scalar_mul_ui(n_poly_t A, const n_poly_t B, ulong c, nmod_t ctx);
0273
0274 ulong n_poly_mod_eval_step2(n_poly_t Acur, const n_poly_t Ainc, nmod_t mod);
0275
0276 FLINT_FORCE_INLINE
0277 ulong n_poly_mod_evaluate_nmod(const n_poly_t A, ulong c, nmod_t mod)
0278 {
0279 return _nmod_poly_evaluate_nmod(A->coeffs, A->length, c, mod);
0280 }
0281
0282 FLINT_FORCE_INLINE
0283 void n_poly_mod_neg(n_poly_t A, const n_poly_t B, nmod_t mod)
0284 {
0285 n_poly_fit_length(A, B->length);
0286 _nmod_vec_neg(A->coeffs, B->coeffs, B->length, mod);
0287 A->length = B->length;
0288 }
0289
0290 void n_poly_mod_add_ui(n_poly_t res, const n_poly_t poly, ulong c, nmod_t ctx);
0291 FLINT_FORCE_INLINE
0292 void n_poly_mod_add(n_poly_t A, const n_poly_t B, const n_poly_t C, nmod_t mod)
0293 {
0294 slong Alen = FLINT_MAX(B->length, C->length);
0295 n_poly_fit_length(A, Alen);
0296 _nmod_poly_add(A->coeffs, B->coeffs, B->length, C->coeffs, C->length, mod);
0297 A->length = Alen;
0298 _n_poly_normalise(A);
0299 }
0300
0301 FLINT_FORCE_INLINE
0302 void n_poly_mod_sub(n_poly_t A, const n_poly_t B, const n_poly_t C, nmod_t mod)
0303 {
0304 slong Alen = FLINT_MAX(B->length, C->length);
0305 n_poly_fit_length(A, Alen);
0306 _nmod_poly_sub(A->coeffs, B->coeffs, B->length, C->coeffs, C->length, mod);
0307 A->length = Alen;
0308 _n_poly_normalise(A);
0309 }
0310
0311 FLINT_FORCE_INLINE
0312 void n_poly_mod_product_roots_nmod_vec(n_poly_t A, nn_srcptr r, slong n, nmod_t mod)
0313 {
0314 n_poly_fit_length(A, n + 1);
0315 A->length = n + 1;
0316 _nmod_poly_product_roots_nmod_vec(A->coeffs, r, n, mod);
0317 }
0318
0319 void n_poly_mod_shift_left_scalar_addmul(n_poly_t A, slong k, ulong c, nmod_t mod);
0320
0321 void n_poly_mod_addmul_linear(n_poly_t A, const n_poly_t B, const n_poly_t C, ulong d1, ulong d0, nmod_t mod);
0322
0323 void n_poly_mod_scalar_addmul_nmod(n_poly_t A, const n_poly_t B, const n_poly_t C, ulong d0, nmod_t ctx);
0324
0325 ulong n_poly_mod_eval_pow(n_poly_t P, n_poly_t alphapow, nmod_t ctx);
0326 void n_poly_mod_eval2_pow(ulong * vp, ulong * vm, const n_poly_t P, n_poly_t alphapow, nmod_t ctx);
0327
0328 ulong n_poly_mod_div_root(n_poly_t Q, const n_poly_t A, ulong c, nmod_t ctx);
0329
0330 FLINT_FORCE_INLINE
0331 void _n_poly_mod_mul(n_poly_t A, const n_poly_t B, const n_poly_t C, nmod_t ctx)
0332 {
0333 slong Blen = B->length;
0334 slong Clen = C->length;
0335 slong Alen = Blen + Clen - 1;
0336
0337 FLINT_ASSERT(A != B);
0338 FLINT_ASSERT(A != C);
0339
0340 if (Clen < 1 || Blen < 1)
0341 {
0342 A->length = 0;
0343 return;
0344 }
0345
0346 n_poly_fit_length(A, Alen);
0347 A->length = Alen;
0348
0349 if (Blen >= Clen)
0350 _nmod_poly_mul(A->coeffs, B->coeffs, Blen, C->coeffs, Clen, ctx);
0351 else
0352 _nmod_poly_mul(A->coeffs, C->coeffs, Clen, B->coeffs, Blen, ctx);
0353 }
0354 void n_poly_mod_mul(n_poly_t A, const n_poly_t B, const n_poly_t C, nmod_t mod);
0355 void n_poly_mod_mullow(n_poly_t A, const n_poly_t B, const n_poly_t C, slong n, nmod_t mod);
0356 FLINT_FORCE_INLINE
0357 void _n_poly_mod_div(n_poly_t Q, const n_poly_t A, const n_poly_t B, nmod_t mod)
0358 {
0359 const slong lenA = A->length, lenB = B->length;
0360 FLINT_ASSERT(lenB > 0);
0361 FLINT_ASSERT(Q != A && Q != B);
0362 if (lenA < lenB)
0363 {
0364 n_poly_zero(Q);
0365 return;
0366 }
0367 n_poly_fit_length(Q, lenA - lenB + 1);
0368 _nmod_poly_div(Q->coeffs, A->coeffs, lenA, B->coeffs, lenB, mod);
0369 Q->length = lenA - lenB + 1;
0370 }
0371 void n_poly_mod_div(n_poly_t Q, const n_poly_t A, const n_poly_t B, nmod_t mod);
0372 FLINT_FORCE_INLINE
0373 void _n_poly_mod_rem(n_poly_t R, const n_poly_t A, const n_poly_t B, nmod_t mod)
0374 {
0375 const slong lenA = A->length, lenB = B->length;
0376 FLINT_ASSERT(R != A && R != B);
0377 FLINT_ASSERT(lenB > 0);
0378 if (lenA < lenB)
0379 {
0380 n_poly_set(R, A);
0381 return;
0382 }
0383 n_poly_fit_length(R, lenB - 1);
0384 _nmod_poly_rem(R->coeffs, A->coeffs, lenA, B->coeffs, lenB, mod);
0385 R->length = lenB - 1;
0386 _n_poly_normalise(R);
0387 }
0388 void n_poly_mod_rem(n_poly_t R, const n_poly_t A, const n_poly_t B, nmod_t mod);
0389 FLINT_FORCE_INLINE
0390 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)
0391 {
0392 const slong lenA = A->length, lenB = B->length;
0393
0394 FLINT_ASSERT(lenB > 0);
0395 FLINT_ASSERT(Q != A && Q != B);
0396 FLINT_ASSERT(R != A && R != B);
0397
0398 if (lenA < lenB)
0399 {
0400 n_poly_set(R, A);
0401 n_poly_zero(Q);
0402 return;
0403 }
0404
0405 n_poly_fit_length(Q, lenA - lenB + 1);
0406 n_poly_fit_length(R, lenB - 1);
0407 _nmod_poly_divrem(Q->coeffs, R->coeffs, A->coeffs, lenA, B->coeffs, lenB, mod);
0408 Q->length = lenA - lenB + 1;
0409 R->length = lenB - 1;
0410 _n_poly_normalise(R);
0411 }
0412 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);
0413 FLINT_FORCE_INLINE
0414 void _n_poly_mod_divexact(n_poly_t Q, const n_poly_t A, const n_poly_t B, nmod_t mod)
0415 {
0416 const slong lenA = A->length, lenB = B->length;
0417 FLINT_ASSERT(lenB > 0);
0418 FLINT_ASSERT(Q != A && Q != B);
0419 if (lenA < lenB)
0420 {
0421 n_poly_zero(Q);
0422 return;
0423 }
0424 n_poly_fit_length(Q, lenA - lenB + 1);
0425 _nmod_poly_divexact(Q->coeffs, A->coeffs, lenA, B->coeffs, lenB, mod);
0426 Q->length = lenA - lenB + 1;
0427 }
0428 void n_poly_mod_divexact(n_poly_t Q, const n_poly_t A, const n_poly_t B, nmod_t mod);
0429
0430 void n_poly_mod_pow(n_poly_t res, const n_poly_t poly, ulong e, nmod_t ctx);
0431
0432 ulong n_poly_mod_remove(n_poly_t f, const n_poly_t p, nmod_t ctx);
0433
0434 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);
0435 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);
0436 int n_poly_mod_invmod(n_poly_t A, const n_poly_t B, const n_poly_t P, nmod_t mod);
0437
0438 void n_poly_mod_gcd(n_poly_t G, const n_poly_t A, const n_poly_t B, nmod_t mod);
0439 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);
0440
0441 void n_poly_mod_inv_series(n_poly_t Qinv, const n_poly_t Q, slong n, nmod_t mod);
0442 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);
0443
0444
0445
0446 FLINT_FORCE_INLINE
0447 nmod_t fq_nmod_ctx_mod(const fq_nmod_ctx_t ctx)
0448 {
0449 return ctx->modulus->mod;
0450 }
0451
0452 FLINT_FORCE_INLINE
0453 int _n_fq_is_zero(const ulong * a, slong d)
0454 {
0455 do {
0456 if (a[--d] != 0)
0457 return 0;
0458 } while (d > 0);
0459 return 1;
0460 }
0461
0462 FLINT_FORCE_INLINE
0463 void _n_fq_zero(ulong * a, slong d)
0464 {
0465 slong i;
0466 for (i = 0; i < d; i++)
0467 a[i] = 0;
0468 }
0469
0470 FLINT_FORCE_INLINE
0471 int _n_fq_is_one(const ulong * a, slong d)
0472 {
0473 slong i;
0474 if (a[0] != 1)
0475 return 0;
0476 for (i = 1; i < d; i++)
0477 if (a[i] != 0)
0478 return 0;
0479 return 1;
0480 }
0481
0482 FLINT_FORCE_INLINE
0483 int _n_fq_is_ui(const ulong * a, slong d)
0484 {
0485 slong i;
0486 for (i = 1; i < d; i++)
0487 if (a[i] != 0)
0488 return 0;
0489 return 1;
0490 }
0491
0492 FLINT_FORCE_INLINE
0493 int n_fq_is_one(const ulong * a, const fq_nmod_ctx_t ctx)
0494 {
0495 return _n_fq_is_one(a, fq_nmod_ctx_degree(ctx));
0496 }
0497
0498 FLINT_FORCE_INLINE
0499 void _n_fq_one(ulong * a, slong d)
0500 {
0501 slong i;
0502 a[0] = 1;
0503 for (i = 1; i < d; i++)
0504 a[i] = 0;
0505 }
0506
0507 FLINT_FORCE_INLINE
0508 void _n_fq_set_nmod(ulong * a, ulong b, slong d)
0509 {
0510 slong i;
0511 a[0] = b;
0512 for (i = 1; i < d; i++)
0513 a[i] = 0;
0514 }
0515
0516 void n_fq_gen(ulong * a, const fq_nmod_ctx_t ctx);
0517
0518 FLINT_FORCE_INLINE
0519 void _n_fq_set(
0520 ulong * a,
0521 const ulong * b,
0522 slong d)
0523 {
0524 slong i = 0;
0525 do a[i] = b[i]; while (++i < d);
0526 }
0527
0528 FLINT_FORCE_INLINE
0529 void _n_fq_swap(ulong * a, ulong * b, slong d)
0530 {
0531 slong i = 0;
0532 do FLINT_SWAP(ulong, a[i], b[i]); while (++i < d);
0533 }
0534
0535 FLINT_FORCE_INLINE
0536 int _n_fq_equal(ulong * a, const ulong * b, slong d)
0537 {
0538 slong i = 0;
0539 do
0540 if (a[i] != b[i]) return 0;
0541 while (++i < d);
0542 return 1;
0543 }
0544
0545 int n_fq_equal_fq_nmod(const ulong * a, const fq_nmod_t b, const fq_nmod_ctx_t ctx);
0546
0547 int n_fq_is_canonical(const ulong * a, const fq_nmod_ctx_t ctx);
0548
0549 void n_fq_randtest_not_zero(ulong * a, flint_rand_t state, const fq_nmod_ctx_t ctx);
0550
0551 char * n_fq_get_str_pretty(const ulong * a, const fq_nmod_ctx_t ctx);
0552
0553 #ifdef FLINT_HAVE_FILE
0554 int n_fq_fprint_pretty(FILE * file, const ulong * a, const fq_nmod_ctx_t ctx);
0555 #endif
0556 void n_fq_print_pretty(const ulong * a, const fq_nmod_ctx_t ctx);
0557
0558 void n_fq_get_n_poly(n_poly_t a, const ulong * b, const fq_nmod_ctx_t ctx);
0559 void n_fq_get_fq_nmod(fq_nmod_t a, const ulong * b, const fq_nmod_ctx_t ctx);
0560
0561 void _n_fq_set_n_poly(ulong * a, const ulong * bcoeffs, slong blen, const fq_nmod_ctx_t ctx);
0562 void n_fq_set_fq_nmod(ulong * a, const fq_nmod_t b, const fq_nmod_ctx_t ctx);
0563
0564 FLINT_FORCE_INLINE
0565 void _n_fq_neg(ulong * a, const ulong * b, slong d, nmod_t mod)
0566 {
0567 FLINT_ASSERT(d > 0);
0568 _nmod_vec_neg(a, b, d, mod);
0569 }
0570 FLINT_FORCE_INLINE
0571 void _n_fq_add(ulong * a, const ulong * b, const ulong * c, slong d, nmod_t mod)
0572 {
0573 FLINT_ASSERT(d > 0);
0574 _nmod_vec_add(a, b, c, d, mod);
0575 }
0576 void n_fq_add_si(ulong * a, const ulong * b, slong c, const fq_nmod_ctx_t ctx);
0577 void n_fq_add_fq_nmod(ulong * a, const ulong * b, const fq_nmod_t c, const fq_nmod_ctx_t ctx);
0578 FLINT_FORCE_INLINE
0579 void n_fq_add(ulong * a, const ulong * b, const ulong * c, const fq_nmod_ctx_t ctx)
0580 {
0581 slong d = fq_nmod_ctx_degree(ctx);
0582 FLINT_ASSERT(d > 0);
0583 _nmod_vec_add(a, b, c, d, ctx->modulus->mod);
0584 }
0585 FLINT_FORCE_INLINE
0586 void _n_fq_sub(ulong * a, const ulong * b, const ulong * c, slong d, nmod_t mod)
0587 {
0588 FLINT_ASSERT(d > 0);
0589 _nmod_vec_sub(a, b, c, d, mod);
0590 }
0591 void n_fq_sub_fq_nmod(ulong * a, const ulong * b, const fq_nmod_t c, const fq_nmod_ctx_t ctx);
0592 FLINT_FORCE_INLINE
0593 void n_fq_sub(ulong * a, const ulong * b, const ulong * c, const fq_nmod_ctx_t ctx)
0594 {
0595 slong d = fq_nmod_ctx_degree(ctx);
0596 FLINT_ASSERT(d > 0);
0597 _nmod_vec_sub(a, b, c, d, ctx->modulus->mod);
0598 }
0599
0600
0601 void _n_fq_mul_ui(
0602 ulong * a,
0603 const ulong * b,
0604 ulong c,
0605 slong d,
0606 nmod_t mod);
0607
0608 void _n_fq_madd2(
0609 ulong * a,
0610 const ulong * b,
0611 const ulong * c,
0612 const fq_nmod_ctx_t ctx,
0613 ulong * t);
0614
0615 void _n_fq_mul2(
0616 ulong * t,
0617 const ulong * b,
0618 const ulong * c,
0619 const fq_nmod_ctx_t ctx);
0620
0621 #define N_FQ_REDUCE_ITCH 2
0622 void _n_fq_reduce(ulong * a, ulong * b, slong blen, const fq_nmod_ctx_t ctx, ulong * t);
0623
0624 FLINT_FORCE_INLINE
0625 void _n_fq_reduce2(ulong * a, ulong * b, const fq_nmod_ctx_t ctx, ulong * t)
0626 {
0627 slong blen = 2*fq_nmod_ctx_degree(ctx) - 1;
0628 FLINT_ASSERT(a != b);
0629 while (blen > 0 && b[blen - 1] == 0)
0630 blen--;
0631 _n_fq_reduce(a, b, blen, ctx, t);
0632 }
0633
0634
0635 #define N_FQ_MUL_ITCH 4
0636 FLINT_FORCE_INLINE
0637 void _n_fq_mul(ulong * a, const ulong * b, const ulong * c, const fq_nmod_ctx_t ctx, ulong * t)
0638 {
0639 slong d = fq_nmod_ctx_degree(ctx);
0640 _n_fq_mul2(t, b, c, ctx);
0641 _n_fq_reduce2(a, t, ctx, t + 2*d);
0642 }
0643 FLINT_FORCE_INLINE
0644 void _n_fq_addmul(ulong * a, const ulong * b, const ulong * c, const ulong * e, const fq_nmod_ctx_t ctx, ulong * t)
0645 {
0646 slong d = fq_nmod_ctx_degree(ctx);
0647 _n_fq_mul2(t, c, e, ctx);
0648 _nmod_vec_add(t, t, b, d, ctx->mod);
0649 _n_fq_reduce2(a, t, ctx, t + 2*d);
0650 }
0651
0652 #define N_FQ_LAZY_ITCH 6
0653 int _n_fq_dot_lazy_size(slong len, const fq_nmod_ctx_t ctx);
0654
0655
0656 void _n_fq_madd2_lazy1(ulong * a, const ulong * b, const ulong * c, slong d);
0657 void _n_fq_mul2_lazy1(ulong * a, const ulong * b, const ulong * c, slong d);
0658 void _n_fq_reduce2_lazy1(ulong * a, slong d, nmod_t ctx);
0659
0660
0661 void _n_fq_madd2_lazy2(ulong * a, const ulong * b, const ulong * c, slong d);
0662 void _n_fq_mul2_lazy2(ulong * a, const ulong * b, const ulong * c, slong d);
0663 void _n_fq_reduce2_lazy2(ulong * a, slong d, nmod_t ctx);
0664
0665
0666 void _n_fq_madd2_lazy3(ulong * a, const ulong * b, const ulong * c, slong d);
0667 void _n_fq_mul2_lazy3(ulong * a, const ulong * b, const ulong * c, slong d);
0668 void _n_fq_reduce2_lazy3(ulong * a, slong d, nmod_t ctx);
0669
0670 #define N_FQ_INV_ITCH 1
0671 void _n_fq_inv(ulong * a, const ulong * b, const fq_nmod_ctx_t ctx, ulong * t);
0672 void n_fq_inv(ulong * a, const ulong * b, const fq_nmod_ctx_t ctx);
0673
0674 #define N_FQ_MUL_INV_ITCH FLINT_MAX(N_FQ_MUL_ITCH, N_FQ_INV_ITCH)
0675 void n_fq_mul(ulong * a, const ulong * b, const ulong * c, const fq_nmod_ctx_t ctx);
0676 void n_fq_mul_fq_nmod(ulong * a, const ulong * b, const fq_nmod_t c, const fq_nmod_ctx_t ctx);
0677
0678 void n_fq_addmul(ulong * a, const ulong * b, const ulong * c, const ulong * d, const fq_nmod_ctx_t ctx);
0679
0680 void _n_fq_pow_ui(ulong * a, const ulong * b, ulong e, const fq_nmod_ctx_t ctx);
0681 void n_fq_pow_ui(ulong * a, const ulong * b, ulong e, const fq_nmod_ctx_t ctx);
0682 void n_fq_pow_fmpz(ulong * a, const ulong * b, const fmpz_t e, const fq_nmod_ctx_t ctx);
0683
0684
0685
0686 #define N_FQ_POLY_DIVREM_DIVCONQUER_CUTOFF 20
0687
0688 #define n_fq_poly_init n_poly_init
0689 void n_fq_poly_init2(n_fq_poly_t A, slong alloc, const fq_nmod_ctx_t ctx);
0690 #define n_fq_poly_clear n_poly_clear
0691 #define n_fq_poly_swap n_poly_swap
0692 int n_fq_poly_is_canonical(const n_fq_poly_t a, const fq_nmod_ctx_t ctx);
0693
0694 #define n_fq_poly_degree n_poly_degree
0695
0696 #define n_fq_poly_zero n_poly_zero
0697 void _n_fq_poly_one(n_fq_poly_t A, slong d);
0698 FLINT_FORCE_INLINE
0699 void n_fq_poly_one(n_fq_poly_t A, const fq_nmod_ctx_t ctx)
0700 {
0701 _n_fq_poly_one(A, fq_nmod_ctx_degree(ctx));
0702 }
0703
0704 #define n_fq_poly_is_zero n_poly_is_zero
0705 int n_fq_poly_is_one(n_fq_poly_t A, const fq_nmod_ctx_t ctx);
0706 int n_fq_poly_equal(const n_fq_poly_t A, const n_fq_poly_t B, const fq_nmod_ctx_t ctx);
0707
0708 FLINT_FORCE_INLINE
0709 void _n_fq_poly_normalise(n_fq_poly_t A, slong d)
0710 {
0711 while (A->length > 0 && _n_fq_is_zero(A->coeffs + d*(A->length - 1), d))
0712 A->length--;
0713 }
0714
0715 void n_fq_poly_print_pretty(const n_fq_poly_t A, const char * x, const fq_nmod_ctx_t ctx);
0716
0717 void n_fq_poly_set(n_fq_poly_t A, const n_fq_poly_t B, const fq_nmod_ctx_t ctx);
0718
0719 void n_fq_poly_randtest(n_fq_poly_t A, flint_rand_t state, slong len, const fq_nmod_ctx_t ctx);
0720
0721 void n_fq_poly_make_monic(n_fq_poly_t A, const n_poly_t B, const fq_nmod_ctx_t ctx);
0722
0723 void n_fq_poly_get_coeff_n_fq(ulong * c, const n_poly_t A, slong e, const fq_nmod_ctx_t ctx);
0724 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);
0725
0726 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);
0727 void n_fq_poly_set_coeff_n_fq(n_poly_t A, slong j, const ulong * c, const fq_nmod_ctx_t ctx);
0728
0729 void n_fq_poly_scalar_mul_ui(n_poly_t A, const n_poly_t B, ulong c, const fq_nmod_ctx_t ctx);
0730 void n_fq_poly_scalar_mul_n_fq(n_poly_t A, const n_poly_t B, const ulong * c, const fq_nmod_ctx_t ctx);
0731 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 ulong * d, const fq_nmod_ctx_t ctx);
0732
0733 void n_fq_poly_shift_left_scalar_submul(n_poly_t A, slong k, const ulong * c, const fq_nmod_ctx_t ctx);
0734
0735 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);
0736 void n_fq_poly_evaluate_n_fq(ulong * e, const n_poly_t A, const ulong * c, const fq_nmod_ctx_t ctx);
0737
0738 void n_fq_poly_get_fq_nmod_poly(fq_nmod_poly_t A, const n_poly_t B, const fq_nmod_ctx_t ctx);
0739
0740 void n_fq_poly_set_n_fq(n_poly_t A, const ulong * c, const fq_nmod_ctx_t ctx);
0741 void n_fq_poly_set_fq_nmod(n_poly_t A, const fq_nmod_t c, const fq_nmod_ctx_t ctx);
0742 void n_fq_poly_set_fq_nmod_poly(n_poly_t A, const fq_nmod_poly_t B, const fq_nmod_ctx_t ctx);
0743
0744 void n_fq_poly_shift_left(n_poly_t A, const n_poly_t B, slong n, const fq_nmod_ctx_t ctx);
0745 void n_fq_poly_shift_right(n_poly_t A, const n_poly_t B, slong n, const fq_nmod_ctx_t ctx);
0746
0747 void n_fq_poly_truncate(n_poly_t A, slong len, const fq_nmod_ctx_t ctx);
0748
0749 void n_fq_poly_neg(n_poly_t A, const n_poly_t B, const fq_nmod_ctx_t ctx);
0750 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);
0751 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);
0752 void n_fq_poly_add_si(n_poly_t A, const n_poly_t B, slong c, const fq_nmod_ctx_t ctx);
0753
0754 void _n_fq_poly_mul_(ulong * A, const ulong * B, slong Blen, const ulong * C, slong Clen, const fq_nmod_ctx_t ctx, n_poly_stack_t St);
0755 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);
0756 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);
0757
0758 void n_fq_poly_pow(n_poly_t A, const n_poly_t B, ulong e, const fq_nmod_ctx_t ctx);
0759
0760 ulong n_fq_poly_remove(n_poly_t f, const n_poly_t g, const fq_nmod_ctx_t ctx);
0761
0762 void _n_fq_poly_divrem_basecase_(ulong * Q, ulong * A, const ulong * AA, slong Alen, const ulong * B, slong Blen, const ulong * invB, const fq_nmod_ctx_t ctx, n_poly_stack_t St);
0763 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);
0764
0765 FLINT_FORCE_INLINE
0766 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)
0767 {
0768 n_fq_poly_divrem_divconquer_(Q, R, A, B, ctx, St);
0769 }
0770 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);
0771
0772 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);
0773 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);
0774 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);
0775
0776 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);
0777
0778 void _n_fq_poly_rem_basecase_(ulong * Q, ulong * A, const ulong * AA, slong Alen, const ulong * B, slong Blen, const ulong * invB, const fq_nmod_ctx_t ctx, n_poly_stack_t St);
0779 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);
0780
0781 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);
0782
0783 void n_fq_poly_inv_series(n_poly_t A, const n_poly_t B, slong order, const fq_nmod_ctx_t ctx);
0784
0785 void n_fq_poly_eval_pow(ulong * ev, const n_fq_poly_t A, n_fq_poly_t alphapow, const fq_nmod_ctx_t ctx);
0786
0787
0788
0789 #define n_fq_polyun_init n_polyun_init
0790 #define n_fq_polyun_clear n_polyun_clear
0791
0792 void n_fq_polyun_set(n_fq_polyun_t A, const n_fq_polyun_t B, const fq_nmod_ctx_t ctx);
0793
0794
0795
0796 FLINT_FORCE_INLINE
0797 void n_bpoly_init(n_bpoly_t A)
0798 {
0799 A->coeffs = NULL;
0800 A->alloc = 0;
0801 A->length = 0;
0802 }
0803 void n_bpoly_clear(n_bpoly_t A);
0804 void n_bpoly_realloc(n_bpoly_t A, slong len);
0805
0806 FLINT_FORCE_INLINE
0807 void n_bpoly_fit_length(n_bpoly_t A, slong len)
0808 {
0809 if (len > A->alloc)
0810 n_bpoly_realloc(A, len);
0811 }
0812
0813 FLINT_FORCE_INLINE
0814 void n_bpoly_swap(n_bpoly_t A, n_bpoly_t B)
0815 {
0816 n_bpoly_struct t = *A;
0817 *A = *B;
0818 *B = t;
0819 }
0820
0821 void n_bpoly_print_pretty(const n_bpoly_t A, const char * xvar, const char * yvar);
0822
0823 FLINT_FORCE_INLINE
0824 void n_bpoly_normalise(n_bpoly_t A)
0825 {
0826 while (A->length > 0 && n_poly_is_zero(A->coeffs + A->length - 1))
0827 A->length--;
0828 }
0829
0830 FLINT_FORCE_INLINE void n_bpoly_zero(n_bpoly_t A) { A->length = 0; }
0831 void n_bpoly_one(n_bpoly_t A);
0832 void _n_bpoly_set(n_bpoly_t A, const n_bpoly_t B);
0833
0834 FLINT_FORCE_INLINE
0835 void n_bpoly_set(n_bpoly_t A, const n_bpoly_t B)
0836 {
0837 if (A != B)
0838 _n_bpoly_set(A, B);
0839 }
0840
0841 FLINT_FORCE_INLINE
0842 int n_bpoly_is_zero(const n_bpoly_t A) { return A->length == 0; }
0843 int n_bpoly_equal(const n_bpoly_t A, const n_bpoly_t B);
0844
0845 void n_bpoly_set_coeff(n_bpoly_t A, slong e0, slong e1, ulong c);
0846 void n_bpoly_set_coeff_nonzero(n_bpoly_t A, slong e0, slong e1, ulong c);
0847
0848 void n_bpoly_mod_derivative_gen0(n_bpoly_t A, const n_bpoly_t B, nmod_t ctx);
0849
0850 FLINT_FORCE_INLINE
0851 ulong n_bpoly_get_coeff(const n_bpoly_t A, slong e0, slong e1)
0852 {
0853 return (e0 >= A->length) ? 0 : n_poly_get_coeff(A->coeffs + e0, e1);
0854 }
0855
0856 FLINT_FORCE_INLINE
0857 slong n_bpoly_degree0(const n_bpoly_t A) { return A->length - 1; }
0858 slong n_bpoly_degree1(const n_bpoly_t A);
0859
0860 void n_bpoly_set_poly_gen0(n_bpoly_t A, const n_poly_t B);
0861 void n_bpoly_set_poly_gen1(n_bpoly_t A, const n_poly_t B);
0862
0863
0864
0865 int n_bpoly_mod_is_canonical(const n_bpoly_t A, nmod_t mod);
0866
0867 FLINT_FORCE_INLINE
0868 ulong n_bpoly_bidegree(const n_bpoly_t A)
0869 {
0870 ulong x, y;
0871 FLINT_ASSERT(A->length > 0);
0872 x = A->length - 1;
0873 y = A->coeffs[x].length - 1;
0874 return (x << (FLINT_BITS/2)) + y;
0875 }
0876
0877 void n_bpoly_scalar_mul_nmod(n_bpoly_t A, ulong c, nmod_t ctx);
0878
0879 void n_bpoly_mod_content_last(n_poly_t g, const n_bpoly_t A, nmod_t ctx);
0880
0881 void n_bpoly_mod_divexact_last(n_bpoly_t A, const n_poly_t b, nmod_t ctx);
0882
0883 void n_bpoly_mod_mul_last(n_bpoly_t A, const n_poly_t b, nmod_t ctx);
0884
0885 void n_bpoly_mod_taylor_shift_gen0(n_bpoly_t A, ulong c, nmod_t ctx);
0886 void n_bpoly_mod_taylor_shift_gen1(n_bpoly_t A, const n_bpoly_t B, ulong c, nmod_t ctx);
0887
0888 void n_bpoly_mod_add(n_bpoly_t A, const n_bpoly_t B, const n_bpoly_t C, nmod_t ctx);
0889 void n_bpoly_mod_sub(n_bpoly_t A, const n_bpoly_t B, const n_bpoly_t C, nmod_t ctx);
0890 void n_bpoly_mod_mul(n_bpoly_t A, const n_bpoly_t B, const n_bpoly_t C, nmod_t ctx);
0891
0892 int n_bpoly_mod_divides(n_bpoly_t Q, const n_bpoly_t A, const n_bpoly_t B, nmod_t ctx);
0893
0894 void n_bpoly_mod_make_primitive(n_poly_t g, n_bpoly_t A, nmod_t ctx);
0895
0896 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);
0897 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);
0898
0899 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);
0900 void n_bpoly_mod_interp_lift_2sm_poly(slong * deg1, n_bpoly_t T, const n_poly_t A, const n_poly_t B, ulong alpha, nmod_t mod);
0901 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);
0902
0903 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);
0904
0905
0906
0907 #define n_fq_bpoly_init n_bpoly_init
0908 #define n_fq_bpoly_clear n_bpoly_clear
0909
0910 #define n_fq_bpoly_zero n_bpoly_zero
0911
0912 #define n_fq_bpoly_fit_length n_bpoly_fit_length
0913
0914 #define n_fq_bpoly_normalise n_bpoly_normalise
0915
0916 #define n_fq_bpoly_degree0 n_bpoly_degree0
0917 #define n_fq_bpoly_degree1 n_bpoly_degree1
0918
0919 int n_fq_bpoly_is_canonical(const n_fq_bpoly_t A, const fq_nmod_ctx_t ctx);
0920
0921 void n_fq_bpoly_one(n_fq_bpoly_t A, const fq_nmod_ctx_t ctx);
0922 void n_fq_bpoly_set(n_fq_bpoly_t A, const n_fq_bpoly_t B, const fq_nmod_ctx_t ctx);
0923
0924 int n_fq_bpoly_equal(const n_bpoly_t A, const n_bpoly_t B, const fq_nmod_ctx_t ctx);
0925
0926 void n_fq_bpoly_get_coeff_n_fq(ulong * c, const n_bpoly_t A, slong e0, slong e1, const fq_nmod_ctx_t ctx);
0927 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);
0928 void n_fq_bpoly_set_coeff_n_fq(n_fq_bpoly_t A, slong e0, slong e1, const ulong * c, const fq_nmod_ctx_t ctx);
0929
0930 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);
0931 void n_fq_bpoly_set_n_fq_poly_gen0(n_bpoly_t A, const n_poly_t B, const fq_nmod_ctx_t ctx);
0932 void n_fq_bpoly_set_n_fq_poly_gen1(n_bpoly_t A, const n_poly_t B, const fq_nmod_ctx_t ctx);
0933
0934 void n_fq_bpoly_derivative_gen0(n_bpoly_t A, const n_bpoly_t B, const fq_nmod_ctx_t ctx);
0935
0936 void n_fq_bpoly_scalar_mul_n_fq(n_fq_bpoly_t A, const ulong * c, const fq_nmod_ctx_t ctx);
0937
0938 void n_fq_bpoly_taylor_shift_gen0_fq_nmod(n_bpoly_t A, const fq_nmod_t alpha, const fq_nmod_ctx_t ctx);
0939 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);
0940 void n_fq_bpoly_taylor_shift_gen0_n_fq(n_fq_bpoly_t A, const ulong * alpha, const fq_nmod_ctx_t ctx);
0941
0942 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);
0943
0944 void n_fq_bpoly_print_pretty(const n_fq_bpoly_t A, const char * xvar, const char * yvar, const fq_nmod_ctx_t ctx);
0945
0946
0947
0948 FLINT_FORCE_INLINE
0949 void n_tpoly_init(n_tpoly_t A)
0950 {
0951 A->coeffs = NULL;
0952 A->alloc = 0;
0953 A->length = 0;
0954 }
0955 void n_tpoly_clear(n_tpoly_t A);
0956 void n_tpoly_fit_length(n_tpoly_t A, slong len);
0957
0958 FLINT_FORCE_INLINE
0959 void n_tpoly_swap(n_tpoly_t A, n_tpoly_t B)
0960 {
0961 n_tpoly_struct t = *A;
0962 *A = *B;
0963 *B = t;
0964 }
0965
0966
0967
0968 FLINT_FORCE_INLINE
0969 void n_polyu_init(n_polyu_t A)
0970 {
0971 A->coeffs = NULL;
0972 A->exps = NULL;
0973 A->length = 0;
0974 A->alloc = 0;
0975 }
0976 void n_polyu_clear(n_polyu_t A);
0977 void n_polyu_realloc(n_polyu_t A, slong len);
0978
0979 FLINT_FORCE_INLINE
0980 void n_polyu_fit_length(n_polyu_t A, slong len)
0981 {
0982 FLINT_ASSERT(A->alloc >= 0);
0983 if (len > A->alloc)
0984 n_polyu_realloc(A, len);
0985 }
0986
0987 FLINT_FORCE_INLINE
0988 void n_polyu_swap(n_polyu_t A, n_polyu_t B)
0989 {
0990 n_polyu_struct T = *B;
0991 *B = *A;
0992 *A = T;
0993 }
0994
0995 void n_polyu3_print_pretty(const n_polyu_t A, const char * gen0, const char * gen1, const char * var2);
0996
0997 void n_polyu3_degrees(slong * deg0, slong * deg1, slong * deg2, const n_polyu_t A);
0998
0999
1000
1001 void nmod_pow_cache_start(ulong b, n_poly_t pos_direct, n_poly_t pos_bin, n_poly_t neg_direct);
1002
1003 ulong nmod_pow_cache_mulpow_ui(ulong a, ulong e, n_poly_t pos_direct, n_poly_t pos_bin, n_poly_t neg_direct, nmod_t ctx);
1004 ulong nmod_pow_cache_mulpow_neg_ui(ulong a, ulong e, n_poly_t pos_direct, n_poly_t pos_bin, n_poly_t neg_direct, nmod_t ctx);
1005 ulong nmod_pow_cache_mulpow_fmpz(ulong a, const fmpz_t e, n_poly_t pos_direct, n_poly_t pos_bin, n_poly_t neg_direct, nmod_t ctx);
1006
1007 void n_fq_pow_cache_start_n_fq(const ulong * b, n_poly_t pos_direct, n_poly_t pos_bin, n_poly_t neg_direct, const fq_nmod_ctx_t ctx);
1008 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);
1009
1010 void n_fq_pow_cache_mulpow_ui(ulong * r, const ulong * a, ulong e, n_poly_t pos_direct, n_poly_t pos_bin, n_poly_t neg_direct, const fq_nmod_ctx_t ctx);
1011 void n_fq_pow_cache_mulpow_neg_ui(ulong * r, const ulong * a, ulong e, n_poly_t pos_direct, n_poly_t pos_bin, n_poly_t neg_direct, const fq_nmod_ctx_t ctx);
1012 void n_fq_pow_cache_mulpow_fmpz(ulong * r, const ulong * 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);
1013
1014
1015
1016 void nmod_eval_interp_init(nmod_eval_interp_t E);
1017 void nmod_eval_interp_clear(nmod_eval_interp_t E);
1018
1019 int nmod_eval_interp_set_degree_modulus(nmod_eval_interp_t E, slong deg, nmod_t ctx);
1020
1021 FLINT_FORCE_INLINE
1022 slong nmod_eval_interp_eval_length(nmod_eval_interp_t E)
1023 {
1024 return 1 + E->radix*E->d;
1025 }
1026
1027 void nmod_eval_interp_to_coeffs_poly(n_poly_t a, const n_poly_t v, nmod_eval_interp_t E, nmod_t ctx);
1028 void nmod_eval_interp_from_coeffs_poly(n_poly_t v, const n_poly_t a, nmod_eval_interp_t E, nmod_t ctx);
1029 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);
1030 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);
1031
1032 FLINT_FORCE_INLINE void nmod_evals_zero(n_poly_t a) { a->length = 0; }
1033 void nmod_evals_add_inplace(n_poly_t a, n_poly_t b, slong len, nmod_t ctx);
1034 void nmod_evals_mul(n_poly_t a, n_poly_t b, n_poly_t c, slong len, nmod_t ctx);
1035 void nmod_evals_addmul(n_poly_t a, n_poly_t b, n_poly_t c, slong len, nmod_t ctx);
1036 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);
1037
1038 FLINT_FORCE_INLINE void n_fq_evals_zero(n_fq_poly_t a) { a->length = 0; }
1039 void n_fq_evals_add_inplace(n_fq_poly_t a, n_fq_poly_t b, slong len, const fq_nmod_ctx_t ctx);
1040 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);
1041 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);
1042 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);
1043
1044
1045
1046 FLINT_FORCE_INLINE
1047 void n_polyun_init(n_polyun_t A)
1048 {
1049 A->coeffs = NULL;
1050 A->exps = NULL;
1051 A->length = 0;
1052 A->alloc = 0;
1053 }
1054 void n_polyun_clear(n_polyun_t A);
1055 void n_polyun_realloc(n_polyun_t A, slong len);
1056
1057 int n_polyun_is_canonical(const n_polyun_t A);
1058 int n_polyun_mod_is_canonical(const n_polyun_t A, nmod_t mod);
1059
1060 FLINT_FORCE_INLINE
1061 void n_polyun_fit_length(n_polyun_t A, slong len)
1062 {
1063 if (len > A->alloc)
1064 n_polyun_realloc(A, len);
1065 }
1066
1067 FLINT_FORCE_INLINE
1068 void n_polyun_swap(n_polyun_t A, n_polyun_t B)
1069 {
1070 n_polyun_struct t = *B;
1071 *B = *A;
1072 *A = t;
1073 }
1074
1075 void n_polyun_set(n_polyun_t A, const n_polyun_t B);
1076
1077 void n_polyu1n_print_pretty(const n_polyun_t A, const char * var0, const char * varlast);
1078 void n_polyu2n_print_pretty(const n_polyun_t A, const char * gen0, const char * gen1, const char * varlast);
1079 void n_polyu3n_print_pretty(const n_polyun_t A, const char * gen0, const char * gen1, const char * var2, const char * varlast);
1080
1081 int n_polyun_equal(const n_polyun_t A, const n_polyun_t B);
1082
1083 FLINT_FORCE_INLINE
1084 void n_polyun_one(n_polyun_t A)
1085 {
1086 n_polyun_fit_length(A, 1);
1087 A->length = 1;
1088 A->exps[0] = 0;
1089 n_poly_one(A->coeffs + 0);
1090 }
1091
1092 FLINT_FORCE_INLINE
1093 ulong n_polyu1n_bidegree(n_polyun_t A)
1094 {
1095 ulong x = A->exps[0];
1096 ulong y = A->coeffs[0].length - 1;
1097 return (x << (FLINT_BITS/2)) + y;
1098 }
1099
1100 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);
1101
1102
1103
1104 void n_fq_poly_product_roots_n_fq(n_poly_t M, const ulong * H, slong length, const fq_nmod_ctx_t ctx, n_poly_stack_t St);
1105 slong n_polyun_product_roots(n_polyun_t M, const n_polyun_t H, nmod_t ctx);
1106 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);
1107
1108 ulong _nmod_zip_eval_step(ulong * cur, const ulong * inc, const ulong * coeffs, slong length, nmod_t ctx);
1109 void _n_fq_zip_eval_step(ulong * res, ulong * cur, const ulong * inc, const ulong * coeffs, slong length, const fq_nmod_ctx_t ctx);
1110 void _n_fqp_zip_eval_step(ulong * res, ulong * cur, const ulong * inc, const ulong * coeffs, slong length, slong d, nmod_t mod);
1111
1112 int _nmod_zip_vand_solve(ulong * coeffs, const ulong * monomials, slong mlength, const ulong * evals, slong elength, const ulong * master, ulong * scratch, nmod_t ctx);
1113 int _n_fq_zip_vand_solve(ulong * coeffs, const ulong * monomials, slong mlength, const ulong * evals, slong elength, const ulong * master, ulong * scratch, const fq_nmod_ctx_t ctx);
1114 int _n_fqp_zip_vand_solve(ulong * coeffs, const ulong * monomials, slong mlength, const ulong * evals, slong elength, const ulong * master, ulong * scratch, const fq_nmod_ctx_t ctx);
1115
1116
1117
1118 void n_poly_stack_init(n_poly_stack_t S);
1119 void n_poly_stack_clear(n_poly_stack_t S);
1120
1121 n_poly_struct ** n_poly_stack_fit_request(n_poly_stack_t S, slong k);
1122
1123 FLINT_FORCE_INLINE
1124 ulong * n_poly_stack_vec_init(n_poly_stack_t S, slong len)
1125 {
1126 n_poly_struct * poly_top;
1127 poly_top = n_poly_stack_fit_request(S, 1)[0];
1128 S->top += 1;
1129 n_poly_fit_length(poly_top, len);
1130 return poly_top->coeffs;
1131 }
1132
1133 FLINT_FORCE_INLINE
1134 void n_poly_stack_vec_clear(n_poly_stack_t S)
1135 {
1136 FLINT_ASSERT(S->top >= 1);
1137 S->top -= 1;
1138 }
1139
1140 FLINT_FORCE_INLINE
1141 n_poly_struct ** n_poly_stack_request(n_poly_stack_t S, slong k)
1142 {
1143 n_poly_struct ** poly_top;
1144 poly_top = n_poly_stack_fit_request(S, k);
1145 S->top += k;
1146 return poly_top;
1147 }
1148
1149 FLINT_FORCE_INLINE
1150 n_poly_struct * n_poly_stack_take_top(n_poly_stack_t S)
1151 {
1152
1153 n_poly_struct ** poly_top;
1154 FLINT_ASSERT(S->top + 1 <= S->alloc);
1155 poly_top = S->array + S->top;
1156 S->top += 1;
1157 return poly_top[0];
1158 }
1159
1160 FLINT_FORCE_INLINE
1161 void n_poly_stack_give_back(n_poly_stack_t S, slong k)
1162 {
1163 FLINT_ASSERT(S->top >= k);
1164 S->top -= k;
1165 }
1166
1167 FLINT_FORCE_INLINE
1168 slong n_poly_stack_size(const n_poly_stack_t S)
1169 {
1170 return S->top;
1171 }
1172
1173
1174
1175 void n_bpoly_stack_init(n_bpoly_stack_t S);
1176 void n_bpoly_stack_clear(n_bpoly_stack_t S);
1177
1178 n_bpoly_struct ** n_bpoly_stack_fit_request(n_bpoly_stack_t S, slong k);
1179
1180 FLINT_FORCE_INLINE
1181 n_bpoly_struct ** n_bpoly_stack_request(n_bpoly_stack_t S, slong k)
1182 {
1183 n_bpoly_struct ** bpoly_top;
1184 bpoly_top = n_bpoly_stack_fit_request(S, k);
1185 S->top += k;
1186 return bpoly_top;
1187 }
1188
1189 FLINT_FORCE_INLINE
1190 n_bpoly_struct * n_bpoly_stack_take_top(n_bpoly_stack_t S)
1191 {
1192
1193 n_bpoly_struct ** bpoly_top;
1194 FLINT_ASSERT(S->top + 1 <= S->alloc);
1195 bpoly_top = S->array + S->top;
1196 S->top += 1;
1197 return bpoly_top[0];
1198 }
1199
1200 FLINT_FORCE_INLINE
1201 void n_bpoly_stack_give_back(n_bpoly_stack_t S, slong k)
1202 {
1203 FLINT_ASSERT(S->top >= k);
1204 S->top -= k;
1205 }
1206
1207 FLINT_FORCE_INLINE
1208 slong n_bpoly_stack_size(const n_bpoly_stack_t S)
1209 {
1210 return S->top;
1211 }
1212
1213
1214
1215 void n_polyun_stack_init(n_polyun_stack_t S);
1216 void n_polyun_stack_clear(n_polyun_stack_t S);
1217
1218 n_polyun_struct ** n_polyun_stack_fit_request(n_polyun_stack_t S, slong k);
1219
1220 FLINT_FORCE_INLINE
1221 n_polyun_struct ** n_polyun_stack_request(n_polyun_stack_t S, slong k)
1222 {
1223 n_polyun_struct ** polyun_top;
1224 polyun_top = n_polyun_stack_fit_request(S, k);
1225 S->top += k;
1226 return polyun_top;
1227 }
1228
1229 FLINT_FORCE_INLINE
1230 n_polyun_struct * n_polyun_stack_take_top(n_polyun_stack_t S)
1231 {
1232
1233 n_polyun_struct ** polyun_top;
1234 FLINT_ASSERT(S->top + 1 <= S->alloc);
1235 polyun_top = S->array + S->top;
1236 S->top += 1;
1237 return polyun_top[0];
1238 }
1239
1240 FLINT_FORCE_INLINE
1241 void n_polyun_stack_give_back(n_polyun_stack_t S, slong k)
1242 {
1243 FLINT_ASSERT(S->top >= k);
1244 S->top -= k;
1245 }
1246
1247 FLINT_FORCE_INLINE
1248 slong n_polyun_stack_size(const n_polyun_stack_t S)
1249 {
1250 return S->top;
1251 }
1252
1253 #if !defined(FQ_NMOD_H)
1254 # undef fq_nmod_ctx_degree
1255 #endif
1256
1257 #ifdef __cplusplus
1258 }
1259 #endif
1260
1261 #endif