usymenginepoly.h
1 #ifndef SYMENGINE_USYMENGINEPOLY_H
2 #define SYMENGINE_USYMENGINEPOLY_H
3 
4 #include <symengine/polys/upolybase.h>
5 
6 namespace SymEngine
7 {
8 
9 template <typename Container, template <typename X, typename Y> class BaseType,
10  typename Poly>
11 class USymEnginePoly : public BaseType<Container, Poly>
12 {
13 public:
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 
120 template <typename Container, template <typename X, typename Y> class BaseType,
121  typename Poly>
122 RCP<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