Skip to content

Commit

Permalink
Merge pull request #1927 from flintlib/is_field
Browse files Browse the repository at this point in the history
Unified interface for setting whether something is a field
  • Loading branch information
fredrik-johansson authored Apr 19, 2024
2 parents 45e211f + cec020a commit 306b477
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 51 deletions.
27 changes: 18 additions & 9 deletions doc/source/gr_domains.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Groups
larger than `10^{16}`, which is currently unsupported
by the implementation.

Base rings and fields
Basic rings and fields
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_random(gr_ctx_t ctx, flint_rand_t state)
Expand All @@ -101,6 +101,17 @@ Base rings and fields
Initializes *ctx* to the ring of Gaussian integers
`\mathbb{Z}[i]` with elements of type :type:`fmpzi_t`.

Residue rings and finite fields
-------------------------------------------------------------------------------

.. function:: int gr_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field)

Set whether the given ring is actually a field. For example,
in the case of `\mathbb{Z}/n\mathbb{Z}`, this sets whether
the modulus is prime. This can speed up some computations and
enable some functions to complete that otherwise would
return ``GR_UNABLE``.

.. function:: void gr_ctx_init_nmod(gr_ctx_t ctx, ulong n)

Initializes *ctx* to the ring `\mathbb{Z}/n\mathbb{Z}`
Expand Down Expand Up @@ -134,14 +145,6 @@ Base rings and fields
of integers modulo *n* where
elements are flat limb arrays with the same number of limbs as *n*.

.. function:: void gr_ctx_nmod_set_primality(gr_ctx_t ctx, truth_t is_prime)
void gr_ctx_fmpz_mod_set_primality(gr_ctx_t ctx, truth_t is_prime)

For a ring initialized with :func:`gr_ctx_init_nmod`
or :func:`gr_ctx_init_fmpz_mod` respectively,
indicate whether the modulus is prime. This can speed up
some computations.

.. function:: void gr_ctx_init_fq(gr_ctx_t ctx, const fmpz_t p, slong d, const char * var)
void gr_ctx_init_fq_nmod(gr_ctx_t ctx, ulong p, slong d, const char * var)
void gr_ctx_init_fq_zech(gr_ctx_t ctx, ulong p, slong d, const char * var)
Expand All @@ -154,6 +157,9 @@ Base rings and fields
The ``fq_zech`` context requires `q < 2^{64}` (and in practice a much
smaller value than this).

Number fields and algebraic numbers
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_nf(gr_ctx_t ctx, const fmpq_poly_t poly)
void gr_ctx_init_nf_fmpz_poly(gr_ctx_t ctx, const fmpz_poly_t poly)

Expand All @@ -177,6 +183,9 @@ Base rings and fields
requires a degree limit of at least 10000.
Warning: currently not all methods respect these limits.

Real and complex numbers
-------------------------------------------------------------------------------

.. function:: void gr_ctx_init_real_arb(gr_ctx_t ctx, slong prec)
void gr_ctx_init_complex_acb(gr_ctx_t ctx, slong prec)

Expand Down
2 changes: 1 addition & 1 deletion doc/source/mpn_mod.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Context objects

A :type:`truth_t` flag indicating whether `n` is prime.

.. function:: void gr_ctx_mpn_mod_set_primality(gr_ctx_t ctx, truth_t is_prime)
.. function:: void mpn_mod_ctx_set_is_field(gr_ctx_t ctx, truth_t is_prime)

