1 /*
2     Copyright (C) 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_pow_series(acb_ptr h,acb_srcptr f,slong flen,acb_srcptr g,slong glen,slong len,slong prec)15 _acb_poly_pow_series(acb_ptr h,
16     acb_srcptr f, slong flen,
17     acb_srcptr g, slong glen, slong len, slong prec)
18 {
19     if (glen == 1)
20     {
21         _acb_poly_pow_acb_series(h, f, flen, g, len, prec);
22         return;
23     }
24 
25     /* f^g = exp(g * log(f)) */
26     if (flen == 1)
27     {
28         acb_t t;
29         acb_init(t);
30         acb_log(t, f, prec);
31         _acb_vec_scalar_mul(h, g, glen, t, prec);
32         _acb_poly_exp_series(h, h, glen, len, prec);
33         acb_clear(t);
34     }
35     else
36     {
37         acb_ptr t;
38         t = _acb_vec_init(len);
39         _acb_poly_log_series(t, f, flen, len, prec);
40         _acb_poly_mullow(h, t, len, g, glen, len, prec);
41         _acb_poly_exp_series(h, h, len, len, prec);
42         _acb_vec_clear(t, len);
43 
44     }
45 }
46 
47 void
acb_poly_pow_series(acb_poly_t h,const acb_poly_t f,const acb_poly_t g,slong len,slong prec)48 acb_poly_pow_series(acb_poly_t h,
49     const acb_poly_t f, const acb_poly_t g, slong len, slong prec)
50 {
51     slong flen, glen;
52 
53     flen = f->length;
54     glen = g->length;
55 
56     flen = FLINT_MIN(flen, len);
57     glen = FLINT_MIN(glen, len);
58 
59     if (len == 0)
60     {
61         acb_poly_zero(h);
62         return;
63     }
64 
65     if (glen == 0)
66     {
67         acb_poly_one(h);
68         return;
69     }
70 
71     if (flen == 0)
72     {
73         acb_poly_zero(h);
74         return;
75     }
76 
77     if (flen == 1 && glen == 1)
78     {
79         acb_poly_fit_length(h, 1);
80         acb_pow(h->coeffs, f->coeffs, g->coeffs, prec);
81         _acb_poly_set_length(h, 1);
82         _acb_poly_normalise(h);
83         return;
84     }
85 
86     if (f == h || g == h)
87     {
88         acb_poly_t t;
89         acb_poly_init2(t, len);
90         _acb_poly_pow_series(t->coeffs,
91             f->coeffs, flen, g->coeffs, glen, len, prec);
92         _acb_poly_set_length(t, len);
93         _acb_poly_normalise(t);
94         acb_poly_swap(t, h);
95         acb_poly_clear(t);
96     }
97     else
98     {
99         acb_poly_fit_length(h, len);
100         _acb_poly_pow_series(h->coeffs,
101             f->coeffs, flen, g->coeffs, glen, len, prec);
102         _acb_poly_set_length(h, len);
103         _acb_poly_normalise(h);
104     }
105 }
106 
107