FLINT3.7.0-dev
Module · 183 functions

qqbar.h

#include <flint/qqbar.h>

A qqbar_t represents a real or complex algebraic number x \in \overline{\mathbb{Q}} exactly, by its minimal polynomial P \in \mathbb{Z}[t] (irreducible, primitive, with positive leading coefficient) and a complex ball that contains x and no other root of P. This representation is canonical: two qqbar_t values are equal if and only if they have the same minimal polynomial and their balls overlap, so equality, signs, comparisons and all predicates are decided exactly. The balls are refined automatically when an operation needs more precision.

The representation suits individual algebraic numbers of moderate degree, up to 100 say. Arithmetic is expensive: in the general case, x \pm y, xy and x/y for numbers of degrees m and n require an annihilating polynomial of degree mn that is computed from power sums and then factored over \mathbb{Z}, followed by selecting the right factor numerically. FLINT avoids this in many structured cases (quadratic operands, conjugate operands, operands in a common number field or cyclotomic field), see Arithmetic with algebraic numbers. For many operations in one fixed number field it is much more efficient to compute with ca_t (see ca.h) or directly with nf_elem.h, and to convert to qqbar_t only to decide predicates.

qqbar_t is used by ca.h to represent the algebraic generators of number fields and to decide predicates for algebraic numbers. The generic rings interface provides the fields of real and complex algebraic numbers with qqbar_t elements through gr_ctx_init_real_qqbar and gr_ctx_init_complex_qqbar, with optional limits on degrees and sizes set by _gr_ctx_qqbar_set_limits (see gr_domains); generic polynomial and matrix functions such as gr_poly_roots and gr_mat_eigenvalues then work over \overline{\mathbb{Q}}. The guide Using qqbar introduces the module with examples.

AlgorithmAlgebraic numbers by minimal polynomial and isolating ballThe canonical representation of an algebraic number by its minimal polynomial over Z and a complex ball isolating one root, its certification by the interval Newton method, refinement, and exact decisions of equality, realness and signs, as implemented in qqbar.

Guides#

Types and macros#

An algebraic number. The structure consists of an fmpz_poly_struct holding the minimal polynomial and an acb_struct holding the isolating ball (the enclosure). A qqbar_t is an array of one structure, so it is passed by reference.

Aliases for qqbar_struct * and const qqbar_struct *, used for arrays of algebraic numbers.

Give the minimal polynomial of x (usable as an fmpz_poly_t), its coefficient array (an fmpz *) and the enclosure (usable as an acb_t). The data must not be modified in a way that breaks the invariants: the polynomial must remain the primitive minimal polynomial with positive leading coefficient, and the ball must isolate the root.

The working precision (128 bits) at which isolating balls are computed by default and at which refinement loops start.

Memory management#

Initialises res and sets it to zero.

Clears res, freeing its memory.

Allocates an array of len algebraic numbers initialised to zero, or clears the len entries of vec and frees the array.

Assignment#

Swaps x and y in constant time.

void qqbar_set(qqbar_t res, const qqbar_t x)
void qqbar_set_fmpz(qqbar_t res, const fmpz_t x)
void qqbar_set_fmpq(qqbar_t res, const fmpq_t x)

Sets res to x. A rational number p/q in lowest terms with q > 0 has the minimal polynomial q t - p and an exact enclosure.

void qqbar_set_re_im(qqbar_t res, const qqbar_t x, const qqbar_t y)

Sets res to x + yi for real x and y (not checked).

int qqbar_set_d(qqbar_t res, double x)
int qqbar_set_re_im_d(qqbar_t res, double x, double y)

Sets res to the exact value of the double x, or of x + yi, and returns 1. If an input is infinite or NaN, returns 0 and leaves res unchanged.

Properties#

Returns the degree of x, that is, of its minimal polynomial.

Returns whether x is a rational number (degree 1), an integer, or an algebraic integer (its minimal polynomial is monic).

int qqbar_is_zero(const qqbar_t x)
int qqbar_is_one(const qqbar_t x)
int qqbar_is_i(const qqbar_t x)
int qqbar_is_neg_i(const qqbar_t x)

Returns whether x is 0, 1, -1, i or -i. These inspect the minimal polynomial (and the sign of the imaginary part of the enclosure for \pm i) and are therefore very fast.

int qqbar_is_real(const qqbar_t x)

