FLINT3.7.0-dev
Module · 67 functions

fq_mat.h

#include <flint/fq_mat.h>

This module implements dense matrices over a finite field Fq\mathbb{F}_q in the representation of fq.h. Multiplication packs the entries into integers (Kronecker substitution) and multiplies integer matrices for all but small matrices. The linear algebra functions (LU decomposition, row echelon forms, solving, inversion, rank, nullspace, characteristic and minimal polynomial) are thin wrappers around the generic implementations in gr_mat.h, which call fq_mat_mul for the matrix products. The interface is generated from fq_mat_templates.h and is the same for fq_nmod_mat and fq_zech_mat. fq_default_mat provides the same functions for any finite field.

AlgorithmGaussian elimination and LU decompositionLU decomposition with row pivoting over Z/pZ\mathbb{Z}/p\mathbb{Z} in its classical, delayed-reduction and recursive forms, and how FLINT derives triangular solving, linear system solving, inverses, determinants, ranks, echelon forms and nullspaces from it; plus division-free determinants and the Howell form over Z/nZ\mathbb{Z}/n\mathbb{Z}.

Types and conventions#

A dense matrix with r rows and c columns. The entries are stored in the array entries row by row, with stride elements between the starts of consecutive rows (equal to c except for windows). fq_mat_t is an array of one structure.

  • Matrices must be initialised with the dimensions they are used with; no function resizes its output, and dimensions are checked only by assertions.
  • Unless stated otherwise, outputs may be aliased with inputs of the same dimensions.
  • Entries are elements of Fq\mathbb{F}_q as in fq.h: reduced and normalised.

Memory management#

void fq_mat_init(fq_mat_t mat, slong rows, slong cols, const fq_ctx_t ctx)

Initialises mat as a rows by cols zero matrix.

void fq_mat_init_set(fq_mat_t mat, const fq_mat_t src, const fq_ctx_t ctx)

Initialises mat as a copy of src, with the same dimensions.

void fq_mat_clear(fq_mat_t mat, const fq_ctx_t ctx)

Frees the memory used by mat.

void fq_mat_window_init(fq_mat_t window, const fq_mat_t mat, slong r1, slong c1, slong r2, slong c2, const fq_ctx_t ctx)

Initialises window as the submatrix of mat formed by the rows r1≤i<r2r_1 \le i < r_2 and the columns c1≤j<c2c_1 \le j < c_2. The entries are shared with mat, not copied, so changes to one are visible in the other. mat must not be cleared while the window is in use.

void fq_mat_window_clear(fq_mat_t window, const fq_ctx_t ctx)

Clears a window. The entries, which belong to the underlying matrix, are not freed.

Entries and dimensions#

fq_struct * fq_mat_entry(const fq_mat_t mat, slong i, slong j)

Returns a pointer to the entry in row ii and column jj, indexed from zero. No bounds checking is performed.

void fq_mat_entry_set(fq_mat_t mat, slong i, slong j, const fq_t x, const fq_ctx_t ctx)

Sets the entry in row ii and column jj to xx.

slong fq_mat_nrows(const fq_mat_t mat, const fq_ctx_t ctx)
slong fq_mat_ncols(const fq_mat_t mat, const fq_ctx_t ctx)

Return the number of rows, respectively columns, of mat.

Assignment and permutations#

void fq_mat_set(fq_mat_t mat1, const fq_mat_t mat2, const fq_ctx_t ctx)

Copies mat2 into mat1, which must have the same dimensions.

void fq_mat_swap(fq_mat_t mat1, fq_mat_t mat2, const fq_ctx_t ctx)

Swaps the two matrices by swapping their structures; the dimensions may differ. Not for windows.

void fq_mat_swap_entrywise(fq_mat_t mat1, fq_mat_t mat2, const fq_ctx_t ctx)

Swaps the entries of two matrices of the same dimensions one by one; this also works for windows.

void fq_mat_zero(fq_mat_t A, const fq_ctx_t ctx)
void fq_mat_one(fq_mat_t A, const fq_ctx_t ctx)

Set A to the zero matrix, respectively to the matrix with ones on the main diagonal and zeros elsewhere (also for non-square A).

void fq_mat_swap_rows(fq_mat_t mat, slong * perm, slong r, slong s, const fq_ctx_t ctx)
void fq_mat_swap_cols(fq_mat_t mat, slong * perm, slong r, slong s, const fq_ctx_t ctx)

Swap rows, respectively columns, rr and ss of mat. If perm is not NULL, its entries rr and ss are swapped as well, so that it records the permutation.

void fq_mat_invert_rows(fq_mat_t mat, slong * perm, const fq_ctx_t ctx)
void fq_mat_invert_cols(fq_mat_t mat, slong * perm, const fq_ctx_t ctx)

Reverse the order of the rows, respectively columns, of mat, by swapping row ii and row r−1−ir - 1 - i for 0≤i<⌊r/2⌋0 \le i < \lfloor r/2 \rfloor (and likewise for columns). If perm is not NULL, the same permutation is applied to it.

Conversion and concatenation#

void fq_mat_set_nmod_mat(fq_mat_t mat1, const nmod_mat_t mat2, const fq_ctx_t ctx)
void fq_mat_set_fmpz_mod_mat(fq_mat_t mat1, const fmpz_mod_mat_t mat2, const fq_ctx_t ctx)

Set mat1 to the image of the matrix mat2 over Fp\mathbb{F}_p (or over Z/nZ\mathbb{Z}/n\mathbb{Z}, whose entries are mapped to Fp\mathbb{F}_p by reduction) in Fq\mathbb{F}_q. The dimensions must agree.

void fq_mat_concat_vertical(fq_mat_t res, const fq_mat_t mat1, const fq_mat_t mat2, const fq_ctx_t ctx)
void fq_mat_concat_horizontal(fq_mat_t res, const fq_mat_t mat1, const fq_mat_t mat2, const fq_ctx_t ctx)

Set res to the block matrix (AB)\begin{pmatrix} A \\ B \end{pmatrix}, respectively (A B)(A \ B), for AA = mat1 and BB = mat2. For vertical concatenation of an m×nm \times n and a k×nk \times n matrix, res must be (m+k)×n(m + k) \times n; for horizontal concatenation of an m×nm \times n and an m×km \times k matrix, m×(n+k)m \times (n + k).

Comparison#

int fq_mat_equal(const fq_mat_t mat1, const fq_mat_t mat2, const fq_ctx_t ctx)

Returns whether the matrices have the same dimensions and entries.

int fq_mat_is_zero(const fq_mat_t mat, const fq_ctx_t ctx)
int fq_mat_is_one(const fq_mat_t mat, const fq_ctx_t ctx)

Return whether all entries are zero, respectively whether the diagonal entries are one and the others zero. An empty matrix is both zero and one.

int fq_mat_is_empty(const fq_mat_t mat, const fq_ctx_t ctx)
int fq_mat_is_square(const fq_mat_t mat, const fq_ctx_t ctx)

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

Random matrices#

void fq_mat_randtest(fq_mat_t mat, flint_rand_t state, const fq_ctx_t ctx)

Sets the entries of mat to random elements for testing (see fq_randtest).

int fq_mat_randpermdiag(fq_mat_t mat, flint_rand_t state, fq_struct * diag, slong n, const fq_ctx_t ctx)

Sets mat to a random row and column permutation of the diagonal matrix whose first nn diagonal entries are diag and whose other entries are zero; nn must not exceed the number of rows or columns. Returns the parity of the permutation (0 for even, 1 for odd).

void fq_mat_randrank(fq_mat_t mat, flint_rand_t state, slong rank, const fq_ctx_t ctx)

Sets mat to a random sparse matrix of the given rank, with exactly rank nonzero entries, which are random nonzero elements. fq_mat_randops turns it into a dense matrix of the same rank.

void fq_mat_randops(fq_mat_t mat, flint_rand_t state, slong count, const fq_ctx_t ctx)

Applies count random elementary row or column operations (additions or subtractions of a row or column to another) to mat. This preserves the rank and, for square matrices, the determinant.

void fq_mat_randtril(fq_mat_t mat, flint_rand_t state, int unit, const fq_ctx_t ctx)
void fq_mat_randtriu(fq_mat_t mat, flint_rand_t state, int unit, const fq_ctx_t ctx)

Set mat to a random lower, respectively upper, triangular matrix, with ones on the diagonal if unit is nonzero and random nonzero diagonal entries otherwise.

Input and output#

int fq_mat_fprint(FILE * file, const fq_mat_t mat, const fq_ctx_t ctx)
int fq_mat_print(const fq_mat_t mat, const fq_ctx_t ctx)

Print mat to file, respectively stdout: the number of rows and columns separated by a space, two spaces, and the entries in row-major order in the format of fq_fprint, separated by spaces. Return a positive value on success and a non-positive value on failure.

int fq_mat_fprint_pretty(FILE * file, const fq_mat_t mat, const fq_ctx_t ctx)
int fq_mat_print_pretty(const fq_mat_t mat, const fq_ctx_t ctx)

Print mat to file, respectively stdout, as a bracketed list of bracketed rows, with the entries in the format of fq_fprint_pretty. Return a positive value on success.

Arithmetic#

void fq_mat_transpose(fq_mat_t B, const fq_mat_t A, const fq_ctx_t ctx)

Sets BB to ATA^T. BB must have the transposed dimensions of AA; aliasing is allowed for square matrices.

void fq_mat_add(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx)
void fq_mat_sub(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx)

Set CC to A+BA + B, respectively A−BA - B. All three matrices must have the same dimensions.

void fq_mat_neg(fq_mat_t B, const fq_mat_t A, const fq_ctx_t ctx)

Sets BB to −A-A.

void fq_mat_scalar_mul(fq_mat_t B, const fq_mat_t A, const fq_t c, const fq_ctx_t ctx)
void fq_mat_scalar_mul_fmpz(fq_mat_t B, const fq_mat_t A, const fmpz_t c, const fq_ctx_t ctx)
void fq_mat_scalar_mul_si(fq_mat_t B, const fq_mat_t A, const slong c, const fq_ctx_t ctx)
void fq_mat_scalar_mul_ui(fq_mat_t B, const fq_mat_t A, const ulong c, const fq_ctx_t ctx)

Set BB to cAcA, where cc is an element of Fq\mathbb{F}_q or an integer mapped to Fp\mathbb{F}_p.

void fq_mat_mul(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx)

Sets C=ABC = AB, where AA is m×km \times k, BB is k×nk \times n and CC is m×nm \times n. Aliasing is allowed. The function uses fq_mat_mul_KS if FQ_MAT_MUL_KS_CUTOFF returns 1 for mm and nn, and fq_mat_mul_classical otherwise.

Returns 1 if fq_mat_mul should use Kronecker substitution for an r×kr \times k times k×ck \times c product, which is the case if 5min⁡(r,c)>8d+295 \min(r, c) > 8d + 29. (FQ_NMOD_MAT_MUL_KS_CUTOFF and FQ_ZECH_MAT_MUL_KS_CUTOFF are the corresponding tuned functions of the other representations.)

void fq_mat_mul_classical(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx)

Sets C=ABC = AB by computing each entry as a dot product with _fq_vec_dot, which reduces modulo the defining polynomial only once per entry. Aliasing is allowed.

void fq_mat_mul_KS(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx)

Sets C=ABC = AB by Kronecker substitution. CC must not be aliased with AA or BB.

More
void fq_mat_submul(fq_mat_t D, const fq_mat_t C, const fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx)

Sets D=C−ABD = C - AB. DD may be aliased with CC, AA or BB.

void fq_mat_mul_vec(fq_struct * c, const fq_mat_t A, const fq_struct * b, slong blen, const fq_ctx_t ctx)
void fq_mat_mul_vec_ptr(fq_struct * const * c, const fq_mat_t A, const fq_struct * const * b, slong blen, const fq_ctx_t ctx)

Set the vector cc to the matrix-vector product AbAb. The vector (b, blen) is truncated or extended by zeros to the number of columns of AA, and cc receives as many entries as AA has rows. The _ptr version takes arrays of pointers to the entries. cc must not alias bb.

void fq_mat_vec_mul(fq_struct * c, const fq_struct * a, slong alen, const fq_mat_t B, const fq_ctx_t ctx)
void fq_mat_vec_mul_ptr(fq_struct * const * c, const fq_struct * const * a, slong alen, const fq_mat_t B, const fq_ctx_t ctx)

