bit::matrix
— Bit-Matrix Multiplication
Computes the dot product of a bit-vector with a bit-matrix, a bit-matrix with a bit-vector, and a bit-matrix with another bit-matrix.
template<std::unsigned_integral Block, typename Allocator>
constexpr const vector<Block, Allocator>
1(const matrix<Block, Allocator> &M, const vector<Block, Allocator> &v);
dot
template<std::unsigned_integral Block, typename Allocator>
constexpr const vector<Block, Allocator>
2(const vector<Block, Allocator> &v, const matrix<Block, Allocator> &M);
dot
template<std::unsigned_integral Block, typename Allocator>
constexpr const matrix<Block, Allocator>
3(const matrix<Block, Allocator> &M, const matrix<Block, Allocator> &N); dot
- 1
-
Computes \(M \cdot v\)
IfM
isr x c
, thenv.size()
must bec
. The returned bit-vector will have sizer
. - 2
-
Computes \(v \cdot M\)
IfM
isr x c
, thenv.size()
must ber
. The returned bit-vector will have sizec
. - 3
-
Computes \(M \cdot N\)
IfM
isa x b
, thenN
must beb x c
for somec
. The returned bit-matrix will bea x c
.
These dot products are defined by: \[
\begin{aligned}
\left(M \cdot v\right)_i &= \sum_j M_{ij} \times v_j \\
\left(v \cdot M\right)_j &= \sum_i v_i \times M_{ij} \\
\left(M \cdot N\right)_{ij} &= \sum_k M_{ik} \times N_{kj}
\end{aligned}
\] In the case of \(\mathbb{F}_2\), the product is replaced by logical AND
, and the sum by the logical XOR
operation.
The dot product is a critical operation in linear algebra, so it is fortunate that AND
’ing and XOR
’ing for bit-matrices and bit-vectors can be done very efficiently over blocks of elements simultaneously.
The function arguments must have compatible sizes. Set the BIT_VERIFY flag at compile time to check this condition — any violation will cause the program to abort with a helpful message.
|
Example
#include <bit/bit.h>
int main()
{
::vector<> u(6, [](size_t k) { return k % 2; });
bit::vector<> v(8, [](size_t k) { return (k + 1)% 2; });
bit
::matrix<> M(6, 8, [](size_t i, size_t j) { return i == j; });
bit::matrix<> N(8, 4, [](size_t i, size_t j) { return (i + j)%2; });
bit
std::cout << "bit::matrix M:\n" << M << "\n\n";
std::cout << "bit::matrix N:\n" << N << "\n\n";
std::cout << "dot(" << u << ", M) = " << dot(u, M) << "\n\n";
std::cout << "dot(M, " << v << ") = " << dot(M, v) << "\n\n";
std::cout << "dot(M, N):\n" << dot(M, N) << "\n";
}
Output
bit::matrix M:
│1 0 0 0 0 0 0 0│
│0 1 0 0 0 0 0 0│
│0 0 1 0 0 0 0 0│
│0 0 0 1 0 0 0 0│
│0 0 0 0 1 0 0 0│
│0 0 0 0 0 1 0 0│
bit::matrix N:
│0 1 0 1│
│1 0 1 0│
│0 1 0 1│
│1 0 1 0│
│0 1 0 1│
│1 0 1 0│
│0 1 0 1│
│1 0 1 0│
dot([0 1 0 1 0 1], M) = [0 1 0 1 0 1 0 0]
dot(M, [1 0 1 0 1 0 1 0]) = [1 0 1 0 1 0]
dot(M, N):
│0 1 0 1│
│1 0 1 0│
│0 1 0 1│
│1 0 1 0│
│0 1 0 1│
│1 0 1 0│