1 /*
2     Copyright (C) 2011, 2012 Sebastian Pancratz
3     Copyright (C) 2012 Fredrik Johansson
4 
5     This file is part of FLINT.
6 
7     FLINT is free software: you can redistribute it and/or modify it under
8     the terms of the GNU Lesser General Public License (LGPL) as published
9     by the Free Software Foundation; either version 2.1 of the License, or
10     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
11 */
12 
13 #include "padic.h"
14 
_padic_exp_bound(slong v,slong N,const fmpz_t p)15 slong _padic_exp_bound(slong v, slong N, const fmpz_t p)
16 {
17     if (fmpz_fits_si(p))
18     {
19         fmpz_t n, d, f;
20         slong i;
21 
22         fmpz_init(n);
23         fmpz_init(d);
24         fmpz_init(f);
25 
26         fmpz_sub_ui(f, p, 1);
27         fmpz_mul_ui(n, f, N);
28         fmpz_sub_ui(n, n, 1);
29         fmpz_mul_ui(d, f, v);
30         fmpz_sub_ui(d, d, 1);
31         fmpz_cdiv_q(f, n, d);
32         i = fmpz_get_si(f);
33 
34         fmpz_clear(n);
35         fmpz_clear(d);
36         fmpz_clear(f);
37 
38         return i;
39     }
40     else
41     {
42         return (N + (v - 1)) / v;
43     }
44 }
45 
_padic_exp(fmpz_t rop,const fmpz_t u,slong v,const fmpz_t p,slong N)46 void _padic_exp(fmpz_t rop, const fmpz_t u, slong v, const fmpz_t p, slong N)
47 {
48     if (N < 1024)
49         _padic_exp_rectangular(rop, u, v, p, N);
50     else
51         _padic_exp_balanced(rop, u, v, p, N);
52 }
53 
padic_exp(padic_t rop,const padic_t op,const padic_ctx_t ctx)54 int padic_exp(padic_t rop, const padic_t op, const padic_ctx_t ctx)
55 {
56     const slong N  = padic_prec(rop);
57     const slong v  = padic_val(op);
58     const fmpz *p = ctx->p;
59 
60     if (padic_is_zero(op))
61     {
62         padic_one(rop);
63         return 1;
64     }
65 
66     if ((fmpz_equal_ui(p, 2) && v <= 1) || (v <= 0))
67     {
68         return 0;
69     }
70     else
71     {
72         if (v < N)
73         {
74             _padic_exp(padic_unit(rop), padic_unit(op), padic_val(op), p, N);
75             padic_val(rop) = 0;
76         }
77         else
78         {
79             padic_one(rop);
80         }
81         return 1;
82     }
83 }
84 
85