FLINT3.7.0-dev
Algorithm

Multiplying polynomials with ball coefficients

Cost
For well-scaled operands of length nn at precision pp, one product of integer polynomials with coefficients of O(p)O(p) bits, O(M(n(p+log⁡n)))O(M(n(p + \log n))) bit operations; O(n2M(p))O(n^2 M(p)) for the classical algorithm and in the worst case.

Let A=∑iaixiA = \sum_i a_i x^i and B=∑jbjxjB = \sum_j b_j x^j be polynomials whose coefficients are balls ai=[mi±ri]a_i = [m_i \pm r_i], bj=[mj′±rj′]b_j = [m'_j \pm r'_j]. A ball product CC must contain ∑i+j=kαiβj\sum_{i+j=k} \alpha_i \beta_j for all αi∈ai\alpha_i \in a_i, βj∈bj\beta_j \in b_j and every kk. The classical algorithm evaluates each such sum as one ball dot product (Dot products of balls), which costs O(n2)O(n^2) multiplications for length nn but gives nearly optimal enclosures. Fast algorithms (Karatsuba, FFT) cannot simply be run in ball arithmetic: they rely on cancellations that ball arithmetic does not see, so the radii of the output grow like the sum of the absolute values of all intermediate quantities, which for polynomials with coefficients of very different magnitudes destroys the accuracy entirely ([vdH2008], [Hig2002]). FLINT uses the following algorithm instead: the midpoints are multiplied exactly with fast integer polynomial arithmetic, after a scaling and a splitting into blocks that keep the integers small, and the radii are bounded by a separate product of nonnegative polynomials of low precision, following van der Hoeven [vdH2008] and Johansson [Joh2017].

Error bound for the product#

Write A=Am+EA = A_m + E with Am=∑mixiA_m = \sum m_i x^i and E=∑εixiE = \sum \varepsilon_i x^i, ∣εi∣≤ri|\varepsilon_i| \le r_i, and likewise B=Bm+E′B = B_m + E'. For a polynomial PP, let ∣P∣|P| denote the polynomial whose coefficients are the absolute values of those of PP, and write P⪯QP \preceq Q if every coefficient of PP is at most the corresponding coefficient of QQ.

Lemma 1. With the notation above, Ar=∑rixiA_r = \sum r_i x^i and Br=∑rj′xjB_r = \sum r'_j x^j,

∣AB−AmBm∣⪯∣Am∣Br+Ar(∣Bm∣+Br),∣A2−Am2∣⪯Ar(2∣Am∣+Ar).|AB - A_m B_m| \preceq |A_m| B_r + A_r (|B_m| + B_r), \qquad |A^2 - A_m^2| \preceq A_r (2|A_m| + A_r).

Proof. AB−AmBm=AmE′+EBm+EE′=AmE′+E(Bm+E′)AB - A_m B_m = A_m E' + E B_m + E E' = A_m E' + E(B_m + E'), and the coefficients of a product of polynomials satisfy ∣PQ∣⪯∣P∣ ∣Q∣|PQ| \preceq |P|\,|Q| by the triangle inequality, with ∣E∣⪯Ar|E| \preceq A_r, ∣E′∣⪯Br|E'| \preceq B_r and ∣Bm+E′∣⪯∣Bm∣+Br|B_m + E'| \preceq |B_m| + B_r. For the square, A2−Am2=2AmE+E2=E(2Am+E)A^2 - A_m^2 = 2 A_m E + E^2 = E(2A_m + E).

So it suffices to compute the product AmBmA_m B_m of the midpoints with rigorously bounded rounding error, and upper bounds for one or two products of polynomials with nonnegative coefficients. These products need only a few bits of relative accuracy, because they bound errors.

Scaling and blocks#

The coefficients of a power series often decay or grow geometrically: the coefficients of exe^x are 1/k!1/k!, those of 1/(1−100x)1/(1 - 100x) are 100k100^k. Representing all of them as integers with a common exponent would need O(nlog⁡n)O(n \log n) or O(n)O(n) bits per coefficient. The substitution x→2−cxx \to 2^{-c} x, which multiplies the coefficient of xkx^k by 2−ck2^{-ck}, is exact in binary floating-point arithmetic and commutes with multiplication: if A~(x)=A(2−cx)\tilde A(x) = A(2^{-c} x), then A~(x)B~(x)=(AB)(2−cx)\tilde A(x) \tilde B(x) = (AB)(2^{-c} x), and the coefficients of ABAB are those of A~B~\tilde A \tilde B multiplied by 2ck2^{ck}.

FLINT chooses cc as the nearest integer to the average slope of the exponents between the first and the last nonzero midpoint of the two operands: if the first and last nonzero midpoints of AA have indices a1<a2a_1 < a_2 and exponents e1,e2e_1, e_2, and those of BB indices b1<b2b_1 < b_2 and exponents f1,f2f_1, f_2, then

c=⌊(e2−e1)+(f2−f1)(a2−a1)+(b2−b1)+12⌋.c = \left\lfloor \frac{(e_2 - e_1) + (f_2 - f_1)}{(a_2 - a_1) + (b_2 - b_1)} + \frac12 \right\rfloor.