Returns whether x is real. This is decided exactly, see qqbar_sgn_im.

void qqbar_height(fmpz_t res, const qqbar_t x)

Sets res to the height of x, the largest absolute value of a coefficient of its minimal polynomial, or returns the number of bits of the height.

int qqbar_within_limits(const qqbar_t x, slong deg_limit, slong bits_limit)

Returns whether x has degree at most deg_limit and height of at most bits_limit bits. A limit of 0 means no limit.

int qqbar_binop_within_limits(const qqbar_t x, const qqbar_t y, slong deg_limit, slong bits_limit)

Returns whether the trivial bounds for the result of a binary operation on x and y are within the limits: the product of the degrees must be at most deg_limit and the sum of the height bits at most bits_limit. The degree bound is rigorous, the height bound only a heuristic. A limit of 0 means no limit.

Conversions#

void _qqbar_get_fmpq(fmpz_t num, fmpz_t den, const qqbar_t x)
void qqbar_get_fmpq(fmpq_t res, const qqbar_t x)
void qqbar_get_fmpz(fmpz_t res, const qqbar_t x)

Sets the output to the rational number x (as a numerator and denominator for the underscore version), or to the integer x. Throws an exception if x is not rational, respectively not an integer.

Special values#

void qqbar_one(qqbar_t res)
void qqbar_i(qqbar_t res)
void qqbar_phi(qqbar_t res)

Sets res to 0, 1, the imaginary unit i, or the golden ratio \varphi = \frac{1}{2}(1 + \sqrt{5}).

Input and output#

void qqbar_print(const qqbar_t x)

Prints x to standard output in a form intended for debugging: the degree, the coefficients of the minimal polynomial (from the constant term upwards) and the enclosure, for example deg 2 [-1, -1, 1] [1.61803398874989484820458683436563811772 +/- 6.00e-39] for \varphi.

void qqbar_printn(const qqbar_t x, slong n)
void qqbar_printnd(const qqbar_t x, slong n)

Prints a decimal approximation of x with n significant digits to standard output, such as 1.41421 - 1.73205*I; qqbar_printnd appends the degree, as in 1.41421 - 1.73205*I (deg 4).

char * qqbar_get_str_nd(const qqbar_t x, slong n)

Returns a string with the output of qqbar_printnd. The caller must free it with flint_free.

Random generation#

void qqbar_randtest(qqbar_t res, flint_rand_t state, slong deg, slong bits)
void qqbar_randtest_real(qqbar_t res, flint_rand_t state, slong deg, slong bits)

Sets res to a random algebraic number, a random real algebraic number, or a random nonreal algebraic number, with degree at most deg and height of at most bits bits. For qqbar_randtest_nonreal, deg must be at least 2.

Comparisons#

All comparisons are exact. They first compare enclosures, refining them as needed, and fall back to exact computations (such as computing x - y) only when the numbers are equal or very close.

int qqbar_equal(const qqbar_t x, const qqbar_t y)

Returns whether x = y: the minimal polynomials must be equal and the enclosures must contain a common root, which is decided by refining them until they are disjoint or their union is proved to contain a single root.

int qqbar_equal_fmpq_poly_val(const qqbar_t x, const fmpq_poly_t f, const qqbar_t y)

Returns whether x = f(y). This is faster than computing f(y) with qqbar_evaluate_fmpq_poly: the value f(y) is first compared numerically with x, and only if they cannot be separated is P(f(y)) = 0 checked exactly in \mathbb{Q}(y), where P is the minimal polynomial of x.

int qqbar_cmp_re(const qqbar_t x, const qqbar_t y)
int qqbar_cmp_im(const qqbar_t x, const qqbar_t y)

Compares the real parts, or the imaginary parts, of x and y, returning -1, 0 or 1.

int qqbar_cmpabs_re(const qqbar_t x, const qqbar_t y)
int qqbar_cmpabs_im(const qqbar_t x, const qqbar_t y)
int qqbar_cmpabs(const qqbar_t x, const qqbar_t y)

Compares the absolute values of the real parts, of the imaginary parts, or of x and y themselves, returning -1, 0 or 1.

int qqbar_cmp_root_order(const qqbar_t x, const qqbar_t y)

