Loading...
Searching...
No Matches
SymEngine::XReplaceVisitor Class Reference
+ Inheritance diagram for SymEngine::XReplaceVisitor:
+ Collaboration diagram for SymEngine::XReplaceVisitor:

Public Member Functions

 XReplaceVisitor (const map_basic_basic &subs_dict, bool cache=true)
 
void bvisit (const Basic &x)
 
void bvisit (const Add &x)
 
void bvisit (const Mul &x)
 
void bvisit (const Pow &x)
 
void bvisit (const OneArgFunction &x)
 
template<class T >
void bvisit (const TwoArgBasic< T > &x)
 
void bvisit (const MultiArgFunction &x)
 
void bvisit (const FunctionSymbol &x)
 
void bvisit (const Contains &x)
 
void bvisit (const And &x)
 
void bvisit (const Or &x)
 
void bvisit (const Not &x)
 
void bvisit (const Xor &x)
 
void bvisit (const FiniteSet &x)
 
void bvisit (const ImageSet &x)
 
void bvisit (const Union &x)
 
void bvisit (const Piecewise &pw)
 
void bvisit (const Derivative &x)
 
void bvisit (const Subs &x)
 
void bvisit (const ComplexBase &x)
 
RCP< const Basicapply (const Basic &x)
 
RCP< const Basicapply (const RCP< const Basic > &x)
 

Protected Attributes

RCP< const Basicresult_
 
const map_basic_basicsubs_dict_
 
map_basic_basic visited
 
bool cache
 

Detailed Description

Definition at line 25 of file subs.h.

Constructor & Destructor Documentation

◆ XReplaceVisitor()

SymEngine::XReplaceVisitor::XReplaceVisitor ( const map_basic_basic subs_dict,
bool  cache = true 
)
inline

Definition at line 35 of file subs.h.

36 : subs_dict_(subs_dict), cache(cache)
37 {
38 if (cache) {
39 visited = subs_dict;
40 }
41 }

Member Function Documentation

◆ apply() [1/2]

RCP< const Basic > SymEngine::XReplaceVisitor::apply ( const Basic x)
inline

Definition at line 319 of file subs.h.

320 {
321 return apply(x.rcp_from_this());
322 }

◆ apply() [2/2]

RCP< const Basic > SymEngine::XReplaceVisitor::apply ( const RCP< const Basic > &  x)
inline

Definition at line 324 of file subs.h.

325 {
326 if (cache) {
327 auto it = visited.find(x);
328 if (it != visited.end()) {
329 result_ = it->second;
330 } else {
331 x->accept(*this);
332 insert(visited, x, result_);
333 }
334 } else {
335 auto it = subs_dict_.find(x);
336 if (it != subs_dict_.end()) {
337 result_ = it->second;
338 } else {
339 x->accept(*this);
340 }
341 }
342 return result_;
343 }
T end(T... args)
T find(T... args)
void insert(T1 &m, const T2 &first, const T3 &second)
Definition: dict.h:83

◆ bvisit() [1/20]

void SymEngine::XReplaceVisitor::bvisit ( const Add x)
inline

Definition at line 48 of file subs.h.

49 {
51 RCP<const Number> coef;
52
53 auto it = subs_dict_.find(x.get_coef());
54 if (it != subs_dict_.end()) {
55 coef = zero;
56 Add::coef_dict_add_term(outArg(coef), d, one, it->second);
57 } else {
58 coef = x.get_coef();
59 }
60
61 for (const auto &p : x.get_dict()) {
62 auto it
63 = subs_dict_.find(Add::from_dict(zero, {{p.first, p.second}}));
64 if (it != subs_dict_.end()) {
65 Add::coef_dict_add_term(outArg(coef), d, one, it->second);
66 } else {
67 it = subs_dict_.find(p.second);
68 if (it != subs_dict_.end()) {
69 Add::coef_dict_add_term(outArg(coef), d, one,
70 mul(it->second, apply(p.first)));
71 } else {
72 Add::coef_dict_add_term(outArg(coef), d, p.second,
73 apply(p.first));
74 }
75 }
76 }
77 result_ = Add::from_dict(coef, std::move(d));
78 }
static RCP< const Basic > from_dict(const RCP< const Number > &coef, umap_basic_num &&d)
Create an appropriate instance from dictionary quickly.
Definition: add.cpp:140
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.
Definition: add.cpp:261
T move(T... args)
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352

