29 #ifdef STATOR_USE_BOOST_SHARED_PTR 30 # include <boost/shared_ptr.hpp> 32 using boost::shared_ptr;
33 using boost::make_shared;
34 using boost::dynamic_pointer_cast;
38 using std::shared_ptr;
39 using std::make_shared;
40 using std::dynamic_pointer_cast;
50 template<
class Config = DefaultReprConfig> std::string
repr(
const sym::RTBase&);
51 template<
class Config = DefaultReprConfig> std::string
repr(
const sym::Expr&);
55 template<
class Op>
struct UnaryOp<Expr, Op>;
56 template<
class Op>
struct BinaryOp<Expr, Op, Expr>;
69 typedef shared_ptr<const RTBase>
Base;
72 Expr(
const std::shared_ptr<const RTBase>& p) : Base(p) {}
74 Expr(
const std::string&);
81 template<std::
intmax_t Num, std::
intmax_t Denom>
84 template<
typename ...Args>
87 template<
class Op,
class Arg_t>
90 template<
class LHS_t,
class Op,
class RHS_t>
96 bool operator!=(
const Expr& o)
const {
return !(*
this == o); }
98 explicit operator bool()
const {
return Base::operator bool(); }
100 template<
class T> T as()
const;
111 virtual Expr visit(
const double&) = 0;
112 virtual Expr visit(
const VarRT&) = 0;
134 template<
typename Derived>
136 inline virtual Expr visit(
const double& x) {
return static_cast<Derived*
>(
this)->apply(x); }
137 inline virtual Expr visit(
const VarRT& x) {
return static_cast<Derived*
>(
this)->apply(x); }
140 {
return static_cast<Derived*
>(
this)->apply(x); }
142 {
return static_cast<Derived*
>(
this)->apply(x); }
144 {
return static_cast<Derived*
>(
this)->apply(x); }
146 {
return static_cast<Derived*
>(
this)->apply(x); }
148 {
return static_cast<Derived*
>(
this)->apply(x); }
150 {
return static_cast<Derived*
>(
this)->apply(x); }
152 {
return static_cast<Derived*
>(
this)->apply(x); }
154 {
return static_cast<Derived*
>(
this)->apply(x); }
156 {
return static_cast<Derived*
>(
this)->apply(x); }
158 {
return static_cast<Derived*
>(
this)->apply(x); }
160 {
return static_cast<Derived*
>(
this)->apply(x); }
175 virtual Expr clone()
const = 0;
185 template<
class Derived>
189 return Expr(std::make_shared<Derived>(static_cast<const Derived&>(*
this)));
193 auto other = dynamic_pointer_cast<
const Derived>(o);
196 return *
static_cast<const Derived*
>(
this) == *other;
204 inline Var(
const char v) : idx(v) {}
206 template<
typename ...Args>
208 idx(
Var<Args...>::idx)
219 inline char getidx()
const {
return idx; }
232 template<
class ...Args1,
class ...Args2,
233 typename =
typename std::enable_if<std::is_base_of<
Dynamic,
Var<Args1...> >::value || std::is_base_of<Dynamic,
Var<Args2...> >::value>::type >
248 const T&
get()
const {
return _val; }
255 template<
class LHS_t>
294 template<
typename Op>
299 return Expr(std::make_shared<UnaryOp>(_arg->clone()));
303 return (_arg == o.
_arg);
317 template<
typename Op>
322 return Expr(std::make_shared<BinaryOp>(_l->clone(),
_r->clone()));
326 return (_l == o.
_l) && (
_r == o.
_r);
347 template<std::
intmax_t Num, std::
intmax_t Denom>
350 template<
class Op,
class Arg_t>
353 template<
class LHS_t,
class Op,
class RHS_t>
356 template<
typename ...Args>
363 stator_throw() <<
"Invalid as<>(), expression is as follows:" << *
this;
369 return (*(*
this)) ==
e;
384 template<
typename Visitor,
typename LHS_t,
typename Op>
388 template<
class RHS_t>
389 Expr apply(
const RHS_t& RHS) {
return _visitor.dd_visit(_LHS, RHS, Op()); }
396 template<
typename Visitor,
typename Op>
399 _RHS(RHS), _visitor(visitor) {}
401 template<
class LHS_t>
404 return _RHS->visit(visitor);
415 Expr apply(
const double& arg) {
return Op::apply(arg); }
420 template<
class T1,
class T2,
class Op>
463 template<
typename Op>
469 Expr ret = (arg ? arg : op.
getArg())->visit(visitor);
478 template<
typename Op>
488 if (l ==
typename Op::left_zero())
489 return typename Op::left_zero();
490 if (l ==
typename Op::left_identity())
492 if (r ==
typename Op::right_zero())
493 return typename Op::right_zero();
494 if (r ==
typename Op::right_identity())
499 Expr ret = l->visit(visitor);
503 if (lchanged || rchanged)
513 Expr result = f->visit(visitor);
514 return result ? result : f;
533 template<
typename Op>
536 return arg ?
Expr(Op::apply(arg)) : op.shared_from_this();
539 template<
typename Op>
545 return Expr(Op::apply(l ? l : op.
_l, r ? r : op.
_r));
555 template<
class Var,
class Arg>
558 Expr result = f->visit(visitor);
559 return (result) ? result : f;
590 template<class T, typename = typename std::enable_if<IsConstant<T>::value>::type>
596 return Expr((v == _var) ? 1 : 0);
606 template<
typename Op>
620 return f->visit(visitor);
643 if (_value) o.
getRHS()->visit(*
this);
659 FastSubRT(VarRT var,
double replacement): _var(var), _replacement(replacement) {}
673 _intermediate = _replacement;
679 template<
typename Op>
681 op.getArg()->visit(*
this);
682 _intermediate = Op::apply(_intermediate);
686 template<
typename Op>
688 op.
getLHS()->visit(*
this);
689 double lval = _intermediate;
690 op.
getRHS()->visit(*
this);
691 _intermediate = Op::apply(lval, _intermediate);
bool operator==(const UnaryOp< Expr, Op > &o) const
Expr apply(const VarRT &v)
bool operator==(const Expr o) const
DoubleDispatch2(const LHS_t &LHS, Visitor &visitor)
Expr apply(const BinaryOp< Expr, Op, Expr > &op)
A CRTP helper base class which transforms the visitor interface into a call to the derived classes ap...
auto apply(const UnaryOp< Expr, Op > &op) -> decltype(double(Op::apply(0.0)), Expr())
virtual Expr visit(const UnaryOp< Expr, detail::Exp > &x)
A class which recursively inherits from itself to allow ambiguous function definition ordering...
virtual Expr visit(const double &)=0
bool is_constant(const Expr &a)
Symbolic representation of a variable.
detail::C_wrap< stator::constant_ratio::e >::type e
A symbolic/compile-time rational approximation of .
virtual Expr visit(const BinaryOp< Expr, detail::Power, Expr > &x)
bool operator==(const Expr o) const
Expr apply(const UnaryOp< Expr, Op > &op)
bool operator==(const Expr &) const
virtual Expr visit(const BinaryOp< Expr, detail::Add, Expr > &x)
DoubleDispatch1(const Expr &RHS, Visitor &visitor)
Abstract interface class for all runtime symbolic classes.
constexpr bool operator==(const C< n1, d1 > &, const C< n2, d2 > &)
static auto apply(const L &l, const R &r) -> STATOR_AUTORETURN(l - r)
Expr dd_visit(const T1 &l, const T2 &r, Op)
Expr apply(const LHS_t &lhs)
Expr apply(const double &arg)
std::enable_if< std::is_integral< T >::value, std::string >::type repr(T a)
CompareConstantsVisitor(const LHS_t &l)
A class representing a compile-time rational constant (i.e., std::ratio).
double fast_sub(const Expr &f, const Relation< Var, double > &rel)
Main header for the stator::symbolic library.
Specialisation of Var for runtime variables.
Expr visit(detail::VisitorInterface &c) const
Expr apply(const RHS_t &RHS)
Expr apply(const double &v)
Template argument for dynamic types, as well as their base class.
Relation< VarRT, Expr > operator=(const Expr &f) const
Specialisation of BinaryOp for runtime arguments (Expr).
Symbolic representation of a binary symbolic operation.
SubstituteRT(VarRT var, Expr replacement)
Expr simplify(const Expr &f)
Symbolic representation of a variable substitution.
Expr apply(const UnaryOp< Expr, Op > &op)
The generic holder/smart pointer for a runtime Abstract Syntax Tree (AST) (expression).
Var(const Var< Args... > v)
FastSubRT(VarRT var, double replacement)
BinaryOp(const Expr &lhs, const Expr &rhs)
virtual Expr visit(const UnaryOp< Expr, detail::Arbsign > &x)
Expr(const detail::NoIdentity &)
bool operator!=(const Expr &o) const
The stator symbolic math library.
Expr apply(const BinaryOp< Expr, Op, Expr > &op)
Expr dd_visit(const BinaryOp< Expr, detail::Multiply, Expr > &r, const double &l, detail::Multiply)
virtual Expr visit(const BinaryOp< Expr, detail::Divide, Expr > &x)
bool operator==(const BinaryOp &o) const
Expr apply(const BinaryOp< Expr, Op, Expr > &op)
Expr apply(const UnaryOp< Expr, Op > &v)
virtual Expr visit(const BinaryOp< Expr, detail::Multiply, Expr > &x)
Expr dd_visit(const double &l, const BinaryOp< Expr, detail::Multiply, Expr > &r, detail::Multiply)
virtual Expr visit(const VarRT &x)
bool operator==(const VarRT &o) const
virtual Expr visit(const double &x)
Abstract interface class for the visitor programming pattern for Expr types.
Expr apply(const BinaryOp< Expr, Op, Expr > &o)
virtual Expr visit(const UnaryOp< Expr, detail::Cosine > &x)
Expr apply(const BinaryOp< Expr, Op, Expr > &op)
Expr apply(const VarRT &v)
CRTP helper base class which implements some of the common boilerplate code for runtime symbolic type...
virtual Expr visit(const UnaryOp< Expr, detail::Sine > &x)
Expr dd_visit(const double &l, const T2 &r, detail::Subtract)
auto sub(BinaryOp< LHS, Op, RHS > f, Relation< Var, Arg > x) -> STATOR_AUTORETURN_BYVALUE(Op::apply(sub(f._l, x), sub(f._r, x)))
Expr apply(const UnaryOp< Expr, Op > &a)
Expr worker(const T &rhs, detail::choice< 1 >)
Expr apply(const T &v)
Visitor to allow the compile time derivative implementation for unary operators.
Specialisation of unary operator for runtime arguments and use in runtime expressions (Expr)...
auto derivative(const Expression &)
Performs a symbolic derivative on the expression.
The stator library namespace.
virtual Expr visit(const BinaryOp< Expr, detail::Subtract, Expr > &x)
A type trait to denote symbolic terms (i.e., one that is not yet immediately evaluable to a "normal" ...
Type trait to determine if a certain type is a constant.
shared_ptr< const RTBase > Base
Symbolic representation of a unary operator (i.e., sin(x)).
A class used to start the ambiguous function definition ordering calculation.
virtual Expr visit(const UnaryOp< Expr, detail::Log > &x)
bool operator==(const detail::NoIdentity &) const
Expr apply(const VarRT &v)
Expr(const std::shared_ptr< const RTBase > &p)
virtual Expr visit(const UnaryOp< Expr, detail::Absolute > &x)
auto store(const T &val) -> decltype(store_impl(val, select_overload
auto worker(const T &rhs, detail::choice< 0 >) -> decltype(LHS_t()==rhs, Expr())