Compares x and y in the order used to sort roots of polynomials, returning -1, 0 or 1: real numbers come first, in decreasing order; nonreal numbers follow, by decreasing real part, then by increasing absolute value of the imaginary part, then with positive imaginary part first. Complex conjugates are therefore adjacent, the one in the upper half-plane first.

Returns a hash of x. Currently only the minimal polynomial is hashed, so conjugates have equal hashes, and similar polynomials give similar hash values; apply an integer hash function to the result if all bits must look random.

Complex parts#

void qqbar_conj(qqbar_t res, const qqbar_t x)

Sets res to the complex conjugate of x (the minimal polynomial is unchanged).

void qqbar_re(qqbar_t res, const qqbar_t x)
void qqbar_im(qqbar_t res, const qqbar_t x)
void qqbar_re_im(qqbar_t res1, qqbar_t res2, const qqbar_t x)

Sets res to the real part or the imaginary part of x, or res1 and res2 to both, computed as (x + \overline{x})/2 and (x - \overline{x})/(2i).

void qqbar_abs(qqbar_t res, const qqbar_t x)
void qqbar_abs2(qqbar_t res, const qqbar_t x)

Sets res to |x| or |x|^2 = x \overline{x}.

void qqbar_sgn(qqbar_t res, const qqbar_t x)

Sets res to the complex sign of x: 0 if x = 0, otherwise x/|x|.

int qqbar_sgn_re(const qqbar_t x)
int qqbar_sgn_im(const qqbar_t x)

Returns the sign (-1, 0 or 1) of the real or imaginary part of x.

More
int qqbar_csgn(const qqbar_t x)

Returns the extension of the real sign function that is 1 in the open right half-plane, -1 in the open left half-plane, the sign of the imaginary part on the imaginary axis, and 0 at 0; equivalently \operatorname{csgn}(x) = x / \sqrt{x^2} for x \ne 0.

Integer parts#

void qqbar_floor(fmpz_t res, const qqbar_t x)
void qqbar_ceil(fmpz_t res, const qqbar_t x)

Sets res to \lfloor x \rfloor or \lceil x \rceil; for nonreal x, of its real part.

Arithmetic#

Arithmetic with a rational operand is an affine transformation of the minimal polynomial (see qqbar_scalar_op) and is cheap. Arithmetic with two irrational operands is described in Arithmetic with algebraic numbers.

void qqbar_neg(qqbar_t res, const qqbar_t x)

Sets res to -x.

void qqbar_add(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_add_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y)
void qqbar_add_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y)
void qqbar_add_ui(qqbar_t res, const qqbar_t x, ulong y)
void qqbar_add_si(qqbar_t res, const qqbar_t x, slong y)

Sets res to x + y.

void qqbar_sub(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_sub_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y)
void qqbar_sub_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y)
void qqbar_sub_ui(qqbar_t res, const qqbar_t x, ulong y)
void qqbar_sub_si(qqbar_t res, const qqbar_t x, slong y)
void qqbar_fmpq_sub(qqbar_t res, const fmpq_t x, const qqbar_t y)
void qqbar_fmpz_sub(qqbar_t res, const fmpz_t x, const qqbar_t y)
void qqbar_ui_sub(qqbar_t res, ulong x, const qqbar_t y)
void qqbar_si_sub(qqbar_t res, slong x, const qqbar_t y)

Sets res to x - y.

void qqbar_mul(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_mul_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y)
void qqbar_mul_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y)
void qqbar_mul_ui(qqbar_t res, const qqbar_t x, ulong y)
void qqbar_mul_si(qqbar_t res, const qqbar_t x, slong y)

Sets res to x y.

void qqbar_mul_2exp_si(qqbar_t res, const qqbar_t x, slong e)

Sets res to x \cdot 2^e.

void qqbar_sqr(qqbar_t res, const qqbar_t x)

Sets res to x^2.

void qqbar_inv(qqbar_t res, const qqbar_t x)

Sets res to 1/x, whose minimal polynomial is the reversal of that of x. Throws an exception (FLINT_DIVZERO) if x = 0.

void qqbar_div(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_div_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y)
void qqbar_div_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y)
void qqbar_div_ui(qqbar_t res, const qqbar_t x, ulong y)
void qqbar_div_si(qqbar_t res, const qqbar_t x, slong y)
void qqbar_fmpq_div(qqbar_t res, const fmpq_t x, const qqbar_t y)
void qqbar_fmpz_div(qqbar_t res, const fmpz_t x, const qqbar_t y)
void qqbar_ui_div(qqbar_t res, ulong x, const qqbar_t y)
void qqbar_si_div(qqbar_t res, slong x, const qqbar_t y)

