usymenginepoly.h
1#ifndef SYMENGINE_USYMENGINEPOLY_H
2#define SYMENGINE_USYMENGINEPOLY_H
3
4#include <symengine/polys/upolybase.h>
5
6namespace SymEngine
7{
8
9template <typename Container, template <typename X, typename Y> class BaseType,
10 typename Poly>
11class USymEnginePoly : public BaseType<Container, Poly>
12{
13public:
14 using Cf = typename BaseType<Container, Poly>::coef_type;
15 using Key = typename Container::key_type;
16
17 USymEnginePoly(const RCP<const Basic> &var, Container &&dict)
18 : BaseType<Container, Poly>(var, std::move(dict))
19 {
20 }
21
22 int compare(const Basic &o) const
23 {
24 SYMENGINE_ASSERT(is_a<Poly>(o))
25 const Poly &s = down_cast<const Poly &>(o);
26
27 if (this->get_poly().size() != s.get_poly().size())
28 return (this->get_poly().size() < s.get_poly().size()) ? -1 : 1;
29
30 int cmp = unified_compare(this->get_var(), s.get_var());
31 if (cmp != 0)
32 return cmp;
33
34 return unified_compare(this->get_poly().dict_, s.get_poly().dict_);
35 }
36
37 bool is_canonical(const Container &dict) const
38 {
39 // Check if dictionary contains terms with coeffienct 0
40 for (auto iter : dict.dict_)
41 if (iter.second == 0)
42 return false;
43 return true;
44 }
45
46 static RCP<const Poly> from_vec(const RCP<const Basic> &var,
47 const std::vector<Cf> &v)
48 {
49 return make_rcp<const Poly>(var, Container::from_vec(v));
50 }
51
52 static Container container_from_dict(const RCP<const Basic> &var,
54 {
55 return std::move(Container(d));
56 }
57
58 template <typename FromPoly>
59 static enable_if_t<is_a_UPoly<FromPoly>::value, RCP<const Poly>>
60 from_poly(const FromPoly &p)
61 {
62 return Poly::from_container(p.get_var(),
63 std::move(Container::from_poly(p)));
64 }
65
66 Cf eval(const Cf &x) const
67 {
68 Key last_deg = this->get_poly().dict_.rbegin()->first;
69 Cf result(0), x_pow;
70
71 for (auto it = this->get_poly().dict_.rbegin();
72 it != this->get_poly().dict_.rend(); ++it) {
73 mp_pow_ui(x_pow, x, last_deg - (*it).first);
74 last_deg = (*it).first;
75 result = (*it).second + x_pow * result;
76 }
77 mp_pow_ui(x_pow, x, last_deg);
78 result *= x_pow;
79
80 return result;
81 }
82
83 inline const std::map<Key, Cf> &get_dict() const
84 {
85 return this->get_poly().dict_;
86 }
87
88 inline Cf get_coeff(Key x) const
89 {
90 return this->get_poly().get_coeff(x);
91 }
92
93 typedef typename std::map<Key, Cf>::const_iterator iterator;
94 typedef typename std::map<Key, Cf>::const_reverse_iterator r_iterator;
95 iterator begin() const
96 {
97 return this->get_poly().dict_.begin();
98 }
99 iterator end() const
100 {
101 return this->get_poly().dict_.end();
102 }
103 r_iterator obegin() const
104 {
105 return this->get_poly().dict_.rbegin();
106 }
107 r_iterator oend() const
108 {
109 return this->get_poly().dict_.rend();
110 }
111
112 int size() const
113 {
114 if (this->get_poly().dict_.empty())
115 return 0;
116 return this->get_degree() + 1;
117 }
118};
119
120template <typename Container, template <typename X, typename Y> class BaseType,
121 typename Poly>
122RCP<const Poly> pow_upoly(const USymEnginePoly<Container, BaseType, Poly> &a,
123 unsigned int p)
124{
125 auto dict = Poly::container_type::pow(a.get_poly(), p);
126 return Poly::from_container(a.get_var(), std::move(dict));
127}
128} // namespace SymEngine
129
130#endif
T begin(T... args)
The lowest unit of symbolic representation.
Definition: basic.h:97
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
int unified_compare(const T &a, const T &b)
Definition: dict.h:205