FLINT3.7.0-dev

Solving linear systems with ball matrices

Synopsis#include <flint/arb_mat.h>
int arb_mat_solve(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec)source
int arb_mat_solve_lu(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec)source
int arb_mat_solve_precond(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, slong prec)source

Solve AX=BAX = B for a square matrix AA and XX, BB with mm columns. Return nonzero if AA is proved invertible, in which case X contains the exact solution for every pair of matrices in the balls AA and BB; return zero (with X undefined) if m>0m > 0 and this could not be proved. The lu version uses Gaussian elimination in ball arithmetic, the precond version preconditions with an approximate inverse [HS1967], and the default uses the lu version if n≤4n \le 4 or prec>10n\mathit{prec} > 10n and the precond version otherwise. See Solving linear systems with ball matrices.

int arb_mat_solve_preapprox(arb_mat_t X, const arb_mat_t A, const arb_mat_t B, const arb_mat_t R, const arb_mat_t T, slong prec)source

Solves AX=BAX = B given an approximate inverse RR of AA and an approximate solution TT, by bounding the error of TT (Theorem 10.2 of [Rum2010]). Returns nonzero if ∥I−RA∥∞<1\|I - RA\|_\infty < 1 could be proved, which shows that AA is invertible; X then contains the exact solution. Returns zero (with X undefined) otherwise, for example if RR is not a good enough approximation.

int arb_mat_inv(arb_mat_t X, const arb_mat_t A, slong prec)source

Sets X to A−1A^{-1} by solving AX=IAX = I with arb_mat_solve. Returns nonzero if AA is proved invertible (and X contains the exact inverse) and zero otherwise, with X undefined.

void arb_mat_det_lu(arb_t det, const arb_mat_t A, slong prec)source
void arb_mat_det_precond(arb_t det, const arb_mat_t A, slong prec)source
void arb_mat_det(arb_t det, const arb_mat_t A, slong prec)source

Set det to an enclosure of the determinant of the square matrix AA. The lu version uses Gaussian elimination and bounds the remaining submatrix by Hadamard's inequality when no more pivots can be found; the precond version multiplies AA by approximate inverses of the factors of an approximate LU decomposition and encloses the determinant of the result, which is close to the identity [Rum2010]. The default uses direct formulas for n≤3n \le 3 and triangular matrices, the lu version if n≤10n \le 10 or prec>10n\mathit{prec} > 10n, and the precond version otherwise; it throws an exception for a non-square matrix.

arb_mat_solve(X, A, B, prec) solves AX=BAX = B for a square matrix AA of real balls and returns nonzero if it has proved that every matrix in AA is invertible; X then contains A−1BA^{-1} B for every choice of AA and BB in the input balls. A return value of zero means that this could not be proved: AA may be singular, or the input or the working precision may not be accurate enough. arb_mat_inv solves AX=IAX = I in the same way, and arb_mat_det encloses the determinant (it cannot fail, but its enclosure may contain zero). Two families of algorithms are available, and the difference between them is large.

AlgorithmVerified linear algebraHow arb_mat and acb_mat solve linear systems, invert matrices and compute determinants with rigorous enclosures, by interval Gaussian elimination, by preconditioning with an approximate inverse, and by certifying an approximate solution with a residual bound.

Gaussian elimination in ball arithmetic#

arb_mat_solve_lu computes an LU decomposition with partial pivoting directly in ball arithmetic (arb_mat_lu) and solves the two triangular systems. It succeeds if every pivot excludes zero. This is the fastest method, and at high precision the best one, but in ball arithmetic the radii grow with every elimination step: the computed balls must contain the result for all matrices in the input balls and the dependencies between entries are lost at each step, so the radii typically grow exponentially with nn even for well-conditioned matrices. At 64-bit precision, the enclosures of a random 40×4040 \times 40 system are already useless and larger systems fail entirely (see the example below). The method is therefore used by default only when prec>10n\mathit{prec} > 10n or n≤4n \le 4.

Preconditioning#