◆ bvisit() [2/20]

void SymEngine::XReplaceVisitor::bvisit ( const And x)
inline

Definition at line 191 of file subs.h.

192 {
193 set_boolean v;
194 for (const auto &elem : x.get_container()) {
195 auto a = apply(elem);
196 if (not is_a_Boolean(*a))
197 throw SymEngineException("expected an object of type Boolean");
198 v.insert(rcp_static_cast<const Boolean>(a));
199 }
200 result_ = logical_and(v);
201 }

◆ bvisit() [3/20]

void SymEngine::XReplaceVisitor::bvisit ( const Basic x)
inline

Definition at line 43 of file subs.h.

44 {
45 result_ = x.rcp_from_this();
46 }

◆ bvisit() [4/20]

void SymEngine::XReplaceVisitor::bvisit ( const ComplexBase x)
inline

Definition at line 308 of file subs.h.

309 {
310 auto it = subs_dict_.find(I);
311 if (it != subs_dict_.end()) {
312 result_ = add(apply(x.real_part()),
313 mul(apply(x.imaginary_part()), it->second));
314 } else {
315 result_ = x.rcp_from_this();
316 }
317 }
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
Definition: add.cpp:425

◆ bvisit() [5/20]

void SymEngine::XReplaceVisitor::bvisit ( const Contains x)
inline

Definition at line 178 of file subs.h.

179 {
180 RCP<const Basic> a = apply(x.get_expr());
181 auto c = apply(x.get_set());
182 if (not is_a_Set(*c))
183 throw SymEngineException("expected an object of type Set");
184 RCP<const Set> b = rcp_static_cast<const Set>(c);
185 if (a == x.get_expr() and b == x.get_set())
186 result_ = x.rcp_from_this();
187 else
188 result_ = x.create(a, b);
189 }

◆ bvisit() [6/20]

void SymEngine::XReplaceVisitor::bvisit ( const Derivative x)
inline

Definition at line 285 of file subs.h.

286 {
287 auto expr = apply(x.get_arg());
288 for (const auto &sym : x.get_symbols()) {
289 auto s = apply(sym);
290 if (not is_a<Symbol>(*s)) {
291 throw SymEngineException("expected an object of type Symbol");
292 }
293 expr = expr->diff(rcp_static_cast<const Symbol>(s));
294 }
295 result_ = expr;
296 }

◆ bvisit() [7/20]

void SymEngine::XReplaceVisitor::bvisit ( const FiniteSet x)
inline

Definition at line 235 of file subs.h.

236 {
237 set_basic v;
238 for (const auto &elem : x.get_container()) {
239 v.insert(apply(elem));
240 }
241 result_ = x.create(v);
242 }
T insert(T... args)

◆ bvisit() [8/20]

void SymEngine::XReplaceVisitor::bvisit ( const FunctionSymbol x)
inline

Definition at line 169 of file subs.h.

170 {
171 vec_basic v = x.get_args();
172 for (auto &elem : v) {
173 elem = apply(elem);
174 }
175 result_ = x.create(v);
176 }

◆ bvisit() [9/20]

void SymEngine::XReplaceVisitor::bvisit ( const ImageSet x)
inline

Definition at line 244 of file subs.h.

245 {
246 RCP<const Basic> s = apply(x.get_symbol());
247 RCP<const Basic> expr = apply(x.get_expr());
248 auto bs_ = apply(x.get_baseset());
249 if (not is_a_Set(*bs_))
250 throw SymEngineException("expected an object of type Set");
251 RCP<const Set> bs = rcp_static_cast<const Set>(bs_);
252 if (s == x.get_symbol() and expr == x.get_expr()
253 and bs == x.get_baseset()) {
254 result_ = x.rcp_from_this();
255 } else {
256 result_ = x.create(s, expr, bs);
257 }
258 }