Set the flag indicating whether `n` is prime. Setting this to ``T_TRUE``
speeds up some algorithms which can assume that the ring
Expand Down
12 changes: 6 additions & 6 deletions src/fq_default/ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ void fq_default_ctx_init_type(fq_default_ctx_t ctx,
{
gr_ctx_init_nmod(FQ_DEFAULT_GR_CTX(ctx), fmpz_get_ui(p));
NMOD_CTX_A(FQ_DEFAULT_GR_CTX(ctx))[0] = 0;
gr_ctx_nmod_set_primality(FQ_DEFAULT_GR_CTX(ctx), T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(FQ_DEFAULT_GR_CTX(ctx), T_TRUE));
}
else if (type == FQ_DEFAULT_FMPZ_MOD || (type == 0 && d == 1))
{
gr_ctx_init_fmpz_mod(FQ_DEFAULT_GR_CTX(ctx), p);
gr_ctx_fmpz_mod_set_primality(FQ_DEFAULT_GR_CTX(ctx), T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(FQ_DEFAULT_GR_CTX(ctx), T_TRUE));
}
else
{
Expand Down Expand Up @@ -82,12 +82,12 @@ void fq_default_ctx_init_modulus_type(fq_default_ctx_t ctx,

_gr_ctx_init_nmod(FQ_DEFAULT_GR_CTX(ctx), &mod);
NMOD_CTX_A(FQ_DEFAULT_GR_CTX(ctx))[0] = a;
gr_ctx_nmod_set_primality(FQ_DEFAULT_GR_CTX(ctx), T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(FQ_DEFAULT_GR_CTX(ctx), T_TRUE));
}
else if (type == FQ_DEFAULT_FMPZ_MOD || (type == 0 && d == 1))
{
gr_ctx_init_fmpz_mod(FQ_DEFAULT_GR_CTX(ctx), p);
gr_ctx_fmpz_mod_set_primality(FQ_DEFAULT_GR_CTX(ctx), T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(FQ_DEFAULT_GR_CTX(ctx), T_TRUE));

fmpz_mod_divides(FQ_DEFAULT_CTX_FMPZ_MOD_A(ctx), modulus->coeffs + 0,
modulus->coeffs + 1, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
Expand Down Expand Up @@ -137,7 +137,7 @@ void fq_default_ctx_init_modulus_nmod_type(fq_default_ctx_t ctx,

_gr_ctx_init_nmod(FQ_DEFAULT_GR_CTX(ctx), &mod);
NMOD_CTX_A(FQ_DEFAULT_GR_CTX(ctx))[0] = a;
gr_ctx_nmod_set_primality(FQ_DEFAULT_GR_CTX(ctx), T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(FQ_DEFAULT_GR_CTX(ctx), T_TRUE));
}
else if (type == FQ_DEFAULT_FMPZ_MOD || (type == 0 && d == 1))
{
Expand All @@ -152,7 +152,7 @@ void fq_default_ctx_init_modulus_nmod_type(fq_default_ctx_t ctx,
fmpz_init_set_ui(pp, p);
gr_ctx_init_fmpz_mod(FQ_DEFAULT_GR_CTX(ctx), pp);
fmpz_clear(pp);
gr_ctx_fmpz_mod_set_primality(FQ_DEFAULT_GR_CTX(ctx), T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(FQ_DEFAULT_GR_CTX(ctx), T_TRUE));
fmpz_set_ui(FMPZ_MOD_CTX_A(FQ_DEFAULT_GR_CTX(ctx)), a);
}
else
Expand Down
7 changes: 4 additions & 3 deletions src/gr.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ typedef enum
GR_METHOD_CTX_SET_REAL_PREC,
GR_METHOD_CTX_GET_REAL_PREC,

GR_METHOD_CTX_SET_IS_FIELD,
GR_METHOD_CTX_SET_GEN_NAME,
GR_METHOD_CTX_SET_GEN_NAMES,

Expand Down Expand Up @@ -780,6 +781,7 @@ typedef int ((*gr_method_ctx)(gr_ctx_ptr));
typedef truth_t ((*gr_method_ctx_predicate)(gr_ctx_ptr));
typedef int ((*gr_method_ctx_set_si)(gr_ctx_ptr, slong));
typedef int ((*gr_method_ctx_get_si)(slong *, gr_ctx_ptr));
typedef int ((*gr_method_ctx_set_truth)(gr_ctx_ptr, truth_t));
typedef int ((*gr_method_ctx_stream)(gr_stream_t, gr_ctx_ptr));
typedef int ((*gr_method_ctx_set_str)(gr_ctx_ptr, const char *));
typedef int ((*gr_method_ctx_set_strs)(gr_ctx_ptr, const char **));
Expand Down Expand Up @@ -876,6 +878,7 @@ typedef int ((*gr_method_set_fexpr_op)(gr_ptr, fexpr_vec_t, gr_vec_t, const fexp
#define GR_CTX_PREDICATE(ctx, NAME) (((gr_method_ctx_predicate *) ctx->methods)[GR_METHOD_ ## NAME])
#define GR_CTX_SET_SI(ctx, NAME) (((gr_method_ctx_set_si *) ctx->methods)[GR_METHOD_ ## NAME])
#define GR_CTX_GET_SI(ctx, NAME) (((gr_method_ctx_get_si *) ctx->methods)[GR_METHOD_ ## NAME])
#define GR_CTX_SET_TRUTH(ctx, NAME) (((gr_method_ctx_set_truth *) ctx->methods)[GR_METHOD_ ## NAME])
#define GR_CTX_SET_STR(ctx, NAME) (((gr_method_ctx_set_str *) ctx->methods)[GR_METHOD_ ## NAME])
#define GR_CTX_SET_STRS(ctx, NAME) (((gr_method_ctx_set_strs *) ctx->methods)[GR_METHOD_ ## NAME])
#define GR_STREAM_IN(ctx, NAME) (((gr_method_stream_in *) ctx->methods)[GR_METHOD_ ## NAME])
Expand Down Expand Up @@ -994,6 +997,7 @@ GR_INLINE truth_t gr_ctx_has_real_prec(gr_ctx_t ctx) { return GR_CTX_PREDICATE(c
GR_INLINE WARN_UNUSED_RESULT int gr_ctx_set_real_prec(gr_ctx_t ctx, slong prec) { return GR_CTX_SET_SI(ctx, CTX_SET_REAL_PREC)(ctx, prec); }
GR_INLINE WARN_UNUSED_RESULT int gr_ctx_get_real_prec(slong * prec, gr_ctx_t ctx) { return GR_CTX_GET_SI(ctx, CTX_GET_REAL_PREC)(prec, ctx); }

GR_INLINE WARN_UNUSED_RESULT int gr_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field) { return GR_CTX_SET_TRUTH(ctx, CTX_SET_IS_FIELD)(ctx, is_field); }
GR_INLINE WARN_UNUSED_RESULT int gr_ctx_set_gen_name(gr_ctx_t ctx, const char * s) { return GR_CTX_SET_STR(ctx, CTX_SET_GEN_NAME)(ctx, s); }
GR_INLINE WARN_UNUSED_RESULT int gr_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) { return GR_CTX_SET_STRS(ctx, CTX_SET_GEN_NAMES)(ctx, s); }

Expand Down Expand Up @@ -1366,17 +1370,14 @@ void gr_ctx_init_fmpzi(gr_ctx_t ctx);

void gr_ctx_init_fmpz_mod(gr_ctx_t ctx, const fmpz_t n);
void _gr_ctx_init_fmpz_mod_from_ref(gr_ctx_t ctx, const void * fmod_ctx);
void gr_ctx_fmpz_mod_set_primality(gr_ctx_t ctx, truth_t is_prime);

void gr_ctx_init_nmod(gr_ctx_t ctx, ulong n);
void _gr_ctx_init_nmod(gr_ctx_t ctx, void * nmod_t_ref);
void gr_ctx_nmod_set_primality(gr_ctx_t ctx, truth_t is_prime);

void gr_ctx_init_nmod8(gr_ctx_t ctx, unsigned char n);
void gr_ctx_init_nmod32(gr_ctx_t ctx, unsigned int n);

int gr_ctx_init_mpn_mod(gr_ctx_t ctx, const fmpz_t n);
void gr_ctx_mpn_mod_set_primality(gr_ctx_t ctx, truth_t is_prime);

void gr_ctx_init_real_qqbar(gr_ctx_t ctx);
void gr_ctx_init_complex_qqbar(gr_ctx_t ctx);
Expand Down
14 changes: 8 additions & 6 deletions src/gr/fmpz_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ _gr_fmpz_mod_ctx_clear(gr_ctx_t ctx)
fmpz_clear(FMPZ_MOD_CTX_A(ctx));
}

int
_gr_fmpz_mod_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field)
{
FMPZ_MOD_IS_PRIME(ctx) = is_field;
return GR_SUCCESS;
}

truth_t
_gr_fmpz_mod_ctx_is_field(gr_ctx_t ctx)
{
Expand Down Expand Up @@ -728,6 +735,7 @@ gr_method_tab_input _fmpz_mod_methods_input[] =
{GR_METHOD_CTX_IS_EXACT, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_CANONICAL,
(gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_SET_IS_FIELD,(gr_funcptr) _gr_fmpz_mod_ctx_set_is_field},
{GR_METHOD_INIT, (gr_funcptr) _gr_fmpz_mod_init},
{GR_METHOD_CLEAR, (gr_funcptr) _gr_fmpz_mod_clear},
{GR_METHOD_SWAP, (gr_funcptr) _gr_fmpz_mod_swap},
Expand Down Expand Up @@ -837,9 +845,3 @@ _gr_ctx_init_fmpz_mod_from_ref(gr_ctx_t ctx, const void * fctx)
_fmpz_mod_methods_initialized = 1;
}
}

void
gr_ctx_fmpz_mod_set_primality(gr_ctx_t ctx, truth_t is_prime)
{
FMPZ_MOD_IS_PRIME(ctx) = is_prime;
}
14 changes: 8 additions & 6 deletions src/gr/nmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ _gr_nmod_ctx_is_field(const gr_ctx_t ctx)
return n_is_prime(NMOD_CTX(ctx).n) ? T_TRUE : T_FALSE;
}

int
_gr_nmod_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field)
{
NMOD_IS_PRIME(ctx) = is_field;
return GR_SUCCESS;
}

void
_gr_nmod_init(ulong * x, const gr_ctx_t ctx)
{
Expand Down Expand Up @@ -1442,6 +1449,7 @@ gr_method_tab_input __gr_nmod_methods_input[] =
{GR_METHOD_CTX_IS_EXACT, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_CANONICAL,
(gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_SET_IS_FIELD,(gr_funcptr) _gr_nmod_ctx_set_is_field},
{GR_METHOD_INIT, (gr_funcptr) _gr_nmod_init},
{GR_METHOD_CLEAR, (gr_funcptr) _gr_nmod_clear},
{GR_METHOD_SWAP, (gr_funcptr) _gr_nmod_swap},
Expand Down Expand Up @@ -1563,9 +1571,3 @@ _gr_ctx_init_nmod(gr_ctx_t ctx, void * nmod_t_ref)
__gr_nmod_methods_initialized = 1;
}
}

void
gr_ctx_nmod_set_primality(gr_ctx_t ctx, truth_t is_prime)
{
NMOD_IS_PRIME(ctx) = is_prime;
}
4 changes: 2 additions & 2 deletions src/gr/test/t-fmpz_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ TEST_FUNCTION_START(gr_fmpz_mod, state)
fmpz_abs(n, n);
gr_ctx_init_fmpz_mod(ZZn, n);
if (n_randint(state, 2))
gr_ctx_fmpz_mod_set_primality(ZZn, fmpz_is_probabprime(n) ? T_TRUE : T_FALSE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ZZn, fmpz_is_probabprime(n) ? T_TRUE : T_FALSE));
gr_test_ring(ZZn, 10, flags);
gr_ctx_clear(ZZn);
}
Expand All @@ -39,7 +39,7 @@ TEST_FUNCTION_START(gr_fmpz_mod, state)
fmpz_abs(n, n);
gr_ctx_init_fmpz_mod(ZZn, n);
if (n_randint(state, 2))
gr_ctx_fmpz_mod_set_primality(ZZn, fmpz_is_probabprime(n) ? T_TRUE : T_FALSE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ZZn, fmpz_is_probabprime(n) ? T_TRUE : T_FALSE));
gr_test_ring(ZZn, 100, flags);
gr_ctx_clear(ZZn);
}
Expand Down
2 changes: 1 addition & 1 deletion src/gr/test/t-nmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ TEST_FUNCTION_START(gr_nmod, state)
n = n_randtest_not_zero(state);
gr_ctx_init_nmod(ZZn, n);
if (n_randint(state, 2))
gr_ctx_nmod_set_primality(ZZn, n_is_prime(n) ? T_TRUE : T_FALSE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ZZn, n_is_prime(n) ? T_TRUE : T_FALSE));
gr_test_ring(ZZn, 100, flags);
gr_ctx_clear(ZZn);
}
Expand Down
8 changes: 7 additions & 1 deletion src/mpn_mod.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ _mpn_mod_ctx_struct;
#define MPN_MOD_CTX_IS_PRIME(ctx) (MPN_MOD_CTX(ctx)->is_prime)
#define MPN_MOD_CTX_MODULUS_BITS(ctx) ((MPN_MOD_CTX_NLIMBS(ctx) - 1) * FLINT_BITS + (FLINT_BITS - MPN_MOD_CTX_NORM(ctx)))

