29 #ifndef PIRANHA_MONOMIAL_HPP 30 #define PIRANHA_MONOMIAL_HPP 37 #include <initializer_list> 45 #include <type_traits> 49 #include <piranha/array_key.hpp> 50 #include <piranha/config.hpp> 51 #include <piranha/detail/cf_mult_impl.hpp> 52 #include <piranha/detail/monomial_common.hpp> 53 #include <piranha/detail/prepare_for_print.hpp> 54 #include <piranha/detail/safe_integral_adder.hpp> 57 #include <piranha/is_cf.hpp> 58 #include <piranha/is_key.hpp> 59 #include <piranha/math.hpp> 60 #include <piranha/mp_integer.hpp> 61 #include <piranha/mp_rational.hpp> 62 #include <piranha/pow.hpp> 63 #include <piranha/s11n.hpp> 64 #include <piranha/safe_cast.hpp> 65 #include <piranha/symbol_utils.hpp> 66 #include <piranha/term.hpp> 99 template <
typename T,
typename S = std::
integral_constant<std::
size_t, 0u>>
105 PIRANHA_TT_CHECK(std::is_copy_assignable, T);
108 template <
typename U>
109 using comparison_enabler =
typename std::enable_if<is_less_than_comparable<U>::value,
int>::type;
123 template <
typename U>
124 using init_list_enabler = enable_if_t<std::is_constructible<base, std::initializer_list<U>>::value,
int>;
136 template <
typename U, init_list_enabler<U> = 0>
143 template <
typename Iterator>
144 using it_ctor_enabler
145 = enable_if_t<conjunction<is_input_iterator<Iterator>,
146 has_safe_cast<T,
typename std::iterator_traits<Iterator>::value_type>>::value,
166 template <
typename Iterator, it_ctor_enabler<Iterator> = 0>
193 template <
typename Iterator, it_ctor_enabler<Iterator> = 0>
196 if (unlikely(this->
size() != s.size())) {
197 piranha_throw(std::invalid_argument,
"the monomial constructor from range and symbol set " 198 "yielded an invalid monomial: the final size is " 199 + std::to_string(this->
size())
200 +
", while the size of the symbol set is " 201 + std::to_string(s.size()));
237 return this->
size() == args.size();
263 if (unlikely(args.size() != std::get<0>(sbe))) {
265 "invalid sizes in the invocation of is_unitary() for a monomial: the monomial has a size of " 266 + std::to_string(std::get<0>(sbe)) +
", while the reference symbol set has a size of " 267 + std::to_string(args.size()));
269 return std::all_of(std::get<1>(sbe), std::get<2>(sbe), [](
const T &element) {
return math::is_zero(element); });
274 template <
typename U>
275 using degree_type = enable_if_t<conjunction<std::is_constructible<add_t<U, U>,
int>,
279 template <typename U, enable_if_t<std::is_integral<U>::value,
int> = 0>
280 static void expo_add(degree_type<U> &retval,
const U &n)
282 detail::safe_integral_adder(retval,
static_cast<degree_type<U>
>(n));
284 template <typename U, enable_if_t<!std::is_integral<U>::value,
int> = 0>
285 static void expo_add(degree_type<U> &retval,
const U &x)
312 template <
typename U = T>
316 if (unlikely(args.size() != std::get<0>(sbe))) {
318 std::invalid_argument,
319 "invalid symbol set for the computation of the degree of a monomial: the size of the symbol set (" 320 + std::to_string(args.size()) +
") differs from the size of the monomial (" 321 + std::to_string(std::get<0>(sbe)) +
")");
323 degree_type<U> retval(0);
324 for (; std::get<1>(sbe) != std::get<2>(sbe); ++std::get<1>(sbe)) {
325 expo_add(retval, *std::get<1>(sbe));
356 template <
typename U = T>
360 if (unlikely(args.size() != std::get<0>(sbe))) {
361 piranha_throw(std::invalid_argument,
"invalid symbol set for the computation of the partial degree of a " 362 "monomial: the size of the symbol set (" 363 + std::to_string(args.size())
364 +
") differs from the size of the monomial (" 365 + std::to_string(std::get<0>(sbe)) +
")");
367 if (unlikely(p.size() && *p.rbegin() >= args.size())) {
368 piranha_throw(std::invalid_argument,
"the largest value in the positions set for the computation of the " 369 "partial degree of a monomial is " 370 + std::to_string(*p.rbegin())
371 +
", but the monomial has a size of only " 372 + std::to_string(args.size()));
374 degree_type<U> retval(0);
375 for (
const auto &i : p) {
376 expo_add(retval, std::get<1>(sbe)[i]);
388 template <
typename U = T>
402 template <
typename U = T>
424 if (unlikely(args.size() != std::get<0>(sbe))) {
425 piranha_throw(std::invalid_argument,
"invalid symbol set for the identification of a linear " 426 "monomial: the size of the symbol set (" 427 + std::to_string(args.size())
428 +
") differs from the size of the monomial (" 429 + std::to_string(std::get<0>(sbe)) +
")");
433 for (
size_type i = 0u; i < std::get<0>(sbe); ++i, ++std::get<1>(sbe)) {
445 piranha_assert(std::get<1>(sbe) == std::get<2>(sbe));
446 if (n_linear != 1u) {
449 return std::make_pair(
true,
symbol_idx{candidate});
454 template <
typename U>
455 using pow_enabler = monomial_pow_enabler<T, U>;
488 template <
typename U, pow_enabler<U> = 0>
492 if (unlikely(args.size() != std::get<0>(sbe))) {
493 piranha_throw(std::invalid_argument,
"invalid symbol set for the exponentiation of a " 494 "monomial: the size of the symbol set (" 495 + std::to_string(args.size())
496 +
") differs from the size of the monomial (" 497 + std::to_string(std::get<0>(sbe)) +
")");
501 for (decltype(retval.
size()) i = 0u; i < std::get<0>(sbe); ++i, ++std::get<1>(sbe)) {
502 monomial_pow_mult_exp(retval[i], *std::get<1>(sbe), x, monomial_pow_dispatcher<T, U>{});
510 template <
typename U>
511 using dec_t = decltype(--std::declval<U &>());
513 template <
typename U>
514 using monomial_partial_dispatcher = disjunction_idx<
518 is_detected<dec_t, U>>;
520 template <
typename U>
521 static void ip_dec(U &x,
const std::integral_constant<std::size_t, 0u> &)
524 if (unlikely(x == std::numeric_limits<U>::min())) {
525 piranha_throw(std::overflow_error,
"negative overflow error in the calculation of the " 526 "partial derivative of a monomial");
528 x =
static_cast<U
>(x - U(1));
530 template <
typename U>
531 static void ip_dec(U &x,
const std::integral_constant<std::size_t, 1u> &)
536 template <
typename U>
537 using partial_enabler = enable_if_t<(monomial_partial_dispatcher<U>::value < 2u),
int>;
565 template <
typename U = T, partial_enabler<U> = 0>
569 if (unlikely(args.size() != std::get<0>(sbe))) {
571 "invalid symbol set for the computation of the partial derivative of a " 572 "monomial: the size of the symbol set (" 573 + std::to_string(args.size()) +
") differs from the size of the monomial (" 574 + std::to_string(std::get<0>(sbe)) +
")");
576 if (p >= std::get<0>(sbe) ||
math::is_zero(std::get<1>(sbe)[p])) {
579 return std::make_pair(T(0),
monomial{args});
582 T expo(std::get<1>(sbe)[p]);
586 ip_dec(m[static_cast<typename base::size_type>(p)], monomial_partial_dispatcher<U>{});
588 return std::make_pair(std::move(expo), std::move(m));
594 template <
typename U>
595 using inc_t = decltype(++std::declval<U &>());
597 template <
typename U>
598 using monomial_int_dispatcher = disjunction_idx<
602 is_detected<inc_t, U>>;
604 template <
typename U>
605 static void ip_inc(U &x,
const std::integral_constant<std::size_t, 0u> &)
608 if (unlikely(x == std::numeric_limits<U>::max())) {
609 piranha_throw(std::overflow_error,
"positive overflow error in the calculation of the " 610 "antiderivative of a monomial");
612 x =
static_cast<U
>(x + U(1));
614 template <
typename U>
615 static void ip_inc(U &x,
const std::integral_constant<std::size_t, 1u> &)
620 template <
typename U>
621 using integrate_enabler = enable_if_t<(monomial_int_dispatcher<U>::value < 2u),
int>;
653 template <
typename U = T,
integrate_enabler<U> = 0>
657 if (unlikely(args.size() != std::get<0>(sbe))) {
658 piranha_throw(std::invalid_argument,
"invalid symbol set for the computation of the antiderivative of a " 659 "monomial: the size of the symbol set (" 660 + std::to_string(args.size())
661 +
") differs from the size of the monomial (" 662 + std::to_string(std::get<0>(sbe)) +
")");
666 const PIRANHA_MAYBE_TLS T one(1);
667 auto it_args = args.begin();
668 for (decltype(retval.
size()) i = 0; std::get<1>(sbe) != std::get<2>(sbe); ++i, ++std::get<1>(sbe), ++it_args) {
669 const auto &cur_sym = *it_args;
681 auto &ref = retval[i];
683 ip_inc(ref, monomial_int_dispatcher<U>{});
686 "unable to perform monomial integration: a negative " 687 "unitary exponent was encountered in correspondence of the variable '" 698 return std::make_pair(std::move(expo), std::move(retval));
704 template <typename U, enable_if_t<is_mp_rational<U>::value,
int> = 0>
705 static void print_exponent(std::ostream &os,
const U &e)
710 os <<
'(' << e <<
')';
713 template <typename U, enable_if_t<!is_mp_rational<U>::value,
int> = 0>
714 static void print_exponent(std::ostream &os,
const U &e)
716 os << detail::prepare_for_print(e);
735 if (unlikely(args.size() != std::get<0>(sbe))) {
737 "cannot print monomial: the size of the symbol set (" + std::to_string(args.size())
738 +
") differs from the size of the monomial (" + std::to_string(std::get<0>(sbe)) +
")");
740 bool empty_output =
true;
741 auto it_args = args.begin();
742 for (decltype(args.size()) i = 0; std::get<1>(sbe) != std::get<2>(sbe); ++i, ++std::get<1>(sbe), ++it_args) {
750 empty_output =
false;
753 print_exponent(os, *std::get<1>(sbe));
774 if (unlikely(args.size() != std::get<0>(sbe))) {
775 piranha_throw(std::invalid_argument,
"cannot print monomial in TeX mode: the size of the symbol set (" 776 + std::to_string(args.size())
777 +
") differs from the size of the monomial (" 778 + std::to_string(std::get<0>(sbe)) +
")");
780 std::ostringstream oss_num, oss_den, *cur_oss;
781 const PIRANHA_MAYBE_TLS T zero(0);
783 auto it_args = args.begin();
784 for (decltype(args.size()) i = 0; std::get<1>(sbe) != std::get<2>(sbe); ++i, ++std::get<1>(sbe), ++it_args) {
785 cur_value = *std::get<1>(sbe);
790 if (zero < cur_value) {
791 cur_oss = std::addressof(oss_num);
794 cur_oss = std::addressof(oss_den);
796 *cur_oss <<
"{" << *it_args <<
"}";
798 *cur_oss <<
"^{" << detail::prepare_for_print(cur_value) <<
"}";
802 const std::string num_str = oss_num.str(), den_str = oss_den.str();
803 if (!num_str.empty() && !den_str.empty()) {
804 os <<
"\\frac{" << num_str <<
"}{" << den_str <<
"}";
805 }
else if (!num_str.empty() && den_str.empty()) {
807 }
else if (num_str.empty() && !den_str.empty()) {
808 os <<
"\\frac{1}{" << den_str <<
"}";
814 template <
typename U>
816 = enable_if_t<conjunction<is_multipliable_in_place<pow_t<U, T>>, std::is_constructible<pow_t<U, T>,
int>,
845 template <
typename U>
849 if (unlikely(args.size() != std::get<0>(sbe))) {
851 "cannot evaluate monomial: the size of the symbol set (" + std::to_string(args.size())
852 +
") differs from the size of the monomial (" + std::to_string(std::get<0>(sbe)) +
")");
854 if (unlikely(values.size() != std::get<0>(sbe))) {
856 "cannot evaluate monomial: the size of the vector of values (" + std::to_string(values.size())
857 +
") differs from the size of the monomial (" + std::to_string(std::get<0>(sbe)) +
")");
860 eval_type<U> retval(
math::pow(values[0], *std::get<1>(sbe)++));
861 for (decltype(values.size()) i = 1; i < values.size(); ++i, ++std::get<1>(sbe)) {
865 retval *=
math::pow(values[i], *std::get<1>(sbe));
867 piranha_assert(std::get<1>(sbe) == std::get<2>(sbe));
870 return eval_type<U>(1);
875 template <
typename U>
876 using subs_type = eval_type<U>;
914 template <
typename U>
918 if (unlikely(args.size() != std::get<0>(sbe))) {
920 "cannot perform substitution in a monomial: the size of the symbol set (" 921 + std::to_string(args.size()) +
") differs from the size of the monomial (" 922 + std::to_string(std::get<0>(sbe)) +
")");
924 if (unlikely(smap.size() && smap.rbegin()->first >= std::get<0>(sbe))) {
927 "invalid argument(s) for substitution in a monomial: the last index of the substitution map (" 928 + std::to_string(smap.rbegin()->first) +
") must be smaller than the monomial's size (" 929 + std::to_string(std::get<0>(sbe)) +
")");
931 std::vector<std::pair<subs_type<U>,
monomial>> retval;
935 const PIRANHA_MAYBE_TLS T zero(0);
937 auto it = smap.begin();
938 auto ret(
math::pow(it->second, std::get<1>(sbe)[it->first]));
942 mon_ret[
static_cast<decltype(mon_ret.
size())
>(it->first)] = zero;
944 for (++it; it != smap.end(); ++it) {
945 ret *=
math::pow(it->second, std::get<1>(sbe)[it->first]);
946 mon_ret[
static_cast<decltype(mon_ret.
size())
>(it->first)] = zero;
950 retval.emplace_back(std::move(ret), std::move(mon_ret));
953 retval.emplace_back(subs_type<U>(1), *
this);
961 template <
typename U>
962 using ipow_subs_d_assign_dispatcher = disjunction_idx<
964 disjunction<std::is_integral<U>, std::is_same<integer, U>>,
967 template <
typename U>
968 static void ipow_subs_d_assign(
integer &d,
const U &expo,
const std::integral_constant<std::size_t, 0> &)
972 template <
typename U>
973 static void ipow_subs_d_assign(
integer &d,
const U &expo,
const std::integral_constant<std::size_t, 1> &)
978 template <
typename U>
979 using ipow_subs_expo_assign_dispatcher = disjunction_idx<
981 std::is_same<integer, U>,
984 template <
typename U>
985 static void ipow_subs_expo_assign(U &expo,
const integer &r,
const std::integral_constant<std::size_t, 0> &)
989 template <
typename U>
990 static void ipow_subs_expo_assign(U &expo,
const integer &r,
const std::integral_constant<std::size_t, 1> &)
995 template <
typename U>
996 using ips_type = decltype(
math::pow(std::declval<const U &>(), std::declval<const integer &>()));
998 template <
typename U>
1000 = enable_if_t<conjunction<std::is_constructible<ips_type<U>,
int>, is_returnable<ips_type<U>>>::value
1001 && (ipow_subs_d_assign_dispatcher<T>::value < 2u)
1002 && (ipow_subs_expo_assign_dispatcher<T>::value < 2u),
1043 template <
typename U>
1047 if (unlikely(this->
size() != args.size())) {
1049 "cannot perform integral power substitution in a monomial: the size of the symbol set (" 1050 + std::to_string(args.size()) +
") differs from the size of the monomial (" 1051 + std::to_string(this->
size()) +
")");
1053 if (unlikely(!n.
sgn())) {
1055 "invalid integral power for ipow_subs() in a monomial: the power must be nonzero");
1058 std::vector<std::pair<ipow_subs_type<U>,
monomial>> retval;
1060 if (p < args.size()) {
1061 auto &expo = mon[
static_cast<decltype(mon.
size())
>(p)];
1062 PIRANHA_MAYBE_TLS
integer q, r, d;
1064 ipow_subs_d_assign(d, expo, ipow_subs_d_assign_dispatcher<T>{});
1073 tdiv_qr(q, r, d, n);
1077 ipow_subs_expo_assign(expo, r, ipow_subs_expo_assign_dispatcher<T>{});
1078 retval.emplace_back(
math::pow(x, q), std::move(mon));
1083 retval.emplace_back(ipow_subs_type<U>(1), std::move(mon));
1089 template <
typename Cf>
1090 using multiply_enabler = enable_if_t<conjunction<has_add3<T>,
has_mul3<Cf>>::value,
int>;
1115 template <
typename Cf, multiply_enabler<Cf> = 0>
1121 if (unlikely(t1.
m_key.size() != args.size())) {
1123 "cannot multiply terms with monomial keys: the size of the symbol set (" 1124 + std::to_string(args.size()) +
") differs from the size of the first monomial (" 1125 + std::to_string(t1.
m_key.size()) +
")");
1147 if (unlikely(std::get<0u>(sbe1) != std::get<0u>(sbe2))) {
1149 "mismatched sizes in a monomial comparison: the first monomial has a size of " 1150 + std::to_string(std::get<0u>(sbe1)) +
", the second monomial has a size of " 1151 + std::to_string(std::get<0u>(sbe2)));
1153 return std::lexicographical_compare(std::get<1u>(sbe1), std::get<2u>(sbe1), std::get<1u>(sbe2),
1154 std::get<2u>(sbe2));
1158 #if !defined(PIRANHA_DOXYGEN_INVOKED) 1160 template <
typename Archive,
typename T1,
typename S1>
1163 template <
typename Archive,
typename T1,
typename S1>
1167 #if defined(PIRANHA_WITH_MSGPACK) 1169 template <
typename Stream>
1170 using msgpack_pack_enabler = enable_if_t<
1172 template <
typename U>
1173 using msgpack_convert_enabler = enable_if_t<has_msgpack_convert<typename U::container_type>::value,
int>;
1191 template <
typename Stream, msgpack_pack_enabler<Stream> = 0>
1194 if (unlikely(this->
size() != s.size())) {
1195 piranha_throw(std::invalid_argument,
"incompatible symbol set in monomial serialization: the reference " 1196 "symbol set has a size of " 1197 + std::to_string(s.size())
1198 +
", while the monomial being serialized has a size of " 1199 + std::to_string(this->
size()));
1218 template <
typename U = monomial, msgpack_convert_enabler<U> = 0>
1222 if (unlikely(this->
size() != s.size())) {
1223 piranha_throw(std::invalid_argument,
"incompatible symbol set in monomial serialization: the reference " 1224 "symbol set has a size of " 1225 + std::to_string(s.size())
1226 +
", while the monomial being deserialized has a size of " 1227 + std::to_string(this->
size()));
1233 template <
typename T,
typename S>
1240 namespace serialization
1243 template <
typename Archive,
typename T,
typename S>
1246 if (unlikely(k.key().size() != k.ss().size())) {
1247 piranha_throw(std::invalid_argument,
"incompatible symbol set in monomial serialization: the reference " 1248 "symbol set has a size of " 1249 + std::to_string(k.ss().size())
1250 +
", while the monomial being serialized has a size of " 1251 + std::to_string(k.key().size()));
1256 template <
typename Archive,
typename T,
typename S>
1260 if (unlikely(k.key().size() != k.ss().size())) {
1261 piranha_throw(std::invalid_argument,
"incompatible symbol set in monomial serialization: the reference " 1262 "symbol set has a size of " 1263 + std::to_string(k.ss().size())
1264 +
", while the monomial being deserialized has a size of " 1265 + std::to_string(k.key().size()));
1269 template <
typename Archive,
typename T,
typename S>
1272 split_free(ar, k, version);
1280 inline namespace impl
1284 template <
typename Archive,
typename T,
typename S>
1285 using monomial_boost_save_enabler
1286 = enable_if_t<has_boost_save<Archive, typename monomial<T, S>::container_type>::value>;
1288 template <
typename Archive,
typename T,
typename S>
1289 using monomial_boost_load_enabler
1290 = enable_if_t<has_boost_load<Archive, typename monomial<T, S>::container_type>::value>;
1302 template <
typename Archive,
typename T,
typename S>
1317 template <
typename Archive,
typename T,
typename S>
1330 template <
typename T,
typename S>
1331 struct hash<
piranha::monomial<T, S>> :
public hash<piranha::array_key<T, piranha::monomial<T, S>, S>> {
math_pow_t< T, U > pow(const T &x, const U &y)
Exponentiation.
bool is_unitary(const symbol_fset &args) const
Check if the monomial is unitary.
void msgpack_convert(const msgpack::object &o, msgpack_format f, const symbol_fset &s)
Deserialize from msgpack object.
Cf m_cf
Coefficient member.
void print(std::ostream &os, const symbol_fset &args) const
Print.
void boost_load(Archive &ar, T &x)
Load from Boost archive.
Multiprecision integer class.
Default implementation of piranha::boost_load().
mp_integer< 1 > integer
Alias for piranha::mp_integer with 1 limb of static storage.
void msgpack_convert(T &x, const msgpack::object &o, msgpack_format f)
Convert msgpack object.
std::vector< std::pair< ipow_subs_type< U >, monomial > > ipow_subs(const symbol_idx &p, const integer &n, const U &x, const symbol_fset &args) const
Substitution of integral power.
monomial()=default
Defaulted default constructor.
monomial(Iterator begin, Iterator end, const symbol_fset &s)
Constructor from range and symbol set.
monomial(Iterator begin, Iterator end)
Constructor from range.
void print_tex(std::ostream &os, const symbol_fset &args) const
Print in TeX mode.
monomial(std::initializer_list< U > list)
Constructor from initializer list.
monomial pow(const U &x, const symbol_fset &args) const
Monomial exponentiation.
bool is_compatible(const symbol_fset &args) const noexcept
Compatibility check.
Implementation of piranha::boost_load() via the Boost API.
container_type m_container
Internal container.
Type trait to detect the presence of the piranha::math::is_unitary() function.
In-place addable type trait.
bool is_zero(const symbol_fset &) const noexcept
Zero check.
Default implementation of piranha::boost_save().
void negate(T &x)
In-place negation.
Type trait to detect the presence of the piranha::math::negate function.
#define PIRANHA_FORWARDING_CTOR(Derived, Base)
Constructor-forwarding macro.
degree_type< U > degree(const symbol_idx_fset &p, const symbol_fset &args) const
Partial degree.
std::vector< std::pair< subs_type< U >, monomial > > subs(const symbol_idx_fmap< U > &smap, const symbol_fset &args) const
Substitution.
degree_type< U > ldegree(const symbol_idx_fset &p, const symbol_fset &args) const
Partial low degree (equivalent to the partial degree).
#define piranha_throw(exception_type,...)
Exception-throwing macro.
std::pair< T, monomial > partial(const symbol_idx &p, const symbol_fset &args) const
Partial derivative.
boost::container::flat_set< std::string > symbol_fset
Flat set of symbols.
auto size_begin_end() const -> decltype(m_container.size_begin_end())
Get size, begin and end iterator (const version).
Wrapper for the serialization of keys via Boost.
msgpack_format
Serialization format for msgpack.
Detect if type can be returned from a function.
std::pair< T, monomial > integrate(const std::string &s, const symbol_fset &args) const
Integration.
monomial & operator=(const monomial &other)=default
Copy assignment operator.
static void multiply(std::array< term< Cf, monomial >, multiply_arity > &res, const term< Cf, monomial > &t1, const term< Cf, monomial > &t2, const symbol_fset &args)
Multiply terms with a monomial key.
typename container_type::size_type size_type
Size type.
symbol_fset::size_type symbol_idx
Symbol index.
bool is_zero(const T &x)
Zero test.
bool operator<(const monomial &other) const
Comparison operator.
boost::container::flat_map< symbol_idx, T > symbol_idx_fmap
Flat map of symbol indices.
Implementation of piranha::boost_save() via the Boost API.
eval_type< U > evaluate(const std::vector< U > &values, const symbol_fset &args) const
Evaluation.
void msgpack_pack(msgpack::packer< Stream > &packer, const T &x, msgpack_format f)
Pack generic object in a msgpack stream.
Detect the presence of piranha::msgpack_pack().
degree_type< U > ldegree(const symbol_fset &args) const
Low degree (equivalent to the degree).
std::pair< bool, symbol_idx > is_linear(const symbol_fset &args) const
Detect linear monomial.
boost::container::flat_set< symbol_idx > symbol_idx_fset
Flat set of symbol indices.
Type trait to detect piranha::safe_cast().
void boost_save(Archive &ar, const T &x)
Save to Boost archive.
Type trait for classes that can be output-streamed.
Detect piranha::math::mul3().
static const std::size_t multiply_arity
Arity of the multiply() method.
iterator begin()
Begin iterator.
void msgpack_pack(msgpack::packer< Stream > &packer, msgpack_format f, const symbol_fset &s) const
Serialize in msgpack format.
void push_back(value_type &&x)
Move-add element at the end.
size_type size() const
Size.
iterator end()
End iterator.
degree_type< U > degree(const symbol_fset &args) const
Degree.
safe_cast_type< To, From > safe_cast(const From &x)
Safe cast.
bool is_unitary(const T &x)
Unitary test.