Sets res to x / y. Throws an exception (FLINT_DIVZERO) if y = 0.

void qqbar_scalar_op(qqbar_t res, const qqbar_t x, const fmpz_t a, const fmpz_t b, const fmpz_t c)

Sets res to (a x + b)/c in one operation, for integers a, b and c \ne 0, by transforming the minimal polynomial and the enclosure. Throws an exception if c = 0.

Powers and roots#

void qqbar_sqrt(qqbar_t res, const qqbar_t x)

Sets res to the principal square root of x.

void qqbar_rsqrt(qqbar_t res, const qqbar_t x)

Sets res to 1/\sqrt{x}. Throws an exception if x = 0.

void qqbar_pow_ui(qqbar_t res, const qqbar_t x, ulong n)
void qqbar_pow_si(qqbar_t res, const qqbar_t x, slong n)
void qqbar_pow_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t n)
void qqbar_pow_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t n)

Sets res to x^n; for rational n = p/q the principal branch (x^{1/q})^p. x^0 = 1 for all x. Raising zero to a negative power throws an exception, and so does a rational exponent whose numerator or denominator does not fit in a word.

void qqbar_root_ui(qqbar_t res, const qqbar_t x, ulong n)
void qqbar_fmpq_root_ui(qqbar_t res, const fmpq_t x, ulong n)

Sets res to the principal n-th root of x, for n \ge 1. The minimal polynomial is found among the factors of P(t^n), where P is the minimal polynomial of x; principal roots of positive rational numbers and roots of roots of unity are computed directly.

void qqbar_fmpq_pow_si_ui(qqbar_t res, const fmpq_t x, slong m, ulong n)

Sets res to the principal branch of x^{m/n} for a rational x and n \ge 1. Throws an exception if x = 0 and m < 0.

int qqbar_pow(qqbar_t res, const qqbar_t x, const qqbar_t y)

General exponentiation: if x^y is an algebraic number, sets res to it and returns 1; if x^y is transcendental or undefined, returns 0. By the Gelfond–Schneider theorem, x^y for algebraic x \notin \{0, 1\} and irrational algebraic y is transcendental, so the result is algebraic only if y is rational, x \in \{0, 1\} or y = 0. Unlike the other functions, this one returns 0 instead of throwing for 0^y with \operatorname{Re}(y) \le 0, y \ne 0.

Numerical enclosures#

The following functions return polished enclosures, in which the real and imaginary parts are both accurate to prec bits and are exact when they are exactly representable (that is, when a real or imaginary part is a sufficiently small dyadic number). Polishing can be expensive; use qqbar_enclosure_raw when it is not needed, or qqbar_cache_enclosure to avoid repeated work.

void qqbar_get_acb(acb_t res, const qqbar_t x, slong prec)
void qqbar_get_arb(arb_t res, const qqbar_t x, slong prec)

Sets res to an enclosure of x rounded to prec bits. For qqbar_get_arb, if x is not real, res is set to [\mathrm{NaN} \pm \infty].

void qqbar_get_arb_re(arb_t res, const qqbar_t x, slong prec)
void qqbar_get_arb_im(arb_t res, const qqbar_t x, slong prec)

Sets res to an enclosure of the real or imaginary part of x rounded to prec bits.

Refines the enclosure stored in res to somewhat more than prec bits (at least QQBAR_DEFAULT_PREC). Operations normally refine enclosures in temporary variables without storing the result; calling this function first helps when res is used as an operand many times.

Numerator and denominator#

void qqbar_denominator(fmpz_t res, const qqbar_t y)

Sets res to the leading coefficient d of the minimal polynomial of y, a denominator in the sense that d y is an algebraic integer.

void qqbar_numerator(qqbar_t res, const qqbar_t y)

Sets res to d y, where d is given by qqbar_denominator.

Conjugates#

Sets the entries of the array res to the d conjugates of x (including x), where d is the degree of x, sorted as by qqbar_cmp_root_order.

Polynomial evaluation#

