Loading...
Searching...
No Matches
uexprpoly.h
1
5#ifndef SYMENGINE_UEXPRPOLY_H
6#define SYMENGINE_UEXPRPOLY_H
7
10#include <symengine/polys/usymenginepoly.h>
11
12namespace SymEngine
13{
14
15class UExprDict : public ODictWrapper<int, Expression, UExprDict>
16{
17
18public:
23 {
24 }
25 UExprDict(const int &i) : ODictWrapper(i) {}
26 UExprDict(const map_int_Expr &p) : ODictWrapper(p) {}
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) {
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
160class UExprPoly : public USymEnginePoly<UExprDict, UExprPolyBase, UExprPoly>
161{
162public:
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
192inline RCP<const UExprPoly> uexpr_poly(RCP<const Basic> i, UExprDict &&dict)
193{
194 return UExprPoly::from_container(i, std::move(dict));
195}
196
197inline 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
T at(T... args)
#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
bool is_integer() const
Definition uexprpoly.cpp:63
bool is_minus_one() const
Definition uexprpoly.cpp:56
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 end(T... args)
T find(T... args)
T move(T... args)
Main namespace for SymEngine package.
Definition add.cpp:19
void hash_combine(hash_t &seed, const T &v)
Definition basic-inl.h:95
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition mul.cpp:352
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
Definition symbol.h:82
int unified_compare(const T &a, const T &b)
Definition dict.h:205
std::enable_if< std::is_integral< T >::value, RCP< constInteger > >::type integer(T i)
Definition integer.h:197
T rbegin(T... args)
T rend(T... args)
T substr(T... args)