FLINT3.7.0-dev
Module · 72 functions

qadic.h

#include <flint/qadic.h>

This module implements arithmetic in the unramified extension Qq\mathbf{Q}_q of Qp\mathbf{Q}_p of degree dd, q=pdq = p^d, represented as Qp[X]/(f)\mathbf{Q}_p[X]/(f) for a monic polynomial ff that is irreducible modulo pp. An element is a qadic_t, which is a padic_poly_t of length at most dd: a value pvg(X)p^v g(X) with g∈Z[X]g \in \mathbb{Z}[X], together with an absolute precision NN. As in padic.h, every function computes the exact result from the stored inputs and reduces it modulo pNp^N for the precision NN of the output. The context qadic_ctx_t holds a padic_ctx_t for pp, the polynomial ff in a sparse representation and the name of the generator.

Besides the field operations, the module provides the functions that make unramified extensions useful in pp-adic point counting: the Frobenius automorphism, Teichmüller lifts, the norm and the trace, all described in Frobenius, Teichmüller lifts, norm and trace, and the exponential and logarithm.

AlgorithmArithmetic in unramified extensionsHow qadic represents the unramified extension Q_q = Q_p[X]/(f) and computes products with reduction modulo a sparse defining polynomial, inverses, powers, traces by Newton's identities, norms by resultants or as exp(Tr(log x)), and square roots including the Artin–Schreier step for p = 2.

Types and context#

An element pvg(X)+O(pN)p^v g(X) + O(p^N) of Qq\mathbf{Q}_q; the same type as padic_poly_struct and padic_poly_t. A reduced element has length at most dd, coefficients in [0,pN−v)[0, p^{N - v}) not all divisible by pp (or is zero with v=0v = 0). All functions require reduced inputs and produce reduced outputs unless stated otherwise.

A context for Qq\mathbf{Q}_q. The fields are pctx (a padic_ctx_struct for pp, including the table of powers and the printing mode), the arrays a and j of length len giving f(X)=∑i<lenaiXjif(X) = \sum_{i < \mathtt{len}} a_i X^{j_i} with jj increasing and the last term XdX^d, and var, the name of the generator used for printing.

void qadic_ctx_init(qadic_ctx_t ctx, const fmpz_t p, slong d, slong min, slong max, const char * var, enum padic_print_mode mode)

Initialises ctx for the extension of degree d≥1d \ge 1 of Qp\mathbf{Q}_p, with powers pep^e for min≤e<max\mathtt{min} \le e < \mathtt{max} precomputed, generator name var and printing mode mode. The defining polynomial is the Conway polynomial for (p,d)(p, d) if the database contains it, otherwise for word-size pp the polynomial of nmod_poly_minimal_irreducible (a binomial, trinomial, tetranomial or pentanomial), and otherwise a random sparse irreducible polynomial. The prime pp is not checked.

void qadic_ctx_init_conway(qadic_ctx_t ctx, const fmpz_t p, slong d, slong min, slong max, const char * var, enum padic_print_mode mode)

Like qadic_ctx_init but always uses the Conway polynomial, and throws if p>109987p > 109987 or the database has no Conway polynomial for (p,d)(p, d).

int _qadic_ctx_init_conway_ui(qadic_ctx_t ctx, ulong p, slong d, slong min, slong max, const char * var, enum padic_print_mode mode)

Initialises ctx with the Conway polynomial for (p,d)(p, d) and returns 1, or returns 0 without initialising ctx if the database does not contain it.

void qadic_ctx_init_modulus(qadic_ctx_t ctx, const fmpz_t p, const fmpz_mod_poly_t modulus, slong min, slong max, const char * var, enum padic_print_mode mode)
void qadic_ctx_init_modulus_nmod(qadic_ctx_t ctx, ulong p, const nmod_poly_t modulus, slong min, slong max, const char * var, enum padic_print_mode mode)

Initialise ctx with the given defining polynomial, which must be monic and irreducible over Fp\mathbf{F}_p (not checked). Its coefficients, taken in [0,p)[0, p), define ff; only the nonzero ones are stored.

Clears ctx.

Returns the degree dd of the extension.