This is cheap and gives slowly varying scaled coefficients for power series with similar decay rates; it is not optimal in general.

Next, the scaled midpoints of each operand are split into maximal runs of consecutive indices, called blocks, such that within a block all nonzero midpoints are integer multiples of a common power of two 2e2^{e} and have absolute value below 2e+H2^{e + H}, where the height HH is at most 3p+5123p + 512 for the working precision pp. A block tt starting at index sts_t thus defines an integer polynomial PtP_t with A~m=∑t2etxstPt(x)\tilde A_m = \sum_t 2^{e_t} x^{s_t} P_t(x), exactly, and similarly B~m=∑u2eu′xsu′Qu(x)\tilde B_m = \sum_u 2^{e'_u} x^{s'_u} Q_u(x). Then

A~mB~m=∑t,u2et+eu′xst+su′PtQu,\tilde A_m \tilde B_m = \sum_{t, u} 2^{e_t + e'_u} x^{s_t + s'_u} P_t Q_u,

where each PtQuP_t Q_u is a product of integer polynomials, computed exactly by _fmpz_poly_mulmid (Kronecker substitution, Schönhage–Strassen or the small-prime FFT, see Multiplying polynomials over Z). Each output coefficient is the sum of the contributions of all block pairs; each contribution is rounded to pp bits when it is added, with the rounding error added to the radius. Well-scaled operands form a single block each, and then the midpoint product is one exact integer polynomial product followed by one rounding per coefficient.

The products of nonnegative polynomials in Lemma 1 are computed in the same way. Their coefficients are mag_t numbers with 30-bit mantissas (Representation of radii and midpoints); after the same scaling they are split into blocks of height at most 3⋅30+512=6023 \cdot 30 + 512 = 602 bits. For a pair of blocks of which the shorter has fewer than 1000 coefficients, the product is computed in double-precision floating-point arithmetic, each coefficient being converted exactly to a double with a fixed exponent offset (the block height guarantees that neither the operands nor the products overflow or underflow); otherwise it is computed exactly with integers. The results are converted to upper bounds with mag_set_d_2exp_fmpz and mag_set_fmpz_2exp_fmpz, which round upwards.

Lemma 2 (Floating-point sums of nonnegative products). Let s=∑i=1Lxiyis = \sum_{i=1}^{L} x_i y_i with nonnegative doubles xi,yix_i, y_i, L≤1000L \le 1000, and let s~\tilde s be the value computed by multiplying and adding in any order in IEEE double precision with rounding to nearest, without overflow or underflow. Then s≤(1+10−9)s~s \le (1 + 10^{-9}) \tilde s.

Proof. Each product and each partial sum is rounded once, with a relative error factor 1+δ1 + \delta, ∣δ∣≤u=2−53|\delta| \le u = 2^{-53}. Since all quantities are nonnegative, each term xiyix_i y_i enters s~\tilde s multiplied by a product of at most LL such factors, each at least 1−u1 - u, so s~≥(1−u)Ls\tilde s \ge (1 - u)^L s. Hence s≤(1−u)−Ls~≤(1+1.2⋅10−13)s~s \le (1 - u)^{-L} \tilde s \le (1 + 1.2 \cdot 10^{-13}) \tilde s for L≤1000L \le 1000. (A fused multiply-add only removes roundings.)

The implementation multiplies the double results by 1+10−91 + 10^{-9}, a comfortable margin over Lemma 2.

Algorithm 1: Block multiplication

Input: AA, BB with ball coefficients, a window [ℓ,h)[\ell, h) of output indices, precision pp. Output: balls cℓ,…,ch−1c_\ell, \ldots, c_{h-1}.

  1. Drop the coefficients of each operand that only contribute below xℓx^\ell or above xh−1x^{h-1}, and the trailing zero coefficients.
  2. If some coefficient is not finite, use the classical algorithm.
  3. Compute the scaling exponent cc.
  4. Radii: compute upper bounds for the coefficients ℓ,…,h−1\ell, \ldots, h-1 of ∣A~m∣B~r+A~r(∣B~m∣+B~r)|\tilde A_m| \tilde B_r + \tilde A_r(|\tilde B_m| + \tilde B_r) (or of A~r(2∣A~m∣+A~r)\tilde A_r(2|\tilde A_m| + \tilde A_r) for a square), omitting the terms with Ar=0A_r = 0 or Br=0B_r = 0, by block products as described above, and store them as the radii of ckc_k.
  5. Midpoints: split A~m\tilde A_m, B~m\tilde B_m into blocks of height at most 3p+5123p + 512; for each pair of blocks, compute the exact middle product of the integer polynomials and add its coefficients, times the power of two, to the balls ckc_k with rounding to pp bits.
  6. Multiply ckc_k by 2ck2^{ck}.

Theorem 3. For every choice of αi∈ai\alpha_i \in a_i and βj∈bj\beta_j \in b_j, the coefficient ∑i+j=kαiβj\sum_{i+j=k} \alpha_i \beta_j of the product lies in the ball ckc_k computed by Algorithm 1, for ℓ≤k<h\ell \le k < h.