void _qqbar_evaluate_fmpq_poly(qqbar_t res, const fmpz * poly, const fmpz_t den, slong len, const qqbar_t x)
void qqbar_evaluate_fmpq_poly(qqbar_t res, const fmpq_poly_t poly, const qqbar_t x)
void _qqbar_evaluate_fmpz_poly(qqbar_t res, const fmpz * poly, slong len, const qqbar_t x)
void qqbar_evaluate_fmpz_poly(qqbar_t res, const fmpz_poly_t poly, const qqbar_t x)

Sets res to f(x) for the polynomial f given by poly (with denominator den for the underscore fmpq version). The polynomial is first reduced modulo the minimal polynomial of x if its degree is too large; constant and linear polynomials and rational x are handled directly. In general, the minimal polynomial of f(x) is the minimal polynomial of the matrix of multiplication by f(x) in \mathbb{Q}(x), see Arithmetic with algebraic numbers.

int qqbar_evaluate_fmpz_mpoly(qqbar_t res, const fmpz_mpoly_t poly, qqbar_srcptr x, slong deg_limit, slong bits_limit, const fmpz_mpoly_ctx_t ctx)

Sets res to the value of the multivariate polynomial poly at the algebraic numbers x (one per variable of ctx) and returns 1. If a temporary result (not necessarily the final value, in case of cancellation) exceeds deg_limit or bits_limit in the sense of qqbar_binop_within_limits, the evaluation is aborted and 0 is returned. The evaluation uses the generic multivariate Horner scheme gr_fmpz_mpoly_evaluate_horner over the \overline{\mathbb{Q}} context (gr_fmpz_mpoly_evaluate_iter for a single term).

Polynomial roots#

Flags for the root-finding functions: the polynomial is known to be irreducible (it may still have content), so that no factorisation is done; the roots need not be sorted.

Full documentation
void qqbar_roots_fmpz_poly(qqbar_ptr res, const fmpz_poly_t poly, int flags)
void qqbar_roots_fmpq_poly(qqbar_ptr res, const fmpq_poly_t poly, int flags)

Sets the entries of the array res to the d = \deg(\mathit{poly}) roots of poly, repeated according to multiplicity. Unless QQBAR_ROOTS_UNSORTED is given, the roots are sorted by qqbar_cmp_root_order; copies of a repeated root are always consecutive. See Roots of polynomials and eigenvalues.

Full documentation

Sets the first entries of res to the real roots of poly, repeated according to multiplicity, and returns their number. The array must have room for \deg(\mathit{poly}) entries. Unless QQBAR_ROOTS_UNSORTED is given, the roots are in decreasing order, so that the output agrees with the first entries of the output of qqbar_roots_fmpz_poly. This is faster than computing all roots, since nonreal roots are never isolated and factors without real roots are skipped.

Full documentation
void qqbar_eigenvalues_fmpz_mat(qqbar_ptr res, const fmpz_mat_t mat, int flags)
void qqbar_eigenvalues_fmpq_mat(qqbar_ptr res, const fmpq_mat_t mat, int flags)

Sets the entries of res to the eigenvalues of the square matrix mat, repeated according to algebraic multiplicity, by computing the characteristic polynomial and calling qqbar_roots_fmpz_poly with the same flags.

Full documentation
int _qqbar_roots_poly_squarefree(qqbar_ptr roots, qqbar_srcptr coeffs, slong len, slong deg_limit, slong bits_limit)

Sets roots to the d = \mathit{len} - 1 roots of the squarefree polynomial f = a_0 + \cdots + a_d x^d with algebraic coefficients coeffs (a_d \ne 0), and returns 1; returns 0 if a limit is exceeded.

More

Roots of unity and trigonometric functions#

The following functions take rational numbers as two words p, q rather than as fmpq_t, since the minimal polynomials have degree O(q) and only small q are feasible. The inputs need not be reduced but should not be close to the limits of a word, as they may be added or multiplied internally.

Sets res to the root of unity e^{2 \pi i p / q} or e^{\pi i p / q}. The minimal polynomial is a cyclotomic polynomial.

int qqbar_is_root_of_unity(slong * p, ulong * q, const qqbar_t x)

Returns whether x is a root of unity, that is, whether its minimal polynomial is cyclotomic. If so and if p and q are not NULL, sets them to the integers with 0 \le p < q and \gcd(p, q) = 1 such that x = e^{2 \pi i p / q}.

