FLINT3.7.0-dev
Module · 113 functions

nf_elem.h

#include <flint/nf_elem.h>

This module implements arithmetic with elements of a number field K=Q(θ)=Q[x]/(f)K = \mathbf{Q}(\theta) = \mathbf{Q}[x]/(f) given by an nf_t (nf.h). An element is a polynomial in θ\theta of degree less than d=deg⁡fd = \deg f with rational coefficients, stored as an integer numerator polynomial and a common positive denominator. Fields of degree 1 and 2 use a fixed-size representation, and the field Q(i)\mathbf{Q}(i) has its own multiplication. Products are reduced modulo ff using precomputed powers of θ\theta; inverses are computed by the extended Euclidean algorithm, norms as resultants, traces from precomputed power sums. Every function takes the nf_t as its last argument, and all elements passed to a function must belong to the same field.

The guide Getting started with nf_elem shows the basic operations. How a fixed number field compares with the other exact representations (qqbar, ca) is discussed in Choosing a representation for exact numbers.

AlgorithmArithmetic in number fieldsHow nf_elem represents elements of Q[x]/(f) with special cases for degrees 1 and 2 and for Q(i), multiplies with reduction by precomputed powers of the generator, inverts by the extended Euclidean algorithm, and computes norms as resultants and traces from power sums of the roots.

Guides#

Types and representation#

An element of a number field: a union of an fmpq_poly_t (general fields), an lnf_elem_t (degree 1) and a qnf_elem_t (degree 2). Which member is used is determined by the flag of the nf_t.

An element of a field of degree 1, as a numerator num and a denominator den.

An element (a0+a1θ+a2θ2)/q(a_0 + a_1\theta + a_2\theta^2)/q of a field of degree 2, as an array num of three fmpz and a denominator den. The third coefficient allows products to be formed without immediate reduction; in a reduced element it is zero.

The fmpq_poly_t, lnf_elem_t and qnf_elem_t members of the union.

Pointers to the numerator coefficients and the denominator in each representation.

An element is reduced if its numerator has degree less than dd and canonical if moreover the numerator and denominator are coprime (their content is 1) and the denominator is positive, with denominator 1 for zero. Functions without a leading underscore require canonical inputs and produce canonical outputs unless stated otherwise, and allow aliasing.

Memory management#

void nf_elem_init(nf_elem_t a, const nf_t nf)
void nf_elem_clear(nf_elem_t a, const nf_t nf)

Initialise aa to zero in nf, respectively clear it.

void nf_elem_swap(nf_elem_t a, nf_elem_t b, const nf_t nf)

Swaps aa and bb in constant time.

Set aa to a random canonical element, respectively a random nonzero one, whose numerator coefficients and denominator have at most bits bits.

Canonicalisation and reduction#

Removes the common content of numerator and denominator and makes the denominator positive (1 for zero). Does not reduce modulo ff.

void _nf_elem_reduce(nf_elem_t a, const nf_t nf)

Reduces the numerator of aa modulo the defining polynomial, without canonicalising. Used after products with delayed reduction (nf_elem_mul_red with red =0= 0).

void nf_elem_reduce(nf_elem_t a, const nf_t nf)

Reduces aa modulo the defining polynomial and canonicalises it.

Returns whether aa is invertible modulo the defining polynomial, that is, whether gcd⁡(a,f)=1\gcd(a, f) = 1 in Q[x]\mathbf{Q}[x]. This matters only when ff is reducible, which is not excluded by nf_init; the function is meant for test code.

Assignment and conversion#

void nf_elem_zero(nf_elem_t a, const nf_t nf)
void nf_elem_one(nf_elem_t a, const nf_t nf)

Set aa to 0, respectively 1.

void nf_elem_gen(nf_elem_t a, const nf_t nf)

Sets aa to the generator θ\theta, the class of xx. In a field of degree 1 this is the root −f0/f1-f_0/f_1 of f=f1x+f0f = f_1 x + f_0.

void nf_elem_set(nf_elem_t a, const nf_elem_t b, const nf_t nf)

Sets aa to bb.

void nf_elem_set_si(nf_elem_t a, slong c, const nf_t nf)
void nf_elem_set_ui(nf_elem_t a, ulong c, const nf_t nf)
void nf_elem_set_fmpz(nf_elem_t a, const fmpz_t c, const nf_t nf)
void nf_elem_set_fmpq(nf_elem_t a, const fmpq_t c, const nf_t nf)

Set aa to the rational number cc.

void nf_elem_set_fmpq_poly(nf_elem_t a, const fmpq_poly_t pol, const nf_t nf)

Sets aa to the image of the canonical polynomial pol in KK, reducing it modulo ff if its degree is at least dd.

void nf_elem_get_fmpq_poly(fmpq_poly_t pol, const nf_elem_t a, const nf_t nf)

Sets pol to the polynomial in xx representing the reduced element aa.

void nf_elem_set_fmpz_mat_row(nf_elem_t b, const fmpz_mat_t M, const slong i, fmpz_t den, const nf_t nf)

Sets bb to the element whose numerator coefficients are the entries of row ii of MM (column 0 holding the constant coefficient) and whose denominator is den, and canonicalises it.

void nf_elem_get_fmpz_mat_row(fmpz_mat_t M, const slong i, fmpz_t den, const nf_elem_t b, const nf_t nf)

Sets row ii of MM, which must have dd columns, to the numerator coefficients of bb (column 0 holding the constant coefficient) and den to its denominator.

void _nf_elem_get_nmod_poly(nmod_poly_t pol, const nf_elem_t a, const nf_t nf)

Sets pol to the numerator of aa reduced modulo the modulus of pol, ignoring the denominator.

void nf_elem_get_nmod_poly_den(nmod_poly_t pol, const nf_elem_t a, const nf_t nf, int den)
void nf_elem_get_nmod_poly(nmod_poly_t pol, const nf_elem_t a, const nf_t nf)

Set pol to the reduction of the numerator of aa modulo the modulus nn of pol; if den is nonzero (always for nf_elem_get_nmod_poly), multiply it by the inverse of the denominator modulo nn, which must exist.

void nf_elem_get_fmpz_mod_poly_den(fmpz_mod_poly_t pol, const nf_elem_t a, const nf_t nf, int den, const fmpz_mod_ctx_t ctx)

Versions of the three functions above for a multiword modulus given by ctx.

Coefficients and denominator#

void nf_elem_get_den(fmpz_t d, const nf_elem_t b, const nf_t nf)
void nf_elem_set_den(nf_elem_t b, fmpz_t d, const nf_t nf)

Get and set the denominator of bb. nf_elem_set_den requires d>0d > 0 and does not canonicalise.

int nf_elem_den_is_one(const nf_elem_t a, const nf_t nf)

Returns whether the denominator of aa is 1, that is, whether the canonical aa lies in Z[θ]\mathbb{Z}[\theta].

void nf_elem_get_coeff_fmpq(fmpq_t a, const nf_elem_t b, slong i, const nf_t nf)

Sets aa to the coefficient of θi\theta^i in bb, a rational number.

void nf_elem_get_coeff_fmpz(fmpz_t a, const nf_elem_t b, slong i, const nf_t nf)

Sets aa to the coefficient of θi\theta^i in the numerator of bb, ignoring the denominator.

void _nf_elem_set_coeff_num_fmpz(nf_elem_t a, slong i, const fmpz_t b, const nf_t nf)

Sets the coefficient of θi\theta^i in the numerator of aa to bb, keeping the denominator, and canonicalises. Allows ii up to 2(d−1)2(d - 1), so that the result may be unreduced; throws for larger ii.

Comparison#

int _nf_elem_equal(const nf_elem_t a, const nf_elem_t b, const nf_t nf)

