FLINT3.7.0-dev
Module · 127 functions

acb_mat.h

#include <flint/acb_mat.h>

This module implements dense matrices whose entries are complex balls (acb_t), with the same interface as arb_mat.h for arithmetic, solving linear systems, inversion, determinants, the characteristic polynomial and the exponential. A matrix of balls represents the set of complex matrices whose entries lie in the balls, and the functions return enclosures of the exact results for every matrix in that set. In addition, the module computes eigenvalues and eigenvectors: the QR algorithm gives floating-point approximations, and the methods of Rump, Miyajima and van der Hoeven and Mourrain turn them into certified enclosures of the individual eigenvalues, of clusters of eigenvalues, or of the whole spectrum (Eigenvalues and eigenvectors). Real matrices use these functions after conversion with acb_mat_set_arb_mat.

Large products of complex matrices are computed by acb_mat_mul_reorder as products of real matrices with arb_mat_mul (Ball matrix multiplication). The solvers follow Verified linear algebra, and the eigenvalue algorithms Eigenvalue enclosures. The characteristic polynomial, the companion matrix and powers are computed by the generic implementations in gr_mat.h with the complex ball context.

AlgorithmEigenvalue enclosuresHow acb_mat computes rigorous enclosures of the eigenvalues and eigenvectors of complex matrices by certifying floating-point approximations from the QR algorithm, with a global perturbation bound, a Gershgorin test after an approximate diagonalisation, and Rump's fixed-point method for eigenvalue clusters.

Types and conventions#

A matrix with complex ball entries. The structure has the fields entries (a pointer to the entry in the top left corner), r and c (the numbers of rows and columns) and stride (the distance in acb_struct between the starts of consecutive rows). An acb_mat_t is an array of one acb_mat_struct, so it is passed by reference.

acb_mat_entry(mat, i, j)

Evaluates to a pointer to the entry in row i and column j of mat (no bounds check).

acb_ptr acb_mat_entry_ptr(acb_mat_t mat, slong i, slong j)

Returns a pointer to the entry in row i and column j of mat; the same as acb_mat_entry, as a function.

Evaluate to the number of rows and columns of mat.

The conventions are those of Types and conventions: dimensions are fixed at initialisation and must be compatible; outputs may alias inputs; functions that can fail numerically return nonzero only when the result is certified; predicates return 1 only if the property certainly holds; the approx functions compute floating-point results without error bounds. acb_mat.h does not include acb.h, which programs that work with the entries must include.

Memory management#

Initialises mat as the zero matrix with r rows and c columns.

Frees the memory used by mat.

Swap two matrices. acb_mat_swap swaps the structures (also when the dimensions differ); acb_mat_swap_entrywise swaps the entries one by one and requires equal dimensions, which also works for windows.

Returns the number of bytes allocated on the heap by x, excluding sizeof(acb_mat_struct).

void acb_mat_window_init(acb_mat_t window, const acb_mat_t mat, slong r1, slong c1, slong r2, slong c2)

Initialise window as a view of the submatrix of mat formed by rows r_1 \le i < r_2 and columns c_1 \le j < c_2, sharing its entries, and release it again (which frees nothing). Require 0 \le r_1 \le r_2 \le the number of rows and likewise for the columns. A window must not be used after mat has been cleared.

Conversions#

void acb_mat_set(acb_mat_t dest, const acb_mat_t src)
void acb_mat_set_fmpq_mat(acb_mat_t dest, const fmpq_mat_t src, slong prec)

Set dest to src, which must have the same dimensions: exactly, or with the entries rounded to prec bits. Real input gives entries with imaginary part exactly zero.

void acb_mat_set_real_imag(acb_mat_t mat, const arb_mat_t re, const arb_mat_t im)

Extract the real or imaginary parts of the entries of mat, or set mat to \mathit{re} + i \cdot \mathit{im}, exactly.

Random generation#

void acb_mat_randtest(acb_mat_t mat, flint_rand_t state, slong prec, slong mag_bits)

Sets mat to a random matrix of random density whose nonzero entries have midpoints of up to prec bits and exponents of up to mag_bits bits.

