629 lines
22 KiB
Plaintext
629 lines
22 KiB
Plaintext
|
/*=============================================================================
|
||
|
|
||
|
This file is part of FLINT.
|
||
|
|
||
|
FLINT is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
FLINT is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with FLINT; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
|
||
|
=============================================================================*/
|
||
|
/******************************************************************************
|
||
|
|
||
|
Copyright (C) 2011, 2012 Sebastian Pancratz
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Data structures
|
||
|
|
||
|
A $p$-adic number of type \code{padic_t} comprises a unit~$u$,
|
||
|
a valuation~$v$, and a precision~$N$.
|
||
|
|
||
|
We provide the following macros to access these fields, so that
|
||
|
code can be developed somewhat independently from the underlying
|
||
|
data layout.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
fmpz * padic_unit(const padic_t op)
|
||
|
|
||
|
Returns the unit part of the $p$-adic number as a FLINT integer, which
|
||
|
can be used as an operand for the \code{fmpz} functions.
|
||
|
|
||
|
Note that this function is implemented as a macro, but it can only be
|
||
|
used as an \emph{rvalue}.
|
||
|
|
||
|
slong padic_val(const padic_t op)
|
||
|
|
||
|
Returns the valuation part of the $p$-adic number.
|
||
|
|
||
|
Note that this function is implemented as a macro and that
|
||
|
the expression \code{padic_val(op)} can be used as both an
|
||
|
\emph{lvalue} and an \emph{rvalue}.
|
||
|
|
||
|
slong padic_prec(const padic_t op)
|
||
|
|
||
|
Returns the precision of the $p$-adic number.
|
||
|
|
||
|
Note that this function is implemented as a macro and that
|
||
|
the expression \code{padic_prec(op)} can be used as both an
|
||
|
\emph{lvalue} and an \emph{rvalue}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Context
|
||
|
|
||
|
A context object for $p$-adic arithmetic contains data pertinent to
|
||
|
$p$-adic computations, but which we choose not to store with each
|
||
|
element individually.
|
||
|
|
||
|
Currently, this includes the prime number~$p$, its \code{double}
|
||
|
inverse in case of word-sized primes, precomputed powers of $p$
|
||
|
in the range given by \code{min} and \code{max}, and the printing
|
||
|
mode.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_ctx_init(padic_ctx_t ctx, const fmpz_t p, slong min, slong max,
|
||
|
enum padic_print_mode mode)
|
||
|
|
||
|
Initialises the context \code{ctx} with the given data.
|
||
|
|
||
|
Assumes that $p$ is a prime. This is not verified but the subsequent
|
||
|
behaviour is undefined if $p$ is a composite number.
|
||
|
|
||
|
Assumes that \code{min} and \code{max} are non-negative and that
|
||
|
\code{min} is at most \code{max}, raising and \code{abort} signal
|
||
|
otherwise.
|
||
|
|
||
|
Assumes that the printing mode is one of \code{PADIC_TERSE},
|
||
|
\code{PADIC_SERIES}, or\\ \code{PADIC_VAL_UNIT}. Using the example
|
||
|
$x = 7^{-1} 12$ in $\mathbf{Q}_7$, these behave as follows:
|
||
|
\begin{itemize}
|
||
|
\item In \code{PADIC_TERSE} mode, a $p$-adic number is printed
|
||
|
in the same way as a rational number, e.g.\ \code{12/7}.
|
||
|
\item In \code{PADIC_SERIES} mode, a $p$-adic number is printed
|
||
|
digit by digit, e.g.\ \code{5*7^-1 + 1}.
|
||
|
\item In \code{PADIC_VAL_UNIT} mode, a $p$-adic number is
|
||
|
printed showing the valuation and unit parts separately,
|
||
|
e.g.\ \code{12*7^-1}.
|
||
|
\end{itemize}
|
||
|
|
||
|
void padic_ctx_clear(padic_ctx_t ctx);
|
||
|
|
||
|
Clears all memory that has been allocated as part of the context.
|
||
|
|
||
|
int _padic_ctx_pow_ui(fmpz_t rop, ulong e, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to $p^e$ as efficiently as possible, where
|
||
|
\code{rop} is expected to be an uninitialised \code{fmpz_t}.
|
||
|
|
||
|
If the return value is non-zero, it is the responsibility of
|
||
|
the caller to clear the returned integer.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Memory management
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_init(padic_t rop)
|
||
|
|
||
|
Initialises the $p$-adic number with the precision set to
|
||
|
\code{PADIC_DEFAULT_PREC}, which is defined as~$20$.
|
||
|
|
||
|
void padic_init2(padic_t rop, slong N)
|
||
|
|
||
|
Initialises the $p$-adic number \code{rop} with precision~$N$.
|
||
|
|
||
|
void padic_clear(padic_t rop)
|
||
|
|
||
|
Clears all memory used by the $p$-adic number \code{rop}.
|
||
|
|
||
|
void _padic_canonicalise(padic_t rop, const padic_ctx_t ctx)
|
||
|
|
||
|
Brings the $p$-adic number \code{rop} into canonical form.
|
||
|
|
||
|
That is to say, ensures that either $u = v = 0$ or
|
||
|
$p \nmid u$. There is no reduction modulo a power
|
||
|
of $p$.
|
||
|
|
||
|
void _padic_reduce(padic_t rop, const padic_ctx_t ctx)
|
||
|
|
||
|
Given a $p$-adic number \code{rop} in canonical form,
|
||
|
reduces it modulo $p^N$.
|
||
|
|
||
|
void padic_reduce(padic_t rop, const padic_ctx_t ctx)
|
||
|
|
||
|
Ensures that the $p$-adic number \code{rop} is reduced.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Randomisation
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_randtest(padic_t rop, flint_rand_t state, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to a random $p$-adic number modulo $p^N$ with valuation
|
||
|
in the range $[- \ceil{N/10}, N)$, $[N - \ceil{-N/10}, N)$, or $[-10, 0)$
|
||
|
as $N$ is positive, negative or zero, whenever \code{rop} is non-zero.
|
||
|
|
||
|
void padic_randtest_not_zero(padic_t rop, flint_rand_t state,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to a random non-zero $p$-adic number modulo $p^N$,
|
||
|
where the range of the valuation is as for the function
|
||
|
\code{padic_randtest()}.
|
||
|
|
||
|
void padic_randtest_int(padic_t rop, flint_rand_t state,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to a random $p$-adic integer modulo $p^N$.
|
||
|
|
||
|
Note that whenever $N \leq 0$, \code{rop} is set to zero.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Assignments and conversions
|
||
|
|
||
|
All assignment functions set the value of \code{rop} from \code{op},
|
||
|
reduced to the precision of \code{rop}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_set(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the $p$-adic number \code{op}.
|
||
|
|
||
|
void padic_set_si(padic_t rop, slong op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the $p$-adic number \code{rop} to the
|
||
|
\code{slong} integer \code{op}.
|
||
|
|
||
|
void padic_set_ui(padic_t rop, ulong op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the $p$-adic number \code{rop} to the \code{ulong}
|
||
|
integer \code{op}.
|
||
|
|
||
|
void padic_set_fmpz(padic_t rop, const fmpz_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the $p$-adic number \code{rop} to the integer \code{op}.
|
||
|
|
||
|
void padic_set_fmpq(padic_t rop, const fmpq_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the rational \code{op}.
|
||
|
|
||
|
void padic_set_mpz(padic_t rop, const mpz_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the $p$-adic number \code{rop} to the MPIR integer \code{op}.
|
||
|
|
||
|
void padic_set_mpq(padic_t rop, const mpq_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the MPIR rational \code{op}.
|
||
|
|
||
|
void padic_get_fmpz(fmpz_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the integer \code{rop} to the exact $p$-adic integer \code{op}.
|
||
|
|
||
|
If \code{op} is not a $p$-adic integer, raises an \code{abort} signal.
|
||
|
|
||
|
void padic_get_fmpq(fmpq_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the rational \code{rop} to the $p$-adic number \code{op}.
|
||
|
|
||
|
void padic_get_mpz(mpz_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the MPIR integer \code{rop} to the $p$-adic integer \code{op}.
|
||
|
|
||
|
If \code{op} is not a $p$-adic integer, raises an \code{abort} signal.
|
||
|
|
||
|
void padic_get_mpq(mpq_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the MPIR rational \code{rop} to the value of \code{op}.
|
||
|
|
||
|
void padic_swap(padic_t op1, padic_t op2)
|
||
|
|
||
|
Swaps the two $p$-adic numbers \code{op1} and \code{op2}.
|
||
|
|
||
|
Note that this includes swapping the precisions. In particular, this
|
||
|
operation is not equivalent to swapping \code{op1} and \code{op2}
|
||
|
using \code{padic_set()} and an auxiliary variable whenever the
|
||
|
precisions of the two elements are different.
|
||
|
|
||
|
void padic_zero(padic_t rop)
|
||
|
|
||
|
Sets the $p$-adic number \code{rop} to zero.
|
||
|
|
||
|
void padic_one(padic_t rop)
|
||
|
|
||
|
Sets the $p$-adic number \code{rop} to one, reduced modulo the
|
||
|
precision of \code{rop}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Comparison
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
int padic_is_zero(const padic_t op)
|
||
|
|
||
|
Returns whether \code{op} is equal to zero.
|
||
|
|
||
|
int padic_is_one(const padic_t op)
|
||
|
|
||
|
Returns whether \code{op} is equal to one, that is, whether
|
||
|
$u = 1$ and $v = 0$.
|
||
|
|
||
|
int padic_equal(const padic_t op1, const padic_t op2)
|
||
|
|
||
|
Returns whether \code{op1} and \code{op2} are equal, that is,
|
||
|
whether $u_1 = u_2$ and $v_1 = v_2$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Arithmetic operations
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
slong * _padic_lifts_exps(slong *n, slong N)
|
||
|
|
||
|
Given a positive integer $N$ define the sequence
|
||
|
$a_0 = N, a_1 = \ceil{a_0/2}, \dotsc, a_{n-1} = \ceil{a_{n-2}/2} = 1$.
|
||
|
Then $n = \ceil{\log_2 N} + 1$.
|
||
|
|
||
|
This function sets $n$ and allocates and returns the array~$a$.
|
||
|
|
||
|
void _padic_lifts_pows(fmpz *pow, const slong *a, slong n, const fmpz_t p)
|
||
|
|
||
|
Given an array~$a$ as computed above, this function
|
||
|
computes the corresponding powers of $p$, that is,
|
||
|
\code{pow[i]} is equal to $p^{a_i}$.
|
||
|
|
||
|
void padic_add(padic_t rop, const padic_t op1, const padic_t op2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the sum of \code{op1} and \code{op2}.
|
||
|
|
||
|
void padic_sub(padic_t rop, const padic_t op1, const padic_t op2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the difference of \code{op1} and \code{op2}.
|
||
|
|
||
|
void padic_neg(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the additive inverse of \code{op}.
|
||
|
|
||
|
void padic_mul(padic_t rop, const padic_t op1, const padic_t op2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the product of \code{op1} and \code{op2}.
|
||
|
|
||
|
void padic_shift(padic_t rop, const padic_t op, slong v, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the product of \code{op} and $p^v$.
|
||
|
|
||
|
void padic_div(padic_t rop, const padic_t op1, const padic_t op2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the quotient of \code{op1} and \code{op2}.
|
||
|
|
||
|
void _padic_inv_precompute(padic_inv_t S, const fmpz_t p, slong N)
|
||
|
|
||
|
Pre-computes some data and allocates temporary space for
|
||
|
$p$-adic inversion using Hensel lifting.
|
||
|
|
||
|
void _padic_inv_clear(padic_inv_t S)
|
||
|
|
||
|
Frees the memory used by $S$.
|
||
|
|
||
|
void _padic_inv_precomp(fmpz_t rop, const fmpz_t op, const padic_inv_t S)
|
||
|
|
||
|
Sets \code{rop} to the inverse of \code{op} modulo $p^N$,
|
||
|
assuming that \code{op} is a unit and $N \geq 1$.
|
||
|
|
||
|
In the current implementation, allows aliasing, but this might
|
||
|
change in future versions.
|
||
|
|
||
|
Uses some data $S$ precomputed by calling the function
|
||
|
\code{_padic_inv_precompute()}. Note that this object
|
||
|
is not declared \code{const} and in fact it carries a field
|
||
|
providing temporary work space. This allows repeated calls of
|
||
|
this function to avoid repeated memory allocations, as used
|
||
|
e.g.\ by the function \code{padic_log()}.
|
||
|
|
||
|
void _padic_inv(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N)
|
||
|
|
||
|
Sets \code{rop} to the inverse of \code{op} modulo $p^N$,
|
||
|
assuming that \code{op} is a unit and $N \geq 1$.
|
||
|
|
||
|
In the current implementation, allows aliasing, but this might
|
||
|
change in future versions.
|
||
|
|
||
|
void padic_inv(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Computes the inverse of \code{op} modulo $p^N$.
|
||
|
|
||
|
Suppose that \code{op} is given as $x = u p^v$.
|
||
|
Raises an \code{abort} signal if $v < -N$. Otherwise,
|
||
|
computes the inverse of $u$ modulo $p^{N+v}$.
|
||
|
|
||
|
This function employs Hensel lifting of an inverse modulo $p$.
|
||
|
|
||
|
int padic_sqrt(padic_rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether \code{op} is a $p$-adic square. If this is
|
||
|
the case, sets \code{rop} to one of the square roots; otherwise,
|
||
|
the value of \code{rop} is undefined.
|
||
|
|
||
|
We have the following theorem:
|
||
|
|
||
|
Let $u \in \mathbf{Z}^{\times}$. Then $u$ is a
|
||
|
square if and only if $u \bmod p$ is a square in
|
||
|
$\mathbf{Z} / p \mathbf{Z}$, for $p > 2$, or if
|
||
|
$u \bmod 8$ is a square in $\mathbf{Z} / 8 \mathbf{Z}$,
|
||
|
for $p = 2$.
|
||
|
|
||
|
void padic_pow_si(padic_t rop, const padic_t op, slong e,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to \code{op} raised to the power~$e$,
|
||
|
which is defined as one whenever $e = 0$.
|
||
|
|
||
|
Assumes that some computations involving $e$ and the
|
||
|
valuation of \code{op} do not overflow in the \code{slong}
|
||
|
range.
|
||
|
|
||
|
Note that if the input $x = p^v u$ is defined modulo $p^N$
|
||
|
then $x^e = p^{ev} u^e$ is defined modulo $p^{N + (e - 1) v}$,
|
||
|
which is a precision loss in case $v < 0$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Exponential
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
slong _padic_exp_bound(slong v, slong N, const fmpz_t p)
|
||
|
|
||
|
Returns an integer $i$ such that for all $j \geq i$ we have
|
||
|
$\ord_p(x^j / j!) \geq N$, where $\ord_p(x) = v$.
|
||
|
|
||
|
When $p$ is a word-sized prime,
|
||
|
returns $\ceil{\frac{(p-1)N - 1}{(p-1)v - 1}}$.
|
||
|
Otherwise, returns $\ceil{N/v}$.
|
||
|
|
||
|
Assumes that $v < N$. Moreover, $v$ has to be at least $2$ or $1$,
|
||
|
depending on whether $p$ is $2$ or odd.
|
||
|
|
||
|
void _padic_exp_rectangular(fmpz_t rop, const fmpz_t u, slong v,
|
||
|
const fmpz_t p, slong N)
|
||
|
|
||
|
void _padic_exp_balanced(fmpz_t rop, const fmpz_t u, slong v,
|
||
|
const fmpz_t p, slong N)
|
||
|
|
||
|
void _padic_exp(fmpz_t rop, const fmpz_t u, slong v, const fmpz_t p, slong N)
|
||
|
|
||
|
Sets \code{rop} to the $p$-exponential function evaluated at
|
||
|
$x = p^v u$, reduced modulo~$p^N$.
|
||
|
|
||
|
Assumes that $x \neq 0$, that $\ord_p(x) < N$ and that
|
||
|
$\exp(x)$ converges, that is, that $\ord_p(x)$ is at least
|
||
|
$2$ or $1$ depending on whether the prime~$p$ is $2$ or odd.
|
||
|
|
||
|
Supports aliasing between \code{rop} and $u$.
|
||
|
|
||
|
int padic_exp(padic_t y, const padic_t x, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the $p$-adic exponential function converges at
|
||
|
the $p$-adic number $x$, and if so sets $y$ to its value.
|
||
|
|
||
|
The $p$-adic exponential function is defined by the usual series
|
||
|
\begin{equation*}
|
||
|
\exp_p(x) = \sum_{i = 0}^{\infty} \frac{x^i}{i!}
|
||
|
\end{equation*}
|
||
|
but this only converges only when $\ord_p(x) > 1 / (p - 1)$. For
|
||
|
elements $x \in \mathbf{Q}_p$, this means that $\ord_p(x) \geq 1$
|
||
|
when $p \geq 3$ and $\ord_2(x) \geq 2$ when $p = 2$.
|
||
|
|
||
|
int padic_exp_rectangular(padic_t y, const padic_t x, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the $p$-adic exponential function converges at
|
||
|
the $p$-adic number $x$, and if so sets $y$ to its value.
|
||
|
|
||
|
Uses a rectangular splitting algorithm to evaluate the series
|
||
|
expression of $\exp(x) \bmod{p^N}$.
|
||
|
|
||
|
int padic_exp_balanced(padic_t y, const padic_t x, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the $p$-adic exponential function converges at
|
||
|
the $p$-adic number $x$, and if so sets $y$ to its value.
|
||
|
|
||
|
Uses a balanced approach, balancing the size of chunks of $x$
|
||
|
with the valuation and hence the rate of convergence, which
|
||
|
results in a quasi-linear algorithm in $N$, for fixed $p$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Logarithm
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
slong _padic_log_bound(slong v, slong N, const fmpz_t p)
|
||
|
|
||
|
Returns $b$ such that for all $i \geq b$ we have
|
||
|
\begin{equation*}
|
||
|
i v - \ord_p(i) \geq N
|
||
|
\end{equation*}
|
||
|
where $v \geq 1$.
|
||
|
|
||
|
Assumes that $1 \leq v < N$ or $2 \leq v < N$ when $p$ is
|
||
|
odd or $p = 2$, respectively, and also that $N < 2^{f-2}$
|
||
|
where $f$ is \code{FLINT_BITS}.
|
||
|
|
||
|
void _padic_log(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N)
|
||
|
|
||
|
void _padic_log_rectangular(fmpz_t z,
|
||
|
const fmpz_t y, slong v, const fmpz_t p, slong N)
|
||
|
|
||
|
void _padic_log_satoh(fmpz_t z,
|
||
|
const fmpz_t y, slong v, const fmpz_t p, slong N)
|
||
|
|
||
|
void _padic_log_balanced(fmpz_t z,
|
||
|
const fmpz_t y, slong v, const fmpz_t p, slong N)
|
||
|
|
||
|
Computes
|
||
|
\begin{equation*}
|
||
|
z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N},
|
||
|
\end{equation*}
|
||
|
reduced modulo $p^N$.
|
||
|
|
||
|
Note that this can be used to compute the $p$-adic logarithm
|
||
|
via the equation
|
||
|
\begin{align*}
|
||
|
\log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\
|
||
|
& = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}.
|
||
|
\end{align*}
|
||
|
|
||
|
Assumes that $y = 1 - x$ is non-zero and that $v = \ord_p(y)$
|
||
|
is at least $1$ when $p$ is odd and at least $2$ when $p = 2$
|
||
|
so that the series converges.
|
||
|
|
||
|
Assumes that $v < N$, and hence in particular $N \geq 2$.
|
||
|
|
||
|
Does not support aliasing between $y$ and $z$.
|
||
|
|
||
|
int padic_log(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the $p$-adic logarithm function converges at
|
||
|
the $p$-adic number \code{op}, and if so sets \code{rop} to its
|
||
|
value.
|
||
|
|
||
|
The $p$-adic logarithm function is defined by the usual series
|
||
|
\begin{equation*}
|
||
|
\log_p(x) = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i}
|
||
|
\end{equation*}
|
||
|
but this only converges when $\ord_p(x)$ is at least $2$ or $1$
|
||
|
when $p = 2$ or $p > 2$, respectively.
|
||
|
|
||
|
int padic_log_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the $p$-adic logarithm function converges at
|
||
|
the $p$-adic number \code{op}, and if so sets \code{rop} to its
|
||
|
value.
|
||
|
|
||
|
Uses a rectangular splitting algorithm to evaluate the series
|
||
|
expression of $\log(x) \bmod{p^N}$.
|
||
|
|
||
|
int padic_log_satoh(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the $p$-adic logarithm function converges at
|
||
|
the $p$-adic number \code{op}, and if so sets \code{rop} to its
|
||
|
value.
|
||
|
|
||
|
Uses an algorithm based on a result of Satoh, Skjernaa and Taguchi
|
||
|
that $\ord_p\bigl(a^{p^k} - 1\bigr) > k$, which implies that
|
||
|
\begin{equation*}
|
||
|
\log(a) \equiv p^{-k} \Bigl( \log\bigl(a^{p^k}\bigr) \pmod{p^{N+k}}
|
||
|
\Bigr) \pmod{p^N}.
|
||
|
\end{equation*}
|
||
|
|
||
|
int padic_log_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the $p$-adic logarithm function converges at
|
||
|
the $p$-adic number \code{op}, and if so sets \code{rop} to its
|
||
|
value.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Special functions
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N)
|
||
|
|
||
|
Computes the Teichmuller lift of the $p$-adic unit \code{op},
|
||
|
assuming that $N \geq 1$.
|
||
|
|
||
|
Supports aliasing between \code{rop} and \code{op}.
|
||
|
|
||
|
void padic_teichmuller(padic_t rop, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Computes the Teichmuller lift of the $p$-adic unit \code{op}.
|
||
|
|
||
|
If \code{op} is a $p$-adic integer divisible by $p$, sets \code{rop}
|
||
|
to zero, which satisfies $t^p - t = 0$, although it is clearly not
|
||
|
a $(p-1)$-st root of unity.
|
||
|
|
||
|
If \code{op} has negative valuation, raises an \code{abort} signal.
|
||
|
|
||
|
ulong padic_val_fac_ui_2(ulong n)
|
||
|
|
||
|
Computes the $2$-adic valuation of $n!$.
|
||
|
|
||
|
Note that since $n$ fits into an \code{ulong}, so does
|
||
|
$\ord_2(n!)$ since $\ord_2(n!) \leq (n - 1) / (p - 1) = n - 1$.
|
||
|
|
||
|
ulong padic_val_fac_ui(ulong n, const fmpz_t p)
|
||
|
|
||
|
Computes the $p$-adic valuation of $n!$.
|
||
|
|
||
|
Note that since $n$ fits into an \code{ulong}, so does
|
||
|
$\ord_p(n!)$ since $\ord_p(n!) \leq (n - 1) / (p - 1)$.
|
||
|
|
||
|
void padic_val_fac(fmpz_t rop, const fmpz_t op, const fmpz_t p)
|
||
|
|
||
|
Sets \code{rop} to the $p$-adic valuation of the factorial
|
||
|
of \code{op}, assuming that \code{op} is non-negative.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Input and output
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
char * padic_get_str(char * str, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns the string representation of the $p$-adic number \code{op}
|
||
|
according to the printing mode set in the context.
|
||
|
|
||
|
If \code{str} is \code{NULL} then a new block of memory is allocated
|
||
|
and a pointer to this is returned. Otherwise, it is assumed that
|
||
|
the string \code{str} is large enough to hold the representation and
|
||
|
it is also the return value.
|
||
|
|
||
|
int _padic_fprint(FILE * file, const fmpz_t u, slong v, const padic_ctx_t ctx)
|
||
|
|
||
|
int padic_fprint(FILE * file, const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Prints the string representation of the $p$-adic number \code{op}
|
||
|
to the stream \code{file}.
|
||
|
|
||
|
In the current implementation, always returns $1$.
|
||
|
|
||
|
int _padic_print(const fmpz_t u, slong v, const padic_ctx_t ctx)
|
||
|
|
||
|
int padic_print(const padic_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Prints the string representation of the $p$-adic number \code{op}
|
||
|
to the stream \code{stdout}.
|
||
|
|
||
|
In the current implementation, always returns $1$.
|
||
|
|
||
|
void padic_debug(const padic_t op)
|
||
|
|
||
|
Prints debug information about \code{op} to the stream \code{stdout},
|
||
|
in the format \code{"(u v N)"}.
|
||
|
|