GF2::Matrix
Overview
A GF2::Matrix represents a matrix over GF(2) (a.k.a. \(\mathbb{F}_2\)) the simplest Galois field that has just two elements usually denoted 0 & 1, or as booleans—true & false, or as bits—set & unset.
Arithmetic in GF(2) is defined mod 2 which has the effect that addition/subtraction becomes the XOR operation while multiplication/division becomes AND.
We often refer to an object of the type GF2::Matrix as a bit-matrix.
It is a matrix where all the elements are either 0 or 1 and where arithmetic is expected to be done mod 2.
A GF2::Matrix is stored in row-major mode where each row is a single GF2::Vector.
This means it is typically much more efficient to arrange computations to work row by row as opposed to column by column.
Most of the time you will be using higher level methods already defined in the class or as free functions where that is already taken into account.
The main aim here is to facilitate efficient linear algebra over GF(2) where the bit-vector class is GF2::Vector.
This bit-matrix class is implemented as a std::vector of rows where each row is a single bit-vector.
If instead, the primary aim was to minimize storage, one would simply store the bit-matrix as a single long bit-vector with appropriate index operations.
However, in that case, matrix operations would often need to be done on an element by element basis which is much, much slower than doing things block by block as we do here.
Like bit-vectors, bit-matrices are sized dynamically at runtime and the row elements are packed into blocks that can be any unsigned integral type. That template parameter defaults to 64-bit words (it might be reasonable to use a smaller type for lots of small matrices).
Arbitrary \(m \times n\) bit-matrices are supported but some methods only make sense for square matrices where \(n = m\).
Many of the methods defined for GF2::Vector are also implemented for GF2::Matrix.
We also define free functions dot(lhs, rhs) to handle matrix-vector, vector-matrix, and matrix-matrix multiplication.
There are methods to solve linear systems of equations \(A \cdot x = b\).
Danilevsky’s method to compute characteristic polynomials, (and the determinant) for a GF2::Matrix is available and works for quite large matrices (ones with millions of entries) that would choke a naive implementation that didn’t take into account the special nature of arithmetic over GF(2).
See below for the full list.
Declaration
The GF2::Matrix class is defined in the header <GF2/Matrix.h> as follows:
namespace GF2 {
template<
std::unsigned_integral Block = uint64_t,
Allocator = std::allocator<Block>
> class Matrix;
}
The two template parameters add some visual clutter but they both have reasonable defaults so the clutter completely disappears in most uses.
For example your code might have a line like:
...
GF2::Matrix M(3,5);
...
This creates a 3 x 5 matrix with 15 elements which by default are all set to 0.
Template Parameters
|
The individual matrix elements/bits are stored by row and the rows in turn are packed into blocks.
The default |
|
The default |
As mentioned, the default std::unsigned_integral used for a Block is 64-bits which is the native size for many modern CPU’s.
Of course if you are using lots of smaller bit-matrices and have concerns about space being conserved you might use a different Block.
Perhaps if the bit-matrices all fit in 32 bits you might have code along the lines
using Matrix = GF2::Matrix<uint32_t>;
Matrix mat = ...
You should use just one Block type throughout your code. In theory, there is no reason that one couldn’t intermingle operations between say a GF2::Matrix<uint32_t> and a GF2::Vector<uint64_t> but doing so efficiently greatly increases code complexity and the library doesn’t support this.
|
Class Types
Type |
Definition |
|---|---|
|
Alias for |
Methods
Construction |
|
|---|---|
Create a bit-matrix in various ways. |
|
Class methods to construct a bit-matrix with a random fill. |
|
Class methods to construct various “special” bit-matrices. |
|
Class method so construct a companion matrix from its top-row only. |
|
Queries |
|
Query to see if this matrix is special in some way. |
|
Element Access |
|
Access a bit-matrix element, or a whole row, or whole column. |
|
Checks if all, any, or none of the bit-matrix elements are set. |
|
The number of set elements overall or just on a diagonal. |
|
Extracts a bit-matrix as a distinct copy of some of the elements of this one. |
|
Extracts the lower or upper triangular elements of this bit-matrix.
These return distinct copies of some of the elements of this bit-matrix. |
|
Capacity |
|
The number of rows, columns, and elements in the bit-matrix etc. |
|
Information about the capacity of the bit-matrix—how many rows/columns can be added without needing a memory allocation. |
|
Tries to reduce memory usage by freeing unused memory |
|
Modifiers |
|
Clears all the elements from the bit-matrix so |
|
Resizes the bit-matrix, padding out any added values with zeros. |
|
Adds a single row or a column to the end of the bit-matrix or remove the final row or column. |
|
Augments a bit-matrix in-place by appending columns from a vector or another bit-matrix on the right. |
|
Swaps two rows or two columns in a bit-matrix. |
|
Transpose a square bit-matrix in-place. |
|
Methods to replace some of the contents of the bit-matrix with other values. |
|
Sets, resets, or flips various elements in the bit-matrix. |
|
Sets or flips the values in a bit-matrix based on the return value from a function of each element index-pair. |
|
|
Element-by-element logical operations between this bit-matrix and another of equal dimensions. Note that in GF(2) addition and subtraction are the same as XOR, while multiplication is the same as AND. |
Left and right shifts of the bit-matrix rows. |
|
Changes this bit-matrix in place to a row-echelon form. |
|
Conversions |
|
Returns various string representations of the bit-matrix. |
|
Packs the bit-matrix into a bit-vector. |
|
Other methods |
|
Returns the probability that a “fair” square bit-matrix is either invertible or singular. |
|
Debugging |
|
A method to write some descriptive data about the bit-matrix to a stream. |
|
|
The first two are optional compile time flags that control the degree of safety checking that is performed in the library. |
Non-member Functions
Element-by-element logical operations between two bit-matrices of equal dimensions. Note that in GF(2) addition and subtraction are the same as XOR, while multiplication is the same as AND. |
|
Returns the dot product of a bit-matrix with a bit-vector or another bit-matrix. |
|
Returns an augmented bit-matrix by copying one input and then appending columns from a bit-vector or another bit-matrix on the right of that. |
|
Returns the transpose of an arbitrary rectangular bit-matrix as a new bit-matrix. |
|
Raises a square bit-matrix to a power \(n\) or \(2^n\) respectively. |
|
Evaluates a polynomial over GF(2) using a square bit-matrix as the argument. |
|
Attempts to return the inverse of a square bit-matrix. |
|
Attempts to solve a system of linear equations \(A \cdot x = b\) where \(A\) is a square bit-matrix. |
|
Returns a |
|
Returns a |
|
Returns the row-echelon forms of an arbitrary bit-matrix. |
|
Returns the coefficients of the characteristic polynomial of a square bit-matrix. |
|
Returns the companion matrices that are the diagonal blocks in the Frobenius form of a square bit-matrix. |
|
Performs stream input and output for bit-matrices. |
|
Prints multiple bit-matrices or a bit-matrix with potentially multiple bit-vectors side by side to a stream. |