Skip to content

Commit 1abbff9

Browse files
authored
Naive Buchberger algorithm for fmpz_mod_mpoly (#2445)
* Added naive Buchberger to fmpz_mod_mpoly * Added get_set fmpz to fmpz_mod_mpoly
1 parent eb0f43a commit 1abbff9

15 files changed

+1381
-0
lines changed

doc/source/fmpz_mod_mpoly.rst

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,126 @@ Univariate Functions
628628
Try to set *D* to the discriminant of *Ax*.
629629

630630

631+
Vectors
632+
--------------------------------------------------------------------------------
633+
634+
.. type:: fmpz_mod_mpoly_vec_struct
635+
636+
.. type:: fmpz_mod_mpoly_vec_t
637+
638+
A type holding a vector of :type:`fmpz_mod_mpoly_t`.
639+
640+
.. macro:: fmpz_mod_mpoly_vec_entry(vec, i)
641+
642+
Macro for accessing the entry at position *i* in *vec*.
643+
644+
.. function:: void fmpz_mod_mpoly_vec_init(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx)
645+
646+
Initializes *vec* to a vector of length *len*, setting all entries to the zero polynomial.
647+
648+
.. function:: void fmpz_mod_mpoly_vec_clear(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_ctx_t ctx)
649+
650+
Clears *vec*, freeing its allocated memory.
651+
652+
.. function:: void fmpz_mod_mpoly_vec_print(const fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_ctx_t ctx)
653+
654+
Prints *vec* to standard output.
655+
656+
.. function:: void fmpz_mod_mpoly_vec_swap(fmpz_mod_mpoly_vec_t x, fmpz_mod_mpoly_vec_t y, const fmpz_mod_mpoly_ctx_t ctx)
657+
658+
Swaps *x* and *y* efficiently.
659+
660+
.. function:: void fmpz_mod_mpoly_vec_fit_length(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx)
661+
662+
Allocates room for *len* entries in *vec*.
663+
664+
.. function:: void fmpz_mod_mpoly_vec_set(fmpz_mod_mpoly_vec_t dest, const fmpz_mod_mpoly_vec_t src, const fmpz_mod_mpoly_ctx_t ctx)
665+
666+
Sets *dest* to a copy of *src*.
667+
668+
.. function:: void fmpz_mod_mpoly_vec_append(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx)
669+
670+
Appends *f* to the end of *vec*.
671+
672+
.. function:: slong fmpz_mod_mpoly_vec_insert_unique(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx)
673+
674+
Inserts *f* without duplication into *vec* and returns its index.
675+
If this polynomial already exists, *vec* is unchanged. If this
676+
polynomial does not exist in *vec*, it is appended.
677+
678+
.. function:: void fmpz_mod_mpoly_vec_set_length(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx)
679+
680+
Sets the length of *vec* to *len*, truncating or zero-extending
681+
as needed.
682+
683+
.. function:: void fmpz_mod_mpoly_vec_randtest_not_zero(fmpz_mod_mpoly_vec_t vec, flint_rand_t state, slong len, slong poly_len, ulong exp_bound, fmpz_mod_mpoly_ctx_t ctx)
684+
685+
Sets *vec* to a random vector with exactly *len* entries, all nonzero,
686+
with random parameters defined by *poly_len* and *exp_bound*.
687+
688+
689+
Ideals and Gröbner bases
690+
-------------------------------------------------------------------------------
691+
692+
The following methods deal with ideals in `\mathbb{Z}/n\mathbb{Z}[x_1, \dots, x_m]`.
693+
We use monic polynomials as normalised generators.
694+
695+
.. function:: void fmpz_mod_mpoly_spoly(fmpz_mod_mpoly_t res, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_t g, const fmpz_mod_mpoly_ctx_t ctx)
696+
697+
Sets *res* to the *S*-polynomial of *f* and *g*, scaled by making *f* and *g* monic first.
698+
699+
.. function:: void fmpz_mod_mpoly_reduction_monic_part(fmpz_mod_mpoly_t res, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_ctx_t ctx)
700+
701+
Sets *res* to the monic remainder of multivariate
702+
division with remainder with respect to the polynomials *vec*.
703+
704+
.. function:: int fmpz_mod_mpoly_vec_is_groebner(const fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx)
705+
706+
If *F* is *NULL*, checks if *G* is a Gröbner basis. If *F* is not *NULL*,
707+
checks if *G* is a Gröbner basis for *F*.
708+
709+
.. function:: int fmpz_mod_mpoly_vec_is_autoreduced(const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx)
710+
711+
Checks whether the vector *F* is autoreduced (or inter-reduced).
712+
713+
.. function:: void fmpz_mod_mpoly_vec_autoreduction(fmpz_mod_mpoly_vec_t H, const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx)
714+
715+
Sets *H* to the autoreduction (inter-reduction) of *F*.
716+
717+
.. function:: void fmpz_mod_mpoly_vec_autoreduction_groebner(fmpz_mod_mpoly_vec_t H, const fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_ctx_t ctx)
718+
719+
Sets *H* to the autoreduction (inter-reduction) of *G*.
720+
Assumes that *G* is a Gröbner basis.
721+
This produces a reduced Gröbner basis, which is unique
722+
(up to the sort order of the entries in the vector).
723+
724+
.. function:: void fmpz_mod_mpoly_buchberger_naive(fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx)
725+
726+
Sets *G* to a Gröbner basis for *F*, computed using
727+
a naive implementation of Buchberger's algorithm.
728+
729+
.. function:: int fmpz_mod_mpoly_buchberger_naive_with_limits(fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_vec_t F, slong ideal_len_limit, slong poly_len_limit, const fmpz_mod_mpoly_ctx_t ctx)
730+
731+
As :func:`fmpz_mod_mpoly_buchberger_naive`, but halts if during the
732+
execution of Buchberger's algorithm the length of the
733+
ideal basis set exceeds *ideal_len_limit*, or the length of any
734+
polynomial exceeds *poly_len_limit*.
735+
Returns 1 for success and 0 for failure. On failure, *G* is
736+
a valid basis for *F* but it might not be a Gröbner basis.
737+
738+
739+
Converting to/from other polynomial types
740+
-------------------------------------------------------------------------------
741+
742+
.. function:: void fmpz_mod_mpoly_set_fmpz_mpoly(fmpz_mod_mpoly_t A, const fmpz_mpoly_t B, const fmpz_mod_mpoly_ctx_t ctxm, const fmpz_mpoly_ctx_t ctx)
743+
744+
Sets :type:`fmpz_mod_mpoly_t` *A* to :type:`fmpz_mpoly_t` *B* with coefficients modulo the modulus in *ctxm*.
745+
746+
.. function:: void fmpz_mod_mpoly_get_fmpz_mpoly(fmpz_mpoly_t A, const fmpz_mod_mpoly_t B, const fmpz_mpoly_ctx_t ctx)
747+
748+
Sets :type:`fmpz_mpoly_t` *A* to the :type:`fmpz_mod_mpoly_t` *B*.
749+
750+
631751
Internal Functions
632752
--------------------------------------------------------------------------------
633753

src/fmpz_mod_mpoly.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ void fmpz_mod_mpoly_divrem_ideal_monagan_pearce(
678678
const fmpz_mod_mpoly_t A, fmpz_mod_mpoly_struct * const * B, slong len,
679679
const fmpz_mod_mpoly_ctx_t ctx);
680680

681+
681682
/* Square root ***************************************************************/
682683

683684
int fmpz_mod_mpoly_sqrt_heap(fmpz_mod_mpoly_t Q,
@@ -711,6 +712,9 @@ int fmpz_mod_mpoly_quadratic_root(fmpz_mod_mpoly_t Q,
711712
void fmpz_mod_mpoly_term_content(fmpz_mod_mpoly_t M,
712713
const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
713714

715+
void fmpz_mod_mpoly_monic_part(fmpz_mod_mpoly_t res,
716+
const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx);
717+
714718
int fmpz_mod_mpoly_content_vars(fmpz_mod_mpoly_t g,
715719
const fmpz_mod_mpoly_t A, slong * vars, slong vars_length,
716720
const fmpz_mod_mpoly_ctx_t ctx);
@@ -947,6 +951,67 @@ void fmpz_mod_mpoly_from_mpolyl_perm_inflate(fmpz_mod_mpoly_t A,
947951
const slong * perm, const ulong * shift, const ulong * stride);
948952

949953

954+
/* Vectors of multivariate polynomials */
955+
956+
typedef struct
957+
{
958+
fmpz_mod_mpoly_struct * p;
959+
slong alloc;
960+
slong length;
961+
}
962+
fmpz_mod_mpoly_vec_struct;
963+
964+
typedef fmpz_mod_mpoly_vec_struct fmpz_mod_mpoly_vec_t[1];
965+
966+
#define fmpz_mod_mpoly_vec_entry(vec, i) ((vec)->p + (i))
967+
968+
void fmpz_mod_mpoly_vec_init(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx);
969+
void fmpz_mod_mpoly_vec_print(const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
970+
void fmpz_mod_mpoly_vec_swap(fmpz_mod_mpoly_vec_t x, fmpz_mod_mpoly_vec_t y, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
971+
void fmpz_mod_mpoly_vec_fit_length(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx);
972+
void fmpz_mod_mpoly_vec_clear(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_ctx_t ctx);
973+
void fmpz_mod_mpoly_vec_set(fmpz_mod_mpoly_vec_t dest, const fmpz_mod_mpoly_vec_t src, const fmpz_mod_mpoly_ctx_t ctx);
974+
void fmpz_mod_mpoly_vec_append(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx);
975+
slong fmpz_mod_mpoly_vec_insert_unique(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx);
976+
void fmpz_mod_mpoly_vec_set_length(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx);
977+
void fmpz_mod_mpoly_vec_randtest_not_zero(fmpz_mod_mpoly_vec_t vec, flint_rand_t state, slong len, slong poly_len, ulong exp_bound, fmpz_mod_mpoly_ctx_t ctx);
978+
979+
980+
/* Ideals and Groenber bases */
981+
982+
void fmpz_mod_mpoly_spoly(fmpz_mod_mpoly_t res,
983+
const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_t g, const fmpz_mod_mpoly_ctx_t ctx);
984+
985+
void fmpz_mod_mpoly_reduction_monic_part(fmpz_mod_mpoly_t res,
986+
const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_vec_t Iv, const fmpz_mod_mpoly_ctx_t ctx);
987+
988+
int fmpz_mod_mpoly_vec_is_groebner(const fmpz_mod_mpoly_vec_t G,
989+
const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
990+
991+
void fmpz_mod_mpoly_vec_set_monic_unique(fmpz_mod_mpoly_vec_t G,
992+
const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
993+
994+
int fmpz_mod_mpoly_buchberger_naive_with_limits(fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_vec_t F,
995+
slong ideal_len_limit, slong poly_len_limit, const fmpz_mod_mpoly_ctx_t ctx);
996+
997+
void fmpz_mod_mpoly_buchberger_naive(fmpz_mod_mpoly_vec_t G,
998+
const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
999+
1000+
int fmpz_mod_mpoly_vec_is_autoreduced(const fmpz_mod_mpoly_vec_t G,
1001+
const fmpz_mod_mpoly_ctx_t ctx);
1002+
1003+
void fmpz_mod_mpoly_vec_autoreduction_groebner(fmpz_mod_mpoly_vec_t H,
1004+
const fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_ctx_t ctx);
1005+
1006+
/* Convert to/from fmpz_mpoly */
1007+
1008+
void fmpz_mod_mpoly_set_fmpz_mpoly(fmpz_mod_mpoly_t res,
1009+
const fmpz_mpoly_t f, fmpz_mod_mpoly_ctx_t ctxm, fmpz_mpoly_ctx_t ctx);
1010+
1011+
void fmpz_mod_mpoly_get_fmpz_mpoly(fmpz_mpoly_t res,
1012+
const fmpz_mod_mpoly_t f, fmpz_mpoly_ctx_t ctx);
1013+
1014+
9501015
/******************************************************************************
9511016
9521017
Internal consistency checks

0 commit comments

Comments
 (0)