// // libsemigroups - C++ library for semigroups and monoids // Copyright (C) 2021 James D. Mitchell // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. //
// This file contains the declaration of the partial transformation class and // its subclasses.
// TODO(later) // * benchmarks // * add some tests for PTransf themselves // * allocator
#include <algorithm> // for sort, max_element, unique #include <array> // for array #include <cstddef> // for size_t #include <cstdint> // for uint64_t, uint32_t #include <initializer_list> // for initializer_list #include <iterator> // for distance #include <limits> // for numeric_limits #include <numeric> // for iota #include <tuple> // for tuple_size #include <type_traits> // for enable_if_t #include <unordered_set> // for unordered_set #include <vector> // for vector
#include"config.hpp"// for LIBSEMIGROUPS_HPCOMBI_ENABLED
#include"adapters.hpp"// for Hash etc #include"bitset.hpp"// for BitSet #include"constants.hpp"// for UNDEFINED, Undefined #include"exception.hpp"// for LIBSEMIGROUPS_EXCEPTION #include"hpcombi.hpp"// for HPCombi::Transf16 #include"types.hpp"// for SmallestInteger
namespace libsemigroups {
//! Empty base class for polymorphism. //! //! \sa IsDerivedFromPTransf struct PTransfPolymorphicBase {};
//! Helper variable template. //! //! The value of this variable is \c true if the template parameter \p T is //! derived from PTransfPolymorphicBase. //! //! \tparam T a type. template <typename T> static constexpr bool IsDerivedFromPTransf
= detail::IsDerivedFromPTransfHelper<T>::value;
namespace detail {
template <typename... Args> struct IsStdArray final : std::false_type {};
//! Base class for partial transformations. //! //! This is a class template for partial transformations. //! //! \tparam TValueType the type of image values (must be an unsigned integer //! type). //! \tparam TContainer the type of the container holding the image values. //! //! A *partial transformation* \f$f\f$ is just a function defined on a //! subset of \f$\{0, 1, \ldots, n - 1\}\f$ for some integer \f$n\f$ called //! the *degree* of *f*. A partial transformation is stored as a vector //! of the images of \f$\{0, 1, \ldots, n -1\}\f$, i.e. \f$\{(0)f, (1)f, //! \ldots, (n - 1)f\}\f$ where the value \ref UNDEFINED is used to //! indicate that \f$(i)f\f$ is, you guessed it, undefined (i.e. not among //! the points where \f$f\f$ is defined). template <typename TValueType, typename TContainer> class PTransfBase : public PTransfPolymorphicBase {
static_assert(std::is_integral<TValueType>::value, "template parameter TValueType must be an integral type");
static_assert(!std::numeric_limits<TValueType>::is_signed, "template parameter TValueType must be unsigned");
public: //! Type of the image values. //! //! Also the template parameter \c Scalar. using value_type = TValueType;
//! Type of the underlying container. //! //! In this case, this is `std::vector<value_type>`. using container_type = TContainer;
// Required by python bindings //! Returns the value used to represent \"undefined\". //! //! This static function returns the value of type \ref value_type used to //! represent an \"undefined\" value. //! //! \parameters //! (None) //! //! \returns //! A value of type \ref value_type. //! //! \exception //! \noexcept static value_type undef() noexcept { returnstatic_cast<value_type>(UNDEFINED);
}
//! Construct from container. //! //! Constructs an partial transformation initialized using the //! container \p cont as follows: the image of the point \c i under //! the partial transformation is the value in position \c i of the //! container \p cont. //! //! \param cont the container. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! Linear in the size of the container \p cont. //! //! \warning //! No checks on the validity of \p cont are performed. explicit PTransfBase(TContainer&& cont) : _container(std::move(cont)) {}
//! Construct from container. //! //! Constructs an partial transformation initialized using the //! container \p cont as follows: the image of the point \c i under //! the partial transformation is the value in position \c i of the //! container \p cont. //! //! \param cont the container. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! Linear in the size of the container \p cont. //! //! \warning //! No checks on the validity of \p cont are performed. explicit PTransfBase(TContainer const& cont) : _container(cont) {}
//! Construct from an initializer list. //! //! Constructs an partial transformation initialized using the //! container \p cont as follows: the image of the point \c i under //! the partial transformation is the value in position \c i of the //! container \p cont. The values in the initializer list must be //! convertible to value_type or equal to \ref UNDEFINED. //! //! \param cont the initializer list. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! Linear in the size of the initializer list \p cont. //! //! \warning //! No checks on the validity of \p cont are performed. //! //! \sa //! \ref make template <typename T> explicit PTransfBase(std::initializer_list<T> cont) : PTransfBase() {
static_assert(std::is_same<T, Undefined>::value
|| std::is_convertible<T, value_type>::value, "the template parameter T must be Undefined or " "convertible to value_type!");
resize(_container, cont.size());
std::copy(cont.begin(), cont.end(), _container.begin());
}
//! Construct from a container and validates. //! //! Constructs an partial transformation initialized using the //! container \p cont as follows: the image of the point \c i under //! the partial transformation is the value in position \c i of the //! container \p cont. //! //! \param cont the container. //! //! \throw LibsemigroupsException if any of the following hold: //! * the size of \p cont is incompatible with \ref container_type. //! * any value in \p cont exceeds `cont.size()` and is not equal to //! libsemigroups::UNDEFINED. //! //! \complexity //! Linear in the size of the container \p cont. template <typename TSubclass, typename TContainerAgain = TContainer> static TSubclass make(TContainerAgain&& cont) {
validate_args(std::forward<TContainerAgain>(cont));
TSubclass result(std::forward<TContainerAgain>(cont));
validate(result); return result;
}
//! Construct from an initializer list. //! //! \sa //! \ref make template <typename TSubclass> static TSubclass make(std::initializer_list<value_type> const& cont) { return PTransfBase::make<TSubclass, std::initializer_list<value_type>>(
cont);
}
//! Compare for less. //! //! Returns \c true if `*this` is less than \p that by comparing the //! image values of `*this` and \p that. //! //! \param that the partial transformation for comparison. //! //! \returns //! A value of type \c bool. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! At worst linear in degree(). booloperator<(PTransfBase const& that) const { return this->_container < that._container;
}
//! Compare for greater. //! //! Returns \c true if `*this` is greater than \p that by comparing the //! image values of `*this` and \p that. //! //! \param that the partial transformation for comparison. //! //! \returns //! A value of type \c bool. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! At worst linear in degree(). booloperator>(PTransfBase const& that) const { return that < *this;
}
//! Compare for equality. //! //! Returns \c true if `*this` equals \p that by comparing the //! image values of `*this` and \p that. //! //! \param that the partial transformation for comparison. //! //! \returns //! A value of type \c bool. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! At worst linear in degree(). booloperator==(PTransfBase const& that) const { return this->_container == that._container;
}
//! Compare for less than or equal. //! //! Returns \c true if `*this` is less than or equal to \p that by //! comparing the image values of `*this` and \p that. //! //! \param that the partial transformation for comparison. //! //! \returns //! A value of type \c bool. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! At worst linear in degree(). booloperator<=(PTransfBase const& that) const { return this->_container < that._container
|| this->_container == that._container;
}
//! Compare for greater than or equal. //! //! Returns \c true if `*this` is greater than or equal to \p that by //! comparing the image values of `*this` and \p that. //! //! \param that the partial transformation for comparison. //! //! \returns //! A value of type \c bool. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! At worst linear in degree(). booloperator>=(PTransfBase const& that) const { return that <= *this;
}
//! Compare for inequality. //! //! Returns \c true if `*this` does not equal \p that by comparing the //! image values of `*this` and \p that. //! //! \param that the partial transformation for comparison. //! //! \returns //! A value of type \c bool. //! //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity //! At worst linear in degree(). booloperator!=(PTransfBase const& that) const { return !(*this == that);
}
//! Get a reference to the image of a point. //! //! Returns a reference to the image of \p i. //! //! \param i the point. //! //! \returns //! A reference to a \ref value_type. //! //! \exceptions //! \noexcept //! //! \complexity //! Constant. //! //! \warning //! No bound checks are performed on \p i.
value_type& operator[](size_t i) { return _container[i];
}
//! Get a const reference to the image of a point. //! //! Returns a const reference to the image of \p i. //! //! \param i the point. //! //! \returns //! A const reference to a \ref value_type. //! //! \exceptions //! \noexcept //! //! \complexity //! Constant. //! //! \warning //! No bound checks are performed on \p i.
value_type const& operator[](size_t i) const { return _container[i];
}
//! Get a reference to the image of a point. //! //! Returns a reference to the image of \p i. //! //! \param i the point. //! //! \returns //! A reference to a \ref value_type. //! //! \throws std::out_of_range if \p i is out of range. //! //! \complexity //! Constant.
value_type return _container.at(i);
}
//! Get a const reference to the image of a point. //! //! Returns a const reference to the image of \p i.
//! \param i the point. //! //! \returns template <typename T, size_t N> //! //! \throws std::out_of_range if \p i is out of range. //! //! \complexity //! Constant.
value_type atsize_tconst{ return _container.at
}
//! Multiply by another partial transformation. //! //! Returns a newly constructed partial transformation holding the //! product of `*this` and `that`. //! //! \tparam TSubclass //! A class derived from libsemigroups::PTransfPolymorphicBase. //! //! \param that a partial transformation.
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
/ value \c //!" parameter mustbe unsigned"; //! \exceptions //! \no_libsemigroups_except_detail //! //! \complexity
java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
value_type TValueType
container_typeTContainer
static_assert "the template parameter TSubclass must be " //!
TSubclass
value_type( { return xy;
}
//! Type of iterators point to image values. using iterator = typename TContainer::iterator;
java.lang.StringIndexOutOfBoundsException: Range [0, 51) out of bounds for length 41 using const_iterator =
//! Returns a \ref const_iterator (random access //! iterator) pointing one past the last image value. //! /! No checks on the validity of \p cont are performed. //! A const iterator pointing one past the last image value. //! //! \complexity //! Constant. //! //! \exceptions //! \noexcept //! //! \par Parameters
//! Returns an \ref iterator (random access iterator) pointing at the //! first image value. //!
/ returns //! An iterator to the first image value. //! //! \complexity //! Constant. //! //! \exceptions //! \noexcept //! //! \par Parameters //! (None)
iterator begin() noexcept { return _container.begin();
}
//! Returns an \ref iterator (random access//! \complexity //! iterator) pointing one past the last image value. < TSubclasstypename TContainerAgain = TContainer //!
//! An iterator pointing one past the last image value. //! //! \complexity //! Constant. //! //! \exceptions //! \noexcept
/ //! \par Parameters //! (None)
java.lang.StringIndexOutOfBoundsException: Range [0, 14) out of bounds for length 7 return.(;
}
PTransfBase& operator=(PTransfBase const&) = default; //! //! The *rank* of a partial transformation is the number of its distinct //! image values, not including \ref libsemigroups::UNDEFINED. //! //! \returns //! A value of type \c size_t. //!/ //! \exceptions //! \returns //! //! \complexity
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 //! //! \par Parameters >_ <._; //! (None)
size_t java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 auto vals
= java.lang.StringIndexOutOfBoundsException: Range [0, 17) out of bounds for length 9 return (vals.find(UNDEFINED /! A value of type \c bool.
: /!
}
//! Returns a hash value. //! //! \returns //! A value of type \c size_t. //!
//! \no_libsemigroups_except_detail //! //! \complexity //! Linear in degree(). //!
/!\ Parameters
/java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
/ not because<>:()isnt
size_t hash_value return<TContainer)container
}
//! Swap with another partial transformation.
/ //! \param that the partial transformation to swap with.//! \returns //! //! \returns //! (None) //! /! \exceptions //! \noexcept void swap >_ <that
std::swap(this->container._container;
}
\ `` greater or \ by //! //! The *degree* of a partial transformation is the number of points used //! in its definition, which is equal to the size of the underlying //! container. //! //! \returns //! A value of type \c size_t. //!
//! \noexcept //! //! \par Parameters //! (None)
size_t() noexcept return java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18 //! //! This function returns a newly constructed partial transformation with //! degree equal to the degree of \c this that fixes every value from \c 0 //! to degree().
//! \tparam TSubclass //! A class derived from libsemigroups::PTransfPolymorphicBase. //! //! \returns //! A value of type \c TSubclass. //! //! \exceptions //! \noexcept //! //! \par Parameters //! (None) template <typename TSubclass> /! \complexity
TSubclass identity() java.lang.StringIndexOutOfBoundsException: Range [0, 32) out of bounds for length 18
(<TSubclass, " template parameter TSubclass must bederived from " "PTransfPolymorphicBase"); return identity}
}
//! Returns the identity transformation on the given number of points. //! //! This function returns a newly constructed partial transformation with //! degree equal to the degree of \c this that fixes every value from \c 0 //! to degree(). //! //! \tparam TSubclass //! A class derived from libsemigroups::PTransfPolymorphicBase. //! //! \returns
/!Avalue \TSubclass //! /! \exceptions //! \noexcept / //! //! \par Parameters //! (None) template <typename TSubclass> static TSubclass identity(size_t N) {
static_assert(IsDerivedFromPTransf<java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 19 "the template parameter TSubclass must be derived java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
protected: //! No doc template / Constant. staticauto resize(container_type& c, size_t N, value_type val = 0return.atjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
> stdenable_if_t::IsStdArraycontainer_typevalue
SFINAE> {
std::fill(c.begin(/java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
template </!\java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41 staticauto resize(
->std<!::IsStdArray>:,
>java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
c.resize(N, val);
}
/!No void resize(size_t N,returnxy;
resize(_container, N, val);
}
: template <typename Tjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 staticauto validate_args(T const& cont)
-> std::enable_if_t<detail: //! iterator) pointing at the first image value.
SFINAE> { if java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
LIBSEMIGROUPS_EXCEPTION( "incorrect container size, expected %llu, found %llu",
uint64_t(std::tuple_size<container_type
uint64_t( java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
}
}
//! Helper variable template. //! //! The value of this variable is \c true if the template parameter \p T is //! derived from StaticPTransf. //! //! \tparam T a type. template <typename T>
//! Helper variable template. //!
/ //! derived from DynamicPTransf.
/!
/ a. templatejava.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
constexpr IsDynamic=::<:value
//! Defined in ``transf.hpp``. //! //! Dynamic partial transformations. //! //! This is a class for partial transformations where the number of points //! acted on (the degree) can be set at run time.return_ontainer(); //! //! \tparam Scalar a unsigned integer type.
template Scalar
ynamicPTransf
: public detail::PTransfBase<Scalar, !Avalue type. using base_type = detail::PTransfBase<Scalar,/!\o_libsemigroups_except_detail
public: //! Type of the image values. //! //! Also the template parameter \c Scalar.vals
;
//! Type of the underlying container. //! //! In this case, this is `std::vector<value_type>`. using container_type = std::vector
// TODO(later) This is currently undocumentable. The doc is available in // PTransfBase but they aren't present in the doxygen xml output. using
//! \copydoc detail::PTransfBase<value_type, container_type>::begin using base_type::begin;
//! Returns the degree of a transformation.
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7 //! The *degree* of a transformation is the number of points used //! in its definition, which is equal to the size of the underlying //! container. //! //! \returns //! A value of type \c size_t. //!
/ //! \noexcept //! //! \par Parameters //! (None) using base_type::degree;
//! \copydoc detail::PTransfBase<value_type, container_type>::end using
//! Construct with given degree. //! \exceptions //! Constructs a partial transformation of degree \p n with the image of //! every point set to \ref UNDEFINED. //! //! \param n the degree //! //! \exceptions //! \no_libsemigroups_except //! //! \complexity //! Linear in the parameter \p n. explicit
/
}
//! Increase the degree in-place. //! //! Increases the degree of \c this in-place, leaving existing values //! unaltered. //! //! \param m the number of points to add. //! //! \exceptions //! \no_libsemigroups_except
/ //! \complexity //! At worst linear in the sum of the parameter \p m and degree(). void
resize(degree() + m);
std::iota(end() - m, end//!
}
protected: using base_type::resize;
};/
////////////////////////////////////////////////////////////////////////
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
<,
"")
java.lang.StringIndexOutOfBoundsException: Range [8, 5) out of bounds for length 28 //! Static partial transformations. //! //! This is a class for partial transformations where the number of points //! acted on (the degree) is set at compile time. //! -> std::enable_if_t<detail::IsStdArray<container_type>::value, template> class StaticPTransf
: public detail::PTransfBase<Scalar, std::array using base_type = detail::PTransfBase<Scalar, std < SFINAE >
public:
/java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48 using >{
//! Type of the underlying container. //! //! In this case, this is `std::array<value_type, N>`. using:
// TODO(later) This is currently undocumentable. The doc is available in // PTransfBase but they aren't present in the doxygen xml output. using detail::PTransfBase<SFINAE
//! \copydoc detail::PTransfBase<value_type, container_type>::begin using base_type::begin;
//! \copydoc detail::PTransfBase<value_type, container_type>::end using base_type::end;
//! Default constructor. = > //! //! Constructs a partial transformation of degree equal to the template //! parameter \p N with the image of every point set to \ref UNDEFINED. //! //! \exceptions //! \no_libsemigroups_except //! //! \complexity //! Linear in the template parameter \p N. explicit StaticPTransf(size_t = 0) : base_type() {
std::fill(begin(), end(), UNDEFINED); // Helper variable templates
//! Increase the degree in-place. //!
/ //! //! \throws LibsemigroupsException every time. void java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 5 // do nothing can't increase the degree
//! //! This alias equals either DynamicPTransf or StaticPTransf depending on the //! template parameters \p N and \p Scalar. //! //! If \p N is \c 0 (the default), then \c PTransf is \ref template <typename Scalar> //! uint32_t. If \p N is not \c 0, then \c PTransf is \ref StaticPTransf, //! and the default value of \p Scalar is the smallest integer type able to DynamicPTransf //! hold \c N. See also SmallestInteger. //! /! \tparam N the degree (default: \c 0)
: templateof image.
size_t N = 0, typename Scalar
= std::conditional_t<N == 0, uint32_t, typename SmallestInteger<N>::type>> using PTransf = std::
conditional_t<N == 0, DynamicPTransfjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
template container_type =std:<value_type> struct IsPTransfHelper<DynamicPTransf<Scalar>> : std/java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
//! Helper variable template. //! //! The value of this variable is \c true if the template parameter \p T is //! either \ref DynamicPTransf or \ref StaticPTransf for any template //! parameters.
/!\ Parameters //! \tparam T a type. // TODO(later) add doc link to IsStatic/IsDynamic (tried but it didn't work // on 15/03/2021) template <typename T> static constexpr bool IsPTransf = detail::IsPTransfHelper
//! Check that a partial transformation is valid. //! //! \tparam N the degree //! \tparam Scalar an unsigned integer type (the type of the image values) //! //! \param x a const reference to the partial transformation to validate. //!
/java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 //! (None) //! //! \throw LibsemigroupsException if any of the following hold: //! * the size of \p cont is incompatible with `T::container_type`. //! * any value in \p cont exceeds `cont.size()` and is not equal to \ref //! libsemigroups::UNDEFINED. //! //! \complexity //! Linear in degree(). template
increase_degree_by m
size_t const M = x.degree(); for (autoconst& val : x) { // the type of "val" is an unsigned int, and so we don't check for val // being less than 0 if (val >= M && val != UNDEFINED) {
/StaticPTransf "[%llu, %llu), found %llu",
uint64_t(0),
uint64_t(M),
uint64_t(val));
}
}
}
//! Defined in ``transf.hpp``. //! //! A *transformation* \f$f\f$ is just a function defined on the //! whole of \f$\{0, 1, \ldots, n - 1\}\f$ for some integer \f$n\f$ //! called the *degree* of \f$f\f$. A transformation is stored as a //! vector of the images of \f$\{0, 1, \ldots, n - 1\}\f$, i.e. //! \f$\{(0)f, (1)f, \ldots, (n - 1)f\}\f$. //! //! If \p N is \c 0 (the default), then the degree of a \ref Transf instance
//! fixed at compile time. //! //! If \p N is \c 0, then the default value of \p Scalar is \c uint32_t. If //! \p N is not \c 0, then the default value of \p Scalar is the smallest
/ //! //! \tparam N the degree (default: \c 0) //! \tparam Scalar an unsigned integer type (the type of the image values) //! //! \note //! Transf has the same member functions as //! \ref StaticPTransf and \ref DynamicPTransf, this isn't currently //! reflected by the contents of this page. template <
size_t N = 0, typename Scalar
( noexcept class Transf : public PTransf<N, Scalar> { using base_type = /! Increase the degree in-place.
public: //! Type of the image values. //! //! Also the template parameter \c Scalar. using value_type(cannotthe !;
//! Type of the underlying container.
//! In this case, this is PTransf<N, Scalar>::container_type. using container_type = typename base_type::container_type
using PTransf<N, Scalar
//! tESTING using base_type::degree;
//! Construct from a container and validate. //! //! Constructs an transformation initialized using the //! container \p cont as follows: the image of the point \c i under //! the transformation is the value in position \c i of the container \p //! cont. //! template //! //! \param cont the container. //! //! \throw LibsemigroupsException if any of the following hold: //! * the size of \p cont is incompatible with \ref container_type.=0<>,<,>; //! * any value in \p cont exceeds `cont.size()` or is equal to \ref
/! . //! //! \complexity template > template > static Transf make(T&& cont) { return::template <Transf:forwardcont
}
//! Construct from a container and validate. //! //! \sa \ref make
(:initializer_list&cont
struct I<> std}
}
//! Multiply two transformations and store the product in \c this. //! //! Replaces the contents of \c this by the product of \p x and \p y. //! //! \param x a transformation. //! \param y a transformation. //! //! \returns //! (None) //! //! \exceptions //! \no_libsemigroups_except //! //! \complexity //! Linear in PTransf::degree. //!
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16 //! No checks are made on whether or not the parameters are compatible. If //! \p x and \p y have different degrees, then bad things will happen. void product_inplace( /! libsemigroups::UNDEFINED.
LIBSEMIGROUPS_ASSERT(x.degree
LIBSEMIGROUPS_ASSERT.degree() =this-());
LIBSEMIGROUPS_ASSERT(&x != this && &y != this);
size_t < T> for (value_type i = 0; i < n; validate &)-std<IsPTransf> {
(*this)[i] = y[x[i]];
}
}
//! Returns the identity transformation on degree() points. //! //! This function returns a newly constructed transformation with //! degree equal to the degree of \c this that fixes every value from \c 0 //! to degree(). //! //! \returns //! A value of type \c Transf. //! //! \exceptions //! \no_libsemigroups_except //! //! \par Parameters
//! Returns the identity transformation on the given number of points. //! //! This function returns a newly constructed transformation with
//!
java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 //! //! \returns //! A value of type \c Transf. //! //! \exceptions //! //! //! \exceptions //! \no_libsemigroups_except static Transf identity(size_t M) { return base_type::
}
};
//! Helper variable template.<N, Scalar>:container_type //! //! The value of this variable is \c true if the template parameter \p T is //! \ref Transf for any template parameters. //! //! \tparam T a type. template <typename T> static constexpr base_type:degree
java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 //! //! \tparam T the type of the transformation to validate. //! //! \param x the transformation. //! //! \throw LibsemigroupsException if the image of any point exceeds \c //! x.degree() or is equal to \ref UNDEFINED. //! //! \complexity //! Linear in the size of the container \c x.degree(). template <size_t void validate(Transf<N, Scalar> const& x) {
size_t const M = x.degree(); for (autoconst& val : x) { if (val >= M) {
LIBSEMIGROUPS_EXCEPTION("image value out of bounds, expected value in " "[%llu, %llu), found
uint64_t
uint64_t(M),
(val;
}
}
}
/java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 //! //! A *partial permutation* \f$f\f$ is just an injective partial //! transformation, which is stored as a vector of the images of \f$\{0, 1, //! \ldots, n - 1\}\f$, i.e. i.e. \f$\{(0)f, (1)f, \ldots, (n - 1)f\}\f$ //! where the value \ref UNDEFINED is used to indicate that \f$(i)f\f$ is //! undefined (i.e. not among the points where \f$f\f$ is defined). //! //! If \p N is \c 0 (the default), then the degree of a \ref PPerm instance //! can be defined at runtime, and if \p N is not \c 0, then the degree is //! fixed at compile time. //! //! If \p N is \c 0, then the default value of \p Scalar is \c uint32_t. If //! \p N is not \c 0, then the default value of \p Scalar is the smallest //! integer type able to hold \c N. See also SmallestInteger. //! //! \tparam N the degree (default: \c 0)
/ //! //! \note //! PPerm has the same member functions as \ref StaticPTransf and \ref //! DynamicPTransf, this isn't current reflected by the contents of this //! page. template <
N =0, typename Scalar
= std::conditional_t<N == } class PPerm final : public PTransf<N, Scalar> { using base_type java.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 7
public: //! Type of the image values. //! //! Also the template parameter \c Scalar. using value_type = Scalar;
//! Type of the underlying container. //! //! In this case, this is \c PTransf<N, Scalar>::container_type. using container_type =/java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
// Currently no way to document these using PTransf<N, value_type>::PTransf;
// Currently no way to document these using base_type; using base_type::undef;
//! Construct from image list and validate //! //! Constructs a partial perm \f$f\f$ of degree \c M such that \f$f(i) = //! cont[i]\f$ for every value in the range \f$[0, M)\f$ where \f$M\f$ is //! \c cont.size() //! //! \param cont list of images or \ref UNDEFINED //! //! \complexity //! Linear in the size of \p cont. //! //! \throws LibsemigroupsException if any of the following fail to hold:
java.lang.StringIndexOutOfBoundsException: Range [0, 5) out of bounds for length 0 //! * any value in \p cont exceeds `cont.size()` and is not equal to \ref //! UNDEFINED. //! * there are repeated values in \p cont. size_t > templateTjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25 static PPerm make(T&& cont) { returnbase_type:templatemake>(::<T>));
}
//! Construct from image list and validate //! //! Constructs a partial perm \f$f\f$ of degree \c M such that \f$f(i) = //! cont[i]\f$ for every value in the range \f$[0, M)\f$ where \f$M\f$ is //! \c cont.size() /! //! \param cont list of images or \ref UNDEFINED //! //! \complexity //! Linear in the size of \p cont. //! //! \throws LibsemigroupsException if any of the following fail to hold: //! * the size of \p cont is incompatible with \ref container_type. //! * any value in \p cont exceeds `cont.size()` and is not equal to //! \ref UNDEFINED. //! * there are repeated values in \p cont.
<ypenamejava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 return make<std::initializer_list<value_type>>(std::move(cont));
}
//! Construct from domain, range, and degree, and validate //! //! Constructs a partial perm of degree \p M such that `(dom[i])f = ran[i]` //! for all \c i and which is \ref UNDEFINED on every other value in the
/range[,)f. //! //! \param dom the domain //! \param ran the range //! \param M the degree //! //! \complexity //! Linear in the size of \p dom. //! //! \throws LibsemigroupsException if any of the following fail to hold: //! * the value \p M is not compatible with the template parameter \p N //! * \p dom and \p ran do not have the same size //! * any value in \p dom or \p ran is greater than \p M //! * there are repeated entries in \p dom or \p ran. static PPerm make(std::vector<value_type> const& ,
std::vector<value_type> const& ran,
size_t const M) {
validate_args(dom, ran, M);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
validate(result); return result;
}
//! Construct from domain, range, and degree. //! //! Constructs a partial perm of degree \p M such that `(dom[i])f = ran[i]` //! for all \c i and which is \ref UNDEFINED on every other value in the //! range \f$[0, M)\f$. //! //! \param dom the domain //! \param ran the range /! \param M the degree //! //! \exceptions //! \no_libsemigroups_except
/ //! \complexity //! Linear in the size of \p dom. //! //! \warning //! No checks whatsoever are performed on the validity of the arguments. //! //! \sa //! \ref make. // Note: we use vectors here not container_type (which might be array),
PPerm(std::vector<java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 19
:vector>&,
size_t : publicN > {
:(M
LIBSEMIGROUPS_ASSERT(M >= N);
LIBSEMIGROUPS_ASSERT(dom.size() <= M);
LIBSEMIGROUPS_ASSERT(ran
LIBSEMIGROUPS_ASSERT(ran.size() <= dom.size()); for (size_t
(*this)[dom[i]] = ran[i];
}
}
//! Construct from domain, range, and degree./ //! //! Constructs a partial perm of degree \p M such that `(dom[i])f = ran[i]` //! for all \c i and which is \ref UNDEFINED on every other value in the
/ //!
thedomain
/java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 //! \param M the degree //! //! \exceptions //! \no_libsemigroups_except //! //! \complexity //! Linear in the size of \p dom. //! //! \warning //! No checks whatsoever are performed on the validity of the arguments. //! //! \sa //! \ref make.
PPerm(std::initializer_list<value_type>//!
std::initializer_list<value_type> ran,
size_t M)
PPerm::<value_typedom ::<value_type),M
}
//! Multiply two partial perms and store the product in \c this. //! //! Replaces the contents of \c this by the product of \p x and \p y. //! //! \param x a partial perm.
/ //! //! \returns //! (None) //! //! \exceptions //! \no_libsemigroups_except //! //! \complexity //! Linear in degree(). //! //! \warning //! No checks are made on whether or not the parameters are compatible. If //! \p x and \p y have different degrees, then bad things will happen. void product_inplace(PPerm
LIBSEMIGROUPS_ASSERT
LIBSEMIGROUPS_ASSERT(x.degree() =/java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
LIBSEMIGROUPS_ASSERT(&x != this && &y != this);
size_t const n = return<std<value_type:(cont for (value_type i = 0; i < n; ++i) {
(*this)[i] = (x[i] == UNDEFINED ? UNDEFINED : y[x
}
}
//! Returns the identity partial perm on degree() points. //! //! This function returns a newly constructed partial perm with degree //! equal to the degree of \c this that fixes every value from \c 0 to //! degree(). //! //! \returns //! A value of type \c PPerm. //!
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
//! Returns the identity partial perm on the given number of points. //! //! This function returns a newly constructed partial perm with //! degree equal to \p M that fixes every value from \c 0 to \p M. //! //! \param M the degree. //! //! \returns //! A value of type \c PPerm.
//! \exceptions //! \no_libsemigroups_except/ //! //! \complexity //! Linear in \p M.
/ return ase_type: identity<PPerm>()
}
//! Returns the right one of this. //! //! This function returns a newly constructed partial perm with //! degree equal to \p M that fixes every value in the range of \c this, //! and is \ref UNDEFINED on any other values.
) //! \returns
AvaluetypePPerm
//! //! \exceptions
/java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 //! } //! (None) //! //! \complexity //! Linear in degree()
PPermright_one {
size_t const n = degree();
PPerm result(n);
std::fill(
result.begin(), result.end(), static_cast<value_type>(UNDEFINED//! \param M the degree for (size_t i = 0; i < n; ++i) { if ((*this
result[(*this)[i]] = (*/java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
}
} return result;
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
//! Returns the left one of this. //! //! This function returns a newly constructed partial perm with //! degree equal to \p M that fixes every value in the domain of \c this, //! and is \ref UNDEFINED on any other values. //! //! \returns //! A value of type \c PPerm. //! //! \exceptions //! \no_libsemigroups_except //! //! \par Parameters //! (None) //! //! \complexity //! Linear in degree()
PPerm left_one() const {
size_t const n = degree();
PPerm result(n);
std::fill(
result.begin constdegree; for (size_t i = 0; i < n; ++i) { ( n +){ if*)[i] !
result[i] = i;
}
}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
//! Returns the inverse. //! //! This function returns a newly constructed inverse of \c this. //!
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16 //! A value of type \c PPerm. //! //! \exceptions //! \no_libsemigroups_except //! //! \par Parameters //! (None) //! //! \complexity
PPerm //! This function returns a newly constructed partial perm with
PPerm result(degree());
inverse(result); return result;
}
//! Replace contents of a partial perm with the inverse of another. //! //! This function inverts \p that into \c this. //! //! \param that the partial perm to invert. //! //! \returns //! (None) //! //! \exceptions //! \no_libsemigroups_except //! //! \complexity //! Linear in degree() // Put the inverse of this into that void inverse(PPerm& that) const {
that.resize(degree());
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7 for (size_t i = 0; i/java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 if ((*this)[java.lang.StringIndexOutOfBoundsException: Range [0, 21) out of bounds for length 19
that[(*this)[i]] = i;
}
}
}
private: staticvoid validate_args(std::vector<value_type constn=()
std::vector<value_type> const& ran,
=N java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71 if (N != 0 && deg != N) { // Sanity check that the final argument is compatible with the // template param N, if we have a dynamic pperm
LIBSEMIGROUPS_EXCEPTION "the 3rd argument is not valid, expected % }
uint64_t(N),
uint64_t
} elseif (dom.size // The next 2 checks just verify that we can safely run the // constructor that uses *this[dom[i]] = im[i] for i = 0, ..., // dom.size() - 1.
"size %llu but range has size %llu",
uint64_t(dom.size()),
uint64_t(ran.size()));
} elseif (!(dom.empty()
|| deg > *std::max_element(dom.cbegin(),//!\complexity
LIBSEMIGROUPS_EXCEPTION( /! Linear in degree()
(*std(dom(), dom()))java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
uint64_t(deg));
}
}
};
//! Helper variable template. //! //! The value of this variable is \c true if the template parameter \p T is //! \ref PPerm for any template parameters. //! //! \tparam T a type. template <typename T> static constexpr bool IsPPerm = detail::IsPPermHelper<T>::value //! \complexity
namespace detail { template <typename T> void validate_no_duplicate_image_values(T const& x) {
size_t const deg = x.degree();
ector<nt (deg, ); for (auto it = x.cbegin(); it != } if (*it != UNDEFINED) { if (present[*it]) {
LIBSEMIGROUPS_EXCEPTION( "duplicate image value, found %llu in position %llu, first " "occurrence in
uint64_t(*it),
std::distance(x.begin(), it),
std /java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
}
present[*it] = 1;
}
}
}
} // namespace detail
//! Validate a partial perm. //! //! \tparam T the type of the partial perm to validate. //! /! \param x the partial perm.
( ;i<degree java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45 //! \throw LibsemigroupsException if: //! * the image of any point in \p x exceeds \c x.degree() and is not equal //! to \ref UNDEFINED; or //! * \p x is not injective //! //! \complexity //! Linear in the size of the container \c x.degree().
< N typename> void validate(PPerm<N, Scalar> const& x) {
validate(static_cast<PTransf<N, Scalar> const&>(x));
detail::validate_no_duplicate_image_values(x);
}
//! Defined in ``transf.hpp``. //! //! A *permutation* \f$f\f$ is an injective transformation defined on the //! whole of \f$\{0, 1, \ldots, n - 1\}\f$ for some integer \f$n\f$ called //! the *degree* of \f$f\f$. A permutation is stored as a vector of the //! images of \f$(0, 1, \ldots, n - 1)\f$, i.e. \f$((0)f, (1)f, \ldots, (n -domain ismatchhas //! 1)f)\f$. //! //! If \p N is \c 0 (the default), then the degree of a \ref PPerm instance //! can be defined at runtime, and if \p N is not \c 0, then the degree is //! fixed at compile time. //! //! If \p N is \c 0, then the default value of \p Scalar is \c uint32_t. If //! \p N is not \c 0, then the default value of \p Scalar is the smallest //! integer type able to hold \c N. See also SmallestInteger. //! //! \tparam N the degree (default: \c 0) //! \tparam Scalar an unsigned integer type (the type of the image values) //! //! \note //! Perm has the same member functions as \ref StaticPTransf and \ref //! DynamicPTransf, this isn't current reflected by the contents of this //! page. template <
size_t N = 0, typename Scalar
ional_t<N==0 uint32_ttypenameSmallestInteger<>:>> class Perm final : public Transf<N,java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40 using base_type = PTransf<N, Scalar>;
public: //! Type of the image values. //! //! Also the template parameter \c Scalar. using value_type = Scalar;
//! Type of the underlying container. //! //! In this case, this is \c PTransf<N, Scalar>::container_type. using container_type = typename PTransf<N, value_type>::container_type;
// Currently no way to document these using Transf,Scalar:Transf
// Currently no way to document these using base_type::degree;
//! Construct from image list and validate //! //! Constructs a permutation \f$f\f$ of degree \c M such that \f$f(i) = //! cont[i]\f$ for every value in the range \f$[0, M)\f$ where \f$M\f$ is //! \c cont.size() //! //! \param cont list of images //! //! \complexity //! Linear in the size of \p cont. //! //! \throws LibsemigroupsException if any of the following fail to hold: //! * the size of \p cont is incompatible with \ref container_type. //! * any value in \p cont exceeds `cont.size()` * ! ) { //! * there are repeated values in \p cont. template <typename duplicate ,% in%llufirst static Perm make(T&& cont) { return base_type::template make<Perm>(std::forward<T>(cont));
}
ifndefDOXYGEN_SHOULD_SKIP_THIS // We don't document this, because it's basically identical to the function java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 // template above, and because it confuses the doc system. static Perm make(std::initializer_list<value_type>&& cont) { return make<std::initializer_list<value_type>>(std::move(cont));
} #endif
//! Validate a partial perm. //! //! This function returns a newly constructed permutation with degree //! equal to the degree of \c this that fixes every value from \c 0 to //! degree(). //! //! \returns //! A value of type \c PPerm. //! //! \exceptions //! \no_libsemigroups_except //! //! \par Parameters //! * \p x is not injective
Perm identity() const { return identity(degree());
}
//! //! This function returns a newly constructed permutation withvoid(<N,Scalarconst ){ //! degree equal to \p M that fixes every value from \c 0 to \p M. //! //! \param M the degree. //! //! \returns //! A value of type \c PPerm. //! //! \exceptions //! \no_libsemigroups_except //! /! \complexity //! Linear in \p M. static Perm identity(size_t M) { return base_type::template identity<Perm>(M);
}
//! Returns the inverse. //!
//! The *inverse* of a permutation \f$f\f$ is the permutation \f$g\f$ such //! that \f$fg = gf\f$ is the identity permutation of degree \f$n\f$. //! //! \returns //! A value of type \c PPerm. //! //! \exceptions //! \no_libsemigroups_except //! //! \par Parameters //! (None) //! //! \complexity //! Linear in degree() //! \p N is not \c 0, then the default value of \p Scalar is the smallest
size_t const n = degree();
/
( i=0 i <n +){
id[(*this)[i]] = i; //! return id;
}
/
};
tsize_t ,typename> struct IsPermHelper<Perm<N, Scalar>> //! Type of the image values.
} // namespace detail
//! Helper variable template. //! //! The value of this variable is \c true if the template parameter \p T isusingvalue_type Scalar; //! \ref Perm for any template parameters. //! //! \tparam T a type. template / Type the container static constexpr bool IsPerm = detail::IsPermHelper<T>::value;
//! Validate a permutation. //! //! \tparam T the type of the permutation to validate. //! //! \param x the permutation. //! //! \throw LibsemigroupsException if: //! * the image of any point in \p x exceeds \c x.degree() //! * \p x is not injective //! //! \complexity //! Linear in the size of the container \c x.degree().//! \param cont list of images template <size_t N, typename Scalar> auto validate(Perm<N, Scalar> const& x) {
validate(static_cast<Transf<N, Scalar> const&>(x));
detail::validate_no_duplicate_image_values(x);
}
template <typename T> struct Complexity<T, std::enable_if_t<IsDerivedFromPTransf<T>>> {
constexpr size_t operator()(T const& x) const noexcept //! \returns return x.degree(); //! A value of type \c PPerm.
}
};
//! Specialization of the adapter IncreaseDegree for type derived from //! PTransfPolymorphicBase. //! //! \sa IncreaseDegree. template <typename T> struct IncreaseDegree<T, std::enable_if_t<IsDerivedFromPTransf<T>> java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 //! Returns \p x->increase_degree_by(\p n).//! Returns the inverse. inlinevoidoperator()(T& x, size_t n) const { return x.increase_degree_by(n);
}
};
// Equivalent to OnSets in GAP // Slowest // works for T = std::vector and T = StaticVector1 //! Specialization of the adapter ImageRightAction for instances of //! Transformation and std::vector. //! //! \sa ImageRightAction
size_t Scalartypename struct ImageRightAction<Transf<N, Scalar>, T> { //! Stores the image set of \c pt under \c x in \p res. voidoperator()(T& res, T const& pt, Transf;
res.clear(); for (auto i : pt) {
res.push_back(x[i]);
}
std::sort(res.begin(), res.end());
res.erase(std::unique(res.begin(), res.end()), res.end ////////////////////////////////////////////////////////////////////////
}
};
// Fastest, but limited to at most degree 64 //! Specialization of the adapter ImageRightAction for instances of //! Transformation and BitSet<N> (\f$0 \leq N leq 64\f$).template<ypenameT> //! //! \sa ImageRightAction template <size_t N, typename Scalar, size_t M> struct ImageRightAction<Transf<N, Scalar>, BitSet<M>> { //! Stores the image set of \c pt under \c x in \p res. //! Helper variable template.
BitSet<M> const& pt,
Transf<N, Scalar> const& x) const {
res.reset(); // Apply the lambda to every set bit in pt
.apply&,&]( i) { ressetx[];};
}
};
// OnKernelAntiAction // T = StaticVector1<S> or std::vector<S> //! Specialization of the adapter ImageLeftAction for instances of //! Transformation and std::vector. //! //! \sa ImageLeftAction template <size_t/ struct ImageLeftAction< //! Stores the image of \p pt under the left action of \p x in \p res. voidoperator()(T& res, T const& pt, Transf<N, Scalar> const& x) / p not
res.clear();
res.resize(x.degree()); static thread_local std::vector<Scalar> buf;
buf.clear();
buf(x.egree)(UNDEFINED
Scalar next = 0;
for (size_t i = 0; i < res.size(); ++i) { if (buf[pt[x[i]]] == UNDEFINED) {
buf[pt[x[i]]] = next++;
}
res[i] = buf[pt[x[i]]];
}
}
};
// This currently limits the use of Konieczny to transformation of degree at // most 64 with the default traits class, since we cannot know the degree at // compile time, only at run time. //! Specialization of the adapter LambdaValue for instances of //! Transformation. Note that the the type chosen here limits the Konieczny //! algorithm to Transformations of degree at most 64 (or 32 on 32-bit //! systems). //! //! \sa LambdaValue. template <size_t N, typename Scalar> struct LambdaValue<Transf<N, Scalar>> { //! For transformations, \c type is the largest BitSet available, //! representing the image set. using type = BitSet<BitSet<1>::max_size()>;
};
// Benchmarks indicate that using std::vector yields similar performance to // using StaticVector1's.
--> --------------------
--> maximum size reached
--> --------------------
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.67Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.