series_flint.cpp
1 #include <symengine/series_visitor.h>
2 
3 #ifdef HAVE_SYMENGINE_FLINT
4 namespace SymEngine
5 {
6 
7 URatPSeriesFlint::URatPSeriesFlint(fqp_t p, const std::string varname,
8  const unsigned degree)
9  : SeriesBase(std::move(p), varname, degree){SYMENGINE_ASSIGN_TYPEID()} RCP<
10  const URatPSeriesFlint> URatPSeriesFlint::series(const RCP<const Basic>
11  &t,
12  const std::string &x,
13  unsigned int prec)
14 {
15  fqp_t p("2 0 1");
16  SeriesVisitor<fqp_t, fmpq_wrapper, URatPSeriesFlint> visitor(p, x, prec);
17  return visitor.series(t);
18 }
19 
20 hash_t URatPSeriesFlint::__hash__() const
21 {
22  std::hash<std::string> str_hash;
23  hash_t seed = SYMENGINE_URATPSERIESFLINT;
24  hash_combine(seed, var_);
25  hash_combine(seed, degree_);
26  hash_combine(seed, str_hash(p_.to_string()));
27  return seed;
28 }
29 
30 RCP<const Basic> URatPSeriesFlint::as_basic() const
31 {
32  RCP<const Symbol> x = symbol(var_);
33  RCP<const Number> zcoef;
34  umap_basic_num dict_;
35  mpq_t gc;
36  mpq_init(gc);
37  for (unsigned n = 0; n < degree_; n++) {
38  const fmpq_wrapper fc(p_.get_coeff(n));
39  if (not fc.is_zero()) {
40  fmpq_get_mpq(gc, fc.get_fmpq_t());
41  RCP<const Number> basic = Rational::from_mpq(rational_class(gc));
42  auto term = SymEngine::mul(SymEngine::pow(x, SymEngine::integer(n)),
43  basic);
44  if (n == 0)
45  zcoef = basic;
46  Add::coef_dict_add_term(outArg(basic), dict_, one, term);
47  } else if (n == 0)
48  zcoef = integer(0);
49  }
50  mpq_clear(gc);
51  return Add::from_dict(zcoef, std::move(dict_));
52 }
53 
54 umap_int_basic URatPSeriesFlint::as_dict() const
55 {
56  umap_int_basic map;
57  mpq_t gc;
58  mpq_init(gc);
59  for (unsigned n = 0; n < degree_; n++) {
60  const fmpq_wrapper fc(p_.get_coeff(n));
61  if (not fc.is_zero()) {
62  fmpq_get_mpq(gc, fc.get_fmpq_t());
63  RCP<const Number> basic = Rational::from_mpq(rational_class(gc));
64  map[n] = basic;
65  }
66  }
67  mpq_clear(gc);
68  return map;
69 }
70 
71 RCP<const Basic> URatPSeriesFlint::get_coeff(int n) const
72 {
73  const fmpq_wrapper fc(p_.get_coeff(n));
74  mpq_t gc;
75  mpq_init(gc);
76  fmpq_get_mpq(gc, fc.get_fmpq_t());
77  rational_class r(gc);
78  mpq_clear(gc);
79  return Rational::from_mpq(std::move(r));
80 }
81 
82 int URatPSeriesFlint::compare(const Basic &o) const
83 {
84  SYMENGINE_ASSERT(is_a<URatPSeriesFlint>(o))
85  const URatPSeriesFlint &s = down_cast<const URatPSeriesFlint &>(o);
86  if (var_ != s.var_)
87  return (var_ < s.var_) ? -1 : 1;
88  if (degree_ != s.degree_)
89  return (degree_ < s.degree_) ? -1 : 1;
90  if (p_ == s.p_)
91  return 0;
92  return (p_ < s.p_) ? -1 : 1;
93 }
94 
95 fqp_t URatPSeriesFlint::var(const std::string &s)
96 {
97  fqp_t r("2 0 1");
98  return r;
99 }
100 
101 fqp_t URatPSeriesFlint::convert(const integer_class &x)
102 {
103  return fqp_t(get_mpz_t(x));
104 }
105 
106 fqp_t URatPSeriesFlint::convert(const rational_class &x)
107 {
108  return fqp_t(get_mpq_t(x));
109 }
110 
111 fqp_t URatPSeriesFlint::convert(const Integer &x)
112 {
113  return convert(x.as_integer_class());
114 }
115 
116 fqp_t URatPSeriesFlint::convert(const Rational &x)
117 {
118  return convert(x.as_rational_class());
119 }
120 
121 fqp_t URatPSeriesFlint::convert(const Basic &x)
122 {
123  throw NotImplementedError("SeriesFlint::convert not Implemented");
124 }
125 
126 fqp_t URatPSeriesFlint::pow(const fqp_t &s, int n, unsigned prec)
127 {
128  if (n > 0)
129  return fqp_t(s.pow(unsigned(n)));
130  else if (n < 0)
131  return fqp_t(s.inv_series(prec).pow(unsigned(-n)));
132  return fqp_t("1 1");
133 }
134 
135 unsigned URatPSeriesFlint::ldegree(const fqp_t &s)
136 {
137  int i = 0;
138  while (i <= numeric_cast<int>(s.degree()))
139  if (not s.get_coeff(i++).is_zero())
140  return numeric_cast<unsigned>(i - 1);
141  return 0;
142 }
143 
144 fmpq_wrapper URatPSeriesFlint::root(fmpq_wrapper &c, unsigned n)
145 {
146  fmpq_wrapper cl_rat = c, cl_root;
147  cl_rat.canonicalise();
148  cl_root.get_num() = cl_rat.get_num().root(n);
149  if (cl_rat.get_den() == 1)
150  cl_root.get_den() = 1;
151  else
152  cl_root.get_den() = cl_rat.get_den().root(n);
153  return cl_root;
154 }
155 
156 fqp_t URatPSeriesFlint::diff(const fqp_t &s, const fqp_t &var)
157 {
158  return s.derivative();
159 }
160 
161 fqp_t URatPSeriesFlint::integrate(const fqp_t &s, const fqp_t &var)
162 {
163  return s.integral();
164 }
165 
166 fqp_t URatPSeriesFlint::subs(const fqp_t &s, const fqp_t &var, const fqp_t &r,
167  unsigned prec)
168 {
169  return s.subs(r, prec);
170 }
171 } // namespace SymEngine
172 #endif // HAVE_SYMENGINE_FLINT
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
Definition: symbol.h:82
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
STL namespace.