Prints pp, dd and ff to stdout.

Memory management and reduction#

void qadic_init2(qadic_t rop, slong prec)

Initialise rop to zero with precision PADIC_DEFAULT_PREC, respectively prec.

Clears rop.

void _fmpz_poly_reduce(fmpz * R, slong lenR, const fmpz * a, const slong * j, slong len)

Reduces (R, lenR) in place modulo the sparse monic polynomial f=∑kakXjkf = \sum_k a_k X^{j_k} of degree d=jlen−1d = j_{\mathtt{len} - 1}, setting the coefficients of degree at least dd to zero. The array jj must be increasing; (R, lenR) may have leading zeros.

void _fmpz_mod_poly_reduce(fmpz * R, slong lenR, const fmpz * a, const slong * j, slong len, const fmpz_t p)

Like _fmpz_poly_reduce, followed by reduction of the remaining coefficients modulo pp (typically a prime power) into [0,p)[0, p).

void qadic_reduce(qadic_t rop, const qadic_ctx_t ctx)

Reduces rop modulo ff and pN−vp^{N - v} and canonicalises it, or sets it to zero if v≥Nv \ge N.

Return the valuation vv and the precision NN of op.

Random generation#

void qadic_randtest(qadic_t rop, flint_rand_t state, const qadic_ctx_t ctx)

Set rop to a random reduced element, respectively a random nonzero one, with valuation drawn as for padic_randtest.

Sets rop to a random reduced element of valuation vv, which is zero if v≥Nv \ge N.

Sets rop to a random reduced element of Zq\mathbf{Z}_q, with valuation in [0,N)[0, N), or to zero if N≤0N \le 0.

Assignment and conversion#

void qadic_set(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Sets rop to op, reduced to the precision of rop.

void qadic_one(qadic_t rop)

Set rop to 0, respectively 1 (or 0 if the precision is not positive).

void qadic_gen(qadic_t rop, const qadic_ctx_t ctx)

Sets rop to the generator XX, or to zero if its precision is not positive. For d=1d = 1 it sets rop to the root −a0-a_0 of ff, reduced modulo pNp^N.

void qadic_set_ui(qadic_t rop, ulong op, const qadic_ctx_t ctx)

Sets rop to the integer op, reduced.

void qadic_set_fmpz_poly(qadic_t rop, const fmpz_poly_t op, const qadic_ctx_t ctx)

Sets rop to the image of the integer polynomial op in Qq\mathbf{Q}_q, reduced modulo ff and pNp^N.

int qadic_get_padic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)

If op lies in Qp\mathbf{Q}_p, that is, has length at most 1, sets rop to its value and returns 1; otherwise returns 0. The value is canonicalised but not reduced to the precision of rop.

Comparison#

int qadic_is_zero(const qadic_t op)
int qadic_is_one(const qadic_t op)

Return whether op is 0, respectively 1.

int qadic_equal(const qadic_t op1, const qadic_t op2)

Returns whether the stored values are equal; the precisions are not compared.

Arithmetic#

All functions in this section allow aliasing between outputs and inputs.

