65 : coef_{coef}, dict_{
std::move(dict)} {
66 SYMENGINE_ASSIGN_TYPEID()
74 hash_t seed = SYMENGINE_ADD, temp;
75 hash_combine<Basic>(seed, *
coef_);
76 for (
const auto &p :
dict_) {
77 temp = p.first->hash();
78 hash_combine<Basic>(temp, *(p.second));
90 if (is_a<Add>(o) and
eq(*
coef_, *(down_cast<const Add &>(o).
coef_))
91 and unified_eq(
dict_, down_cast<const Add &>(o).
dict_))
109 SYMENGINE_ASSERT(is_a<Add>(o))
110 const Add &s = down_cast<const Add &>(o);
145 }
else if (d.size() == 1 and coef->is_zero()) {
147 if (is_a<Integer>(*(p->second))) {
148 if (down_cast<const Integer &>(*(p->second)).is_zero()) {
151 if (down_cast<const Integer &>(*(p->second)).is_one()) {
154 if (is_a<Mul>(*(p->first))) {
155 #if !defined(WITH_SYMENGINE_THREAD_SAFE) && defined(WITH_SYMENGINE_RCP)
156 if (down_cast<const Mul &>(*(p->first)).use_count() == 1) {
164 = down_cast<const Mul &>(*(p->first)).get_dict();
173 = down_cast<const Mul &>(*(p->first)).get_dict();
180 if (is_a<Pow>(*(p->first))) {
181 insert(m, down_cast<const Pow &>(*(p->first)).get_base(),
182 down_cast<const Pow &>(*(p->first)).get_exp());
186 return make_rcp<const Mul>(p->second,
191 if (is_a<Mul>(*(p->first))) {
192 #if !defined(WITH_SYMENGINE_THREAD_SAFE) && defined(WITH_SYMENGINE_RCP)
193 if (down_cast<const Mul &>(*(p->first)).use_count() == 1) {
201 = down_cast<const Mul &>(*(p->first)).get_dict();
210 = down_cast<const Mul &>(*(p->first)).get_dict();
215 if (is_a<Pow>(*p->first)) {
216 insert(m, down_cast<const Pow &>(*(p->first)).get_base(),
217 down_cast<const Pow &>(*(p->first)).get_exp());
221 return make_rcp<const Mul>(p->second,
std::move(m));
224 insert(m, p->second, one);
225 return make_rcp<const Mul>(one,
std::move(m));
228 return make_rcp<const Add>(coef,
std::move(d));
238 const RCP<const Basic> &t)
243 if (not(coef->is_zero()))
246 iaddnum(outArg(it->second), coef);
247 if (it->second->is_zero())
263 const RCP<const Basic> &term)
266 iaddnum(coef,
mulnum(c, rcp_static_cast<const Number>(term)));
267 }
else if (is_a<Add>(*term)) {
269 for (
const auto &q : (down_cast<const Add &>(*term)).
dict_)
271 iaddnum(coef, down_cast<const Add &>(*term).coef_);
276 RCP<const Number> coef2;
288 const Ptr<RCP<const Basic>> &b)
const
291 *a =
mul(p->first, p->second);
307 const Ptr<RCP<const Number>> &coef,
308 const Ptr<RCP<const Basic>> &term)
310 if (is_a<Mul>(*
self)) {
311 if (
neq(*(down_cast<const Mul &>(*self).get_coef()), *one)) {
312 *coef = (down_cast<const Mul &>(*
self)).
get_coef();
321 *coef = rcp_static_cast<const Number>(
self);
324 SYMENGINE_ASSERT(not is_a<Add>(*
self));
353 if (dict.
size() == 0)
355 if (dict.
size() == 1) {
361 for (
const auto &p : dict) {
364 if (p.second ==
null)
370 if (is_a<Integer>(*p.first)
371 and down_cast<const Integer &>(*p.first).is_one())
375 and down_cast<const Number &>(*p.second).is_zero())
379 if (is_a<Mul>(*p.first)
380 and not(down_cast<const Mul &>(*p.first).get_coef()->is_one()))
400 if (not
coef_->is_zero()) {
406 for (
const auto &p :
dict_) {
407 if (
eq(*p.second, *one)) {
425 RCP<const Basic>
add(
const RCP<const Basic> &a,
const RCP<const Basic> &b)
428 RCP<const Number> coef;
430 if (is_a<Add>(*a) and is_a<Add>(*b)) {
431 coef = (down_cast<const Add &>(*a)).
get_coef();
432 d = (down_cast<const Add &>(*a)).get_dict();
433 for (
const auto &p : (down_cast<const Add &>(*b)).get_dict())
435 iaddnum(outArg(coef), down_cast<const Add &>(*b).get_coef());
436 }
else if (is_a<Add>(*a)) {
437 coef = (down_cast<const Add &>(*a)).
get_coef();
438 d = (down_cast<const Add &>(*a)).get_dict();
440 if (not down_cast<const Number &>(*b).is_zero()) {
441 iaddnum(outArg(coef), rcp_static_cast<const Number>(b));
444 RCP<const Number> coef2;
448 }
else if (is_a<Add>(*b)) {
449 coef = (down_cast<const Add &>(*b)).
get_coef();
450 d = (down_cast<const Add &>(*b)).get_dict();
452 if (not down_cast<const Number &>(*a).is_zero()) {
453 iaddnum(outArg(coef), rcp_static_cast<const Number>(a));
456 RCP<const Number> coef2;
465 auto it = d.
find(one);
484 RCP<const Number> coef = zero;
485 for (
const auto &i : a) {
495 RCP<const Basic>
sub(
const RCP<const Basic> &a,
const RCP<const Basic> &b)
497 return add(a,
mul(minus_one, b));
Classes and functions relating to the binary operation of addition.
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.
bool __eq__(const Basic &o) const override
Test equality.
RCP< const Number > coef_
RCP< const Basic > sub(const RCP< const Basic > &a, const RCP< const Basic > &b)
Substracts b from a.
vec_basic get_args() const override
Returns the arguments of the Add.
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.
void as_two_terms(const Ptr< RCP< const Basic >> &a, const Ptr< RCP< const Basic >> &b) const
Converts the Add into a sum of two Basic objects.
bool is_canonical(const RCP< const Number > &coef, const umap_basic_num &dict) const
Checks if a given dictionary and coeffient is in cannonical form.
int compare(const Basic &o) const override
Compares Add objects.
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
const RCP< const Number > & get_coef() const
static void dict_add_term(umap_basic_num &d, const RCP< const Number > &coef, const RCP< const Basic > &t)
Adds a new term to the expression.
Add(const RCP< const Number > &coef, umap_basic_num &&dict)
Default constructor.
static void as_coef_term(const RCP< const Basic > &self, const Ptr< RCP< const Number >> &coef, const Ptr< RCP< const Basic >> &term)
Converts a Basic self into the form of coefficient * term.
hash_t __hash__() const override
Generates the hash representation.
The lowest unit of symbolic representation.
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
Main namespace for SymEngine package.
bool is_a_Number(const Basic &b)
RCP< const Number > mulnum(const RCP< const Number > &self, const RCP< const Number > &other)
Multiply self and other
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)
int unified_compare(const T &a, const T &b)
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b