GF2++
Loading...
Searching...
No Matches
BitPoly.h
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: 2025 Nessan Fitzmaurice <nzznfitz+gh@icloud.com>
3// SPDX-License-Identifier: MIT
4
8
9#include <gf2/BitVec.h>
10#include <sstream>
11
12namespace gf2 {
13
14// Forward declarations to avoid recursive inclusion issues when we define polynomial evaluation for bit-matrices.
15template<Unsigned Word>
16class BitMat;
17
29template<Unsigned Word = usize>
30class BitPoly {
31private:
32 BitVec<Word> m_coeffs;
33
34public:
37
39 using word_type = Word;
40
43
53 constexpr BitPoly() : m_coeffs{} {}
54
64 template<BitStore Src>
65 constexpr BitPoly(Src const& coeffs) : m_coeffs{coeffs.size()} {
66 m_coeffs.copy(coeffs);
67 }
68
82 constexpr BitPoly(BitVec<Word>&& coeffs) : m_coeffs{std::move(coeffs)} {}
83
87
95 static constexpr BitPoly zero() { return BitPoly<Word>{}; }
96
104 static constexpr BitPoly one() { return BitPoly<Word>{std::move(coeffs_type::ones(1))}; }
105
113 static constexpr BitPoly constant(bool val) { return BitPoly<Word>{std::move(coeffs_type::constant(val, 1))}; }
114
124 static constexpr BitPoly zeros(usize n) { return BitPoly<Word>{std::move(coeffs_type::zeros(n + 1))}; }
125
135 static constexpr BitPoly ones(usize n) { return BitPoly<Word>{std::move(coeffs_type::ones(n + 1))}; }
136
144 static constexpr BitPoly x_to_the(usize n) { return BitPoly<Word>{std::move(coeffs_type::unit(n + 1, n))}; }
145
154 static constexpr BitPoly from(usize n, std::invocable<usize> auto f) {
155 return BitPoly<Word>{std::move(coeffs_type::from(n + 1, f))};
156 }
157
161
168 static constexpr BitPoly random(usize n) {
169 // BitPoly of degree `n` has `n + 1` coefficients.
170 auto coeffs = coeffs_type::random(n + 1);
171
172 // If `n > 0` we want the coefficient of `x^n` to be one for sure. If `n == 0` then a random 0/1 is fine.
173 if (n > 0) coeffs.set(n);
174 return BitPoly{std::move(coeffs)};
175 }
176
189 static constexpr BitPoly seeded_random(usize n, std::uint64_t seed) {
190 // BitPoly of degree `n` has `n + 1` coefficients.
191 auto coeffs = coeffs_type::seeded_random(n + 1, seed);
192
193 // If `n > 0` we want the coefficient of `x^n` to be one for sure. If `n == 0` then a random 0/1 is fine.
194 if (n > 0) coeffs.set(n);
195 return BitPoly{std::move(coeffs)};
196 }
197
201
215 constexpr usize degree() const { return m_coeffs.last_set().value_or(0); }
216
228 constexpr usize size() const { return m_coeffs.size(); }
229
231 constexpr bool is_zero() const { return m_coeffs.none(); }
232
234 constexpr bool is_non_zero() const { return m_coeffs.any(); }
235
237 constexpr bool is_one() const { return degree() == 0 && m_coeffs.size() >= 1 && m_coeffs.get(0); }
238
240 constexpr bool is_constant() const { return degree() == 0; }
241
243 constexpr bool is_monic() const { return m_coeffs.trailing_zeros() == 0; }
244
248 constexpr bool is_empty() const { return m_coeffs.is_empty(); }
249
253
261 constexpr auto operator[](usize i) const { return m_coeffs[i]; }
262
274 constexpr auto operator[](usize i) { return m_coeffs[i]; }
275
286 constexpr const coeffs_type& coefficients() const { return m_coeffs; }
287
300 constexpr coeffs_type& coefficients() { return m_coeffs; }
301
315 template<BitStore Src>
316 constexpr void copy_coefficients(Src const& coeffs) {
317 m_coeffs.resize(coeffs.size());
318 m_coeffs.copy(coeffs);
319 }
320
335 constexpr void move_coefficients(coeffs_type&& coeffs) { m_coeffs = std::move(coeffs); }
336
340
350 constexpr BitPoly& clear() {
351 m_coeffs.clear();
352 return *this;
353 }
354
373 constexpr BitPoly& resize(usize n) {
374 m_coeffs.resize(n);
375 return *this;
376 }
377
387 constexpr BitPoly& shrink_to_fit() {
388 m_coeffs.shrink_to_fit();
389 return *this;
390 }
391
405 constexpr BitPoly& make_monic() {
406 if (is_non_zero()) m_coeffs.resize(degree() + 1);
407 return *this;
408 }
409
413
423 constexpr BitPoly& operator+=(BitPoly const& rhs) {
424 // Edge case.
425 if (rhs.is_zero()) return *this;
426
427 // Another edge case.
428 if (is_zero()) {
429 *this = rhs;
430 return *this;
431 }
432
433 // Perhaps we need to get bigger to accommodate the rhs? Note that added coefficients are zeros.
434 auto rhs_degree = rhs.degree();
435 if (m_coeffs.size() < rhs_degree + 1) m_coeffs.resize(rhs_degree + 1);
436
437 // Add in the active rhs words.
438 for (auto i = 0uz; i < rhs.monic_word_count(); ++i) {
439 m_coeffs.set_word(i, m_coeffs.word(i) ^ rhs.m_coeffs.word(i));
440 }
441 return *this;
442 }
443
455 constexpr BitPoly& operator-=(BitPoly const& rhs) { return operator+=(rhs); }
456
470 constexpr BitPoly& operator*=(BitPoly const& rhs) {
471 // Edge cases: zero BitPolys.
472 if (rhs.is_zero()) return clear();
473 if (is_zero()) return *this;
474
475 // Edge cases: either BitPoly is one.
476 if (rhs.is_one()) return *this;
477 if (is_one()) {
478 *this = rhs;
479 return *this;
480 }
481
482 // Generally we pass the work to the convolution method for bit-vectors.
483 *this = BitPoly{std::move(convolve(m_coeffs, rhs.m_coeffs))};
484 return *this;
485 }
486
496 constexpr auto operator+(BitPoly<Word> const& rhs) const {
497 // Avoid unnecessary resizing by adding the smaller degree BitPoly to the larger one ...
498 if (degree() >= rhs.degree()) {
499 BitPoly<Word> result{*this};
500 result += rhs;
501 return result;
502 } else {
503 BitPoly<Word> result{rhs};
504 result += *this;
505 return result;
506 }
507 }
508
520 constexpr auto operator-(BitPoly<Word> const& rhs) const {
521 // Subtraction is identical to addition in GF(2).
522 return operator+(rhs);
523 }
524
534 constexpr auto operator*(BitPoly<Word> const& rhs) const {
535 BitPoly<Word> result{*this};
536 result *= rhs;
537 return result;
538 }
539
543
557 constexpr void squared(BitPoly& dst) const {
558 // Edge case: any constant BitPoly.
559 if (is_constant()) {
560 dst = *this;
561 return;
562 }
563
564 // In GF(2) if p(x) = a + bx + cx^2 + ... then p(x)^2 = a^2 + b^2x^2 + c^2x^4 + ...
565 // This identity means we can use the `riffle` method to square the BitPoly.
566 m_coeffs.riffled(dst.m_coeffs);
567 }
568
580 constexpr BitPoly squared() const {
581 BitPoly dst;
582 squared(dst);
583 return dst;
584 }
585
598 auto new_degree = degree() + n;
599 auto new_size = new_degree + 1;
600 if (m_coeffs.size() < new_size) { m_coeffs.resize(new_size); }
601 m_coeffs >>= n;
602 return *this;
603 }
604
608
617 constexpr bool operator()(bool x) const {
618 // Edge case: the zero BitPoly.
619 if (is_zero()) { return false; }
620
621 // Edge case: `x = false` which is the same as `x = 0` & we always have p(0) = p_0.
622 if (!x) { return m_coeffs.get(0); }
623
624 // We are evaluating the BitPoly at `x = true` which is the same as `x = 1`: p(1) = p_0 + p_1 + p_2 + ...
625 Word sum = 0;
626 for (auto i = 0uz; i < m_coeffs.words(); ++i) sum ^= m_coeffs.word(i);
627 return gf2::count_ones(sum) % 2 == 1;
628 }
629
644 constexpr auto operator()(BitMat<Word> const& M) const {
645 // The bit-matrix argument must be square.
646 gf2_assert(M.is_square(), "Matrix must be square -- not {} x {}!", M.rows(), M.cols());
647
648 // The returned bit-matrix will be n x n.
649 auto n = M.rows();
650
651 // Edge case: If the polynomial is zero then the return value is the n x n zero matrix.
652 if (is_zero()) return BitMat<Word>{n, n};
653
654 // Otherwise we start with the polynomial sum being the n x n identity matrix.
655 auto result = BitMat<Word>::identity(n);
656
657 // Work backwards a la Horner ...
658 auto d = degree();
659 while (d > 0) {
660
661 // Always multiply ...
662 result = M * result;
663
664 // Add the identity to the sum if the corresponding polynomial coefficient is 1.
665 if (m_coeffs[d - 1]) result.add_identity();
666
667 // And count down ...
668 d--;
669 }
670
671 return result;
672 }
673
677
695 BitPoly reduce_x_to_the(usize n, bool n_is_log2 = false) const {
696 // Error check: anything mod 0 is not defined.
697 if (is_zero()) throw std::invalid_argument("... mod P(x) is not defined for P(x) := 0.");
698
699 // Edge case: anything mod 1 = 0.
700 if (is_one()) return BitPoly<Word>::zero();
701
702 // Edge case: x^0 = 1 and 1 mod P(x) = 1 for any P(x) != 1 (we already handled the case where P(x) := 1).
703 if (n == 0 && !n_is_log2) return BitPoly<Word>::one();
704
705 // The BitPoly P(x) is non-zero so can be written as P(x) = x^d + p(x) where degree(p) < d.
706 auto d = degree();
707
708 // Edge case: P(x) = x + c where c is a constant so x = P(x) + c (subtraction in GF(2) is the same as addition).
709 // Then x^e = (P(x) + c)^e = terms in powers of P(x) + c^e. Hence, x^e mod P(x) = c^e = c.
710 if (d == 1) return BitPoly<Word>::constant(m_coeffs.get(1));
711
712 // We can write p(x) = p_0 + p_1 x + ... + p_{d-1} x^{d-1}. All that matters are those coefficients.
713 auto p = m_coeffs.sub(0, d);
714
715 // A lambda to perform: q(x) <- x*q(x) mod P(x) where degree(q) < d.
716 // The lambda works on the coefficients of q(x) passed as a bit-vector q.
717 auto times_x_step = [&](auto& q) {
718 bool add_p = q[d - 1];
719 q >>= 1;
720 if (add_p) q ^= p;
721 };
722
723 // Iteratively precompute x^{d+i} mod P(x) for i = 0, 1, ..., d-1 starting with x^d mod P(x) ~ p.
724 // We store all the bit-vectors in a standard `std::vector` of length d.
725 std::vector<coeffs_type> power_mod(d, coeffs_type{d});
726 power_mod[0] = p;
727 for (auto i = 1uz; i < d; ++i) {
728 power_mod[i] = power_mod[i - 1];
729 times_x_step(power_mod[i]);
730 }
731
732 // Some workspace we use/reuse below in order to minimize allocations/deallocations.
733 coeffs_type s{2 * d}, h{d};
734
735 // lambda to perform: q(x) <- q(x)^2 mod P(x) where degree(q) < d.
736 // The lambda works on the coefficients of q(x) passed as a bit-vector q.
737 auto square_step = [&](auto& q) {
738 // Square q(x) storing the result in workspace `s`.
739 q.riffled(s);
740
741 // Split s(x) = l(x) + x^d * h(x) where l(x) & h(x) are both of degree less than d.
742 // We reuse q(x) for l(x).
743 s.split_at(d, q, h);
744
745 // s(x) = q(x) + h(x) so s(x) mod P(x) = q(x) + h(x) mod P(x) which we handle term by term.
746 // If h(x) != 0 then at most every second term in h(x) is 1 (nature of BitPoly squares in GF(2)).
747 if (auto h_first = h.first_set()) {
748 auto h_last = h.last_set();
749 for (auto i = *h_first; i <= *h_last; i += 2)
750 if (h[i]) q ^= power_mod[i];
751 }
752 };
753
754 // Our return value r(x) := x^e mod P(x) has degree < d: r(x) = r_0 + r_1 x + ... + r_{d-1} x^{d-1}.
755 coeffs_type r{d};
756
757 // If `n_is_log2` is `true`, we are reducing x^(2^n) mod P(x) which is done iteratively by squaring.
758 if (n_is_log2) {
759 // Note that we already handled edge case where P(x) = x + c above.
760 // Start with r(x) = x mod P(x) -> x^2 mod P(x) -> x^4 mod P(x) ...
761 r[1] = true;
762 for (auto i = 0uz; i < n; ++i) square_step(r);
763 return BitPoly{std::move(r)};
764 }
765
766 // Small exponent case: n < d => x^n mod P(x) = x^n.
767 if (n < d) return BitPoly::x_to_the(n);
768
769 // Matching exponent case: n = d => x^n mod P(x) = x^d mod P(x) = p(x).
770 if (n == d) return BitPoly{std::move(p)};
771
772 // General case: n > d is handled by a square & multiply algorithm.
773 usize n_bit = std::bit_floor(n);
774
775 // Start with r(x) = x mod P(x) which takes care of the most significant binary digit in n.
776 // TODO: We could start a bit further along with a higher power r(x) := x^? mod P(x) where ? < n but > 1.
777 r[1] = 1;
778 n_bit >>= 1;
779
780 // And off we go ...
781 while (n_bit) {
782
783 // Always do a square step and then a times_x step if necessary (i.e. if current bit in N is set).
784 square_step(r);
785 if (n & n_bit) times_x_step(r);
786
787 // On to the next bit position in n.
788 n_bit >>= 1;
789 }
790
791 // Made it.
792 return BitPoly{std::move(r)};
793 }
794
798
811 std::string to_string(std::string_view var = "x") const {
812 // Edge case: the zero BitPoly.
813 if (is_zero()) return "0";
814
815 // Otherwise we construct the string ...
816 std::ostringstream ss;
817
818 // All terms other than the first one are preceded by a "+"
819 bool first_term = true;
820 for (auto i = 0uz; i <= degree(); ++i) {
821 if (m_coeffs.get(i)) {
822 if (i == 0) {
823 ss << "1";
824 } else {
825 if (!first_term) ss << " + ";
826 if (i == 1)
827 ss << var;
828 else
829 ss << var << "^" << i;
830 }
831 first_term = false;
832 }
833 }
834 return ss.str();
835 }
836
849 std::string to_full_string(std::string_view var = "x") const {
850 // Edge case: the zero BitPoly.
851 if (is_empty()) return "0";
852
853 // Otherwise we construct the string ...
854 std::ostringstream ss;
855
856 // Start with the first term ...
857 if (m_coeffs.get(0))
858 ss << "1";
859 else
860 ss << "0";
861
862 // Now all the other terms, each preceded by a "+"
863 for (auto i = 1uz; i < size(); ++i) {
864 ss << " + ";
865 if (m_coeffs.get(i) == false) ss << "0";
866 if (i == 1)
867 ss << var;
868 else
869 ss << var << "^" << i;
870 }
871 return ss.str();
872 }
873
875 std::ostream& operator<<(std::ostream& s) const { return s << to_string(); }
876
880
892 friend constexpr bool operator==(BitPoly const& lhs, BitPoly const& rhs) {
893 // Edge case.
894 if (&lhs == &rhs) return true;
895
896 // Check the active words for equality.
897 auto count = lhs.monic_word_count();
898 if (rhs.monic_word_count() != count) return false;
899 for (auto i = 0uz; i < count; ++i)
900 if (lhs.m_coeffs.word(i) != rhs.m_coeffs.word(i)) return false;
901
902 // Made it
903 return true;
904 }
905
907
908private:
909 // Returns the number of "active" words underlying the coefficient bit-vector.
910 // There may be high order trailing zero coefficients that have no real impact on most bit-polynomial calculations.
911 // This method returns the number of "words" that matter in the coefficient bit-vector store of words.
912 constexpr usize monic_word_count() const {
913 if (auto deg = m_coeffs.last_set()) return word_index<Word>(*deg) + 1;
914 return 0;
915 }
916};
917
918} // namespace gf2
919
920// --------------------------------------------------------------------------------------------------------------------
921// Specialises `std::formatter` to handle bit-polynomials ...
922// -------------------------------------------------------------------------------------------------------------------
923
937template<gf2::Unsigned Word>
938struct std::formatter<gf2::BitPoly<Word>> {
939
941 constexpr auto parse(std::format_parse_context const& ctx) {
942 auto it = ctx.begin();
943 if (*it != '}') m_var.clear();
944 while (it != ctx.end() && *it != '}') {
945 m_var += *it;
946 ++it;
947 }
948 return it;
949 }
950
952 template<class FormatContext>
953 auto format(gf2::BitPoly<Word> const& rhs, FormatContext& ctx) const {
954 return std::format_to(ctx.out(), "{}", rhs.to_string(m_var));
955 }
956
957 std::string m_var = "x";
958};
Vectors over GF(2) with compactly stored bit-elements in a standard vector of primitive unsigned word...
#define gf2_assert(cond,...)
A confirmation macro that checks a boolean condition cond. On failure, the confirmation prints an e...
Definition assert.h:98
A dynamically-sized matrix over GF(2) stored as a vector of bit-vectors representing the rows of the ...
Definition BitMat.h:32
constexpr bool is_square() const
Returns true if this a square bit-matrix? Note that empty bit-matrices are NOT considered square.
Definition BitMat.h:652
constexpr usize cols() const
Returns the number of columns in the bit-matrix.
Definition BitMat.h:629
static constexpr BitMat identity(usize m)
Factory method to create the m x m identity bit-matrix.
Definition BitMat.h:380
constexpr void add_identity()
Adds the identity bit-matrix to the bit-matrix.
Definition BitMat.h:1601
constexpr usize rows() const
Returns the number of rows in the bit-matrix.
Definition BitMat.h:626
A BitPoly represents a polynomial over GF(2) where we store the polynomial coefficients in a bit-vect...
Definition BitPoly.h:30
constexpr auto operator*(BitPoly< Word > const &rhs) const
Returns the product of two bit-polynomials.
Definition BitPoly.h:534
constexpr bool is_empty() const
Returns true if the bit-polynomial is empty, i.e., has no coefficients.
Definition BitPoly.h:248
constexpr bool is_zero() const
Returns true if the bit-polynomial is some form of the zero BitPoly p(x) := 0.
Definition BitPoly.h:231
std::string to_string(std::string_view var="x") const
Returns a readable string representation of the bit-polynomial p(x) = p0 + p1x + ....
Definition BitPoly.h:811
static constexpr BitPoly constant(bool val)
Factory method to return the constant bit-polynomial p(x) := val where val is a boolean.
Definition BitPoly.h:113
constexpr auto operator[](usize i)
Returns the coefficient of in the bit-polynomial as a BitRef.
Definition BitPoly.h:274
constexpr BitPoly(Src const &coeffs)
Constructs a bit-polynomial with the given coefficients by copying them from any bit-store.
Definition BitPoly.h:65
constexpr BitPoly & make_monic()
Kills any trailing zero coefficients, so e.g. p(x) := 0*x^4 + x^2 + x becomes p(x) := x^2 + x.
Definition BitPoly.h:405
constexpr bool is_constant() const
Returns true if the bit-polynomial is either p(x) := 0 or 1.
Definition BitPoly.h:240
constexpr usize size() const
Returns the "size" of the bit-polynomial which is its total number of coefficients.
Definition BitPoly.h:228
constexpr BitPoly & shrink_to_fit()
Shrinks the BitPoly to have the minimum number of coefficients and returns self.
Definition BitPoly.h:387
constexpr bool is_non_zero() const
Returns true if the bit-polynomial is non-zero.
Definition BitPoly.h:234
static constexpr BitPoly zero()
Factory method to return the "zero" bit-polynomial p(x) := 0.
Definition BitPoly.h:95
static constexpr BitPoly from(usize n, std::invocable< usize > auto f)
Factory method to return a new bit-polynomial of degree n with coefficients set by calling the functi...
Definition BitPoly.h:154
constexpr BitPoly & clear()
Clears the BitPoly, i.e., sets it to the zero BitPoly & returns self.
Definition BitPoly.h:350
constexpr BitPoly & operator+=(BitPoly const &rhs)
In-place addition with another bit-polynomial, returning a reference to the result.
Definition BitPoly.h:423
constexpr void copy_coefficients(Src const &coeffs)
Set the bit-polynomial coefficients by copying them from a pre-filled bit-store.
Definition BitPoly.h:316
constexpr BitPoly & resize(usize n)
Resizes the BitPoly to have the n coefficients and returns self.
Definition BitPoly.h:373
constexpr void move_coefficients(coeffs_type &&coeffs)
Set the BitPoly coefficients by moving a bit-vector of coefficients into place.
Definition BitPoly.h:335
constexpr BitPoly(BitVec< Word > &&coeffs)
Constructs a bit-polynomial with the given coefficients by moving them.
Definition BitPoly.h:82
std::ostream & operator<<(std::ostream &s) const
The usual output stream operator for a bit-polynomial.
Definition BitPoly.h:875
constexpr bool is_one() const
Returns true if the bit-polynomial is p(x) := 1.
Definition BitPoly.h:237
BitVec< Word > coeffs_type
The type used to store the bit-polynomial coefficients.
Definition BitPoly.h:36
static constexpr BitPoly one()
Factory method to return the "one" bit-polynomial p(x) := 1.
Definition BitPoly.h:104
constexpr BitPoly squared() const
Returns a new BitPoly that is the square of this BitPoly.
Definition BitPoly.h:580
std::string to_full_string(std::string_view var="x") const
Returns a readable full string representation of the bit-polynomial.
Definition BitPoly.h:849
constexpr auto operator[](usize i) const
Returns the coefficient of in the bit-polynomial as a boolean.
Definition BitPoly.h:261
constexpr usize degree() const
Returns the degree of the bit-polynomial.
Definition BitPoly.h:215
constexpr BitPoly()
The default constructor creates an empty bit-polynomial with no coefficients.
Definition BitPoly.h:53
Word word_type
The underlying unsigned word type used to store the bits.
Definition BitPoly.h:39
constexpr const coeffs_type & coefficients() const
Read-only access to all the coefficients of the bit-polynomial.
Definition BitPoly.h:286
constexpr bool is_monic() const
Returns true if the bit-polynomial is monic, i.e., no trailing zero coefficients.
Definition BitPoly.h:243
constexpr BitPoly & operator-=(BitPoly const &rhs)
In-place subtraction with another bit-polynomial, returning a reference to the result.
Definition BitPoly.h:455
constexpr void squared(BitPoly &dst) const
Fills dst with the square of this bit-polynomial.
Definition BitPoly.h:557
constexpr BitPoly & times_x_to_the(usize n)
Multiplies the BitPoly by x^n and returns self.
Definition BitPoly.h:597
constexpr coeffs_type & coefficients()
Read-write access to all the coefficients of the bit-polynomial.
Definition BitPoly.h:300
constexpr auto operator+(BitPoly< Word > const &rhs) const
Returns the sum of two bit-polynomials.
Definition BitPoly.h:496
constexpr auto operator-(BitPoly< Word > const &rhs) const
Returns the difference of two bit-polynomials.
Definition BitPoly.h:520
static constexpr BitPoly zeros(usize n)
Factory method to return a bit-polynomial with n + 1 coefficients, all initialized to zero.
Definition BitPoly.h:124
constexpr bool operator()(bool x) const
Evaluates the BitPoly at the boolean scalar point x and returns the result.
Definition BitPoly.h:617
constexpr auto operator()(BitMat< Word > const &M) const
Evaluates the bit-polynomial for a square gf2::BitMat argument M.
Definition BitPoly.h:644
static constexpr BitPoly random(usize n)
Factory method to return a new bit-polynomial of degree n with n + 1 coefficients picked uniformly at...
Definition BitPoly.h:168
constexpr BitPoly & operator*=(BitPoly const &rhs)
In-place multiplication with another bit-polynomial, returning a reference to the result.
Definition BitPoly.h:470
static constexpr BitPoly seeded_random(usize n, std::uint64_t seed)
Factory method to return a new bit-polynomial of degree n with n + 1 coefficients picked uniformly at...
Definition BitPoly.h:189
static constexpr BitPoly x_to_the(usize n)
Factory method to return the bit-polynomial p(x) := x^n.
Definition BitPoly.h:144
BitPoly reduce_x_to_the(usize n, bool n_is_log2=false) const
If this polynomial is P(x) we return x^e mod P(x) for e = n or e = 2^n depending on the n_is_log2 arg...
Definition BitPoly.h:695
static constexpr BitPoly ones(usize n)
Factory method to return a monic bit-polynomial of degree n with n + 1 coefficients,...
Definition BitPoly.h:135
friend constexpr bool operator==(BitPoly const &lhs, BitPoly const &rhs)
Equality operator checks that any pair of bit-polynomials are equal in content.
Definition BitPoly.h:892
A dynamically-sized vector over GF(2) with bit elements compactly stored in a standard vector of prim...
Definition BitVec.h:23
constexpr Word word(usize i) const
Returns word i from the bit-vector's underlying word store.
Definition BitVec.h:79
static constexpr BitVec constant(usize n, bool value)
Definition BitVec.h:213
static constexpr BitVec zeros(usize n)
Definition BitVec.h:194
constexpr void split_at(usize at, BitVec< word_type > &left, BitVec< word_type > &right) const
Views a bit-store as two parts containing the elements [0, at) and [at, size()) respectively.
Definition BitVec.h:1552
static BitVec random(usize len, double p=0.5, u64 seed=0)
Definition BitVec.h:345
static constexpr BitVec ones(usize n)
Definition BitVec.h:202
static BitVec seeded_random(usize len, u64 seed)
Definition BitVec.h:368
static constexpr BitVec from(Src src)
Definition BitVec.h:257
constexpr std::optional< usize > last_set() const
Returns the index of the last set bit in the bit-store or {} if no bits are set.
Definition BitVec.h:1283
static constexpr BitVec unit(usize n, usize i)
Definition BitVec.h:224
The namespace for the gf2 library.
Definition assert.h:119
auto convolve(Lhs const &lhs, Rhs const &rhs)
Convolutions:
Definition BitStore.h:2106
constexpr usize count_ones(Store const &store)
Returns the number of set bits in the store.
Definition BitStore.h:674
constexpr usize word_index(usize i)
Returns the index of the Unsigned word holding bit element i.
Definition Unsigned.h:540
std::size_t usize
Word type alias for the platform's "native"-sized unsigned integer.
Definition Unsigned.h:42
STL namespace.
constexpr auto parse(std::format_parse_context const &ctx)
Parse a bit-polynomial format specifier for a variable name (default is "x").
Definition BitPoly.h:941
auto format(gf2::BitPoly< Word > const &rhs, FormatContext &ctx) const
Defer the work to the to_string(...) method in the class.
Definition BitPoly.h:953