Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:15:14

0001 /*
0002     Copyright (C) 2020 Daniel Schultz
0003 
0004     This file is part of FLINT.
0005 
0006     FLINT is free software: you can redistribute it and/or modify it under
0007     the terms of the GNU Lesser General Public License (LGPL) as published
0008     by the Free Software Foundation; either version 3 of the License, or
0009     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
0010 */
0011 
0012 #ifndef FMPZ_MOD_MPOLY_FACTOR_H
0013 #define FMPZ_MOD_MPOLY_FACTOR_H
0014 
0015 #ifdef FMPZ_MOD_MPOLY_FACTOR_INLINES_C
0016 #define FMPZ_MOD_MPOLY_FACTOR_INLINE
0017 #else
0018 #define FMPZ_MOD_MPOLY_FACTOR_INLINE static inline
0019 #endif
0020 
0021 #include "fmpz_mod_poly.h"
0022 #include "fmpz_mod_mpoly.h"
0023 
0024 #ifdef __cplusplus
0025 extern "C" {
0026 #endif
0027 
0028 FMPZ_MOD_MPOLY_FACTOR_INLINE
0029 void fmpz_mod_mpoly_factor_init(fmpz_mod_mpoly_factor_t f,
0030                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0031 {
0032     fmpz_init_set_ui(f->constant, 1);
0033     f->poly  = NULL;
0034     f->exp   = NULL;
0035     f->num   = 0;
0036     f->alloc = 0;
0037 }
0038 
0039 void fmpz_mod_mpoly_factor_init2(fmpz_mod_mpoly_factor_t f,
0040                                   slong alloc, const fmpz_mod_mpoly_ctx_t ctx);
0041 
0042 void fmpz_mod_mpoly_factor_realloc(fmpz_mod_mpoly_factor_t f,
0043                                   slong alloc, const fmpz_mod_mpoly_ctx_t ctx);
0044 
0045 void fmpz_mod_mpoly_factor_fit_length(fmpz_mod_mpoly_factor_t f,
0046                                     slong len, const fmpz_mod_mpoly_ctx_t ctx);
0047 
0048 void fmpz_mod_mpoly_factor_clear(fmpz_mod_mpoly_factor_t f,
0049                                                const fmpz_mod_mpoly_ctx_t ctx);
0050 
0051 FMPZ_MOD_MPOLY_FACTOR_INLINE
0052 slong fmpz_mod_mpoly_factor_length(const fmpz_mod_mpoly_factor_t f,
0053                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0054 {
0055     return f->num;
0056 }
0057 
0058 FMPZ_MOD_MPOLY_FACTOR_INLINE
0059 void fmpz_mod_mpoly_factor_get_constant_fmpz(fmpz_t c,
0060                const fmpz_mod_mpoly_factor_t f, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0061 {
0062     fmpz_set(c, f->constant);
0063 }
0064 
0065 FMPZ_MOD_MPOLY_FACTOR_INLINE
0066 void fmpz_mod_mpoly_factor_get_base(fmpz_mod_mpoly_t p,
0067      const fmpz_mod_mpoly_factor_t f, slong i, const fmpz_mod_mpoly_ctx_t ctx)
0068 {
0069     FLINT_ASSERT(i < (ulong) f->num);
0070     fmpz_mod_mpoly_set(p, f->poly + i, ctx);
0071 }
0072 
0073 FMPZ_MOD_MPOLY_FACTOR_INLINE
0074 void fmpz_mod_mpoly_factor_swap_base(fmpz_mod_mpoly_t p,
0075             fmpz_mod_mpoly_factor_t f, slong i, const fmpz_mod_mpoly_ctx_t ctx)
0076 {
0077     FLINT_ASSERT(i < (ulong) f->num);
0078     fmpz_mod_mpoly_swap(p, f->poly + i, ctx);
0079 }
0080 
0081 FMPZ_MOD_MPOLY_FACTOR_INLINE
0082 slong fmpz_mod_mpoly_factor_get_exp_si(fmpz_mod_mpoly_factor_t f,
0083                                        slong i, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0084 {
0085     FLINT_ASSERT(i < (ulong) f->num);
0086     return fmpz_get_si(f->exp + i);
0087 }
0088 
0089 FMPZ_MOD_MPOLY_FACTOR_INLINE
0090 void fmpz_mod_mpoly_factor_swap(fmpz_mod_mpoly_factor_t f,
0091                      fmpz_mod_mpoly_factor_t g, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0092 {
0093    fmpz_mod_mpoly_factor_struct t = *f;
0094    *f = *g;
0095    *g = t;
0096 }
0097 
0098 void fmpz_mod_mpoly_factor_set(fmpz_mod_mpoly_factor_t f,
0099               const fmpz_mod_mpoly_factor_t g, const fmpz_mod_mpoly_ctx_t ctx);
0100 
0101 void fmpz_mod_mpoly_factor_print_pretty(const fmpz_mod_mpoly_factor_t f,
0102                            const char ** vars, const fmpz_mod_mpoly_ctx_t ctx);
0103 
0104 int fmpz_mod_mpoly_factor_content(fmpz_mod_mpoly_factor_t f,
0105                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0106 
0107 int fmpz_mod_mpoly_factor_squarefree(fmpz_mod_mpoly_factor_t f,
0108                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0109 
0110 int fmpz_mod_mpoly_factor(fmpz_mod_mpoly_factor_t f,
0111                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0112 
0113 void fmpz_mod_mpoly_factor_sort(fmpz_mod_mpoly_factor_t f,
0114                                                const fmpz_mod_mpoly_ctx_t ctx);
0115 
0116 int fmpz_mod_mpoly_factor_cmp(const fmpz_mod_mpoly_factor_t A,
0117               const fmpz_mod_mpoly_factor_t B, const fmpz_mod_mpoly_ctx_t ctx);
0118 
0119 /******************************************************************************
0120 
0121    Internal functions (guaranteed to change without notice)
0122 
0123 ******************************************************************************/
0124 
0125 /* fmpz_mod_poly extras ******************************************************/
0126 
0127 FMPZ_MOD_MPOLY_FACTOR_INLINE
0128 slong _fmpz_mod_poly_degree(const fmpz_mod_poly_t a)
0129 {
0130     return a->length - 1;
0131 }
0132 
0133 void fmpz_mod_poly_scalar_addmul_fmpz_mod(fmpz_mod_poly_t A,
0134            const fmpz_mod_poly_t B, const fmpz_mod_poly_t C, const fmpz_t d0,
0135                                                      const fmpz_mod_ctx_t ctx);
0136 
0137 void fmpz_mod_poly_addmul_linear(fmpz_mod_poly_t A,
0138                     const fmpz_mod_poly_t B, const fmpz_mod_poly_t C,
0139                    const fmpz_t d1, const fmpz_t d0, const fmpz_mod_ctx_t ctx);
0140 
0141 void fmpz_mod_poly_shift_left_scalar_addmul_fmpz_mod(
0142          fmpz_mod_poly_t A, slong k, const fmpz_t c, const fmpz_mod_ctx_t ctx);
0143 
0144 void fmpz_mod_poly_eval_pow(fmpz_t eval, const fmpz_mod_poly_t P,
0145                            fmpz_mod_poly_t alphapow, const fmpz_mod_ctx_t ctx);
0146 
0147 void fmpz_mod_poly_eval2_pow(fmpz_t evalp, fmpz_t evalm,
0148                             const fmpz_mod_poly_t P, fmpz_mod_poly_t alphapow,
0149                                                      const fmpz_mod_ctx_t ctx);
0150 
0151 /* fmpz_mod_mat extras *******************************************************/
0152 
0153 int fmpz_mod_mat_is_reduced(const fmpz_mod_mat_t N, const fmpz_mod_ctx_t ctx);
0154 
0155 void fmpz_mod_mat_init_nullspace_tr(fmpz_mod_mat_t X,
0156                                  fmpz_mod_mat_t tmp, const fmpz_mod_ctx_t ctx);
0157 
0158 /*****************************************************************************/
0159 
0160 typedef struct
0161 {
0162     fmpz_mod_poly_struct * coeffs;
0163     slong alloc;
0164     slong length;
0165 } fmpz_mod_bpoly_struct;
0166 
0167 typedef fmpz_mod_bpoly_struct fmpz_mod_bpoly_t[1];
0168 
0169 
0170 typedef struct
0171 {
0172     fmpz_mod_bpoly_struct * coeffs;
0173     slong alloc;
0174     slong length;
0175 } fmpz_mod_tpoly_struct;
0176 
0177 typedef fmpz_mod_tpoly_struct fmpz_mod_tpoly_t[1];
0178 
0179 
0180 typedef struct
0181 {
0182     ulong * exps;
0183     fmpz * coeffs;
0184     slong length;
0185     slong alloc;
0186 } fmpz_mod_polyu_struct;
0187 
0188 typedef fmpz_mod_polyu_struct fmpz_mod_polyu_t[1];
0189 
0190 
0191 typedef struct
0192 {
0193     fmpz_mod_poly_struct * coeffs;
0194     ulong * exps;
0195     slong alloc;
0196     slong length;
0197 } fmpz_mod_polyun_struct;
0198 
0199 typedef fmpz_mod_polyun_struct fmpz_mod_polyun_t[1];
0200 
0201 /*
0202     fmpz_mod_mpolyu_t
0203     sparse univariates with fmpz_mod_mpoly_t coefficients
0204         with uniform bits and LEX ordering
0205 */
0206 typedef struct
0207 {
0208    fmpz_mod_mpoly_struct * coeffs;
0209    ulong * exps;
0210    slong alloc;
0211    slong length;
0212    flint_bitcnt_t bits;    /* default bits to construct coeffs */
0213 } fmpz_mod_mpolyu_struct;
0214 typedef fmpz_mod_mpolyu_struct fmpz_mod_mpolyu_t[1];
0215 
0216 /*
0217     fmpz_mod_mpolyn_t
0218     sparse multivariates with fmpz_mod_poly_t coefficients
0219         with LEX ordering
0220 */
0221 typedef struct
0222 {
0223    fmpz_mod_poly_struct * coeffs;
0224    ulong * exps;
0225    slong alloc;
0226    slong length;
0227    slong bits;
0228 } fmpz_mod_mpolyn_struct;
0229 
0230 typedef fmpz_mod_mpolyn_struct fmpz_mod_mpolyn_t[1];
0231 
0232 /*****************************************************************************/
0233 
0234 int fmpz_mod_mpoly_factor_separable(fmpz_mod_mpoly_factor_t f,
0235             const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx, int sep);
0236 
0237 int fmpz_mod_mpoly_factor_expand(fmpz_mod_mpoly_t A,
0238               const fmpz_mod_mpoly_factor_t f, const fmpz_mod_mpoly_ctx_t ctx);
0239 
0240 FMPZ_MOD_MPOLY_FACTOR_INLINE
0241 int fmpz_mod_mpoly_factor_matches(const fmpz_mod_mpoly_t a,
0242                const fmpz_mod_mpoly_factor_t f, const fmpz_mod_mpoly_ctx_t ctx)
0243 {
0244     int matches;
0245     fmpz_mod_mpoly_t t;
0246     fmpz_mod_mpoly_init(t, ctx);
0247     fmpz_mod_mpoly_factor_expand(t, f, ctx);
0248     matches = fmpz_mod_mpoly_equal(t, a, ctx);
0249     fmpz_mod_mpoly_clear(t, ctx);
0250     return matches;
0251 }
0252 
0253 FMPZ_MOD_MPOLY_FACTOR_INLINE
0254 void fmpz_mod_mpoly_factor_append_fmpz_swap(fmpz_mod_mpoly_factor_t f,
0255             fmpz_mod_mpoly_t A, const fmpz_t e, const fmpz_mod_mpoly_ctx_t ctx)
0256 {
0257     slong i = f->num;
0258     fmpz_mod_mpoly_factor_fit_length(f, i + 1, ctx);
0259     fmpz_mod_mpoly_swap(f->poly + i, A, ctx);
0260     fmpz_set(f->exp + i, e);
0261     f->num = i + 1;
0262 }
0263 
0264 FMPZ_MOD_MPOLY_FACTOR_INLINE
0265 void fmpz_mod_mpoly_factor_one(fmpz_mod_mpoly_factor_t f,
0266                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0267 {
0268     fmpz_one(f->constant);
0269     f->num = 0;
0270 }
0271 
0272 void _fmpz_mod_mpoly_get_lead0(
0273     fmpz_mod_mpoly_t c,
0274     const fmpz_mod_mpoly_t A,
0275     const fmpz_mod_mpoly_ctx_t ctx);
0276 
0277 void _fmpz_mod_mpoly_set_lead0(
0278     fmpz_mod_mpoly_t A,
0279     const fmpz_mod_mpoly_t B,
0280     const fmpz_mod_mpoly_t c,
0281     const fmpz_mod_mpoly_ctx_t ctx);
0282 
0283 /*****************************************************************************/
0284 
0285 void _fmpz_mod_mpoly_factor_set_nmod_mpoly_factor(
0286     fmpz_mod_mpoly_factor_t f,
0287     const fmpz_mod_mpoly_ctx_t ctx,
0288     const nmod_mpoly_factor_t nf,
0289     const nmod_mpoly_ctx_t nctx);
0290 
0291 
0292 /* stack *********************************************************************/
0293 
0294 typedef struct
0295 {
0296     fmpz_mod_poly_struct ** array;
0297     slong alloc;
0298     slong top;
0299 } fmpz_mod_poly_stack_struct;
0300 
0301 typedef fmpz_mod_poly_stack_struct fmpz_mod_poly_stack_t[1];
0302 
0303 
0304 typedef struct
0305 {
0306     fmpz_mod_bpoly_struct ** array;
0307     slong alloc;
0308     slong top;
0309 } fmpz_mod_bpoly_stack_struct;
0310 
0311 typedef fmpz_mod_bpoly_stack_struct fmpz_mod_bpoly_stack_t[1];
0312 
0313 typedef struct
0314 {
0315     fmpz_mod_polyun_struct ** array;
0316     slong alloc;
0317     slong top;
0318 } fmpz_mod_polyun_stack_struct;
0319 
0320 typedef fmpz_mod_polyun_stack_struct fmpz_mod_polyun_stack_t[1];
0321 
0322 typedef struct
0323 {
0324     fmpz_mod_mpolyn_struct ** array;
0325     slong alloc;
0326     slong top;
0327     flint_bitcnt_t bits;
0328 } fmpz_mod_mpolyn_stack_struct;
0329 
0330 typedef fmpz_mod_mpolyn_stack_struct fmpz_mod_mpolyn_stack_t[1];
0331 
0332 typedef struct {
0333     fmpz_mod_poly_stack_t poly_stack;
0334     fmpz_mod_bpoly_stack_t bpoly_stack;
0335 } fmpz_mod_poly_bpoly_stack_struct;
0336 
0337 typedef fmpz_mod_poly_bpoly_stack_struct fmpz_mod_poly_bpoly_stack_t[1];
0338 
0339 typedef struct {
0340     fmpz_mod_poly_stack_t poly_stack;
0341     fmpz_mod_polyun_stack_t polyun_stack;
0342 } fmpz_mod_poly_polyun_stack_struct;
0343 
0344 typedef fmpz_mod_poly_polyun_stack_struct fmpz_mod_poly_polyun_stack_t[1];
0345 
0346 typedef struct {
0347     fmpz_mod_poly_stack_t poly_stack;
0348     fmpz_mod_polyun_stack_t polyun_stack;
0349     fmpz_mod_mpolyn_stack_t mpolyn_stack;
0350 } fmpz_mod_poly_polyun_mpolyn_stack_struct;
0351 
0352 typedef fmpz_mod_poly_polyun_mpolyn_stack_struct
0353                                        fmpz_mod_poly_polyun_mpolyn_stack_t[1];
0354 
0355 void fmpz_mod_poly_stack_init(fmpz_mod_poly_stack_t S);
0356 
0357 void fmpz_mod_poly_stack_clear(fmpz_mod_poly_stack_t S);
0358 
0359 fmpz_mod_poly_struct ** fmpz_mod_poly_stack_fit_request(
0360                                              fmpz_mod_poly_stack_t S, slong k);
0361 
0362 FMPZ_MOD_MPOLY_INLINE
0363 fmpz_mod_poly_struct ** fmpz_mod_poly_stack_request(
0364                                               fmpz_mod_poly_stack_t S, slong k)
0365 {
0366     fmpz_mod_poly_struct ** poly_top;
0367     poly_top = fmpz_mod_poly_stack_fit_request(S, k);
0368     S->top += k;
0369     return poly_top;
0370 }
0371 
0372 FMPZ_MOD_MPOLY_INLINE
0373 fmpz_mod_poly_struct * fmpz_mod_poly_stack_take_top(fmpz_mod_poly_stack_t S)
0374 {
0375     /* assume the request for 1 has already been fitted */
0376     fmpz_mod_poly_struct ** poly_top;
0377     FLINT_ASSERT(S->top + 1 <= S->alloc);
0378     poly_top = S->array + S->top;
0379     S->top += 1;
0380     return poly_top[0];
0381 }
0382 
0383 FMPZ_MOD_MPOLY_INLINE
0384 void fmpz_mod_poly_stack_give_back(fmpz_mod_poly_stack_t S, slong k)
0385 {
0386     FLINT_ASSERT(S->top >= k);
0387     S->top -= k;
0388 }
0389 
0390 FMPZ_MOD_MPOLY_INLINE
0391 slong fmpz_mod_poly_stack_size(const fmpz_mod_poly_stack_t S)
0392 {
0393     return S->top;
0394 }
0395 
0396 void fmpz_mod_bpoly_stack_init(fmpz_mod_bpoly_stack_t S);
0397 
0398 void fmpz_mod_bpoly_stack_clear(fmpz_mod_bpoly_stack_t S);
0399 
0400 fmpz_mod_bpoly_struct ** fmpz_mod_bpoly_stack_fit_request(
0401                                             fmpz_mod_bpoly_stack_t S, slong k);
0402 
0403 FMPZ_MOD_MPOLY_INLINE
0404 fmpz_mod_bpoly_struct ** fmpz_mod_bpoly_stack_request(
0405                                              fmpz_mod_bpoly_stack_t S, slong k)
0406 {
0407     fmpz_mod_bpoly_struct ** bpoly_top;
0408     bpoly_top = fmpz_mod_bpoly_stack_fit_request(S, k);
0409     S->top += k;
0410     return bpoly_top;
0411 }
0412 
0413 FMPZ_MOD_MPOLY_INLINE
0414 fmpz_mod_bpoly_struct * fmpz_mod_bpoly_stack_take_top(fmpz_mod_bpoly_stack_t S)
0415 {
0416     /* assume the request for 1 has already been fitted */
0417     fmpz_mod_bpoly_struct ** bpoly_top;
0418     FLINT_ASSERT(S->top + 1 <= S->alloc);
0419     bpoly_top = S->array + S->top;
0420     S->top += 1;
0421     return bpoly_top[0];
0422 }
0423 
0424 FMPZ_MOD_MPOLY_INLINE
0425 void fmpz_mod_bpoly_stack_give_back(fmpz_mod_bpoly_stack_t S, slong k)
0426 {
0427     FLINT_ASSERT(S->top >= k);
0428     S->top -= k;
0429 }
0430 
0431 FMPZ_MOD_MPOLY_INLINE
0432 slong fmpz_mod_bpoly_stack_size(const fmpz_mod_bpoly_stack_t S)
0433 {
0434     return S->top;
0435 }
0436 
0437 
0438 void fmpz_mod_polyun_stack_init(fmpz_mod_polyun_stack_t S);
0439 
0440 void fmpz_mod_polyun_stack_clear(fmpz_mod_polyun_stack_t S);
0441 
0442 fmpz_mod_polyun_struct ** fmpz_mod_polyun_stack_fit_request(
0443                                            fmpz_mod_polyun_stack_t S, slong k);
0444 
0445 FMPZ_MOD_MPOLY_INLINE
0446 fmpz_mod_polyun_struct ** fmpz_mod_polyun_stack_request(
0447                                             fmpz_mod_polyun_stack_t S, slong k)
0448 {
0449     fmpz_mod_polyun_struct ** polyun_top;
0450     polyun_top = fmpz_mod_polyun_stack_fit_request(S, k);
0451     S->top += k;
0452     return polyun_top;
0453 }
0454 
0455 FMPZ_MOD_MPOLY_INLINE
0456 fmpz_mod_polyun_struct * fmpz_mod_polyun_stack_take_top(fmpz_mod_polyun_stack_t S)
0457 {
0458     /* assume the request for 1 has already been fitted */
0459     fmpz_mod_polyun_struct ** polyun_top;
0460     FLINT_ASSERT(S->top + 1 <= S->alloc);
0461     polyun_top = S->array + S->top;
0462     S->top += 1;
0463     return polyun_top[0];
0464 }
0465 
0466 FMPZ_MOD_MPOLY_INLINE
0467 void fmpz_mod_polyun_stack_give_back(fmpz_mod_polyun_stack_t S, slong k)
0468 {
0469     FLINT_ASSERT(S->top >= k);
0470     S->top -= k;
0471 }
0472 
0473 FMPZ_MOD_MPOLY_INLINE
0474 slong fmpz_mod_polyun_stack_size(const fmpz_mod_polyun_stack_t S)
0475 {
0476     return S->top;
0477 }
0478 
0479 
0480 
0481 void fmpz_mod_mpolyn_stack_init(fmpz_mod_mpolyn_stack_t S,
0482                           flint_bitcnt_t bits, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
0483 
0484 void fmpz_mod_mpolyn_stack_clear(fmpz_mod_mpolyn_stack_t S,
0485                                                const fmpz_mod_mpoly_ctx_t ctx);
0486 
0487 fmpz_mod_mpolyn_struct ** fmpz_mod_mpolyn_stack_fit_request(
0488            fmpz_mod_mpolyn_stack_t S, slong k, const fmpz_mod_mpoly_ctx_t ctx);
0489 
0490 FMPZ_MOD_MPOLY_INLINE
0491 fmpz_mod_mpolyn_struct ** fmpz_mod_mpolyn_stack_request(
0492             fmpz_mod_mpolyn_stack_t S, slong k, const fmpz_mod_mpoly_ctx_t ctx)
0493 {
0494     fmpz_mod_mpolyn_struct ** mpolyn_top;
0495     mpolyn_top = fmpz_mod_mpolyn_stack_fit_request(S, k, ctx);
0496     S->top += k;
0497     return mpolyn_top;
0498 }
0499 
0500 FMPZ_MOD_MPOLY_INLINE
0501 fmpz_mod_mpolyn_struct * fmpz_mod_mpolyn_stack_take_top(fmpz_mod_mpolyn_stack_t S)
0502 {
0503     /* assume the request for 1 has already been fitted */
0504     fmpz_mod_mpolyn_struct ** mpolyn_top;
0505     FLINT_ASSERT(S->top + 1 <= S->alloc);
0506     mpolyn_top = S->array + S->top;
0507     S->top += 1;
0508     return mpolyn_top[0];
0509 }
0510 
0511 FMPZ_MOD_MPOLY_INLINE
0512 void fmpz_mod_mpolyn_stack_give_back(fmpz_mod_mpolyn_stack_t S, slong k)
0513 {
0514     FLINT_ASSERT(S->top >= k);
0515     S->top -= k;
0516 }
0517 
0518 FMPZ_MOD_MPOLY_INLINE
0519 slong fmpz_mod_mpolyn_stack_size(const fmpz_mod_mpolyn_stack_t S)
0520 {
0521     return S->top;
0522 }
0523 
0524 /* poly_vec ******************************************************************/
0525 
0526 slong _fmpz_mod_poly_vec_max_degree(const fmpz_mod_poly_struct * A,
0527                                          slong Alen, const fmpz_mod_ctx_t ctx);
0528 
0529 void _fmpz_mod_poly_vec_content(fmpz_mod_poly_t g,
0530          const fmpz_mod_poly_struct * A, slong Alen, const fmpz_mod_ctx_t ctx);
0531 
0532 void _fmpz_mod_poly_vec_remove_content(fmpz_mod_poly_t g,
0533                fmpz_mod_poly_struct * A, slong Alen, const fmpz_mod_ctx_t ctx);
0534 
0535 void _fmpz_mod_poly_vec_mul_poly(fmpz_mod_poly_struct * A,
0536                 slong Alen, const fmpz_mod_poly_t g, const fmpz_mod_ctx_t ctx);
0537 
0538 void _fmpz_mod_poly_vec_divexact_poly(fmpz_mod_poly_struct * A,
0539                 slong Alen, const fmpz_mod_poly_t g, const fmpz_mod_ctx_t ctx);
0540 
0541 void _fmpz_mod_poly_vec_mul_fmpz_mod(fmpz_mod_poly_struct * A,
0542                          slong Alen, const fmpz_t g, const fmpz_mod_ctx_t ctx);
0543 
0544 /* polyun ********************************************************************/
0545 
0546 FMPZ_MOD_MPOLY_FACTOR_INLINE
0547 ulong fmpz_mod_polyu1n_bidegree(const fmpz_mod_polyun_t A)
0548 {
0549     ulong x, y;
0550     FLINT_ASSERT(A->length > 0);
0551     x = A->exps[0];
0552     y = A->coeffs[0].length - 1;
0553     return (x << (FLINT_BITS/2)) + y;
0554 }
0555 
0556 FMPZ_MOD_MPOLY_FACTOR_INLINE
0557 const fmpz * fmpz_mod_polyun_leadcoeff(const fmpz_mod_polyun_t A)
0558 {
0559     FLINT_ASSERT(A->length > 0);
0560     FLINT_ASSERT(A->coeffs[0].length > 0);
0561     return A->coeffs[0].coeffs + A->coeffs[0].length - 1;
0562 }
0563 
0564 
0565 FMPZ_MOD_MPOLY_FACTOR_INLINE
0566 void fmpz_mod_polyun_swap(fmpz_mod_polyun_t A, fmpz_mod_polyun_t B)
0567 {
0568     fmpz_mod_polyun_struct t = *A;
0569     *A = *B;
0570     *B = t;
0571 }
0572 
0573 int fmpz_mod_polyun_is_canonical(const fmpz_mod_polyun_t A,
0574                                                     const fmpz_mod_ctx_t ctx);
0575 
0576 FMPZ_MOD_MPOLY_INLINE
0577 void fmpz_mod_polyun_init(fmpz_mod_polyun_t A, const fmpz_mod_ctx_t FLINT_UNUSED(ctx))
0578 {
0579     A->length = 0;
0580     A->alloc = 0;
0581     A->coeffs = NULL;
0582     A->exps = NULL;
0583 }
0584 
0585 void fmpz_mod_polyun_clear(fmpz_mod_polyun_t A, const fmpz_mod_ctx_t ctx);
0586 
0587 void fmpz_mod_polyun_realloc(fmpz_mod_polyun_t A,
0588                                           slong len, const fmpz_mod_ctx_t ctx);
0589 
0590 void fmpz_mod_polyu2n_print_pretty(const fmpz_mod_polyun_t A,
0591                 const char * var0, const char * var1, const char * varlast,
0592                                                      const fmpz_mod_ctx_t ctx);
0593 
0594 int fmpz_mod_polyun_equal(fmpz_mod_polyun_t A,
0595                           const fmpz_mod_polyun_t B, const fmpz_mod_ctx_t ctx);
0596 
0597 void fmpz_mod_polyun_set(fmpz_mod_polyun_t A,
0598                           const fmpz_mod_polyun_t B, const fmpz_mod_ctx_t ctx);
0599 
0600 void fmpz_mod_polyu3n_print_pretty( const fmpz_mod_polyun_t A,
0601                     const char * var0, const char * var1, const char * var2,
0602                                const char * varlast, const fmpz_mod_ctx_t ctx);
0603 
0604 void fmpz_mod_polyu1n_print_pretty(const fmpz_mod_polyun_t A,
0605             const char * var0, const char * varlast, const fmpz_mod_ctx_t ctx);
0606 
0607 FMPZ_MOD_MPOLY_INLINE
0608 void fmpz_mod_polyun_fit_length(fmpz_mod_polyun_t A, slong len,
0609                                                       const fmpz_mod_ctx_t ctx)
0610 {
0611     if (len > A->alloc)
0612         fmpz_mod_polyun_realloc(A, len, ctx);
0613 }
0614 
0615 void fmpz_mod_polyun_one(fmpz_mod_polyun_t A, const fmpz_mod_ctx_t ctx);
0616 
0617 void fmpz_mod_mpoly_get_polyu1n(fmpz_mod_polyun_t A,
0618                             const fmpz_mod_mpoly_t B, slong varx, slong vary,
0619                                                const fmpz_mod_mpoly_ctx_t ctx);
0620 
0621 void fmpz_mod_mpoly_set_polyu1n(fmpz_mod_mpoly_t B,
0622                             const fmpz_mod_polyun_t A, slong varx, slong vary,
0623                                                const fmpz_mod_mpoly_ctx_t ctx);
0624 
0625 /* mpolyn ********************************************************************/
0626 
0627 void fmpz_mod_mpolyn_init(fmpz_mod_mpolyn_t A, flint_bitcnt_t bits,
0628                                                const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
0629 
0630 FMPZ_MOD_MPOLY_INLINE void fmpz_mod_mpolyn_swap(fmpz_mod_mpolyn_t A,
0631                            fmpz_mod_mpolyn_t B, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0632 {
0633    fmpz_mod_mpolyn_struct t = *A;
0634    *A = *B;
0635    *B = t;
0636 }
0637 
0638 void fmpz_mod_mpolyn_fit_length(fmpz_mod_mpolyn_t A,
0639                                  slong length, const fmpz_mod_mpoly_ctx_t ctx);
0640 
0641 FMPZ_MOD_MPOLY_FACTOR_INLINE
0642 const fmpz * fmpz_mod_mpolyn_leadcoeff(const fmpz_mod_mpolyn_t A)
0643 {
0644     FLINT_ASSERT(A->length > 0);
0645     FLINT_ASSERT(A->coeffs[0].length > 0);
0646     return A->coeffs[0].coeffs + A->coeffs[0].length - 1;
0647 }
0648 
0649 int fmpz_mod_mpolyn_is_canonical(const fmpz_mod_mpolyn_t A,
0650                                                const fmpz_mod_mpoly_ctx_t ctx);
0651 
0652 slong fmpz_mod_mpolyn_lastdeg(const fmpz_mod_mpolyn_t A,
0653                                                const fmpz_mod_mpoly_ctx_t ctx);
0654 
0655 void fmpz_mod_mpolyn_clear(fmpz_mod_mpolyn_t A,
0656                                                const fmpz_mod_mpoly_ctx_t ctx);
0657 
0658 void fmpz_mod_mpolyn_one(fmpz_mod_mpolyn_t A,
0659                                                const fmpz_mod_mpoly_ctx_t ctx);
0660 
0661 void fmpz_mod_mpolyn_scalar_mul_fmpz_mod(fmpz_mod_mpolyn_t A,
0662                                const fmpz_t c, const fmpz_mod_mpoly_ctx_t ctx);
0663 
0664 int fmpz_mod_mpolyn_equal(const fmpz_mod_mpolyn_t A,
0665                    const fmpz_mod_mpolyn_t B, const fmpz_mod_mpoly_ctx_t ctx);
0666 
0667 void fmpz_mod_mpolyn_print_pretty(const fmpz_mod_mpolyn_t poly,
0668                               const char ** x, const fmpz_mod_mpoly_ctx_t ctx);
0669 
0670 void fmpz_mod_mpoly_cvtfrom_mpolyn(
0671     fmpz_mod_mpoly_t A,
0672     const fmpz_mod_mpolyn_t B,
0673     slong var,
0674     const fmpz_mod_mpoly_ctx_t ctx);
0675 
0676 void fmpz_mod_mpoly_cvtto_mpolyn(
0677     fmpz_mod_mpolyn_t A,
0678     const fmpz_mod_mpoly_t B,
0679     slong var,
0680     const fmpz_mod_mpoly_ctx_t ctx);
0681 
0682 void fmpz_mod_mpoly_to_mpolyn_perm_deflate(
0683     fmpz_mod_mpolyn_t A,
0684     const fmpz_mod_mpoly_ctx_t nctx,
0685     const fmpz_mod_mpoly_t B,
0686     const fmpz_mod_mpoly_ctx_t ctx,
0687     const slong * perm,
0688     const ulong * shift,
0689     const ulong * stride);
0690 
0691 void fmpz_mod_mpoly_from_mpolyn_perm_inflate(
0692     fmpz_mod_mpoly_t A,
0693     flint_bitcnt_t Abits,
0694     const fmpz_mod_mpoly_ctx_t ctx,
0695     const fmpz_mod_mpolyn_t B,
0696     const fmpz_mod_mpoly_ctx_t nctx,
0697     const slong * perm,
0698     const ulong * shift,
0699     const ulong * stride);
0700 
0701 void fmpz_mod_mpolyn_set(
0702     fmpz_mod_mpolyn_t A,
0703     const fmpz_mod_mpolyn_t B,
0704     const fmpz_mod_mpoly_ctx_t ctx);
0705 
0706 int fmpz_mod_mpolyn_is_nonzero_fmpz(
0707     const fmpz_mod_mpolyn_t A,
0708     const fmpz_mod_mpoly_ctx_t ctx);
0709 
0710 int fmpz_mod_mpolyn_divides(
0711     fmpz_mod_mpolyn_t Q,
0712     const fmpz_mod_mpolyn_t A,
0713     const fmpz_mod_mpolyn_t B,
0714     const fmpz_mod_mpoly_ctx_t ctx);
0715 
0716 /* interp ********************************************************************/
0717 
0718 void fmpz_mod_polyu1n_interp_reduce_2sm_poly(
0719     fmpz_mod_poly_t E,
0720     fmpz_mod_poly_t F,
0721     const fmpz_mod_polyun_t A,
0722     fmpz_mod_poly_t alphapow,
0723     const fmpz_mod_ctx_t ctx);
0724 
0725 void fmpz_mod_polyu1n_interp_lift_2sm_poly(
0726     slong * lastdeg,
0727     fmpz_mod_polyun_t F,
0728     const fmpz_mod_poly_t A,
0729     const fmpz_mod_poly_t B,
0730     const fmpz_t alpha,
0731     const fmpz_mod_ctx_t ctx);
0732 
0733 int fmpz_mod_polyu1n_interp_crt_2sm_poly(
0734     slong * lastdeg,
0735     fmpz_mod_polyun_t F,
0736     fmpz_mod_polyun_t T,
0737     const fmpz_mod_poly_t A,
0738     const fmpz_mod_poly_t B,
0739     const fmpz_mod_poly_t modulus,
0740     fmpz_mod_poly_t alphapow,
0741     const fmpz_mod_ctx_t ctx);
0742 
0743 void fmpz_mod_mpolyn_interp_reduce_sm_poly(
0744     fmpz_mod_poly_t E,
0745     const fmpz_mod_mpolyn_t A,
0746     const fmpz_t alpha,
0747     const fmpz_mod_mpoly_ctx_t ctx);
0748 
0749 void fmpz_mod_mpolyn_interp_lift_sm_poly(
0750     fmpz_mod_mpolyn_t A,
0751     const fmpz_mod_poly_t B,
0752     const fmpz_mod_mpoly_ctx_t ctx);
0753 
0754 int fmpz_mod_mpolyn_interp_crt_sm_poly(
0755     slong * lastdeg_,
0756     fmpz_mod_mpolyn_t F,
0757     fmpz_mod_mpolyn_t T,
0758     const fmpz_mod_poly_t A,
0759     const fmpz_mod_poly_t modulus,
0760     const fmpz_t alpha,
0761     const fmpz_mod_mpoly_ctx_t ctx);
0762 
0763 void fmpz_mod_mpolyn_interp_reduce_2sm_mpolyn(
0764     fmpz_mod_mpolyn_t E,
0765     fmpz_mod_mpolyn_t F,
0766     fmpz_mod_mpolyn_t A,
0767     slong var,
0768     fmpz_mod_poly_t alphapow,
0769     const fmpz_mod_mpoly_ctx_t ctx);
0770 
0771 void fmpz_mod_mpolyn_interp_lift_2sm_mpolyn(
0772     slong * lastdeg,
0773     fmpz_mod_mpolyn_t T,
0774     fmpz_mod_mpolyn_t A,
0775     fmpz_mod_mpolyn_t B,
0776     slong var,
0777     const fmpz_t alpha,
0778     const fmpz_mod_mpoly_ctx_t ctx);
0779 
0780 int fmpz_mod_mpolyn_interp_crt_2sm_mpolyn(
0781     slong * lastdeg,
0782     fmpz_mod_mpolyn_t F,
0783     fmpz_mod_mpolyn_t T,
0784     fmpz_mod_mpolyn_t A,
0785     fmpz_mod_mpolyn_t B,
0786     slong var,
0787     fmpz_mod_poly_t modulus,
0788     fmpz_mod_poly_t alphapow,
0789     const fmpz_mod_mpoly_ctx_t ctx);
0790 
0791 void fmpz_mod_mpolyn_interp_lift_sm_mpoly(
0792     fmpz_mod_mpolyn_t A,
0793     const fmpz_mod_mpoly_t B,
0794     const fmpz_mod_mpoly_ctx_t ctx);
0795 
0796 int fmpz_mod_mpolyn_interp_crt_sm_mpoly(
0797     slong * lastdeg,
0798     fmpz_mod_mpolyn_t F,
0799     fmpz_mod_mpolyn_t T,
0800     fmpz_mod_mpoly_t A,
0801     fmpz_mod_poly_t modulus,
0802     fmpz_mod_poly_t alphapow,
0803     const fmpz_mod_mpoly_ctx_t ctx);
0804 
0805 int fmpz_mod_mpolyn_interp_mcrt_sm_mpoly(
0806     slong * lastdeg,
0807     fmpz_mod_mpolyn_t F,
0808     const fmpz_mod_mpoly_t A,
0809     const fmpz_mod_poly_t modulus,
0810     fmpz_mod_poly_t alphapow,
0811     const fmpz_mod_mpoly_ctx_t ctx);
0812 
0813 
0814 /* polyu *********************************************************************/
0815 
0816 FMPZ_MOD_MPOLY_FACTOR_INLINE
0817 void fmpz_mod_polyu_swap(
0818     fmpz_mod_polyu_t A,
0819     fmpz_mod_polyu_t B)
0820 {
0821     fmpz_mod_polyu_struct t = *A;
0822     *A = *B;
0823     *B = t;
0824 }
0825 
0826 void fmpz_mod_polyu_init(fmpz_mod_polyu_t A);
0827 
0828 void fmpz_mod_polyu_clear(fmpz_mod_polyu_t A);
0829 
0830 void fmpz_mod_polyu_realloc(fmpz_mod_polyu_t A, slong len);
0831 
0832 FMPZ_MOD_MPOLY_FACTOR_INLINE
0833 void fmpz_mod_polyu_fit_length(
0834     fmpz_mod_polyu_t a,
0835     slong len,
0836     const fmpz_mod_ctx_t FLINT_UNUSED(ctx))
0837 {
0838     if (len > a->alloc)
0839         fmpz_mod_polyu_realloc(a, len);
0840 }
0841 
0842 void fmpz_mod_polyu3_degrees(
0843     slong * deg0,
0844     slong * deg1,
0845     slong * deg2,
0846     const fmpz_mod_polyu_t A);
0847 
0848 void fmpz_mod_polyu3_print_pretty(
0849     const fmpz_mod_polyu_t A,
0850     const char * var0,
0851     const char * var1,
0852     const char * var2,
0853     const fmpz_mod_ctx_t FLINT_UNUSED(ctx));
0854 
0855 /* mpolyu ********************************************************************/
0856 
0857 int fmpz_mod_mpolyu_is_canonical(const fmpz_mod_mpolyu_t A,
0858                                                const fmpz_mod_mpoly_ctx_t ctx);
0859 
0860 void fmpz_mod_mpolyu3_print_pretty(const fmpz_mod_mpolyu_t A,
0861                     const char * var0, const char * var1, const char * var2,
0862                            const char ** vars, const fmpz_mod_mpoly_ctx_t ctx);
0863 
0864 
0865 /* bpoly *********************************************************************/
0866 
0867 int fmpz_mod_bpoly_is_canonical(const fmpz_mod_bpoly_t A,
0868                                                      const fmpz_mod_ctx_t ctx);
0869 
0870 FMPZ_MOD_MPOLY_FACTOR_INLINE
0871 void fmpz_mod_bpoly_init(fmpz_mod_bpoly_t A, const fmpz_mod_ctx_t FLINT_UNUSED(ctx))
0872 {
0873     A->coeffs = NULL;
0874     A->alloc = 0;
0875     A->length = 0;
0876 }
0877 
0878 void fmpz_mod_bpoly_clear(fmpz_mod_bpoly_t A, const fmpz_mod_ctx_t ctx);
0879 
0880 FMPZ_MOD_MPOLY_FACTOR_INLINE
0881 void fmpz_mod_bpoly_swap(fmpz_mod_bpoly_t A, fmpz_mod_bpoly_t B,
0882                                                       const fmpz_mod_ctx_t FLINT_UNUSED(ctx))
0883 {
0884     fmpz_mod_bpoly_struct t = *A;
0885     *A = *B;
0886     *B = t;
0887 }
0888 
0889 
0890 FMPZ_MOD_MPOLY_FACTOR_INLINE
0891 void fmpz_mod_bpoly_get_coeff(fmpz_t c, const fmpz_mod_bpoly_t A,
0892                                   slong e0, slong e1, const fmpz_mod_ctx_t ctx)
0893 {
0894     if (e0 >= A->length)
0895         fmpz_zero(c);
0896     else
0897         fmpz_mod_poly_get_coeff_fmpz(c, A->coeffs + e0, e1, ctx);
0898 }
0899 
0900 
0901 FMPZ_MOD_MPOLY_FACTOR_INLINE
0902 slong fmpz_mod_bpoly_degree0(const fmpz_mod_bpoly_t A, const fmpz_mod_ctx_t FLINT_UNUSED(ctx))
0903 {
0904     return A->length - 1;
0905 }
0906 
0907 FMPZ_MOD_MPOLY_FACTOR_INLINE
0908 void fmpz_mod_bpoly_normalise(fmpz_mod_bpoly_t A, const fmpz_mod_ctx_t ctx)
0909 {
0910     while (A->length > 0 && fmpz_mod_poly_is_zero(A->coeffs + A->length - 1, ctx))
0911         A->length--;
0912 }
0913 
0914 int fmpz_mod_bpoly_equal(
0915     const fmpz_mod_bpoly_t A,
0916     const fmpz_mod_bpoly_t B,
0917     const fmpz_mod_ctx_t ctx);
0918 
0919 void fmpz_mod_bpoly_set(
0920     fmpz_mod_bpoly_t A,
0921     const fmpz_mod_bpoly_t B,
0922     const fmpz_mod_ctx_t ctx);
0923 
0924 
0925 void fmpz_mod_bpoly_set_poly_gen1(
0926     fmpz_mod_bpoly_t A,
0927     const fmpz_mod_poly_t B,
0928     const fmpz_mod_ctx_t ctx);
0929 
0930 
0931 void fmpz_mod_bpoly_set_poly_gen0(
0932     fmpz_mod_bpoly_t A,
0933     const fmpz_mod_poly_t B,
0934     const fmpz_mod_ctx_t ctx);
0935 
0936 void fmpz_mod_bpoly_one(fmpz_mod_bpoly_t A, const fmpz_mod_ctx_t ctx);
0937 
0938 FMPZ_MOD_MPOLY_FACTOR_INLINE
0939 int fmpz_mod_bpoly_is_one(const fmpz_mod_bpoly_t A, const fmpz_mod_ctx_t ctx)
0940 {
0941     return A->length == 1 && fmpz_mod_poly_is_one(A->coeffs + 0, ctx);
0942 }
0943 
0944 slong fmpz_mod_bpoly_degree1(const fmpz_mod_bpoly_t A,
0945                                                      const fmpz_mod_ctx_t FLINT_UNUSED(ctx));
0946 
0947 void fmpz_mod_bpoly_print_pretty(const fmpz_mod_bpoly_t A,
0948                const char * xvar, const char * yvar, const fmpz_mod_ctx_t ctx);
0949 
0950 void fmpz_mod_bpoly_fit_length(fmpz_mod_bpoly_t A, slong len,
0951                                                      const fmpz_mod_ctx_t ctx);
0952 
0953 void fmpz_mod_bpoly_set_coeff(fmpz_mod_bpoly_t A, slong xi, slong yi,
0954                                      const fmpz_t c, const fmpz_mod_ctx_t ctx);
0955 
0956 void fmpz_mod_bpoly_zero(fmpz_mod_bpoly_t A, const fmpz_mod_ctx_t FLINT_UNUSED(ctx));
0957 
0958 void fmpz_mod_bpoly_reverse_vars(fmpz_mod_bpoly_t A,
0959                            const fmpz_mod_bpoly_t B, const fmpz_mod_ctx_t ctx);
0960 
0961 void fmpz_mod_bpoly_taylor_shift_gen1(
0962     fmpz_mod_bpoly_t A,
0963     const fmpz_mod_bpoly_t B,
0964     const fmpz_t c,
0965     const fmpz_mod_ctx_t ctx);
0966 
0967 void fmpz_mod_bpoly_sub(
0968     fmpz_mod_bpoly_t A,
0969     const fmpz_mod_bpoly_t B,
0970     const fmpz_mod_bpoly_t C,
0971     const fmpz_mod_ctx_t ctx);
0972 
0973 void fmpz_mod_bpoly_add(
0974     fmpz_mod_bpoly_t A,
0975     const fmpz_mod_bpoly_t B,
0976     const fmpz_mod_bpoly_t C,
0977     const fmpz_mod_ctx_t ctx);
0978 
0979 void fmpz_mod_bpoly_make_primitive(
0980     fmpz_mod_poly_t g,
0981     fmpz_mod_bpoly_t A,
0982     const fmpz_mod_ctx_t ctx);
0983 
0984 void fmpz_mod_bpoly_mul(
0985     fmpz_mod_bpoly_t A,
0986     const fmpz_mod_bpoly_t B,
0987     const fmpz_mod_bpoly_t C,
0988     const fmpz_mod_ctx_t ctx);
0989 
0990 void fmpz_mod_bpoly_mul_series(
0991     fmpz_mod_bpoly_t A,
0992     const fmpz_mod_bpoly_t B,
0993     const fmpz_mod_bpoly_t C,
0994     slong order,
0995     const fmpz_mod_ctx_t ctx);
0996 
0997 void fmpz_mod_bpoly_divrem_series(
0998     fmpz_mod_bpoly_t Q,
0999     fmpz_mod_bpoly_t R,
1000     const fmpz_mod_bpoly_t A,
1001     const fmpz_mod_bpoly_t B,
1002     slong order,
1003     const fmpz_mod_ctx_t ctx);
1004 
1005 int fmpz_mod_bpoly_divides(
1006     fmpz_mod_bpoly_t Q,
1007     const fmpz_mod_bpoly_t A,
1008     const fmpz_mod_bpoly_t B,
1009     const fmpz_mod_ctx_t ctx);
1010 
1011 void fmpz_mod_bpoly_taylor_shift_gen0(
1012     fmpz_mod_bpoly_t A,
1013     const fmpz_t alpha,
1014     const fmpz_mod_ctx_t ctx);
1015 
1016 void fmpz_mod_bpoly_derivative_gen0(
1017     fmpz_mod_bpoly_t A,
1018     const fmpz_mod_bpoly_t B,
1019     const fmpz_mod_ctx_t ctx);
1020 
1021 void fmpz_mod_bpoly_make_monic_series(
1022     fmpz_mod_bpoly_t A,
1023     const fmpz_mod_bpoly_t B,
1024     slong order,
1025     const fmpz_mod_ctx_t ctx);
1026 
1027 
1028 FMPZ_MOD_MPOLY_INLINE
1029 void fmpz_mod_tpoly_init(fmpz_mod_tpoly_t A, const fmpz_mod_ctx_t FLINT_UNUSED(ctx))
1030 {
1031     A->coeffs = NULL;
1032     A->alloc = 0;
1033     A->length = 0;
1034 }
1035 
1036 FMPZ_MOD_MPOLY_INLINE
1037 void fmpz_mod_tpoly_swap(fmpz_mod_tpoly_t A, fmpz_mod_tpoly_t B,
1038                                                       const fmpz_mod_ctx_t FLINT_UNUSED(ctx))
1039 {
1040     fmpz_mod_tpoly_struct t = *A;
1041     *A = *B;
1042     *B = t;
1043 }
1044 
1045 void fmpz_mod_tpoly_fit_length(fmpz_mod_tpoly_t A, slong len,
1046                                                      const fmpz_mod_ctx_t ctx);
1047 
1048 void fmpz_mod_tpoly_clear(fmpz_mod_tpoly_t A, const fmpz_mod_ctx_t ctx);
1049 
1050 
1051 void fmpz_mod_mpoly_get_fmpz_mod_bpoly(fmpz_mod_bpoly_t A,
1052                             const fmpz_mod_mpoly_t B, slong var0, slong var1,
1053                                                const fmpz_mod_mpoly_ctx_t ctx);
1054 
1055 void fmpz_mod_mpoly_set_fmpz_mod_bpoly(fmpz_mod_mpoly_t A,
1056         flint_bitcnt_t Abits, const fmpz_mod_bpoly_t B, slong var0, slong var1,
1057                                                const fmpz_mod_mpoly_ctx_t ctx);
1058 
1059 int fmpz_mod_bpoly_factor_smprime(fmpz_mod_poly_t c,
1060                     fmpz_mod_tpoly_t F, fmpz_mod_bpoly_t B, int allow_shift,
1061                                                      const fmpz_mod_ctx_t ctx);
1062 
1063 /*****************************************************************************/
1064 
1065 int _fmpz_mod_zip_vand_solve(
1066     fmpz * coeffs,             /* in Fp: size mlength */
1067     const fmpz * monomials,    /* in Fp: size mlength */
1068     slong mlength,
1069     const fmpz * evals,        /* in Fp: size elength */
1070     slong elength,
1071     const fmpz * master,       /* in Fp: size mlength + 1 */
1072     fmpz * scratch,            /* in Fp: size mlength */
1073     const fmpz_mod_ctx_t ctx);
1074 
1075 void _fmpz_mod_zip_eval_step(
1076     fmpz_t ev,
1077     fmpz * cur,            /* in Fp */
1078     const fmpz * inc,      /* in Fp */
1079     const fmpz * coeffs,   /* in Fp */
1080     slong length,
1081     const fmpz_mod_ctx_t ctx);
1082 
1083 
1084 /*****************************************************************************/
1085 
1086 typedef struct
1087 {
1088     fmpz_mod_mpoly_struct * coeffs;
1089     slong alloc;
1090     slong length;
1091 } fmpz_mod_mpolyv_struct;
1092 
1093 typedef fmpz_mod_mpolyv_struct fmpz_mod_mpolyv_t[1];
1094 
1095 FMPZ_MOD_MPOLY_FACTOR_INLINE
1096 void fmpz_mod_mpolyv_init(fmpz_mod_mpolyv_t A, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
1097 {
1098     A->coeffs = NULL;
1099     A->alloc = 0;
1100     A->length = 0;
1101 }
1102 
1103 FMPZ_MOD_MPOLY_FACTOR_INLINE
1104 void fmpz_mod_mpolyv_swap(fmpz_mod_mpolyv_t A, fmpz_mod_mpolyv_t B,
1105                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
1106 {
1107    fmpz_mod_mpolyv_struct t = *A;
1108    *A = *B;
1109    *B = t;
1110 }
1111 
1112 void fmpz_mod_mpolyv_clear(fmpz_mod_mpolyv_t A,
1113                                                const fmpz_mod_mpoly_ctx_t ctx);
1114 
1115 void fmpz_mod_mpolyv_print_pretty(const fmpz_mod_mpolyv_t poly,
1116                               const char ** x, const fmpz_mod_mpoly_ctx_t ctx);
1117 
1118 void fmpz_mod_mpolyv_fit_length(fmpz_mod_mpolyv_t A, slong length,
1119                                                const fmpz_mod_mpoly_ctx_t ctx);
1120 
1121 void fmpz_mod_mpolyv_set_coeff(fmpz_mod_mpolyv_t A, slong i,
1122                            fmpz_mod_mpoly_t c, const fmpz_mod_mpoly_ctx_t ctx);
1123 
1124 void fmpz_mod_mpoly_to_mpolyv(fmpz_mod_mpolyv_t A,
1125                     const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_t xalpha,
1126                                                const fmpz_mod_mpoly_ctx_t ctx);
1127 
1128 void fmpz_mod_mpoly_from_mpolyv(fmpz_mod_mpoly_t A,
1129                  flint_bitcnt_t Abits, const fmpz_mod_mpolyv_t B,
1130                 const fmpz_mod_mpoly_t xalpha, const fmpz_mod_mpoly_ctx_t ctx);
1131 
1132 int _fmpz_mod_mpoly_vec_content_mpoly(fmpz_mod_mpoly_t g,
1133                                 const fmpz_mod_mpoly_struct * A, slong Alen,
1134                                               const fmpz_mod_mpoly_ctx_t ctx);
1135 
1136 void _fmpz_mod_mpoly_vec_divexact_mpoly(fmpz_mod_mpoly_struct * A,
1137          slong Alen, const fmpz_mod_mpoly_t c, const fmpz_mod_mpoly_ctx_t ctx);
1138 
1139 void _fmpz_mod_mpoly_vec_mul_mpoly(fmpz_mod_mpoly_struct * A,
1140          slong Alen, const fmpz_mod_mpoly_t c, const fmpz_mod_mpoly_ctx_t ctx);
1141 
1142 /*****************************************************************************/
1143 
1144 int _fmpz_mod_mpoly_factor_separable(fmpz_mod_mpoly_factor_t f,
1145             const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx, int sep);
1146 
1147 int fmpz_mod_mpoly_factor_lcc_wang(fmpz_mod_mpoly_struct * lc_divs,
1148              const fmpz_mod_mpoly_factor_t lcAfac, const fmpz_mod_poly_t Auc,
1149              const fmpz_mod_bpoly_struct * Auf, slong r,
1150            const fmpz_mod_poly_struct * alpha, const fmpz_mod_mpoly_ctx_t ctx);
1151 
1152 int fmpz_mod_mpoly_factor_irred_smprime_zassenhaus(
1153                             fmpz_mod_mpolyv_t fac, const fmpz_mod_mpoly_t A,
1154                            const fmpz_mod_mpoly_ctx_t ctx, flint_rand_t state);
1155 
1156 int fmpz_mod_mpoly_factor_irred_smprime_wang(fmpz_mod_mpolyv_t fac,
1157                 const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_factor_t lcAfac,
1158                 const fmpz_mod_mpoly_t lcA, const fmpz_mod_mpoly_ctx_t ctx,
1159                                                            flint_rand_t state);
1160 
1161 int fmpz_mod_mpoly_factor_irred_smprime_zippel(fmpz_mod_mpolyv_t fac,
1162                 const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_factor_t lcAfac,
1163                 const fmpz_mod_mpoly_t lcA, const fmpz_mod_mpoly_ctx_t ctx,
1164                                                            flint_rand_t state);
1165 
1166 /*****************************************************************************/
1167 
1168 void fmpz_mod_mpoly_compression_do(fmpz_mod_mpoly_t L,
1169                  const fmpz_mod_mpoly_ctx_t Lctx, fmpz * Acoeffs, slong Alen,
1170                                                         mpoly_compression_t M);
1171 
1172 void fmpz_mod_mpoly_compression_undo(fmpz_mod_mpoly_t A,
1173     flint_bitcnt_t Abits, const fmpz_mod_mpoly_ctx_t Actx, fmpz_mod_mpoly_t L,
1174                        const fmpz_mod_mpoly_ctx_t Lctx, mpoly_compression_t M);
1175 
1176 /*****************************************************************************/
1177 
1178 typedef struct {
1179     flint_bitcnt_t bits;
1180     slong w;
1181     slong r;
1182     fmpz_mod_poly_struct * inv_prod_dbetas;
1183     fmpz_mod_mpoly_struct * inv_prod_dbetas_mvar;
1184     fmpz_mod_poly_struct * dbetas;
1185     fmpz_mod_mpoly_struct * dbetas_mvar;
1186     fmpz_mod_mpoly_struct * prod_mbetas;
1187     fmpz_mod_mpolyv_struct * prod_mbetas_coeffs;
1188     fmpz_mod_mpoly_struct * mbetas;
1189     fmpz_mod_mpoly_struct * deltas;
1190     fmpz_mod_mpoly_struct * xalpha;
1191     fmpz_mod_mpoly_struct * q;
1192     fmpz_mod_mpoly_geobucket_struct * G;
1193     fmpz_mod_mpoly_struct * qt;
1194     fmpz_mod_mpoly_struct * newt;
1195     fmpz_mod_mpolyv_struct * delta_coeffs;
1196     fmpz_mod_mpoly_t T;
1197     fmpz_mod_mpoly_t Q;
1198     fmpz_mod_mpoly_t R;
1199 } fmpz_mod_mpoly_pfrac_struct;
1200 
1201 typedef fmpz_mod_mpoly_pfrac_struct fmpz_mod_mpoly_pfrac_t[1];
1202 
1203 
1204 int fmpz_mod_mpoly_pfrac_init(fmpz_mod_mpoly_pfrac_t Iv,
1205     flint_bitcnt_t bits, slong l, slong r, const fmpz_mod_mpoly_struct * betas,
1206                           const fmpz * alpha, const fmpz_mod_mpoly_ctx_t ctx);
1207 
1208 void fmpz_mod_mpoly_pfrac_clear(fmpz_mod_mpoly_pfrac_t Iv,
1209                                               const fmpz_mod_mpoly_ctx_t ctx);
1210 
1211 int fmpz_mod_mpoly_pfrac(slong r, fmpz_mod_mpoly_t t, const slong * deg,
1212                      fmpz_mod_mpoly_pfrac_t Iv, const fmpz_mod_mpoly_ctx_t ctx);
1213 
1214 int fmpz_mod_mpoly_hlift(slong m, fmpz_mod_mpoly_struct * f, slong r,
1215             const fmpz * alpha, const fmpz_mod_mpoly_t A, const slong * degs,
1216                                                const fmpz_mod_mpoly_ctx_t ctx);
1217 
1218 int fmpz_mod_bpoly_pfrac(slong r, fmpz_mod_bpoly_struct * C,
1219           slong * C_deg1_bound, fmpz_mod_bpoly_t A, fmpz_mod_bpoly_struct * B,
1220                                                      const fmpz_mod_ctx_t ctx);
1221 
1222 int fmpz_mod_bpoly_hlift2(fmpz_mod_bpoly_t A, fmpz_mod_bpoly_t B0,
1223                   fmpz_mod_bpoly_t B1, const fmpz_t alpha, slong degree_inner,
1224                      const fmpz_mod_ctx_t ctx, fmpz_mod_poly_bpoly_stack_t St);
1225 
1226 int fmpz_mod_bpoly_hlift(slong r, fmpz_mod_bpoly_t A,
1227            fmpz_mod_bpoly_struct * B, const fmpz_t alpha, slong degree_inner,
1228                      const fmpz_mod_ctx_t ctx, fmpz_mod_poly_bpoly_stack_t St);
1229 
1230 int fmpz_mod_polyu3_hlift(slong r, fmpz_mod_polyun_struct * BB,
1231               fmpz_mod_polyu_t A, fmpz_mod_polyu_struct * B, const fmpz_t beta,
1232                                  slong degree_inner, const fmpz_mod_ctx_t ctx);
1233 
1234 int fmpz_mod_mpoly_hlift_zippel(slong m, fmpz_mod_mpoly_struct * B,
1235      slong r, const fmpz * alpha, const fmpz_mod_mpoly_t A, const slong * degs,
1236                            const fmpz_mod_mpoly_ctx_t ctx, flint_rand_t state);
1237 
1238 int fmpz_mod_mpoly_factor_algo(fmpz_mod_mpoly_factor_t f,
1239                     const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx,
1240                                                             unsigned int algo);
1241 
1242 int fmpz_mod_mpoly_factor_zassenhaus(fmpz_mod_mpoly_factor_t f,
1243                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
1244 
1245 int fmpz_mod_mpoly_factor_wang(fmpz_mod_mpoly_factor_t f,
1246                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
1247 
1248 int fmpz_mod_mpoly_factor_zippel(fmpz_mod_mpoly_factor_t f,
1249                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
1250 
1251 int _fmpz_mod_mpoly_evaluate_rest_fmpz_mod_poly(fmpz_mod_poly_struct * E,
1252                 slong * starts, slong * ends, slong * stops, ulong * es,
1253                 const fmpz * Acoeffs, const ulong * Aexps, slong Alen, slong var,
1254                 const fmpz_mod_poly_struct * alphas,
1255                 const slong * offsets, const slong * shifts,
1256                    slong N, ulong mask, slong nvars, const fmpz_mod_ctx_t ctx);
1257 
1258 void _fmpz_mod_mpoly_eval_rest_to_fmpz_mod_bpoly(fmpz_mod_bpoly_t E,
1259              const fmpz_mod_mpoly_t A, const fmpz_mod_poly_struct * alphabetas,
1260                                                 const fmpz_mod_mpoly_ctx_t ctx);
1261 
1262 void _fmpz_mod_mpoly_set_fmpz_mod_bpoly_var1_zero(fmpz_mod_mpoly_t A,
1263                      flint_bitcnt_t Abits, const fmpz_mod_bpoly_t B, slong var,
1264                                                const fmpz_mod_mpoly_ctx_t ctx);
1265 
1266 /* gcd ***********************************************************************/
1267 
1268 int _fmpz_mod_mpoly_gcd_algo(fmpz_mod_mpoly_t G,
1269                             fmpz_mod_mpoly_t Abar, fmpz_mod_mpoly_t Bbar,
1270                             const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
1271                             const fmpz_mod_mpoly_ctx_t ctx, unsigned int algo);
1272 
1273 int fmpz_mod_polyu1n_gcd_brown_smprime(
1274     fmpz_mod_polyun_t G,
1275     fmpz_mod_polyun_t Abar,
1276     fmpz_mod_polyun_t Bbar,
1277     fmpz_mod_polyun_t A,
1278     fmpz_mod_polyun_t B,
1279     const fmpz_mod_ctx_t ctx,
1280     fmpz_mod_poly_stack_t St_poly,
1281     fmpz_mod_polyun_stack_t St_polyun);
1282 
1283 int fmpz_mod_mpolyn_gcd_brown_smprime(
1284     fmpz_mod_mpolyn_t G,
1285     fmpz_mod_mpolyn_t Abar,
1286     fmpz_mod_mpolyn_t Bbar,
1287     fmpz_mod_mpolyn_t A,
1288     fmpz_mod_mpolyn_t B,
1289     slong var,
1290     const fmpz_mod_mpoly_ctx_t ctx,
1291     const mpoly_gcd_info_t Iv,
1292     fmpz_mod_poly_polyun_mpolyn_stack_t St);
1293 
1294 int fmpz_mod_mpolyl_gcdp_zippel(
1295     fmpz_mod_mpoly_t G,
1296     fmpz_mod_mpoly_t Abar,
1297     fmpz_mod_mpoly_t Bbar,
1298     fmpz_mod_mpoly_t A,
1299     fmpz_mod_mpoly_t B,
1300     slong var,
1301     const fmpz_mod_mpoly_ctx_t ctx,
1302     flint_rand_t state);
1303 
1304 int fmpz_mod_mpolyl_gcd_zippel2_smprime(
1305     fmpz_mod_mpoly_t rG, const slong * rGdegs,
1306     fmpz_mod_mpoly_t rAbar,
1307     fmpz_mod_mpoly_t rBbar,
1308     const fmpz_mod_mpoly_t A, const slong * Adegs,
1309     const fmpz_mod_mpoly_t B, const slong * Bdegs,
1310     const fmpz_mod_mpoly_t gamma, const slong * gammadegs,
1311     const fmpz_mod_mpoly_ctx_t ctx);
1312 
1313 int fmpz_mod_mpolyl_gcd_hensel_smprime(
1314     fmpz_mod_mpoly_t G, slong Gdeg,
1315     fmpz_mod_mpoly_t Abar,
1316     fmpz_mod_mpoly_t Bbar,
1317     const fmpz_mod_mpoly_t A,
1318     const fmpz_mod_mpoly_t B,
1319     const fmpz_mod_mpoly_ctx_t ctx);
1320 
1321 /* pow_cache */
1322 
1323 void fmpz_mod_pow_cache_start(const fmpz_t b,
1324                                   fmpz_mod_poly_t c, const fmpz_mod_ctx_t ctx);
1325 
1326 void fmpz_mod_pow_cache_mulpow_ui(fmpz_t a, const fmpz_t b,
1327                          ulong e, fmpz_mod_poly_t c, const fmpz_mod_ctx_t ctx);
1328 
1329 /* zip helpers */
1330 
1331 void mpoly_monomial_evals_fmpz_mod(
1332     fmpz_mod_poly_t EH,
1333     const ulong * Aexps, slong Alen, flint_bitcnt_t Abits,
1334     fmpz_mod_poly_struct * alpha_caches,
1335     slong start,
1336     slong stop,
1337     const mpoly_ctx_t mctx,
1338     const fmpz_mod_ctx_t fpctx);
1339 
1340 void mpoly1_monomial_evals_fmpz_mod(
1341     fmpz_mod_polyun_t EH,
1342     const ulong * Aexps, flint_bitcnt_t Abits,
1343     const ulong * Amarks, slong Amarkslen,
1344     fmpz_mod_poly_struct * alpha_caches,
1345     slong m,
1346     const mpoly_ctx_t mctx,
1347     const fmpz_mod_ctx_t fpctx);
1348 
1349 void mpoly2_monomial_evals_fmpz_mod(
1350     fmpz_mod_polyun_t EH,
1351     const ulong * Aexps, flint_bitcnt_t Abits,
1352     ulong * Amarks, slong Amarkslen,
1353     fmpz_mod_poly_struct * alpha_caches,
1354     slong m,
1355     const mpoly_ctx_t mctx,
1356     const fmpz_mod_ctx_t fpctx);
1357 
1358 void fmpz_mod_mpoly_mock_eval_coeff(
1359     fmpz_mod_polyun_t mock,
1360     const fmpz_mod_mpoly_t A,
1361     const fmpz_mod_polyun_t Aeh_inc,
1362     const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
1363 
1364 slong fmpz_mod_polyun_product_roots(
1365     fmpz_mod_polyun_t M,
1366     const fmpz_mod_polyun_t H,
1367     const fmpz_mod_ctx_t ctx);
1368 
1369 void fmpz_mod_polyun_zip_start(
1370     fmpz_mod_polyun_t Z,
1371     fmpz_mod_polyun_t H,
1372     slong req_images,
1373     const fmpz_mod_ctx_t fctx);
1374 
1375 void fmpz_mod_polyu2n_zip_eval_cur_inc_coeff(
1376     fmpz_mod_polyun_t E,
1377     fmpz_mod_polyun_t Acur,
1378     const fmpz_mod_polyun_t Ainc,
1379     const fmpz_mod_polyun_t Acoeff,
1380     const fmpz_mod_ctx_t ctx);
1381 
1382 int fmpz_mod_polyun_zip_solve(
1383     fmpz_mod_mpoly_t A,
1384     fmpz_mod_polyun_t Z,
1385     fmpz_mod_polyun_t H,
1386     fmpz_mod_polyun_t M,
1387     const fmpz_mod_mpoly_ctx_t ctx);
1388 
1389 #ifdef __cplusplus
1390 }
1391 #endif
1392 
1393 #endif