MPN_MOD_INLINE int
mpn_mod_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field)
{
MPN_MOD_CTX_IS_PRIME(ctx) = is_field;
return GR_SUCCESS;
}

/* Helpers which actually belong in mpn_extras.h */

FLINT_FORCE_INLINE
Expand Down Expand Up @@ -186,7 +193,6 @@ char * _flint_mpn_get_str(mp_srcptr x, mp_size_t n);
int gr_ctx_init_mpn_mod(gr_ctx_t ctx, const fmpz_t n);
int _gr_ctx_init_mpn_mod(gr_ctx_t ctx, mp_srcptr n, mp_size_t nlimbs);
void gr_ctx_init_mpn_mod_randtest(gr_ctx_t ctx, flint_rand_t state);
void gr_ctx_mpn_mod_set_primality(gr_ctx_t ctx, truth_t is_prime);

int mpn_mod_ctx_write(gr_stream_t out, gr_ctx_t ctx);
void mpn_mod_ctx_clear(gr_ctx_t ctx);
Expand Down
10 changes: 2 additions & 8 deletions src/mpn_mod/ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ gr_method_tab_input _mpn_mod_methods_input[] =
{GR_METHOD_CTX_IS_EXACT, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_CANONICAL,
(gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_SET_IS_FIELD,(gr_funcptr) mpn_mod_ctx_set_is_field},
{GR_METHOD_INIT, (gr_funcptr) mpn_mod_init},
{GR_METHOD_CLEAR, (gr_funcptr) mpn_mod_clear},
{GR_METHOD_SWAP, (gr_funcptr) mpn_mod_swap},
Expand Down Expand Up @@ -186,13 +187,6 @@ gr_ctx_init_mpn_mod(gr_ctx_t ctx, const fmpz_t n)
return _gr_ctx_init_mpn_mod(ctx, COEFF_TO_PTR(*n)->_mp_d, COEFF_TO_PTR(*n)->_mp_size);
}