arb_mat_solve_precond first computes an approximate inverse R≈A−1R \approx A^{-1} of the midpoint matrix in floating-point arithmetic (arb_mat_approx_solve with B=IB = I). Then RARA is close to the identity matrix, and the system (RA)X=RB(RA) X = RB has the same solution as AX=BAX = B if RR is invertible. Following Hansen and Smith [HS1967], the products RARA and RBRB are computed in ball arithmetic and the new system is solved:

  • If BB has few columns (m<0.1n+1m < 0.1n + 1), (RA)X=RB(RA)X = RB is solved by ball Gaussian elimination. Since RARA is close to II, the pivots stay close to 1 and the radii grow only mildly.
  • Otherwise, with E=I−RAE = I - RA, if ∥E∥∞≤δ<1\|E\|_\infty \le \delta < 1 then RARA is invertible and X=(I−E)−1RBX = (I - E)^{-1} RB satisfies ∥Xj−(RB)j∥∞≤δ1−δ∥(RB)j∥∞\|X_j - (RB)_j\|_\infty \le \frac{\delta}{1-\delta} \|(RB)_j\|_\infty for each column jj, by the Neumann series. The result is RBRB with this bound added to every entry. If δ≥1\delta \ge 1, the first method is used instead.

The cost is about that of three matrix multiplications and an approximate inversion, several times that of arb_mat_solve_lu, but the radii of the result are of the order of κ(A)\kappa(A) times the radii of the input and the unit roundoff, as in a numerical backward error analysis, and do not grow exponentially with nn. This is the default for n>4n > 4 unless prec>10n\mathit{prec} > 10n. The theory is in Verified linear algebra.

Certifying a given approximation#

arb_mat_solve_preapprox(X, A, B, R, T, prec) certifies an approximate solution TT computed by any means, given an approximate inverse RR. By Theorem 10.2 of [Rum2010], if ∥I−RA∥∞<1\|I - RA\|_\infty < 1 then AA is invertible and each column of the exact solution satisfies

∥Xj−Tj∥∞≤∥R(ATj−Bj)∥∞1−∥I−RA∥∞.\|X_j - T_j\|_\infty \le \frac{\|R(AT_j - B_j)\|_\infty}{1 - \|I - RA\|_\infty}.

The function computes RARA and the residual AT−BAT - B in ball arithmetic, so the result is rigorous even though RR and TT are not. It returns zero if ∥I−RA∥∞<1\|I - RA\|_\infty < 1 cannot be shown, for example because RR is a poor approximation. This is the cheapest way to obtain error bounds when good approximations are already available, for example from a previous solve at lower precision.

Inverse and determinant#

arb_mat_inv sets the output to the identity and calls arb_mat_solve, so it inherits the choice of algorithm.

arb_mat_det uses explicit formulas for n≤3n \le 3 and the product of the diagonal for triangular matrices. Otherwise, for n≤10n \le 10 or prec>10n\mathit{prec} > 10n, it calls arb_mat_det_lu, which performs ball Gaussian elimination as far as pivots can be found, multiplies the pivots, and bounds the determinant of the remaining submatrix by Hadamard's inequality ∣det⁡M∣≤∏i∥mi∥2|\det M| \le \prod_i \|m_i\|_2 over its rows. For larger matrices it calls arb_mat_det_precond, following Rump [Rum2010]: from an approximate decomposition PA≈LUPA \approx LU it forms M=L−1PAU−1M = L^{-1} P A U^{-1} in ball arithmetic with approximate inverses of the triangular factors, which is close to the identity, encloses det⁡M∈[1±(enε−1)]\det M \in [1 \pm (e^{n\varepsilon} - 1)] with ε\varepsilon the largest Gershgorin radius max⁡i∑j∣mij−δij∣\max_i \sum_j |m_{ij} - \delta_{ij}| (since every eigenvalue of MM lies within ε\varepsilon of 1), and divides by det⁡U−1\det U^{-1} (the product of the diagonal of the approximate U−1U^{-1}; L−1L^{-1} has unit diagonal). If the result contains zero, the LU bound is also computed and the better enclosure is returned.

Examples#

The program solves AX=BAX = B for random matrices with entries in [−1,1][-1, 1] and prints the largest radius of the solution vector. The radii from ball Gaussian elimination grow by a factor of about 10410^4 each time nn doubles, until no pivot can be certified; those of the preconditioned solver stay near the unit roundoff:

Examplearb_mat_solve_compare.cchecked by make checkdoc
#include <flint/ulong_extras.h>
#include <flint/arb.h>
#include <flint/arb_mat.h>

