29 #ifndef PIRANHA_IPOW_SUBSTITUTABLE_SERIES_HPP 30 #define PIRANHA_IPOW_SUBSTITUTABLE_SERIES_HPP 33 #include <type_traits> 37 #include <piranha/mp_integer.hpp> 38 #include <piranha/series.hpp> 39 #include <piranha/symbol_utils.hpp> 48 struct ipow_substitutable_series_tag {
74 template <
typename Series,
typename Derived>
79 template <
typename Term,
typename T>
80 struct subs_term_score {
81 static const unsigned value
86 template <
typename T,
typename Term>
88 = decltype(
math::ipow_subs(std::declval<typename Term::cf_type const &>(), std::declval<std::string const &>(),
89 std::declval<const integer &>(), std::declval<T const &>()));
90 template <
typename T,
typename Term>
91 using ret_type_1 = decltype(std::declval<
const cf_subs_type<T, Term> &>() * std::declval<Derived const &>());
92 template <typename T, typename Term, typename std::enable_if<subs_term_score<Term, T>::value == 1u,
int>::type = 0>
93 static ret_type_1<T, Term> subs_term_impl(
const Term &t,
const symbol_idx &idx,
const std::string &name,
99 tmp.set_symbol_set(s_set);
100 tmp.insert(Term(
typename Term::cf_type(1), t.m_key));
105 template <
typename T,
typename Term>
106 using k_subs_type =
typename decltype(std::declval<const typename Term::key_type &>().
ipow_subs(
107 std::declval<const symbol_idx &>(), std::declval<const integer &>(), std::declval<const T &>(),
108 std::declval<const symbol_fset &>()))::value_type::first_type;
109 template <
typename T,
typename Term>
110 using ret_type_2_ = decltype(std::declval<Derived const &>() * std::declval<
const k_subs_type<T, Term> &>());
111 template <
typename T,
typename Term>
112 using ret_type_2 =
typename std::enable_if<is_addable_in_place<ret_type_2_<T, Term>>::value
113 && std::is_constructible<ret_type_2_<T, Term>,
const int &>::value,
114 ret_type_2_<T, Term>>::type;
115 template <typename T, typename Term, typename std::enable_if<subs_term_score<Term, T>::value == 2u,
int>::type = 0>
116 static ret_type_2<T, Term> subs_term_impl(
const Term &t,
const symbol_idx &idx,
const std::string &name,
121 ret_type_2<T, Term> retval(0);
122 auto ksubs = t.m_key.ipow_subs(idx, n, x, s_set);
123 for (
auto &p : ksubs) {
125 tmp.set_symbol_set(s_set);
126 tmp.insert(Term{t.m_cf, std::move(p.second)});
128 retval += std::move(tmp) * std::move(p.first);
134 template <
typename T,
typename Term>
136 = decltype(std::declval<
const cf_subs_type<T, Term> &>() * std::declval<
const ret_type_2<T, Term> &>());
137 template <typename T, typename Term, typename std::enable_if<subs_term_score<Term, T>::value == 3u,
int>::type = 0>
138 static ret_type_3<T, Term> subs_term_impl(
const Term &t,
const symbol_idx &idx,
const std::string &name,
143 ret_type_2<T, Term> acc(0);
144 auto ksubs = t.m_key.ipow_subs(idx, n, x, s_set);
146 for (
auto &p : ksubs) {
148 tmp.set_symbol_set(s_set);
149 tmp.insert(Term(
typename Term::cf_type(1), std::move(p.second)));
151 acc += std::move(tmp) * std::move(p.first);
153 return std::move(cf_subs) * std::move(acc);
156 template <
typename T>
157 using subs_type_ = decltype(subs_term_impl(std::declval<typename Series::term_type const &>(),
158 std::declval<const symbol_idx &>(), std::declval<const std::string &>(),
159 std::declval<const integer &>(), std::declval<const T &>(),
160 std::declval<symbol_fset const &>()));
162 template <
typename T>
163 using ipow_subs_type = enable_if_t<
167 template <
typename Int>
168 using ipow_subs_int_enabler = enable_if_t<std::is_integral<Int>::value,
int>;
223 template <
typename T>
226 const auto idx =
ss_index_of(this->m_symbol_set, name);
227 ipow_subs_type<T> retval(0);
228 for (
const auto &t : this->m_container) {
229 retval += subs_term_impl(t, idx, name, n, x, this->m_symbol_set);
251 template <
typename T,
typename Int, ipow_subs_
int_enabler<Int> = 0>
252 ipow_subs_type<T>
ipow_subs(
const std::string &name,
const Int &n,
const T &x)
const 258 inline namespace impl
262 template <
typename Series,
typename T>
263 using ipow_subs_mem_t = decltype(std::declval<const Series &>().ipow_subs(
264 std::declval<const std::string &>(), std::declval<const integer &>(), std::declval<const T &>()));
266 template <
typename Series,
typename T>
267 using ipow_subs_impl_ipow_subs_series_enabler
268 = enable_if_t<conjunction<std::is_base_of<ipow_substitutable_series_tag, Series>,
269 is_detected<ipow_subs_mem_t, Series, T>>::value>;
280 template <
typename Series,
typename T>
281 struct ipow_subs_impl<Series, T, ipow_subs_impl_ipow_subs_series_enabler<Series, T>> {
296 -> decltype(s.ipow_subs(name, n, x))
298 return s.ipow_subs(name, n, x);
Multiprecision integer class.
mp_integer< 1 > integer
Alias for piranha::mp_integer with 1 limb of static storage.
In-place addable type trait.
#define PIRANHA_FORWARDING_CTOR(Derived, Base)
Constructor-forwarding macro.
Default functor for the implementation of piranha::math::ipow_subs().
boost::container::flat_set< std::string > symbol_fset
Flat set of symbols.
auto operator()(const Series &s, const std::string &name, const integer &n, const T &x) const -> decltype(s.ipow_subs(name, n, x))
Call operator.
symbol_fset::size_type symbol_idx
Symbol index.
symbol_idx ss_index_of(const symbol_fset &ref, const std::string &name)
Identify the index of a symbol in a symbol_fset.
ipow_subs_type< T > ipow_subs(const std::string &name, const Int &n, const T &x) const
Substitution.
ipow_subs_type< T > ipow_subs(const std::string &name, const integer &n, const T &x) const
Substitution.
Type trait to detect the presence of the integral power substitution method in keys.
ipow_substitutable_series()=default
Defaulted default constructor.
Toolbox for series suitable for integral power substitution.
ipow_substitutable_series & operator=(const ipow_substitutable_series &other)=default
Copy assignment operator.
#define PIRANHA_TT_CHECK(tt,...)
Macro for static type trait checks.
~ipow_substitutable_series()
Trivial destructor.
Type trait to detect series types.
Type trait to detect the availability of the piranha::math::ipow_subs() function. ...
#define PIRANHA_FORWARDING_ASSIGNMENT(Derived, Base)
Assignment-forwarding macro.
math_ipow_subs_t< T, U > ipow_subs(const T &x, const std::string &name, const integer &n, const U &y)
Substitution of integral power.