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