series_flint.h
1 #ifndef SYMENGINE_SERIES_FLINT_H
2 #define SYMENGINE_SERIES_FLINT_H
3 
4 #include <symengine/series.h>
5 #include <symengine/expression.h>
6 #include <symengine/symengine_exception.h>
7 
8 #ifdef HAVE_SYMENGINE_FLINT
9 #include <symengine/flint_wrapper.h>
10 
11 namespace SymEngine
12 {
13 
14 using fqp_t = fmpq_poly_wrapper;
15 // Univariate Rational Coefficient Power SeriesBase using Flint
16 class SYMENGINE_EXPORT URatPSeriesFlint
17  : public SeriesBase<fqp_t, fmpq_wrapper, URatPSeriesFlint>
18 {
19 public:
20  URatPSeriesFlint(const fqp_t p, const std::string varname,
21  const unsigned degree);
22  IMPLEMENT_TYPEID(SYMENGINE_URATPSERIESFLINT)
23  int compare(const Basic &o) const override;
24  hash_t __hash__() const override;
25  RCP<const Basic> as_basic() const override;
26  umap_int_basic as_dict() const override;
27  RCP<const Basic> get_coeff(int) const override;
28 
29  static RCP<const URatPSeriesFlint>
30  series(const RCP<const Basic> &t, const std::string &x, unsigned int prec);
31  static fqp_t var(const std::string &s);
32  static fqp_t convert(const integer_class &x);
33  static fqp_t convert(const rational_class &x);
34  static fqp_t convert(const Rational &x);
35  static fqp_t convert(const Integer &x);
36  static fqp_t convert(const Basic &x);
39  static inline fqp_t mul(const fqp_t &s, const fqp_t &r, unsigned prec)
40  {
41  return s.mullow(r, prec);
42  }
43  static fqp_t pow(const fqp_t &s, int n, unsigned prec);
44  static unsigned ldegree(const fqp_t &s);
45  static inline fmpq_wrapper find_cf(const fqp_t &s, const fqp_t &var,
46  unsigned deg)
47  {
48  return s.get_coeff(deg);
49  }
50  static fmpq_wrapper root(fmpq_wrapper &c, unsigned n);
51  static fqp_t diff(const fqp_t &s, const fqp_t &var);
52  static fqp_t integrate(const fqp_t &s, const fqp_t &var);
53  static fqp_t subs(const fqp_t &s, const fqp_t &var, const fqp_t &r,
54  unsigned prec);
55 
56  static inline fqp_t series_invert(const fqp_t &s, const fqp_t &var,
57  unsigned int prec)
58  {
59  SYMENGINE_ASSERT(not s.get_coeff(0).is_zero());
60  return s.inv_series(prec);
61  }
62  static inline fqp_t series_reverse(const fqp_t &s, const fqp_t &var,
63  unsigned int prec)
64  {
65  SYMENGINE_ASSERT(s.get_coeff(0).is_zero()
66  and not s.get_coeff(1).is_zero());
67  return s.revert_series(prec);
68  }
69  static inline fqp_t series_log(const fqp_t &s, const fqp_t &var,
70  unsigned int prec)
71  {
72  SYMENGINE_ASSERT(s.get_coeff(0).is_one());
73  return s.log_series(prec);
74  }
75  static inline fqp_t series_exp(const fqp_t &s, const fqp_t &var,
76  unsigned int prec)
77  {
78  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
79  return s.exp_series(prec);
80  }
81  static inline fqp_t series_sin(const fqp_t &s, const fqp_t &var,
82  unsigned int prec)
83  {
84  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
85  return s.sin_series(prec);
86  }
87 
88  static inline fqp_t series_cos(const fqp_t &s, const fqp_t &var,
89  unsigned int prec)
90  {
91  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
92  return s.cos_series(prec);
93  }
94 
95  static inline fqp_t series_tan(const fqp_t &s, const fqp_t &var,
96  unsigned int prec)
97  {
98  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
99  return s.tan_series(prec);
100  }
101  static inline fqp_t series_atan(const fqp_t &s, const fqp_t &var,
102  unsigned int prec)
103  {
104  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
105  return s.atan_series(prec);
106  }
107  static inline fqp_t series_atanh(const fqp_t &s, const fqp_t &var,
108  unsigned int prec)
109  {
110  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
111  return s.atanh_series(prec);
112  }
113  static inline fqp_t series_asin(const fqp_t &s, const fqp_t &var,
114  unsigned int prec)
115  {
116  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
117  return s.asin_series(prec);
118  }
119  static inline fqp_t series_asinh(const fqp_t &s, const fqp_t &var,
120  unsigned int prec)
121  {
122  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
123  return s.asinh_series(prec);
124  }
125  static inline fqp_t series_acos(const fqp_t &s, const fqp_t &var,
126  unsigned int prec)
127  {
128  throw NotImplementedError("acos() not implemented");
129  }
130  static inline fqp_t series_sinh(const fqp_t &s, const fqp_t &var,
131  unsigned int prec)
132  {
133  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
134  return s.sinh_series(prec);
135  }
136  static inline fqp_t series_cosh(const fqp_t &s, const fqp_t &var,
137  unsigned int prec)
138  {
139  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
140  return s.cosh_series(prec);
141  }
142  static inline fqp_t series_tanh(const fqp_t &s, const fqp_t &var,
143  unsigned int prec)
144  {
145  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
146  return s.tanh_series(prec);
147  }
148  static inline fqp_t series_lambertw(const fqp_t &s, const fqp_t &var,
149  unsigned int prec)
150  {
151  SYMENGINE_ASSERT(s.get_coeff(0).is_zero());
152 
153  fqp_t p1;
154  p1.set_zero();
155 
156  auto steps = step_list(prec);
157  for (const auto step : steps) {
158  const fqp_t e(series_exp(p1, var, step));
159  const fqp_t p2(mul(e, p1, step) - s);
160  const fqp_t p3(
161  series_invert(mul(e, fqp_t(p1 + fqp_t(1)), step), var, step));
162  p1 -= mul(p2, p3, step);
163  }
164  return p1;
165  }
166 
167  static inline fqp_t series_nthroot(const fqp_t &s, int n, const fqp_t &var,
168  unsigned int prec)
169  {
170  fqp_t one;
171  one.set_one();
172  if (n == 0)
173  return one;
174  if (n == 1)
175  return s;
176  if (n == -1)
177  return series_invert(s, var, prec);
178 
179  const unsigned ldeg = ldegree(s);
180  if (ldeg % n != 0) {
181  throw NotImplementedError("Puiseux series not implemented.");
182  }
183  fqp_t ss = s;
184  if (ldeg != 0) {
185  ss = s * pow(var, -ldeg, prec);
186  }
187  fmpq_wrapper ct = find_cf(ss, var, 0);
188  bool do_inv = false;
189  if (n < 0) {
190  n = -n;
191  do_inv = true;
192  }
193 
194  fmpq_wrapper ctroot = root(ct, n);
195  fqp_t res_p = one, sn = fqp_t(ss / ct);
196  auto steps = step_list(prec);
197  for (const auto step : steps) {
198  fqp_t t = mul(pow(res_p, n + 1, step), sn, step);
199  res_p += (res_p - t) / n;
200  }
201  if (ldeg != 0) {
202  res_p *= pow(var, ldeg / n, prec);
203  }
204  if (do_inv)
205  return fqp_t(res_p * ctroot);
206  else
207  return fqp_t(series_invert(res_p, var, prec) * ctroot);
208  }
209 };
210 } // namespace SymEngine
211 
212 #endif // HAVE_SYMENGINE_FLINT
213 
214 #endif // SYMENGINE_SERIES_FLINT_H
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Definition: basic.h:344
RCP< const Number > mul(const Number &other) const override
Multiplication.
Definition: series.h:110
RCP< const Number > pow(const Number &other) const override
Power.
Definition: series.h:128
Main namespace for SymEngine package.
Definition: add.cpp:19
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352