GF2::Vector
Overview
A GF2::Vector represents a vector 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 over GF(2) is defined mod 2 which has the effect that addition/subtraction becomes the XOR operation while multiplication/division becomes AND.
The class is something of a hybrid between a std::vector and a std::bitset along with some extra mathematical features to facilitate linear algebra.
We often refer to an object of the type GF2::Vector as a bit-vector.
A bit-vector is dynamically sized at runtime and can be resized as needs dictate.
A std::bitset on the other hand, has a fixed size determined at compile time that can never be changed.
Boost does have a boost::dynamic_bitset`class that, as its name suggests, allows for a bitset to be sized at runtime.
However, it isn’t aimed at algebraic operations.
By default, a bit-vector prints in vector-order.
For example, a bit-vector of size 4 will print as v0v1v2v3 with the elements in increasing order where the least significant element, v0, is printed first on the left.
A std::bitset on the other hand, prints in bit-order.
The equivalent std::bitset prints as b3b2b1b0 with the least significant bit b0 printed last on the right.
To be fair, for many applications printing in bit-order makes perfect sense.
If a size 4 bit-vector or bitset is initialized with the hex number 0x1, the bit-vector prints as 1000.
The bitset prints the same value as 0001 which may be more natural in many settings.
For this reason, GF2::Vector also supports conversions to a string in bit-order though it is not the default.
It isn’t the default because our main aim here is linear algebra.
Bit-order is not at all natural for matrices over GF(2).
It is too confusing to print a matrix in anything but the natural order with the (0,0) element at the top left and proceeding from there.
The elements of a GF2::Vector are packed in an array of some unsigned integer type as defined by the class template parameter Block.
The default Block is an unsigned 64-bit word.
Most of the methods defined in the GF2::Vector class operate on whole blocks at a time so are very efficient.
Declaration
The GF2::Vector class is defined in the header <GF2/Vector.h> as follows:
namespace GF2 {
template<
std::unsigned_integral Block = uint64_t,
Allocator = std::allocator<Block>
> class Vector;
}
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 simple line like:
...
GF2::Vector v(32);
...
This creates a vector with 32 elements which by default are all set to 0. The 32 elements are packed into a singly 64-bit word so in this example there is some spare capacity.
Template Parameters
|
The individual vector elements/bits are packed into blocks of type |
Allocator = |
The default |
The default std::unsigned_integral used for a Block is 64-bits as that is the native size for many modern CPU’s.
Of course if you are using lots of smaller bit-vectors and have concerns about space being conserved you might use a different Block.
Perhaps if the bit-vectors all fit in 8 bits you might have code along the lines
using Vector = GF2::Vector<uint8_t>;
Vector v = ...
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::Vector<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 |
|---|---|
Proxy class representing a reference to an individual vector element (a single bit). |
Class Constants
|
A public |
Methods
Construction |
|
|---|---|
Create a bit-vector in various ways. |
|
Factory methods to construct bit-vectors with all the bits set to 1 or 0 or in a checker board pattern 1010101… or 0101010… |
|
Factory method to construct a bit-vector with a random fill. |
|
Factory method to construct a bit-vector whose elements match the bits of some unsigned integer type. |
|
Element Access |
|
Access a specific bit. |
|
Checks if all, any, or none of the bit-vector elements are set. |
|
The number of set or unset elements ( |
|
Extracts a vector as a distinct copy of some of the elements of this one. |
|
Access the underlying block store: |
|
Read-only access to the underlying |
|
Iteration |
|
Returns the index of the first, last, next, or previous set element. |
|
Iterates over the elements and calls a function for each set index. |
|
Returns the index location of the set or unset bits in the bit-vector. |
|
Capacity |
|
The number of elements in the bit-vector. |
|
Information about the capacity of the bit-vector—how many bits can it contain before needing a memory allocation. |
|
Reserves storage. Does not change the |
|
Tries to reduce memory usage by freeing unused memory |
|
Modifiers |
|
Clears all the elements from the bit-vector so |
|
Removes the last element from the bit-vector or pushes a new on the end. |
|
Adds elements/bits from various sources to the end of the bit-vector. |
|
Resizes the bit-vector, padding out any added values with zeros. |
|
Swaps the values of two elements in the bit-vector. |
|
Swaps the contents of the bit-vector with another. |
|
Methods to replace some of the contents of the bit-vector with other values. |
|
Sets, resets, or flips various ranges of elements in the bit-vector. |
|
Sets or flips the values in a bit-vector based on the return value from a function of the element index. |
|
|
Element-by-element logical operations in-place between this bit-vector and another of equal size. 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-vector elements. |
|
Conversions |
|
Returns various string representations of the bit-vector. |
|
Debugging |
|
A method to write some descriptive data about the bit-vector 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
These functions have the general form One sub-family of these There is another sub-family that takes an unsigned word, a collection of unsigned words, or a |
|
Element-by-element logical operations between two equal sized bit-vectors. Note that in GF(2) addition and subtraction are the same as XOR, while multiplication is the same as AND. |
|
Logical DIFF for two equal sized bit-vectors. |
|
Joins two bit-vectors to create new one. |
|
Returns the dot product of two equal sized bit-vectors. |
|
Returns the convolution of two bit-vectors. |
|
Evaluates a polynomial over GF(2). |
|
Performs stream input and output for bit-vectors. |