◆ bvisit() [10/20]

void SymEngine::XReplaceVisitor::bvisit ( const Mul x)
inline

Definition at line 80 of file subs.h.

81 {
82 RCP<const Number> coef = one;
83 map_basic_basic d;
84 for (const auto &p : x.get_dict()) {
85 RCP<const Basic> factor_old;
86 if (eq(*p.second, *one)) {
87 factor_old = p.first;
88 } else {
89 factor_old = make_rcp<Pow>(p.first, p.second);
90 }
91 RCP<const Basic> factor = apply(factor_old);
92 if (factor == factor_old) {
93 // TODO: Check if Mul::dict_add_term is enough
94 Mul::dict_add_term_new(outArg(coef), d, p.second, p.first);
95 } else if (is_a_Number(*factor)) {
96 imulnum(outArg(coef), rcp_static_cast<const Number>(factor));
97 } else if (is_a<Mul>(*factor)) {
98 RCP<const Mul> tmp = rcp_static_cast<const Mul>(factor);
99 imulnum(outArg(coef), tmp->get_coef());
100 for (const auto &q : tmp->get_dict()) {
101 Mul::dict_add_term_new(outArg(coef), d, q.second, q.first);
102 }
103 } else {
104 RCP<const Basic> exp, t;
105 Mul::as_base_exp(factor, outArg(exp), outArg(t));
106 Mul::dict_add_term_new(outArg(coef), d, exp, t);
107 }
108 }
109
110 // Replace the coefficient
111 RCP<const Basic> factor = apply(x.get_coef());
112 if (is_a_Number(*factor)) {
113 imulnum(outArg(coef), rcp_static_cast<const Number>(factor));
114 } else if (is_a<Mul>(*factor)) {
115 RCP<const Mul> tmp = rcp_static_cast<const Mul>(factor);
116 imulnum(outArg(coef), tmp->get_coef());
117 for (const auto &q : tmp->get_dict()) {
118 Mul::dict_add_term_new(outArg(coef), d, q.second, q.first);
119 }
120 } else {
121 RCP<const Basic> exp, t;
122 Mul::as_base_exp(factor, outArg(exp), outArg(t));
123 Mul::dict_add_term_new(outArg(coef), d, exp, t);
124 }
125 result_ = Mul::from_dict(coef, std::move(d));
126 }
static void as_base_exp(const RCP< const Basic > &self, const Ptr< RCP< const Basic > > &exp, const Ptr< RCP< const Basic > > &base)
Convert to a base and exponent form.
Definition: mul.cpp:320
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
Definition: mul.cpp:115
bool is_a_Number(const Basic &b)
Definition: number.h:130
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
Definition: pow.cpp:271
int factor(const Ptr< RCP< const Integer > > &f, const Integer &n, double B1)
Definition: ntheory.cpp:370

◆ bvisit() [11/20]

void SymEngine::XReplaceVisitor::bvisit ( const MultiArgFunction x)
inline

Definition at line 160 of file subs.h.

161 {
162 vec_basic v = x.get_args();
163 for (auto &elem : v) {
164 elem = apply(elem);
165 }
166 result_ = x.create(v);
167 }

◆ bvisit() [12/20]

void SymEngine::XReplaceVisitor::bvisit ( const Not x)
inline

Definition at line 215 of file subs.h.

216 {
217 RCP<const Basic> a = apply(x.get_arg());
218 if (not is_a_Boolean(*a))
219 throw SymEngineException("expected an object of type Boolean");
220 result_ = logical_not(rcp_static_cast<const Boolean>(a));
221 }

◆ bvisit() [13/20]

void SymEngine::XReplaceVisitor::bvisit ( const OneArgFunction x)
inline

Definition at line 139 of file subs.h.

140 {
141 apply(x.get_arg());
142 if (result_ == x.get_arg()) {
143 result_ = x.rcp_from_this();
144 } else {
145 result_ = x.create(result_);
146 }
147 }

◆ bvisit() [14/20]

void SymEngine::XReplaceVisitor::bvisit ( const Or x)
inline

Definition at line 203 of file subs.h.

