libsemigroups  v3.2.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
bipart.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2021-2025 James D. Mitchell
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17//
18
19// This file contains the declaration of the Bipartition and Blocks classes.
20
21#ifndef LIBSEMIGROUPS_BIPART_HPP_
22#define LIBSEMIGROUPS_BIPART_HPP_
23
24// TODO(2)
25// * benchmarks
26// * use Duf/Suf where possible (later?)
27// * template like transformations/pperms etc (later?)
28
29#include <algorithm> // for max
30#include <cstddef> // for size_t
31#include <cstdint> // for uint32_t, int32_t
32#include <cstdlib> // for abs
33#include <initializer_list> // for initializer_list
34#include <string_view> // for string_view
35#include <type_traits> // for decay_t, false_type, is_signed, true_type
36#include <unordered_set> // for unordered_set
37#include <vector> // for vector
38
39#include "adapters.hpp" // for Hash
40#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
41#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
42#include "types.hpp" // for enable_if_is_same
43
44#include "detail/fmt.hpp"
45
46namespace libsemigroups {
57
58 // Forward decls
59 class Bipartition;
60 class Blocks;
61
67 namespace blocks {
87 void throw_if_invalid(Blocks const& x);
88
110
111 } // namespace blocks
112
118 namespace bipartition {
133 [[nodiscard]] Bipartition one(Bipartition const& f);
134
156
166
185
205
217
230 Bipartition random(size_t deg);
231
232 } // namespace bipartition
233
243 template <typename Thing>
244 static constexpr bool IsBipartition [[deprecated]]
245 = std::is_same_v<std::decay_t<Thing>, Bipartition>;
246
247 namespace detail {
248
250 template <typename Thing, typename Scalar>
251 static void
252 throw_if_bad_args(std::vector<std::vector<Scalar>> const& blocks) {
253 static_assert(std::is_same_v<Thing, Bipartition>
254 || std::is_same_v<Thing, Blocks>);
255 static_assert(std::is_signed<Scalar>::value,
256 "the 2nd template parameter Scalar must be signed");
257 int32_t offset = 2;
258 if (!std::is_same_v<Thing, Bipartition>) {
259 offset = 1;
260 }
261 int32_t m = 0;
262 int32_t deg = 0;
264 for (size_t i = 0; i < blocks.size(); ++i) {
265 auto const& block = blocks[i];
266 if (block.empty()) {
267 LIBSEMIGROUPS_EXCEPTION("the argument (blocks) is invalid, "
268 "expected all blocks to be non-empty, but "
269 "found empty block in position {}",
270 i);
271 }
272 bool positive = block[0] >= 0;
273
274 for (size_t j = 0; j < block.size(); ++j) {
275 auto x = block[j];
276 vals.insert(x);
277 if (x == 0) {
278 LIBSEMIGROUPS_EXCEPTION("the argument (blocks) is invalid, "
279 "expected non-zero values but found 0 in "
280 "position {} of the block with index {}",
281 j,
282 i);
283 } else if (!std::is_same_v<Thing, Bipartition> && positive && x < 0) {
285 "the argument (blocks) is invalid, expected every value in the "
286 "block with index {} to be {}tive, but found {} in position {}",
287 i,
288 positive ? "posi" : "nega",
289 x,
290 j);
291 }
292 x = std::abs(x);
293
294 m = std::max(x, m);
295 deg++;
296 }
297 }
298
299 if (m >= static_cast<int32_t>(0x40000000)) {
301 "too many points, expected at most {}, found {}", 0x40000000, m);
302 } else if (deg != offset * m || vals.size() != size_t(deg)) {
303 std::string range, prefix;
304 if (std::is_same_v<Thing, Bipartition>) {
305 prefix = "the union of";
306 range = fmt::format("{{{}, ..., -1, 1, ..., {}}}", -m, m);
307 } else {
308 prefix
309 = "the set consisting of the absolute values of the entries in ";
310 range = fmt::format("[1, {}]", m);
311 }
312 LIBSEMIGROUPS_EXCEPTION("{} the given blocks is not {},"
313 " only {} values were given",
314 prefix,
315 range,
316 deg);
317 }
318 }
319
321 template <typename Thing, typename Scalar>
322 static void throw_if_bad_args(
325 throw_if_bad_args<Thing>(arg);
326 }
327
329 template <typename Thing, typename Scalar>
330 static void throw_if_bad_args(std::vector<Scalar> const&) {
331 // checks for this argument type are done in throw_if_invalid
332 }
333
335 template <typename Thing, typename Scalar>
336 static void throw_if_bad_args(std::initializer_list<Scalar> const&) {
337 // checks for this argument type are done in throw_if_invalid
338 }
339 } // namespace detail
340
358 class Blocks {
359 private:
360 std::vector<uint32_t> _blocks;
361 std::vector<bool> _lookup;
362
363 public:
368
373
378
388 Blocks() noexcept;
389
410
420 explicit Blocks(size_t degree) : _blocks(degree), _lookup() {}
421
441 // TODO(0) this should be a make function not a constructor
443
448
453
457 Blocks(Blocks const& copy);
458
462 Blocks(Blocks&& copy);
463
464 ~Blocks();
465
483 LIBSEMIGROUPS_ASSERT(i < _lookup.size());
484 _lookup[i] = val;
485 return *this;
486 }
487
501 Blocks& is_transverse_block(size_t i, bool val) {
502 throw_if_class_index_out_of_range(i);
503 return is_transverse_block_no_checks(i, val);
504 }
505
524 [[nodiscard]] bool is_transverse_block_no_checks(size_t index) const {
525 LIBSEMIGROUPS_ASSERT(index < _lookup.size());
526 return _lookup[index];
527 }
528
544 [[nodiscard]] bool is_transverse_block(size_t index) const {
545 throw_if_class_index_out_of_range(index);
546 return is_transverse_block_no_checks(index);
547 }
548
565 Blocks& block_no_checks(size_t i, uint32_t val);
566
580 Blocks& block(size_t i, uint32_t val);
581
597 [[nodiscard]] bool operator==(Blocks const& that) const {
598 return _blocks == that._blocks && _lookup == that._lookup;
599 }
600
616 [[nodiscard]] bool operator!=(Blocks const& that) const {
617 return !(*this == that);
618 }
619
634 [[nodiscard]] bool operator<(Blocks const& that) const;
635
636 // TODO(2) operator<=, operator>, operator>=
637
648 [[nodiscard]] uint32_t degree() const noexcept {
649 return _blocks.size();
650 }
651
664 [[nodiscard]] uint32_t number_of_blocks() const noexcept {
665 return _lookup.size();
666 }
667
680 [[nodiscard]] uint32_t rank() const;
681
693 [[nodiscard]] size_t hash_value() const noexcept;
694
708 [[nodiscard]] lookup_const_iterator cbegin_lookup() const noexcept {
709 return _lookup.cbegin();
710 }
711
716 [[nodiscard]] lookup_const_iterator cend_lookup() const noexcept {
717 return _lookup.cend();
718 }
719
733 [[nodiscard]] std::vector<bool> const& lookup() const noexcept {
734 return _lookup;
735 }
736
747 [[nodiscard]] const_iterator cbegin() const noexcept {
748 return _blocks.cbegin();
749 }
750
761 [[nodiscard]] const_iterator cend() const noexcept {
762 return _blocks.cend();
763 }
764
777 [[nodiscard]] uint32_t const& operator[](size_t i) const {
778 LIBSEMIGROUPS_ASSERT(i < _blocks.size());
779 return _blocks[i];
780 }
781
793 [[nodiscard]] uint32_t const& at(size_t i) const {
794 // TODO(2) better error
795 return _blocks.at(i);
796 }
797
798 private:
799 void throw_if_class_index_out_of_range(size_t index) const;
800 }; // class Blocks
801
826
837
854 template <typename Return, typename Container>
855 [[nodiscard]] enable_if_is_same<Return, Blocks> make(Container const& cont) {
856 detail::throw_if_bad_args<Blocks>(cont);
857 Blocks result(cont);
859 return result;
860 }
861
877 template <typename Return>
882
901 std::string_view braces
902 = "{}",
903 size_t max_width = 72);
904
921 // TODO(2) add more explanation to the doc here
923 private:
924 mutable size_t _nr_blocks;
925 mutable size_t _nr_left_blocks;
926 mutable std::vector<bool> _trans_blocks_lookup;
927 mutable size_t _rank;
928 std::vector<uint32_t> _vector;
929
930 public:
936
942
948
953
959 explicit Bipartition(size_t N);
960
982
992
1001
1016
1020
1025
1030
1035
1040
1041 ~Bipartition();
1042
1054 [[nodiscard]] bool operator==(Bipartition const& that) const {
1055 return _vector == that._vector;
1056 }
1057
1072 [[nodiscard]] bool operator<(Bipartition const& that) const {
1073 return _vector < that._vector;
1074 }
1075
1076 // TODO(2) other operators <=, >, >=, !=
1077
1090 // not noexcept because Hash<T>::operator() isn't
1091 [[nodiscard]] size_t hash_value() const {
1092 return Hash<std::vector<uint32_t>>()(_vector);
1093 }
1094
1109 [[nodiscard]] uint32_t& operator[](size_t i) {
1110 return _vector[i];
1111 }
1112
1128 [[nodiscard]] uint32_t const& operator[](size_t i) const {
1129 return _vector[i];
1130 }
1131
1147 [[nodiscard]] uint32_t& at(size_t i) {
1148 return _vector.at(i);
1149 }
1150
1168 [[nodiscard]] uint32_t const& at(size_t i) const {
1169 return _vector.at(i);
1170 }
1171
1184 [[nodiscard]] const_iterator cbegin() const noexcept {
1185 return _vector.cbegin();
1186 }
1187
1199 [[nodiscard]] iterator begin() noexcept {
1200 return _vector.begin();
1201 }
1202
1216 [[nodiscard]] const_iterator cend() const noexcept {
1217 return _vector.cend();
1218 }
1219
1233 [[nodiscard]] iterator end() noexcept {
1234 return _vector.end();
1235 }
1236
1250 [[nodiscard]] const_iterator cbegin_left_blocks() const noexcept {
1251 return cbegin();
1252 }
1253
1267 [[nodiscard]] const_iterator cend_left_blocks() const noexcept {
1268 return cbegin() + degree();
1269 }
1270
1284 [[nodiscard]] const_iterator cbegin_right_blocks() const noexcept {
1285 return cend_left_blocks();
1286 }
1287
1301 [[nodiscard]] const_iterator cend_right_blocks() const noexcept {
1302 return cend();
1303 }
1304
1316 [[nodiscard]] size_t degree() const noexcept;
1317
1332 [[nodiscard]] static Bipartition one(size_t n);
1333
1357 Bipartition const& y,
1358 size_t thread_id = 0);
1359
1373 [[nodiscard]] size_t rank() const;
1374
1387 [[nodiscard]] uint32_t number_of_blocks() const;
1388
1403 [[nodiscard]] uint32_t number_of_left_blocks() const;
1404
1419 [[nodiscard]] uint32_t number_of_right_blocks() const;
1420
1437 [[nodiscard]] bool is_transverse_block_no_checks(size_t index) const;
1438
1453 [[nodiscard]] bool is_transverse_block(size_t index) const;
1454
1468 // TODO(2) remove this
1469 [[nodiscard]] Blocks* left_blocks() const;
1470
1485 [[nodiscard]] Blocks* left_blocks_no_checks() const;
1486
1499 // TODO(2) remove this
1500 [[nodiscard]] Blocks* right_blocks() const;
1501
1515 [[nodiscard]] Blocks* right_blocks_no_checks() const;
1516
1529 void set_number_of_blocks(size_t n) noexcept;
1530
1543 void set_number_of_left_blocks(size_t n) noexcept;
1544
1557 void set_rank(size_t n) noexcept;
1558
1572 [[nodiscard]] lookup_const_iterator cbegin_lookup() const noexcept {
1573 init_trans_blocks_lookup();
1574 return _trans_blocks_lookup.cbegin();
1575 }
1576
1581 [[nodiscard]] lookup_const_iterator cend_lookup() const noexcept {
1582 init_trans_blocks_lookup();
1583 return _trans_blocks_lookup.cend();
1584 }
1585
1599 [[nodiscard]] std::vector<bool> const& lookup() const noexcept {
1600 return _trans_blocks_lookup;
1601 }
1602
1603 private:
1604 void init_trans_blocks_lookup() const;
1605 }; // class Bipartition
1606
1617
1634 template <typename Return, typename Container>
1636 make(Container const& cont) {
1637 detail::throw_if_bad_args<Bipartition>(cont);
1638 Bipartition result(cont);
1640 return result;
1641 }
1642
1648 template <typename Return>
1653
1657 template <typename Return>
1662
1683 std::string_view braces
1684 = "{}",
1685 size_t max_width = 72);
1686
1708 [[nodiscard]] Bipartition operator*(Bipartition const& x,
1709 Bipartition const& y);
1710
1726 [[nodiscard]] inline bool operator!=(Bipartition const& x,
1727 Bipartition const& y) {
1728 return !(x == y);
1729 }
1730
1736 [[nodiscard]] inline bool operator<=(Bipartition const& x,
1737 Bipartition const& y) {
1738 return x < y || x == y;
1739 }
1740
1747 [[nodiscard]] inline bool operator>(Bipartition const& x,
1748 Bipartition const& y) {
1749 return y < x;
1750 }
1751
1758 [[nodiscard]] inline bool operator>=(Bipartition const& x,
1759 Bipartition const& y) {
1760 return y <= x;
1761 }
1762
1764 // Adapters
1766
1771 template <>
1786 [[nodiscard]] size_t operator()(Bipartition const& x) const noexcept {
1787 return x.degree() * x.degree();
1788 }
1789 };
1790
1791 template <>
1792 struct Degree<Bipartition> {
1793 [[nodiscard]] size_t operator()(Bipartition const& x) const noexcept {
1794 return x.degree();
1795 }
1796 };
1797
1798 template <>
1799 struct Hash<Bipartition> {
1800 [[nodiscard]] size_t operator()(Bipartition const& x) const {
1801 return x.hash_value();
1802 }
1803 };
1804
1805 template <>
1806 struct One<Bipartition> {
1807 [[nodiscard]] Bipartition operator()(Bipartition const& x) const {
1808 return (*this)(x.degree());
1809 }
1810
1811 [[nodiscard]] Bipartition operator()(size_t N = 0) const {
1812 return Bipartition::one(N);
1813 }
1814 };
1815
1816 template <>
1817 struct Product<Bipartition> {
1818 void operator()(Bipartition& xy,
1819 Bipartition const& x,
1820 Bipartition const& y,
1821 size_t thread_id = 0) {
1822 xy.product_inplace_no_checks(x, y, thread_id);
1823 }
1824 };
1825
1826 template <>
1827 struct IncreaseDegree<Bipartition> {
1828 void operator()(Bipartition&, size_t) {}
1829 };
1830
1831} // namespace libsemigroups
1832#endif // LIBSEMIGROUPS_BIPART_HPP_
Class for representing bipartitions.
Definition bipart.hpp:922
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:1072
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:1109
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:947
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:941
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:1128
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:1301
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:1581
std::vector< uint32_t >::iterator iterator
Type of iterators pointing to block lookup.
Definition bipart.hpp:935
bool operator==(Bipartition const &that) const
Compare bipartitions for equality.
Definition bipart.hpp:1054
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:1599
const_iterator cbegin_left_blocks() const noexcept
Const iterator pointing to the index of the first left block.
Definition bipart.hpp:1250
iterator begin() noexcept
Return an iterator pointing to the index of the first block.
Definition bipart.hpp:1199
const_iterator cend() const noexcept
Return a const iterator pointing one beyond the last index of the last block.
Definition bipart.hpp:1216
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:1267
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a value.
Definition bipart.hpp:1168
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:1572
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:1184
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:1091
const_iterator cbegin_right_blocks() const noexcept
Const iterator pointing to the index of the first right block.
Definition bipart.hpp:1284
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:1147
iterator end() noexcept
Return an iterator pointing one beyond the last index of the last block.
Definition bipart.hpp:1233
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:358
Blocks & operator=(Blocks const &)
Default copy assignment operator.
bool operator==(Blocks const &that) const
Compare two blocks objects for equality.
Definition bipart.hpp:597
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:777
Blocks & block_no_checks(size_t i, uint32_t val)
Set the block that a point belongs to.
Blocks & operator=(Blocks &&)
Default move assignment operator.
Blocks() noexcept
Constructs a blocks object of size 0.
bool is_transverse_block(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:544
typename std::vector< uint32_t >::iterator iterator
Type for iterators pointing to the index of the block.
Definition bipart.hpp:372
lookup_const_iterator cend_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:716
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:501
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:733
const_iterator cend() const noexcept
Return a const iterator pointing one past-the-end of the last block.
Definition bipart.hpp:761
std::vector< bool >::const_iterator lookup_const_iterator
Type for const iterators pointing to the transverse block lookup.
Definition bipart.hpp:367
bool is_transverse_block_no_checks(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:524
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:482
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a point.
Definition bipart.hpp:793
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:708
Blocks(Blocks const &copy)
Default copy constructor.
const_iterator cbegin() const noexcept
Return a const iterator pointing to the index of the first block.
Definition bipart.hpp:747
uint32_t rank() const
Return the number of transverse blocks.
uint32_t number_of_blocks() const noexcept
Return the number of blocks in a Blocks object.
Definition bipart.hpp:664
bool operator!=(Blocks const &that) const
Compare two blocks objects for inequality.
Definition bipart.hpp:616
uint32_t degree() const noexcept
Return the degree of a blocks object.
Definition bipart.hpp:648
Blocks(Blocks &&copy)
Default move constructor.
typename std::vector< uint32_t >::const_iterator const_iterator
Type for const iterators pointing to the index of the block.
Definition bipart.hpp:377
Blocks & block(size_t i, uint32_t val)
Set the block that a point belongs to.
std::string to_human_readable_repr(Action< Element, Point, Func, Traits, LeftOrRight > const &action)
Return a human readable representation of an Action object.
bool operator<=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1736
bool operator>=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1758
bool operator>(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1747
Bipartition operator*(Bipartition const &x, Bipartition const &y)
Multiply two bipartitions.
static constexpr bool IsBipartition
Helper variable template.
Definition bipart.hpp:245
bool operator!=(Bipartition const &x, Bipartition const &y)
Check bipartitions for inequality.
Definition bipart.hpp:1726
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
enable_if_is_same< Return, Blocks > make(Container const &cont)
Check the arguments, construct a Blocks object, and check it.
Definition bipart.hpp:855
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:48
T insert(T... args)
T max(T... args)
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.
void uniform_random(Bipartition &x)
Replace the contents of a bipartition with a random bipartition.
void random(Bipartition &x)
Replace the contents of a bipartition with a random bipartition.
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
T size(T... args)
size_t operator()(Bipartition const &x) const noexcept
Definition bipart.hpp:1786
Adapter for the complexity of multiplication.
Definition adapters.hpp:128
Adapter for hashing.
Definition adapters.hpp:453
size_t operator()(Value const &x) const
Hash x using std::hash.
Definition adapters.hpp:462
Adapter for increasing the degree of an element.
Definition adapters.hpp:206
Adapter for the identity element of the given type.
Definition adapters.hpp:253
Adapter for the product of two elements.
Definition adapters.hpp:291