/* todo: have a generic interface for this */
void
gr_ctx_mpn_mod_set_primality(gr_ctx_t ctx, truth_t is_prime)
{
MPN_MOD_CTX_IS_PRIME(ctx) = is_prime;
}

static const int
randtest_primes[][2] = {
#if FLINT_BITS == 32
Expand Down Expand Up @@ -223,7 +217,7 @@ gr_ctx_init_mpn_mod_randtest(gr_ctx_t ctx, flint_rand_t state)
fmpz_ui_pow_ui(n, 2, randtest_primes[i][0]);
fmpz_add_si(n, n, randtest_primes[i][1]);
GR_MUST_SUCCEED(gr_ctx_init_mpn_mod(ctx, n));
gr_ctx_mpn_mod_set_primality(ctx, n_randint(state, 2) ? T_TRUE : T_UNKNOWN);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ctx, n_randint(state, 2) ? T_TRUE : T_UNKNOWN));
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions src/mpn_mod/profile/p-mat_vs_fmpz_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ int main()
GR_MUST_SUCCEED(gr_ctx_init_mpn_mod(ctx, p));
gr_ctx_init_fmpz_mod(ctx2, p);

gr_ctx_mpn_mod_set_primality(ctx, T_TRUE);
gr_ctx_fmpz_mod_set_primality(ctx2, T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ctx, T_TRUE));
GR_MUST_SUCCEED(gr_ctx_set_is_field(ctx2, T_TRUE));

