SymEngine::Mul Class Reference

#include <mul.h>

+ Inheritance diagram for SymEngine::Mul:
+ Collaboration diagram for SymEngine::Mul:

Public Member Functions

virtual void accept (Visitor &v) const
 
virtual void accept (EvalRealDoubleVisitorFinal &v) const
 
 Mul (const RCP< const Number > &coef, map_basic_basic &&dict)
 
virtual hash_t __hash__ () const
 
virtual bool __eq__ (const Basic &o) const
 
virtual int compare (const Basic &o) const
 
void as_two_terms (const Ptr< RCP< const Basic >> &a, const Ptr< RCP< const Basic >> &b) const
 Rewrite as 2 terms. More...
 
void power_num (const Ptr< RCP< const Number >> &coef, map_basic_basic &d, const RCP< const Number > &exp) const
 Power all terms with the exponent exp
 
bool is_canonical (const RCP< const Number > &coef, const map_basic_basic &dict) const
 
virtual vec_basic get_args () const
 Returns the list of arguments.
 
const RCP< const Number > & get_coef () const
 
const map_basic_basicget_dict () const
 
- Public Member Functions inherited from SymEngine::Basic
TypeID get_type_code () const
 
 Basic ()
 Constructor.
 
 Basic (const Basic &)=delete
 Delete the copy constructor and assignment.
 
Basicoperator= (const Basic &)=delete
 Assignment operator in continuation with above.
 
 Basic (Basic &&)=delete
 Delete the move constructor and assignment.
 
Basicoperator= (Basic &&)=delete
 Assignment operator in continuation with above.
 
hash_t hash () const
 
bool __neq__ (const Basic &o) const
 true if this is not equal to o. More...
 
int __cmp__ (const Basic &o) const
 Comparison operator.
 
std::string __str__ () const
 
RCP< const Basicsubs (const map_basic_basic &subs_dict) const
 Substitutes 'subs_dict' into 'self'.
 
RCP< const Basicxreplace (const map_basic_basic &subs_dict) const
 
virtual RCP< const Basicexpand_as_exp () const
 expands the special function in terms of exp function
 
RCP< const Basicdiff (const RCP< const Symbol > &x, bool cache=true) const
 
- Public Member Functions inherited from SymEngine::EnableRCPFromThis< Basic >
RCP< Basicrcp_from_this ()
 Get RCP<T> pointer to self (it will cast the pointer to T)
 
RCP< const Basicrcp_from_this () const
 Get RCP<const T> pointer to self (it will cast the pointer to const T)
 
RCP< const T2 > rcp_from_this_cast () const
 Get RCP<T2> pointer to self (it will cast the pointer to T2)
 
unsigned int use_count () const
 

Static Public Member Functions

static RCP< const Basicfrom_dict (const RCP< const Number > &coef, map_basic_basic &&d)
 Create a Mul from a dict.
 
static void dict_add_term (map_basic_basic &d, const RCP< const Basic > &exp, const RCP< const Basic > &t)
 Add terms to dict.
 
static void dict_add_term_new (const Ptr< RCP< const Number >> &coef, map_basic_basic &d, const RCP< const Basic > &exp, const RCP< const Basic > &t)
 
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.
 

Static Public Attributes

static const TypeID type_code_id = SYMENGINE_MUL
 the dictionary of the rest (e.g. x*y in 2*x*y) More...
 

Private Attributes

RCP< const Numbercoef_
 
map_basic_basic dict_
 The coefficient (e.g. 2 in 2*x*y)
 

Additional Inherited Members

- Data Fields inherited from SymEngine::Basic
TypeID type_code_
 

Detailed Description

Mul class keeps a product of symbolic expressions. Internal representation of an Mul is a numeric coefficient coef_ and a dictionary dict_ of key-value pairs.

 Mul(coef_, {{key1, value1}, {key2, value2}, ... })

This represents the following expression,

 coef_ * key1^value1 * key2^value2 * ...

coef_ is an objecct of type Number, i.e. a numeric coefficient like Integer, RealDouble, Complex.

