fmpz_poly_q.hRepresentation and arithmetic of rational functions
An fmpz_poly_q_t represents as a quotient of integer polynomials with in and having positive leading coefficient. Any has exactly one such representation: clearing denominators of a representation over gives one over , and two coprime representations satisfy , so and by Gauss's lemma, hence . Since the gcd in includes the content, is not canonical, while is.
Canonical forms make equality testing a comparison of coefficients, but reducing a quotient costs a polynomial gcd in , which is much more expensive than a product. The arithmetic functions therefore never reduce a full product. They use Henrici's algorithms [Hen1956], which exploit the coprimality of the inputs to cancel common factors before multiplying.
Henrici's algorithms#
Let and be canonical.
Lemma 1 (Products). With and ,
and the right-hand side is canonical up to the sign of the denominator.
Proof. An irreducible dividing both the numerator and the denominator divides one of , and one of , . It cannot divide both and , since , and it cannot divide both and , by the definition of ; the other two cases are symmetric.
Lemma 2 (Sums). With , , and ,
Proof. , because and ; likewise . So every common factor of and divides .
So a sum costs one gcd of the denominators and one gcd of with the (usually small) , and a product two gcds of polynomials of the size of the inputs, instead of a gcd of the full numerator and denominator. When the denominators are coprime, which is the common case, no cancellation happens at all. fmpz_poly_q_add, fmpz_poly_q_sub, fmpz_poly_q_mul and fmpz_poly_q_div implement these formulas, with shortcuts for zero operands, for denominators equal to 1 and for constant denominators, where the arithmetic of fmpq_poly is used. The derivative is computed with a similar saving: with and , whose numerator and denominator can only share a constant factor [Hor1972].
Working with numerators and denominators#
fmpz_poly_q_numref and fmpz_poly_q_denref give access to the two fmpz_poly_structs, so any fmpz_poly function can be used to build a rational function, after which fmpz_poly_q_canonicalise restores the canonical form. Strings in the format of fmpz_poly_q_set_str are an alternative for small inputs.
#include <flint/flint.h>
#include <flint/fmpq.h>
#include <flint/fmpz_poly.h>
#include <flint/fmpz_poly_q.h>
int main(void)
{
fmpz_poly_q_t f, g, h;
fmpq_t a, v;
fmpz_poly_q_init(f);
fmpz_poly_q_init(g);
fmpz_poly_q_init(h);
fmpq_init(a);
fmpq_init(v);
/* f = (2x^2 - 2)/(4x^2 + 4x), built directly, then canonicalised */
fmpz_poly_set_str(fmpz_poly_q_numref(f), "3 -2 0 2");
fmpz_poly_set_str(fmpz_poly_q_denref(f), "3 0 4 4");
fmpz_poly_q_canonicalise(f);
flint_printf("f = "); fmpz_poly_q_print_pretty(f, "x");
flint_printf(" ("); fmpz_poly_q_print(f); flint_printf(")\n");
fmpz_poly_q_set_str(g, "2 1 3/1 2"); /* (3x + 1)/2 */
fmpz_poly_q_mul(h, f, g);
flint_printf("f g = "); fmpz_poly_q_print_pretty(h, "x"); flint_printf("\n");
fmpz_poly_q_add(h, f, g);
flint_printf("f + g = "); fmpz_poly_q_print_pretty(h, "x"); flint_printf("\n");
fmpz_poly_q_derivative(h, f);
flint_printf("f' = "); fmpz_poly_q_print_pretty(h, "x"); flint_printf("\n");
fmpq_set_si(a, 1, 3);
if (fmpz_poly_q_evaluate_fmpq(v, f, a) == 0)
{
flint_printf("f(1/3) = "); fmpq_print(v); flint_printf("\n");
}
fmpq_set_si(a, 0, 1);
flint_printf("f(0) defined: %d\n", fmpz_poly_q_evaluate_fmpq(v, f, a) == 0);
fmpz_poly_q_clear(f);
fmpz_poly_q_clear(g);
fmpz_poly_q_clear(h);
fmpq_clear(a);
fmpq_clear(v);
return 0;
}f = (x-1)/(2*x) (2 -1 1/2 0 2) f g = (3*x^2-2*x-1)/(4*x) f + g = (3*x^2+2*x-1)/(2*x) f' = 1/(2*x^2) f(1/3) = -1 f(0) defined: 0
The common factor of the numerator and denominator of is removed by fmpz_poly_q_canonicalise. In the denominators and have the gcd , and since the numerator is coprime to 2 in , nothing more cancels.
References#
- [Hen1956] Peter Henrici : "A Subroutine for Computations with Rational Numbers" J. ACM (1956), https://doi.org/10.1145/320815.320818
- [Hor1972] Ellis Horowitz : "Algorithms for Rational Function Arithmetic Operations" Annual ACM Symposium on Theory of Computing: Proceedings of the Fourth Annual ACM Symposium on Theory of Computing (Denver) (1972), https://doi.org/10.1145/800152.804903
The FLINT team, “Representation and arithmetic of rational functions (fmpz_poly_q.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/fmpz_poly_q/representation.html (generated 2026-11-02).
@misc{flint-doc-fmpz-poly-q-representation,
author = {{The FLINT team}},
title = {{Representation and arithmetic of rational functions (fmpz\_poly\_q.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/fmpz_poly_q/representation.html},
note = {Generated 2026-11-02}
}