Sets the square matrix mat to a random matrix with the eigenvalues given by the vector E (with their multiplicities), constructed as Q U Q^{*} with Q the exponential of a random skew-Hermitian matrix (unitary up to rounding) and U a random upper triangular matrix with diagonal E. The result is computed in ball arithmetic and contains a matrix with exactly these eigenvalues. For testing.

Input and output#

void acb_mat_printd(const acb_mat_t mat, slong digits)
void acb_mat_fprintd(FILE * file, const acb_mat_t mat, slong digits)

Print mat to standard output or to file, one row per line as [a, b, ...], each entry printed with acb_fprintd to digits decimal digits.

Comparisons#

int acb_mat_equal(const acb_mat_t mat1, const acb_mat_t mat2)

Returns whether the matrices have the same dimensions and identical balls as entries.

int acb_mat_overlaps(const acb_mat_t mat1, const acb_mat_t mat2)

Returns whether the matrices have the same dimensions and each entry of mat1 overlaps the corresponding entry of mat2.

int acb_mat_contains(const acb_mat_t mat1, const acb_mat_t mat2)
int acb_mat_contains_fmpz_mat(const acb_mat_t mat1, const fmpz_mat_t mat2)
int acb_mat_contains_fmpq_mat(const acb_mat_t mat1, const fmpq_mat_t mat2)

Return whether the matrices have the same dimensions and each entry of mat2 is contained in the corresponding entry of mat1.

int acb_mat_eq(const acb_mat_t mat1, const acb_mat_t mat2)
int acb_mat_ne(const acb_mat_t mat1, const acb_mat_t mat2)

Return whether mat1 and mat2 certainly represent the same matrix (same dimensions and all entries exact and equal), respectively certainly represent different matrices (different dimensions, or some pair of entries that do not overlap).

Return whether mat has zero rows or zero columns, respectively as many rows as columns.

int acb_mat_is_zero(const acb_mat_t mat)

Return whether all entries of mat have zero radius, are exactly zero, or are finite.

int acb_mat_is_real(const acb_mat_t mat)

Returns whether all entries of mat have imaginary part exactly zero.

int acb_mat_is_triu(const acb_mat_t mat)
int acb_mat_is_tril(const acb_mat_t mat)
int acb_mat_is_diag(const acb_mat_t mat)

Return whether all entries below, above, respectively off the main diagonal of mat are exactly zero. The matrix need not be square.

Special matrices#

Set all entries of mat to zero; the diagonal entries to one and the others to zero; all entries to one; the diagonal entries to i and the others to zero; or all entries to indeterminate balls.

void acb_mat_dft(acb_mat_t mat, int type, slong prec)

Sets mat to the unitary DFT matrix of order n, the smaller dimension of mat,

A_{j,k} = \frac{1}{\sqrt{n}} \exp\left(-\frac{2\pi i}{n} jk\right),

which satisfies A^{-1} = A^{*} (if mat is not square, the formula is used for all entries). type is ignored and should be 0.

Transpose and conjugate#

void acb_mat_transpose(acb_mat_t dest, const acb_mat_t src)

Set dest to the transpose, respectively the conjugate transpose, of src, exactly. Aliasing is allowed for square matrices.

void acb_mat_conjugate(acb_mat_t dest, const acb_mat_t src)

Sets dest to the entrywise complex conjugate of src.

Norms#

Sets b to an upper bound for the infinity norm \max_i \sum_j |a_{ij}| of every matrix in A.

void acb_mat_frobenius_norm(arb_t res, const acb_mat_t A, slong prec)

Set res to an enclosure, respectively an upper bound, of the Frobenius norm (\sum_{i,j} |a_{ij}|^2)^{1/2}.

Arithmetic#

void acb_mat_neg(acb_mat_t dest, const acb_mat_t src)

Sets dest to -\mathit{src}, exactly.

void acb_mat_add(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)
void acb_mat_sub(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)

Set res to the sum or difference of matrices of equal dimensions.

void acb_mat_mul_classical(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)
void acb_mat_mul_threaded(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)
void acb_mat_mul_reorder(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)
void acb_mat_mul(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)