Returns whether a=ba = b for reduced but not necessarily canonical aa and bb, by cross-multiplication, with a cheap test of the bit sizes first.

int nf_elem_equal(const nf_elem_t a, const nf_elem_t b, const nf_t nf)

Returns whether a=ba = b for canonical aa and bb, by comparing the representations.

int nf_elem_equal_si(const nf_elem_t a, const slong b, const nf_t nf)
int nf_elem_equal_ui(const nf_elem_t a, const ulong b, const nf_t nf)
int nf_elem_equal_fmpz(const nf_elem_t a, const fmpz_t b, const nf_t nf)
int nf_elem_equal_fmpq(const nf_elem_t a, const fmpq_t b, const nf_t nf)

Return whether the canonical element aa equals the rational number bb.

int nf_elem_is_zero(const nf_elem_t a, const nf_t nf)
int nf_elem_is_one(const nf_elem_t a, const nf_t nf)

Return whether aa is 0, respectively 1.

int nf_elem_is_gen(const nf_elem_t a, const nf_t nf)

Returns whether aa equals the generator θ\theta. In a field of degree 1 with defining polynomial f=f1x+f0f = f_1 x + f_0, the generator is the rational number −f0/f1-f_0/f_1.

int nf_elem_is_integer(const nf_elem_t a, const nf_t nf)
int nf_elem_is_rational(const nf_elem_t a, const nf_t nf)

Return whether the canonical element aa lies in Z\mathbb{Z}, respectively in Q\mathbf{Q}.

Input and output#

void nf_elem_print_pretty(const nf_elem_t a, const nf_t nf, const char * var)

Prints aa to stdout as a polynomial in the variable var, a nonempty string.

char * nf_elem_get_str_pretty(const nf_elem_t a, const char * var, const nf_t nf)

Returns the string printed by nf_elem_print_pretty, allocated with flint_malloc.

Arithmetic#

void nf_elem_neg(nf_elem_t a, const nf_elem_t b, const nf_t nf)

Sets aa to −b-b.

void _nf_elem_add(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)
void _nf_elem_sub(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)

Set aa to b+cb + c, respectively b−cb - c, without canonicalising.

void nf_elem_add(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)
void nf_elem_sub(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)

Set aa to b+cb + c, respectively b−cb - c.

void nf_elem_add_si(nf_elem_t a, const nf_elem_t b, slong c, const nf_t nf)
void nf_elem_add_fmpz(nf_elem_t a, const nf_elem_t b, const fmpz_t c, const nf_t nf)
void nf_elem_add_fmpq(nf_elem_t a, const nf_elem_t b, const fmpq_t c, const nf_t nf)
void nf_elem_sub_si(nf_elem_t a, const nf_elem_t b, slong c, const nf_t nf)
void nf_elem_sub_fmpz(nf_elem_t a, const nf_elem_t b, const fmpz_t c, const nf_t nf)
void nf_elem_sub_fmpq(nf_elem_t a, const nf_elem_t b, const fmpq_t c, const nf_t nf)
void nf_elem_si_sub(nf_elem_t a, slong c, const nf_elem_t b, const nf_t nf)
void nf_elem_fmpz_sub(nf_elem_t a, const fmpz_t c, const nf_elem_t b, const nf_t nf)
void nf_elem_fmpq_sub(nf_elem_t a, const fmpq_t c, const nf_elem_t b, const nf_t nf)

Set aa to b+cb + c, b−cb - c, respectively c−bc - b, for a rational number cc.

void nf_elem_scalar_mul_si(nf_elem_t a, const nf_elem_t b, slong c, const nf_t nf)
void nf_elem_scalar_mul_fmpz(nf_elem_t a, const nf_elem_t b, const fmpz_t c, const nf_t nf)
void nf_elem_scalar_mul_fmpq(nf_elem_t a, const nf_elem_t b, const fmpq_t c, const nf_t nf)

Set aa to cbcb.

