Frobenius, Teichmüller lifts, norm and trace
#include <flint/qadic.h>void qadic_frobenius(qadic_t rop, const qadic_t op, slong e, const qadic_ctx_t ctx)sourceSets rop to , reduced, for any integer , which is taken modulo . is the automorphism of that reduces to on ; it generates the Galois group, which is cyclic of order .
void qadic_teichmuller(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)sourceSets rop to the Teichmüller lift of op: the unique -th root of unity congruent to op modulo , reduced. Sets rop to zero if op is zero or divisible by , or if the precision of rop is not positive. Throws if op has negative valuation.
void _qadic_trace(fmpz_t rop, const fmpz * op, slong len, const fmpz * a, const slong * j, slong lena, const fmpz_t pN)sourcevoid qadic_trace(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)sourceSet rop to the trace of op over , reduced modulo pN, respectively to the precision of rop. The trace is computed from the power sums of the roots of by Newton's identities.
void qadic_norm(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)sourcevoid qadic_norm_analytic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)sourcevoid qadic_norm_resultant(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)sourceSet rop to the norm of op over , reduced to the precision of rop. The analytic version computes for the unit part and throws unless ( for ) or ; the resultant version computes as a determinant modulo ; qadic_norm chooses.
The extension is Galois with cyclic Galois group of order , generated by the Frobenius automorphism , the unique automorphism that reduces to on the residue field . These functions compute , the Teichmüller lifts, which are the roots of unity of order prime to , and the trace and norm, which are the sum and the product of the conjugates . All four reduce their output to its precision; for the norm and trace the output is a padic_t.
Algorithms#
qadic_frobeniuscomputes the image of the generator as the root of congruent to modulo , by Newton iteration, and evaluates the input polynomial at it by rectangular splitting. The cost is multiplications modulo and multiplications in at each precision. Elements of are returned unchanged, and for precision 1 the image is computed as a power .qadic_teichmullerlifts a unit to the root of congruent to modulo by the Newton iteration , which costs multiplications at each precision (Teichmüller lifts).qadic_tracecomputes the power sums of the roots of by Newton's identities and returns for the element ; the cost is linear in times the number of terms of .qadic_normuses when the unit part is ( for ) and is large compared with , and otherwise the resultant , computed as the determinant of the Sylvester matrix modulo (Norm).
The valuation passes through unchanged for , is zero for the Teichmüller lift, and is multiplied by for the norm (); the trace of is , which can have larger valuation.
Example#
The program works in the extension of degree 3 of defined by the Conway polynomial , to precision . It computes the Teichmüller lift of the generator, checks that is a 26th root of unity and that , checks that is the identity, and computes the norm and trace of , which are and minus the coefficient of in .
#include <flint/flint.h>
#include <flint/fmpz.h>
#include <flint/padic.h>
#include <flint/qadic.h>
int main(void)
{
fmpz_t p, e;
qadic_ctx_t ctx;
qadic_t x, t, s, u;
padic_t n;
fmpz_init_set_ui(p, 3);
fmpz_init(e);
qadic_ctx_init_conway(ctx, p, 3, 0, 20, "X", PADIC_SERIES);
qadic_ctx_print(ctx);
qadic_init2(x, 8); qadic_init2(t, 8); qadic_init2(s, 8); qadic_init2(u, 8);
padic_init2(n, 8);
qadic_gen(x, ctx);
qadic_teichmuller(t, x, ctx); /* the (q-1)-th root of unity = X mod 3 */
flint_printf("t = "); qadic_print_pretty(t, ctx); flint_printf("\n");
fmpz_set_ui(e, 26); /* q - 1 = 26 */
qadic_pow(u, t, e, ctx);
flint_printf("t^26 == 1: %d\n", qadic_is_one(u));
qadic_frobenius(s, t, 1, ctx); /* Sigma(t) */
fmpz_set_ui(e, 3);
qadic_pow(u, t, e, ctx); /* t^p */
flint_printf("Sigma(t) == t^3: %d\n", qadic_equal(s, u));
qadic_frobenius(s, x, 3, ctx); /* Sigma^3 = identity */
flint_printf("Sigma^3(X) == X: %d\n", qadic_equal(s, x));
qadic_norm(n, x, ctx);
flint_printf("Norm(X) = "); padic_print(n, &ctx->pctx);
qadic_trace(n, x, ctx);
flint_printf(", Trace(X) = "); padic_print(n, &ctx->pctx);
flint_printf("\n");
qadic_clear(x); qadic_clear(t); qadic_clear(s); qadic_clear(u);
padic_clear(n);
qadic_ctx_clear(ctx);
fmpz_clear(p); fmpz_clear(e);
return 0;
}p = 3 d = 3 f(X) = 1 + 2*X + X^3 t = (X) + (X^2)*3 + (1)*3^2 + (2*X^2+1)*3^3 + (X+1)*3^4 + (X)*3^5 + (X+2)*3^6 + (2*X^2+X+2)*3^7 t^26 == 1: 1 Sigma(t) == t^3: 1 Sigma^3(X) == X: 1 Norm(X) = 2 + 2*3^1 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7, Trace(X) = 0
The series form of the norm shows the 3-adic expansion of , whose digits are all . The relation holds for every Teichmüller lift, because both sides are -th roots of unity with the same reduction modulo .
The FLINT team, “Frobenius, Teichmüller lifts, norm and trace (qadic.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/qadic/galois.html (generated 2026-11-02).
@misc{flint-doc-qadic-galois,
author = {{The FLINT team}},
title = {{Frobenius, Teichmüller lifts, norm and trace (qadic.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/qadic/galois.html},
note = {Generated 2026-11-02}
}