fq_zech.h
#include <flint/fq_zech.h>This module implements arithmetic in a finite field , , in the Zech logarithm representation: a nonzero element is stored as the integer with , where is the generator of the field, a root of a primitive defining polynomial, and zero is stored as . Multiplication, division and powering are additions, subtractions and multiplications of logarithms modulo , and addition uses a table of Zech logarithms , defined by , with entries. The context therefore holds tables of words, built in operations when it is created, which limits the representation to small fields; fq_default uses it for .
The interface is the one documented in detail for fq.h, with fq_zech in place of fq and word-size integers (ulong, nmod_poly, nmod_mat) in place of multiprecision ones, plus conversions to and from the fq_nmod representation, on which a Zech context is built. Multivariate polynomials with coefficients in this representation are in fq_zech_mpoly.h.
Types#
A Zech logarithm context: (qm1), (qm1o2, 0 if ; the logarithm of ), (qm1opm1), with a floating-point inverse, the norm of the generator (prime_root, a primitive root modulo ), the tables zech_log_table (the Zech logarithms ), prime_field_table (the logarithms of ) and eval_table (for each , the integer encoding the coefficients of ), a pointer to the underlying fq_nmod context, a flag owns_fq_nmod_ctx and the flag is_conway.
An element: a structure with one field value, the discrete logarithm of the element, or for zero. Elements need no memory management, but fq_zech_init and fq_zech_clear exist for uniformity.
Context management#
void fq_zech_ctx_init_ui(fq_zech_ctx_t ctx, ulong p, slong d, const char * var)Initialises ctx as a Zech context for , with the generator printed as var, defined by the Conway polynomial if it is in FLINT's table and by a random primitive polynomial otherwise. Requires (otherwise FLINT_ERROR is thrown); the tables need words.
void fq_zech_ctx_init_conway_ui(fq_zech_ctx_t ctx, ulong p, slong d, const char * var)int _fq_zech_ctx_init_conway_ui(fq_zech_ctx_t ctx, ulong p, slong d, const char * var)Initialise ctx with the Conway polynomial for , which is primitive. The first function throws FLINT_ERROR if the polynomial is not in FLINT's table; the second returns 0 in that case and 1 on success.
void fq_zech_ctx_init_random_ui(fq_zech_ctx_t ctx, ulong p, slong d, const char * var)Initialises ctx with a random monic primitive polynomial of degree (from nmod_poly_randtest_monic_primitive, with an internal random state).
void fq_zech_ctx_init_modulus(fq_zech_ctx_t ctx, const nmod_poly_t modulus, const char * var)int fq_zech_ctx_init_modulus_check(fq_zech_ctx_t ctx, const nmod_poly_t modulus, const char * var)Initialise ctx with the given defining polynomial, which must be primitive; it is copied into a new fq_nmod context owned by ctx. While the tables are built, primitivity is checked: the powers must be distinct. fq_zech_ctx_init_modulus throws FLINT_ERROR for a non-primitive polynomial; fq_zech_ctx_init_modulus_check returns 1 on success and 0 if the polynomial is not primitive. After a return value of 0, all memory has already been freed: ctx must not be used, and need not be cleared (clearing it is allowed and has no effect). fq_default_ctx_init_modulus_nmod falls back to fq_nmod for a non-primitive modulus.
void fq_zech_ctx_init_fq_nmod_ctx(fq_zech_ctx_t ctx, fq_nmod_ctx_t ctxn)int fq_zech_ctx_init_fq_nmod_ctx_check(fq_zech_ctx_t ctx, fq_nmod_ctx_t ctxn)Initialise ctx as the Zech representation of the field of the fq_nmod context ctxn, which is referenced, not copied: it must stay alive while ctx is used and is not cleared with ctx. The defining polynomial must be primitive; fq_zech_ctx_init_fq_nmod_ctx throws FLINT_ERROR otherwise, and the _check version returns 0 instead of 1 (after which the memory allocated for ctx has been freed: ctx must not be used, clearing it is allowed and has no effect, and ctxn remains owned by the caller).
void fq_zech_ctx_init(fq_zech_ctx_t ctx, fmpz_t p, slong d, const char * var)void fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, fmpz_t p, slong d, const char * var)int _fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, fmpz_t p, slong d, const char * var)void fq_zech_ctx_init_random(fq_zech_ctx_t ctx, fmpz_t p, slong d, const char * var)Deprecated versions of the _ui functions, taking the prime as an fmpz_t that must fit in a word.
void fq_zech_ctx_init_randtest(fq_zech_ctx_t ctx, flint_rand_t state, int type)void fq_zech_ctx_init_randtest_reducible(fq_zech_ctx_t ctx, flint_rand_t state, int type)Initialise ctx as a random field for testing, with a random primitive modulus: primes of up to 5 bits for type 0 and 1, of up to 4 bits for 2 and 3, and degree at most 4 for even and 3 for odd type. The reducible version is the same, since a Zech context needs an irreducible (indeed primitive) modulus.
void fq_zech_ctx_clear(fq_zech_ctx_t ctx)Frees the tables, and the fq_nmod context if ctx owns it.
const nmod_poly_struct * fq_zech_ctx_modulus(const fq_zech_ctx_t ctx)slong fq_zech_ctx_degree(const fq_zech_ctx_t ctx)ulong fq_zech_ctx_prime(const fq_zech_ctx_t ctx)Return the defining polynomial, the degree and the characteristic .
ulong fq_zech_ctx_order_ui(const fq_zech_ctx_t ctx)void fq_zech_ctx_order(fmpz_t f, const fq_zech_ctx_t ctx)Return, respectively set f to, the number of elements . fq_zech_ctx_order is deprecated.
int fq_zech_ctx_fprint(FILE * file, const fq_zech_ctx_t ctx)void fq_zech_ctx_print(const fq_zech_ctx_t ctx)Print Zech Representation: followed by the description of the underlying fq_nmod context to file, respectively stdout.
Memory management#
void fq_zech_init(fq_zech_t rop, const fq_zech_ctx_t ctx)void fq_zech_init2(fq_zech_t rop, const fq_zech_ctx_t ctx)void fq_zech_clear(fq_zech_t rop, const fq_zech_ctx_t ctx)fq_zech_init and fq_zech_init2 set rop to zero; fq_zech_clear does nothing.
void fq_zech_reduce(fq_zech_t rop, const fq_zech_ctx_t ctx)Subtracts from the value of rop if it is at least . Values in are valid elements and are not changed.
Assignment and conversion#
void fq_zech_set(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx)void fq_zech_swap(fq_zech_t op1, fq_zech_t op2, const fq_zech_ctx_t ctx)void fq_zech_zero(fq_zech_t rop, const fq_zech_ctx_t ctx)void fq_zech_one(fq_zech_t rop, const fq_zech_ctx_t ctx)void fq_zech_gen(fq_zech_t rop, const fq_zech_ctx_t ctx)Copy, swap, and set to 0 (logarithm ), 1 (logarithm 0) or the generator (logarithm 1).
void fq_zech_set_ui(fq_zech_t rop, const ulong x, const fq_zech_ctx_t ctx)void fq_zech_set_si(fq_zech_t rop, const slong x, const fq_zech_ctx_t ctx)void fq_zech_set_fmpz(fq_zech_t rop, const fmpz_t x, const fq_zech_ctx_t ctx)Set rop to the image of the integer in , using the table of logarithms of the prime field.
int fq_zech_get_fmpz(fmpz_t a, const fq_zech_t op, const fq_zech_ctx_t ctx)If op lies in , sets a to its representative in and returns 1; otherwise returns 0.
void fq_zech_get_fq_nmod(fq_nmod_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx)void fq_zech_set_fq_nmod(fq_zech_t rop, const fq_nmod_t op, const fq_zech_ctx_t ctx)Convert between the Zech representation and the polynomial representation of the underlying fq_nmod context ctx->fq_nmod_ctx. fq_zech_get_fq_nmod reads the coefficients from eval_table; fq_zech_set_fq_nmod sums with table lookups.
void fq_zech_get_nmod_poly(nmod_poly_t a, const fq_zech_t b, const fq_zech_ctx_t ctx)void fq_zech_set_nmod_poly(fq_zech_t a, const nmod_poly_t b, const fq_zech_ctx_t ctx)Convert between an element and its representative in . fq_zech_get_nmod_poly also sets the modulus of a to . fq_zech_set_nmod_poly accepts a polynomial of any length, using to reduce exponents.
void fq_zech_get_nmod_mat(nmod_mat_t col, const fq_zech_t a, const fq_zech_ctx_t ctx)void fq_zech_set_nmod_mat(fq_zech_t a, const nmod_mat_t col, const fq_zech_ctx_t ctx)Convert between a and the column vector of the coefficients of its polynomial representative.
Comparison#
int fq_zech_equal(const fq_zech_t op1, const fq_zech_t op2, const fq_zech_ctx_t ctx)int fq_zech_is_zero(const fq_zech_t op, const fq_zech_ctx_t ctx)int fq_zech_is_one(const fq_zech_t op, const fq_zech_ctx_t ctx)Return whether the logarithms are equal, whether op is 0, respectively 1.
int fq_zech_is_invertible(const fq_zech_t op, const fq_zech_ctx_t ctx)int fq_zech_is_invertible_f(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx)Return whether op is nonzero. The second version sets rop to one if it is (a Zech context always describes a field).
Arithmetic#
void fq_zech_add(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, const fq_zech_ctx_t ctx)void fq_zech_sub(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, const fq_zech_ctx_t ctx)Set rop to , with one lookup in the Zech table: , and for odd .
void fq_zech_sub_one(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx)void fq_zech_neg(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx)Set rop to , respectively (adding to the logarithm, or nothing if ).
void fq_zech_mul(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, const fq_zech_ctx_t ctx)void fq_zech_sqr(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx)Set rop to , respectively , by adding logarithms modulo .
void fq_zech_mul_fmpz(fq_zech_t rop, const fq_zech_t op, const fmpz_t x, const fq_zech_ctx_t ctx)void fq_zech_mul_si(fq_zech_t rop, const fq_zech_t op, slong x, const fq_zech_ctx_t ctx)void fq_zech_mul_ui(fq_zech_t rop, const fq_zech_t op, ulong x, const fq_zech_ctx_t ctx)Set rop to op times the image of the integer in .
void fq_zech_inv(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx)void fq_zech_div(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, const fq_zech_ctx_t ctx)Set rop to (logarithm ), respectively . Throw FLINT_ERROR on division by zero.
void fq_zech_gcdinv(fq_zech_t rop, fq_zech_t inv, const fq_zech_t op, const fq_zech_ctx_t ctx)For nonzero op, sets rop to one and inv to the inverse; for zero op, sets rop to zero.
void fq_zech_pow(fq_zech_t rop, const fq_zech_t op1, const fmpz_t e, const fq_zech_ctx_t ctx)void fq_zech_pow_ui(fq_zech_t rop, const fq_zech_t op1, const ulong e, const fq_zech_ctx_t ctx)Set rop to for (with ), by multiplying the logarithm by modulo . fq_zech_pow throws FLINT_ERROR for .
Roots#
int fq_zech_sqrt(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx)int fq_zech_is_square(const fq_zech_t op1, const fq_zech_ctx_t ctx)For odd , an element is a square if and only if its logarithm is even, and then half of it is the logarithm of a square root. For every element is a square, with square root of logarithm or . fq_zech_sqrt returns 1 and sets rop to a square root if op1 is a square, and returns 0 otherwise.
void fq_zech_pth_root(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx)Sets rop to the -th root of op1, by multiplying the logarithm by modulo .
Frobenius map, norm, trace and order#
void fq_zech_frobenius(fq_zech_t rop, const fq_zech_t op, slong e, const fq_zech_ctx_t ctx)Sets rop to (any , taken modulo ), by multiplying the logarithm by .
void fq_zech_norm(fmpz_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx)Sets rop to the norm of , which is , where for the monic defining polynomial is stored in the context (prime_root); one modular exponentiation in .
void fq_zech_trace(fmpz_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx)Sets rop to the trace of op, computed as the sum of the conjugates with Zech additions, and converted from a logarithm in the prime field to the integer .
int fq_zech_multiplicative_order(fmpz * ord, const fq_zech_t op, const fq_zech_ctx_t ctx)int fq_zech_is_primitive(const fq_zech_t op, const fq_zech_ctx_t ctx)Multiplicative order (returning 0 for zero, 1 for a primitive element and otherwise) and primitivity test, as fq_multiplicative_order and fq_is_primitive; the order of is , but the generic algorithm, which factors , is used.
Random elements#
void fq_zech_rand(fq_zech_t rop, flint_rand_t state, const fq_zech_ctx_t ctx)void fq_zech_rand_not_zero(fq_zech_t rop, flint_rand_t state, const fq_zech_ctx_t ctx)void fq_zech_randtest(fq_zech_t rop, flint_rand_t state, const fq_zech_ctx_t ctx)void fq_zech_randtest_not_zero(fq_zech_t rop, flint_rand_t state, const fq_zech_ctx_t ctx)Set rop to a uniformly random element, respectively nonzero element; the randtest versions use a different random generator.
Input and output#
int fq_zech_fprint(FILE * file, const fq_zech_t op, const fq_zech_ctx_t ctx)void fq_zech_print(const fq_zech_t op, const fq_zech_ctx_t ctx)char * fq_zech_get_str(const fq_zech_t op, const fq_zech_ctx_t ctx)Print, respectively return as a newly allocated string, the logarithm of op as a decimal integer ( for zero).
int fq_zech_fprint_pretty(FILE * file, const fq_zech_t op, const fq_zech_ctx_t ctx)void fq_zech_print_pretty(const fq_zech_t op, const fq_zech_ctx_t ctx)char * fq_zech_get_str_pretty(const fq_zech_t op, const fq_zech_ctx_t ctx)Print, respectively return as a newly allocated string, op as a power of the generator, such as a^17, and zero as 0.
Bit packing#
void fq_zech_bit_pack(fmpz_t f, const fq_zech_t op, flint_bitcnt_t bit_size, const fq_zech_ctx_t ctx)void fq_zech_bit_unpack(fq_zech_t rop, const fmpz_t f, flint_bitcnt_t bit_size, const fq_zech_ctx_t ctx)Pack the coefficients of the polynomial representative of op into bit_size-bit fields of an integer, and unpack and convert back, via the fq_nmod representation, as fq_bit_pack and fq_bit_unpack.
The FLINT team, “fq_zech.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/fq_zech/index.html (generated 2026-11-02).
@misc{flint-doc-fq-zech-index,
author = {{The FLINT team}},
title = {{fq\_zech.h (module overview)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/fq_zech/index.html},
note = {Generated 2026-11-02}
}