1 /*
2 Copyright (C) 2012, 2013 Fredrik Johansson
3
4 This file is part of Arb.
5
6 Arb is free software: you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version. See <http://www.gnu.org/licenses/>.
10 */
11
12 #include "acb_poly.h"
13
14 void
_acb_poly_log_series(acb_ptr res,acb_srcptr f,slong flen,slong n,slong prec)15 _acb_poly_log_series(acb_ptr res, acb_srcptr f, slong flen, slong n, slong prec)
16 {
17 flen = FLINT_MIN(flen, n);
18
19 if (flen == 1)
20 {
21 acb_log(res, f, prec);
22 _acb_vec_zero(res + 1, n - 1);
23 }
24 else if (n == 2)
25 {
26 acb_div(res + 1, f + 1, f + 0, prec); /* safe since hlen >= 2 */
27 acb_log(res, f, prec);
28 }
29 else if (_acb_vec_is_zero(f + 1, flen - 2)) /* f = a + bx^d */
30 {
31 slong i, j, d = flen - 1;
32
33 for (i = 1, j = d; j < n; j += d, i++)
34 {
35 if (i == 1)
36 acb_div(res + j, f + d, f + 0, prec);
37 else
38 acb_mul(res + j, res + j - d, res + d, prec);
39 _acb_vec_zero(res + j - d + 1, flen - 2);
40 }
41 _acb_vec_zero(res + j - d + 1, n - (j - d + 1));
42
43 for (i = 2, j = 2 * d; j < n; j += d, i++)
44 acb_div_si(res + j, res + j, i % 2 ? i : -i, prec);
45
46 acb_log(res, f, prec); /* done last to allow aliasing */
47 }
48 else
49 {
50 acb_ptr f_diff, f_inv;
51 acb_t a;
52 slong alloc;
53
54 alloc = n + flen - 1;
55 f_inv = _acb_vec_init(alloc);
56 f_diff = f_inv + n;
57
58 acb_init(a);
59 acb_log(a, f, prec);
60
61 _acb_poly_derivative(f_diff, f, flen, prec);
62 _acb_poly_inv_series(f_inv, f, flen, n, prec);
63 _acb_poly_mullow(res, f_inv, n - 1, f_diff, flen - 1, n - 1, prec);
64 _acb_poly_integral(res, res, n, prec);
65 acb_swap(res, a);
66
67 acb_clear(a);
68 _acb_vec_clear(f_inv, alloc);
69 }
70 }
71
72 void
acb_poly_log_series(acb_poly_t res,const acb_poly_t f,slong n,slong prec)73 acb_poly_log_series(acb_poly_t res, const acb_poly_t f, slong n, slong prec)
74 {
75 if (n == 0)
76 {
77 acb_poly_zero(res);
78 return;
79 }
80
81 acb_poly_fit_length(res, n);
82 if (f->length == 0)
83 _acb_vec_indeterminate(res->coeffs, n);
84 else
85 _acb_poly_log_series(res->coeffs, f->coeffs, f->length, n, prec);
86 _acb_poly_set_length(res, n);
87 _acb_poly_normalise(res);
88 }
89
90