flint_printf(" bits n add mul solve\n");

Expand Down
6 changes: 3 additions & 3 deletions src/mpn_mod/test/t-mpn_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ TEST_FUNCTION_START(mpn_mod, state)
}

GR_MUST_SUCCEED(gr_ctx_init_mpn_mod(ZZn, n));
gr_ctx_mpn_mod_set_primality(ZZn, T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ZZn, T_TRUE));
gr_test_ring(ZZn, 100 * flint_test_multiplier(), flags);
gr_ctx_clear(ZZn);
}
Expand All @@ -58,7 +58,7 @@ TEST_FUNCTION_START(mpn_mod, state)
}

GR_MUST_SUCCEED(gr_ctx_init_mpn_mod(ZZn, n));
gr_ctx_mpn_mod_set_primality(ZZn, T_TRUE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ZZn, T_TRUE));
gr_test_ring(ZZn, 100 * flint_test_multiplier(), flags);
gr_ctx_clear(ZZn);
}
Expand All @@ -74,7 +74,7 @@ TEST_FUNCTION_START(mpn_mod, state)
}

if (n_randint(state, 2))
gr_ctx_mpn_mod_set_primality(ZZn, fmpz_is_probabprime(n) ? T_TRUE : T_FALSE);
GR_MUST_SUCCEED(gr_ctx_set_is_field(ZZn, fmpz_is_probabprime(n) ? T_TRUE : T_FALSE));

/* test Waksman mul */
{
Expand Down
Loading

0 comments on commit 306b477

Please sign in to comment.