FLINT3.7.0-dev
Algorithm

Matrix arithmetic in multi-double formats

Cost
mknmkn terms for an m×km \times k by k×nk \times n product, each O(N2)O(N^2) double operations (about 140 for N=4N = 4); the block recursive LU decomposition and triangular solving cost a constant times the product.

The plain formats of dfloat (dfloat.h) implement the matrix methods of the generic rings, so that gr_mat_mul, gr_mat_lu, gr_mat_nonsingular_solve, gr_mat_inv and the eigensolvers of gr_mat run on them with the generic block algorithms and fast base cases. This page describes the product kernel and the base cases; the expansions themselves and their error-free transformations are described in Double-word and multi-double arithmetic.

One double#

For N=1N = 1 the product is flint_dgemm, an optimised BLAS-like double precision product. A complex product C=ABC = AB is a single real product of twice the size: the m×km \times k complex matrix AA, read as an m×2km \times 2k real matrix of parts, times the 2k×2n2k \times 2n real matrix

(Re⁡BIm⁡B−Im⁡BRe⁡B)\begin{pmatrix} \operatorname{Re} B & \operatorname{Im} B \\ -\operatorname{Im} B & \operatorname{Re} B \end{pmatrix}

(with interleaved rows and columns, a copy of BB), whose result is the m×2nm \times 2n matrix of the parts of CC.

The product kernel#

For N≥2N \ge 2 the product is a SIMD kernel. The columns of BB are packed, a block of WW columns at a time (W=4W = 4 with AVX2 or NEON and 8 with AVX-512), in structure-of-arrays form: component cc of the entries bl,j0,…,bl,j0+W−1b_{l,j_0}, \ldots, b_{l,j_0+W-1} is one vector register. Each row of AA then runs along a block, its entries broadcast to the lanes, so that the WW lanes compute WW entries of CC in parallel.

The terms ailblja_{il} b_{lj} of a dot product are not renormalised one by one. The product of two expansions a=∑iaia = \sum_i a_i and b=∑jbjb = \sum_j b_j splits into order sums T0,…,TN−1T_0, \ldots, T_{N-1}, where TrT_r collects the products aibja_i b_j with i+j=ri + j = r and the error terms of the products of the order below (as in the scalar multiplication kernel; exact except for the plain additions of the last order, which are relative to the term). These go into accumulators S0,…,SNS_0, \ldots, S_N of the order sums of the whole dot product: each addition into SrS_r is a TwoSum whose error term goes on to Sr+1S_{r+1}, and only the additions into the extra accumulator SNS_N round. The accumulators are renormalised every 32 terms, before their magnitudes can drift apart, and at the end. For d4 this costs about 140 double operations per term, a third fewer than a renormalised product followed by a renormalised sum, and it is more accurate than a dot product of rounded products: the error is that of one rounding of the exact dot product plus the terms dropped from each product. For k=64k = 64 it was measured at most 0.4⋅2−53N∑l∣ail∣∣blj∣0.4 \cdot 2^{-53N} \sum_l |a_{il}| |b_{lj}| for entries of uniform magnitude and 3.2⋅2−53N∑l∣ail∣∣blj∣3.2 \cdot 2^{-53N} \sum_l |a_{il}| |b_{lj}| for magnitudes spread over 2±202^{\pm 20}, against 1.0 and 5.1 for the classical algorithm with the scalar operations. (Without the extra accumulator SNS_N the kernel lost five to eight bits.)

Only exact operations and fused multiply-subtracts (for the error terms of products) are used, so the results do not depend on the vector width. A complex term is four real terms; with real entries the zero imaginary parts cost nothing extra, since the additions of an exact zero are exact. Two rows of AA are processed together, sharing the loads of BB. The rows of AA are split into panels small enough for the panel and a packed block of BB to stay in the L2 cache, and the panels run in parallel with the threads FLINT is set to use. An entry whose result is not finite is recomputed with the scalar operations.

The kernel is used from dimension 2. Its cost is cubic, while the block algorithms of arb_mat_approx_mul and acb_mat_approx_mul (exact integer matrix products through BLAS) are cheaper per term for large matrices; from dimension 1600, 1000 and 600 (d2, d3, d4; complex: 1500, 900, 500) the entries are converted to arf_t and multiplied at 53N+453N + 4 bits, with an accuracy in the norm of the blocks rather than entrywise. This makes dfloat depend on arb_mat and acb_mat, which it otherwise sits below; it is a provisional solution until a fast arbitrary-precision floating-point matrix product is available at a lower level.

LU decomposition and triangular solving#

gr_mat_lu is the block recursive algorithm (gr_mat_lu_recursive) above 16 rows and columns, which spends most of its time in matrix products A11−A10A01A_{11} - A_{10} A_{01}. It leaves to the base case the factorization of tall panels of a few columns, where the generic classical algorithm, working along the short rows, pays a function call per entry. The base case has the same pivoting (the entry of largest magnitude, judged by the head of the expansion) and the same layout of LL as gr_mat_lu_classical, but eliminates column by column, four rows at a time in the SIMD lanes: the multipliers ej=aj,c/pe_j = a_{j,c}/p for the rows below the pivot pp, then xj,c′←xj,c′−ej pc′x_{j,c'} \gets x_{j,c'} - e_j\, p_{c'} with pc′p_{c'} broadcast. The results are those of the scalar operations.

The triangular solvers are the block recursive algorithms above 16. In the base case, for four or more right-hand sides the rows of the solution are computed as vectors, Xj=(Bj−∑iLjiXi)/LjjX_j = (B_j - \sum_i L_{ji} X_i) / L_{jj}, with the SIMD products of a vector by a scalar; for fewer, by the classical algorithm with dot products along the rows of LL.

The recursion subtracts each product from the block it updates in a separate pass, for want of a fused operation C←C−ABC \gets C - AB in gr_mat; such an operation, as a ring method tuned for each type, would save a temporary matrix and a pass over it.

Accuracy#

The decompositions are those of Gaussian elimination with partial pivoting in the arithmetic of the format, backward stable in the usual sense with the unit roundoff replaced by the effective accuracy of the format, a small multiple of 2−53N2^{-53N}. Measured on random linear systems, the solutions are as accurate as with arf_t at 53N53N bits to within a bit; see Floating-point backends for the approximate functions for how the approximate functions of arb_mat use this.

Use in FLINT#

  • The methods GR_METHOD_MAT_MUL, GR_METHOD_MAT_LU, GR_METHOD_MAT_NONSINGULAR_SOLVE_TRIL and GR_METHOD_MAT_NONSINGULAR_SOLVE_TRIU of the plain real and complex dfloat rings; timings in Linear algebra.
  • The approximate functions of arb_mat and acb_mat (LU decomposition, solving, inversion, eigenvalues) convert to these rings when they are faster.

Referenced from#

Cite this page

The FLINT team, “Matrix arithmetic in multi-double formats,” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/algorithms/floating-point/dfloat-matrices.html (generated 2026-11-07).