41 struct expand_to_Polynomial_ID;
42 struct expand_Constants_ID;
43 struct expand_Constants_to_ID;
52 template <
typename ...Args>
68 template<
class Config = DefaultSimplifyConfig>
void simplify();
71 template<
class Config,
class T>
74 template<
class Config,
class T>
83 template<
class Config = DefaultSimplifyConfig,
class T>
95 template<
class T>
auto expand(
const T& a)
109 template<
class T>
auto N(
const T& a)
115 template<
class T>
auto try_N(
const T& a)
127 template<
class Config,
class LHS,
class RHS,
class Op>
129 ->
typename std::enable_if<!std::is_same<decltype(Op::apply(f._l, f._r)),
BinaryOp<LHS, Op, RHS> >::value, decltype(Op::apply(f._l, f._r))>::type
130 {
return Op::apply(f._l, f._r); };
133 template<
class Config,
class LHS,
class RHS,
class Op,
134 typename =
typename std::enable_if<std::is_same<RHS, typename Op::right_zero>::value >::type>
137 template<
class Config,
class LHS,
class RHS,
class Op,
138 typename =
typename std::enable_if<std::is_same<LHS, typename Op::left_zero>::value && !std::is_same<RHS, typename Op::right_zero>::value>::type>
142 template<
class Config,
class LHS,
class Op>
145 template<
class Config,
class RHS,
class Op,
146 typename =
typename std::enable_if<!std::is_same<RHS, typename Op::right_identity>::value>::type>
150 template<
class Config,
class ...VarArgs1,
class ...VarArgs2,
156 template<class Config, class RHS, typename = typename std::enable_if<!std::is_same<RHS, Null>::value>::type>
160 template<
class Config,
class ...VarArgs1,
class ...VarArgs2,
165 template<
class Config,
class ...VarArgs1,
class ...VarArgs2,
class Order,
170 template<
class Config,
class ...VarArgs1,
class ...VarArgs2,
class Order,
176 template<
class Config,
class LHS,
class RHS,
class Op>
178 ->
STATOR_AUTORETURN(try_simplify<Config>(Op::apply(simplify<Config>(f.
_l), simplify<Config>(f.
_r))));
181 template<
class Config,
class LHS,
class RHS,
class Op>
185 template<
class Config,
class LHS,
class RHS,
class Op>
191 template<
class Config,
class Arg, std::
intmax_t Power>
193 ->
STATOR_AUTORETURN(try_simplify<Config>(PowerOpSub<Power>::eval(simplify<Config>(f.
_l))));
195 template<
class Config,
class Arg, std::
intmax_t Power>
209 typename =
typename std::enable_if<PowerOpEnableExpansion<Arg>::value>::type>
225 template<
class Config,
class Arg1,
class Arg2,
class Arg3,
class Op,
226 typename =
typename std::enable_if<Op::associative>::type>
231 template<
class Config,
class Arg1,
class Arg2,
class Arg3,
class Op,
232 typename =
typename std::enable_if<Op::associative>::type>
237 template<
class Config,
class Arg1,
class Arg2,
class Arg3,
class Op,
238 typename =
typename std::enable_if<Op::associative>::type>
243 template<
class Config,
class Arg1,
class Arg2,
class Arg3,
class Op,
244 typename =
typename std::enable_if<Op::associative>::type>
250 template<
class Config = DefaultSimplifyConfig,
class L,
class Op,
class R>
265 template<
class Config =
DefaultSimplifyConfig,
class PolyVar,
class ...VarArgs,
size_t Order,
class Real,
266 typename =
typename std::enable_if<Config::expand_to_Polynomial &&
variable_in<
Var<VarArgs...>, PolyVar>::value>::type>
271 std::copy(f.
_r.begin(), f.
_r.end(), retval.begin() + 1);
277 template<
class Config =
DefaultSimplifyConfig,
class PolyVar,
class ...VarArgs,
size_t Order,
class Real,
278 typename =
typename std::enable_if<(Config::expand_to_Polynomial &&
variable_in<
Var<VarArgs...>, PolyVar>::value)>::type>
283 std::copy(f.
_l.begin(), f.
_l.end(), retval.begin() + 1);
289 typename =
typename std::enable_if<Config::expand_to_Polynomial>::type>
296 typename =
typename std::enable_if<Config::expand_to_Polynomial>::type>
306 typename =
typename std::enable_if<std::is_arithmetic<T>::value || std::is_base_of<Eigen::EigenBase<T>, T>::value>::type>
310 typename =
typename std::enable_if<std::is_arithmetic<T>::value>::type>
313 template<std::intmax_t n1, std::intmax_t d1,
314 typename =
typename std::enable_if<!(n1 % d1)>::type>
317 template<std::intmax_t n1, std::intmax_t d1,
318 typename =
typename std::enable_if<n1 % d1>::type>
321 template<
class Config, std::intmax_t num, std::intmax_t den,
322 typename =
typename std::enable_if<Config::expand_Constants>::type>
327 template<
class Config,
class PolyVar,
size_t Order,
class Real,
class Op,
class Real2,
328 typename =
typename std::enable_if<Config::expand_to_Polynomial && detail::IsConstant<Real2>::value>::type>
334 template<
class Config,
class PolyVar,
size_t Order,
class Real,
class Op,
class Real2,
335 typename =
typename std::enable_if<Config::expand_to_Polynomial && detail::IsConstant<Real2>::value>::type>
341 {
return N > M ?
N : M; }
346 template<
class Config =
DefaultSimplifyConfig,
class Real1,
size_t N,
class Real2,
size_t M,
class PolyVar1,
class PolyVar2,
class Op,
347 typename =
typename std::enable_if<std::is_same<Op,detail::Add>::value || std::is_same<Op,detail::Subtract>::value>::type,
354 for (
size_t i(0); i <= std::min(N, M); ++i)
355 retval[i] = Op::apply(f._l[i], f._r[i]);
357 for (
size_t i(std::min(N, M)+1); i <=
N; ++i)
358 retval[i] = Op::apply(f._l[i],
empty_sum(f._l[i]));
360 for (
size_t i(std::min(N, M)+1); i <= M; ++i)
361 retval[i] = Op::apply(
empty_sum(f._r[i]), f._r[i]);
369 class PolyVar1,
class PolyVar2,
class Op,
370 typename =
typename std::enable_if<std::is_same<Op,detail::Multiply>::value>::type>
375 for (
size_t i(0); i <= N+M; ++i)
376 for (
size_t j(i>N?i-N:0); (j <= i) && (j <=M); ++j)
377 retval[i] += Op::apply(f._l[j], f._r[i-j]);
383 template<
class Config = DefaultSimplifyConfig,
class Real1,
class Real2,
size_t M,
class PolyVar1,
class PolyVar2>
388 for (
size_t i(0); i <= M; ++i)
389 retval[i] += f._l[i] / f._r[0];
419 template<
class Config,
class Arg>
420 auto simplify_UnaryOp(
const UnaryOp<UnaryOp<Arg, detail::Arbsign>, detail::Arbsign>& f, detail::choice<0>)
424 template<
class Config,
class Arg,
class Op>
429 template<
class Config = DefaultSimplifyConfig,
class Arg,
class Op>
435 typename =
typename std::enable_if<std::is_same<Op,detail::Multiply>::value
436 || std::is_same<Op,detail::Divide>::value>::type>
440 template<
class Config,
class LHS,
class Arg,
class Op,
441 typename =
typename std::enable_if<std::is_same<Op,detail::Multiply>::value
442 || std::is_same<Op,detail::Divide>::value>::type>
446 template<
class Config,
class RHS,
class Arg,
class Op,
447 typename =
typename std::enable_if<std::is_same<Op,detail::Multiply>::value
448 || std::is_same<Op,detail::Divide>::value>::type>
453 template<
class Config = DefaultSimplifyConfig,
class Arg, std::
intmax_t Power>
455 ->
typename std::enable_if<!(Power % 2), decltype(try_simplify<Config>(
pow(f._l._arg,
C<Power>())))>::type
456 {
return try_simplify<Config>(
pow(f._l._arg,
C<Power>())); }
459 template<
class Config = DefaultSimplifyConfig,
class Arg, std::
intmax_t Power>
461 ->
typename std::enable_if<Power % 2, decltype(try_simplify<Config>(
arbsign(
pow(f._l._arg,
C<Power>()))))>::type
SimplifyConfig<> DefaultSimplifyConfig
#define STATOR_AUTORETURN_BYVALUE(EXPR)
A convenience Macro for defining auto by-value return type functions.
A class which recursively inherits from itself to allow ambiguous function definition ordering...
auto try_simplify(const T &a) -> decltype(detail::try_simplify_imp< Config >(a, detail::select_overload
A method to apply simplification only if it is available.
Symbolic representation of a variable.
SimplifyConfig< expand_to_Polynomial, expand_Constants > ExpandConfig
auto N(const T &a) -> STATOR_AUTORETURN(simplify< NConfig >(a))
A variant of simplify that converts compile time symbols into numbers.
auto simplify_powerop_impl(const PowerOp< Arg, C< Power, 1 > > &f, detail::choice< 0 >) -> STATOR_AUTORETURN(try_simplify< Config >(PowerOpSub< Power >::eval(simplify< Config >(f._l))))
Polynomial< Order+1, Real, PolyVar > simplify(MultiplyOp< Var< VarArgs... >, Polynomial< Order, Real, PolyVar > > &f)
Type trait which determines if an operation (multiplication, addition) can be distributed over the co...
static auto apply(const Arg &a) -> STATOR_AUTORETURN((UnaryOp< decltype(store(a)), Arbsign >(a)))
auto simplify_UnaryOp(const UnaryOp< UnaryOp< Arg, detail::Arbsign >, detail::Arbsign > &f, detail::choice< 0 >) -> STATOR_AUTORETURN(try_simplify< Config >(detail::Arbsign::apply(f._arg._arg)))
Specialisation for squares of matrix expressions.
auto try_N(const T &a) -> STATOR_AUTORETURN(try_simplify< NConfig >(a))
A variant of try_simplify that converts compile time symbols into numbers.
A class representing a compile-time rational constant (i.e., std::ratio).
choice< LAST_OVERLOAD_LVL > last_choice
auto expand(const T &a) -> STATOR_AUTORETURN(simplify< ExpandConfig >(a))
A variant of simplify that expands into Polynomial types aggressively.
Symbolic representation of a binary symbolic operation.
Expr simplify(const Expr &f)
auto toArithmetic(T val) -> STATOR_AUTORETURN_BYVALUE(val)
A converter to arithmetic types.
#define STATOR_AUTORETURN(EXPR)
A convenience Macro for defining auto return type functions.
The stator symbolic math library.
T empty_sum(const T &)
Returns the empty sum of a type.
auto simplify_BinaryOp(const BinaryOp< LHS, Op, RHS > &f, detail::choice< 0 >) -> typename std::enable_if<!std::is_same< decltype(Op::apply(f._l, f._r)), BinaryOp< LHS, Op, RHS > >::value, decltype(Op::apply(f._l, f._r))>::type
auto arbsign(const Arg &arg) -> STATOR_AUTORETURN((UnaryOp< decltype(store(arg)), detail::Arbsign >(arg)))
constexpr size_t max_order(size_t N, size_t M)
typename stator::orphan::get_type< sym::expand_Constants_to< double >, Args... >::value expand_Constants_to_t
auto pow(const LHS &l, const RHS &r) -> STATOR_AUTORETURN(std::pow(l, r))
SimplifyConfig< expand_Constants > NConfig
Symbolic representation of a unary operator (i.e., sin(x)).
A class used to start the ambiguous function definition ordering calculation.
auto try_simplify_imp(const T &a, detail::choice< 0 >) -> STATOR_AUTORETURN(simplify< Config >(a))
auto store(const T &val) -> decltype(store_impl(val, select_overload
auto try_expand(const T &a) -> STATOR_AUTORETURN(try_simplify< ExpandConfig >(a))
A variant of try_simplify that expands into Polynomial types aggressively.
Array representation of Polynomial.