Set res to the matrix product. The classical version computes each entry with acb_dot, and the threaded version does the same with the rows of the output distributed over flint_get_num_threads() threads. The reorder version writes the operands as A = A_r + iA_i, B = B_r + iB_i with real matrices and computes the product with real matrix multiplications by arb_mat_mul (one if both operands are real, two if one is, otherwise four, A_r B_r - A_i B_i and A_r B_i + A_i B_r), which benefits from the block algorithm of arb_mat_mul_block.

More
void acb_mat_mul_entrywise(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)

Sets res to the entrywise product of matrices of equal dimensions.

void acb_mat_sqr_classical(acb_mat_t res, const acb_mat_t mat, slong prec)
void acb_mat_sqr(acb_mat_t res, const acb_mat_t mat, slong prec)

Set res to A^2 for a square matrix A.

void acb_mat_pow_ui(acb_mat_t res, const acb_mat_t mat, ulong exp, slong prec)

Sets res to A^e for a square matrix A, by binary exponentiation. A wrapper of gr_mat_pow_ui.

void acb_mat_approx_mul(acb_mat_t res, const acb_mat_t mat1, const acb_mat_t mat2, slong prec)

Approximate matrix multiplication: the input radii are ignored and the output is a floating-point approximation of the product of the midpoints. The output radii carry no meaning.

Scalar arithmetic#

Sets B to 2^c A, exactly.

void acb_mat_scalar_addmul_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec)
void acb_mat_scalar_addmul_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec)

Set B to B + cA.

void acb_mat_scalar_mul_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec)
void acb_mat_scalar_mul_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec)
void acb_mat_scalar_mul_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec)

Set B to cA.

void acb_mat_scalar_div_fmpz(acb_mat_t B, const acb_mat_t A, const fmpz_t c, slong prec)
void acb_mat_scalar_div_arb(acb_mat_t B, const acb_mat_t A, const arb_t c, slong prec)
void acb_mat_scalar_div_acb(acb_mat_t B, const acb_mat_t A, const acb_t c, slong prec)

Set B to A / c.

Matrix-vector products#

Set res to the product vA of the row vector v (of length the number of rows of A) by A, respectively the product Av of A by the column vector v, each entry computed by acb_dot. The underscore versions do not allow res to alias v.

LU decomposition and solving#

int acb_mat_lu_classical(slong * perm, acb_mat_t LU, const acb_mat_t A, slong prec)
int acb_mat_lu_recursive(slong * perm, acb_mat_t LU, const acb_mat_t A, slong prec)
int acb_mat_lu(slong * perm, acb_mat_t LU, const acb_mat_t A, slong prec)

Compute an LU decomposition PA = LU of an n \times n matrix A by Gaussian elimination with partial pivoting in ball arithmetic. Return nonzero if n pivots that do not contain zero are found, which proves that A is invertible; then L (unit lower triangular, without its diagonal) and U are stored in LU, and perm[i] is the row of A that became row i. Return zero, leaving perm and LU undefined, otherwise. LU may be the same object as A.

More
void acb_mat_solve_tril_classical(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec)
void acb_mat_solve_tril_recursive(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec)
void acb_mat_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec)
void acb_mat_solve_triu_classical(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec)
void acb_mat_solve_triu_recursive(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec)
void acb_mat_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec)

Solve LX = B for a lower triangular L, respectively UX = B for an upper triangular U, by substitution. Only the relevant triangle is read; the diagonal must not contain zero (not checked; otherwise the output is not finite). If unit is nonzero, the diagonal is taken to be all ones and is not read. The recursive versions use block substitution with matrix products; the defaults use them when B has at least 40 rows and 40 columns.

void acb_mat_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t LU, const acb_mat_t B, slong prec)

Solves AX = B given an LU decomposition PA = LU computed by acb_mat_lu (assumed valid, not checked). X may be the same object as B but not as LU.

int acb_mat_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec)
int acb_mat_solve_lu(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec)

Solve AX = B for a square matrix A and X, B with m columns. Return nonzero if A is proved invertible, in which case X contains the exact solution for every pair of matrices in the balls A and B; return zero (with X undefined) if m > 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 \le 4 or \mathit{prec} > 10n and the precond version otherwise. See Solving linear systems with ball matrices.

int acb_mat_inv(acb_mat_t X, const acb_mat_t A, slong prec)

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