Proof. Step 1 only removes terms that do not occur in the requested coefficients. The scaling in steps 3 and 6 is exact. In step 5, the block representation of the midpoints is exact and the block products are exact, so the only errors are the roundings when adding the contributions, which ball addition adds to the radii. The midpoint of the result after step 5 therefore differs from the coefficient of A~mB~m\tilde A_m \tilde B_m by at most the radius accumulated in step 5. By Lemma 1, the coefficient of the exact product differs from that of A~mB~m\tilde A_m \tilde B_m by at most the coefficient of the bound polynomial, for which step 4 computed an upper bound: the conversions of midpoints to mag_t in step 4 round upwards, the integer products are exact, the double products are bounded by Lemma 2, and the final conversions round upwards.

The block algorithm is about as accurate as the classical one when the scaled coefficients of each operand vary by much less than 23p2^{3p}, as is typical for power series of analytic functions: each coefficient of the product is then rounded once, to pp bits relative to the largest term in its sum. For badly scaled operands it degenerates gracefully to many small blocks, and in the worst case (every coefficient a block of its own) to the classical algorithm with more overhead.

Selection and cost#

_arb_poly_mullow uses the classical algorithm if the output or one of the operands has length at most 7, or if the output length or twice the length of the shorter operand is at most a cutoff that is 110 for p≤128p \le 128 and 104/(ln⁡p)310^4/(\ln p)^3 clamped to [8,60][8, 60] above (increased by 25% for squares at p≥256p \ge 256 and again at p≥4096p \ge 4096). At high precision, the integer products are long, and the block algorithm wins earlier.

For operands of length nn that form single blocks, the midpoint product is one integer polynomial product with O(p+log⁡n)O(p + \log n)-bit coefficients, that is, O(M(n(p+log⁡n)))O(M(n(p + \log n))) bit operations, and the radius products cost O(n2)O(n^2) double operations for n<1000n < 1000 (fast in practice, since they are simple dot products) and O(M(nlog⁡n))O(M(n \log n)) beyond. The classical algorithm costs O(n2M(p))O(n^2 M(p)).

Complex polynomials#

For complex polynomials, _acb_poly_mullow and _acb_poly_mulmid first try _acb_poly_mulmid_fmpzi, when _acb_poly_mulmid_use_fmpzi predicts that it is faster (roughly, when the number of coefficient products per input coefficient times p0.57p^{0.57} is at least 240, or 330 for squares). It scales both operands as above, using the larger of the real and imaginary midpoints for the slope, writes all real and imaginary midpoints of each operand as Gaussian integers times a single power of two, and fails if this needs more than 3p+5123p + 512 bits. The midpoints of the product are then one product of Gaussian integer polynomials (_fmpzi_poly_mulmid), and the radii of the real and imaginary parts are bounded separately: for (ar+iai)(br+ibi)(a_r + i a_i)(b_r + i b_i) with radii ρ\rho,

rad⁡(Re⁡)≤∣ar∣ρbr+ρar(∣br∣+ρbr)+∣ai∣ρbi+ρai(∣bi∣+ρbi)\operatorname{rad}(\operatorname{Re}) \le |a_r| \rho_{b_r} + \rho_{a_r}(|b_r| + \rho_{b_r}) + |a_i| \rho_{b_i} + \rho_{a_i}(|b_i| + \rho_{b_i})

and symmetrically for the imaginary part, which is Lemma 1 applied to arbr−aibia_r b_r - a_i b_i and arbi+aibra_r b_i + a_i b_r; the eight (four for a square) products of nonnegative polynomials are computed by _arb_poly_addmulmid_mag. If the operands are not well-scaled, the transposed algorithm computes the real and imaginary parts of the product with four real products _arb_poly_mulmid, each of which uses its own blocks. The Gauss variant with three real products, (a+bi)(c+di)=(ac−bd)+((a+b)(c+d)−ac−bd)i(a + bi)(c + di) = (ac - bd) + ((a + b)(c + d) - ac - bd) i, is faster but loses accuracy when ∣a∣|a| and ∣b∣|b| (or ∣c∣|c| and ∣d∣|d|) differ greatly, since the error of the large products then swamps the small part; it is available but not used by default.

Use in FLINT#

Referenced from#

References#

  • [vdH2008] J. van der Hoeven. Making fast multiplication of polynomials numerically stable. Technical report 2008-02, Université Paris-Sud, Orsay, 2008.
  • [Hig2002] N. J. Higham. Accuracy and Stability of Numerical Algorithms, second edition, chapter 24 (The fast Fourier transform and applications). SIAM, 2002. https://doi.org/10.1137/1.9780898718027
  • [Joh2017] F. Johansson. "Arb: efficient arbitrary-precision midpoint-radius interval arithmetic". IEEE Transactions on Computers, vol 66, issue 8, 2017, pp. 1281-1292. https://doi.org/10.1109/TC.2017.2690633
Cite this page

The FLINT team, “Multiplying polynomials with ball coefficients,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/ball-arithmetic/polynomial-multiplication.html (generated 2026-11-02).