For example, the following are valid representations

 Mul(2, {{x, 2}, {y, 5}})
 Mul(3, {{x, 1}, {y, 4}, {z, 3}})

Following are invalid representations. (valid equivalent is shown next to them)

When key is a numeric and value is an integers,

Mul(2, {{3, 2}, {x, 2}}) -> Mul(18, {{x, 2}}) Mul(2, {{I, 3}, {x, 2}}) -> Mul(-2*I, {{x, 2}})

When key is an integer and value is a Rational not in the range (0, 1)

Mul(2, {{3, 3/2}, {x, 2}}) -> Mul(6, {{3, 1/2}, {x, 2}}) Mul(2, {{3, -1/2}, {x, 2}}) -> Mul(2/3, {{3, 1/2}, {x, 2}})

When the value is zero

Mul(3, {{x, 0}, {y, 2}}) -> Mul(3, {{y, 2}})

When key and value are numeric and one of them is inexact

Mul(2, {{3, 0.5}, {x, 2}}) -> Mul(3.464..., {x, 2}})

When coef_ is one and the dictionary is of size 1

Mul(1, {{x, 2}}) -> Pow(x, 2)

When coef_ is zero

Mul(0, {{x, 2}}) -> Integer(0) Mul(0.0, {{x, 2}}) -> RealDouble(0.0)

When key is 1

Mul(2, {{1, x}, {x, 2}}) -> Mul(2, {{x, 2}})

When value is zero

Mul(2, {{1, x}, {x, 2}}) -> Mul(2, {{x, 2}})

Definition at line 73 of file mul.h.

Constructor & Destructor Documentation

◆ Mul()

SymEngine::Mul::Mul ( const RCP< const Number > &  coef,
map_basic_basic &&  dict 
)

Constructs Mul from a dictionary by copying the contents of the dictionary:

Definition at line 10 of file mul.cpp.

11  : coef_{coef}, dict_{std::move(dict)}
12 {
13  SYMENGINE_ASSIGN_TYPEID()
14  SYMENGINE_ASSERT(is_canonical(coef, dict_))
15 }
bool is_canonical(const RCP< const Number > &coef, const map_basic_basic &dict) const
Definition: mul.cpp:17
map_basic_basic dict_
The coefficient (e.g. 2 in 2*x*y)
Definition: mul.h:78
T move(T... args)

Member Function Documentation

◆ __eq__()

bool SymEngine::Mul::__eq__ ( const Basic o) const
virtual

Equality comparator

Parameters
o- Object to be compared with
Returns
whether the 2 objects are equal

Implements SymEngine::Basic.

Definition at line 90 of file mul.cpp.

91 {
92  if (is_a<Mul>(o) and eq(*coef_, *(down_cast<const Mul &>(o).coef_))
93  and unified_eq(dict_, down_cast<const Mul &>(o).dict_))
94  return true;
95 
96  return false;
97 }
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21

◆ __hash__()

hash_t SymEngine::Mul::__hash__ ( ) const
virtual
Returns
size of the hash

Implements SymEngine::Basic.

Definition at line 79 of file mul.cpp.

80 {
81  hash_t seed = SYMENGINE_MUL;
82  hash_combine<Basic>(seed, *coef_);
83  for (const auto &p : dict_) {
84  hash_combine<Basic>(seed, *(p.first));
85  hash_combine<Basic>(seed, *(p.second));
86  }
87  return seed;
88 }

◆ as_two_terms()

void SymEngine::Mul::as_two_terms ( const Ptr< RCP< const Basic >> &  a,
const Ptr< RCP< const Basic >> &  b 
) const

Rewrite as 2 terms.