void qadic_add(qadic_t rop, const qadic_t op1, const qadic_t op2, const qadic_ctx_t ctx)
void qadic_sub(qadic_t rop, const qadic_t op1, const qadic_t op2, const qadic_ctx_t ctx)
void qadic_neg(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Set rop to op1+op2op_1 + op_2, op1−op2op_1 - op_2 and −op-op, reduced. These are the corresponding padic_poly functions.

void qadic_mul(qadic_t rop, const qadic_t op1, const qadic_t op2, const qadic_ctx_t ctx)

Sets rop to op1 op2op_1 \, op_2, reduced: the integer polynomials are multiplied in Z[X]\mathbb{Z}[X] and the product is reduced modulo ff and pN−v1−v2p^{N - v_1 - v_2} (Multiplication and reduction).

void _qadic_inv(fmpz * rop, const fmpz * op, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N)

Sets (rop, d) to the inverse of the unit (op, len) modulo ff and pNp^N, for 1≤len≤d1 \le len \le d and N≥1N \ge 1, by Newton iteration from the inverse modulo pp. Does not allow aliasing.

void qadic_inv(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Sets rop to 1/op1/op, reduced, or to zero if N+v≤0N + v \le 0. Throws if op is zero.

void _qadic_pow(fmpz * rop, const fmpz * op, slong len, const fmpz_t e, const fmpz * a, const slong * j, slong lena, const fmpz_t p)

Sets (rop, 2d - 1) to (op, len) raised to the power e≥0e \ge 0, reduced modulo ff and the integer pp (typically a prime power); only the first dd coefficients can be nonzero. Requires 1≤len≤d1 \le len \le d. Does not allow aliasing.

void qadic_pow(qadic_t rop, const qadic_t op, const fmpz_t e, const qadic_ctx_t ctx)

Sets rop to opeop^e, reduced, with op0=1op^0 = 1. Throws if e<0e < 0. Assumes that e⋅ve \cdot v fits in a slong.

Square roots#

int qadic_sqrt(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Returns whether op is a square in Qq\mathbf{Q}_q, and if so sets rop to a square root, reduced. If the valuation of the root is at least the precision of rop, rop is set to zero and squareness is decided from the residue of the unit (modulo pp, or modulo 8 for p=2p = 2); if op has no digits of precision left, 1 is returned.

More
struct qadic2_sqrt_precomp * _qadic_char2_sqrt_precomp_init(const qadic_ctx_t ctx)
int _qadic_char2_sqrt_with_precomp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx, const struct qadic2_sqrt_precomp * data)
void _qadic_char2_sqrt_precomp_clear(struct qadic2_sqrt_precomp * data)

For p=2p = 2, precompute the LUP decomposition of the matrix of the Artin–Schreier map Y↦Y2+YY \mapsto Y^2 + Y on Fq\mathbf{F}_q, compute square roots as qadic_sqrt using it, and free it. The structure is opaque. The first two functions throw if p≠2p \ne 2.

Exponential and logarithm#

The algorithms are those of padic.h, with polynomial arithmetic modulo ff; see The p-adic exponential and logarithm.

void _qadic_exp(fmpz * rop, const fmpz * op, slong v, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N, const fmpz_t pN)
void _qadic_exp_rectangular(fmpz * rop, const fmpz * op, slong v, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N, const fmpz_t pN)

Set (rop, 2d - 1) to the exponential of the nonzero element (op, v, len) modulo pNp^N, where pN is pNp^N, assuming that the series converges and v<Nv < N. Do not allow aliasing. _qadic_exp uses rectangular splitting for N<8192/bN < 8192/b, where bb is the bit length of pp, and the balanced algorithm otherwise.

void _qadic_exp_balanced(fmpz * rop, const fmpz * x, slong v, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N, const fmpz_t pN)

Sets (rop, d) to the exponential of (x, v, len) modulo pNp^N by the balanced (bit-burst) algorithm, assuming convergence and v<Nv < N. Requires 1≤len≤d1 \le len \le d; the input may be zero. Allows aliasing.

int qadic_exp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
int qadic_exp_rectangular(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
int qadic_exp_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Return whether the exponential series converges at op, that is, whether op is zero or has valuation at least 1 (odd pp) or 2 (p=2p = 2), and if so set rop to exp⁡(op)\exp(op), reduced.

void _qadic_log(fmpz * z, const fmpz * y, slong v, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N, const fmpz_t pN)
void _qadic_log_rectangular(fmpz * z, const fmpz * y, slong v, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N, const fmpz_t pN)
void _qadic_log_balanced(fmpz * z, const fmpz * y, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N, const fmpz_t pN)

Set (z, d) to

log⁡(1−y)=−∑i=1∞yii mod pN\log(1 - y) = -\sum_{i = 1}^{\infty} \frac{y^i}{i} \bmod p^N

for a nonzero yy reduced modulo pNp^N, of valuation vv with 1≤v<N1 \le v < N. The array zz must have space for 2d−12d - 1 coefficients. _qadic_log_rectangular allows aliasing between yy and zz, _qadic_log_balanced does not. _qadic_log uses rectangular splitting for N<1024/bN < 1024/b, where bb is the bit length of pp, and the balanced algorithm otherwise.

int qadic_log(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
int qadic_log_rectangular(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
int qadic_log_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)

If ord⁡p(op−1)≥1\operatorname{ord}_p(op - 1) \ge 1 (for every pp, including p=2p = 2), set rop to log⁡(op)\log(op), reduced, and return 1; otherwise, in particular for op=0op = 0, return 0.

Frobenius, Teichmüller lifts, norm and trace#

These functions are described in more detail on Frobenius, Teichmüller lifts, norm and trace.

void _qadic_frobenius_a(fmpz * rop, slong e, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N)

Sets (rop, 2d - 1) to Σe(X)\Sigma^e(X) modulo pNp^N, where Σ\Sigma is the Frobenius automorphism; only the first dd coefficients can be nonzero. Requires d≥2d \ge 2, N≥2N \ge 2 and 0<e<d0 < e < d.

void _qadic_frobenius(fmpz * rop, const fmpz * op, slong len, slong e, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N)

Sets (rop, 2d - 1) to Σe\Sigma^e applied to (op, len), modulo pNp^N, for 1≤len≤d1 \le len \le d and 0<e<d0 < e < d. Does not allow aliasing.

void qadic_frobenius(qadic_t rop, const qadic_t op, slong e, const qadic_ctx_t ctx)

Sets rop to Σe(op)\Sigma^e(op), reduced, for any integer ee, which is taken modulo dd. Σ\Sigma is the automorphism of Qq\mathbf{Q}_q that reduces to x↦xpx \mapsto x^p on Fq\mathbf{F}_q; it generates the Galois group, which is cyclic of order dd.

Full documentation
void _qadic_teichmuller(fmpz * rop, const fmpz * op, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N)

Sets (rop, d) to the Teichmüller lift of the unit (op, len) modulo pNp^N, for N≥1N \ge 1. Allows aliasing.

void qadic_teichmuller(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Sets rop to the Teichmüller lift of op: the unique (q−1)(q - 1)-th root of unity congruent to op modulo pp, reduced. Sets rop to zero if op is zero or divisible by pp, or if the precision of rop is not positive. Throws if op has negative valuation.

Full documentation
void _qadic_trace(fmpz_t rop, const fmpz * op, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t pN)
void qadic_trace(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Set rop to the trace of op over Qp\mathbf{Q}_p, reduced modulo pN, respectively to the precision of rop. The trace is computed from the power sums of the roots of ff by Newton's identities.

Full documentation
void _qadic_norm(fmpz_t rop, const fmpz * op, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t p, slong N)

Sets rop to the norm of the unit (op, len), len≥1len \ge 1, reduced modulo pNp^N; the result is a unit. Chooses between the analytic and the resultant method.

void qadic_norm(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)
void qadic_norm_analytic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)
void qadic_norm_resultant(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)

Set rop to the norm of op over Qp\mathbf{Q}_p, reduced to the precision of rop. The analytic version computes exp⁡(Tr⁡(log⁡u))\exp(\operatorname{Tr}(\log u)) for the unit part uu and throws unless u≡1(modp)u \equiv 1 \pmod p ( mod 4\bmod 4 for p=2p = 2) or u∈Qpu \in \mathbf{Q}_p; the resultant version computes Res⁡(f,u)\operatorname{Res}(f, u) as a determinant modulo pNp^N; qadic_norm chooses.

Full documentation

Output#

int qadic_fprint_pretty(FILE * file, const qadic_t op, const qadic_ctx_t ctx)
int qadic_print_pretty(const qadic_t op, const qadic_ctx_t ctx)

Print op as a polynomial in the generator, in the printing mode of the context: in PADIC_TERSE mode as a polynomial with rational coefficients, in PADIC_SERIES mode as a sum of polynomials with coefficients in [0,p)[0, p) times powers of pp (throws if a coefficient is negative), and in PADIC_VAL_UNIT mode as (g)*p^v. Return 1.

int qadic_debug(const qadic_t op)

Prints the raw fields of op, as padic_poly_debug. Returns 1.

Cite this page

The FLINT team, “qadic.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/qadic/index.html (generated 2026-11-02).