Loading...
Searching...
No Matches
uintpoly_flint.h
Go to the documentation of this file.
1
5#ifndef SYMENGINE_UINTPOLY_FLINT_H
6#define SYMENGINE_UINTPOLY_FLINT_H
7
8#include <symengine/polys/upolybase.h>
9
10#ifdef HAVE_SYMENGINE_FLINT
11#include <symengine/flint_wrapper.h>
14
15namespace SymEngine
16{
17
18template <typename Container, template <typename X, typename Y> class BaseType,
19 typename Poly>
20class UFlintPoly : public BaseType<Container, Poly>
21{
22public:
23 using Cf = typename BaseType<Container, Poly>::coef_type;
24
25 UFlintPoly(const RCP<const Basic> &var, Container &&dict)
26 : BaseType<Container, Poly>(var, std::move(dict))
27 {
28 }
29
30 int compare(const Basic &o) const
31 {
32 SYMENGINE_ASSERT(is_a<Poly>(o))
33 const Poly &s = down_cast<const Poly &>(o);
34
35 if (this->get_poly().degree() != s.get_poly().degree())
36 return (this->get_poly().degree() < s.get_poly().degree()) ? -1 : 1;
37
38 int cmp = this->get_var()->compare(*s.get_var());
39 if (cmp != 0)
40 return cmp;
41
42 for (unsigned int i = 0; i < this->get_poly().length(); ++i) {
43 if (this->get_poly().get_coeff(i) != s.get_poly().get_coeff(i))
44 return (this->get_poly().get_coeff(i)
45 < s.get_poly().get_coeff(i))
46 ? -1
47 : 1;
48 }
49 return 0;
50 }
51
52 static Container container_from_dict(const RCP<const Basic> &var,
54 {
55 Container f;
56 for (auto const &p : d) {
57 if (p.second != 0) {
58 typename Container::internal_coef_type r(get_mp_t(p.second));
59 f.set_coeff(p.first, r);
60 }
61 }
62 return f;
63 }
64
65 static RCP<const Poly> from_vec(const RCP<const Basic> &var,
66 const std::vector<Cf> &v)
67 {
68 // TODO improve this (we already know the degree)
69 Container f;
70 for (unsigned int i = 0; i < v.size(); i++) {
71 if (v[i] != 0) {
72 typename Container::internal_coef_type r(get_mp_t(v[i]));
73 f.set_coeff(i, r);
74 }
75 }
76 return make_rcp<const Poly>(var, std::move(f));
77 }
78
79 template <typename FromPoly>
80 static enable_if_t<is_a_UPoly<FromPoly>::value, RCP<const Poly>>
81 from_poly(const FromPoly &p)
82 {
83 Container f;
84 for (auto it = p.begin(); it != p.end(); ++it) {
85 typename Container::internal_coef_type r(get_mp_t(it->second));
86 f.set_coeff(it->first, r);
87 }
88 return Poly::from_container(p.get_var(), std::move(f));
89 }
90
91 Cf eval(const Cf &x) const
92 {
93 typename Container::internal_coef_type r(get_mp_t(x));
94 return to_mp_class(this->get_poly().eval(r));
95 }
96
97 Cf get_coeff(unsigned int x) const
98 {
99 return to_mp_class(this->get_poly().get_coeff(x));
100 }
101
102 // can't return by reference
103 Cf get_coeff_ref(unsigned int x) const
104 {
105 return to_mp_class(this->get_poly().get_coeff(x));
106 }
107
108 typedef ContainerForIter<Poly, Cf> iterator;
109 typedef ContainerRevIter<Poly, Cf> r_iterator;
110 iterator begin() const
111 {
112 return iterator(this->template rcp_from_this_cast<Poly>(), 0);
113 }
114 iterator end() const
115 {
116 return iterator(this->template rcp_from_this_cast<Poly>(), size());
117 }
118 r_iterator obegin() const
119 {
120 return r_iterator(this->template rcp_from_this_cast<Poly>(),
121 (long)size() - 1);
122 }
123 r_iterator oend() const
124 {
125 return r_iterator(this->template rcp_from_this_cast<Poly>(), -1);
126 }
127
128 int size() const
129 {
130 return numeric_cast<int>(this->get_poly().length());
131 }
132};
133
134class UIntPolyFlint : public UFlintPoly<fzp_t, UIntPolyBase, UIntPolyFlint>
135{
136public:
137 IMPLEMENT_TYPEID(SYMENGINE_UINTPOLYFLINT)
139 UIntPolyFlint(const RCP<const Basic> &var, fzp_t &&dict);
141 hash_t __hash__() const override;
142
143}; // UIntPolyFlint
144
145class URatPolyFlint : public UFlintPoly<fqp_t, URatPolyBase, URatPolyFlint>
146{
147public:
148 IMPLEMENT_TYPEID(SYMENGINE_URATPOLYFLINT)
150 URatPolyFlint(const RCP<const Basic> &var, fqp_t &&dict);
152 hash_t __hash__() const override;
153}; // URatPolyFlint
154
155template <typename Container, template <typename X, typename Y> class BaseType,
156 typename Poly>
158factors(const UFlintPoly<Container, BaseType, Poly> &a)
159{
160 auto fac_wrapper = a.get_poly().factors();
161 auto &fac = fac_wrapper.get_fmpz_poly_factor_t();
163 if (fac->c != 1_z)
165 make_rcp<const Poly>(a.get_var(), numeric_cast<int>(fac->c)), 1));
166 SYMENGINE_ASSERT(fac->p != NULL and fac->exp != NULL)
167 for (long i = 0; i < fac->num; i++) {
168 fzp_t z;
169 z.swap_fmpz_poly_t(fac->p[i]);
171 make_rcp<const Poly>(a.get_var(), std::move(z)), fac->exp[i]));
172 }
173 return S;
174}
175
176template <typename Container, template <typename X, typename Y> class BaseType,
177 typename Poly>
178RCP<const Poly> gcd_upoly(const UFlintPoly<Container, BaseType, Poly> &a,
179 const Poly &b)
180{
181 if (!(a.get_var()->__eq__(*b.get_var())))
182 throw SymEngineException("Error: variables must agree.");
183 return make_rcp<const Poly>(a.get_var(), a.get_poly().gcd(b.get_poly()));
184}
185
186template <typename Container, template <typename X, typename Y> class BaseType,
187 typename Poly>
188RCP<const Poly> lcm_upoly(const UFlintPoly<Container, BaseType, Poly> &a,
189 const Poly &b)
190{
191 if (!(a.get_var()->__eq__(*b.get_var())))
192 throw SymEngineException("Error: variables must agree.");
193 return make_rcp<const Poly>(a.get_var(), a.get_poly().lcm(b.get_poly()));
194}
195
196template <typename Container, template <typename X, typename Y> class BaseType,
197 typename Poly>
198RCP<const Poly> pow_upoly(const UFlintPoly<Container, BaseType, Poly> &a,
199 unsigned int p)
200{
201 return make_rcp<const Poly>(a.get_var(), a.get_poly().pow(p));
202}
203
204template <typename Container, template <typename X, typename Y> class BaseType,
205 typename Poly>
206bool divides_upoly(const UFlintPoly<Container, BaseType, Poly> &a,
207 const Poly &b, const Ptr<RCP<const Poly>> &res)
208{
209 if (!(a.get_var()->__eq__(*b.get_var())))
210 throw SymEngineException("Error: variables must agree.");
211
212 typename Poly::container_type q, r;
213
214 b.get_poly().divrem(q, r, a.get_poly());
215 if (r == 0) {
216 *res = make_rcp<Poly>(a.get_var(), std::move(q));
217 return true;
218 } else {
219 return false;
220 }
221}
222} // namespace SymEngine
223
224#endif // HAVE_SYMENGINE_FLINT
225
226#endif // SYMENGINE_UINTPOLY_FLINT_H
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Definition: basic.h:340
T begin(T... args)
T end(T... args)
T make_pair(T... args)
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
STL namespace.
T push_back(T... args)
T size(T... args)