Sets res to \cos(\pi x), \sin(\pi x), \tan(\pi x), \cot(\pi x), \sec(\pi x) or \csc(\pi x) for x = p/q. The functions with an int return value return 1, or 0 if x is a pole. The cosine uses the minimal polynomial of \cos(2 \pi / n) (fmpz_poly_cos_minpoly), and the other functions are reduced to it.

int qqbar_log_pi_i(slong * p, ulong * q, const qqbar_t x)

If y = \log(x) / (\pi i) is algebraic, which happens exactly when x is a root of unity and then y is rational, sets p/q to y in lowest terms with -1 < y \le 1 and returns 1; otherwise returns 0.

int qqbar_atan_pi(slong * p, ulong * q, const qqbar_t x)
int qqbar_asin_pi(slong * p, ulong * q, const qqbar_t x)
int qqbar_acos_pi(slong * p, ulong * q, const qqbar_t x)
int qqbar_acot_pi(slong * p, ulong * q, const qqbar_t x)
int qqbar_asec_pi(slong * p, ulong * q, const qqbar_t x)
int qqbar_acsc_pi(slong * p, ulong * q, const qqbar_t x)

If y = f(x) / \pi is algebraic, where f is the principal branch of the inverse trigonometric function, sets p/q to y (necessarily rational) in lowest terms and returns 1; otherwise returns 0. The ranges are |y| < \frac{1}{2} for atan, |y| \le \frac{1}{2} for asin and acsc, 0 \le y \le 1 for acos and asec, and -\frac{1}{2} < y \le \frac{1}{2} for acot.

Guessing and simplification#

int qqbar_guess(qqbar_t res, const acb_t z, slong max_deg, slong max_bits, int flags, slong prec)

Tries to find an algebraic number of degree at most max_deg and height of at most max_bits bits contained in the ball z, using LLL to find an integer relation between 1, z, \ldots, z^{\mathit{max\_deg}} at working precision prec. Returns 1 and sets res on success. The result is only a heuristic: success does not prove that the number behind z equals res, and failure does not prove that no such algebraic number exists.

More
int qqbar_express_in_field(fmpq_poly_t res, const qqbar_t alpha, const qqbar_t x, slong max_bits, int flags, slong prec)

Tries to express x in the number field \mathbb{Q}(\alpha): on success, returns 1 and sets res to a polynomial f of degree less than \deg \alpha with f(\alpha) = x. The identity is verified exactly, so success is proved. Failure does not prove that x \notin \mathbb{Q}(\alpha).

More

Symbolic expressions and radicals#

The functions in this section use fexpr_t (see fexpr.h) and are declared only if fexpr.h is included before qqbar.h. See Symbolic expressions and closed forms for examples.

void qqbar_get_quadratic(fmpz_t res_a, fmpz_t res_b, fmpz_t res_c, fmpz_t res_q, const qqbar_t x, int factoring)

For x of degree 1 or 2, computes integers a, b, c, q with x = (a + b \sqrt{c})/q, q > 0, \gcd(a, b, q) = 1 and c not a perfect square; for rational x, b = c = 0.

Full documentation
int qqbar_set_fexpr(qqbar_t res, const fexpr_t expr)

Sets res to the algebraic number given by the expression expr and returns 1, or returns 0 if expr is not understood.

Full documentation

Sets res to AlgebraicNumberSerialized(List(coeffs), enclosure), which reflects the internal representation exactly. It can be read back with qqbar_set_fexpr cheaply and is the recommended format for serialisation, although it is not meant for human readers.

Full documentation

Sets res to PolynomialRootNearest(List(coeffs), point), where the decimal point is closer to x than to any other root, or to PolynomialRootIndexed(List(coeffs), index), where index (starting from 1) is the position of x among the roots in the order of qqbar_cmp_root_order. Both describe x unambiguously and readably, and can be read back with qqbar_set_fexpr, at the cost of root isolation.

Full documentation
int qqbar_get_fexpr_formula(fexpr_t res, const qqbar_t x, ulong flags)

Tries to write x as a closed-form expression with arithmetic operations, radicals and possibly exponentials or trigonometric functions, without PolynomialRootNearest or PolynomialRootIndexed. Returns 1 on success and 0 on failure. flags selects the methods (with flags = 0 only rational numbers are handled).

Full documentation

