/* Copyright (C) 2020 Daniel Schultz This file is part of FLINT. FLINT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #ifndef NMOD_MPOLY_FACTOR_H #define NMOD_MPOLY_FACTOR_H #ifdef NMOD_MPOLY_FACTOR_INLINES_C #define NMOD_MPOLY_FACTOR_INLINE FLINT_DLL #else #define NMOD_MPOLY_FACTOR_INLINE static __inline__ #endif #undef ulong #define ulong ulongxx /* interferes with system includes */ #include #undef ulong #include #define ulong mp_limb_t #include "nmod_mpoly.h" #include "n_poly.h" #ifdef __cplusplus extern "C" { #endif FLINT_DLL void nmod_mpoly_get_bpoly(n_bpoly_t A, const nmod_mpoly_t B, slong var0, slong var1, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_set_bpoly(nmod_mpoly_t A, flint_bitcnt_t Abits, const n_bpoly_t B, slong var0, slong var1, const nmod_mpoly_ctx_t ctx); FLINT_DLL int n_bpoly_mod_factor_smprime( n_poly_t c, n_tpoly_t F, n_bpoly_t B, int allow_shift, nmod_t ctx); FLINT_DLL void n_bpoly_mod_factor_lgprime( n_poly_t c, n_tpoly_t F, n_bpoly_t B, nmod_t ctx); /*****************************************************************************/ FLINT_DLL int nmod_mat_is_reduced(const nmod_mat_t N); FLINT_DLL void nmod_mat_init_nullspace_tr(nmod_mat_t X, nmod_mat_t tmp); /*****************************************************************************/ typedef struct { mp_limb_t constant; nmod_mpoly_struct * poly; fmpz * exp; slong num; slong alloc; } nmod_mpoly_factor_struct; typedef nmod_mpoly_factor_struct nmod_mpoly_factor_t[1]; NMOD_MPOLY_FACTOR_INLINE void nmod_mpoly_factor_init(nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx) { f->constant = 1; f->poly = NULL; f->exp = NULL; f->num = 0; f->alloc = 0; } FLINT_DLL void nmod_mpoly_factor_init2(nmod_mpoly_factor_t f, slong alloc, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_factor_realloc(nmod_mpoly_factor_t f, slong alloc, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_factor_fit_length(nmod_mpoly_factor_t f, slong len, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_factor_clear(nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx); NMOD_MPOLY_FACTOR_INLINE slong nmod_mpoly_factor_length(const nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx) { return f->num; } NMOD_MPOLY_FACTOR_INLINE ulong nmod_mpoly_factor_get_constant_ui(const nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx) { return f->constant; } NMOD_MPOLY_FACTOR_INLINE void nmod_mpoly_factor_get_base(nmod_mpoly_t p, const nmod_mpoly_factor_t f, slong i, const nmod_mpoly_ctx_t ctx) { FLINT_ASSERT(i < (ulong) f->num); nmod_mpoly_set(p, f->poly + i, ctx); } NMOD_MPOLY_FACTOR_INLINE void nmod_mpoly_factor_swap_base(nmod_mpoly_t p, nmod_mpoly_factor_t f, slong i, const nmod_mpoly_ctx_t ctx) { FLINT_ASSERT(i < (ulong) f->num); nmod_mpoly_swap(p, f->poly + i, ctx); } NMOD_MPOLY_FACTOR_INLINE slong nmod_mpoly_factor_get_exp_si(nmod_mpoly_factor_t f, slong i, const nmod_mpoly_ctx_t ctx) { FLINT_ASSERT(i < (ulong) f->num); return fmpz_get_si(f->exp + i); } FLINT_DLL void nmod_mpoly_factor_append_ui(nmod_mpoly_factor_t f, const nmod_mpoly_t A, ulong e, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_factor_append_fmpz(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const fmpz_t e, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_factor_set(nmod_mpoly_factor_t f, const nmod_mpoly_factor_t g, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_factor_print_pretty(const nmod_mpoly_factor_t f, const char ** vars, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_content(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_squarefree(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_separable(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, int sep); FLINT_DLL int nmod_mpoly_factor(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_factor_sort(nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_cmp( const nmod_mpoly_factor_t A, const nmod_mpoly_factor_t B, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_expand(nmod_mpoly_t A, const nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx); NMOD_MPOLY_FACTOR_INLINE int nmod_mpoly_factor_matches(const nmod_mpoly_t a, const nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx) { int matches; nmod_mpoly_t t; nmod_mpoly_init(t, ctx); nmod_mpoly_factor_expand(t, f, ctx); matches = nmod_mpoly_equal(t, a, ctx); nmod_mpoly_clear(t, ctx); return matches; } FLINT_DLL int nmod_mpoly_factor_fix_units(nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx); NMOD_MPOLY_FACTOR_INLINE void nmod_mpoly_factor_swap(nmod_mpoly_factor_t f, nmod_mpoly_factor_t g, const nmod_mpoly_ctx_t ctx) { nmod_mpoly_factor_struct t = *f; *f = *g; *g = t; } NMOD_MPOLY_FACTOR_INLINE void nmod_mpoly_factor_one(nmod_mpoly_factor_t f, const nmod_mpoly_ctx_t ctx) { f->constant = 1; f->num = 0; } FLINT_DLL void _nmod_mpoly_get_lead0( nmod_mpoly_t c, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL void _nmod_mpoly_set_lead0( nmod_mpoly_t A, const nmod_mpoly_t B, const nmod_mpoly_t c, const nmod_mpoly_ctx_t ctx); /* n_poly_vec ****************************************************************/ FLINT_DLL slong _n_poly_vec_max_degree(const n_poly_struct * A, slong Alen); FLINT_DLL void _n_poly_vec_mul_nmod_intertible(n_poly_struct * A, slong Alen, mp_limb_t c, nmod_t ctx); FLINT_DLL void _n_poly_vec_mod_mul_poly(n_poly_struct * A, slong Alen, const n_poly_t g, const nmod_t ctx); FLINT_DLL void _n_poly_vec_mod_divexact_poly(n_poly_struct * A, slong Alen, const n_poly_t g, nmod_t ctx); FLINT_DLL void _n_poly_vec_mod_content(n_poly_t g, const n_poly_struct * A, slong Alen, nmod_t ctx); FLINT_DLL void _n_poly_vec_mod_remove_content(n_poly_t g, n_poly_struct * A, slong Alen, nmod_t ctx); /* polyun ********************************************************************/ FLINT_DLL void nmod_mpoly_get_polyu1n(n_polyun_t A, const nmod_mpoly_t B, slong varx, slong vary, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_set_polyu1n(nmod_mpoly_t B, const n_polyun_t A, slong varx, slong vary, const nmod_mpoly_ctx_t ctx); /*****************************************************************************/ typedef struct { nmod_mpoly_struct * coeffs; slong alloc; slong length; } nmod_mpolyv_struct; typedef nmod_mpolyv_struct nmod_mpolyv_t[1]; NMOD_MPOLY_FACTOR_INLINE void nmod_mpolyv_init(nmod_mpolyv_t A, const nmod_mpoly_ctx_t ctx) { A->coeffs = NULL; A->alloc = 0; A->length = 0; } NMOD_MPOLY_FACTOR_INLINE void nmod_mpolyv_swap(nmod_mpolyv_t A, nmod_mpolyv_t B, const nmod_mpoly_ctx_t ctx) { nmod_mpolyv_struct t = *A; *A = *B; *B = t; } FLINT_DLL void nmod_mpolyv_clear(nmod_mpolyv_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpolyv_print_pretty(const nmod_mpolyv_t poly, const char ** x, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpolyv_fit_length(nmod_mpolyv_t A, slong length, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpolyv_set_coeff(nmod_mpolyv_t A, slong i, nmod_mpoly_t c, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_to_mpolyv(nmod_mpolyv_t A, const nmod_mpoly_t B, const nmod_mpoly_t xalpha, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_from_mpolyv(nmod_mpoly_t A, flint_bitcnt_t Abits, const nmod_mpolyv_t B, const nmod_mpoly_t xalpha, const nmod_mpoly_ctx_t ctx); FLINT_DLL int _nmod_mpoly_vec_content_mpoly(nmod_mpoly_t g, const nmod_mpoly_struct * A, slong Alen, const nmod_mpoly_ctx_t ctx); FLINT_DLL void _nmod_mpoly_vec_divexact_mpoly(nmod_mpoly_struct * A, slong Alen, const nmod_mpoly_t c, const nmod_mpoly_ctx_t ctx); FLINT_DLL void _nmod_mpoly_vec_mul_mpoly(nmod_mpoly_struct * A, slong Alen, const nmod_mpoly_t c, const nmod_mpoly_ctx_t ctx); /*****************************************************************************/ FLINT_DLL int _nmod_mpoly_factor_separable(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, int sep); FLINT_DLL int nmod_mpoly_factor_lcc_wang(nmod_mpoly_struct * lc_divs, const nmod_mpoly_factor_t lcAfac, const n_poly_t Auc, const n_bpoly_struct * Auf, slong r, const n_poly_struct * alpha, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_irred_smprime_zassenhaus(nmod_mpolyv_t fac, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_medprime_zassenhaus(nmod_mpolyv_t fac, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_lgprime_zassenhaus(nmod_mpolyv_t fac, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_smprime_wang(nmod_mpolyv_t fac, const nmod_mpoly_t A, const nmod_mpoly_factor_t lcAfac, const nmod_mpoly_t lcA, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_medprime_wang(nmod_mpolyv_t Af, const nmod_mpoly_t A, const nmod_mpoly_factor_t lcAfac, const nmod_mpoly_t lcA, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_lgprime_wang(nmod_mpolyv_t Af, const nmod_mpoly_t A, const nmod_mpoly_factor_t lcAfac, const nmod_mpoly_t lcA, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_smprime_zippel(nmod_mpolyv_t fac, const nmod_mpoly_t A, const nmod_mpoly_factor_t lcAfac, const nmod_mpoly_t lcA, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_medprime_zippel(nmod_mpolyv_t Af, const nmod_mpoly_t A, const nmod_mpoly_factor_t lcAfac, const nmod_mpoly_t lcA, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_irred_lgprime_zippel(nmod_mpolyv_t Af, const nmod_mpoly_t A, const nmod_mpoly_factor_t lcAfac, const nmod_mpoly_t lcA, const nmod_mpoly_ctx_t ctx, flint_rand_t state); /*****************************************************************************/ FLINT_DLL void nmod_mpoly_compression_do(nmod_mpoly_t L, const nmod_mpoly_ctx_t Lctx, mp_limb_t * Acoeffs, slong Alen, mpoly_compression_t M); FLINT_DLL void nmod_mpoly_compression_undo(nmod_mpoly_t A, flint_bitcnt_t Abits, const nmod_mpoly_ctx_t Actx, nmod_mpoly_t L, const nmod_mpoly_ctx_t Lctx, mpoly_compression_t M); /*****************************************************************************/ FLINT_DLL int nmod_mpolyu_is_canonical(const nmod_mpolyu_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpolyu3_print_pretty(const nmod_mpolyu_t A, const char * var0, const char * var1, const char * var2, const char ** vars, const nmod_mpoly_ctx_t ctx); /*****************************************************************************/ typedef struct { flint_bitcnt_t bits; slong w; slong r; n_poly_struct * inv_prod_dbetas; nmod_mpoly_struct * inv_prod_dbetas_mvar; n_poly_struct * dbetas; nmod_mpoly_struct * dbetas_mvar; nmod_mpoly_struct * prod_mbetas; nmod_mpolyv_struct * prod_mbetas_coeffs; nmod_mpoly_struct * mbetas; nmod_mpoly_struct * deltas; nmod_mpoly_struct * xalpha; nmod_mpoly_struct * q; nmod_mpoly_geobucket_struct * G; nmod_mpoly_struct * qt; nmod_mpoly_struct * newt; nmod_mpolyv_struct * delta_coeffs; nmod_mpoly_t T; nmod_mpoly_t Q; nmod_mpoly_t R; } nmod_mpoly_pfrac_struct; typedef nmod_mpoly_pfrac_struct nmod_mpoly_pfrac_t[1]; FLINT_DLL int nmod_mpoly_pfrac_init(nmod_mpoly_pfrac_t I, flint_bitcnt_t bits, slong l, slong r, const nmod_mpoly_struct * betas, const mp_limb_t * alpha, const nmod_mpoly_ctx_t ctx); FLINT_DLL void nmod_mpoly_pfrac_clear(nmod_mpoly_pfrac_t I, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_pfrac(slong r, nmod_mpoly_t t, const slong * deg, nmod_mpoly_pfrac_t I, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_hlift(slong m, nmod_mpoly_struct * f, slong r, const mp_limb_t * alpha, const nmod_mpoly_t A, const slong * degs, const nmod_mpoly_ctx_t ctx); FLINT_DLL int n_bpoly_mod_pfrac(slong r, n_bpoly_struct * C, slong * C_deg1_bound, n_bpoly_t A, n_bpoly_struct * B, nmod_t mod); FLINT_DLL int n_bpoly_mod_hlift2(n_bpoly_t A, n_bpoly_t B0, n_bpoly_t B1, mp_limb_t alpha, slong degree_inner, nmod_t mod, n_poly_bpoly_stack_t St); FLINT_DLL int n_bpoly_mod_hlift2_cubic(n_bpoly_t A, n_bpoly_t B0, n_bpoly_t B1, mp_limb_t alpha, slong degree_inner, nmod_t ctx, nmod_eval_interp_t E, n_poly_bpoly_stack_t St); FLINT_DLL int n_bpoly_mod_hlift(slong r, n_bpoly_t A, n_bpoly_struct * B, mp_limb_t alpha, slong degree_inner, nmod_t mod, n_poly_bpoly_stack_t St); FLINT_DLL int n_bpoly_mod_hlift_cubic(slong r, n_bpoly_t A, n_bpoly_struct * B, mp_limb_t alpha, slong degree_inner, nmod_t mod, nmod_eval_interp_t E, n_poly_bpoly_stack_t St); FLINT_DLL int n_polyu3_mod_hlift(slong r, n_polyun_struct * BB, n_polyu_t A, n_polyu_struct * B, mp_limb_t beta, slong degree_inner, nmod_t ctx); FLINT_DLL int nmod_mpoly_hlift_zippel(slong m, nmod_mpoly_struct * B, slong r, const mp_limb_t * alpha, const nmod_mpoly_t A, const slong * degs, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpoly_factor_algo(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx, unsigned int algo); FLINT_DLL int nmod_mpoly_factor_zassenhaus(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_wang(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL int nmod_mpoly_factor_zippel(nmod_mpoly_factor_t f, const nmod_mpoly_t A, const nmod_mpoly_ctx_t ctx); FLINT_DLL int _nmod_mpoly_evaluate_rest_n_poly(n_poly_struct * E, slong * starts, slong * ends, slong * stops, ulong * es, const mp_limb_t * Acoeffs, const ulong * Aexps, slong Alen, slong var, const n_poly_struct * alphas, const slong * offsets, const slong * shifts, slong N, ulong mask, slong nvars, nmod_t ctx); FLINT_DLL void _nmod_mpoly_eval_rest_to_n_bpoly(n_bpoly_t E, const nmod_mpoly_t A, const n_poly_struct * alphabetas, const nmod_mpoly_ctx_t ctx); FLINT_DLL void _nmod_mpoly_set_n_bpoly_var1_zero(nmod_mpoly_t A, flint_bitcnt_t Abits, const n_bpoly_t B, slong var, const nmod_mpoly_ctx_t ctx); /* gcd ***********************************************************************/ FLINT_DLL int nmod_mpolyl_gcdp_zippel_smprime(nmod_mpoly_t G, nmod_mpoly_t Abar, nmod_mpoly_t Bbar, nmod_mpoly_t A, nmod_mpoly_t B, slong var, const nmod_mpoly_ctx_t ctx, flint_rand_t state); FLINT_DLL int nmod_mpolyl_gcds_zippel(nmod_mpoly_t G, const ulong * Gmarks, slong Gmarkslen, nmod_mpoly_t A, nmod_mpoly_t B, slong *perm, slong l, slong var, const nmod_mpoly_ctx_t ctx, flint_rand_t state, slong * Gdegbound, n_poly_t Amarks, n_poly_t Bmarks); /* zip helpers ***************************************************************/ FLINT_DLL void mpoly_monomial_evals_nmod(n_poly_t EH, const ulong * Aexps, slong Alen, flint_bitcnt_t Abits, n_poly_struct * alpha_caches, slong start, slong stop, const mpoly_ctx_t mctx, const nmod_t fpctx); FLINT_DLL void mpoly1_monomial_evals_nmod(n_polyun_t EH, const ulong * Aexps, flint_bitcnt_t Abits, const ulong * Amarks, slong Amarkslen, n_poly_struct * alpha_caches, slong m, const mpoly_ctx_t mctx, const nmod_t fpctx); FLINT_DLL void mpoly2_monomial_evals_nmod(n_polyun_t EH, const ulong * Aexps, flint_bitcnt_t Abits, ulong * Amarks, slong Amarkslen, n_poly_struct * alpha_caches, slong m, const mpoly_ctx_t mctx, const nmod_t fpctx); FLINT_DLL void n_polyun_zip_start(n_polyun_t Z, n_polyun_t H, slong req_images); FLINT_DLL int n_polyu2n_add_zip_must_match(n_polyun_t Z, const n_bpoly_t A, slong cur_length); FLINT_DLL int n_polyun_zip_solve(nmod_mpoly_t A, n_polyun_t Z, n_polyun_t H, n_polyun_t M, const nmod_mpoly_ctx_t ctx); #ifdef __cplusplus } #endif #endif