2 #include <symengine/polys/basic_conversions.h>
5 #define ACCEPT(CLASS) \
6 void CLASS::accept(Visitor &v) const \
14 #define SYMENGINE_ENUM(TypeID, Class) ACCEPT(Class)
15 #include "symengine/type_codes.inc"
18 void preorder_traversal(
const Basic &b, Visitor &v)
21 for (
const auto &p : b.get_args())
22 preorder_traversal(*p, v);
25 void postorder_traversal(
const Basic &b, Visitor &v)
27 for (
const auto &p : b.get_args())
28 postorder_traversal(*p, v);
32 void preorder_traversal_stop(
const Basic &b, StopVisitor &v)
37 for (
const auto &p : b.get_args()) {
38 preorder_traversal_stop(*p, v);
44 void postorder_traversal_stop(
const Basic &b, StopVisitor &v)
46 for (
const auto &p : b.get_args()) {
47 postorder_traversal_stop(*p, v);
54 bool has_symbol(
const Basic &b,
const Basic &x)
59 HasSymbolVisitor v(ptrFromRef(x));
63 RCP<const Basic> coeff(
const Basic &b,
const Basic &x,
const Basic &n)
65 if (!(is_a<Symbol>(x) || is_a<FunctionSymbol>(x))) {
66 throw NotImplementedError(
"Not implemented for non (Function)Symbols.");
68 CoeffVisitor v(ptrFromRef(x), ptrFromRef(n));
78 void bvisit(
const Symbol &x)
83 void bvisit(
const Subs &x)
85 set_basic set_ = free_symbols(*x.get_arg());
86 for (
const auto &p : x.get_variables()) {
90 for (
const auto &p : x.get_point()) {
91 auto iter = v.
insert(p->rcp_from_this());
98 void bvisit(
const Basic &x)
100 for (
const auto &p : x.
get_args()) {
101 auto iter = v.
insert(p->rcp_from_this());
116 for (
unsigned i = 0; i < m.nrows(); i++) {
117 for (
unsigned j = 0; j < m.ncols(); j++) {
118 m.get(i, j)->accept(*
this);
128 return visitor.apply(m);
131 set_basic free_symbols(
const Basic &b)
133 FreeSymbolsVisitor visitor;
134 return visitor.apply(b);
137 set_basic function_symbols(
const Basic &b)
139 return atoms<FunctionSymbol>(b);
142 RCP<const Basic> TransformVisitor::apply(
const RCP<const Basic> &x)
148 void TransformVisitor::bvisit(
const Basic &x)
150 result_ = x.rcp_from_this();
153 void TransformVisitor::bvisit(
const Add &x)
156 for (
const auto &a : x.get_args()) {
159 result_ =
add(newargs);
162 void TransformVisitor::bvisit(
const Mul &x)
165 for (
const auto &a : x.get_args()) {
168 result_ =
mul(newargs);
171 void TransformVisitor::bvisit(
const Pow &x)
173 auto base_ = x.get_base(), exp_ = x.get_exp();
174 auto newarg1 = apply(base_), newarg2 = apply(exp_);
175 if (base_ != newarg1 or exp_ != newarg2) {
176 result_ =
pow(newarg1, newarg2);
178 result_ = x.rcp_from_this();
182 void TransformVisitor::bvisit(
const OneArgFunction &x)
184 auto farg = x.get_arg();
185 auto newarg = apply(farg);
186 if (
eq(*newarg, *farg)) {
187 result_ = x.rcp_from_this();
189 result_ = x.create(newarg);
193 void TransformVisitor::bvisit(
const MultiArgFunction &x)
195 auto fargs = x.get_args();
197 for (
const auto &a : fargs) {
200 auto nbarg = x.create(newargs);
204 void TransformVisitor::bvisit(
const Piecewise &x)
206 auto branch_cond_pairs = x.get_vec();
207 PiecewiseVec new_pairs;
208 for (
const auto &branch_cond : branch_cond_pairs) {
209 auto branch = branch_cond.first;
210 auto cond = branch_cond.second;
211 auto new_branch = apply(branch);
212 auto new_cond = apply(cond);
213 if (!is_a_Boolean(*new_cond)) {
214 new_cond =
Eq(new_cond, boolTrue);
217 {new_branch, rcp_static_cast<const Boolean>(new_cond)});
219 result_ = piecewise(new_pairs);
222 void preorder_traversal_local_stop(
const Basic &b, LocalStopVisitor &v)
225 if (v.stop_ or v.local_stop_)
227 for (
const auto &p : b.get_args()) {
228 preorder_traversal_local_stop(*p, v);
234 void CountOpsVisitor::apply(
const Basic &b)
236 unsigned count_now = count;
237 auto it = v.find(b.rcp_from_this());
240 insert(v, b.rcp_from_this(), count - count_now);
246 void CountOpsVisitor::bvisit(
const Mul &x)
248 if (
neq(*(x.get_coef()), *one)) {
250 apply(*x.get_coef());
253 for (
const auto &p : x.get_dict()) {
254 if (
neq(*p.second, *one)) {
264 void CountOpsVisitor::bvisit(
const Add &x)
266 if (
neq(*(x.get_coef()), *zero)) {
268 apply(*x.get_coef());
271 for (
const auto &p : x.get_dict()) {
272 if (
neq(*p.second, *one)) {
282 void CountOpsVisitor::bvisit(
const Pow &x)
286 apply(*x.get_base());
289 void CountOpsVisitor::bvisit(
const Number &x) {}
291 void CountOpsVisitor::bvisit(
const ComplexBase &x)
293 if (
neq(*x.real_part(), *zero)) {
297 if (
neq(*x.imaginary_part(), *one)) {
302 void CountOpsVisitor::bvisit(
const Symbol &x) {}
304 void CountOpsVisitor::bvisit(
const Constant &x) {}
306 void CountOpsVisitor::bvisit(
const Basic &x)
309 for (
const auto &p : x.get_args()) {
314 unsigned count_ops(
const vec_basic &a)
The lowest unit of symbolic representation.
virtual vec_basic get_args() const =0
Returns the list of arguments.
RCP< T > rcp_from_this()
Get RCP<T> pointer to self (it will cast the pointer to T)
Main namespace for SymEngine package.
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
void insert(T1 &m, const T2 &first, const T3 &second)
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
RCP< const Boolean > Eq(const RCP< const Basic > &lhs)
Returns the canonicalized Equality object from a single argument.
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b