Set the vector cc to the vector-matrix product aBaB. The vector (a, alen) is truncated or extended by zeros to the number of rows of BB, and cc receives as many entries as BB has columns. cc must not alias aa.

Gaussian elimination#

These functions use recursive (block) LU decomposition and triangular solving for large matrices (Gaussian elimination and LU decomposition), so that their cost is dominated by matrix multiplications with fq_mat_mul.

slong fq_mat_lu(slong * P, fq_mat_t A, int rank_check, const fq_ctx_t ctx)

Computes a generalised LU decomposition PA=LUPA = LU of AA in place, and returns the rank of AA. P must have room for as many entries as AA has rows; it receives the row permutation.

More
slong fq_mat_rref(fq_mat_t B, const fq_mat_t A, const fq_ctx_t ctx)

Sets BB to the reduced row echelon form of AA and returns the rank of AA. The form is computed from an LU decomposition. BB may be aliased with AA. If AA is zero, BB is set to zero and 0 is returned.

Reduces row mm of AA against the earlier rows, which must already be in reduced form (pivot entries 1, not necessarily in order), and returns the column of the new pivot, or −1-1 if row mm becomes zero. P[i] is the row with its pivot in column ii, or −1-1; it is updated when a new pivot is found, and the new pivot row is scaled to make the pivot 1. L[i] is the number of possibly nonzero columns of row ii, which allows faster reduction of matrices that are zero on the right; the entries of L must be nondecreasing, and can all be set to the number of columns. The arithmetic is done without intermediate reductions modulo the defining polynomial.

slong fq_mat_rank(const fq_mat_t A, const fq_ctx_t ctx)

Returns the rank of AA, computed by LU decomposition.

int fq_mat_inv(fq_mat_t B, fq_mat_t A, const fq_ctx_t ctx)

If the square matrix AA is invertible, sets B=A−1B = A^{-1} and returns 1; otherwise returns 0 and the entries of BB are undefined. AA is not modified (although not declared const), and BB may be aliased with AA.

void fq_mat_solve_tril(fq_mat_t X, const fq_mat_t L, const fq_mat_t B, int unit, const fq_ctx_t ctx)
void fq_mat_solve_triu(fq_mat_t X, const fq_mat_t U, const fq_mat_t B, int unit, const fq_ctx_t ctx)

Set X=L−1BX = L^{-1} B, respectively X=U−1BX = U^{-1} B, for a square lower, respectively upper, triangular matrix with nonzero diagonal entries. If unit is nonzero, the diagonal is assumed to consist of ones and is not read. Only the triangular part of the matrix is read. Aliasing of XX and BB is allowed. Classical substitution is used if BB has fewer than 64 rows or columns, and block recursion otherwise.

int fq_mat_solve(fq_mat_t X, const fq_mat_t A, const fq_mat_t C, const fq_ctx_t ctx)

Solves AX=CAX = C for a square matrix AA. Returns 1 and sets XX if AA is nonsingular; otherwise returns 0 and XX is undefined.

int fq_mat_can_solve(fq_mat_t X, const fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx)

Solves AX=BAX = B for a matrix AA of any shape: if a solution exists, sets XX to one and returns 1, otherwise returns 0 and XX is undefined. For an m×nm \times n matrix AA and an m×km \times k matrix BB, XX must be n×kn \times k.

Computes a basis of the right nullspace {v:Av=0}\{v : Av = 0\} of AA and returns its dimension kk (the nullity). XX must have as many rows and at least as many columns as AA has columns; its first kk columns receive the basis and the remaining columns are set to zero.

Characteristic and minimal polynomial#

void fq_mat_similarity(fq_mat_t A, slong r, fq_t d, const fq_ctx_t ctx)

Replaces the square matrix AA by P−1APP^{-1} A P, where PP is the identity matrix with the entries in row rr and every column j∉{r−1,r}j \notin \{r - 1, r\} replaced by dd. Such transforms preserve the characteristic and minimal polynomials.

The characteristic and minimal polynomials of a matrix, fq_mat_charpoly and fq_mat_minpoly, are declared in fq_poly.h and documented with fq_poly.h.

Cite this page

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