diff --git a/.nojekyll b/.nojekyll index b842712..335681d 100644 --- a/.nojekyll +++ b/.nojekyll @@ -1 +1 @@ -0f37c3a0 \ No newline at end of file +d02e2c60 \ No newline at end of file diff --git a/content/bit_assert/index.html b/content/bit_assert/index.html index d1f0aeb..8d6a3fd 100644 --- a/content/bit_assert/index.html +++ b/content/bit_assert/index.html @@ -531,12 +531,10 @@
The bit_assert.h
header has three replacements for the standard assert
macro — they all allow for an additional string output that you can use to print the values of the variables that triggered any failure.
1bit_assert(condition, message)
-2bit_debug_assert(condition, message)
-3bit_always_assert(condition, message)
The bit_assert.h
header has two replacements for the standard assert
macro — they allow for an additional string output that you can use to print the values of the variables that triggered any failure.
BIT_NDEBUG
flag at compile time. This version is closest in spirit to the standard assert
macro.
+Assertions of this type are only verified if you set the BIT_DEBUG
flag at compile time.
BIT_DEBUG
flag at compile time.
-Assuming the asserts are “on,” in all cases, if condition
evaluates to false
, we print an error message to std::cerr
, and the program will exit.
Assuming an assertion is “on,” in all cases, if condition
evaluates to false
, we print an error message to std::cerr
, and the program will exit.
The error message always includes the location of the failure and an extra dynamic payload typically used to print the values of the variables that triggered the failure. The payload can be anything that can be formatted using the facilities in std::format
.
These look like functions but are macros, and the level of assertion checking performed is controlled by setting compiler flags at build time:
-Macro | -Description | -
---|---|
BIT_DEBUG |
-If set, we will perform demanding but potentially useful safety assertions on indices, size equality checks, etc. | -
BIT_NDEBUG |
-If set, we turn off even relatively innocuous safety assertions for maximum performance. | -
If you set the BIT_NDEBUG
flag, the library will ensure that BIT_DEBUG
is not set.
If you set the BIT_DEBUG
flag, the library will perform demanding but potentially useful safety assertions on indices, size equality checks, etc. Otherwise all the bit_debug_assert
calls are no-ops.
Here m_size
is holds the size of the vector—so we must have i < m_size
Here m_size
is holds the size of the vector — so we must have i < m_size
To check every element access, set the BIT_DEBUG
flag during compiles. If the assertion fails, the program exits with an error message that gives the offending values.
The bit_debug_assert
line expands to nothing if the BIT_DEBUG
flag is not set during compiles.
Example—Message from an assertion failure
+Example — Message from an assertion failure
#include <bit/bit.h>
int main()
{
@@ -693,7 +658,7 @@ Examples
Compile the sample program with the BIT_DEBUG
flag set and get:
Output
BIT ASSERTION FAILURE:
-Function 'set' (vector.h, line 893):
+Function 'set' (vector.h, line 910):
Statement 'i < m_size' is NOT true: Index i = 12 must be < `m_size` = 12
The program will then exit.
@@ -708,24 +673,16 @@ bit_debug_assertThe check here is off by default, and you need to do something special (i.e., define the BIT_DEBUG
flag at compile time) to enable it. The idea is that production code may do many of these dot products, and we do not generally want to pay for the check. However, enabling these sorts of checks may be very useful during development.
The bit_debug_assert(...)
macro expands to nothing unless you set the BIT_DEBUG
flag at compile time.
-
-bit_assert
-On the other hand, some checks are pretty cheap, especially when you compare the cost to the actual work done by the function. The bit_assert(...)
form is helpful for those cheaper verifications.
-For example, a pre-condition for a matrix inversion method is that the input matrix must be square. Here is how you might do that check in an invert(const Matrix& M)
function:
-
-We can only invert square matrices. The M.is_square()
call checks that condition and, on failure, throws an exception with a helpful message.
-This particular check is always on by default, and the programmer needs to do something special (i.e., define the BIT_NDEBUG
flag at compile time) to deactivate it.
-The bit_assert(...)
macro expands to nothing only if you set the BIT_NDEBUG
flag at compile time — the behavior is the same as the standard assert
macro but allows for adding a formatted error message.
-
bit_always_assert
-There may be checks you never want to be turned off. The final form bit_always_assert(...)
accomplishes those tasks — it is unaffected by compiler flags.
-For instance, in that last example, the check cost is very slight compared to the work done by the invert(...)
method, so leaving it on even in production code is probably not a problem. You might well want to use the bit_always_assert(...)
version so the check never gets disabled:
-
-The decision to use one of these forms vs. another depends on the cost of doing the check versus the work done by the method in question. A primary use case for bit_debug_assert
is to do things like bounds checking on indices — from experience, this is vital during development. However, bounds-checking every index operation incurs a considerable performance penalty and can slow down numerical code by orders of magnitude. So it makes sense to have the checks in place for development but to ensure they are never there in release builds.
-In the development cycle, asserting range indices and so on is helpful. However, those assertions are expensive and can slow down numerical code by orders of magnitude. Therefore, we don’t want there to be any chance that those verifications are accidentally left “on” in our production code. The first form, bit_debug_assert(...)
, covers these asserts. Turning on bit_debug_assert
asserts requires the programmer to take a specific action, namely, setting the BIT_DEBUG
flag during compile time.
-On the other hand, some assertions are relatively cheap, especially compared to the work done by the containing function. For example, a pre-condition for the matrix::invert
method is that the input bit-matrix is square. There is probably no harm if we always do that assert, which is very cheap compared to the typical cost of inverting a bit-matrix. The second form, bit_assert(...)
, is suitable for those cheaper verifications. Turning off even those assertions is possible, but the programmer must take a specific action. She must set the BIT_NDEBUG
flag during compile time.
-Finally, you may wish that some assertions are always checked. The final form above accomplishes those tasks.
+There may be other checks you never want to be turned off. The bit_always_assert(...)
form accomplishes those tasks — it is unaffected by compiler flags.
+For example, a pre-condition for a matrix inversion method is that the input matrix must be square. Here is how we do that check in an invert(const Matrix& M)
function:
+
+We can only invert square matrices. The M.is_square()
call checks that condition and, on failure, exits the program with a helpful message.
+Here the cost of the check is very slight compared to the work done by the invert(...)
method, so leaving it on even in production code is not a problem.
+The decision to use one form vs. the other depends on the cost of doing the check versus the work done by the method in question. A primary use case for bit_debug_assert
is to do things like bounds checking on indices — from experience, this is vital during development. However, bounds-checking every index operation incurs a considerable performance penalty and can slow down numerical code by orders of magnitude. So it makes sense to have the checks in place for development but to ensure they are never there in release builds.
+The first form, bit_debug_assert(...)
, covers these types of checks. Turning on bit_debug_assert
asserts requires the programmer to take a specific action, namely, setting the BIT_DEBUG
flag during compile time.
+On the other hand, some assertions are relatively cheap, especially compared to the work done by the containing function. For example, a pre-condition for the matrix::invert
method is that the input bit-matrix is square. There is probably no harm if we always do that assert, which is very cheap compared to the typical cost of inverting a bit-matrix. The second form, bit_always_assert(...)
, is suitable for those cheaper verifications.
diff --git a/content/matrix/access.html b/content/matrix/access.html
index 04a5e28..a3e4cbf 100644
--- a/content/matrix/access.html
+++ b/content/matrix/access.html
@@ -668,7 +668,7 @@ bit::matrix
— Element Access<
See Also
+[bit_assert
]
diff --git a/content/matrix/index.html b/content/matrix/index.html
index 66408c2..1c49096 100644
--- a/content/matrix/index.html
+++ b/content/matrix/index.html
@@ -1160,21 +1160,13 @@ Debugging
-BIT_DEBUG
+BIT_DEBUG
This compile-time flag enables extra safety checks.
-BIT_NDEBUG
-This compile-time flag turns off most safety checks.
-
-
bit_debug_assert
These assertions are only checked if the BIT_DEBUG
flag is set at compile time.
-
-bit_assert
-These assertions are checked unless the BIT_NDEBUG
flag is set at compile time.
-
bit_always_assert
Use this form for checks that must always be performed.
diff --git a/content/matrix/invert.html b/content/matrix/invert.html
index 20e5bc1..1bff7e4 100644
--- a/content/matrix/invert.html
+++ b/content/matrix/invert.html
@@ -600,7 +600,7 @@ bit::matrix
— Bit-Matrix Inve
-The input matrix must be square, and the bit_assert
macro checks that pre-condition. Setting the BIT_NDEBUG
flag at compile time turns off that check.
+The input matrix must be square, and the bit_always_assert
macro checks that pre-condition.
Example
diff --git a/content/matrix/pow.html b/content/matrix/pow.html
index 81e91e1..8067b53 100644
--- a/content/matrix/pow.html
+++ b/content/matrix/pow.html
@@ -602,7 +602,7 @@ bit::matrix
— Powers of a Bit
-The input matrix must be square, and the bit_assert
macro checks that pre-condition. Setting the BIT_NDEBUG
flag at compile time turns off that check.
+The input matrix must be square, and the bit_always_assert
macro checks that pre-condition.
Example
diff --git a/content/matrix/swap.html b/content/matrix/swap.html
index 942e71e..4413559 100644
--- a/content/matrix/swap.html
+++ b/content/matrix/swap.html
@@ -596,7 +596,7 @@ bit::matrix
— Swap Two Rows/C
-Generally, these methods do not check whether the indices are in bounds. If they aren’t, the behavior is undefined (but bound to be wrong!) All of them will perform range checking if you set the BIT_DEBUG
at compile time. See bit_assert
.
+Generally, these methods do not check whether the indices are in bounds. If they aren’t, the behavior is undefined (but bound to be wrong!) All of them will perform range checking if you set the BIT_DEBUG
at compile time. See [bit_assert
].
Example
diff --git a/content/notes/design.html b/content/notes/design.html
index 42b7118..5e9f5b3 100644
--- a/content/notes/design.html
+++ b/content/notes/design.html
@@ -761,9 +761,7 @@ Assertions
The most commonly used form in the library is bit_debug_assert(...)
. This form expands to nothing unless the programmer sets the BIT_DEBUG
flag at compile time. That is typically done automatically only for debug software builds and is never done for release/optimized builds.
-There are a couple of other versions of our assert macros.
-The bit_assert(...)
macro is always on unless the programmer sets the BIT_NDEBUG
flag at compile time. Typically, we employ this form if the assertion check is relatively cheap compared to the work done in the function call. For example, the bit-matrix inversion function uses this form of assertion to check that the input bit-matrix is square. That check cost is negligible compared to the typical cost of inverting a bit-matrix, but to extract every ounce of efficiency, you can set the BIT_NDEBUG
flag during compile time.
-Finally, some checks must always be performed. The bit_always_assert(...)
form handles those cases.
+There is also a version bit_always_assert(...)
for checks that should always be carried out no matter what flags are passed to the compiler. Typically these are for assertions where the cost of the check is cheap compared to the cost of the work done in the method.
diff --git a/content/notes/gf2.html b/content/notes/gf2.html
index ff0c090..00e25e9 100644
--- a/content/notes/gf2.html
+++ b/content/notes/gf2.html
@@ -629,7 +629,7 @@ Some things are si
Gaussian Elimination in \(\FF\)
Suppose that \(A\) is an \(n \times n\) matrix over \(\FF\) and \(b\) is a compatibly sized bit-vector where we are interested in finding an \(x\) satisfying \(A \cdot x = b\). Then the pseudocode for Gaussian elimination looks like:
-
+
\begin{algorithm} \caption{Gaussian Elimination in $F_2$} \begin{algorithmic} \Procedure{Solve}{$A, b, n$} \For {$j = 0$ \To $n - 1$} \State $s = j$ \While {$A(s,j) = 0$} \State $s = s + 1$ \EndWhile \If {$s > n$} \Continue \EndIf \If {$ s \ne j$} \State swap rows $s$ and $j$ in the matrix $A$ \State swap elements $s$ and $j$ in the vector $b$ \EndIf \For {$i = j+1$ \To $n$} \If {$A(i,j) == 1$} \State replace row $i$ in $A$ with the sum of rows $i$ and $j$ \State replace element $i$ in $b$ with the sum of elements $i$ and $j$ \EndIf \EndFor \EndFor \EndProcedure \end{algorithmic} \end{algorithm}
diff --git a/content/polynomial/access.html b/content/polynomial/access.html
index d80a6c9..250bfce 100644
--- a/content/polynomial/access.html
+++ b/content/polynomial/access.html
@@ -683,7 +683,7 @@ bit::polynomial
— Coefficient
See Also
polynomial::reference
polynomial::size
-bit_assert
+[bit_assert
]
diff --git a/content/polynomial/evaluation.html b/content/polynomial/evaluation.html
index f1bcda2..e7776a2 100644
--- a/content/polynomial/evaluation.html
+++ b/content/polynomial/evaluation.html
@@ -629,7 +629,7 @@ Matrix Arguments
-The input matrix must be square, and the bit_assert
macro checks that pre-condition. Setting the BIT_NDEBUG
flag at compile time turns off that check.
+The input matrix must be square, and the bit_always_assert
macro checks that pre-condition.
Example
diff --git a/content/polynomial/index.html b/content/polynomial/index.html
index 38186c2..b352ed6 100644
--- a/content/polynomial/index.html
+++ b/content/polynomial/index.html
@@ -995,7 +995,7 @@ Other Instance Meth
Debugging
-You can set some compile-time flags that enable extra safety checks. You might set these flags in DEBUG
builds where performance is not the critical concern.
+You can set a compile-time flag to enable extra safety checks. These checks can have a severe performance penalty so typically are only turned on for development.
@@ -1010,21 +1010,13 @@ Debugging
-BIT_DEBUG
+BIT_DEBUG
This compile-time flag enables extra safety checks.
-BIT_NDEBUG
-This compile-time flag turns off most safety checks.
-
-
bit_debug_assert
These assertions are only checked if you set the BIT_DEBUG
flag at compile time.
-
-bit_assert
-These assertions are checked unless you set the BIT_NDEBUG
flag at compile time.
-
bit_always_assert
These assertions are always checked.
diff --git a/content/vector/access.html b/content/vector/access.html
index 75ef9bd..080ceaa 100644
--- a/content/vector/access.html
+++ b/content/vector/access.html
@@ -672,7 +672,7 @@ bit::vector
— Element Access<
See Also
vector::reference
vector::size
-bit_assert
+[bit_assert
]
diff --git a/content/vector/index.html b/content/vector/index.html
index 93717a6..52ef34b 100644
--- a/content/vector/index.html
+++ b/content/vector/index.html
@@ -1210,7 +1210,7 @@ Other Instance Meth
Debugging
-You can set some compile-time flags that enable range checking and so on. You might set these flags in DEBUG
builds where performance is not the critical concern.
+You can set a compile-time flag BIT_DEBUG
to enable range checking and other assertions. These checks can have a substantial performance impact so typically are only used during development.
@@ -1225,21 +1225,13 @@ Debugging
-BIT_DEBUG
+BIT_DEBUG
This compile-time flag enables extra safety checks.
-BIT_NDEBUG
-This compile-time flag turns off most safety checks.
-
-
bit_debug_assert
These assertions are only checked if you set the BIT_DEBUG
flag at compile time.
-
-bit_assert
-These assertions are checked unless you set the BIT_NDEBUG
flag at compile time.
-
bit_always_assert
These assertions are always checked.
diff --git a/search.json b/search.json
index f111147..a171dcd 100644
--- a/search.json
+++ b/search.json
@@ -105,14 +105,14 @@
"href": "content/matrix/pow.html",
"title": "bit::matrix — Powers of a Bit-Matrix",
"section": "",
- "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have methods that raise a square bit-matrix to a power \\(n\\) or \\(2^n\\).\ntemplate<std::unsigned_integral Block, typename Allocator>\nconstexpr matrix<Block, Allocator>\n1pow(const matrix<Block, Allocator> &M, std::size_t n);\n\ntemplate<std::unsigned_integral Block, typename Allocator>\nconstexpr matrix<Block, Allocator>\n2pow2(const matrix<Block, Allocator> &M, std::size_t n);\n\n1\n\nReturns \\(M^n\\).\n\n2\n\nReturns \\(M^{2^n}\\).\n\n\nFor example, we can raise \\(M\\) to the power \\(2^{128}\\), which is not representable as a typical std::size_t.\nWe use repeated squaring to compute the powers efficiently. It is also worth noting that all arithmetic in \\(\\FF\\) is mod 2, so there are no overflow issues even for large \\(n\\).\n\n\n\n\n\n\nThe bit-matrix argument must be square\n\n\n\nThe input matrix must be square, and the bit_assert macro checks that pre-condition. Setting the BIT_NDEBUG flag at compile time turns off that check.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n auto M = bit::matrix<>::random(4);\n std::cout << \"M:\\n\" << M << '\\n';\n1 std::cout << \"M^2:\\n\" << pow(M,2) << '\\n';\n2 std::cout << \"M^{256}:\\n\" << pow(M,256) << '\\n';\n3 std::cout << \"M^{2^8}:\\n\" << pow2(M,8) << '\\n';\n4 std::cout << \"M^{2^{100}}:\\n\" << pow2(M,100) << '\\n';\n}\n\n1\n\nSimple square of a small random bit-matrix.\n\n2\n\nRaise to the power \\(256\\) using pow.\n\n3\n\nRaise to the power \\(2^8 = 256\\) using pow2.\n\n4\n\nRaise to the power \\(2^{100} = 1,267,650,600,228,229,401,496,703,205,376\\).\n\n\nOutput\nM:\n│1 0 1 1│\n│1 1 0 1│\n│0 0 0 1│\n│1 1 1 1│\nM^2:\n│0 1 0 1│\n│1 0 0 1│\n│1 1 1 1│\n│1 0 0 0│\nM^{256}:\n│0 0 0 1│\n│1 1 0 1│\n│1 0 1 1│\n│0 1 0 1│\nM^{2^8}:\n│0 0 0 1│\n│1 1 0 1│\n│1 0 1 1│\n│0 1 0 1│\nM^{2^{100}}:\n│0 0 0 1│\n│1 1 0 1│\n│1 0 1 1│\n│0 1 0 1│\n\nSee Also\npolynomial::operator()\n\n\n\n\n Back to top"
+ "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have methods that raise a square bit-matrix to a power \\(n\\) or \\(2^n\\).\ntemplate<std::unsigned_integral Block, typename Allocator>\nconstexpr matrix<Block, Allocator>\n1pow(const matrix<Block, Allocator> &M, std::size_t n);\n\ntemplate<std::unsigned_integral Block, typename Allocator>\nconstexpr matrix<Block, Allocator>\n2pow2(const matrix<Block, Allocator> &M, std::size_t n);\n\n1\n\nReturns \\(M^n\\).\n\n2\n\nReturns \\(M^{2^n}\\).\n\n\nFor example, we can raise \\(M\\) to the power \\(2^{128}\\), which is not representable as a typical std::size_t.\nWe use repeated squaring to compute the powers efficiently. It is also worth noting that all arithmetic in \\(\\FF\\) is mod 2, so there are no overflow issues even for large \\(n\\).\n\n\n\n\n\n\nThe bit-matrix argument must be square\n\n\n\nThe input matrix must be square, and the bit_always_assert macro checks that pre-condition.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n auto M = bit::matrix<>::random(4);\n std::cout << \"M:\\n\" << M << '\\n';\n1 std::cout << \"M^2:\\n\" << pow(M,2) << '\\n';\n2 std::cout << \"M^{256}:\\n\" << pow(M,256) << '\\n';\n3 std::cout << \"M^{2^8}:\\n\" << pow2(M,8) << '\\n';\n4 std::cout << \"M^{2^{100}}:\\n\" << pow2(M,100) << '\\n';\n}\n\n1\n\nSimple square of a small random bit-matrix.\n\n2\n\nRaise to the power \\(256\\) using pow.\n\n3\n\nRaise to the power \\(2^8 = 256\\) using pow2.\n\n4\n\nRaise to the power \\(2^{100} = 1,267,650,600,228,229,401,496,703,205,376\\).\n\n\nOutput\nM:\n│1 0 1 1│\n│1 1 0 1│\n│0 0 0 1│\n│1 1 1 1│\nM^2:\n│0 1 0 1│\n│1 0 0 1│\n│1 1 1 1│\n│1 0 0 0│\nM^{256}:\n│0 0 0 1│\n│1 1 0 1│\n│1 0 1 1│\n│0 1 0 1│\nM^{2^8}:\n│0 0 0 1│\n│1 1 0 1│\n│1 0 1 1│\n│0 1 0 1│\nM^{2^{100}}:\n│0 0 0 1│\n│1 1 0 1│\n│1 0 1 1│\n│0 1 0 1│\n\nSee Also\npolynomial::operator()\n\n\n\n\n Back to top"
},
{
"objectID": "content/matrix/invert.html",
"href": "content/matrix/invert.html",
"title": "bit::matrix — Bit-Matrix Inversion",
"section": "",
- "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have a non-member function that attempts to invert a square bit-matrix.\ntemplate<std::unsigned_integral Block, typename Allocator>\nstd::optional<matrix<Block, Allocator>>\nbit::invert(const matrix<Block, Allocator> &M);\nIf this method succeeds, it will return \\(M^{-1}\\) wrapped in a std::optional. If the input matrix \\(M\\) is singular, it will return std::nullopt instead.\n\n\n\n\n\n\nBit-matrices are often singular\n\n\n\nRandomly filled matrices over \\(\\FF\\) are likely to be singular. In fact, for matrices that are \\(10 \\times 10\\) or larger, there is a 71% chance the matrix is singular if the elements were set by flipping fair coins. Contrast that to matrices over the reals where, mathematically at least, matrices are almost surely invertible (though the numerics of the situation may not be so sure).\n\n\n\n\n\n\n\n\nThe bit-matrix argument must be square\n\n\n\nThe input matrix must be square, and the bit_assert macro checks that pre-condition. Setting the BIT_NDEBUG flag at compile time turns off that check.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n1 auto A = bit::matrix<>::rotate(8);\n auto B = bit::invert(A);\n if(B) {\n std::cout << \"bit::matrix, its inverse, their product:\\n\";\n bit::print(A,*B, bit::dot(A,*B));\n }\n else {\n std::cout << \"bit::matrix:\\n\" << A << \"\\n\" << \"Is singular!\\n\";\n }\n}\n\n1\n\nThe product of A and any 8-element bit-vector will rotate the elements in the vector one place to the left — see matrix::rotate. Obviously, A is invertible, so B exists and acts on bit-vectors by rotating their elements one place to the right.\n\n\nOutput\nbit::matrix, its inverse, their product:\n00000001 01000000 10000000\n10000000 00100000 01000000\n01000000 00010000 00100000\n00100000 00001000 00010000\n00010000 00000100 00001000\n00001000 00000010 00000100\n00000100 00000001 00000010\n00000010 10000000 00000001\n\nSee Also\nmatrix::probability_invertible\nmatrix::probability_singular\n\n\n\n\n Back to top"
+ "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have a non-member function that attempts to invert a square bit-matrix.\ntemplate<std::unsigned_integral Block, typename Allocator>\nstd::optional<matrix<Block, Allocator>>\nbit::invert(const matrix<Block, Allocator> &M);\nIf this method succeeds, it will return \\(M^{-1}\\) wrapped in a std::optional. If the input matrix \\(M\\) is singular, it will return std::nullopt instead.\n\n\n\n\n\n\nBit-matrices are often singular\n\n\n\nRandomly filled matrices over \\(\\FF\\) are likely to be singular. In fact, for matrices that are \\(10 \\times 10\\) or larger, there is a 71% chance the matrix is singular if the elements were set by flipping fair coins. Contrast that to matrices over the reals where, mathematically at least, matrices are almost surely invertible (though the numerics of the situation may not be so sure).\n\n\n\n\n\n\n\n\nThe bit-matrix argument must be square\n\n\n\nThe input matrix must be square, and the bit_always_assert macro checks that pre-condition.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n1 auto A = bit::matrix<>::rotate(8);\n auto B = bit::invert(A);\n if(B) {\n std::cout << \"bit::matrix, its inverse, their product:\\n\";\n bit::print(A,*B, bit::dot(A,*B));\n }\n else {\n std::cout << \"bit::matrix:\\n\" << A << \"\\n\" << \"Is singular!\\n\";\n }\n}\n\n1\n\nThe product of A and any 8-element bit-vector will rotate the elements in the vector one place to the left — see matrix::rotate. Obviously, A is invertible, so B exists and acts on bit-vectors by rotating their elements one place to the right.\n\n\nOutput\nbit::matrix, its inverse, their product:\n00000001 01000000 10000000\n10000000 00100000 01000000\n01000000 00010000 00100000\n00100000 00001000 00010000\n00010000 00000100 00001000\n00001000 00000010 00000100\n00000100 00000001 00000010\n00000010 10000000 00000001\n\nSee Also\nmatrix::probability_invertible\nmatrix::probability_singular\n\n\n\n\n Back to top"
},
{
"objectID": "content/matrix/set_if.html",
@@ -286,7 +286,7 @@
"href": "content/polynomial/index.html#instance-methods",
"title": "The bit::polynomial Class",
"section": "Instance Methods",
- "text": "Instance Methods\n\nConstruction\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::constructors\nConstruct bit-polynomials in various ways.\n\n\npolynomial::power\nFactory method to generate the polynomial \\(p(x) = x^n\\).\n\n\npolynomial::random\nFactory method constructs a bit-polynomial with random coefficients.\n\n\n\n\n\n\nQueries\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::size\nHow many coefficients are there in this polynomial?\n\n\npolynomial::empty\nDoes this polynomial have no coefficients? This is treated as a form of the zero polynomial.\n\n\npolynomial::capacity\nHow many coefficients can the polynomial have without causing memory allocation.\n\n\npolynomial::zero\nIs this the zero polynomial \\(p(x) = 0\\)?\n\n\npolynomial::nonzero\nIs this polynomial nonzero?\n\n\npolynomial::one\nIs this polynomial \\(p(x) = 1\\)?\n\n\npolynomial::constant\nIs this a constant polynomial \\(p(x) = 0 \\text{ or } 1\\)?\n\n\npolynomial::degree\nReturns the degree of the polynomial.\n\n\npolynomial::monic\nIs this a monic polynomial (so no trailing zero coefficients).\n\n\npolynomial::count0\nHow many zero coefficients does this polynomial have?\n\n\npolynomial::count1\nHow many one coefficients does this polynomial have?\n\n\n\n\n\n\nModifiers\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::resize\nResizes the number of coefficients in the polynomial up or down. Any added coefficients are set to zero.\n\n\npolynomial::clear\nClears all the coefficients from the polynomial so that size() becomes 0.\n\n\npolynomial::make_monic\nEliminates any trailing zero coefficients to make the polynomial monic.\n\n\npolynomial::shrink_to_fit\nAttempts to free up any memory that is not used by the polynomial.\n\n\n\n\n\n\nCoefficient Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::operator[]\nAccess a particular polynomial coefficient naturally.\n\n\npolynomial::get\nRead-only access to a particular polynomial coefficient.\n\n\npolynomial::set\nWrite access to a particular polynomial coefficient or all of them at once.\n\n\npolynomial::reset\nWrite access to a particular polynomial coefficient or all of them at once.\n\n\npolynomial::coefficients\nRead-only access to the polynomial coefficients as a bit-vector.\n\n\npolynomial::set_coefficients\nWrite access to the polynomial coefficients as a bit-vector.\n\n\n\n\n\n\nPolynomial Evaluation\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::operator()\nEvaluate the polynomial for a scalar or bit-matrix argument.\n\n\n\n\n\n\nArithmetic\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::operator+=\nAdds another polynomial to this one.\n\n\npolynomial::operator-=\nSubtracts another polynomial from this one.\n\n\npolynomial::operator*=\nMultiplies this polynomial by another one.\n\n\npolynomial::times_x\nMultiplies this polynomial by a power of x.\n\n\npolynomial::squared\nReturns a new polynomial that is the square of this one.\n\n\n\n\n\n\nString Conversions\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::to_string\nReturns a string representation of the polynomial.\n\n\n\n\n\n\nOther Instance Methods\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::sub\nCreate a distinct sub-polynomial of this one.\n\n\npolynomial::split\nSplit polynomial \\(p(x)\\) into \\(p(x) = l(x) + x^n h(x)\\).\n\n\npolynomial::reduce\nReduces \\(x^e\\) by this polynomial (\\(e\\) can be very large).\n\n\n\n\n\n\nDebugging\nYou can set some compile-time flags that enable extra safety checks. You might set these flags in DEBUG builds where performance is not the critical concern.\n\n\n\n\n\n\n\n\nMacro\nDescription\n\n\n\n\nBIT_DEBUG\nThis compile-time flag enables extra safety checks.\n\n\nBIT_NDEBUG\nThis compile-time flag turns off most safety checks.\n\n\nbit_debug_assert\nThese assertions are only checked if you set the BIT_DEBUG flag at compile time.\n\n\nbit_assert\nThese assertions are checked unless you set the BIT_NDEBUG flag at compile time.\n\n\nbit_always_assert\nThese assertions are always checked.",
+ "text": "Instance Methods\n\nConstruction\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::constructors\nConstruct bit-polynomials in various ways.\n\n\npolynomial::power\nFactory method to generate the polynomial \\(p(x) = x^n\\).\n\n\npolynomial::random\nFactory method constructs a bit-polynomial with random coefficients.\n\n\n\n\n\n\nQueries\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::size\nHow many coefficients are there in this polynomial?\n\n\npolynomial::empty\nDoes this polynomial have no coefficients? This is treated as a form of the zero polynomial.\n\n\npolynomial::capacity\nHow many coefficients can the polynomial have without causing memory allocation.\n\n\npolynomial::zero\nIs this the zero polynomial \\(p(x) = 0\\)?\n\n\npolynomial::nonzero\nIs this polynomial nonzero?\n\n\npolynomial::one\nIs this polynomial \\(p(x) = 1\\)?\n\n\npolynomial::constant\nIs this a constant polynomial \\(p(x) = 0 \\text{ or } 1\\)?\n\n\npolynomial::degree\nReturns the degree of the polynomial.\n\n\npolynomial::monic\nIs this a monic polynomial (so no trailing zero coefficients).\n\n\npolynomial::count0\nHow many zero coefficients does this polynomial have?\n\n\npolynomial::count1\nHow many one coefficients does this polynomial have?\n\n\n\n\n\n\nModifiers\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::resize\nResizes the number of coefficients in the polynomial up or down. Any added coefficients are set to zero.\n\n\npolynomial::clear\nClears all the coefficients from the polynomial so that size() becomes 0.\n\n\npolynomial::make_monic\nEliminates any trailing zero coefficients to make the polynomial monic.\n\n\npolynomial::shrink_to_fit\nAttempts to free up any memory that is not used by the polynomial.\n\n\n\n\n\n\nCoefficient Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::operator[]\nAccess a particular polynomial coefficient naturally.\n\n\npolynomial::get\nRead-only access to a particular polynomial coefficient.\n\n\npolynomial::set\nWrite access to a particular polynomial coefficient or all of them at once.\n\n\npolynomial::reset\nWrite access to a particular polynomial coefficient or all of them at once.\n\n\npolynomial::coefficients\nRead-only access to the polynomial coefficients as a bit-vector.\n\n\npolynomial::set_coefficients\nWrite access to the polynomial coefficients as a bit-vector.\n\n\n\n\n\n\nPolynomial Evaluation\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::operator()\nEvaluate the polynomial for a scalar or bit-matrix argument.\n\n\n\n\n\n\nArithmetic\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::operator+=\nAdds another polynomial to this one.\n\n\npolynomial::operator-=\nSubtracts another polynomial from this one.\n\n\npolynomial::operator*=\nMultiplies this polynomial by another one.\n\n\npolynomial::times_x\nMultiplies this polynomial by a power of x.\n\n\npolynomial::squared\nReturns a new polynomial that is the square of this one.\n\n\n\n\n\n\nString Conversions\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::to_string\nReturns a string representation of the polynomial.\n\n\n\n\n\n\nOther Instance Methods\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\npolynomial::sub\nCreate a distinct sub-polynomial of this one.\n\n\npolynomial::split\nSplit polynomial \\(p(x)\\) into \\(p(x) = l(x) + x^n h(x)\\).\n\n\npolynomial::reduce\nReduces \\(x^e\\) by this polynomial (\\(e\\) can be very large).\n\n\n\n\n\n\nDebugging\nYou can set a compile-time flag to enable extra safety checks. These checks can have a severe performance penalty so typically are only turned on for development.\n\n\n\n\n\n\n\n\nMacro\nDescription\n\n\n\n\nBIT_DEBUG\nThis compile-time flag enables extra safety checks.\n\n\nbit_debug_assert\nThese assertions are only checked if you set the BIT_DEBUG flag at compile time.\n\n\nbit_always_assert\nThese assertions are always checked.",
"crumbs": [
"Home",
"Bit-Polynomials",
@@ -464,7 +464,7 @@
"href": "content/vector/access.html",
"title": "bit::vector — Element Access",
"section": "",
- "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\n1constexpr bool element(std::size_t i) const;\n2constexpr reference element(std::size_t i);\n\n3constexpr bool operator[](std::size_t i) const;\nconstexpr reference operator[](std::size_t i);\n\n4constexpr bool operator()(std::size_t i) const;\nconstexpr reference operator()(std::size_t i);\n\n5constexpr bool test(std::size_t i) const;\n\n6constexpr bool front() const;\nconstexpr reference front()\n\n7constexpr bool back() const;\nconstexpr reference back()\n\n1\n\nAccesses the value for bit-vector element i.\n\n2\n\nReturns a vector::reference object — allows modification of the value at index i.\n\n3\n\nThe operator[] methods are synonyms for the element methods.\n\n4\n\nThe operator() methods are also synonyms for the element methods.\n\n5\n\nAnother way to access the value for element i.\n\n6\n\nAccess the element at index 0.\n\n7\n\nAccess the element at index size() - 1.\n\n\n\n\n\n\n\n\nBounds checking\n\n\n\nGenerally, these methods do not check whether the index i is in bounds. The behavior is undefined if it is out of bounds, but it will surely not be good! Set the BIT_DEBUG flag at compile time to check this condition — any violation will cause the program to abort with a helpful message.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n std::size_t n = 11;\n bit::vector<> v(n);\n std::cout << \"Setting successive bits:\\n\";\n std::cout << v << '\\n';\n for (std::size_t i = 0; i < n; ++i) {\n v[i] = true;\n std::cout << v << '\\n';\n }\n std::cout << \"Resetting the front and back elements of v ...\\n\";\n v.front() = 0;\n v.back() = 0;\n std::cout << v << '\\n';\n std::cout << \"v.front(): \" << v.front() << '\\n';\n std::cout << \"v.back(): \" << v.back() << '\\n';\n}\nOutput\nSetting successive bits:\n[0 0 0 0 0 0 0 0 0 0 0]\n[1 0 0 0 0 0 0 0 0 0 0]\n[1 1 0 0 0 0 0 0 0 0 0]\n[1 1 1 0 0 0 0 0 0 0 0]\n[1 1 1 1 0 0 0 0 0 0 0]\n[1 1 1 1 1 0 0 0 0 0 0]\n[1 1 1 1 1 1 0 0 0 0 0]\n[1 1 1 1 1 1 1 0 0 0 0]\n[1 1 1 1 1 1 1 1 0 0 0]\n[1 1 1 1 1 1 1 1 1 0 0]\n[1 1 1 1 1 1 1 1 1 1 0]\n[1 1 1 1 1 1 1 1 1 1 1]\nResetting the front and back elements of v ...\n[0 1 1 1 1 1 1 1 1 1 0]\nv.front(): 0\nv.back(): 0\n\nSee Also\nvector::reference\nvector::size\nbit_assert\n\n\n\n\n Back to top"
+ "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\n1constexpr bool element(std::size_t i) const;\n2constexpr reference element(std::size_t i);\n\n3constexpr bool operator[](std::size_t i) const;\nconstexpr reference operator[](std::size_t i);\n\n4constexpr bool operator()(std::size_t i) const;\nconstexpr reference operator()(std::size_t i);\n\n5constexpr bool test(std::size_t i) const;\n\n6constexpr bool front() const;\nconstexpr reference front()\n\n7constexpr bool back() const;\nconstexpr reference back()\n\n1\n\nAccesses the value for bit-vector element i.\n\n2\n\nReturns a vector::reference object — allows modification of the value at index i.\n\n3\n\nThe operator[] methods are synonyms for the element methods.\n\n4\n\nThe operator() methods are also synonyms for the element methods.\n\n5\n\nAnother way to access the value for element i.\n\n6\n\nAccess the element at index 0.\n\n7\n\nAccess the element at index size() - 1.\n\n\n\n\n\n\n\n\nBounds checking\n\n\n\nGenerally, these methods do not check whether the index i is in bounds. The behavior is undefined if it is out of bounds, but it will surely not be good! Set the BIT_DEBUG flag at compile time to check this condition — any violation will cause the program to abort with a helpful message.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n std::size_t n = 11;\n bit::vector<> v(n);\n std::cout << \"Setting successive bits:\\n\";\n std::cout << v << '\\n';\n for (std::size_t i = 0; i < n; ++i) {\n v[i] = true;\n std::cout << v << '\\n';\n }\n std::cout << \"Resetting the front and back elements of v ...\\n\";\n v.front() = 0;\n v.back() = 0;\n std::cout << v << '\\n';\n std::cout << \"v.front(): \" << v.front() << '\\n';\n std::cout << \"v.back(): \" << v.back() << '\\n';\n}\nOutput\nSetting successive bits:\n[0 0 0 0 0 0 0 0 0 0 0]\n[1 0 0 0 0 0 0 0 0 0 0]\n[1 1 0 0 0 0 0 0 0 0 0]\n[1 1 1 0 0 0 0 0 0 0 0]\n[1 1 1 1 0 0 0 0 0 0 0]\n[1 1 1 1 1 0 0 0 0 0 0]\n[1 1 1 1 1 1 0 0 0 0 0]\n[1 1 1 1 1 1 1 0 0 0 0]\n[1 1 1 1 1 1 1 1 0 0 0]\n[1 1 1 1 1 1 1 1 1 0 0]\n[1 1 1 1 1 1 1 1 1 1 0]\n[1 1 1 1 1 1 1 1 1 1 1]\nResetting the front and back elements of v ...\n[0 1 1 1 1 1 1 1 1 1 0]\nv.front(): 0\nv.back(): 0\n\nSee Also\nvector::reference\nvector::size\n[bit_assert]\n\n\n\n\n Back to top"
},
{
"objectID": "content/vector/join.html",
@@ -923,19 +923,7 @@
"href": "content/bit_assert/index.html#introduction",
"title": "Assertions",
"section": "Introduction",
- "text": "Introduction\nThe bit_assert.h header has three replacements for the standard assert macro — they all allow for an additional string output that you can use to print the values of the variables that triggered any failure.\n1bit_assert(condition, message)\n2bit_debug_assert(condition, message)\n3bit_always_assert(condition, message)\n\n1\n\nassertions of this type are verified unless you set the BIT_NDEBUG flag at compile time. This version is closest in spirit to the standard assert macro.\n\n2\n\nassertions of this type are only verified if you set the BIT_DEBUG flag at compile time.\n\n3\n\nassertions of this type are always verified and cannot be turned off with a compiler flag.\n\n\nAssuming the asserts are “on,” in all cases, if condition evaluates to false, we print an error message to std::cerr, and the program will exit.\nThe error message always includes the location of the failure and an extra dynamic payload typically used to print the values of the variables that triggered the failure. The payload can be anything that can be formatted using the facilities in std::format.\nThese look like functions but are macros, and the level of assertion checking performed is controlled by setting compiler flags at build time:",
- "crumbs": [
- "Home",
- "Debugging",
- "Assertions"
- ]
- },
- {
- "objectID": "content/bit_assert/index.html#compiler-flags",
- "href": "content/bit_assert/index.html#compiler-flags",
- "title": "Assertions",
- "section": "Compiler Flags",
- "text": "Compiler Flags\n\n\n\n\n\n\n\n\nMacro\nDescription\n\n\n\n\nBIT_DEBUG\nIf set, we will perform demanding but potentially useful safety assertions on indices, size equality checks, etc.\n\n\nBIT_NDEBUG\nIf set, we turn off even relatively innocuous safety assertions for maximum performance.\n\n\n\n\n\n\n\n\n\n\nConsistency is enforced\n\n\n\nIf you set the BIT_NDEBUG flag, the library will ensure that BIT_DEBUG is not set.\n\n\n\n\n\n\n\n\nMicrosoft compiler\n\n\n\nMicrosoft’s old traditional preprocessor is not happy with these macros, but their newer cross-platform compatible one is fine. Add the /Zc:preprocessor flag to use that upgrade at compile time. Our CMake module compiler_init does that automatically for you.",
+ "text": "Introduction\nThe bit_assert.h header has two replacements for the standard assert macro — they allow for an additional string output that you can use to print the values of the variables that triggered any failure.\n1bit_debug_assert(condition, message)\n2bit_always_assert(condition, message)\n\n1\n\nAssertions of this type are only verified if you set the BIT_DEBUG flag at compile time.\n\n2\n\nAssertions of this type are always verified and cannot be turned off with a compiler flag.\n\n\nAssuming an assertion is “on,” in all cases, if condition evaluates to false, we print an error message to std::cerr, and the program will exit.\nThe error message always includes the location of the failure and an extra dynamic payload typically used to print the values of the variables that triggered the failure. The payload can be anything that can be formatted using the facilities in std::format.\n\n\n\n\n\n\nCompiler Flag\n\n\n\nIf you set the BIT_DEBUG flag, the library will perform demanding but potentially useful safety assertions on indices, size equality checks, etc. Otherwise all the bit_debug_assert calls are no-ops.\n\n\n\n\n\n\n\n\nMicrosoft compiler\n\n\n\nMicrosoft’s old traditional preprocessor is not happy with these macros, but their newer cross-platform compatible one is fine. Add the /Zc:preprocessor flag to use that upgrade at compile time. Our CMake module compiler_init does that automatically for you.",
"crumbs": [
"Home",
"Debugging",
@@ -947,7 +935,7 @@
"href": "content/bit_assert/index.html#examples",
"title": "Assertions",
"section": "Examples",
- "text": "Examples\nExample — Snippet from the bit::vector<>::set method\n/// @brief Set the element at index `i` to 1.\nconstexpr bit::vector &set(std::size_t i)\n{\n bit_debug_assert(i < m_size, \"index `i` = \" << i << \" must be < `m_size` which is \" << m_size);\n ...\n}\nHere m_size is holds the size of the vector—so we must have i < m_size\nTo check every element access, set the BIT_DEBUG flag during compiles. If the assertion fails, the program exits with an error message that gives the offending values.\nThe bit_debug_assert line expands to nothing if the BIT_DEBUG flag is not set during compiles.\nExample—Message from an assertion failure\n#include <bit/bit.h>\nint main()\n{\n1 std::size_t n = 12;\n bit::vector<> v(n);\n2 v.set(n);\n std::cout << v << \"\\n\";\n}\n\n1\n\nConstruct a vector of size 12 and then attempt to set the “last” element.\n\n2\n\nA deliberate but typical off-by-one index error as the valid indices are from 0 to n-1, which is 11.\n\n\nCompile the sample program with the BIT_DEBUG flag set and get:\nOutput\nBIT ASSERTION FAILURE:\nFunction 'set' (vector.h, line 893):\nStatement 'i < m_size' is NOT true: Index i = 12 must be < `m_size` = 12\nThe program will then exit.",
+ "text": "Examples\nExample — Snippet from the bit::vector<>::set method\n/// @brief Set the element at index `i` to 1.\nconstexpr bit::vector &set(std::size_t i)\n{\n bit_debug_assert(i < m_size, \"index `i` = \" << i << \" must be < `m_size` which is \" << m_size);\n ...\n}\nHere m_size is holds the size of the vector — so we must have i < m_size\nTo check every element access, set the BIT_DEBUG flag during compiles. If the assertion fails, the program exits with an error message that gives the offending values.\nThe bit_debug_assert line expands to nothing if the BIT_DEBUG flag is not set during compiles.\nExample — Message from an assertion failure\n#include <bit/bit.h>\nint main()\n{\n1 std::size_t n = 12;\n bit::vector<> v(n);\n2 v.set(n);\n std::cout << v << \"\\n\";\n}\n\n1\n\nConstruct a vector of size 12 and then attempt to set the “last” element.\n\n2\n\nA deliberate but typical off-by-one index error as the valid indices are from 0 to n-1, which is 11.\n\n\nCompile the sample program with the BIT_DEBUG flag set and get:\nOutput\nBIT ASSERTION FAILURE:\nFunction 'set' (vector.h, line 910):\nStatement 'i < m_size' is NOT true: Index i = 12 must be < `m_size` = 12\nThe program will then exit.",
"crumbs": [
"Home",
"Debugging",
@@ -959,7 +947,7 @@
"href": "content/bit_assert/index.html#design-rationale",
"title": "Assertions",
"section": "Design Rationale",
- "text": "Design Rationale\n\nbit_debug_assert\nIn the development cycle, it can be helpful to range-check indices and so on. However, those checks are expensive and can slow down numerical code by orders of magnitude. Therefore, we don’t want there to be any chance that those verifications are accidentally left “on” in the production code. The bit_debug_assert(...) form covers this type of verification. Turning on these checks requires the programmer to take a specific action — namely, she must set the BIT_DEBUG flag during compile time.\nFor example, here is a pre-condition from a hypothetical dot(Vector u, Vector v) function:\nbit_debug_assert(u.size() == v.size(), \"Vector sizes {} and {} DO NOT match!\", u.size(), v.size());\nThis code checks that the two vector arguments have equal length — a necessary constraint for the dot product operation to make sense. If the requirement is not satisfied, the code will exit with an informative message that includes the size of the two vectors.\nThe check here is off by default, and you need to do something special (i.e., define the BIT_DEBUG flag at compile time) to enable it. The idea is that production code may do many of these dot products, and we do not generally want to pay for the check. However, enabling these sorts of checks may be very useful during development.\nThe bit_debug_assert(...) macro expands to nothing unless you set the BIT_DEBUG flag at compile time.\n\n\nbit_assert\nOn the other hand, some checks are pretty cheap, especially when you compare the cost to the actual work done by the function. The bit_assert(...) form is helpful for those cheaper verifications.\nFor example, a pre-condition for a matrix inversion method is that the input matrix must be square. Here is how you might do that check in an invert(const Matrix& M) function:\nbit_assert(M.is_square(), \"Cannot invert a {} x {} NON-square matrix!\", M.rows(), M.cols());\nWe can only invert square matrices. The M.is_square() call checks that condition and, on failure, throws an exception with a helpful message.\nThis particular check is always on by default, and the programmer needs to do something special (i.e., define the BIT_NDEBUG flag at compile time) to deactivate it.\nThe bit_assert(...) macro expands to nothing only if you set the BIT_NDEBUG flag at compile time — the behavior is the same as the standard assert macro but allows for adding a formatted error message.\n\n\nbit_always_assert\nThere may be checks you never want to be turned off. The final form bit_always_assert(...) accomplishes those tasks — it is unaffected by compiler flags.\nFor instance, in that last example, the check cost is very slight compared to the work done by the invert(...) method, so leaving it on even in production code is probably not a problem. You might well want to use the bit_always_assert(...) version so the check never gets disabled:\nbit_always_assert(M.is_square(), \"Cannot invert a {} x {} NON-square matrix!\", M.rows(), M.cols());\nThe decision to use one of these forms vs. another depends on the cost of doing the check versus the work done by the method in question. A primary use case for bit_debug_assert is to do things like bounds checking on indices — from experience, this is vital during development. However, bounds-checking every index operation incurs a considerable performance penalty and can slow down numerical code by orders of magnitude. So it makes sense to have the checks in place for development but to ensure they are never there in release builds.\nIn the development cycle, asserting range indices and so on is helpful. However, those assertions are expensive and can slow down numerical code by orders of magnitude. Therefore, we don’t want there to be any chance that those verifications are accidentally left “on” in our production code. The first form, bit_debug_assert(...), covers these asserts. Turning on bit_debug_assert asserts requires the programmer to take a specific action, namely, setting the BIT_DEBUG flag during compile time.\nOn the other hand, some assertions are relatively cheap, especially compared to the work done by the containing function. For example, a pre-condition for the matrix::invert method is that the input bit-matrix is square. There is probably no harm if we always do that assert, which is very cheap compared to the typical cost of inverting a bit-matrix. The second form, bit_assert(...), is suitable for those cheaper verifications. Turning off even those assertions is possible, but the programmer must take a specific action. She must set the BIT_NDEBUG flag during compile time.\nFinally, you may wish that some assertions are always checked. The final form above accomplishes those tasks.\n\n\n\n\n\n\nMacro-land\n\n\n\nWe are in macro land here, so there are no namespaces. Typically, macros have names in caps, but the standard assert does not follow that custom, so neither do these bit_assert macros.\n\n\n\n\nSee Also\nassert",
+ "text": "Design Rationale\n\nbit_debug_assert\nIn the development cycle, it can be helpful to range-check indices and so on. However, those checks are expensive and can slow down numerical code by orders of magnitude. Therefore, we don’t want there to be any chance that those verifications are accidentally left “on” in the production code. The bit_debug_assert(...) form covers this type of verification. Turning on these checks requires the programmer to take a specific action — namely, she must set the BIT_DEBUG flag during compile time.\nFor example, here is a pre-condition from a hypothetical dot(Vector u, Vector v) function:\nbit_debug_assert(u.size() == v.size(), \"Vector sizes {} and {} DO NOT match!\", u.size(), v.size());\nThis code checks that the two vector arguments have equal length — a necessary constraint for the dot product operation to make sense. If the requirement is not satisfied, the code will exit with an informative message that includes the size of the two vectors.\nThe check here is off by default, and you need to do something special (i.e., define the BIT_DEBUG flag at compile time) to enable it. The idea is that production code may do many of these dot products, and we do not generally want to pay for the check. However, enabling these sorts of checks may be very useful during development.\nThe bit_debug_assert(...) macro expands to nothing unless you set the BIT_DEBUG flag at compile time.\n\n\nbit_always_assert\nThere may be other checks you never want to be turned off. The bit_always_assert(...) form accomplishes those tasks — it is unaffected by compiler flags.\nFor example, a pre-condition for a matrix inversion method is that the input matrix must be square. Here is how we do that check in an invert(const Matrix& M) function:\nbit_always_assert(M.is_square(), \"Cannot invert a {} x {} NON-square matrix!\", M.rows(), M.cols());\nWe can only invert square matrices. The M.is_square() call checks that condition and, on failure, exits the program with a helpful message.\nHere the cost of the check is very slight compared to the work done by the invert(...) method, so leaving it on even in production code is not a problem.\nThe decision to use one form vs. the other depends on the cost of doing the check versus the work done by the method in question. A primary use case for bit_debug_assert is to do things like bounds checking on indices — from experience, this is vital during development. However, bounds-checking every index operation incurs a considerable performance penalty and can slow down numerical code by orders of magnitude. So it makes sense to have the checks in place for development but to ensure they are never there in release builds.\nThe first form, bit_debug_assert(...), covers these types of checks. Turning on bit_debug_assert asserts requires the programmer to take a specific action, namely, setting the BIT_DEBUG flag during compile time.\nOn the other hand, some assertions are relatively cheap, especially compared to the work done by the containing function. For example, a pre-condition for the matrix::invert method is that the input bit-matrix is square. There is probably no harm if we always do that assert, which is very cheap compared to the typical cost of inverting a bit-matrix. The second form, bit_always_assert(...), is suitable for those cheaper verifications.\n\n\n\n\n\n\nMacro-land\n\n\n\nWe are in macro land here, so there are no namespaces. Typically, macros have names in caps, but the standard assert does not follow that custom, so neither do these bit_assert macros.\n\n\n\n\nSee Also\nassert",
"crumbs": [
"Home",
"Debugging",
@@ -1082,7 +1070,7 @@
"href": "content/notes/design.html#assertions",
"title": "Library Design Notes",
"section": "Assertions",
- "text": "Assertions\nIn the development cycle, it can be helpful to confirm that indices are in bounds and perform other range checks. However, those checks are expensive and can slow down numerical code by orders of magnitude. We don’t want those verifications accidentally left “on” in our production code.\nFor this reason, we include our versions of the standard [std::assert] macro.\n\n\n\n\n\n\nAssertions have messages\n\n\n\nOur assertions come with the ability to print an explanation of what caused any failure.\n\n\nThe most commonly used form in the library is bit_debug_assert(...). This form expands to nothing unless the programmer sets the BIT_DEBUG flag at compile time. That is typically done automatically only for debug software builds and is never done for release/optimized builds.\nThere are a couple of other versions of our assert macros.\nThe bit_assert(...) macro is always on unless the programmer sets the BIT_NDEBUG flag at compile time. Typically, we employ this form if the assertion check is relatively cheap compared to the work done in the function call. For example, the bit-matrix inversion function uses this form of assertion to check that the input bit-matrix is square. That check cost is negligible compared to the typical cost of inverting a bit-matrix, but to extract every ounce of efficiency, you can set the BIT_NDEBUG flag during compile time.\nFinally, some checks must always be performed. The bit_always_assert(...) form handles those cases.",
+ "text": "Assertions\nIn the development cycle, it can be helpful to confirm that indices are in bounds and perform other range checks. However, those checks are expensive and can slow down numerical code by orders of magnitude. We don’t want those verifications accidentally left “on” in our production code.\nFor this reason, we include our versions of the standard [std::assert] macro.\n\n\n\n\n\n\nAssertions have messages\n\n\n\nOur assertions come with the ability to print an explanation of what caused any failure.\n\n\nThe most commonly used form in the library is bit_debug_assert(...). This form expands to nothing unless the programmer sets the BIT_DEBUG flag at compile time. That is typically done automatically only for debug software builds and is never done for release/optimized builds.\nThere is also a version bit_always_assert(...) for checks that should always be carried out no matter what flags are passed to the compiler. Typically these are for assertions where the cost of the check is cheap compared to the cost of the work done in the method.",
"crumbs": [
"Home",
"Technical Notes",
@@ -1321,7 +1309,7 @@
"href": "content/vector/index.html#instance-methods",
"title": "The bit::vector Class",
"section": "Instance Methods",
- "text": "Instance Methods\n\nConstruction\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::constructors\nConstruct bit-vectors in various ways.\n\n\nvector::random\nFactory method constructs a bit-vector with a random fill.\n\n\nvector::zeros\nFactory method to construct bit-vectors with all the bits set to 0.\n\n\nvector::ones\nFactory method to construct bit-vectors with all the bits set to 1.\n\n\nvector::unit\nFactory method to construct a unit bit-vector.\n\n\nvector::checker_board\nFactory method to construct bit-vectors with bits in a checker-board pattern 1010101… or 0101010…\n\n\nvector::from\nFactory methods that construct bit-vectors from the bits in an integer or from strings.\n\n\n\n\n\n\nElement Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::element\nAccess an element in a bit-vector.\n\n\nvector::operator()\nAccess an element in a bit-vector.\n\n\nvector::operator[]\nAccess an element in a bit-vector.\n\n\nvector::test\nCheck the status of a particular element in a bit-vector.\n\n\nvector::front\nAccess the first element of a bit-vector.\n\n\nvector::back\nAccess the final element of a bit-vector.\n\n\nvector::all\nAre all the bits in the bit-vector set to 1?\n\n\nvector::any\nAre any bits in the bit-vector set to 1?\n\n\nvector::none\nAre none of the bits in the bit-vector set to 1?\n\n\nvector::count\nCount the set bits in a bit-vector.\n\n\nvector::count0\nCount the unset bits in a bit-vector.\n\n\nvector::count1\nCount the set bits in a bit-vector.\n\n\nvector::parity\nParity is the number of set bits mod 2.\n\n\nvector::sub\nExtracts a sub-vector as a distinct copy of some of elements in a bit-vector.\n\n\nvector::blocks\nAccess the underlying block store as a std::vector<Block>.\n\n\nvector::allocator\nRead-only access to the underlying Allocator for the block store.\n\n\n\n\n\n\nBlock Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::bits_per_block\nThe number of bit-vector elements that can fit in one storage block.\n\n\nvector::block_store_type\nWe store the underlying blocks in this type of container.\n\n\nvector::blocks_needed\nComputes the number of blocks needed to store a particular bit-vector.\n\n\nvector::allocator\nThe memory manager for the block store.\n\n\nvector::block_count\nThe number of blocks in the block store.\n\n\nvector::block\nAccess an individual block.\n\n\nvector::block_index_for\nReturns the index of the block holding a particular bit-vector element.\n\n\nvector::bit_index_for\nReturns the specific bit inside that block where that particular bit-vector element resides.\n\n\nvector::blocks\nAccess the underlying block store as a block_store_type\n\n\nvector::clean\nThis sets any extra/junk bits in the last occupied block to 0.\n\n\nvector::block_constructor\nConstruct a bit::vector by copying or moving a prefilled block_store_type of blocks.\n\n\n\n\n\n\nIteration\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::if_set_call\nCalls a function for each set index.\n\n\nvector::first_set\nReturns the index location of the first set bit.\n\n\nvector::next_set\nReturns the index location of the next set bit.\n\n\nvector::final_set\nReturns the index location of the final set bit.\n\n\nvector::prev_set\nReturns the index location of the previous set bit.\n\n\nvector::set_indices\nReturns the index locations of the set bits.\n\n\nvector::unset_indices\nReturns the index locations of the unset bits.\n\n\n\n\n\n\nCapacity\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::size\nReturns the number of elements in the bit-vector\n\n\nvector::empty\nQueries whether the bit-vector is empty.\n\n\nvector::capacity\nHow many bits can a bit-vector hold before it resizes?\n\n\nvector::unused\nHow many bits can be added before a bit-vector resizes?\n\n\nvector::reserve\nReserves storage for a bit-vector without changing its size().\n\n\nvector::shrink_to_fit\nTries to reduce memory usage by freeing unused memory.\n\n\n\n\n\n\nModifiers\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::clear\nClears all the elements from the bit-vector so its size() becomes 0.\n\n\nvector::push\nPushes an element onto the end of the bit-vector.\n\n\nvector::pop\nRemoves the last element from the bit-vector\n\n\nvector::append\nAdds elements/bits from various sources to the end of the bit-vector.\n\n\nvector::resize\nResizes the bit-vector, padding out any added values with zeros.\n\n\nvector::swap_elements\nSwaps the values of two elements in the bit-vector.\n\n\nvector::swap\nSwaps the contents of the bit-vector with another.\n\n\nvector::replace\nMethods to replace some sub-vectors of the bit-vector with other values.\n\n\nvector::set\nSet various ranges of elements in the bit-vector to 1.\n\n\nvector::reset\nSet various ranges of elements in the bit-vector to 0.\n\n\nvector::flip\nFlip various ranges of elements in the bit-vector from 0 to 1 and vice versa.\n\n\nvector::set_if\nSets elements in a bit-vector based on the return value from a function of the element index.\n\n\nvector::flip_if\nFlips values in a bit-vector based on the return value from a function of the element index.\n\n\nvector::operator&=\nElement-by-element logical AND in-place between this bit-vector and another of equal size.\n\n\nvector::operator^=\nElement-by-element logical XOR in-place between this bit-vector and another of equal size.\n\n\nvector::operator|=\nElement-by-element logical OR in-place between this bit-vector and another of equal size.\n\n\nvector::operator+=\nElement-by-element logical XOR in-place between this bit-vector and another of equal size.\n\n\nvector::operator-=\nElement-by-element logical XOR in-place between this bit-vector and another of equal size.\n\n\nvector::operator*=\nElement-by-element logical AND in-place between this bit-vector and another of equal size.\n\n\nvector::operator~\nFlips the values of all elements in this bit-vector.\n\n\nvector::operator<<=\nLeft shift the elements of this bit-vector in-place.\n\n\nvector::operator>>=\nRight shift the elements of this bit-vector in-place.\n\n\nvector::operator<<\nReturns a left-shifted copy of this bit-vector.\n\n\nvector::operator>>\nReturns a right-shifted copy of this bit-vector.\n\n\n\n\n\n\nString Conversions\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::to_string\nReturns a binary-string representation using configurable characters for set and unset elements. The elements are in vector order.\n\n\nvector::to_pretty_string\nReturns a formatted representation e.g. [1 1 0 1 0 1].\n\n\nvector::to_bit_order\nReturns a binary-string representation using configurable characters for set and unset elements. The least significant bit is on the right.\n\n\nvector::to_hex\nReturns a compact hex string representation of the bit-vector.\n\n\nvector::polynomial\nInterprets the elements of a bit-vector as the coefficients of a polynomial over \\(\\FF\\) and returns a string representation of that polynomial.\n\n\nvector::description\nWrites some descriptive data about the bit-vector to a stream.\n\n\n\n\n\n\nOther Instance Methods\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::trimmed_right\nReturns a copy of a bit-vector with any trailing zeros removed.\n\n\nvector::trimmed_left\nReturns a copy of a bit-vector with any leading zeros removed.\n\n\nvector::trimmed\nReturns a copy of a bit-vector with any leading or trailing zeros removed.\n\n\nvector::riffled\nReturns a copy of a bit-vector with any added interleaved zeros.\n\n\nvector::dot\nReturns the dot product of this bit-vector with another of equal size.\n\n\nvector::unit_floor\nReturns a unit bit-vector with its 1 at the location of our final set bit.\n\n\nvector::unit_ceil\nReturns a unit bit-vector with its 1 at the location one slot past our final set bit.\n\n\n\n\n\n\nDebugging\nYou can set some compile-time flags that enable range checking and so on. You might set these flags in DEBUG builds where performance is not the critical concern.\n\n\n\n\n\n\n\n\nMacro\nDescription\n\n\n\n\nBIT_DEBUG\nThis compile-time flag enables extra safety checks.\n\n\nBIT_NDEBUG\nThis compile-time flag turns off most safety checks.\n\n\nbit_debug_assert\nThese assertions are only checked if you set the BIT_DEBUG flag at compile time.\n\n\nbit_assert\nThese assertions are checked unless you set the BIT_NDEBUG flag at compile time.\n\n\nbit_always_assert\nThese assertions are always checked.",
+ "text": "Instance Methods\n\nConstruction\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::constructors\nConstruct bit-vectors in various ways.\n\n\nvector::random\nFactory method constructs a bit-vector with a random fill.\n\n\nvector::zeros\nFactory method to construct bit-vectors with all the bits set to 0.\n\n\nvector::ones\nFactory method to construct bit-vectors with all the bits set to 1.\n\n\nvector::unit\nFactory method to construct a unit bit-vector.\n\n\nvector::checker_board\nFactory method to construct bit-vectors with bits in a checker-board pattern 1010101… or 0101010…\n\n\nvector::from\nFactory methods that construct bit-vectors from the bits in an integer or from strings.\n\n\n\n\n\n\nElement Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::element\nAccess an element in a bit-vector.\n\n\nvector::operator()\nAccess an element in a bit-vector.\n\n\nvector::operator[]\nAccess an element in a bit-vector.\n\n\nvector::test\nCheck the status of a particular element in a bit-vector.\n\n\nvector::front\nAccess the first element of a bit-vector.\n\n\nvector::back\nAccess the final element of a bit-vector.\n\n\nvector::all\nAre all the bits in the bit-vector set to 1?\n\n\nvector::any\nAre any bits in the bit-vector set to 1?\n\n\nvector::none\nAre none of the bits in the bit-vector set to 1?\n\n\nvector::count\nCount the set bits in a bit-vector.\n\n\nvector::count0\nCount the unset bits in a bit-vector.\n\n\nvector::count1\nCount the set bits in a bit-vector.\n\n\nvector::parity\nParity is the number of set bits mod 2.\n\n\nvector::sub\nExtracts a sub-vector as a distinct copy of some of elements in a bit-vector.\n\n\nvector::blocks\nAccess the underlying block store as a std::vector<Block>.\n\n\nvector::allocator\nRead-only access to the underlying Allocator for the block store.\n\n\n\n\n\n\nBlock Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::bits_per_block\nThe number of bit-vector elements that can fit in one storage block.\n\n\nvector::block_store_type\nWe store the underlying blocks in this type of container.\n\n\nvector::blocks_needed\nComputes the number of blocks needed to store a particular bit-vector.\n\n\nvector::allocator\nThe memory manager for the block store.\n\n\nvector::block_count\nThe number of blocks in the block store.\n\n\nvector::block\nAccess an individual block.\n\n\nvector::block_index_for\nReturns the index of the block holding a particular bit-vector element.\n\n\nvector::bit_index_for\nReturns the specific bit inside that block where that particular bit-vector element resides.\n\n\nvector::blocks\nAccess the underlying block store as a block_store_type\n\n\nvector::clean\nThis sets any extra/junk bits in the last occupied block to 0.\n\n\nvector::block_constructor\nConstruct a bit::vector by copying or moving a prefilled block_store_type of blocks.\n\n\n\n\n\n\nIteration\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::if_set_call\nCalls a function for each set index.\n\n\nvector::first_set\nReturns the index location of the first set bit.\n\n\nvector::next_set\nReturns the index location of the next set bit.\n\n\nvector::final_set\nReturns the index location of the final set bit.\n\n\nvector::prev_set\nReturns the index location of the previous set bit.\n\n\nvector::set_indices\nReturns the index locations of the set bits.\n\n\nvector::unset_indices\nReturns the index locations of the unset bits.\n\n\n\n\n\n\nCapacity\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::size\nReturns the number of elements in the bit-vector\n\n\nvector::empty\nQueries whether the bit-vector is empty.\n\n\nvector::capacity\nHow many bits can a bit-vector hold before it resizes?\n\n\nvector::unused\nHow many bits can be added before a bit-vector resizes?\n\n\nvector::reserve\nReserves storage for a bit-vector without changing its size().\n\n\nvector::shrink_to_fit\nTries to reduce memory usage by freeing unused memory.\n\n\n\n\n\n\nModifiers\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::clear\nClears all the elements from the bit-vector so its size() becomes 0.\n\n\nvector::push\nPushes an element onto the end of the bit-vector.\n\n\nvector::pop\nRemoves the last element from the bit-vector\n\n\nvector::append\nAdds elements/bits from various sources to the end of the bit-vector.\n\n\nvector::resize\nResizes the bit-vector, padding out any added values with zeros.\n\n\nvector::swap_elements\nSwaps the values of two elements in the bit-vector.\n\n\nvector::swap\nSwaps the contents of the bit-vector with another.\n\n\nvector::replace\nMethods to replace some sub-vectors of the bit-vector with other values.\n\n\nvector::set\nSet various ranges of elements in the bit-vector to 1.\n\n\nvector::reset\nSet various ranges of elements in the bit-vector to 0.\n\n\nvector::flip\nFlip various ranges of elements in the bit-vector from 0 to 1 and vice versa.\n\n\nvector::set_if\nSets elements in a bit-vector based on the return value from a function of the element index.\n\n\nvector::flip_if\nFlips values in a bit-vector based on the return value from a function of the element index.\n\n\nvector::operator&=\nElement-by-element logical AND in-place between this bit-vector and another of equal size.\n\n\nvector::operator^=\nElement-by-element logical XOR in-place between this bit-vector and another of equal size.\n\n\nvector::operator|=\nElement-by-element logical OR in-place between this bit-vector and another of equal size.\n\n\nvector::operator+=\nElement-by-element logical XOR in-place between this bit-vector and another of equal size.\n\n\nvector::operator-=\nElement-by-element logical XOR in-place between this bit-vector and another of equal size.\n\n\nvector::operator*=\nElement-by-element logical AND in-place between this bit-vector and another of equal size.\n\n\nvector::operator~\nFlips the values of all elements in this bit-vector.\n\n\nvector::operator<<=\nLeft shift the elements of this bit-vector in-place.\n\n\nvector::operator>>=\nRight shift the elements of this bit-vector in-place.\n\n\nvector::operator<<\nReturns a left-shifted copy of this bit-vector.\n\n\nvector::operator>>\nReturns a right-shifted copy of this bit-vector.\n\n\n\n\n\n\nString Conversions\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::to_string\nReturns a binary-string representation using configurable characters for set and unset elements. The elements are in vector order.\n\n\nvector::to_pretty_string\nReturns a formatted representation e.g. [1 1 0 1 0 1].\n\n\nvector::to_bit_order\nReturns a binary-string representation using configurable characters for set and unset elements. The least significant bit is on the right.\n\n\nvector::to_hex\nReturns a compact hex string representation of the bit-vector.\n\n\nvector::polynomial\nInterprets the elements of a bit-vector as the coefficients of a polynomial over \\(\\FF\\) and returns a string representation of that polynomial.\n\n\nvector::description\nWrites some descriptive data about the bit-vector to a stream.\n\n\n\n\n\n\nOther Instance Methods\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nvector::trimmed_right\nReturns a copy of a bit-vector with any trailing zeros removed.\n\n\nvector::trimmed_left\nReturns a copy of a bit-vector with any leading zeros removed.\n\n\nvector::trimmed\nReturns a copy of a bit-vector with any leading or trailing zeros removed.\n\n\nvector::riffled\nReturns a copy of a bit-vector with any added interleaved zeros.\n\n\nvector::dot\nReturns the dot product of this bit-vector with another of equal size.\n\n\nvector::unit_floor\nReturns a unit bit-vector with its 1 at the location of our final set bit.\n\n\nvector::unit_ceil\nReturns a unit bit-vector with its 1 at the location one slot past our final set bit.\n\n\n\n\n\n\nDebugging\nYou can set a compile-time flag BIT_DEBUG to enable range checking and other assertions. These checks can have a substantial performance impact so typically are only used during development.\n\n\n\n\n\n\n\n\nMacro\nDescription\n\n\n\n\nBIT_DEBUG\nThis compile-time flag enables extra safety checks.\n\n\nbit_debug_assert\nThese assertions are only checked if you set the BIT_DEBUG flag at compile time.\n\n\nbit_always_assert\nThese assertions are always checked.",
"crumbs": [
"Home",
"Bit-Vectors",
@@ -1485,7 +1473,7 @@
"href": "content/polynomial/access.html",
"title": "bit::polynomial — Coefficient Access",
"section": "",
- "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have methods to access the coefficients of the polynomial either individually or as a whole.\n1constexpr bool operator[](std::size_t i) const;\n2constexpr reference operator[](std::size_t i);\n\n3constexpr bool get(std::size_t i) const;\n4constexpr polynomial& set(std::size_t i, bool val=true)\n5constexpr polynomial& reset(std::size_t i)\n\n6constexpr polynomial& set()\n7constexpr polynomial& reset()\n\n8constexpr const vector_type& coefficients() const;\n9constexpr polynomial& set_coefficients(vector_type& c);\n10constexpr polynomial& set_coefficients(vector_type&& c);\n\n1\n\nRead-only access to coefficient i.\n\n2\n\nReturns a polynomial::reference object — allows modification of coefficient i.\n\n3\n\nAnother way to get read-only access to coefficient i..\n\n4\n\nSet the value of coefficient i to val.\n\n5\n\nSet the value of coefficient i to false.\n\n6\n\nSets all the polynomial coefficients to 1.\n\n7\n\nSets all the polynomial coefficients to 0.\n\n8\n\nRead-only access to all the polynomial coefficients as a bit-vector.\n\n9\n\nSets the polynomial coefficients by copying the passed-in bit-vector.\n\n10\n\nSets the polynomial coefficients by moving the passed-in bit-vector into place.\n\n\n\n\n\n\n\n\nBounds checking\n\n\n\nGenerally, the methods do not check whether the index i is in bounds. The behavior is undefined if it is out of bounds, but it will surely not be good! Set the BIT_DEBUG flag at compile time to check this condition — any violation will cause the program to abort with a helpful message.\n\n\nThe vector_type is simply a bit::vector with the appropriate Block and Allocator template parameters.\nExample\n#include <bit/bit.h>\nint main()\n{\n bit::polynomial<> p{6};\n std::cout << std::format(\"p(x) = {} has coefficients {:p}\\n\", p, p.coefficients());\n\n p[0] = p[3] = 1;\n std::cout << std::format(\"p(x) = {} has coefficients {:p}\\n\", p, p.coefficients());\n\n p.reset(3);\n p.set(5);\n std::cout << std::format(\"p(x) = {} has coefficients {:p}\\n\\n\", p, p.coefficients());\n\n auto v = bit::vector<>::checker_board(10);\n std::cout << std::format(\"Before call v = {:p}\\n\", v);\n p.set_coefficients(v);\n std::cout << std::format(\"p.set_coefficients(v) gives p = {}.\\n\", p);\n std::cout << std::format(\"After call v = {:p}\\n\\n\", v);\n\n std::cout << std::format(\"Before call v = {:p}\\n\", v);\n p.set_coefficients(std::move(v));\n std::cout << std::format(\"p.set_coefficients(std::move(v)) gives p = {}.\\n\", p);\n std::cout << std::format(\"After call v = {:p}\\n\", v);\n}\nOutput\np(x) = 0 has coefficients [0 0 0 0 0 0]\np(x) = 1 + x^3 has coefficients [1 0 0 1 0 0]\np(x) = 1 + x^5 has coefficients [1 0 0 0 0 1]\n\nBefore call v = [1 0 1 0 1 0 1 0 1 0]\np.set_coefficients(v) gives p = 1 + x^2 + x^4 + x^6 + x^8.\nAfter call v = [1 0 1 0 1 0 1 0 1 0]\n\nBefore call v = [1 0 1 0 1 0 1 0 1 0]\np.set_coefficients(std::move(v)) gives p = 1 + x^2 + x^4 + x^6 + x^8.\nAfter call v = []\n\nSee Also\npolynomial::reference\npolynomial::size\nbit_assert\n\n\n\n\n Back to top"
+ "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have methods to access the coefficients of the polynomial either individually or as a whole.\n1constexpr bool operator[](std::size_t i) const;\n2constexpr reference operator[](std::size_t i);\n\n3constexpr bool get(std::size_t i) const;\n4constexpr polynomial& set(std::size_t i, bool val=true)\n5constexpr polynomial& reset(std::size_t i)\n\n6constexpr polynomial& set()\n7constexpr polynomial& reset()\n\n8constexpr const vector_type& coefficients() const;\n9constexpr polynomial& set_coefficients(vector_type& c);\n10constexpr polynomial& set_coefficients(vector_type&& c);\n\n1\n\nRead-only access to coefficient i.\n\n2\n\nReturns a polynomial::reference object — allows modification of coefficient i.\n\n3\n\nAnother way to get read-only access to coefficient i..\n\n4\n\nSet the value of coefficient i to val.\n\n5\n\nSet the value of coefficient i to false.\n\n6\n\nSets all the polynomial coefficients to 1.\n\n7\n\nSets all the polynomial coefficients to 0.\n\n8\n\nRead-only access to all the polynomial coefficients as a bit-vector.\n\n9\n\nSets the polynomial coefficients by copying the passed-in bit-vector.\n\n10\n\nSets the polynomial coefficients by moving the passed-in bit-vector into place.\n\n\n\n\n\n\n\n\nBounds checking\n\n\n\nGenerally, the methods do not check whether the index i is in bounds. The behavior is undefined if it is out of bounds, but it will surely not be good! Set the BIT_DEBUG flag at compile time to check this condition — any violation will cause the program to abort with a helpful message.\n\n\nThe vector_type is simply a bit::vector with the appropriate Block and Allocator template parameters.\nExample\n#include <bit/bit.h>\nint main()\n{\n bit::polynomial<> p{6};\n std::cout << std::format(\"p(x) = {} has coefficients {:p}\\n\", p, p.coefficients());\n\n p[0] = p[3] = 1;\n std::cout << std::format(\"p(x) = {} has coefficients {:p}\\n\", p, p.coefficients());\n\n p.reset(3);\n p.set(5);\n std::cout << std::format(\"p(x) = {} has coefficients {:p}\\n\\n\", p, p.coefficients());\n\n auto v = bit::vector<>::checker_board(10);\n std::cout << std::format(\"Before call v = {:p}\\n\", v);\n p.set_coefficients(v);\n std::cout << std::format(\"p.set_coefficients(v) gives p = {}.\\n\", p);\n std::cout << std::format(\"After call v = {:p}\\n\\n\", v);\n\n std::cout << std::format(\"Before call v = {:p}\\n\", v);\n p.set_coefficients(std::move(v));\n std::cout << std::format(\"p.set_coefficients(std::move(v)) gives p = {}.\\n\", p);\n std::cout << std::format(\"After call v = {:p}\\n\", v);\n}\nOutput\np(x) = 0 has coefficients [0 0 0 0 0 0]\np(x) = 1 + x^3 has coefficients [1 0 0 1 0 0]\np(x) = 1 + x^5 has coefficients [1 0 0 0 0 1]\n\nBefore call v = [1 0 1 0 1 0 1 0 1 0]\np.set_coefficients(v) gives p = 1 + x^2 + x^4 + x^6 + x^8.\nAfter call v = [1 0 1 0 1 0 1 0 1 0]\n\nBefore call v = [1 0 1 0 1 0 1 0 1 0]\np.set_coefficients(std::move(v)) gives p = 1 + x^2 + x^4 + x^6 + x^8.\nAfter call v = []\n\nSee Also\npolynomial::reference\npolynomial::size\n[bit_assert]\n\n\n\n\n Back to top"
},
{
"objectID": "content/polynomial/times_x.html",
@@ -1541,7 +1529,7 @@
"href": "content/polynomial/evaluation.html#matrix-arguments",
"title": "bit::polynomial — Polynomial Evaluation",
"section": "Matrix Arguments",
- "text": "Matrix Arguments\nIf M is a square bit-matrix then we can evaluate the sum: \\[\np(M) = p_0 I + p_1 M + p_2 M^2 + \\cdots + p_{n-1} M^{n-1}.\n\\] I is the identity matrix with identical dimensions to M. The sum uses Horner’s method.\n\n\n\n\n\n\nThe bit-matrix argument must be square\n\n\n\nThe input matrix must be square, and the bit_assert macro checks that pre-condition. Setting the BIT_NDEBUG flag at compile time turns off that check.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n auto M = bit::matrix<>::identity(6);\n std::cout << std::format(\"Bit-matrix M:\\n{}\\n\", M);\n\n bit::polynomial p{16, [](size_t k) { return (k + 1) % 2; }};\n std::cout << std::format(\"p(M): {:M}\\n{}\\n\", p, p(M));\n\n bit::polynomial q{17, [](size_t k) { return (k + 1) % 2; }};\n std::cout << std::format(\"q(M): {:M}\\n{}\\n\", q, q(M));\n}\nOutput\nBit-matrix M:\n100000\n010000\n001000\n000100\n000010\n000001\np(M): 1 + M^2 + M^4 + M^6 + M^8 + M^10 + M^12 + M^14\n000000\n000000\n000000\n000000\n000000\n000000\nq(M): 1 + M^2 + M^4 + M^6 + M^8 + M^10 + M^12 + M^14 + M^16\n100000\n010000\n001000\n000100\n000010\n000001\n\nSee Also\nmatrix::pow\nmatrix::pow2"
+ "text": "Matrix Arguments\nIf M is a square bit-matrix then we can evaluate the sum: \\[\np(M) = p_0 I + p_1 M + p_2 M^2 + \\cdots + p_{n-1} M^{n-1}.\n\\] I is the identity matrix with identical dimensions to M. The sum uses Horner’s method.\n\n\n\n\n\n\nThe bit-matrix argument must be square\n\n\n\nThe input matrix must be square, and the bit_always_assert macro checks that pre-condition.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n auto M = bit::matrix<>::identity(6);\n std::cout << std::format(\"Bit-matrix M:\\n{}\\n\", M);\n\n bit::polynomial p{16, [](size_t k) { return (k + 1) % 2; }};\n std::cout << std::format(\"p(M): {:M}\\n{}\\n\", p, p(M));\n\n bit::polynomial q{17, [](size_t k) { return (k + 1) % 2; }};\n std::cout << std::format(\"q(M): {:M}\\n{}\\n\", q, q(M));\n}\nOutput\nBit-matrix M:\n100000\n010000\n001000\n000100\n000010\n000001\np(M): 1 + M^2 + M^4 + M^6 + M^8 + M^10 + M^12 + M^14\n000000\n000000\n000000\n000000\n000000\n000000\nq(M): 1 + M^2 + M^4 + M^6 + M^8 + M^10 + M^12 + M^14 + M^16\n100000\n010000\n001000\n000100\n000010\n000001\n\nSee Also\nmatrix::pow\nmatrix::pow2"
},
{
"objectID": "content/polynomial/split.html",
@@ -1604,7 +1592,7 @@
"href": "content/matrix/access.html",
"title": "bit::matrix — Element Access",
"section": "",
- "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have methods to access the rows, the columns, and the individual elements/bits in a bit-matrix.\nconstexpr bool\n1operator()(std::size_t i, std::size_t j);\n\nconstexpr bool\n2test(std::size_t i, std::size_t j) const;\n\nconstexpr bit::vector::reference\n3operator()(std::size_t i, std::size_t j);\n\nconstexpr const bit::vector&\n4row(std::size_t i) const;\n\nconstexpr bit::vector&\nrow(std::size_t i);\n\nconstexpr const bit::vector&\n5operator[](std::size_t i) const;\n\nconstexpr bit::vector&\noperator[](std::size_t i);\n\nconstexpr bit::vector\n6col(std::size_t j) const;\n\n1\n\nAccesses the element at (i, j).\n\n2\n\nAnother way to access element (i, j).\n\n3\n\nReturns an object of type vector::reference that lets you write to slot (i, j).\n\n4\n\nRead-only & read-write access to the elements in row i of a bit-matrix.\n\n5\n\nSynonyms for the row(i) methods to allow for alternate C style indexing a la matrix[i][j].\n\n6\n\nRead-only access to the elements in column i of a bit-matrix.\n\n\n\n\n\n\n\n\nRange checks\n\n\n\nIn general, these methods do not check whether an index is in bounds, and if it isn’t, the behavior is undefined (but bound to be wrong!) Set the BIT_DEBUG flag at compile time to check this condition — any violation will cause the program to abort with a helpful message.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n std::size_t n = 4;\n auto mat = bit::matrix<>::random(n);\n std::cout << \"bit::matrix:\\n\";\n std::cout << mat << '\\n';\n std::cout << \"By rows ...\\n\";\n for (std::size_t i = 0; i < n; ++i)\n std::cout << \"Row \" << i << \": \" << mat[i] << '\\n';\n std::cout << \"By columns ...\\n\";\n for (std::size_t i = 0; i < n; ++i)\n std::cout << \"Col \" << i << \": \" << mat.col(i) << '\\n';\n}\nOutput\nbit::matrix:\n│0 1 1 0│\n│0 1 0 0│\n│0 1 1 0│\n│0 1 0 0│\nBy rows ...\nRow 0: [0 1 1 0]\nRow 1: [0 1 0 0]\nRow 2: [0 1 1 0]\nRow 3: [0 1 0 0]\nBy columns ...\nCol 0: [0 0 0 0]\nCol 1: [1 1 1 1]\nCol 2: [1 0 1 0]\n\nSee Also\nvector::reference\nbit_assert\n\n\n\n\n Back to top"
+ "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nWe have methods to access the rows, the columns, and the individual elements/bits in a bit-matrix.\nconstexpr bool\n1operator()(std::size_t i, std::size_t j);\n\nconstexpr bool\n2test(std::size_t i, std::size_t j) const;\n\nconstexpr bit::vector::reference\n3operator()(std::size_t i, std::size_t j);\n\nconstexpr const bit::vector&\n4row(std::size_t i) const;\n\nconstexpr bit::vector&\nrow(std::size_t i);\n\nconstexpr const bit::vector&\n5operator[](std::size_t i) const;\n\nconstexpr bit::vector&\noperator[](std::size_t i);\n\nconstexpr bit::vector\n6col(std::size_t j) const;\n\n1\n\nAccesses the element at (i, j).\n\n2\n\nAnother way to access element (i, j).\n\n3\n\nReturns an object of type vector::reference that lets you write to slot (i, j).\n\n4\n\nRead-only & read-write access to the elements in row i of a bit-matrix.\n\n5\n\nSynonyms for the row(i) methods to allow for alternate C style indexing a la matrix[i][j].\n\n6\n\nRead-only access to the elements in column i of a bit-matrix.\n\n\n\n\n\n\n\n\nRange checks\n\n\n\nIn general, these methods do not check whether an index is in bounds, and if it isn’t, the behavior is undefined (but bound to be wrong!) Set the BIT_DEBUG flag at compile time to check this condition — any violation will cause the program to abort with a helpful message.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n std::size_t n = 4;\n auto mat = bit::matrix<>::random(n);\n std::cout << \"bit::matrix:\\n\";\n std::cout << mat << '\\n';\n std::cout << \"By rows ...\\n\";\n for (std::size_t i = 0; i < n; ++i)\n std::cout << \"Row \" << i << \": \" << mat[i] << '\\n';\n std::cout << \"By columns ...\\n\";\n for (std::size_t i = 0; i < n; ++i)\n std::cout << \"Col \" << i << \": \" << mat.col(i) << '\\n';\n}\nOutput\nbit::matrix:\n│0 1 1 0│\n│0 1 0 0│\n│0 1 1 0│\n│0 1 0 0│\nBy rows ...\nRow 0: [0 1 1 0]\nRow 1: [0 1 0 0]\nRow 2: [0 1 1 0]\nRow 3: [0 1 0 0]\nBy columns ...\nCol 0: [0 0 0 0]\nCol 1: [1 1 1 1]\nCol 2: [1 0 1 0]\n\nSee Also\nvector::reference\n[bit_assert]\n\n\n\n\n Back to top"
},
{
"objectID": "content/matrix/dot.html",
@@ -1666,7 +1654,7 @@
"href": "content/matrix/index.html#instance-methods",
"title": "The bit::matrix Class",
"section": "Instance Methods",
- "text": "Instance Methods\n\nConstruction\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::constructors\nConstruct a bit-matrix in various ways.\n\n\nmatrix::random\nConstruct a bit-matrix with a random fill.\n\n\nmatrix::from\nConstruct a bit-matrix from a string.\n\n\nmatrix::ones\nCreate a bit-matrix with all the elements set to 1.\n\n\nmatrix::zeros\nCreate a bit-matrix with all the elements set to 0.\n\n\nmatrix::checker_board\nCreate a bit-matrix with the elements set to a checker-board pattern.\n\n\nmatrix::identity\nCreate an identity bit-matrix.\n\n\nmatrix::shift\nCreate a bit-matrix that shifts a bit-vector right or left.\n\n\nmatrix::rotate\nCreate a bit-matrix that rotates the elements of a bit-vector.\n\n\nmatrix::companion\nConstruct a companion matrix from its top-row only.\n\n\n\n\n\n\nQueries\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::is_zero\nIs this a zero bit-matrix?\n\n\nmatrix::is_ones\nIs this bit-matrix all ones?\n\n\nmatrix::is_identity\nIs this an identity bit-matrix?\n\n\nmatrix::is_square\nIs this bit-matrix square?\n\n\nmatrix::is_symmetric\nIs this bit-matrix symmetric?\n\n\n\n\n\n\nElement Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::operator()\nAccess a bit-matrix element, a whole row, or an entire column.\n\n\nmatrix::operator[]\nAccess a bit-matrix element, a whole row, or an entire column.\n\n\nmatrix::row\nRead-write access a bit-matrix row.\n\n\nmatrix::col\nRead only access a bit-matrix column.\n\n\nmatrix::test\nCheck the value of a bit-matrix element.\n\n\nmatrix::all\nCheck that all the bit-matrix elements are set.\n\n\nmatrix::any\nCheck if any bit-matrix elements are set.\n\n\nmatrix::all\nCheck that none of the bit-matrix elements are set.\n\n\nmatrix::count\nCounts the set elements in the bit-matrix.\n\n\nmatrix::count_diagonal\nCounts the set elements on the diagonal of the bit-matrix.\n\n\nmatrix::trace\nSum of the elements on the diagonal.\n\n\nmatrix::sub\nExtracts a bit-matrix as a distinct copy of some of the elements of this one. Note that views into a bit-matrix are not supported.\n\n\nmatrix::lower\nReturns a bit-matrix that is a copy of the lower triangular part of this bit-matrix.\n\n\nmatrix::upper\nReturns a bit-matrix that is a copy of the upper triangular part of this bit-matrix.\n\n\nmatrix::strictly_lower\nReturns a bit-matrix that is a copy of the strictly lower triangular part of this bit-matrix.\n\n\nmatrix::strictly_upper\nReturns a bit-matrix that is a copy of the strictly upper triangular part of this bit-matrix.\n\n\n\n\n\n\nCapacity\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::rows\nThe number of rows in this bit-matrix.\n\n\nmatrix::cols\nThe number of columns in this bit-matrix.\n\n\nmatrix::size\nThe number of elements in this bit-matrix.\n\n\nmatrix::empty\nCheck whether this matrix has no elements.\n\n\nmatrix::row_capacity\nHow many rows can be added to this bit-matrix without a fresh memory allocation?\n\n\nmatrix::col_capacity\nHow many columns can be added to this bit-matrix without a fresh memory allocation?\n\n\nmatrix::shrink_to_fit\nTries to reduce memory usage by freeing unused memory.\n\n\n\n\n\n\nModifiers\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::clear\nClears all the elements so rows(), cols(), and size() all become 0.\n\n\nmatrix::resize\nResizes the bit-matrix, padding out any added values with zeros.\n\n\nmatrix::add_row\nAdds a row to the end of the bit-matrix.\n\n\nmatrix::add_col\nAdds a column to the end of the bit-matrix.\n\n\nmatrix::pop_row\nRemoves the final row of the bit-matrix.\n\n\nmatrix::pop_col\nRemoves the final column of the bit-matrix.\n\n\nmatrix::append\nAugments the bit-matrix in-place by appending columns from a vector or another bit-matrix on the right.\n\n\nmatrix::swap_rows\nSwap two rows.\n\n\nmatrix::swap_cols\nSwap two columns.\n\n\nmatrix::transpose\nTranspose a square bit-matrix in-place.\n\n\nmatrix::replace\nReplace some of the contents of the bit-matrix with other values.\n\n\nmatrix::set\nSets all the elements to 1.\n\n\nmatrix::reset\nSets all the elements to 0.\n\n\nmatrix::flip\nFlips the 1 values to 0 and vice versa.\n\n\nmatrix::set_diagonal\nSets all the diagonal elements to 1.\n\n\nmatrix::reset_diagonal\nSets all the diagonal elements to 0.\n\n\nmatrix::set_if\nSets the values in a bit-matrix based on the return value from a function of each element index-pair.\n\n\nmatrix::flip_if\nFlips the values in a bit-matrix based on the return value from a function of each element index-pair.\n\n\nmatrix::operator&=\nIn-place element-by-element logical AND between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator^=\nIn-place element-by-element logical XOR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator|=\nIn-place element-by-element logical OR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator-=\nIn-place element-by-element logical DIFF between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator~\nFlip all the elements in this bit-matrix.\n\n\nmatrix::operator+=\nIn-place element-by-element logical XOR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator-=\nIn-place element-by-element logical XOR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator*=\nIn-place element-by-element logical AND between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator<<=\nIn-place left shift of the rows in this bit-matrix.\n\n\nmatrix::operator>>=\nIn-place right shift of the rows in this bit-matrix.\n\n\nmatrix::operator<<\nReturns a copy of this bit-matrix where the rows are all left shifted.\n\n\nmatrix::operator>>\nReturns a copy of this bit-matrix where the rows are all right shifted.\n\n\nmatrix::to_echelon_form\nChanges this bit-matrix in place to row-echelon form.\n\n\nmatrix::to_reduced_echelon_form\nChanges this bit-matrix in place to reduced row-echelon form.\n\n\n\n\n\n\nString Conversions\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::to_string\nReturns a binary string representation of this bit-matrix.\n\n\nmatrix::to_pretty_string\nReturns a formatted binary string representation of this bit-matrix.\n\n\nmatrix::to_hex\nReturns a hex string representation of this bit-matrix.\n\n\nmatrix::to_vector\nPacks this bit-matrix into a bit-vector.\n\n\nmatrix::description\nWrites some descriptive data about the bit-matrix to a stream.\n\n\n\n\n\n\nOther methods\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::probability_invertible\nReturns the probability that a “fair” square bit-matrix is invertible.\n\n\nmatrix::probability_singular\nReturns the probability that a “fair” square bit-matrix is singular.\n\n\n\n\n\n\nDebugging\n\n\n\n\n\n\n\n\nMacro\nDescription\n\n\n\n\nBIT_DEBUG\nThis compile-time flag enables extra safety checks.\n\n\nBIT_NDEBUG\nThis compile-time flag turns off most safety checks.\n\n\nbit_debug_assert\nThese assertions are only checked if the BIT_DEBUG flag is set at compile time.\n\n\nbit_assert\nThese assertions are checked unless the BIT_NDEBUG flag is set at compile time.\n\n\nbit_always_assert\nUse this form for checks that must always be performed.",
+ "text": "Instance Methods\n\nConstruction\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::constructors\nConstruct a bit-matrix in various ways.\n\n\nmatrix::random\nConstruct a bit-matrix with a random fill.\n\n\nmatrix::from\nConstruct a bit-matrix from a string.\n\n\nmatrix::ones\nCreate a bit-matrix with all the elements set to 1.\n\n\nmatrix::zeros\nCreate a bit-matrix with all the elements set to 0.\n\n\nmatrix::checker_board\nCreate a bit-matrix with the elements set to a checker-board pattern.\n\n\nmatrix::identity\nCreate an identity bit-matrix.\n\n\nmatrix::shift\nCreate a bit-matrix that shifts a bit-vector right or left.\n\n\nmatrix::rotate\nCreate a bit-matrix that rotates the elements of a bit-vector.\n\n\nmatrix::companion\nConstruct a companion matrix from its top-row only.\n\n\n\n\n\n\nQueries\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::is_zero\nIs this a zero bit-matrix?\n\n\nmatrix::is_ones\nIs this bit-matrix all ones?\n\n\nmatrix::is_identity\nIs this an identity bit-matrix?\n\n\nmatrix::is_square\nIs this bit-matrix square?\n\n\nmatrix::is_symmetric\nIs this bit-matrix symmetric?\n\n\n\n\n\n\nElement Access\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::operator()\nAccess a bit-matrix element, a whole row, or an entire column.\n\n\nmatrix::operator[]\nAccess a bit-matrix element, a whole row, or an entire column.\n\n\nmatrix::row\nRead-write access a bit-matrix row.\n\n\nmatrix::col\nRead only access a bit-matrix column.\n\n\nmatrix::test\nCheck the value of a bit-matrix element.\n\n\nmatrix::all\nCheck that all the bit-matrix elements are set.\n\n\nmatrix::any\nCheck if any bit-matrix elements are set.\n\n\nmatrix::all\nCheck that none of the bit-matrix elements are set.\n\n\nmatrix::count\nCounts the set elements in the bit-matrix.\n\n\nmatrix::count_diagonal\nCounts the set elements on the diagonal of the bit-matrix.\n\n\nmatrix::trace\nSum of the elements on the diagonal.\n\n\nmatrix::sub\nExtracts a bit-matrix as a distinct copy of some of the elements of this one. Note that views into a bit-matrix are not supported.\n\n\nmatrix::lower\nReturns a bit-matrix that is a copy of the lower triangular part of this bit-matrix.\n\n\nmatrix::upper\nReturns a bit-matrix that is a copy of the upper triangular part of this bit-matrix.\n\n\nmatrix::strictly_lower\nReturns a bit-matrix that is a copy of the strictly lower triangular part of this bit-matrix.\n\n\nmatrix::strictly_upper\nReturns a bit-matrix that is a copy of the strictly upper triangular part of this bit-matrix.\n\n\n\n\n\n\nCapacity\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::rows\nThe number of rows in this bit-matrix.\n\n\nmatrix::cols\nThe number of columns in this bit-matrix.\n\n\nmatrix::size\nThe number of elements in this bit-matrix.\n\n\nmatrix::empty\nCheck whether this matrix has no elements.\n\n\nmatrix::row_capacity\nHow many rows can be added to this bit-matrix without a fresh memory allocation?\n\n\nmatrix::col_capacity\nHow many columns can be added to this bit-matrix without a fresh memory allocation?\n\n\nmatrix::shrink_to_fit\nTries to reduce memory usage by freeing unused memory.\n\n\n\n\n\n\nModifiers\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::clear\nClears all the elements so rows(), cols(), and size() all become 0.\n\n\nmatrix::resize\nResizes the bit-matrix, padding out any added values with zeros.\n\n\nmatrix::add_row\nAdds a row to the end of the bit-matrix.\n\n\nmatrix::add_col\nAdds a column to the end of the bit-matrix.\n\n\nmatrix::pop_row\nRemoves the final row of the bit-matrix.\n\n\nmatrix::pop_col\nRemoves the final column of the bit-matrix.\n\n\nmatrix::append\nAugments the bit-matrix in-place by appending columns from a vector or another bit-matrix on the right.\n\n\nmatrix::swap_rows\nSwap two rows.\n\n\nmatrix::swap_cols\nSwap two columns.\n\n\nmatrix::transpose\nTranspose a square bit-matrix in-place.\n\n\nmatrix::replace\nReplace some of the contents of the bit-matrix with other values.\n\n\nmatrix::set\nSets all the elements to 1.\n\n\nmatrix::reset\nSets all the elements to 0.\n\n\nmatrix::flip\nFlips the 1 values to 0 and vice versa.\n\n\nmatrix::set_diagonal\nSets all the diagonal elements to 1.\n\n\nmatrix::reset_diagonal\nSets all the diagonal elements to 0.\n\n\nmatrix::set_if\nSets the values in a bit-matrix based on the return value from a function of each element index-pair.\n\n\nmatrix::flip_if\nFlips the values in a bit-matrix based on the return value from a function of each element index-pair.\n\n\nmatrix::operator&=\nIn-place element-by-element logical AND between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator^=\nIn-place element-by-element logical XOR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator|=\nIn-place element-by-element logical OR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator-=\nIn-place element-by-element logical DIFF between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator~\nFlip all the elements in this bit-matrix.\n\n\nmatrix::operator+=\nIn-place element-by-element logical XOR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator-=\nIn-place element-by-element logical XOR between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator*=\nIn-place element-by-element logical AND between this bit-matrix and another of equal dimensions.\n\n\nmatrix::operator<<=\nIn-place left shift of the rows in this bit-matrix.\n\n\nmatrix::operator>>=\nIn-place right shift of the rows in this bit-matrix.\n\n\nmatrix::operator<<\nReturns a copy of this bit-matrix where the rows are all left shifted.\n\n\nmatrix::operator>>\nReturns a copy of this bit-matrix where the rows are all right shifted.\n\n\nmatrix::to_echelon_form\nChanges this bit-matrix in place to row-echelon form.\n\n\nmatrix::to_reduced_echelon_form\nChanges this bit-matrix in place to reduced row-echelon form.\n\n\n\n\n\n\nString Conversions\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::to_string\nReturns a binary string representation of this bit-matrix.\n\n\nmatrix::to_pretty_string\nReturns a formatted binary string representation of this bit-matrix.\n\n\nmatrix::to_hex\nReturns a hex string representation of this bit-matrix.\n\n\nmatrix::to_vector\nPacks this bit-matrix into a bit-vector.\n\n\nmatrix::description\nWrites some descriptive data about the bit-matrix to a stream.\n\n\n\n\n\n\nOther methods\n\n\n\n\n\n\n\n\nMethod\nDescription\n\n\n\n\nmatrix::probability_invertible\nReturns the probability that a “fair” square bit-matrix is invertible.\n\n\nmatrix::probability_singular\nReturns the probability that a “fair” square bit-matrix is singular.\n\n\n\n\n\n\nDebugging\n\n\n\n\n\n\n\n\nMacro\nDescription\n\n\n\n\nBIT_DEBUG\nThis compile-time flag enables extra safety checks.\n\n\nbit_debug_assert\nThese assertions are only checked if the BIT_DEBUG flag is set at compile time.\n\n\nbit_always_assert\nUse this form for checks that must always be performed.",
"crumbs": [
"Home",
"Bit-Matrices",
@@ -1753,7 +1741,7 @@
"href": "content/matrix/swap.html",
"title": "bit::matrix — Swap Two Rows/Columns",
"section": "",
- "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nSwap any two rows or columns in a bit-matrix — a standard operation in some matrix transformation algorithms.\n1constexpr bit::matrix &swap_rows(std::size_t i0, std::size_t i1);\n2constexpr bit::matrix &swap_cols(std::size_t j0, std::size_t j1);\n\n1\n\nSwap rows i0 and i1.\n\n2\n\nSwap columns j0 and j1.\n\n\nThese methods return a reference to *this, so can be chained with other calls.\n\n\n\n\n\n\nBounds checking\n\n\n\nGenerally, these methods do not check whether the indices are in bounds. If they aren’t, the behavior is undefined (but bound to be wrong!) All of them will perform range checking if you set the BIT_DEBUG at compile time. See bit_assert.\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n1 bit::matrix<> m(4, 8, [](std::size_t i, std::size_t j) { return (i + j)%2; });\n std::cout << \"Original:\\n\" << m << '\\n';\n std::cout << \"Swapped first 2 rows:\\n\" << m.swap_rows(0,1) << '\\n';\n std::cout << \"And back:\\n\" << m.swap_rows(0,1) << '\\n';\n std::cout << \"Swapped first 2 cols:\\n\" << m.swap_cols(0,1) << '\\n';\n std::cout << \"And back:\\n\" << m.swap_cols(0,1) << '\\n';\n}\n\n1\n\nSet up a bit-matrix with a checkerboard pattern of zeros and ones.\n\n\nOutput\nOriginal:\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\nSwapped first 2 rows:\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\nAnd back:\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\nSwapped first 2 cols:\n│1 0 0 1 0 1 0 1│\n│0 1 1 0 1 0 1 0│\n│1 0 0 1 0 1 0 1│\n│0 1 1 0 1 0 1 0│\nAnd back:\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n\nSee Also\nmatrix::replace\n\n\n\n\n Back to top"
+ "text": "\\[\n\\newcommand{\\FF}{\\mathbb{F}_2}\n\\newcommand{\\R}{\\mathbb{R}}\n\\]\n\n\n\n\n\n\n\n\n\n\nSwap any two rows or columns in a bit-matrix — a standard operation in some matrix transformation algorithms.\n1constexpr bit::matrix &swap_rows(std::size_t i0, std::size_t i1);\n2constexpr bit::matrix &swap_cols(std::size_t j0, std::size_t j1);\n\n1\n\nSwap rows i0 and i1.\n\n2\n\nSwap columns j0 and j1.\n\n\nThese methods return a reference to *this, so can be chained with other calls.\n\n\n\n\n\n\nBounds checking\n\n\n\nGenerally, these methods do not check whether the indices are in bounds. If they aren’t, the behavior is undefined (but bound to be wrong!) All of them will perform range checking if you set the BIT_DEBUG at compile time. See [bit_assert].\n\n\nExample\n#include <bit/bit.h>\nint main()\n{\n1 bit::matrix<> m(4, 8, [](std::size_t i, std::size_t j) { return (i + j)%2; });\n std::cout << \"Original:\\n\" << m << '\\n';\n std::cout << \"Swapped first 2 rows:\\n\" << m.swap_rows(0,1) << '\\n';\n std::cout << \"And back:\\n\" << m.swap_rows(0,1) << '\\n';\n std::cout << \"Swapped first 2 cols:\\n\" << m.swap_cols(0,1) << '\\n';\n std::cout << \"And back:\\n\" << m.swap_cols(0,1) << '\\n';\n}\n\n1\n\nSet up a bit-matrix with a checkerboard pattern of zeros and ones.\n\n\nOutput\nOriginal:\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\nSwapped first 2 rows:\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\nAnd back:\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\nSwapped first 2 cols:\n│1 0 0 1 0 1 0 1│\n│0 1 1 0 1 0 1 0│\n│1 0 0 1 0 1 0 1│\n│0 1 1 0 1 0 1 0│\nAnd back:\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n│0 1 0 1 0 1 0 1│\n│1 0 1 0 1 0 1 0│\n\nSee Also\nmatrix::replace\n\n\n\n\n Back to top"
},
{
"objectID": "content/matrix/set.html",
diff --git a/sitemap.xml b/sitemap.xml
index 4956cad..b2bedc0 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -26,11 +26,11 @@
https://nessan.github.io/bit/content/matrix/pow.html
- 2024-07-17T16:21:43.194Z
+ 2024-07-26T14:24:12.984Z
https://nessan.github.io/bit/content/matrix/invert.html
- 2024-05-13T13:49:44.717Z
+ 2024-07-26T14:23:38.269Z
https://nessan.github.io/bit/content/matrix/set_if.html
@@ -98,7 +98,7 @@
https://nessan.github.io/bit/content/polynomial/index.html
- 2024-07-21T13:33:31.086Z
+ 2024-07-26T14:32:34.169Z
https://nessan.github.io/bit/content/polynomial/reduce.html
@@ -250,7 +250,7 @@
https://nessan.github.io/bit/content/bit_assert/index.html
- 2024-07-21T13:20:17.005Z
+ 2024-07-26T14:17:34.796Z
https://nessan.github.io/bit/content/index.html
@@ -270,7 +270,7 @@
https://nessan.github.io/bit/content/notes/design.html
- 2024-05-13T13:49:44.723Z
+ 2024-07-26T14:21:58.206Z
https://nessan.github.io/bit/content/notes/gf2.html
@@ -334,7 +334,7 @@
https://nessan.github.io/bit/content/vector/index.html
- 2024-07-21T12:53:57.144Z
+ 2024-07-26T14:29:03.057Z
https://nessan.github.io/bit/content/vector/sub.html
@@ -406,7 +406,7 @@
https://nessan.github.io/bit/content/polynomial/evaluation.html
- 2024-07-21T13:56:58.765Z
+ 2024-07-26T14:24:40.119Z
https://nessan.github.io/bit/content/polynomial/split.html
@@ -450,7 +450,7 @@
https://nessan.github.io/bit/content/matrix/index.html
- 2024-07-21T13:23:01.157Z
+ 2024-07-26T14:25:01.210Z
https://nessan.github.io/bit/content/matrix/companion.html