void nf_elem_scalar_div_si(nf_elem_t a, const nf_elem_t b, slong c, const nf_t nf)
void nf_elem_scalar_div_fmpz(nf_elem_t a, const nf_elem_t b, const fmpz_t c, const nf_t nf)
void nf_elem_scalar_div_fmpq(nf_elem_t a, const nf_elem_t b, const fmpq_t c, const nf_t nf)

Set aa to b/cb/c for c≠0c \ne 0.

void nf_elem_mul_gen(nf_elem_t a, const nf_elem_t b, const nf_t nf)

Sets aa to θb\theta b, by a shift of the coefficients followed by one reduction step.

void _nf_elem_mul(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)
void _nf_elem_mul_red(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf, int red)

Set aa to bcbc without canonicalising, reducing modulo ff only if red is nonzero (always for _nf_elem_mul). The inputs must be reduced, and aa must not be aliased with bb or cc.

void nf_elem_mul(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)
void nf_elem_mul_red(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf, int red)

Set aa to bcbc, canonicalised. With red =0= 0 the product is not reduced modulo ff, which allows sums of products to be reduced once with nf_elem_reduce. The inputs must be reduced.

More
void _nf_elem_inv(nf_elem_t a, const nf_elem_t b, const nf_t nf)
void nf_elem_inv(nf_elem_t a, const nf_elem_t b, const nf_t nf)

Set aa to b−1b^{-1} for b≠0b \ne 0, by the extended Euclidean algorithm for bb and ff over Q\mathbf{Q}. _nf_elem_inv does not allow aliasing. The result is undefined for b=0b = 0.

void _nf_elem_div(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)
void nf_elem_div(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)

Set aa to b/cb/c for c≠0c \ne 0, as b⋅c−1b \cdot c^{-1}. _nf_elem_div does not canonicalise and does not allow aa to be aliased with bb.

void _nf_elem_pow(nf_elem_t res, const nf_elem_t a, ulong e, const nf_t nf)

Sets res to aea^e by left-to-right binary exponentiation [Knu1997, §4.6.3], for a≠0a \ne 0 and e≥2e \ge 2. Does not allow aliasing.

void nf_elem_pow(nf_elem_t res, const nf_elem_t a, ulong e, const nf_t nf)

Sets res to aea^e, with a0=1a^0 = 1 for all aa including zero.

Norm, trace and representation matrix#

void _nf_elem_norm(fmpz_t rnum, fmpz_t rden, const nf_elem_t a, const nf_t nf)
void nf_elem_norm(fmpq_t res, const nf_elem_t a, const nf_t nf)

Set the rational number rnum/rden, respectively res, to the absolute norm NK/Q(a)N_{K/\mathbf{Q}}(a), the product of the conjugates of aa. It is computed as Res⁡(f,a)\operatorname{Res}(f, a) divided by the appropriate power of the leading coefficient of ff; the resultant of the primitive parts is computed by _fmpz_poly_resultant, which uses the multimodular algorithm for large inputs and a pseudo-remainder (subresultant-type) Euclidean algorithm otherwise (Norm).

void _nf_elem_norm_div(fmpz_t rnum, fmpz_t rden, const nf_elem_t a, const nf_t nf, const fmpz_t divisor, slong nbits)
void nf_elem_norm_div(fmpq_t res, const nf_elem_t a, const nf_t nf, const fmpz_t divisor, slong nbits)

Set the result to NK/Q(a)/divisorN_{K/\mathbf{Q}}(a)/\mathtt{divisor}, assuming that the quotient of the resultant by divisor is an integer of at most nbits bits; the multimodular resultant (_fmpz_poly_resultant_modular_div) then needs only enough primes for the quotient. For divisor =0= 0 the result is 0.

void _nf_elem_trace(fmpz_t rnum, fmpz_t rden, const nf_elem_t a, const nf_t nf)
void nf_elem_trace(fmpq_t res, const nf_elem_t a, const nf_t nf)

