Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
p-adic numbers
A Padic
represents a p-adic number.
This module implements operations p-adic numbers.
Basic usage
Calculate a solution of \(x^2-2=0\) over \(\mathbb Q_7\) using default precision (20 digits).
import Data.Number.Flint main = do withNewPadicCtx 7 1 20 padic_series $ \ctx -> withNewPadic $ \x -> do padic_set_ui x 2 ctx padic_sqrt x x ctx padic_print x ctx putStr "\n"
Running main yields:
>>>
main
3 + 1*7^1 + 2*7^2 + 6*7^3 + 1*7^4 + 2*7^5 + 1*7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 1*7^12 + 1*7^13 + 2*7^15 + 1*7^16 + 1*7^17 + 4*7^18 + 6*7^19
Introduction
The Padic
data type represents elements of \(\mathbb{Q}_p\) to
precision \(N\), stored in the form \(x = p^v u\)
with \(u, v \in \mathbb{Z}\). Arithmetic operations can be carried out with
respect to a context containing the prime number \(p\) and various
pieces of pre-computed data.
Independent of the context, we consider a \(p\)-adic number x = u p^v to be in canonical form whenever either p nmid u or \(u = v = 0\), and we say it is reduced if, in addition, for non-zero \(u\), \(u \in (0, p^{N-v})\).
We briefly describe the interface:
The functions in this module expect arguments of type Padic
, and
each variable carries its own precision. The functions have an interface
that is similar to the MPFR functions. In particular, they have the same
semantics, specified as follows: Compute the requested operation exactly
and then reduce the result to the precision of the output variable.
Synopsis
- data Padic = Padic !(ForeignPtr CPadic)
- data CPadic = CPadic (Ptr CFmpz) CLong CLong
- newPadic :: IO Padic
- withPadic :: Padic -> (Ptr CPadic -> IO a) -> IO (Padic, a)
- withNewPadic :: (Ptr CPadic -> IO a) -> IO (Padic, a)
- data PadicCtx = PadicCtx !(ForeignPtr CPadicCtx)
- data CPadicCtx = CPadicCtx (Ptr CFmpz) CDouble (Ptr CFmpz) CLong CLong PadicPrintMode
- newPadicCtx :: Fmpz -> CLong -> CLong -> PadicPrintMode -> IO PadicCtx
- withPadicCtx :: PadicCtx -> (Ptr CPadicCtx -> IO a) -> IO (PadicCtx, a)
- withNewPadicCtx :: Fmpz -> CLong -> CLong -> PadicPrintMode -> (Ptr CPadicCtx -> IO a) -> IO (PadicCtx, a)
- padic_unit :: Ptr CPadic -> IO (Ptr CFmpz)
- padic_get_val :: Ptr CPadic -> IO CLong
- padic_get_prec :: Ptr CPadic -> IO CLong
- padic_ctx_init :: Ptr CPadicCtx -> Ptr CFmpz -> CLong -> CLong -> PadicPrintMode -> IO ()
- padic_ctx_clear :: Ptr CPadicCtx -> IO ()
- _padic_ctx_pow_ui :: Ptr CFmpz -> CULong -> Ptr CPadicCtx -> IO CInt
- padic_ctx_print :: Ptr CPadicCtx -> IO ()
- padic_init :: Ptr CPadic -> IO ()
- padic_init2 :: Ptr CPadic -> CLong -> IO ()
- padic_clear :: Ptr CPadic -> IO ()
- _padic_canonicalise :: Ptr CPadic -> Ptr CPadicCtx -> IO ()
- _padic_reduce :: Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_reduce :: Ptr CPadic -> Ptr CPadicCtx -> IO ()
- newtype PadicPrintMode = PadicPrintMode {}
- padic_terse :: PadicPrintMode
- padic_series :: PadicPrintMode
- padic_val_unit :: PadicPrintMode
- padic_randtest :: Ptr CPadic -> Ptr CFRandState -> Ptr CPadicCtx -> IO ()
- padic_randtest_not_zero :: Ptr CPadic -> Ptr CFRandState -> Ptr CPadicCtx -> IO ()
- padic_randtest_int :: Ptr CPadic -> Ptr CFRandState -> Ptr CPadicCtx -> IO ()
- padic_set :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_set_si :: Ptr CPadic -> CLong -> Ptr CPadicCtx -> IO ()
- padic_set_ui :: Ptr CPadic -> CULong -> Ptr CPadicCtx -> IO ()
- padic_set_fmpz :: Ptr CPadic -> Ptr CFmpz -> Ptr CPadicCtx -> IO ()
- padic_set_fmpq :: Ptr CPadic -> Ptr CFmpq -> Ptr CPadicCtx -> IO ()
- padic_set_mpz :: Ptr CPadic -> Ptr CMpz -> Ptr CPadicCtx -> IO ()
- padic_set_mpq :: Ptr CPadic -> Ptr CMpq -> Ptr CPadicCtx -> IO ()
- padic_get_fmpz :: Ptr CFmpz -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_get_fmpq :: Ptr CFmpq -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_get_mpz :: Ptr CMpz -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_get_mpq :: Ptr CMpq -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_swap :: Ptr CPadic -> Ptr CPadic -> IO ()
- padic_zero :: Ptr CPadic -> IO ()
- padic_one :: Ptr CPadic -> IO ()
- padic_is_zero :: Ptr CPadic -> IO CInt
- padic_is_one :: Ptr CPadic -> IO CInt
- padic_equal :: Ptr CPadic -> Ptr CPadic -> IO CInt
- _padic_lifts_exps :: Ptr CLong -> CLong -> IO (Ptr CLong)
- _padic_lifts_pows :: Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> IO ()
- padic_add :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_sub :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_neg :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_mul :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_shift :: Ptr CPadic -> Ptr CPadic -> CLong -> Ptr CPadicCtx -> IO ()
- padic_div :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- _padic_inv_precompute :: Ptr CPadicInv -> Ptr CFmpz -> CLong -> IO ()
- _padic_inv_clear :: Ptr CPadicInv -> IO ()
- _padic_inv_precomp :: Ptr CFmpz -> Ptr CFmpz -> Ptr CPadicInv -> IO ()
- _padic_inv :: Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> CLong -> IO ()
- padic_inv :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_sqrt :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- padic_pow_si :: Ptr CPadic -> Ptr CPadic -> CLong -> Ptr CPadicCtx -> IO ()
- _padic_exp_bound :: CLong -> CLong -> Ptr CFmpz -> IO CLong
- _padic_exp_rectangular :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> CLong -> IO ()
- padic_exp :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- padic_exp_rectangular :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- padic_exp_balanced :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- _padic_log_bound :: CLong -> CLong -> Ptr CFmpz -> IO CLong
- _padic_log :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> CLong -> IO ()
- padic_log :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- padic_log_rectangular :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- padic_log_satoh :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- padic_log_balanced :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- _padic_teichmuller :: Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> CLong -> IO ()
- padic_teichmuller :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO ()
- padic_val_fac_ui_2 :: CULong -> IO CULong
- padic_val_fac_ui :: CULong -> Ptr CFmpz -> IO CULong
- padic_val_fac :: Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO ()
- padic_get_str :: CString -> Ptr CPadic -> Ptr CPadicCtx -> IO CString
- _padic_fprint :: Ptr CFile -> Ptr CFmpz -> CLong -> Ptr CPadicCtx -> IO CInt
- _padic_print :: Ptr CFmpz -> CLong -> Ptr CPadicCtx -> IO CInt
- padic_print :: Ptr CPadic -> Ptr CPadicCtx -> IO CInt
- padic_debug :: Ptr CPadic -> IO ()
Data structures
p-adic numbers
A p-adic number of type Padic comprises \(a\) unit \(u\), a valuation
\(v\), and a precision \(N\). Create with newPadic
.
p-adic context
A context object for p 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 double inverse in case of word-sized primes,
precomputed powers of \(p\) in the range given by min and max, and the
printing mode. Create with newPadicCtx
.
Instances
Storable CPadicCtx Source # | |
Defined in Data.Number.Flint.Padic.FFI |
newPadicCtx :: Fmpz -> CLong -> CLong -> PadicPrintMode -> IO PadicCtx Source #
Create p-adic context with prime \(p\), precomputed powers \(p^{min}\)
to \(p^{max}\) and PadicPrintMode
mode
.
withNewPadicCtx :: Fmpz -> CLong -> CLong -> PadicPrintMode -> (Ptr CPadicCtx -> IO a) -> IO (PadicCtx, a) Source #
Use new p-adic ctx
padic_unit :: Ptr CPadic -> IO (Ptr CFmpz) Source #
padic_unit op
Returns the unit part of the \(p\)-adic number as a FLINT integer, which
can be used as an operand for the fmpz
functions.
padic_get_val :: Ptr CPadic -> IO CLong Source #
padic_get_val op
Returns the valuation part of the \(p\)-adic number.
padic_get_prec :: Ptr CPadic -> IO CLong Source #
padic_get_prec op
Returns the precision of the \(p\)-adic number.
padic_ctx_init :: Ptr CPadicCtx -> Ptr CFmpz -> CLong -> CLong -> PadicPrintMode -> IO () Source #
padic_ctx_init ctx p min max mode
Initialises the context 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 min
and max
are non-negative and that min
is at most
max
, raising an abort
signal otherwise.
Assumes that the printing mode is one of PADIC_TERSE
, PADIC_SERIES
,
or PADIC_VAL_UNIT
. Using the example \(x = 7^{-1} 12\) in
\(\mathbf{Q}_7\), these behave as follows:
In padic_terseE
mode, a \(p\)-adic number is printed in the same way as
a rational number, e.g. 12/7
.
In padic_series
mode, a \(p\)-adic number is printed digit by digit,
e.g. 5*7^-1 + 1
.
In padic_val_unit
mode, a \(p\)-adic number is printed showing the
valuation and unit parts separately, e.g. 12*7^-1
.
padic_ctx_clear :: Ptr CPadicCtx -> IO () Source #
padic_ctx_clear ctx
Clears all memory that has been allocated as part of the context.
_padic_ctx_pow_ui :: Ptr CFmpz -> CULong -> Ptr CPadicCtx -> IO CInt Source #
_padic_ctx_pow_ui rop e ctx
Sets rop
to \(p^e\) as efficiently as possible, where rop
is
expected to be an uninitialised fmpz_t
.
If the return value is non-zero, it is the responsibility of the caller to clear the returned integer.
Memory management
padic_init :: Ptr CPadic -> IO () Source #
padic_init rop
Initialises the \(p\)-adic number with the precision set to
PADIC_DEFAULT_PREC
, which is defined as \(20\).
padic_init2 :: Ptr CPadic -> CLong -> IO () Source #
padic_init2 rop N
Initialises the \(p\)-adic number rop
with precision \(N\).
padic_clear :: Ptr CPadic -> IO () Source #
padic_clear rop
Clears all memory used by the \(p\)-adic number rop
.
_padic_canonicalise :: Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
_padic_canonicalise rop ctx
Brings the \(p\)-adic number 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\).
_padic_reduce :: Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
_padic_reduce rop ctx
Given a \(p\)-adic number rop
in canonical form, reduces it modulo
\(p^N\).
padic_reduce :: Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_reduce rop ctx
Ensures that the \(p\)-adic number rop
is reduced.
newtype PadicPrintMode Source #
Instances
Storable PadicPrintMode Source # | |
Defined in Data.Number.Flint.Padic.FFI sizeOf :: PadicPrintMode -> Int # alignment :: PadicPrintMode -> Int # peekElemOff :: Ptr PadicPrintMode -> Int -> IO PadicPrintMode # pokeElemOff :: Ptr PadicPrintMode -> Int -> PadicPrintMode -> IO () # peekByteOff :: Ptr b -> Int -> IO PadicPrintMode # pokeByteOff :: Ptr b -> Int -> PadicPrintMode -> IO () # peek :: Ptr PadicPrintMode -> IO PadicPrintMode # poke :: Ptr PadicPrintMode -> PadicPrintMode -> IO () # | |
Show PadicPrintMode Source # | |
Defined in Data.Number.Flint.Padic.FFI showsPrec :: Int -> PadicPrintMode -> ShowS # show :: PadicPrintMode -> String # showList :: [PadicPrintMode] -> ShowS # | |
Eq PadicPrintMode Source # | |
Defined in Data.Number.Flint.Padic.FFI (==) :: PadicPrintMode -> PadicPrintMode -> Bool # (/=) :: PadicPrintMode -> PadicPrintMode -> Bool # |
Randomisation
padic_randtest :: Ptr CPadic -> Ptr CFRandState -> Ptr CPadicCtx -> IO () Source #
padic_randtest rop state ctx
Sets rop
to a random \(p\)-adic number modulo \(p^N\) with valuation
in the range \([- \lceil N/10\rceil, N)\),
\([N - \lceil -N/10\rceil, N)\), or \([-10, 0)\) as \(N\) is positive,
negative or zero, whenever rop
is non-zero.
padic_randtest_not_zero :: Ptr CPadic -> Ptr CFRandState -> Ptr CPadicCtx -> IO () Source #
padic_randtest_not_zero rop state ctx
Sets rop
to a random non-zero \(p\)-adic number modulo \(p^N\), where
the range of the valuation is as for the function padic_randtest
.
padic_randtest_int :: Ptr CPadic -> Ptr CFRandState -> Ptr CPadicCtx -> IO () Source #
padic_randtest_int rop state ctx
Sets rop
to a random \(p\)-adic integer modulo \(p^N\).
Note that whenever \(N \leq 0\), rop
is set to zero.
Assignments and conversions
padic_set :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_set rop op ctx
Sets rop
to the \(p\)-adic number op
.
padic_set_si :: Ptr CPadic -> CLong -> Ptr CPadicCtx -> IO () Source #
padic_set_si rop op ctx
Sets the \(p\)-adic number rop
to the slong
integer op
.
padic_set_ui :: Ptr CPadic -> CULong -> Ptr CPadicCtx -> IO () Source #
padic_set_ui rop op ctx
Sets the \(p\)-adic number rop
to the ulong
integer op
.
padic_set_fmpz :: Ptr CPadic -> Ptr CFmpz -> Ptr CPadicCtx -> IO () Source #
padic_set_fmpz rop op ctx
Sets the \(p\)-adic number rop
to the integer op
.
padic_set_fmpq :: Ptr CPadic -> Ptr CFmpq -> Ptr CPadicCtx -> IO () Source #
padic_set_fmpq rop op ctx
Sets rop
to the rational op
.
padic_set_mpz :: Ptr CPadic -> Ptr CMpz -> Ptr CPadicCtx -> IO () Source #
padic_set_mpz rop op ctx
Sets the \(p\)-adic number rop
to the MPIR integer op
.
padic_set_mpq :: Ptr CPadic -> Ptr CMpq -> Ptr CPadicCtx -> IO () Source #
padic_set_mpq rop op ctx
Sets rop
to the MPIR rational op
.
padic_get_fmpz :: Ptr CFmpz -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_get_fmpz rop op ctx
Sets the integer rop
to the exact \(p\)-adic integer op
.
If op
is not a \(p\)-adic integer, raises an abort
signal.
padic_get_fmpq :: Ptr CFmpq -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_get_fmpq rop op ctx
Sets the rational rop
to the \(p\)-adic number op
.
padic_get_mpz :: Ptr CMpz -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_get_mpz rop op ctx
Sets the MPIR integer rop
to the \(p\)-adic integer op
.
If op
is not a \(p\)-adic integer, raises an abort
signal.
padic_get_mpq :: Ptr CMpq -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_get_mpq rop op ctx
Sets the MPIR rational rop
to the value of op
.
padic_swap :: Ptr CPadic -> Ptr CPadic -> IO () Source #
padic_swap op1 op2
Swaps the two \(p\)-adic numbers op1
and op2
.
Note that this includes swapping the precisions. In particular, this
operation is not equivalent to swapping op1
and op2
using
padic_set
and an auxiliary variable whenever the precisions of the two
elements are different.
padic_one :: Ptr CPadic -> IO () Source #
padic_one rop
Sets the \(p\)-adic number rop
to one, reduced modulo the precision of
rop
.
Comparison
padic_is_zero :: Ptr CPadic -> IO CInt Source #
padic_is_zero op
Returns whether op
is equal to zero.
padic_is_one :: Ptr CPadic -> IO CInt Source #
padic_is_one op
Returns whether op
is equal to one, that is, whether \(u = 1\) and
\(v = 0\).
padic_equal :: Ptr CPadic -> Ptr CPadic -> IO CInt Source #
padic_equal op1 op2
Returns whether op1
and op2
are equal, that is, whether
\(u_1 = u_2\) and \(v_1 = v_2\).
Arithmetic operations
_padic_lifts_exps :: Ptr CLong -> CLong -> IO (Ptr CLong) Source #
_padic_lifts_exps n N
Given a positive integer \(N\) define the sequence \(a_0 = N, a_1 = \lceil a_0/2\rceil, \dotsc, a_{n-1} = \lceil a_{n-2}/2\rceil = 1\). Then \(n = \lceil\log_2 N\rceil + 1\).
This function sets \(n\) and allocates and returns the array \(a\).
_padic_lifts_pows :: Ptr CFmpz -> Ptr CLong -> CLong -> Ptr CFmpz -> IO () Source #
_padic_lifts_pows pow a n p
Given an array \(a\) as computed above, this function computes the
corresponding powers of \(p\), that is, pow[i]
is equal to
\(p^{a_i}\).
padic_add :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_add rop op1 op2 ctx
Sets rop
to the sum of op1
and op2
.
padic_sub :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_sub rop op1 op2 ctx
Sets rop
to the difference of op1
and op2
.
padic_neg :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_neg rop op ctx
Sets rop
to the additive inverse of op
.
padic_mul :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_mul rop op1 op2 ctx
Sets rop
to the product of op1
and op2
.
padic_shift :: Ptr CPadic -> Ptr CPadic -> CLong -> Ptr CPadicCtx -> IO () Source #
padic_shift rop op v ctx
Sets rop
to the product of op
and \(p^v\).
padic_div :: Ptr CPadic -> Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_div rop op1 op2 ctx
Sets rop
to the quotient of op1
and op2
.
_padic_inv_precompute :: Ptr CPadicInv -> Ptr CFmpz -> CLong -> IO () Source #
_padic_inv_precompute S p N
Pre-computes some data and allocates temporary space for \(p\)-adic inversion using Hensel lifting.
_padic_inv_clear :: Ptr CPadicInv -> IO () Source #
_padic_inv_clear S
Frees the memory used by \(S\).
_padic_inv_precomp :: Ptr CFmpz -> Ptr CFmpz -> Ptr CPadicInv -> IO () Source #
_padic_inv_precomp rop op S
Sets rop
to the inverse of op
modulo \(p^N\), assuming that 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
_padic_inv_precompute
. Note that this object is not declared 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 padic_log
.
_padic_inv :: Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> CLong -> IO () Source #
_padic_inv rop op p N
Sets rop
to the inverse of op
modulo \(p^N\), assuming that op
is
a unit and \(N \geq 1\).
In the current implementation, allows aliasing, but this might change in future versions.
padic_inv :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_inv rop op ctx
Computes the inverse of op
modulo \(p^N\).
Suppose that op
is given as \(x = u p^v\). Raises an 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\).
padic_sqrt :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_sqrt rop op ctx
Returns whether op
is a \(p\)-adic square. If this is the case, sets
rop
to one of the square roots; otherwise, the value of 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\).
padic_pow_si :: Ptr CPadic -> Ptr CPadic -> CLong -> Ptr CPadicCtx -> IO () Source #
padic_pow_si rop op e ctx
Sets rop
to op
raised to the power \(e\), which is defined as one
whenever \(e = 0\).
Assumes that some computations involving \(e\) and the valuation of op
do not overflow in the 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
_padic_exp_bound :: CLong -> CLong -> Ptr CFmpz -> IO CLong Source #
_padic_exp_bound v N p
Returns an integer \(i\) such that for all \(j \geq i\) we have \(\operatorname{ord}_p(x^j / j!) \geq N\), where \(\operatorname{ord}_p(x) = v\).
When \(p\) is a word-sized prime, returns \(\left\lceil \frac{(p-1)N - 1}{(p-1)v - 1}\right\rceil\). Otherwise, returns \(\lceil N/v\rceil\).
Assumes that \(v < N\). Moreover, \(v\) has to be at least \(2\) or \(1\), depending on whether \(p\) is \(2\) or odd.
_padic_exp_rectangular :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> CLong -> IO () Source #
_padic_exp_rectangular rop u v p N
Sets rop
to the \(p\)-exponential function evaluated at \(x = p^v u\),
reduced modulo \(p^N\).
Assumes that \(x \neq 0\), that \(\operatorname{ord}_p(x) < N\) and that \(\exp(x)\) converges, that is, that \(\operatorname{ord}_p(x)\) is at least \(2\) or \(1\) depending on whether the prime \(p\) is \(2\) or odd.
Supports aliasing between rop
and \(u\).
padic_exp :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_exp y x 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
\[`\] \[\exp_p(x) = \sum_{i = 0}^{\infty} \frac{x^i}{i!}\]
but this only converges only when \(\operatorname{ord}_p(x) > 1 / (p - 1)\). For elements \(x \in \mathbf{Q}_p\), this means that \(\operatorname{ord}_p(x) \geq 1\) when \(p \geq 3\) and \(\operatorname{ord}_2(x) \geq 2\) when \(p = 2\).
padic_exp_rectangular :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_exp_rectangular y x 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}\).
padic_exp_balanced :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_exp_balanced y x 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
_padic_log_bound :: CLong -> CLong -> Ptr CFmpz -> IO CLong Source #
_padic_log_bound v N p
Returns \(b\) such that for all \(i \geq b\) we have
\[`\] \[i v - \operatorname{ord}_p(i) \geq N\]
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
FLINT_BITS
.
_padic_log :: Ptr CFmpz -> Ptr CFmpz -> CLong -> Ptr CFmpz -> CLong -> IO () Source #
_padic_log z y v p N
Computes
\[`\] \[z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N},\]
reduced modulo \(p^N\).
Note that this can be used to compute the \(p\)-adic logarithm via the equation
\[`\] \[\begin{aligned} \log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\ & = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}. \end{aligned}\]
Assumes that \(y = 1 - x\) is non-zero and that \(v = \operatorname{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\).
padic_log :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_log rop op ctx
Returns whether the \(p\)-adic logarithm function converges at the
\(p\)-adic number op
, and if so sets rop
to its value.
The \(p\)-adic logarithm function is defined by the usual series
\[`\] \[\log_p(x) = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i}\]
but this only converges when \(\operatorname{ord}_p(x - 1)\) is at least \(2\) or \(1\) when \(p = 2\) or \(p > 2\), respectively.
padic_log_rectangular :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_log_rectangular rop op ctx
Returns whether the \(p\)-adic logarithm function converges at the
\(p\)-adic number op
, and if so sets rop
to its value.
Uses a rectangular splitting algorithm to evaluate the series expression of \(\log(x) \bmod{p^N}\).
padic_log_satoh :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_log_satoh rop op ctx
Returns whether the \(p\)-adic logarithm function converges at the
\(p\)-adic number op
, and if so sets rop
to its value.
Uses an algorithm based on a result of Satoh, Skjernaa and Taguchi that \(\operatorname{ord}_p\bigl(a^{p^k} - 1\bigr) > k\), which implies that
\[`\] \[\log(a) \equiv p^{-k} \Bigl( \log\bigl(a^{p^k}\bigr) \pmod{p^{N+k}} \Bigr) \pmod{p^N}.\]
padic_log_balanced :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO CInt Source #
padic_log_balanced rop op ctx
Returns whether the \(p\)-adic logarithm function converges at the
\(p\)-adic number op
, and if so sets rop
to its value.
Special functions
_padic_teichmuller :: Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> CLong -> IO () Source #
_padic_teichmuller rop op p N
Computes the Teichm"uller lift of the \(p\)-adic unit op
, assuming
that \(N \geq 1\).
Supports aliasing between rop
and op
.
padic_teichmuller :: Ptr CPadic -> Ptr CPadic -> Ptr CPadicCtx -> IO () Source #
padic_teichmuller rop op ctx
Computes the Teichm"uller lift of the \(p\)-adic unit op
.
If op
is a \(p\)-adic integer divisible by \(p\), sets rop
to zero,
which satisfies \(t^p - t = 0\), although it is clearly not a
\((p-1)\)-st root of unity.
If op
has negative valuation, raises an abort
signal.
padic_val_fac_ui_2 :: CULong -> IO CULong Source #
padic_val_fac_ui_2 n
Computes the \(2\)-adic valuation of \(n!\).
Note that since \(n\) fits into an ulong
, so does
\(\operatorname{ord}_2(n!)\) since
\(\operatorname{ord}_2(n!) \leq (n - 1) / (p - 1) = n - 1\).
padic_val_fac_ui :: CULong -> Ptr CFmpz -> IO CULong Source #
padic_val_fac_ui n p
Computes the \(p\)-adic valuation of \(n!\).
Note that since \(n\) fits into an ulong
, so does
\(\operatorname{ord}_p(n!)\) since
\(\operatorname{ord}_p(n!) \leq (n - 1) / (p - 1)\).
padic_val_fac :: Ptr CFmpz -> Ptr CFmpz -> Ptr CFmpz -> IO () Source #
padic_val_fac rop op p
Sets rop
to the \(p\)-adic valuation of the factorial of op
,
assuming that op
is non-negative.
Input and output
padic_get_str :: CString -> Ptr CPadic -> Ptr CPadicCtx -> IO CString Source #
padic_get_str str op ctx
Returns the string representation of the \(p\)-adic number op
according to the printing mode set in the context.
If str
is NULL
then a new block of memory is allocated and a pointer
to this is returned. Otherwise, it is assumed that the string str
is
large enough to hold the representation and it is also the return value.
_padic_fprint :: Ptr CFile -> Ptr CFmpz -> CLong -> Ptr CPadicCtx -> IO CInt Source #
_padic_fprint file u v ctx
Prints the string representation of the \(p\)-adic number op
to the
stream file
.
In the current implementation, always returns \(1\).
_padic_print :: Ptr CFmpz -> CLong -> Ptr CPadicCtx -> IO CInt Source #
_padic_print u v ctx
Prints the string representation of the \(p\)-adic number op
to the
stream stdout
.
In the current implementation, always returns \(1\).