pqc/external/flint-2.4.3/padic/doc/padic.txt
2014-05-24 23:16:06 +02:00

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)"}.