Set the result to the absolute trace Tr⁡K/Q(a)\operatorname{Tr}_{K/\mathbf{Q}}(a), computed as ∑iaiSi\sum_i a_i S_i from the coefficients aia_i of aa and the power sums SiS_i of the roots of ff stored in the nf_t.

void nf_elem_rep_mat(fmpq_mat_t res, const nf_elem_t a, const nf_t nf)

Sets the d×dd \times d matrix res to the matrix of multiplication by aa with respect to the basis 1,θ,…,θd−11, \theta, \ldots, \theta^{d-1}, in the row convention: row jj holds the coordinates of θja\theta^j a.

void nf_elem_rep_mat_fmpz_mat_den(fmpz_mat_t res, fmpz_t den, const nf_elem_t a, const nf_t nf)

Sets res and den so that res/den is the matrix of nf_elem_rep_mat, with res primitive, that is, with content 1.

Reduction modulo integers#

These functions replace an element by a representative with reduced coefficients modulo an integer mm, as needed by multimodular and pp-adic algorithms over number fields. Let qq be the denominator of aa.

void _nf_elem_mod_fmpz(nf_elem_t res, const nf_elem_t a, const fmpz_t mod, const nf_t nf, int sign)

Sets res to the integral element whose coefficients are those of the numerator of aa reduced modulo mm = mod, ignoring the denominator, in [0,m)[0, m) if sign is zero and in the symmetric range otherwise.

void nf_elem_mod_fmpz_den(nf_elem_t res, const nf_elem_t a, const fmpz_t mod, const nf_t nf, int den)
void nf_elem_smod_fmpz_den(nf_elem_t res, const nf_elem_t a, const fmpz_t mod, const nf_t nf, int den)

If den is zero, set res to the integral element with the coefficients of qaqa reduced modulo mm. If den is nonzero, set res to z/qz/q, where zz is the numerator of aa reduced modulo mqmq, so that a−resa - \mathtt{res} is integral with coefficients divisible by mm. The mod versions use the residues in [0,m)[0, m) (or [0,mq)[0, mq)), the smod versions the symmetric residues.

void nf_elem_mod_fmpz(nf_elem_t res, const nf_elem_t a, const fmpz_t mod, const nf_t nf)
void nf_elem_smod_fmpz(nf_elem_t res, const nf_elem_t a, const fmpz_t mod, const nf_t nf)

The case den =1= 1 of the functions above.

void nf_elem_coprime_den(nf_elem_t res, const nf_elem_t a, const fmpz_t mod, const nf_t nf)
void nf_elem_coprime_den_signed(nf_elem_t res, const nf_elem_t a, const fmpz_t mod, const nf_t nf)

Set res to an element congruent to aa modulo mm whose denominator divides m∞m^\infty: writing q=q1q2q = q_1 q_2 with q1q_1 composed of the primes dividing mm and q2q_2 coprime to mm, the numerator of aa is multiplied by q2−1q_2^{-1} modulo mq1m q_1, reduced into [0,mq1)[0, m q_1) (or the symmetric range for the signed version) and divided by q1q_1. Then a−resa - \mathtt{res} has denominator coprime to mm and numerator coefficients divisible by mm.

Internal functions#

void _nf_elem_add_lf(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf, int can)
void _nf_elem_sub_lf(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf, int can)

Addition and subtraction in a field of degree 1, canonicalising the result if can is nonzero.

void _nf_elem_add_qf(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf, int can)
void _nf_elem_sub_qf(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf, int can)
void nf_elem_add_qf(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)
void nf_elem_sub_qf(nf_elem_t a, const nf_elem_t b, const nf_elem_t c, const nf_t nf)

Addition and subtraction in a field of degree 2, on all three numerator coefficients (so that unreduced elements can be added), canonicalising the result if can is nonzero (always for the versions without underscore). The underscore versions do not allow aa to be aliased with cc.

References#

  • [Knu1997] Knuth, D. E. The Art of Computer Programming, volume 2: Seminumerical algorithms, 1997
Cite this page

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