uexprpoly.h
1 
5 #ifndef SYMENGINE_UEXPRPOLY_H
6 #define SYMENGINE_UEXPRPOLY_H
7 
8 #include <symengine/expression.h>
9 #include <symengine/monomials.h>
10 #include <symengine/polys/usymenginepoly.h>
11 
12 namespace SymEngine
13 {
14 
15 class UExprDict : public ODictWrapper<int, Expression, UExprDict>
16 {
17 
18 public:
19  UExprDict() SYMENGINE_NOEXCEPT {}
20  ~UExprDict() SYMENGINE_NOEXCEPT {}
21  UExprDict(UExprDict &&other) SYMENGINE_NOEXCEPT
22  : ODictWrapper(std::move(other))
23  {
24  }
25  UExprDict(const int &i) : ODictWrapper(i) {}
26  UExprDict(const map_int_Expr &p) : ODictWrapper(p) {}
27  UExprDict(const Expression &expr) : ODictWrapper(expr) {}
28 
29  UExprDict(const std::string &s) : ODictWrapper(s) {}
30 
31  UExprDict(const UExprDict &) = default;
32  UExprDict &operator=(const UExprDict &) = default;
33 
34  friend std::ostream &operator<<(std::ostream &os, const UExprDict &expr)
35  {
36  os << expr.dict_;
37  return os;
38  }
39 
40  friend UExprDict operator/(const UExprDict &a, const Expression &b)
41  {
42  return a * (1 / b);
43  }
44 
45  UExprDict &operator/=(const Expression &other)
46  {
47  *this *= (1 / other);
48  return *this;
49  }
50 
51  std::string __str__(const std::string name) const
52  {
54  bool first = true;
55  for (auto it = dict_.rbegin(); it != dict_.rend(); ++it) {
56  std::string t;
57  // if exponent is 0, then print only coefficient
58  if (it->first == 0) {
59  if (first) {
60  o << it->second;
61  } else {
62  t = detail::poly_print(it->second);
63  if (t[0] == '-') {
64  o << " - " << t.substr(1);
65  } else {
66  o << " + " << t;
67  }
68  }
69  first = false;
70  continue;
71  }
72  // if the coefficient of a term is +1 or -1
73  if (it->second == 1 or it->second == -1) {
74  // in cases of -x, print -x
75  // in cases of x**2 - x, print - x
76  if (first) {
77  if (it->second == -1)
78  o << "-";
79  } else {
80  if (down_cast<const Integer &>(*it->second.get_basic())
81  .as_integer_class()
82  < 0) {
83  o << " "
84  << "-"
85  << " ";
86  } else {
87  o << " "
88  << "+"
89  << " ";
90  }
91  }
92  }
93  // if the coefficient of a term is 0, skip
94  else if (it->second == 0)
95  continue;
96  // same logic is followed as above
97  else {
98  // in cases of -2*x, print -2*x
99  // in cases of x**2 - 2*x, print - 2*x
100  if (first) {
101  o << detail::poly_print(it->second) << "*";
102  } else {
103  t = detail::poly_print(it->second);
104  if (t[0] == '-') {
105  o << " - " << t.substr(1);
106  } else {
107  o << " + " << t;
108  }
109  o << "*";
110  }
111  }
112  o << name;
113  // if exponent is not 1, print the exponent;
114  if (it->first > 1) {
115  o << "**" << it->first;
116  } else if (it->first < 0) {
117  o << "**(" << it->first << ")";
118  }
119  // corner cases of only first term handled successfully, switch the
120  // bool
121  first = false;
122  }
123  return o.str();
124  }
125 
126  // const umap_int_basic get_basic() const
127  const RCP<const Basic> get_basic(std::string var) const
128  {
129  RCP<const Symbol> x = symbol(var);
130  umap_basic_num dict;
131  RCP<const Number> coeff = zero;
132  for (const auto &it : dict_) {
133  if (it.first != 0) {
134  auto term
135  = SymEngine::mul(it.second.get_basic(),
136  SymEngine::pow(x, integer(it.first)));
137  Add::coef_dict_add_term(outArg(coeff), dict, one, term);
138  } else {
139  Add::coef_dict_add_term(outArg(coeff), dict, one,
140  it.second.get_basic());
141  }
142  }
143  return Add::from_dict(coeff, std::move(dict));
144  }
145 
146  int compare(const UExprDict &other) const
147  {
148  return unified_compare(dict_, other.dict_);
149  }
150 
151  Expression find_cf(int deg) const
152  {
153  if (dict_.find(deg) != dict_.end())
154  return dict_.at(deg);
155  else
156  return Expression(0);
157  }
158 }; // UExprDict
159 
160 class UExprPoly : public USymEnginePoly<UExprDict, UExprPolyBase, UExprPoly>
161 {
162 public:
163  IMPLEMENT_TYPEID(SYMENGINE_UEXPRPOLY)
165  UExprPoly(const RCP<const Basic> &var, UExprDict &&dict);
166 
167  hash_t __hash__() const override;
168 
169  typedef Expression coef_type;
170 
171  Expression max_coef() const;
173  Expression eval(const Expression &x) const;
174 
176  bool is_zero() const;
178  bool is_one() const;
180  bool is_minus_one() const;
182  bool is_integer() const;
184  bool is_symbol() const;
186  bool is_mul() const;
188  bool is_pow() const;
189 
190 }; // UExprPoly
191 
192 inline RCP<const UExprPoly> uexpr_poly(RCP<const Basic> i, UExprDict &&dict)
193 {
194  return UExprPoly::from_container(i, std::move(dict));
195 }
196 
197 inline RCP<const UExprPoly> uexpr_poly(RCP<const Basic> i, map_int_Expr &&dict)
198 {
199  return UExprPoly::from_dict(i, std::move(dict));
200 }
201 
202 } // namespace SymEngine
203 
204 #endif
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Definition: basic.h:340
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
bool is_zero() const
Definition: uexprpoly.cpp:45
bool is_mul() const
Definition: uexprpoly.cpp:76
bool is_symbol() const
Definition: uexprpoly.cpp:70
hash_t __hash__() const override
Definition: uexprpoly.cpp:11
bool is_integer() const
Definition: uexprpoly.cpp:63
bool is_minus_one() const
Definition: uexprpoly.cpp:56
UExprPoly(const RCP< const Basic > &var, UExprDict &&dict)
Constructor of UExprPoly class.
Definition: uexprpoly.cpp:6
Expression eval(const Expression &x) const
Evaluates the UExprPoly at value x.
Definition: uexprpoly.cpp:34
bool is_one() const
Definition: uexprpoly.cpp:50
bool is_pow() const
Definition: uexprpoly.cpp:83
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
Definition: symbol.h:82
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352
int unified_compare(const T &a, const T &b)
Definition: dict.h:205
T str(T... args)
T substr(T... args)