Methods for qqbar_get_fexpr_formula: recognise Gaussian rationals a + bi; write quadratic numbers as a + b \sqrt{d}; recognise elements of cyclotomic fields, by trying plausible fields, finding candidate representations with LLL and verifying them exactly (heuristic, not guaranteed to find all); solve cubics, quartics and quintics (not yet implemented); depression (not yet implemented); deflation, which handles numbers a^{1/n} where a has a closed form; separation into real and imaginary parts a + bi or modulus and sign m s, tried as a fallback when the other methods fail. QQBAR_FORMULA_ALL enables all methods, which can be expensive.

Full documentation

The form used for elements of cyclotomic fields. The automatic form (0, the default) gives radicals for numbers of low degree, trigonometric functions for real numbers and complex exponentials for nonreal numbers; the other flags (not fully implemented) request exponentials, trigonometric functions or radicals.

Full documentation

Internal functions#

For nonconstant A and B, sets res to a polynomial whose roots are a + b (op = 0), a - b (1), a b (2) or a / b (3) for all roots a of A and b of B, with multiplicity. For op = 3, B must not have the root zero. The polynomial is computed from power sums with power series arithmetic over \mathbb{Q}, see Arithmetic with algebraic numbers.

For A of degree d \ge 2 with roots a_1, \ldots, a_d, sets res to a nonzero integer multiple of the polynomial of degree d(d-1)/2 with roots a_i + a_j (op = 0), (a_i - a_j)^2 (op = 1) or a_i a_j (op = 2) for 1 \le i < j \le d. For two distinct roots x, y of an irreducible A (such as complex conjugates), this annihilates x + y, (x - y)^2 or x y with half the degree of the polynomial from qqbar_fmpz_poly_composed_op.

void qqbar_binary_op(qqbar_t res, const qqbar_t x, const qqbar_t y, int op)

Sets res to x + y, x - y, x y or x / y for op = 0, 1, 2, 3. Trivial cases such as rational operands are not handled here (the public arithmetic functions do that), but structure is exploited to avoid factoring a composed polynomial of degree \deg x \deg y when possible.

More
int _qqbar_validate_uniqueness(acb_t res, const fmpz_poly_t poly, const acb_t z, slong max_prec)

Given a ball z known to contain at least one root of poly, tries to prove that it contains exactly one, by one step of the interval Newton method on a slightly enlarged ball. On success sets res to the resulting (possibly smaller) enclosure of the root and returns 1; otherwise returns 0. The working precision is chosen from the accuracy of z, up to max_prec bits (a value of 0 selects it automatically). Uniqueness on the enlarged ball implies uniqueness on z but not existence, which must be known beforehand.

int _qqbar_validate_existence_uniqueness(acb_t res, const fmpz_poly_t poly, const acb_t z, slong max_prec)

Like _qqbar_validate_uniqueness, but for an arbitrary ball z: proves that z contains exactly one root of poly (one interval Newton step whose result lies in the interior of z). For a real (or purely imaginary) ball the step is done on the real line (or imaginary axis), which proves that the root lies there.

void _qqbar_enclosure_raw(acb_t res, const fmpz_poly_t poly, const acb_t z, slong prec)
void qqbar_enclosure_raw(acb_t res, const qqbar_t x, slong prec)

Sets res to an enclosure of the root of poly isolated by z (or of x) with about prec bits of accuracy, by interval Newton steps with doubling precision; if a step fails to improve the accuracy enough, the roots are recomputed from scratch at higher precision. If z is already accurate enough, it is returned without rounding. The result is not polished as by qqbar_get_acb.

int _qqbar_acb_lindep(fmpz * rel, acb_srcptr vec, slong len, int check, slong prec)

Tries to find an integer vector rel with \sum_i \mathit{rel}_i \mathit{vec}_i \approx 0 using LLL. The working precision is the smaller of prec and the relative accuracy of vec; 95% of the bits go into the LLL matrix and the remaining 5% are used to check the relation by evaluating it in ball arithmetic. If check is set, the return value says whether this check passed; otherwise it says whether the algorithm ran normally (it fails, for example, for non-finite input). A passed check is a heuristic filter against spurious relations, not a proof.

Returns 1 if x is cheaply recognised, from its minimal polynomial q t^d - p and its enclosure, as the principal root (p/q)^{1/d} of a positive rational number with d \ge 2, and 0 otherwise (0 does not prove the contrary). Used to speed up qqbar_root_ui.

Cite this page

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