void acb_mat_det_lu(acb_t det, const acb_mat_t A, slong prec)
void acb_mat_det_precond(acb_t det, const acb_mat_t A, slong prec)
void acb_mat_det(acb_t det, const acb_mat_t A, slong prec)

Set det to an enclosure of the determinant of the square matrix A. 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 A 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 \le 3 and triangular matrices, the lu version if n \le 14 or \mathit{prec} > 10n, and the precond version otherwise; it throws an exception for a non-square matrix.

Approximate solving#

These functions perform floating-point linear algebra on the midpoints of the input, without any error control. The input radii are ignored, and the output matrices hold the approximate results with zero radii. They use the same algorithms as the rigorous versions (partial pivoting, block recursion for large matrices).

void acb_mat_approx_solve_triu(acb_mat_t X, const acb_mat_t U, const acb_mat_t B, int unit, slong prec)
void acb_mat_approx_solve_tril(acb_mat_t X, const acb_mat_t L, const acb_mat_t B, int unit, slong prec)

Approximately solve UX = B or LX = B for a triangular matrix with nonzero diagonal (not checked); with unit set, the diagonal is taken to be ones and not read.

int acb_mat_approx_lu(slong * P, acb_mat_t LU, const acb_mat_t A, slong prec)
void acb_mat_approx_solve_lu_precomp(acb_mat_t X, const slong * perm, const acb_mat_t A, const acb_mat_t B, slong prec)

Compute an approximate LU decomposition with partial pivoting, returning zero if an exactly zero pivot column is encountered, and solve with such a decomposition (assumed to come from acb_mat_approx_lu).

int acb_mat_approx_solve(acb_mat_t X, const acb_mat_t A, const acb_mat_t B, slong prec)

Approximately solve AX = B or invert A. Return zero if the approximate LU decomposition fails, nonzero otherwise; a nonzero return value says nothing about the accuracy of the result.

Characteristic polynomial and companion matrix#

void _acb_mat_charpoly(acb_ptr poly, const acb_mat_t mat, slong prec)
void acb_mat_charpoly(acb_poly_t poly, const acb_mat_t mat, slong prec)

Set poly to the characteristic polynomial \det(xI - A) of the square n \times n matrix A (an exception is raised otherwise). The underscore version writes n + 1 coefficients. Wrappers of _gr_mat_charpoly_berkowitz, the division-free algorithm of Berkowitz with O(n^4) operations, which avoids divisions by balls that contain zero (Characteristic and minimal polynomials). A non-finite matrix gives indeterminate coefficients.

void acb_mat_companion(acb_mat_t mat, const acb_poly_t poly, slong prec)

Set the n \times n matrix mat to the companion matrix of the polynomial of degree n (the underscore version reads n + 1 coefficients). If the leading coefficient cannot be inverted, the result is indeterminate. Wrappers of _gr_mat_companion and gr_mat_companion.

Matrix functions#

Sets S to the truncated exponential series \sum_{k=0}^{N-1} A^k / k!, using rectangular splitting with O(\sqrt{N}) matrix multiplications. The factorials are generated by their recurrence so that the scalars are small integers, and the divisions are postponed by computing partial factorials of length O(\sqrt{N}) [Joh2014b].

void acb_mat_exp(acb_mat_t B, const acb_mat_t A, slong prec)

Sets B to the exponential \exp(A) = \sum_{k \ge 0} A^k/k! of the square matrix A.

More
void acb_mat_trace(acb_t trace, const acb_mat_t mat, slong prec)

Sets trace to the sum of the diagonal entries of the square matrix mat.

void _acb_mat_diag_prod(acb_t res, const acb_mat_t mat, slong a, slong b, slong prec)
void acb_mat_diag_prod(acb_t res, const acb_mat_t mat, slong prec)

Set res to the product of the diagonal entries of mat; the underscore version takes the product of the entries with index a \le i < b (which must be in range; the empty product is 1).

Component and error operations#

Sets B to the matrix of midpoints of A, with zero radii.

Adds err to the radius of every entry of mat.

Eigenvalues and eigenvectors#

The functions in this section are described in more detail, with examples, in Eigenvalues and eigenvectors. They are experimental: there are matrices for which the algorithms fail to converge even as prec is increased, or for which the error bounds are much worse than necessary. A similarity transformation T^{-1} A T can help: balancing, if A is badly scaled, or a random T, if an algorithm fails although A is well-scaled (for example with multiple eigenvalues).