Example: if this=3*x**2*y**2*z**2, thena=x**2andb=3*y**2*z**2`

Definition at line 304 of file mul.cpp.

306 {
307  // Example: if this=3*x**2*y**2*z**2, then a=x**2 and b=3*y**2*z**2
308  auto p = dict_.begin();
309  *a = pow(p->first, p->second);
310  map_basic_basic d = dict_;
311  d.erase(p->first);
312  *b = Mul::from_dict(coef_, std::move(d));
313 }
T begin(T... args)
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
Definition: mul.cpp:116
T erase(T... args)
T pow(T... args)

◆ compare()

int SymEngine::Mul::compare ( const Basic o) const
virtual

Returns -1, 0, 1 for this < o, this == o, this > o. This method is used when you want to sort things like x+y+z into canonical order. This function assumes that o is the same type as this. Use __cmp__ if you want general comparison.

Implements SymEngine::Basic.

Definition at line 99 of file mul.cpp.

100 {
101  SYMENGINE_ASSERT(is_a<Mul>(o))
102  const Mul &s = down_cast<const Mul &>(o);
103  // # of elements
104  if (dict_.size() != s.dict_.size())
105  return (dict_.size() < s.dict_.size()) ? -1 : 1;
106 
107  // coef
108  int cmp = coef_->__cmp__(*s.coef_);
109  if (cmp != 0)
110  return cmp;
111 
112  // Compare dictionaries:
113  return unified_compare(dict_, s.dict_);
114 }
Mul(const RCP< const Number > &coef, map_basic_basic &&dict)
Definition: mul.cpp:10
int unified_compare(const T &a, const T &b)
Definition: dict.h:205
T size(T... args)

◆ is_canonical()

bool SymEngine::Mul::is_canonical ( const RCP< const Number > &  coef,
const map_basic_basic dict 
) const
Returns
true if both coef and dict are in canonical form

Definition at line 17 of file mul.cpp.

19 {
20  if (coef == null)
21  return false;
22  // e.g. 0*x*y
23  if (coef->is_zero())
24  return false;
25  if (dict.size() == 0)
26  return false;
27  if (dict.size() == 1) {
28  // e.g. 1*x, 1*x**2
29  if (coef->is_one())
30  return false;
31  }
32  // Check that each term in 'dict' is in canonical form
33  for (const auto &p : dict) {
34  if (p.first == null)
35  return false;
36  if (p.second == null)
37  return false;
38  // e.g. 2**3, (2/3)**4
39  // However for Complex no simplification is done
40  if ((is_a<Integer>(*p.first) or is_a<Rational>(*p.first))
41  and is_a<Integer>(*p.second))
42  return false;
43  // e.g. 0**x
44  if (is_a<Integer>(*p.first)
45  and down_cast<const Integer &>(*p.first).is_zero())
46  return false;
47  // e.g. 1**x
48  if (is_a<Integer>(*p.first)
49  and down_cast<const Integer &>(*p.first).is_one())
50  return false;
51  // e.g. x**0
52  if (is_a_Number(*p.second)
53  and down_cast<const Number &>(*p.second).is_zero())
54  return false;
55  // e.g. (x*y)**2 (={xy:2}), which should be represented as x**2*y**2
56  // (={x:2, y:2})
57  if (is_a<Mul>(*p.first)) {
58  if (is_a<Integer>(*p.second))
59  return false;
60  if (is_a_Number(*p.second)
61  and neq(*down_cast<const Mul &>(*p.first).coef_, *one)
62  and neq(*down_cast<const Mul &>(*p.first).coef_, *minus_one))
63  return false;
64  }
65  // e.g. x**2**y (={x**2:y}), which should be represented as x**(2y)
66  // (={x:2y})
67  if (is_a<Pow>(*p.first) && is_a<Integer>(*p.second))
68  return false;
69  // e.g. 0.5^2.0 should be represented as 0.25
70  if (is_a_Number(*p.first)
71  and not down_cast<const Number &>(*p.first).is_exact()
72  and is_a_Number(*p.second)
73  and not down_cast<const Number &>(*p.second).is_exact())
74  return false;
75  }
76  return true;
77 }
bool is_a_Number(const Basic &b)
Definition: number.h:130
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
Definition: basic-inl.h:29

Field Documentation

◆ type_code_id

const TypeID SymEngine::Mul::type_code_id = SYMENGINE_MUL
static

the dictionary of the rest (e.g. x*y in 2*x*y)

Type_code_id shared by all instances

Definition at line 81 of file mul.h.


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