29 #ifndef PIRANHA_T_SUBSTITUTABLE_SERIES_HPP 30 #define PIRANHA_T_SUBSTITUTABLE_SERIES_HPP 33 #include <type_traits> 37 #include <piranha/math.hpp> 38 #include <piranha/series.hpp> 39 #include <piranha/symbol_utils.hpp> 49 struct t_substitutable_series_tag {
78 template <
typename Series,
typename Derived>
83 template <
typename Term,
typename T,
typename U>
84 struct t_subs_term_score {
85 static const unsigned value
89 template <
typename T,
typename U,
typename Term =
typename Series::term_type,
typename =
void>
91 static_assert(t_subs_term_score<Term, T, U>::value == 0u,
"Wrong t_subs_term_score value.");
94 template <
typename T,
typename U,
typename Term>
95 struct t_subs_utils<T, U, Term, enable_if_t<t_subs_term_score<Term, T, U>::value == 1u>> {
96 template <
typename T1,
typename U1,
typename Term1>
97 using return_type_ = decltype(
math::t_subs(std::declval<typename Term1::cf_type const &>(),
98 std::declval<std::string const &>(), std::declval<T1 const &>(),
99 std::declval<U1 const &>())
100 * std::declval<Derived const &>());
101 template <
typename T1,
typename U1,
typename Term1>
102 using return_type = enable_if_t<std::is_constructible<return_type_<T1, U1, Term1>,
int>::value
104 return_type_<T1, U1, Term1>>;
105 template <
typename T1,
typename U1,
typename Term1>
106 static return_type<T1, U1, Term1> subs(
const Term1 &t,
const std::string &name,
const symbol_idx &,
const T1 &c,
110 tmp.m_symbol_set = s_set;
111 tmp.insert(Term1(
typename Term1::cf_type(1), t.m_key));
116 template <
typename T,
typename U,
typename Term>
117 struct t_subs_utils<T, U, Term, typename
std::enable_if<t_subs_term_score<Term, T, U>::value == 2u>::type> {
118 template <
typename T1,
typename U1,
typename Term1>
119 using return_type_ = decltype(std::declval<typename Term1::key_type const &>()
120 .
t_subs(std::declval<const symbol_idx &>(), std::declval<T1 const &>(),
121 std::declval<U1 const &>(), std::declval<symbol_fset const &>())[0u]
123 * std::declval<Derived const &>());
124 template <
typename T1,
typename U1,
typename Term1>
125 using return_type =
typename std::enable_if<std::is_constructible<return_type_<T1, U1, Term1>,
int>::value
127 return_type_<T1, U1, Term1>>::type;
128 template <
typename T1,
typename U1,
typename Term1>
129 static return_type<T1, U1, Term1> subs(
const Term1 &t,
const std::string &,
const symbol_idx &idx,
const T1 &c,
132 return_type<T1, U1, Term1> retval(0);
133 const auto key_subs = t.m_key.t_subs(idx, c, s, s_set);
134 for (
const auto &x : key_subs) {
136 tmp.m_symbol_set = s_set;
137 tmp.insert(Term1(t.m_cf, x.second));
138 retval += x.first * tmp;
146 template <
typename T,
typename U,
typename Term>
147 struct t_subs_utils<T,U,Term,typename
std::enable_if<t_subs_term_score<Term,T,U>::value == 3u>::type>
149 typedef decltype(std::declval<typename Term::key_type>().
t_subs(std::declval<std::string>(),std::declval<T>(),
150 std::declval<U>(),std::declval<symbol_set>())) key_t_subs_type;
151 typedef decltype(
math::t_subs(std::declval<Series>(),std::declval<std::string>(),std::declval<T>(),std::declval<U>()))
153 typedef decltype(std::declval<typename key_t_subs_type::value_type::first_type>() * std::declval<Series>() *
154 std::declval<cf_t_subs_type>()) type;
158 template <
typename T,
typename U>
160 = decltype(t_subs_utils<T, U>::subs(std::declval<typename Series::term_type const &>(),
161 std::declval<const std::string &>(), std::declval<const symbol_idx &>(),
162 std::declval<const T &>(), std::declval<const U &>(),
163 std::declval<symbol_fset const &>()));
218 template <
typename T,
typename U>
219 t_subs_type<T, U>
t_subs(
const std::string &name,
const T &c,
const U &s)
const 221 t_subs_type<T, U> retval(0);
222 const auto idx =
ss_index_of(this->m_symbol_set, name);
223 for (
const auto &t : this->m_container) {
224 retval += t_subs_utils<T, U>::subs(t, name, idx, c, s, this->m_symbol_set);
234 template <
typename Series,
typename U,
typename V>
235 using t_subs_impl_t_subs_series_enabler =
typename std::enable_if<
236 std::is_base_of<t_substitutable_series_tag, Series>::value
237 && is_returnable<decltype(std::declval<const Series &>().t_subs(
238 std::declval<const std::string &>(), std::declval<const U &>(), std::declval<const V &>()))>::value>::type;
249 template <
typename Series,
typename U,
typename V>
250 struct t_subs_impl<Series, U, V, detail::t_subs_impl_t_subs_series_enabler<Series, U, V>> {
264 auto operator()(
const Series &
series,
const std::string &name,
const U &c,
const V &s)
const 265 -> decltype(
series.t_subs(name, c, s))
267 return series.t_subs(name, c, s);
t_substitutable_series & operator=(const t_substitutable_series &other)=default
Copy assignment operator.
Type trait to detect the presence of the piranha::math::t_subs function.
In-place addable type trait.
#define PIRANHA_FORWARDING_CTOR(Derived, Base)
Constructor-forwarding macro.
detail::math_t_subs_type< T, U, V > t_subs(const T &x, const std::string &name, const U &c, const V &s)
Trigonometric substitution.
boost::container::flat_set< std::string > symbol_fset
Flat set of symbols.
~t_substitutable_series()
Trivial destructor.
t_subs_type< T, U > t_subs(const std::string &name, const T &c, const U &s) const
Trigonometric substitution.
Toolbox for series that support trigonometric substitution.
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.
Default functor for the implementation of piranha::math::t_subs().
t_substitutable_series()=default
Defaulted default constructor.
Type trait to detect the presence of the trigonometric substitution method in keys.
#define PIRANHA_TT_CHECK(tt,...)
Macro for static type trait checks.
Type trait to detect series types.
#define PIRANHA_FORWARDING_ASSIGNMENT(Derived, Base)
Assignment-forwarding macro.
auto operator()(const Series &series, const std::string &name, const U &c, const V &s) const -> decltype(series.t_subs(name, c, s))
Call operator.