stator
A math, geometry, and utility library
symbolic.hpp
Go to the documentation of this file.
1 
4 /*
5  Copyright (C) 2017 Marcus N Campbell Bannerman <[email protected]>
6 
7  This file is part of stator.
8 
9  stator is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  stator is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with stator. If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #pragma once
24 
25 // stator
26 #include <stator/config.hpp>
27 #include <stator/constants.hpp>
29 
30 // Eigen
31 #include <Eigen/Dense>
32 
33 // C++
34 #include <complex>
35 #include <ratio>
36 #include <type_traits>
37 
38 namespace sym {
41 
42  namespace detail {
46  } // namespace detail
47 
50  struct SymbolicOperator {};
51 }
52 
55 
56 namespace sym {
57 
66  struct Dynamic {};
67 
68 
69  template<class T>
70  struct IsSymbolic {
71  static constexpr bool value = std::is_base_of<SymbolicOperator, T>::value;
72  };
73 
76  template<class Var, class Arg> struct Relation {
77  Relation(const Var var, const Arg& val): _var(var), _val(val) {}
78 
79  const Var _var;
80  const Arg& _val;
81  };
82 
83  namespace detail {
84  struct vidx_ID;
85  };
86 
87  template<char idx>
88  struct vidx : stator::orphan::value_conf_t<detail::vidx_ID, char, idx> {};
89 
94  template<typename ...Args> struct Var : SymbolicOperator {
95  static constexpr const auto idx = stator::orphan::get_value<vidx<'x'>, Args...>::value;
96 
97  template<class Arg>
98  Relation<Var<Args...>, Arg> operator=(const Arg& a) const {
99  return Relation<Var<Args...>, Arg>(*this, a);
100  }
101 
102  char getidx() const { return Var::idx; }
103  };
104 
105  template<typename Var1, typename Var2>
106  struct variable_in {
107  static constexpr const bool value = Var1::idx == Var2::idx;
108  };
109 
110  template<typename Var1, typename Var2>
111  struct enable_if_var_in : std::enable_if<variable_in<Var1, Var2>::value> {
112  };
113 
114  template<typename Var1, typename Var2>
115  struct enable_if_var_not_in : std::enable_if<!variable_in<Var1, Var2>::value> {
116  };
117 
118  template<typename Var1, typename Var2>
121  };
122 
123 
124  namespace detail {
131  template<class T>
132  struct IsConstant : std::conditional<std::is_arithmetic<T>::value || is_C<T>::value || std::is_base_of<Eigen::EigenBase<T>, T>::value, std::true_type, std::false_type>::type {};
133 
134  template<class T>
135  struct IsConstant<std::complex<T> > : IsConstant<T> {};
136 
137  }// namespace detail
138 
139  template<class T>
140  constexpr typename std::enable_if<detail::IsConstant<T>::value, bool>::type is_constant(const T&) { return true;}
141 
142  template<class T>
143  constexpr typename std::enable_if<!detail::IsConstant<T>::value, bool>::type is_constant(const T&) { return false;}
144 
152  template<class T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
153  T empty_sum(const T&) { return T(); }
154 
155  template<class T, typename = typename std::enable_if<std::is_base_of<Eigen::EigenBase<T>, T>::value>::type>
156  auto empty_sum(const T&) -> STATOR_AUTORETURN_BYVALUE(T::Zero());
157 
158  template<class T>
159  T empty_sum(const std::complex<T>&) { return T(); }
160 
172  template<class T, class Var, class Arg,
173  typename = typename std::enable_if<detail::IsConstant<T>::value>::type >
174  auto sub(const T& f, const Relation<Var, Arg>&) -> STATOR_AUTORETURN_BYVALUE(f);
175 
181  template<typename ...Args1, typename ...Args2, class Arg,
182  typename = typename enable_if_var_in<Var<Args1...>, Var<Args2...> >::type>
183  auto sub(const Var<Args1...>& f, const Relation<Var<Args2...>, Arg>& x)
184  -> STATOR_AUTORETURN_BYVALUE(x._val);
185 
191  template<class ...Args1, class Arg, class Var2,
192  typename = typename enable_if_var_not_in<Var<Args1...>, Var2>::type>
193  Var<Args1...> sub(const Var<Args1...>& f, const Relation<Var2, Arg>& x)
194  { return f; }
195 
196 
202  template<class T, class ...Args,
203  typename = typename std::enable_if<detail::IsConstant<T>::value>::type>
204  Null derivative(const T&, Var<Args...>) { return Null(); }
205 
212  template<class ...Args1, class ...Args2,
213  typename = typename std::enable_if<!std::is_base_of<Dynamic, Var<Args1...> >::value && !std::is_base_of<Dynamic, Var<Args2...> >::value>::type>
214  auto derivative(Var<Args1...>, Var<Args2...>) -> typename std::enable_if<Var<Args1...>::idx == Var<Args2...>::idx, Unity>::type
215  { return Unity(); }
216 
218  return StackVector<double, 0>();
219  }
220 
227  template<class ...Args1, class ...Args2,
228  typename = typename std::enable_if<!std::is_base_of<Dynamic, Var<Args1...> >::value && !std::is_base_of<Dynamic, Var<Args2...> >::value>::type>
229  auto derivative(Var<Args1...>, Var<Args2...>) -> typename std::enable_if<Var<Args1...>::idx != Var<Args2...>::idx, Null>::type
230  { return Null(); }
231 
237  template<class F, class Real,
238  typename = typename std::enable_if<detail::IsConstant<F>::value>::type>
239  inline F shift_function(const F& f, const Real t) {
240  return f;
241  }
242 
245  template<class F, class Real,
246  typename = typename std::enable_if<detail::IsConstant<F>::value>::type>
247  inline double precision(const F& f, const Real) {
248  return 0.0;
249  }
250 
251  template<size_t Order, class Real = double, class PolyVar = Var<>> class Polynomial;
252 }
253 
254 
263 #include <stator/symbolic/print.hpp>
#define STATOR_AUTORETURN_BYVALUE(EXPR)
A convenience Macro for defining auto by-value return type functions.
Definition: config.hpp:107
const Arg & _val
Definition: symbolic.hpp:80
Relation(const Var var, const Arg &val)
Definition: symbolic.hpp:77
A class which recursively inherits from itself to allow ambiguous function definition ordering...
Definition: config.hpp:65
bool is_constant(const Expr &a)
Definition: runtime.hpp:651
Symbolic representation of a variable.
Definition: symbolic.hpp:94
C< 0 > Null
A symbolic representation of zero.
Definition: constants.hpp:51
Relation< Var< Args... >, Arg > operator=(const Arg &a) const
Definition: symbolic.hpp:98
F shift_function(const F &f, const Real t)
Shift a function forward. It returns .
Definition: symbolic.hpp:239
Fundamental typedef&#39;s and macros for stator.
Stack-allocated equivalent of std::vector.
A class representing a compile-time rational constant (i.e., std::ratio).
Definition: constants.hpp:31
choice< LAST_OVERLOAD_LVL > last_choice
Definition: config.hpp:73
Template argument for dynamic types, as well as their base class.
Definition: symbolic.hpp:66
StackVector< double, 0 > solve_real_roots(Null f)
Definition: symbolic.hpp:217
C< 1 > Unity
A symbolic representation of one.
Definition: constants.hpp:53
char getidx() const
Definition: symbolic.hpp:102
Symbolic representation of a variable substitution.
Definition: symbolic.hpp:76
static constexpr const auto idx
Definition: symbolic.hpp:95
The stator symbolic math library.
T empty_sum(const T &)
Returns the empty sum of a type.
Definition: symbolic.hpp:153
auto sub(BinaryOp< LHS, Op, RHS > f, Relation< Var, Arg > x) -> STATOR_AUTORETURN_BYVALUE(Op::apply(sub(f._l, x), sub(f._r, x)))
Integration support for the stator::symbolic library.
auto derivative(const Expression &)
Performs a symbolic derivative on the expression.
A type trait to denote symbolic terms (i.e., one that is not yet immediately evaluable to a "normal" ...
Definition: symbolic.hpp:50
const Var _var
Definition: symbolic.hpp:79
Type trait to determine if a certain type is a constant.
Definition: symbolic.hpp:132
double precision(const F &f, const Real)
Estimate the error in evaluating a function at a given time.
Definition: symbolic.hpp:247
Var< vidx< Var1::idx > > type
Definition: symbolic.hpp:120
A class used to start the ambiguous function definition ordering calculation.
Definition: config.hpp:76
auto store(const T &val) -> decltype(store_impl(val, select_overload
Definition: config.hpp:94
Array representation of Polynomial.
Definition: polynomial.hpp:63