qfb.h
#include <flint/qfb.h>This module implements binary quadratic forms f(x, y) = ax^2 + bxy + cy^2 with integer coefficients, written (a, b, c), of discriminant D = b^2 - 4ac. It supports positive definite forms (D < 0, a > 0): reduction to the unique reduced form of an equivalence class, the list of all reduced primitive forms of a discriminant (whose number is the class number h(D)), composition by Shanks' NUCOMP algorithm, powering, prime forms, and the computation of the order of a form and of the exponent of the class group. Indefinite forms are not supported.
The guide Computing in the class group shows how to compute in the class group, and Binary quadratic forms and class groups describes the algorithms. The original module was written by William Hart; the documentation was later revised by Håvard Damm-Johnsen.
AlgorithmBinary quadratic forms and class groupsReduction of positive definite binary quadratic forms, enumeration of the reduced forms of a discriminant (the class number), composition by Shanks' NUCOMP, and the computation of orders and of the exponent of the form class group by a two-stage method in the style of Pollard and Sutherland.Guides#
Types and memory management#
void qfb_array_clear(qfb ** forms, slong num)Clears the first num forms of the array *forms and frees the array, as allocated by qfb_reduced_forms.
Basic operations#
Returns 1 if f and g have the same coefficients, otherwise 0. For reduced forms this tests equivalence.
void qfb_discriminant(fmpz_t D, qfb_t f)Sets D to the discriminant b^2 - 4ac of f = (a, b, c).
int qfb_is_primitive(qfb_t f)Returns 1 if \gcd(a, b, c) = 1, otherwise 0.
Reduction and enumeration#
A positive definite form is reduced if |b| \le a \le c, and b \ge 0 if |b| = a or a = c. Every positive definite form is equivalent under \mathrm{SL}_2(\mathbb{Z}) to exactly one reduced form.
void qfb_reduce(qfb_t r, qfb_t f, fmpz_t D)Sets r to the reduced form equivalent to the positive definite form f, whose discriminant must be D (used to recompute c). Aliasing is allowed.
int qfb_is_reduced(qfb_t r)Returns 1 if the positive definite form r is reduced, otherwise 0.
slong qfb_reduced_forms(qfb ** forms, slong d)slong qfb_reduced_forms_large(qfb ** forms, slong d)Compute all reduced primitive positive definite forms of discriminant d < 0, allocate an array for them, store it in *forms and return their number, the class number h(d). The forms are in no particular order. The array must be freed with qfb_array_clear(forms, num). Returns 0 (with *forms set to NULL) if d \not\equiv 0, 1 \pmod 4, and throws for d \ge 0.
The class group#
The primitive forms of discriminant D modulo equivalence form a finite abelian group under Gauss composition, the form class group, whose identity is the class of the principal form and in which the inverse of the class of (a, b, c) is the class of (a, -b, c).
void qfb_principal_form(qfb_t f, fmpz_t D)Sets f to the principal form of discriminant D, (1, 0, -D/4) for D \equiv 0 \pmod 4 and (1, 1, (1 - D)/4) for D \equiv 1 \pmod 4.
int qfb_is_principal_form(qfb_t f, fmpz_t D)Returns 1 if f is the reduced principal form of discriminant D (the identity of the class group, for reduced f), otherwise 0.
void qfb_inverse(qfb_t r, qfb_t f)Sets r to the reduced inverse of the reduced form f: (a, -b, c), or f itself if a = b or a = c (such forms have order at most 2).
void qfb_prime_form(qfb_t r, fmpz_t D, fmpz_t p)Sets r to a form (p, b, c) of discriminant D with 0 \le b \le p, for a prime p such that D is a square modulo 4p (that is, p splits or ramifies). The result is not specified otherwise. If p^2 \mid D the form may be imprimitive.
Sets r to a form in the class of the composition of f and g, both of discriminant D, by Shanks' NUCOMP algorithm in the version of Jacobson and van der Poorten [JvdP2002], with a partial Lehmer extended GCD (fmpz_xgcd_partial). The parameter must be L = \lfloor |D|^{1/4} \rfloor. The result is nearly reduced (its coefficients are of the size of \sqrt{|D|}) but must be passed to qfb_reduce to obtain the reduced form. f must be primitive.
void qfb_nudupl(qfb_t r, const qfb_t f, fmpz_t D, fmpz_t L)As qfb_nucomp for the composition of f with itself (NUDUPL), which needs fewer operations. f must be primitive.
void qfb_pow_ui(qfb_t r, qfb_t f, fmpz_t D, ulong exp)Set r to the reduced form in the class of f^{\mathit{exp}}, by binary powering with NUDUPL and NUCOMP and a reduction after each step. D must be the discriminant of f, which must be primitive. For exponent 0 the result is the principal form and for exponent 1 a copy of f (not reduced if f is not). qfb_pow_with_root takes L = \lfloor |D|^{1/4} \rfloor as an argument instead of computing it. A negative fmpz_t exponent is allowed: the result is then the power -\mathit{exp} of the inverse form (qfb_inverse).
Order and exponent#
Tries to find the order of the class of the reduced primitive form f in the class group of discriminant n. Returns 1 and sets exponent to the order on success, and returns 0 if the order is not of the form s \cdot q with s a product of prime powers below about B1 and q a prime below about B2_sqrt squared.
Tries to compute the exponent of the class group of discriminant n < 0, the least common multiple of the orders of its elements, as the least common multiple of the orders of prime forms for small primes. Returns 1 and sets exponent on success, and 0 if qfb_exponent_element fails. The parameter c controls the number of prime forms tried; the result is the exponent with high probability (heuristically, at least 1 - 2^{-c}), but it is not proved. The bounds B1 and B2_sqrt are as for qfb_exponent_element.
int qfb_exponent_grh(fmpz_t exponent, fmpz_t n, ulong B1, ulong B2_sqrt)As qfb_exponent, but uses the prime forms of all primes p < 6 \log^2 |n| that split or ramify. Assuming the generalised Riemann hypothesis, these generate the class group [Bach1990], [BD1992], so the result is the exponent of the class group if the function returns 1.
Hash tables#
These functions implement a simple hash table of forms with open addressing, used for the baby-step giant-step stage of qfb_exponent_element. Forms are hashed by a modulo 2^{\mathit{depth}}.
An entry of the table: the form q, a second form q2 and an integer iter.
qfb_hash_t * qfb_hash_init(slong depth)void qfb_hash_clear(qfb_hash_t * qhash, slong depth)Allocate a table of 2^{\mathit{depth}} empty entries (with q->a zero) and free it.
void qfb_hash_insert(qfb_hash_t * qhash, qfb_t q, qfb_t q2, slong iter, slong depth)Stores q, q2 (unless it is NULL) and iter in the first free entry at or after the position given by the hash of q. An exception is raised if the table is full.
slong qfb_hash_find(qfb_hash_t * qhash, qfb_t q, slong depth)Returns the index of an entry containing q or its inverse (the same a and |b|), or -1 if there is none (also when the table is full and does not contain it).
References#
- [JvdP2002] M. J. Jacobson Jr. and A. J. van der Poorten. "Computational aspects of NUCOMP." In International Algorithmic Number Theory Symposium, pp. 120-133. Berlin, Heidelberg: Springer Berlin Heidelberg, 2002.
- [Bach1990] E. Bach, "Explicit bounds for primality testing and related problems", Mathematics of Computation 55 (1990), 355–380. https://doi.org/10.1090/S0025-5718-1990-1023756-8
- [BD1992] D. Buchmann and S. Düllmann. "Distributed class group computation." Informatik: Festschrift zum 60. Geburtstag von Günter Hotz (1992): 69-79.
The FLINT team, “qfb.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/qfb/index.html (generated 2026-10-20).
@misc{flint-doc-qfb-index,
author = {{The FLINT team}},
title = {{qfb.h (module overview)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/qfb/index.html},
note = {Generated 2026-10-20}
}