1 /*
2 Copyright (C) 2012 Sebastian Pancratz
3
4 This file is part of FLINT.
5
6 FLINT 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 "fmpz_mod_poly.h"
13 #include "qadic.h"
14
_qadic_exp(fmpz * rop,const fmpz * op,slong v,slong len,const fmpz * a,const slong * j,slong lena,const fmpz_t p,slong N,const fmpz_t pN)15 void _qadic_exp(fmpz *rop, const fmpz *op, slong v, slong len,
16 const fmpz *a, const slong *j, slong lena,
17 const fmpz_t p, slong N, const fmpz_t pN)
18 {
19 if (N < (WORD(1) << 13) / (slong) fmpz_bits(p))
20 {
21 _qadic_exp_rectangular(rop, op, v, len, a, j, lena, p, N, pN);
22 }
23 else
24 {
25 const slong d = j[lena - 1];
26
27 _qadic_exp_balanced(rop, op, v, len, a, j, lena, p, N, pN);
28 _fmpz_vec_zero(rop + d, d - 1);
29 }
30 }
31
qadic_exp(qadic_t rop,const qadic_t op,const qadic_ctx_t ctx)32 int qadic_exp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
33 {
34 const slong N = qadic_prec(rop);
35 const slong v = op->val;
36 const fmpz *p = (&ctx->pctx)->p;
37
38 if (padic_poly_is_zero(op))
39 {
40 padic_poly_one(rop);
41 return 1;
42 }
43
44 if ((*p == WORD(2) && v <= 1) || (v <= 0))
45 {
46 return 0;
47 }
48 else
49 {
50 if (v < N)
51 {
52 const slong d = qadic_ctx_degree(ctx);
53
54 fmpz *t;
55 fmpz_t pN;
56 int alloc;
57
58 alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx);
59
60 if (rop == op)
61 {
62 t = _fmpz_vec_init(2 * d - 1);
63 }
64 else
65 {
66 padic_poly_fit_length(rop, 2 * d - 1);
67 t = rop->coeffs;
68 }
69
70 _qadic_exp(t, op->coeffs, v, op->length,
71 ctx->a, ctx->j, ctx->len, p, N, pN);
72 rop->val = 0;
73
74 if (rop == op)
75 {
76 _fmpz_vec_clear(rop->coeffs, rop->alloc);
77 rop->coeffs = t;
78 rop->alloc = 2 * d - 1;
79 rop->length = d;
80 }
81 _padic_poly_set_length(rop, d);
82 _padic_poly_normalise(rop);
83
84 if (alloc)
85 fmpz_clear(pN);
86 }
87 else
88 {
89 padic_poly_one(rop);
90 }
91 return 1;
92 }
93 }
94
95