29 #ifndef PIRANHA_TRIGONOMETRIC_SERIES_HPP 30 #define PIRANHA_TRIGONOMETRIC_SERIES_HPP 33 #include <type_traits> 37 #include <piranha/math.hpp> 38 #include <piranha/series.hpp> 39 #include <piranha/symbol_utils.hpp> 49 struct trigonometric_series_tag {
87 template <
typename Series>
93 template <
typename Cf>
94 struct cf_trig_score {
95 static const int value
98 template <
typename Key>
99 struct key_trig_score {
104 template <
typename T>
105 using common_type_checks = conjunction<is_less_than_comparable<T>,
is_returnable<T>>;
107 #define PIRANHA_DEFINE_TRIG_PROPERTY_GETTER(property) \ 108 template <typename Term, enable_if_t<cf_trig_score<typename Term::cf_type>::value == 4u \ 109 && key_trig_score<typename Term::key_type>::value == 0u, \ 111 static auto get_t_##property(const Term &t, const symbol_fset &)->decltype(math::t_##property(t.m_cf)) \ 113 return math::t_##property(t.m_cf); \ 115 template <typename Term, enable_if_t<cf_trig_score<typename Term::cf_type>::value == 0u \ 116 && key_trig_score<typename Term::key_type>::value == 4u, \ 118 static auto get_t_##property(const Term &t, const symbol_fset &s)->decltype(t.m_key.t_##property(s)) \ 120 return t.m_key.t_##property(s); \ 122 template <typename T> \ 123 using t_##property##_type_ = decltype( \ 124 get_t_##property(std::declval<const typename T::term_type &>(), std::declval<const symbol_fset &>())); \ 125 template <typename T> \ 126 using t_##property##_type \ 127 = enable_if_t<common_type_checks<t_##property##_type_<T>>::value, t_##property##_type_<T>>; 128 PIRANHA_DEFINE_TRIG_PROPERTY_GETTER(degree)
129 PIRANHA_DEFINE_TRIG_PROPERTY_GETTER(ldegree)
130 PIRANHA_DEFINE_TRIG_PROPERTY_GETTER(order)
131 PIRANHA_DEFINE_TRIG_PROPERTY_GETTER(lorder)
132 #undef PIRANHA_DEFINE_TRIG_PROPERTY_GETTER 134 #define PIRANHA_DEFINE_PARTIAL_TRIG_PROPERTY_GETTER(property) \ 135 template <typename Term, enable_if_t<cf_trig_score<typename Term::cf_type>::value == 4u \ 136 && key_trig_score<typename Term::key_type>::value == 0u, \ 138 static auto get_t_##property(const Term &t, const symbol_idx_fset &, const symbol_fset &names) \ 139 ->decltype(math::t_##property(t.m_cf, names)) \ 141 return math::t_##property(t.m_cf, names); \ 143 template <typename Term, enable_if_t<cf_trig_score<typename Term::cf_type>::value == 0u \ 144 && key_trig_score<typename Term::key_type>::value == 4u, \ 146 static auto get_t_##property(const Term &t, const symbol_idx_fset &idx, const symbol_fset &names) \ 147 ->decltype(t.m_key.t_##property(idx, names)) \ 149 return t.m_key.t_##property(idx, names); \ 151 template <typename T> \ 152 using pt_##property##_type_ \ 153 = decltype(get_t_##property(std::declval<const typename T::term_type &>(), \ 154 std::declval<const symbol_idx_fset &>(), std::declval<const symbol_fset &>())); \ 155 template <typename T> \ 156 using pt_##property##_type \ 157 = enable_if_t<common_type_checks<pt_##property##_type_<T>>::value, pt_##property##_type_<T>>; 158 PIRANHA_DEFINE_PARTIAL_TRIG_PROPERTY_GETTER(degree)
159 PIRANHA_DEFINE_PARTIAL_TRIG_PROPERTY_GETTER(ldegree)
160 PIRANHA_DEFINE_PARTIAL_TRIG_PROPERTY_GETTER(order)
161 PIRANHA_DEFINE_PARTIAL_TRIG_PROPERTY_GETTER(lorder)
162 #undef PIRANHA_DEFINE_PARTIAL_TRIG_PROPERTY_GETTER 203 template <
typename T = trigonometric_series>
207 auto it = std::max_element(
208 this->m_container.begin(), this->m_container.end(), [
this](
const term_type &t1,
const term_type &t2) {
209 return this->get_t_degree(t1, this->m_symbol_set) < this->get_t_degree(t2, this->m_symbol_set);
211 return (it == this->m_container.end()) ? t_degree_type<T>(0) : get_t_degree(*it, this->m_symbol_set);
225 template <
typename T = trigonometric_series>
230 auto it = std::max_element(this->m_container.begin(), this->m_container.end(),
232 return this->get_t_degree(t1, idx, this->m_symbol_set)
233 < this->get_t_degree(t2, idx, this->m_symbol_set);
235 return (it == this->m_container.end()) ? pt_degree_type<T>(0) : get_t_degree(*it, idx, this->m_symbol_set);
247 template <
typename T = trigonometric_series>
251 auto it = std::min_element(
252 this->m_container.begin(), this->m_container.end(), [
this](
const term_type &t1,
const term_type &t2) {
253 return this->get_t_ldegree(t1, this->m_symbol_set) < this->get_t_ldegree(t2, this->m_symbol_set);
255 return (it == this->m_container.end()) ? t_ldegree_type<T>(0) : get_t_ldegree(*it, this->m_symbol_set);
269 template <
typename T = trigonometric_series>
274 auto it = std::min_element(this->m_container.begin(), this->m_container.end(),
276 return this->get_t_ldegree(t1, idx, this->m_symbol_set)
277 < this->get_t_ldegree(t2, idx, this->m_symbol_set);
279 return (it == this->m_container.end()) ? pt_ldegree_type<T>(0) : get_t_ldegree(*it, idx, this->m_symbol_set);
291 template <
typename T = trigonometric_series>
295 auto it = std::max_element(
296 this->m_container.begin(), this->m_container.end(), [
this](
const term_type &t1,
const term_type &t2) {
297 return this->get_t_order(t1, this->m_symbol_set) < this->get_t_order(t2, this->m_symbol_set);
299 return (it == this->m_container.end()) ? t_order_type<T>(0) : get_t_order(*it, this->m_symbol_set);
313 template <
typename T = trigonometric_series>
318 auto it = std::max_element(
319 this->m_container.begin(), this->m_container.end(), [
this, &idx](
const term_type &t1,
const term_type &t2) {
320 return this->get_t_order(t1, idx, this->m_symbol_set) < this->get_t_order(t2, idx, this->m_symbol_set);
322 return (it == this->m_container.end()) ? pt_order_type<T>(0) : get_t_order(*it, idx, this->m_symbol_set);
334 template <
typename T = trigonometric_series>
338 auto it = std::min_element(
339 this->m_container.begin(), this->m_container.end(), [
this](
const term_type &t1,
const term_type &t2) {
340 return this->get_t_lorder(t1, this->m_symbol_set) < this->get_t_lorder(t2, this->m_symbol_set);
342 return (it == this->m_container.end()) ? t_lorder_type<T>(0) : get_t_lorder(*it, this->m_symbol_set);
356 template <
typename T = trigonometric_series>
361 auto it = std::min_element(this->m_container.begin(), this->m_container.end(),
363 return this->get_t_lorder(t1, idx, this->m_symbol_set)
364 < this->get_t_lorder(t2, idx, this->m_symbol_set);
366 return (it == this->m_container.end()) ? pt_lorder_type<T>(0) : get_t_lorder(*it, idx, this->m_symbol_set);
378 template <
typename Series>
380 typename
std::enable_if<std::is_base_of<detail::trigonometric_series_tag, Series>::value>::type> {
393 template <
typename... Args>
394 auto operator()(
const Series &ts,
const Args &... args)
const -> decltype(ts.t_degree(args...))
396 return ts.t_degree(args...);
405 template <
typename Series>
407 typename
std::enable_if<std::is_base_of<detail::trigonometric_series_tag, Series>::value>::type> {
420 template <
typename... Args>
421 auto operator()(
const Series &ts,
const Args &... args)
const -> decltype(ts.t_ldegree(args...))
423 return ts.t_ldegree(args...);
432 template <
typename Series>
434 typename
std::enable_if<std::is_base_of<detail::trigonometric_series_tag, Series>::value>::type> {
447 template <
typename... Args>
448 auto operator()(
const Series &ts,
const Args &... args)
const -> decltype(ts.t_order(args...))
450 return ts.t_order(args...);
459 template <
typename Series>
461 typename
std::enable_if<std::is_base_of<detail::trigonometric_series_tag, Series>::value>::type> {
474 template <
typename... Args>
475 auto operator()(
const Series &ts,
const Args &... args)
const -> decltype(ts.t_lorder(args...))
477 return ts.t_lorder(args...);
Default functor for the implementation of piranha::math::t_degree().
pt_lorder_type< T > t_lorder(const symbol_fset &names) const
Partial trigonometric low order.
Trigonometric series toolbox.
trigonometric_series()=default
Defaulted default constructor.
auto operator()(const Series &ts, const Args &... args) const -> decltype(ts.t_degree(args...))
Trigonometric degree operator.
symbol_idx_fset ss_intersect_idx(const symbol_fset &s1, const symbol_fset &s2)
Find the indices of the intersection of two symbol_fset.
Type trait to detect if a key type has a trigonometric degree property.
#define PIRANHA_FORWARDING_CTOR(Derived, Base)
Constructor-forwarding macro.
t_order_type< T > t_order() const
Trigonometric order.
auto operator()(const Series &ts, const Args &... args) const -> decltype(ts.t_order(args...))
Trigonometric order operator.
pt_order_type< T > t_order(const symbol_fset &names) const
Partial trigonometric order.
auto operator()(const Series &ts, const Args &... args) const -> decltype(ts.t_lorder(args...))
Trigonometric low order operator.
Type trait to detect if type has a trigonometric low degree property.
trigonometric_series & operator=(const trigonometric_series &other)=default
Copy assignment operator.
Default functor for the implementation of piranha::math::t_lorder().
Type trait to detect if type has a trigonometric order property.
t_degree_type< T > t_degree() const
Trigonometric degree.
pt_degree_type< T > t_degree(const symbol_fset &names) const
Partial trigonometric degree.
pt_ldegree_type< T > t_ldegree(const symbol_fset &names) const
Partial trigonometric low degree.
boost::container::flat_set< std::string > symbol_fset
Flat set of symbols.
Default functor for the implementation of piranha::math::t_ldegree().
Detect if type can be returned from a function.
Type trait to detect if a key type has a trigonometric order property.
Type trait to detect if a key type has a trigonometric low order property.
Type trait to detect if type has a trigonometric degree property.
t_lorder_type< T > t_lorder() const
Trigonometric low order.
auto operator()(const Series &ts, const Args &... args) const -> decltype(ts.t_ldegree(args...))
Trigonometric low degree operator.
t_ldegree_type< T > t_ldegree() const
Trigonometric low degree.
~trigonometric_series()
Trivial destructor.
Type trait to detect if type has a trigonometric low order property.
Type trait to detect if a key type has a trigonometric low degree property.
Default functor for the implementation of piranha::math::t_order().
Type trait to detect series types.
#define PIRANHA_FORWARDING_ASSIGNMENT(Derived, Base)
Assignment-forwarding macro.