Documentation contents

atlas Library · Script File

Gaussian_elim.at

Gaussian elimination on matrices represented by values of type [[rat]]

Use as matrices: lists of their columns, each a list of rational numbers

The main problem considered is fully solving linear systems, including the
problem of inverting a rational matrix (when it can(.

The idea is to do full Gauss-Jordan reduction of the original matrix |A|,
transforming it into an identity matrix, and retain from this process just
the data describing the row operations performed (the reduced matrix itself
is uninteresting). That data can then be applied to a RHS column vector to
solve a linear system, or to a full identity matrix to find |A^-1|. It can
also be used to quickly find the determinant of |A|. These algorithms are
preferable for large matrices to using those built-in for integral matrices,
which are prone to suffer from extreme coefficient growth.

We allow for the possibility of finding columns for which no pivot can be
located (all candidate rows have zeros), in which case we put a different kind
of information in the pivot data, which can later be used to determine the
kernel of the (original) matrix. Of course this should not happen when a
matrix is to be inversed, but functions try to do what they intend to do in
the most general setting (and here we do not even assume square matrices).
Source
atlas-scripts/Gaussian_elim.at (175 lines)
Definitions
16
Loads
Loaded by
cyclotomic.at

Definitions in source order

Pivot_info type

L27
set_type Pivot_info = ( (int,[rat]) pivot | [rat] no_pivot )

Fields: pivot, no_pivot

When doing a pivot step, we either find a pivot, or not. In the former case
we record the pivot row number, as well as the row operation to be applied
after the cyclic row permutation bringing the pivot to the echelon position is
done (row number equal to the number of previous pivots). The latter row
operation is left-multiplication by a matrix differing by only one column from
the identity, and that column is recorded. Since we are doing (full)
Gauss-Jordan reduction and the row permutation is implied by the pivot number,
this column has the inverse of the pivot value on its main diagonal position,
and all other coefficients can be arbitrary. In case no pivot is found (the
part of the column where a pivot might be found is zero) we instead record the
nonzero initial part of the column as the |no_pivot| variant of |Pivot_info|.
L28

times 2 overloads

L42times ([[rat]] M, [rat] v) = [rat]
L45times ([[rat]] M, [[rat]] N) = [[rat]]

pivot_step

L48pivot_step (([rat]->int) choose_pivot) = ([[rat]] M, int i) (Pivot_info , [[rat]] )
the |pivot_step| takes as argument the choice function for the pivot
and produces a function that takes a matrix and a count of previous pivots
for step
remaining matrix

greedy

L73greedy ([rat] choices) = int
the simplest strategy is to select the first nonzero coefficient as pivot

also defined in cyclotomic_Gaussian_elim.at

step

L75step = pivot_step(greedy@[rat])

also defined in cyclotomic_Gaussian_elim.at

get_data

L77get_data ([[rat]] M) = [Pivot_info]

also defined in all_finite_order.at, cyclotomic_Gaussian_elim.at

Once accumulated, the different |Pivot_info| values are combined, taking the
|pivot| fields together (extracting them for the union type), while
transforming the information of non-pivot cases into a matrix whose columns
are independent and span the kernel. A third component of the result is a
function that transforms a row-reduced RHS vector, with as many components as
there are pivots, into a full size vector solution, by mapping each entry to
the corresponfing pivot position, and interspersing zeros at the non-pivot
positions. This function |spread| is constructed by repeated modification,
each newer version first calling the older one and then taking one more entry
to its proper destination. We avoid inadvertently building a recursive call,
by first binding the old function value to a new name |f|, and calling a
function of that name from the newly extended function.
L86

split_data

L100split_data = …

also defined in cyclotomic_Gaussian_elim.at

det

L123det ([[rat]] A) = rat
From the pivot data we can aso directly compute the determinant, basically the
product of the inverses of the main diagonal entries of the row operations.

also defined in basic.at, ratmat.at, cyclotomic_Gaussian_elim.at

apply 2 overloads

L131apply (int i, int k, [rat] coefs) = ([rat]->[rat])
Perform row operations from encoded pivot datum, and new pivot row index |i|
L143apply ([int,[rat]] pivots) = ([rat]->[rat])
Compose those functions for all pivot data (obtained from |split_data|)

also defined in cyclotomic_Gaussian_elim.at

Now put the above together for solving a rational linear system |A*x=b|
L147

affine_subspace type

L149
set_type affine_subspace = ([rat] base_point ,[[rat]] tangent_space)

Fields: base_point, tangent_space

full_solve

L151full_solve ([[rat]] A, [rat] b) = Maybe<affine_subspace>

also defined in cyclotomic_Gaussian_elim.at

a_solution

L160a_solution (([[rat]],[rat])system) = [rat]
When we need one solution, pick particular solution or throw error if none

also defined in cyclotomic_Gaussian_elim.at, cyclotomic_Lie_algebra.at

make_inverse

L167make_inverse ([(int,[rat])] data) = [[rat]]
For inverse of a matrix, apply row operations to columns of identity matrix

also defined in cyclotomic_Gaussian_elim.at

inverse

L170inverse ([[rat]] M) = [[rat]]

also defined in basic.at, combinatorics.at, ratmat.at, parameters.at, tits.at, affine.at, cyclotomic.at, cyclotomic_Gaussian_elim.at, lazy_lists.at

Generated from atlas-scripts at commit 648506c (2026-10-13).