/* largest radius of the entries of X */
static double max_rad(const arb_mat_t X)
{
    slong i, j;
    double r = 0;
    for (i = 0; i < arb_mat_nrows(X); i++)
        for (j = 0; j < arb_mat_ncols(X); j++)
            r = FLINT_MAX(r, mag_get_d(arb_radref(arb_mat_entry(X, i, j))));
    return r;
}

int main(void)
{
    arb_mat_t A, B, X;
    flint_rand_t state;
    slong n, i, j, prec = 64;

    flint_rand_init(state);

    for (n = 10; n <= 80; n *= 2)
    {
        arb_mat_init(A, n, n);
        arb_mat_init(B, n, 1);
        arb_mat_init(X, n, 1);

        /* random entries in [-1, 1] */
        for (i = 0; i < n; i++)
            for (j = 0; j < n; j++)
            {
                arb_set_si(arb_mat_entry(A, i, j), (slong) n_randint(state, 2001) - 1000);
                arb_div_ui(arb_mat_entry(A, i, j), arb_mat_entry(A, i, j), 1000, prec);
            }
        arb_mat_ones(B);

        flint_printf("n = %wd:", n);
        if (arb_mat_solve_lu(X, A, B, prec))
            flint_printf("  lu %.2e", max_rad(X));
        if (arb_mat_solve_precond(X, A, B, prec))
            flint_printf("  precond %.2e", max_rad(X));
        flint_printf("\n");

        arb_mat_clear(A);
        arb_mat_clear(B);
        arb_mat_clear(X);
    }
    flint_rand_clear(state);
    return 0;
}
Output
n = 10:  lu 3.74e-15  precond 2.10e-18
n = 20:  lu 1.39e-09  precond 2.08e-16
n = 40:  lu 3.34e-01  precond 7.47e-17
n = 80:  precond 2.87e-16

The second program computes an approximate solution of a Hilbert system with the floating-point functions and certifies it with arb_mat_solve_preapprox. The exact solution of H6x=(1,…,1)TH_6 x = (1, \ldots, 1)^T is the vector of column sums of H6−1H_6^{-1}, which are integers:

Examplearb_mat_solve_preapprox.cchecked by make checkdoc
#include <flint/arb.h>
#include <flint/arb_mat.h>

int main(void)
{
    arb_mat_t A, B, R, T, X;
    slong n = 6, prec = 128;

    arb_mat_init(A, n, n);
    arb_mat_init(B, n, 1);
    arb_mat_init(R, n, n);
    arb_mat_init(T, n, 1);
    arb_mat_init(X, n, 1);

    arb_mat_hilbert(A, prec);
    arb_mat_ones(B);

    /* floating-point approximations, no error bounds */
    arb_mat_approx_inv(R, A, prec);
    arb_mat_approx_mul(T, R, B, prec);

    /* certify: X = T + error bound */
    if (arb_mat_solve_preapprox(X, A, B, R, T, prec))
        arb_mat_printd(X, 15);
    else
        flint_printf("failed\n");

    arb_mat_clear(A);
    arb_mat_clear(B);
    arb_mat_clear(R);
    arb_mat_clear(T);
    arb_mat_clear(X);
    return 0;
}
Output
[-6.00000000000000 +/- 8.0698e-29]
[210.000000000000 +/- 8.0698e-29]
[-1680.00000000000 +/- 8.0698e-29]
[5040.00000000000 +/- 8.0698e-29]
[-6300.00000000000 +/- 8.0698e-29]
[2772.00000000000 +/- 8.0698e-29]

The Hilbert matrix itself is only known to 128 bits (its entries 1/(j+k+1)1/(j + k + 1) are rounded), and the certified solution is the solution for every matrix in those balls; the radius 8⋅10−298 \cdot 10^{-29} reflects the condition number κ(H6)≈1.5⋅107\kappa(H_6) \approx 1.5 \cdot 10^7 times the rounding of the entries.

Guides#

References#

  • [HS1967] E. Hansen and R. Smith, "Interval Arithmetic in Matrix Computations, Part II", SIAM Journal of Numerical Analysis, 4(1):1-9 (1967). https://doi.org/10.1137/0704001
  • [Rum2010] S. M. Rump, "Verification methods: Rigorous results using floating-point arithmetic", Acta Numerica 19 (2010), 287-449.
Cite this page

The FLINT team, “Solving linear systems with ball matrices (arb_mat.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/arb_mat/solve.html (generated 2026-11-02).