5 #ifndef SYMENGINE_UINTPOLY_FLINT_H
6 #define SYMENGINE_UINTPOLY_FLINT_H
8 #include <symengine/polys/upolybase.h>
10 #ifdef HAVE_SYMENGINE_FLINT
11 #include <symengine/flint_wrapper.h>
18 template <
typename Container,
template <
typename X,
typename Y>
class BaseType,
20 class UFlintPoly :
public BaseType<Container, Poly>
23 using Cf =
typename BaseType<Container, Poly>::coef_type;
25 UFlintPoly(
const RCP<const Basic> &var, Container &&dict)
26 : BaseType<Container, Poly>(var,
std::
move(dict))
30 int compare(
const Basic &o)
const
32 SYMENGINE_ASSERT(is_a<Poly>(o))
33 const Poly &s = down_cast<const Poly &>(o);
35 if (this->get_poly().degree() != s.get_poly().degree())
36 return (this->get_poly().degree() < s.get_poly().degree()) ? -1 : 1;
38 int cmp = this->get_var()->compare(*s.get_var());
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))
52 static Container container_from_dict(
const RCP<const Basic> &var,
56 for (
auto const &p : d) {
58 typename Container::internal_coef_type r(get_mp_t(p.second));
59 f.set_coeff(p.first, r);
65 static RCP<const Poly> from_vec(
const RCP<const Basic> &var,
70 for (
unsigned int i = 0; i < v.
size(); i++) {
72 typename Container::internal_coef_type r(get_mp_t(v[i]));
76 return make_rcp<const Poly>(var,
std::move(f));
79 template <
typename FromPoly>
80 static enable_if_t<is_a_UPoly<FromPoly>::value, RCP<const Poly>>
81 from_poly(
const FromPoly &p)
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);
88 return Poly::from_container(p.get_var(),
std::move(f));
91 Cf eval(
const Cf &x)
const
93 typename Container::internal_coef_type r(get_mp_t(x));
94 return to_mp_class(this->get_poly().eval(r));
97 Cf get_coeff(
unsigned int x)
const
99 return to_mp_class(this->get_poly().get_coeff(x));
103 Cf get_coeff_ref(
unsigned int x)
const
105 return to_mp_class(this->get_poly().get_coeff(x));
108 typedef ContainerForIter<Poly, Cf> iterator;
109 typedef ContainerRevIter<Poly, Cf> r_iterator;
110 iterator
begin()
const
112 return iterator(this->
template rcp_from_this_cast<Poly>(), 0);
116 return iterator(this->
template rcp_from_this_cast<Poly>(), size());
118 r_iterator obegin()
const
120 return r_iterator(this->
template rcp_from_this_cast<Poly>(),
123 r_iterator oend()
const
125 return r_iterator(this->
template rcp_from_this_cast<Poly>(), -1);
130 return numeric_cast<int>(this->get_poly().length());
134 class UIntPolyFlint :
public UFlintPoly<fzp_t, UIntPolyBase, UIntPolyFlint>
139 UIntPolyFlint(
const RCP<const Basic> &var, fzp_t &&dict);
141 hash_t __hash__()
const override;
145 class URatPolyFlint :
public UFlintPoly<fqp_t, URatPolyBase, URatPolyFlint>
150 URatPolyFlint(
const RCP<const Basic> &var, fqp_t &&dict);
152 hash_t __hash__()
const override;
155 template <
typename Container,
template <
typename X,
typename Y>
class BaseType,
158 factors(
const UFlintPoly<Container, BaseType, Poly> &a)
160 auto fac_wrapper = a.get_poly().factors();
161 auto &fac = fac_wrapper.get_fmpz_poly_factor_t();
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++) {
169 z.swap_fmpz_poly_t(fac->p[i]);
171 make_rcp<const Poly>(a.get_var(),
std::move(z)), fac->exp[i]));
176 template <
typename Container,
template <
typename X,
typename Y>
class BaseType,
178 RCP<const Poly> gcd_upoly(
const UFlintPoly<Container, BaseType, Poly> &a,
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()));
186 template <
typename Container,
template <
typename X,
typename Y>
class BaseType,
188 RCP<const Poly> lcm_upoly(
const UFlintPoly<Container, BaseType, Poly> &a,
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()));
196 template <
typename Container,
template <
typename X,
typename Y>
class BaseType,
198 RCP<const Poly> pow_upoly(
const UFlintPoly<Container, BaseType, Poly> &a,
201 return make_rcp<const Poly>(a.get_var(), a.get_poly().pow(p));
204 template <
typename Container,
template <
typename X,
typename Y>
class BaseType,
206 bool divides_upoly(
const UFlintPoly<Container, BaseType, Poly> &a,
207 const Poly &b,
const Ptr<RCP<const Poly>> &res)
209 if (!(a.get_var()->__eq__(*b.get_var())))
210 throw SymEngineException(
"Error: variables must agree.");
212 typename Poly::container_type q, r;
214 b.get_poly().divrem(q, r, a.get_poly());
216 *res = make_rcp<Poly>(a.get_var(),
std::move(q));
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Main namespace for SymEngine package.