6 #ifndef SYMENGINE_VISITOR_H
7 #define SYMENGINE_VISITOR_H
11 #include <symengine/polys/uexprpoly.h>
12 #include <symengine/polys/msymenginepoly.h>
14 #include <symengine/complex_mpc.h>
16 #include <symengine/series_piranha.h>
17 #include <symengine/series_flint.h>
19 #include <symengine/series_piranha.h>
25 #include <symengine/matrix.h>
26 #include <symengine/ntheory_funcs.h>
27 #include <symengine/symengine_casts.h>
28 #include <symengine/tuple.h>
29 #include <symengine/matrix_expressions.h>
38 #define SYMENGINE_ENUM(TypeID, Class) virtual void visit(const Class &) = 0;
39 #include "symengine/type_codes.inc"
46 template <
class Derived,
class Base = Visitor>
51 #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 8 \
52 || defined(__SUNPRO_CC))
56 template <
typename... Args,
58 = enable_if_t<std::is_constructible<Base, Args...>::value>>
59 BaseVisitor(Args &&...args) : Base(std::forward<Args>(args)...)
68 #define SYMENGINE_ENUM(TypeID, Class) \
69 virtual void visit(const Class &x) \
71 down_cast<Derived *>(this)->bvisit(x); \
73 #include "symengine/type_codes.inc"
96 Ptr<const Basic> looking_for_;
101 bool apply(
const Basic &b)
105 preorder_traversal_stop(b, *
this);
108 void bvisit(
const Basic &arg)
110 if (
eq(*looking_for_, arg)) {
126 void bvisit(
const Symbol &x)
142 void bvisit(
const Basic &x) {}
144 bool apply(
const Basic &b)
148 preorder_traversal_stop(b, *
this);
153 SYMENGINE_EXPORT
bool has_basic(
const Basic &b,
const Basic &x);
154 SYMENGINE_EXPORT
bool has_symbol(
const Basic &b,
const Basic &x);
161 RCP<const Basic> coeff_;
164 CoeffVisitor(Ptr<const Basic> x, Ptr<const Basic> n) : x_(x), n_(n) {}
166 void bvisit(
const Add &x)
169 RCP<const Number> coef = zero;
170 for (
auto &p : x.get_dict()) {
171 p.first->accept(*
this);
172 if (
neq(*coeff_, *zero)) {
176 if (
eq(*zero, *n_)) {
177 iaddnum(outArg(coef), x.
get_coef());
182 void bvisit(
const Mul &x)
184 for (
auto &p : x.get_dict()) {
185 if (
eq(*p.first, *x_) and
eq(*p.second, *n_)) {
186 map_basic_basic dict = x.get_dict();
192 if (
eq(*zero, *n_) and not has_symbol(x, *x_)) {
199 void bvisit(
const Pow &x)
210 void bvisit(
const Symbol &x)
212 if (
eq(x, *x_) and
eq(*one, *n_)) {
214 }
else if (
neq(x, *x_) and
eq(*zero, *n_)) {
223 if (
eq(x, *x_) and
eq(*one, *n_)) {
225 }
else if (
neq(x, *x_) and
eq(*zero, *n_)) {
232 void bvisit(
const Basic &x)
234 if (
neq(*zero, *n_)) {
238 if (has_symbol(x, *x_)) {
245 RCP<const Basic> apply(
const Basic &b)
253 SYMENGINE_EXPORT RCP<const Basic> coeff(
const Basic &b,
const Basic &x,
256 SYMENGINE_EXPORT set_basic free_symbols(
const Basic &b);
258 SYMENGINE_EXPORT set_basic free_symbols(
const MatrixBase &m);
260 SYMENGINE_EXPORT set_basic function_symbols(
const Basic &b);
265 RCP<const Basic> result_;
270 virtual RCP<const Basic> apply(
const RCP<const Basic> &x);
272 void bvisit(
const Basic &x);
273 void bvisit(
const Add &x);
274 void bvisit(
const Mul &x);
275 void bvisit(
const Pow &x);
282 auto newarg1 = apply(farg1), newarg2 = apply(farg2);
283 if (farg1 != newarg1 or farg2 != newarg2) {
284 result_ = x.
create(newarg1, newarg2);
286 result_ = x.rcp_from_this();
294 template <
typename Derived,
typename First,
typename... Rest>
296 static const bool value = std::is_base_of<First, Derived>::value
300 template <
typename Derived,
typename First>
302 static const bool value = std::is_base_of<First, Derived>::value;
305 template <
typename... Args>
312 template <
typename T,
314 void bvisit(
const T &x)
316 s.insert(x.rcp_from_this());
317 visited.insert(x.rcp_from_this());
318 bvisit((
const Basic &)x);
321 void bvisit(
const Basic &x)
323 for (
const auto &p : x.
get_args()) {
324 auto iter = visited.insert(p->rcp_from_this());
331 set_basic apply(
const Basic &b)
338 template <
typename... Args>
339 inline set_basic atoms(
const Basic &b)
342 return visitor.apply(b);
353 void apply(
const Basic &b);
354 void bvisit(
const Mul &x);
355 void bvisit(
const Add &x);
356 void bvisit(
const Pow &x);
357 void bvisit(
const Number &x);
359 void bvisit(
const Symbol &x);
361 void bvisit(
const Basic &x);
364 template <
class Derived,
class Base = Visitor>
371 void visit(
const Cot &x)
override
375 void visit(
const Csc &x)
override
379 void visit(
const Sec &x)
override
383 void visit(
const ACot &x)
override
387 void visit(
const ACsc &x)
override
391 void visit(
const ASec &x)
override
395 void visit(
const Coth &x)
override
399 void visit(
const Csch &x)
override
403 void visit(
const Sech &x)
override
407 void visit(
const ACoth &x)
override
411 void visit(
const ACsch &x)
override
415 void visit(
const ASech &x)
override
421 SYMENGINE_EXPORT
unsigned count_ops(
const vec_basic &a);
The base class for representing addition in symbolic expressions.
static RCP< const Basic > from_dict(const RCP< const Number > &coef, umap_basic_num &&d)
Create an appropriate instance from dictionary quickly.
static void coef_dict_add_term(const Ptr< RCP< const Number >> &coef, umap_basic_num &d, const RCP< const Number > &c, const RCP< const Basic > &term)
Updates the numerical coefficient and the dictionary.
const RCP< const Number > & get_coef() const
The lowest unit of symbolic representation.
virtual vec_basic get_args() const =0
Returns the list of arguments.
ComplexBase Class for deriving all complex classes.
RCP< T > rcp_from_this()
Get RCP<T> pointer to self (it will cast the pointer to T)
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
RCP< const Basic > get_arg() const
RCP< const Basic > get_exp() const
RCP< const Basic > get_base() const
virtual RCP< const Basic > create(const RCP< const Basic > &a, const RCP< const Basic > &b) const =0
Method to construct classes with canonicalization.
RCP< const Basic > get_arg1() const
RCP< const Basic > get_arg2() const
Main namespace for SymEngine package.
RCP< const Basic > atan(const RCP< const Basic > &arg)
Canonicalize ATan:
RCP< const Basic > cos(const RCP< const Basic > &arg)
Canonicalize Cos:
RCP< const Basic > sinh(const RCP< const Basic > &arg)
Canonicalize Sinh:
RCP< const Basic > sin(const RCP< const Basic > &arg)
Canonicalize Sin:
RCP< const Basic > tan(const RCP< const Basic > &arg)
Canonicalize Tan:
RCP< const Basic > acos(const RCP< const Basic > &arg)
Canonicalize ACos:
RCP< const Basic > tanh(const RCP< const Basic > &arg)
Canonicalize Tanh:
RCP< const Basic > asin(const RCP< const Basic > &arg)
Canonicalize ASin:
RCP< const Basic > cosh(const RCP< const Basic > &arg)
Canonicalize Cosh:
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
RCP< const Basic > atanh(const RCP< const Basic > &arg)
Canonicalize ATanh:
RCP< const Basic > acosh(const RCP< const Basic > &arg)
Canonicalize ACosh:
RCP< const Basic > asinh(const RCP< const Basic > &arg)
Canonicalize ASinh: