21#ifndef LIBSEMIGROUPS_BIPART_HPP_
22#define LIBSEMIGROUPS_BIPART_HPP_
33#include <initializer_list>
36#include <unordered_set>
39#include "adapters.hpp"
41#include "exception.hpp"
44#include "detail/fmt.hpp"
171 template <
typename T>
186 template <
typename T>
188 = detail::IsBipartitionHelper<std::decay_t<T>>::value;
193 template <
typename BipartitionOrBlocks,
typename Scalar>
196 static_assert(std::is_same_v<BipartitionOrBlocks, Bipartition>
197 || std::is_same_v<BipartitionOrBlocks, Blocks>);
199 "the 2nd template parameter Scalar must be signed");
207 for (
size_t i = 0; i <
blocks.size(); ++i) {
208 auto const& block =
blocks[i];
211 "expected all blocks to be non-empty, but "
212 "found empty block in position {}",
215 bool positive = block[0] >= 0;
217 for (
size_t j = 0; j < block.size(); ++j) {
222 "expected non-zero values but found 0 in "
223 "position {} of the block with index {}",
228 "the argument (blocks) is invalid, expected every value in the "
229 "block with index {} to be {}tive, but found {} in position {}",
231 positive ?
"posi" :
"nega",
242 if (m >=
static_cast<int32_t
>(0x40000000)) {
244 "too many points, expected at most {}, found {}", 0x40000000, m);
245 }
else if (deg != offset * m || vals.
size() !=
size_t(deg)) {
248 prefix =
"the union of";
249 range = fmt::format(
"{{{}, ..., -1, 1, ..., {}}}", -m, m);
252 =
"the set consisting of the absolute values of the entries in ";
253 range = fmt::format(
"[1, {}]", m);
256 " only {} values were given",
264 template <
typename BipartitionOrBlocks,
typename Scalar>
265 static void throw_if_bad_args(
268 throw_if_bad_args<BipartitionOrBlocks>(arg);
272 template <
typename BipartitionOrBlocks,
typename Scalar>
278 template <
typename BipartitionOrBlocks,
typename Scalar>
426 LIBSEMIGROUPS_ASSERT(i < _lookup.size());
445 throw_if_class_index_out_of_range(i);
468 LIBSEMIGROUPS_ASSERT(index < _lookup.size());
469 return _lookup[index];
488 throw_if_class_index_out_of_range(index);
541 return _blocks == that._blocks && _lookup == that._lookup;
560 return !(*
this == that);
591 [[nodiscard]] uint32_t
degree() const noexcept {
592 return _blocks.size();
608 return _lookup.size();
623 [[nodiscard]] uint32_t
rank()
const;
652 return _lookup.cbegin();
660 return _lookup.cend();
691 return _blocks.cbegin();
705 return _blocks.cend();
721 LIBSEMIGROUPS_ASSERT(i < _blocks.size());
736 [[nodiscard]] uint32_t
const&
at(
size_t i)
const {
738 return _blocks.at(i);
742 void throw_if_class_index_out_of_range(
size_t index)
const;
797 template <
typename Return,
typename Container>
799 detail::throw_if_bad_args<Blocks>(cont);
820 template <
typename Return>
844 std::string_view braces
846 size_t max_width = 72);
867 mutable size_t _nr_blocks;
868 mutable size_t _nr_left_blocks;
870 mutable size_t _rank;
998 return _vector == that._vector;
1016 return _vector < that._vector;
1090 [[nodiscard]] uint32_t&
at(
size_t i) {
1091 return _vector.at(i);
1111 [[nodiscard]] uint32_t
const&
at(
size_t i)
const {
1112 return _vector.at(i);
1128 return _vector.cbegin();
1145 return _vector.cend();
1227 [[nodiscard]]
size_t degree() const noexcept;
1269 size_t thread_id = 0);
1484 init_trans_blocks_lookup();
1485 return _trans_blocks_lookup.cbegin();
1493 init_trans_blocks_lookup();
1494 return _trans_blocks_lookup.cend();
1511 return _trans_blocks_lookup;
1515 void init_trans_blocks_lookup()
const;
1545 template <
typename Return,
typename Container>
1548 detail::throw_if_bad_args<Bipartition>(cont);
1559 template <
typename Return>
1568 template <
typename Return>
1594 std::string_view braces
1596 size_t max_width = 72);
1649 return x < y || x == y;
1698 return x.degree() * x.degree();
1703 struct Degree<Bipartition> {
1704 [[nodiscard]]
size_t operator()(Bipartition
const& x)
const noexcept {
1711 [[nodiscard]]
size_t operator()(Bipartition
const& x)
const {
1718 [[nodiscard]] Bipartition operator()(Bipartition
const& x)
const {
1719 return (*
this)(x.degree());
1722 [[nodiscard]] Bipartition operator()(
size_t N = 0)
const {
1729 void operator()(Bipartition& xy,
1730 Bipartition
const& x,
1731 Bipartition
const& y,
1732 size_t thread_id = 0) {
1739 void operator()(Bipartition&,
size_t) {}
Class for representing bipartitions.
Definition bipart.hpp:865
size_t rank() const
Return the number of transverse blocks.
Bipartition(std::vector< std::vector< int32_t > > const &blocks)
Construct a bipartition from a partition.
bool operator<(Bipartition const &that) const
Compare bipartitions for less.
Definition bipart.hpp:1015
void set_number_of_left_blocks(size_t n) noexcept
Set the number of left blocks.
uint32_t & operator[](size_t i)
Return the index of the block containing a value.
Definition bipart.hpp:1052
uint32_t number_of_blocks() const
Return the number of blocks in a Bipartition.
typename std::vector< bool >::const_iterator lookup_const_iterator
Type of const iterators pointing to transverse blocks lookup.
Definition bipart.hpp:890
Bipartition(std::vector< uint32_t > const &blocks)
Construct a bipartition from a const reference to blocks lookup.
std::vector< uint32_t >::const_iterator const_iterator
Type of const iterators pointing to block lookup.
Definition bipart.hpp:884
Blocks * left_blocks_no_checks() const
Return a pointer to the left blocks of a bipartition.
Blocks * right_blocks() const
Return a pointer to the right blocks of a bipartition.
uint32_t const & operator[](size_t i) const
Return the index of the block containing a value.
Definition bipart.hpp:1071
Blocks * left_blocks() const
Return a pointer to the left blocks of a bipartition.
Bipartition & operator=(Bipartition const &)
Default copy assignment operator.
uint32_t number_of_right_blocks() const
Return the number of blocks containing a negative integer.
size_t degree() const noexcept
Return the degree of the bipartition.
void product_inplace_no_checks(Bipartition const &x, Bipartition const &y, size_t thread_id=0)
Modify the current bipartition in-place to contain the product of two bipartitions.
Bipartition()
Construct an uninitialised bipartition of degree 0.
void set_number_of_blocks(size_t n) noexcept
Set the number of blocks.
const_iterator cend_right_blocks() const noexcept
Const iterator pointing one beyond the last index of the last right block.
Definition bipart.hpp:1212
void set_rank(size_t n) noexcept
Set the rank.
bool is_transverse_block(size_t index) const
Check if a block is a transverse block.
uint32_t number_of_left_blocks() const
Return the number of blocks containing a positive integer.
lookup_const_iterator cend_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:1492
std::vector< uint32_t >::iterator iterator
Type of iterators pointing to block lookup.
Definition bipart.hpp:878
bool operator==(Bipartition const &that) const
Compare bipartitions for equality.
Definition bipart.hpp:997
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:1510
const_iterator cbegin_left_blocks() const noexcept
Const iterator pointing to the index of the first left block.
Definition bipart.hpp:1161
const_iterator cend() const noexcept
Return a const iterator pointing one beyond the last index of the last block.
Definition bipart.hpp:1144
bool is_transverse_block_no_checks(size_t index) const
Check if a block is a transverse block.
Bipartition(Bipartition &&)
Default move constructor.
const_iterator cend_left_blocks() const noexcept
Const iterator pointing one beyond the last index of the last left block.
Definition bipart.hpp:1178
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a value.
Definition bipart.hpp:1111
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:1483
Bipartition(size_t N)
Construct an uninitialised bipartition of given degree.
Bipartition(std::initializer_list< uint32_t > const &blocks)
Construct a bipartition from an initializer list blocks lookup.
const_iterator cbegin() const noexcept
Return a const iterator pointing to the index of the first block.
Definition bipart.hpp:1127
static Bipartition one(size_t n)
Return an identity bipartition of given degree.
Bipartition & operator=(Bipartition &&)
Default move assignment operator.
Bipartition(Bipartition const &)
Default copy constructor.
Bipartition(std::vector< uint32_t > &&blocks)
Construct a bipartition from an rvalue reference to blocks lookup.
size_t hash_value() const
Return a hash value.
Definition bipart.hpp:1034
const_iterator cbegin_right_blocks() const noexcept
Const iterator pointing to the index of the first right block.
Definition bipart.hpp:1195
Bipartition(std::initializer_list< std::vector< int32_t > > const &blocks)
Construct a bipartition from a partition.
uint32_t & at(size_t i)
Return a reference to the index of the block containing a value.
Definition bipart.hpp:1090
Blocks * right_blocks_no_checks() const
Return a pointer to the right blocks of a bipartition.
A Blocks object represents a signed partition of the set .
Definition bipart.hpp:301
Blocks & operator=(Blocks const &)=default
Default copy assignment operator.
Blocks(Blocks &©)=default
Default move constructor.
bool operator==(Blocks const &that) const
Compare two blocks objects for equality.
Definition bipart.hpp:540
Blocks(std::vector< std::vector< int32_t > > const &blocks)
Constructs a Blocks object from a vector of vectors of integers.
uint32_t const & operator[](size_t i) const
Return a const reference to the index of the block containing a point.
Definition bipart.hpp:720
Blocks & block_no_checks(size_t i, uint32_t val)
Set the block that a point belongs to.
bool is_transverse_block(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:487
Blocks(Blocks const ©)=default
Default copy constructor.
typename std::vector< uint32_t >::iterator iterator
Type for iterators pointing to the index of the block.
Definition bipart.hpp:315
lookup_const_iterator cend_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:659
size_t hash_value() const noexcept
Return a hash value for a Blocks instance.
Blocks & is_transverse_block(size_t i, bool val)
Set whether or not the block containing a point is transverse.
Definition bipart.hpp:444
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:676
Blocks() noexcept=default
Constructs a blocks object of size 0.
const_iterator cend() const noexcept
Return a const iterator pointing one past-the-end of the last block.
Definition bipart.hpp:704
std::vector< bool >::const_iterator lookup_const_iterator
Type for const iterators pointing to the transverse block lookup.
Definition bipart.hpp:310
bool is_transverse_block_no_checks(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:467
bool operator<(Blocks const &that) const
Compare two blocks objects for less.
Blocks & is_transverse_block_no_checks(size_t i, bool val)
Set whether or not the block containing a point is transverse.
Definition bipart.hpp:425
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a point.
Definition bipart.hpp:736
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:651
const_iterator cbegin() const noexcept
Return a const iterator pointing to the index of the first block.
Definition bipart.hpp:690
uint32_t rank() const
Return the number of transverse blocks.
Blocks & operator=(Blocks &&)=default
Default move assignment operator.
uint32_t number_of_blocks() const noexcept
Return the number of blocks in a Blocks object.
Definition bipart.hpp:607
bool operator!=(Blocks const &that) const
Compare two blocks objects for inequality.
Definition bipart.hpp:559
uint32_t degree() const noexcept
Return the degree of a blocks object.
Definition bipart.hpp:591
typename std::vector< uint32_t >::const_iterator const_iterator
Type for const iterators pointing to the index of the block.
Definition bipart.hpp:320
Blocks & block(size_t i, uint32_t val)
Set the block that a point belongs to.
std::string to_human_readable_repr(AhoCorasick const &ac)
Return a string representation.
bool operator<=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1647
bool operator>=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1669
bool operator>(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1658
Bipartition operator*(Bipartition const &x, Bipartition const &y)
Multiply two bipartitions.
static constexpr bool IsBipartition
Helper variable template.
Definition bipart.hpp:188
bool operator!=(Bipartition const &x, Bipartition const &y)
Check bipartitions for inequality.
Definition bipart.hpp:1637
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:95
enable_if_is_same< Return, Blocks > make(Container const &cont)
Check the arguments, construct a Blocks object, and check it.
Definition bipart.hpp:798
std::enable_if_t< std::is_same_v< Given, Expected >, Expected > enable_if_is_same
Alias equal to the second template parameter if both template parameters are equal.
Definition types.hpp:50
Namespace for Bipartition helper functions.
Definition bipart.hpp:118
std::vector< std::vector< int32_t > > underlying_partition(Bipartition const &x)
Return the underlying partition of a Bipartition object.
Bipartition one(Bipartition const &f)
Return the identity bipartition with the same degree as the given bipartition.
void throw_if_invalid(Bipartition const &x)
Checks a bipartition.
Namespace for Blocks helper functions.
Definition bipart.hpp:67
void throw_if_invalid(Blocks const &x)
Check a Blocks object.
std::vector< std::vector< int32_t > > underlying_partition(Blocks const &x)
Return the underlying partition of a Blocks object.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
size_t operator()(Bipartition const &x) const noexcept
Definition bipart.hpp:1697
Adapter for the complexity of multiplication.
Definition adapters.hpp:121
Adapter for hashing.
Definition adapters.hpp:446
size_t operator()(Value const &x) const
Hash x using std::hash.
Definition adapters.hpp:455
Adapter for increasing the degree of an element.
Definition adapters.hpp:199
Adapter for the identity element of the given type.
Definition adapters.hpp:246
Adapter for the product of two elements.
Definition adapters.hpp:284