int acb_mat_approx_eig_qr(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, const mag_t tol, slong maxiter, slong prec)

Computes floating-point approximations of the n eigenvalues of the n \times n matrix A (in no particular order) in E, and optionally of the corresponding left eigenvectors in the rows of L and right eigenvectors in the columns of R (either may be NULL), without error bounds. Returns nonzero if the QR iteration converged numerically; this is only a heuristic, and the output may be accurate even if zero is returned.

Full documentation

Given approximations E of the eigenvalues and R of the right eigenvectors of the n \times n matrix A, computes \varepsilon such that every eigenvalue of A lies within distance \varepsilon of some \hat\lambda_k \in E, by Theorem 1 of [Miy2010], an extension of the Bauer–Fike theorem. If \|YR - I\|_\infty \ge 1 for the approximate inverse Y of R, eps is set to infinity.

Full documentation
void acb_mat_eig_enclosure_rump(acb_t lambda, acb_mat_t J, acb_mat_t R, const acb_mat_t A, const acb_t lambda_approx, const acb_mat_t R_approx, slong prec)

Given an approximate eigenvalue lambda_approx of A and an n \times k matrix R_approx of approximate eigenvectors (a basis of the invariant subspace of a presumed cluster of k eigenvalues), computes a ball lambda that contains at least k eigenvalues of A (counted with multiplicity) and an n \times k matrix R that contains a basis of the corresponding invariant subspace. If J is not NULL, it is set to a k \times k matrix J \approx \lambda I such that AR - RJ contains zero; the Jordan form of A then has a k \times k block equal to the Jordan form of a matrix in J. For k = 1, AR - R \lambda contains zero. On failure, the outputs are set to indeterminate values.

Full documentation
int acb_mat_eig_simple_rump(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec)
int acb_mat_eig_simple(acb_ptr E, acb_mat_t L, acb_mat_t R, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec)

Attempt to prove that the n \times n matrix A has n simple eigenvalues, given approximations of the eigenvalues and right eigenvectors. Return 1 on success, writing pairwise disjoint enclosures of the eigenvalues to E (in no particular order), and if L or R is not NULL, enclosures of the corresponding left eigenvectors (rows of L) and right eigenvectors (columns of R), normalised so that L = R^{-1}, which gives a diagonalisation LAR = D. Return 0 otherwise.

Full documentation
int acb_mat_eig_multiple_rump(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec)
int acb_mat_eig_multiple(acb_ptr E, const acb_mat_t A, acb_srcptr E_approx, const acb_mat_t R_approx, slong prec)

Compute enclosures of all n eigenvalues of A with multiplicities, given approximations of the eigenvalues and right eigenvectors. On success (return value 1), the n entries of E are either disjoint or identical, identical entries are consecutive, and a run of k identical entries is a ball that contains exactly k eigenvalues (a cluster that could not be separated at this precision) and is disjoint from the other n - k eigenvalues. Return 0 otherwise.

Full documentation

Internal functions#

void acb_mat_swap_rows(acb_mat_t mat, slong * perm, slong r, slong s)

Swaps rows r and s of mat and, if perm is not NULL, the entries r and s of perm.

slong acb_mat_find_pivot_partial(const acb_mat_t mat, slong start_row, slong end_row, slong c)

Returns the index i with \mathit{start\_row} \le i < \mathit{end\_row} of an entry in column c that does not contain zero and has the largest midpoint (comparing the larger of the absolute values of the real and imaginary parts), or -1 if every entry in that range contains zero.

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.
  • [Joh2014b] F. Johansson, "Evaluating parametric holonomic sequences using rectangular splitting", ISSAC 2014, 256-263. https://doi.org/10.1145/2608628.2608629
  • [Miy2010] S. Miyajima, "Fast enclosure for all eigenvalues in generalized eigenvalue problems", Journal of Computational and Applied Mathematics, 233 (2010), 2994-3004, https://doi.org/10.1016/j.cam.2009.11.048
Cite this page

The FLINT team, “acb_mat.h (module overview),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/acb_mat/index.html (generated 2026-10-20).