204 {
205 set_boolean v;
206 for (const auto &elem : x.get_container()) {
207 auto a = apply(elem);
208 if (not is_a_Boolean(*a))
209 throw SymEngineException("expected an object of type Boolean");
210 v.insert(rcp_static_cast<const Boolean>(a));
211 }
212 result_ = logical_or(v);
213 }

◆ bvisit() [15/20]

void SymEngine::XReplaceVisitor::bvisit ( const Piecewise pw)
inline

Definition at line 272 of file subs.h.

273 {
274 PiecewiseVec pwv;
275 pwv.reserve(pw.get_vec().size());
276 for (const auto &expr_pred : pw.get_vec()) {
277 const auto expr = apply(*expr_pred.first);
278 const auto pred = apply(*expr_pred.second);
279 pwv.emplace_back(
280 std::make_pair(expr, rcp_static_cast<const Boolean>(pred)));
281 }
282 result_ = piecewise(std::move(pwv));
283 }
T make_pair(T... args)
T reserve(T... args)

◆ bvisit() [16/20]

void SymEngine::XReplaceVisitor::bvisit ( const Pow x)
inline

Definition at line 128 of file subs.h.

129 {
130 RCP<const Basic> base_new = apply(x.get_base());
131 RCP<const Basic> exp_new = apply(x.get_exp());
132 if (base_new == x.get_base() and exp_new == x.get_exp()) {
133 result_ = x.rcp_from_this();
134 } else {
135 result_ = pow(base_new, exp_new);
136 }
137 }
T pow(T... args)

◆ bvisit() [17/20]

void SymEngine::XReplaceVisitor::bvisit ( const Subs x)
inline

Definition at line 298 of file subs.h.

299 {
300 auto expr = apply(x.get_arg());
301 map_basic_basic new_subs_dict;
302 for (const auto &sym : x.get_dict()) {
303 insert(new_subs_dict, apply(sym.first), apply(sym.second));
304 }
305 result_ = subs(expr, new_subs_dict);
306 }

◆ bvisit() [18/20]

template<class T >
void SymEngine::XReplaceVisitor::bvisit ( const TwoArgBasic< T > &  x)
inline

Definition at line 150 of file subs.h.

151 {
152 RCP<const Basic> a = apply(x.get_arg1());
153 RCP<const Basic> b = apply(x.get_arg2());
154 if (a == x.get_arg1() and b == x.get_arg2())
155 result_ = x.rcp_from_this();
156 else
157 result_ = x.create(a, b);
158 }

◆ bvisit() [19/20]

void SymEngine::XReplaceVisitor::bvisit ( const Union x)
inline

Definition at line 260 of file subs.h.

261 {
262 set_set v;
263 for (const auto &elem : x.get_container()) {
264 auto a = apply(elem);
265 if (not is_a_Set(*a))
266 throw SymEngineException("expected an object of type Set");
267 v.insert(rcp_static_cast<const Set>(a));
268 }
269 result_ = x.create(v);
270 }

◆ bvisit() [20/20]

void SymEngine::XReplaceVisitor::bvisit ( const Xor x)
inline

Definition at line 223 of file subs.h.

224 {
225 vec_boolean v;
226 for (const auto &elem : x.get_container()) {
227 auto a = apply(elem);
228 if (not is_a_Boolean(*a))
229 throw SymEngineException("expected an object of type Boolean");
230 v.push_back(rcp_static_cast<const Boolean>(a));
231 }
232 result_ = logical_xor(v);
233 }

Field Documentation

◆ cache

bool SymEngine::XReplaceVisitor::cache
protected

Definition at line 32 of file subs.h.

◆ result_

RCP<const Basic> SymEngine::XReplaceVisitor::result_
protected

Definition at line 29 of file subs.h.

◆ subs_dict_

const map_basic_basic& SymEngine::XReplaceVisitor::subs_dict_
protected

Definition at line 30 of file subs.h.

◆ visited

map_basic_basic SymEngine::XReplaceVisitor::visited
protected

Definition at line 31 of file subs.h.


The documentation for this class was generated from the following file: