Skip to content

Added fmpz_mod_mpoly_q module #2327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

Added fmpz_mod_mpoly_q module #2327

wants to merge 17 commits into from

Conversation

andrii302
Copy link

In this fork I have written a module for rational polynomials on the mod some prime number field F. The functions and tests were created as an extension of fmpz_mpoly_q module but for the finite field F.

src/gr.h Outdated
@@ -698,7 +698,7 @@ void gr_method_tab_init(gr_funcptr * methods, gr_method_tab_input * tab);
typedef enum
{
GR_CTX_FMPZ, GR_CTX_FMPQ, GR_CTX_FMPZI,
GR_CTX_FMPZ_MOD, GR_CTX_NMOD, GR_CTX_NMOD8, GR_CTX_NMOD32, GR_CTX_MPN_MOD,
GR_CTX_FMPZ_MOD, GR_CTX_FMPZ_MOD_POLY, GR_FMPZ_MOD_MPOLY, GR_CTX_FMPZ_MOD_MPOLY_Q, GR_CTX_NMOD, GR_CTX_NMOD8, GR_CTX_NMOD32, GR_CTX_MPN_MOD,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should go further down, by the other polynomial types.

if (fmpz_mod_mpoly_is_zero(fmpz_mod_mpoly_q_denref(res), ctx))
return 0;

if (fmpz_sgn(fmpz_mod_mpoly_q_denref(res)->coeffs) < 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is redundant. The test for monic denominator below suffices.

ans_coeff = fmpz_mod_is_one(fmpz_mod_mpoly_q_denref(res)->coeffs + 0, ctx->ffinfo);
fmpz_mod_mpoly_clear(g, ctx);

return ans*ans_coeff;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just use && here.

/* Polynomial helper functions */

FMPZ_MOD_MPOLY_Q_INLINE void
_fmpz_vec_content2(fmpz_t res, const fmpz * vec, slong len, const fmpz_t inp)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function can be removed in favor of _fmpz_vec_content_chained (yes, I realize that it is copied from fmpz_mpoly_q.h where the same applies).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm confused about why this function is needed at all for fmpz_mod_mpoly_q. Surely extracting integer GCDs does nothing since we are over a field and normalize the denominator to be monic in the end?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct, I have just realized that I don't need gcd's for the coeff's at all. I am removing it from the code right now.

@andrii302
Copy link
Author

There's a new commit where I made all the requested changes, fixed the incorrect/missing _clear statements and got rid of any use of GCD for the coefficients.

fmpz_mod_mpoly_neg(fmpz_mod_mpoly_q_numref(res), fmpz_mod_mpoly_q_numref(res), ctx);
fmpz_mod_mpoly_neg(fmpz_mod_mpoly_q_denref(res), fmpz_mod_mpoly_q_denref(res), ctx);
}
fmpz_mod_mpoly_q_canonicalise(res, ctx);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need a full canonicalisation here, because you already know that the numerator and denominator are coprime. Just need to make the denominator monic.


fmpz_mod_mpoly_swap(fmpz_mod_mpoly_q_numref(res), fmpz_mod_mpoly_q_denref(res), ctx);

if (fmpz_sgn(fmpz_mod_mpoly_q_denref(res)->coeffs) < 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this should be if (!fmpz_is_one(fmpz_mod_mpoly_q_denref(res)->coeffs)) ... make monic.

{
fmpz_mod_mpoly_print_pretty(fmpz_mod_mpoly_q_numref(f), x, ctx);
}
else if (fmpz_mod_mpoly_is_fmpz(fmpz_mod_mpoly_q_denref(f), ctx))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this branch can be reached. If the denominator is a constant, it should be 1.

@fredrik-johansson
Copy link
Collaborator

fredrik-johansson commented May 30, 2025

There are many branches throughout the code where you check fmpz_mod_mpoly_is_fmpz(den, ...). But in all such cases den will necessarily be 1 for canonicalised inputs, so you can just check fmpz_mod_mpoly_is_one instead and then simplify the calculations.

@andrii302
Copy link
Author

The latest commit deals with the commented parts + added tests for gr_fmpz_mod_mpoly_q module. The functions were also simplified on one part, and made sure to output the canonical form quolynomial on another.

{GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_INTEGRAL_DOMAIN, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_UNIQUE_FACTORIZATION_DOMAIN, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_FIELD, (gr_funcptr) gr_generic_ctx_predicate_false},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_field should be true

{GR_METHOD_CTX_IS_UNIQUE_FACTORIZATION_DOMAIN, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_FIELD, (gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_FINITE, (gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_FINITE_CHARACTERISTIC, (gr_funcptr) gr_generic_ctx_predicate_false},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_finite_characteristic should be true

@fredrik-johansson
Copy link
Collaborator

This looks quite good now. Just some minor things to fix:

  • Correct the is_field and is_finite_characteristic predicates.

  • Add your name to the copyright headers. No need to do this for files where you only made a small edit to existing code, but at least do it for fmpz_mod_mpoly_q.h and fmpz_mod_mpoly_q/*.c.

  • Document gr_ctx_init_fmpz_mod_mpoly_q in gr_domains.rst.

  • I suggest adding a comment both in fmpz_mod_mpoly_q.rst and in the documentation line for gr_ctx_init_fmpz_mod_mpoly_q to the effect "The user is responsible for verifying that m is prime. Composite m will lead to undefined behavior."

Once these are fixed, I will do one more careful reading of the code before merging.

@fredrik-johansson
Copy link
Collaborator

I'm a bit concerned by the fact that quite a few lines in the arithmetic operations don't have test coverage according to codecov. It should be close to 100% (compare https://app.codecov.io/gh/flintlib/flint/tree/main/src%2Ffmpz_mpoly_q). Either there are still some redundant branches, or the randtest function needs to be improved, or the test code needs modifying in some way.

@fredrik-johansson
Copy link
Collaborator

In add and sub for example you have the conditional

    if (fmpz_mod_is_one(y_den->coeffs, ctx->ffinfo))
    {

which will always be true since y is in canonical form.

@fredrik-johansson
Copy link
Collaborator

In set_fmpq, add_fmpq etc. you need error handling for the case where the modulus divides the denominator.

@andrii302
Copy link
Author

The required fixes to the code and documentation were made. The only parts in add and sub unreachable by tests that were left, were for the case when y_den==x_den and GCD(res_num, x_den)!=1, which is mathematically possible, but simply too improbable for the tests. In general the coverage must be significantly better now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants