663 lines
24 KiB
Plaintext
663 lines
24 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
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Module documentation
|
||
|
|
||
|
We represent a polynomial in $\mathbf{Q}_p[x]$ as a
|
||
|
product $p^v f(x)$, where $p$ is a prime number,
|
||
|
$v \in \mathbf{Z}$ and $f(x) \in \mathbf{Z}[x]$.
|
||
|
|
||
|
As a data structure, we call this polynomial \emph{normalised}
|
||
|
if the polynomial $f(x)$ is \emph{normalised}, that is, if the top
|
||
|
coefficient is non-zero.
|
||
|
|
||
|
We say this polynomial is in \emph{canonical form} if one of the
|
||
|
coefficients of $f(x)$ is a $p$-adic unit. If $f(x)$ is the zero
|
||
|
polynomial, we require that $v = 0$.
|
||
|
|
||
|
We say this polynomial is \emph{reduced} modulo $p^N$ if it is
|
||
|
canonical form and if all coefficients lie in the range $[0, p^N)$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Memory management
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_poly_init(padic_poly_t poly)
|
||
|
|
||
|
Initialises \code{poly} for use, setting its length to zero.
|
||
|
The precision of the polynomial is set to \code{PADIC_DEFAULT_PREC}.
|
||
|
A corresponding call to \code{padic_poly_clear()} must be made
|
||
|
after finishing with the \code{padic_poly_t} to free the memory
|
||
|
used by the polynomial.
|
||
|
|
||
|
void padic_poly_init2(padic_poly_t poly, slong alloc, slong prec)
|
||
|
|
||
|
Initialises \code{poly} with space for at least \code{alloc} coefficients
|
||
|
and sets the length to zero. The allocated coefficients are all set to
|
||
|
zero. The precision is set to \code{prec}.
|
||
|
|
||
|
void padic_poly_realloc(padic_poly_t poly, slong alloc, const fmpz_t p)
|
||
|
|
||
|
Reallocates the given polynomial to have space for \code{alloc}
|
||
|
coefficients. If \code{alloc} is zero the polynomial is cleared
|
||
|
and then reinitialised. If the current length is greater than
|
||
|
\code{alloc} the polynomial is first truncated to length \code{alloc}.
|
||
|
|
||
|
void padic_poly_fit_length(padic_poly_t poly, slong len)
|
||
|
|
||
|
If \code{len} is greater than the number of coefficients currently
|
||
|
allocated, then the polynomial is reallocated to have space for at
|
||
|
least \code{len} coefficients. No data is lost when calling this
|
||
|
function.
|
||
|
|
||
|
The function efficiently deals with the case where \code{fit_length} is
|
||
|
called many times in small increments by at least doubling the number
|
||
|
of allocated coefficients when length is larger than the number of
|
||
|
coefficients currently allocated.
|
||
|
|
||
|
void _padic_poly_set_length(padic_poly_t poly, slong len)
|
||
|
|
||
|
Demotes the coefficients of \code{poly} beyond \code{len} and sets
|
||
|
the length of \code{poly} to \code{len}.
|
||
|
|
||
|
Note that if the current length is greater than \code{len} the
|
||
|
polynomial may no slonger be in canonical form.
|
||
|
|
||
|
void padic_poly_clear(padic_poly_t poly)
|
||
|
|
||
|
Clears the given polynomial, releasing any memory used. It must
|
||
|
be reinitialised in order to be used again.
|
||
|
|
||
|
void _padic_poly_normalise(padic_poly_t poly)
|
||
|
|
||
|
Sets the length of \code{poly} so that the top coefficient is non-zero.
|
||
|
If all coefficients are zero, the length is set to zero. This function
|
||
|
is mainly used internally, as all functions guarantee normalisation.
|
||
|
|
||
|
void _padic_poly_canonicalise(fmpz *poly, slong *v, slong len, const fmpz_t p)
|
||
|
|
||
|
void padic_poly_canonicalise(padic_poly_t poly, const fmpz_t p)
|
||
|
|
||
|
Brings the polynomial \code{poly} into canonical form,
|
||
|
assuming that it is normalised already. Does \emph{not}
|
||
|
carry out any reduction.
|
||
|
|
||
|
void padic_poly_reduce(padic_poly_t poly, const padic_ctx_t ctx)
|
||
|
|
||
|
Reduces the polynomial \code{poly} modulo $p^N$, assuming
|
||
|
that it is in canonical form already.
|
||
|
|
||
|
void padic_poly_truncate(padic_poly_t poly, slong n, const fmpz_t p)
|
||
|
|
||
|
Truncates the polynomial to length at most~$n$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Polynomial parameters
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
slong padic_poly_degree(padic_poly_t poly)
|
||
|
|
||
|
Returns the degree of the polynomial \code{poly}.
|
||
|
|
||
|
slong padic_poly_length(padic_poly_t poly)
|
||
|
|
||
|
Returns the length of the polynomial \code{poly}.
|
||
|
|
||
|
slong padic_poly_val(padic_poly_t poly)
|
||
|
|
||
|
Returns the valuation of the polynomial \code{poly},
|
||
|
which is defined to be the minimum valuation of all
|
||
|
its coefficients.
|
||
|
|
||
|
The valuation of the zero polynomial is~$0$.
|
||
|
|
||
|
Note that this is implemented as a macro and can be
|
||
|
used as either a \code{lvalue} or a \code{rvalue}.
|
||
|
|
||
|
slong padic_poly_prec(padic_poly_t poly)
|
||
|
|
||
|
Returns the precision of the polynomial \code{poly}.
|
||
|
|
||
|
Note that this is implemented as a macro and can be
|
||
|
used as either a \code{lvalue} or a \code{rvalue}.
|
||
|
|
||
|
Note that increasing the precision might require
|
||
|
a call to \code{padic_poly_reduce()}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Randomisation
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_poly_randtest(padic_poly_t f, flint_rand_t state,
|
||
|
slong len, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets $f$ to a random polynomial of length at most \code{len}
|
||
|
with entries reduced modulo $p^N$.
|
||
|
|
||
|
void padic_poly_randtest_not_zero(padic_poly_t f, flint_rand_t state,
|
||
|
slong len, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets $f$ to a non-zero random polynomial of length at most \code{len}
|
||
|
with entries reduced modulo $p^N$.
|
||
|
|
||
|
void padic_poly_randtest_val(padic_poly_t f, flint_rand_t state,
|
||
|
slong val, slong len, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets $f$ to a random polynomial of length at most \code{len}
|
||
|
with at most the prescribed valuation \code{val} and entries
|
||
|
reduced modulo $p^N$.
|
||
|
|
||
|
Specifically, we aim to set the valuation to be exactly equal
|
||
|
to \code{val}, but do not check for additional cancellation
|
||
|
when creating the coefficients.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Assignment and basic manipulation
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_poly_set_padic(padic_poly_t poly, const padic_t x,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{poly} to the $p$-adic number $x$,
|
||
|
reduced to the precision of the polynomial.
|
||
|
|
||
|
void padic_poly_set(padic_poly_t poly1, const padic_poly_t poly2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{poly1} to the polynomial \code{poly2},
|
||
|
reduced to the precision of \code{poly1}.
|
||
|
|
||
|
void padic_poly_set_si(padic_poly_t poly, slong x, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{poly} to the \code{signed slong}
|
||
|
integer $x$ reduced to the precision of the polynomial.
|
||
|
|
||
|
void padic_poly_set_ui(padic_poly_t poly, ulong x, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{poly} to the \code{unsigned slong}
|
||
|
integer $x$ reduced to the precision of the polynomial.
|
||
|
|
||
|
void padic_poly_set_fmpz(padic_poly_t poly, const fmpz_t x,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{poly} to the integer $x$
|
||
|
reduced to the precision of the polynomial.
|
||
|
|
||
|
void padic_poly_set_fmpq(padic_poly_t poly, const fmpq_t x,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{poly} to the value of the rational $x$,
|
||
|
reduced to the precision of the polynomial.
|
||
|
|
||
|
void padic_poly_set_fmpz_poly(padic_poly_t rop, const fmpz_poly_t op,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{rop} to the integer polynomial \code{op}
|
||
|
reduced to the precision of the polynomial.
|
||
|
|
||
|
void padic_poly_set_fmpq_poly(padic_poly_t rop,
|
||
|
const fmpq_poly_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{rop} to the value of the rational
|
||
|
polynomial \code{op}, reduced to the precision of the polynomial.
|
||
|
|
||
|
int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the integer polynomial \code{rop} to the value of the $p$-adic
|
||
|
polynomial \code{op} and returns $1$ if the polynomial is $p$-adically
|
||
|
integral. Otherwise, returns $0$.
|
||
|
|
||
|
void padic_poly_get_fmpq_poly(fmpq_poly_t rop,
|
||
|
const padic_poly_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the rational polynomial corresponding to
|
||
|
the $p$-adic polynomial \code{op}.
|
||
|
|
||
|
void padic_poly_zero(padic_poly_t poly)
|
||
|
|
||
|
Sets \code{poly} to the zero polynomial.
|
||
|
|
||
|
void padic_poly_one(padic_poly_t poly)
|
||
|
|
||
|
Sets \code{poly} to the constant polynomial $1$,
|
||
|
reduced to the precision of the polynomial.
|
||
|
|
||
|
void padic_poly_swap(padic_poly_t poly1, padic_poly_t poly2)
|
||
|
|
||
|
Swaps the two polynomials \code{poly1} and \code{poly2},
|
||
|
including their precisions.
|
||
|
|
||
|
This is done efficiently by swapping pointers.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Getting and setting coefficients
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_poly_get_coeff_padic(padic_t c, const padic_poly_t poly, slong n,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets $c$ to the coefficient of $x^n$ in the polynomial,
|
||
|
reduced modulo the precision of $c$.
|
||
|
|
||
|
void padic_poly_set_coeff_padic(padic_poly_t f, slong n, const padic_t c,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the coefficient of $x^n$ in the polynomial $f$ to $c$,
|
||
|
reduced to the precision of the polynomial $f$.
|
||
|
|
||
|
Note that this operation can take linear time in the length
|
||
|
of the polynomial.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Comparison
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
int padic_poly_equal(const padic_poly_t poly1, const padic_poly_t poly2)
|
||
|
|
||
|
Returns whether the two polynomials \code{poly1} and \code{poly2}
|
||
|
are equal.
|
||
|
|
||
|
int padic_poly_is_zero(const padic_poly_t poly)
|
||
|
|
||
|
Returns whether the polynomial \code{poly} is the zero polynomial.
|
||
|
|
||
|
int padic_poly_is_one(const padic_poly_t poly, const padic_ctx_t ctx)
|
||
|
|
||
|
Returns whether the polynomial \code{poly} is equal
|
||
|
to the constant polynomial~$1$, taking the precision
|
||
|
of the polynomial into account.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Addition and subtraction
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_poly_add(fmpz *rop, slong *rval, slong N,
|
||
|
const fmpz *op1, slong val1, slong len1, slong N1,
|
||
|
const fmpz *op2, slong val2, slong len2, slong N2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{(rop, *val, FLINT_MAX(len1, len2)} to the sum of
|
||
|
\code{(op1, val1, len1)} and \code{(op2, val2, len2)}.
|
||
|
|
||
|
Assumes that the input is reduced and guarantees that this is
|
||
|
also the case for the output.
|
||
|
|
||
|
Assumes that $\min\{v_1, v_2\} < N$.
|
||
|
|
||
|
Supports aliasing between the output and input arguments.
|
||
|
|
||
|
void padic_poly_add(padic_poly_t f,
|
||
|
const padic_poly_t g, const padic_poly_t h,
|
||
|
const padic_ctx_t ctx);
|
||
|
|
||
|
Sets $f$ to the sum $g + h$.
|
||
|
|
||
|
void _padic_poly_sub(fmpz *rop, slong *rval,
|
||
|
const fmpz *op1, slong val1, slong len1,
|
||
|
const fmpz *op2, slong val2, slong len2,
|
||
|
const padic_ctx_t ctx);
|
||
|
|
||
|
Sets \code{(rop, *val, FLINT_MAX(len1, len2)} to the difference of
|
||
|
\code{(op1, val1, len1)} and \code{(op2, val2, len2)}.
|
||
|
|
||
|
Assumes that the input is reduced and guarantees that this is
|
||
|
also the case for the output.
|
||
|
|
||
|
Assumes that $\min\{v_1, v_2\} < N$.
|
||
|
|
||
|
Support aliasing between the output and input arguments.
|
||
|
|
||
|
void padic_poly_sub(padic_poly_t f,
|
||
|
const padic_poly_t g, const padic_poly_t h,
|
||
|
const padic_ctx_t ctx);
|
||
|
|
||
|
Sets $f$ to the difference $g - h$.
|
||
|
|
||
|
void padic_poly_neg(padic_poly_t f, const padic_poly_t g,
|
||
|
const padic_ctx_t ctx);
|
||
|
|
||
|
Sets $f$ to $-g$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Scalar multiplication
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_poly_scalar_mul_padic(fmpz *rop, slong *rval,
|
||
|
const fmpz *op, slong val, slong len,
|
||
|
const padic_t c, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{(rop, *rval, len)} to \code{(op, val, len)} multiplied
|
||
|
by the scalar $c$.
|
||
|
|
||
|
The result will only be correctly reduced if the polynomial
|
||
|
is non-zero. Otherwise, the array \code{(rop, len)} will be
|
||
|
set to zero but the valuation \code{*rval} might be wrong.
|
||
|
|
||
|
void padic_poly_scalar_mul_padic(padic_poly_t rop, const padic_poly_t op,
|
||
|
const padic_t c, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{rop} to the product of the
|
||
|
polynomial \code{op} and the $p$-adic number $c$,
|
||
|
reducing the result modulo $p^N$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Multiplication
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_poly_mul(fmpz *rop, slong *rval, slong N,
|
||
|
const fmpz *op1, slong val1, slong len1,
|
||
|
const fmpz *op2, slong val2, slong len2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{(rop, *rval, len1 + len2 - 1)} to the product of
|
||
|
\code{(op1, val1, len1)} and \code{(op2, val2, len2)}.
|
||
|
|
||
|
Assumes that the resulting valuation \code{*rval}, which is
|
||
|
the sum of the valuations \code{val1} and \code{val2}, is less
|
||
|
than the precision~$N$ of the context.
|
||
|
|
||
|
Assumes that \code{len1 >= len2 > 0}.
|
||
|
|
||
|
void padic_poly_mul(padic_poly_t res,
|
||
|
const padic_poly_t poly1, const padic_poly_t poly2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{res} to the product of the two polynomials
|
||
|
\code{poly1} and \code{poly2}, reduced modulo $p^N$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Powering
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_poly_pow(fmpz *rop, slong *rval, slong N,
|
||
|
const fmpz *op, slong val, slong len, ulong e,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{(rop, *rval, e (len - 1) + 1)} to the
|
||
|
polynomial \code{(op, val, len)} raised to the power~$e$.
|
||
|
|
||
|
Assumes that $e > 1$ and \code{len > 0}.
|
||
|
|
||
|
Does not support aliasing between the input and output arguments.
|
||
|
|
||
|
void padic_poly_pow(padic_poly_t rop, const padic_poly_t op, ulong e,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the polynomial \code{rop} to the polynomial \code{op} raised
|
||
|
to the power~$e$, reduced to the precision in \code{rop}.
|
||
|
|
||
|
In the special case $e = 0$, sets \code{rop} to the constant
|
||
|
polynomial one reduced to the precision of \code{rop}.
|
||
|
Also note that when $e = 1$, this operation sets \code{rop} to
|
||
|
\code{op} and then reduces \code{rop}.
|
||
|
|
||
|
When the valuation of the input polynomial is negative,
|
||
|
this results in a loss of $p$-adic precision. Suppose
|
||
|
that the input polynomial is given to precision~$N$ and
|
||
|
has valuation~$v < 0$. The result then has valuation
|
||
|
$e v < 0$ but is only correct to precision $N + (e - 1) v$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Series inversion
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_poly_inv_series(padic_poly_t g, const padic_poly_t f, slong n,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Computes the power series inverse $g$ of $f$ modulo $X^n$,
|
||
|
where $n \geq 1$.
|
||
|
|
||
|
Given the polynomial $f \in \mathbf{Q}[X] \subset \mathbf{Q}_p[X]$,
|
||
|
there exists a unique polynomial $f^{-1} \in \mathbf{Q}[X]$ such that
|
||
|
$f f^{-1} = 1$ modulo $X^n$. This function sets $g$ to $f^{-1}$
|
||
|
reduced modulo $p^N$.
|
||
|
|
||
|
Assumes that the constant coefficient of $f$ is non-zero.
|
||
|
|
||
|
Moreover, assumes that the valuation of the constant coefficient
|
||
|
of $f$ is minimal among the coefficients of $f$.
|
||
|
|
||
|
Note that the result $g$ is zero if and only if $- \ord_p(f) \geq N$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Derivative
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_poly_derivative(fmpz *rop, slong *rval, slong N,
|
||
|
const fmpz *op, slong val, slong len,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{(rop, rval)} to the derivative of \code{(op, val)} reduced
|
||
|
modulo $p^N$.
|
||
|
|
||
|
Supports aliasing of the input and the output parameters.
|
||
|
|
||
|
void padic_poly_derivative(padic_poly_t rop,
|
||
|
const padic_poly_t op, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the derivative of \code{op}, reducing the
|
||
|
result modulo the precision of \code{rop}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Shifting
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void padic_poly_shift_left(padic_poly_t rop, const padic_poly_t op, slong n,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Notationally, sets the polynomial \code{rop} to the polynomial \code{op}
|
||
|
multiplied by $x^n$, where $n \geq 0$, and reduces the result.
|
||
|
|
||
|
void padic_poly_shift_right(padic_poly_t rop, const padic_poly_t op, slong n)
|
||
|
|
||
|
Notationally, sets the polynomial \code{rop} to the polynomial
|
||
|
\code{op} after floor division by $x^n$, where $n \geq 0$, ensuring
|
||
|
the result is reduced.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Evaluation
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_poly_evaluate_padic(fmpz_t u, slong *v, slong N,
|
||
|
const fmpz *poly, slong val, slong len,
|
||
|
const fmpz_t a, slong b, const padic_ctx_t ctx)
|
||
|
|
||
|
void padic_poly_evaluate_padic(padic_t y, const padic_poly_t poly,
|
||
|
const padic_t a, const padic_ctx_t ctx)
|
||
|
|
||
|
Sets the $p$-adic number \code{y} to \code{poly} evaluated at $a$,
|
||
|
reduced in the given context.
|
||
|
|
||
|
Suppose that the polynomial can be written as $F(X) = p^w f(X)$
|
||
|
with $\ord_p(f) = 1$, that $\ord_p(a) = b$ and that both are
|
||
|
defined to precision~$N$. Then $f$ is defined to precision
|
||
|
$N-w$ and so $f(a)$ is defined to precision $N-w$ when $a$ is
|
||
|
integral and $N-w+(n-1)b$ when $b < 0$, where $n = \deg(f)$. Thus,
|
||
|
$y = F(a)$ is defined to precision $N$ when $a$ is integral and
|
||
|
$N+(n-1)b$ when $b < 0$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Composition
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _padic_poly_compose(fmpz *rop, slong *rval, slong N,
|
||
|
const fmpz *op1, slong val1, slong len1,
|
||
|
const fmpz *op2, slong val2, slong len2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{(rop, *rval, (len1-1)*(len2-1)+1)} to the composition
|
||
|
of the two input polynomials, reducing the result modulo $p^N$.
|
||
|
|
||
|
Assumes that \code{len1} is non-zero.
|
||
|
|
||
|
Does not support aliasing.
|
||
|
|
||
|
void padic_poly_compose(padic_poly_t rop,
|
||
|
const padic_poly_t op1, const padic_poly_t op2,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the composition of \code{op1} and \code{op2},
|
||
|
reducing the result in the given context.
|
||
|
|
||
|
To be clear about the order of composition, let $f(X)$ and $g(X)$
|
||
|
denote the polynomials \code{op1} and \code{op2}, respectively.
|
||
|
Then \code{rop} is set to $f(g(X))$.
|
||
|
|
||
|
void _padic_poly_compose_pow(fmpz *rop, slong *rval, slong N,
|
||
|
const fmpz *op, slong val, slong len, slong k,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{(rop, *rval, (len - 1)*k + 1)} to the composition of
|
||
|
\code{(op, val, len)} and the monomial $x^k$, where $k \geq 1$.
|
||
|
|
||
|
Assumes that \code{len} is positive.
|
||
|
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void padic_poly_compose_pow(padic_poly_t rop, const padic_poly_t op, slong k,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Sets \code{rop} to the composition of \code{op} and the monomial $x^k$,
|
||
|
where $k \geq 1$.
|
||
|
|
||
|
Note that no reduction takes place.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Input and output
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
int padic_poly_debug(const padic_poly_t poly)
|
||
|
|
||
|
Prints the data defining the $p$-adic polynomial \code{poly}
|
||
|
in a simple format useful for debugging purposes.
|
||
|
|
||
|
In the current implementation, always returns $1$.
|
||
|
|
||
|
int _padic_poly_fprint(FILE *file, const fmpz *poly, slong val, slong len,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
int padic_poly_fprint(FILE *file, const padic_poly_t poly,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
Prints a simple representation of the polynomial \code{poly}
|
||
|
to the stream \code{file}.
|
||
|
|
||
|
A non-zero polynomial is represented by the number of coeffients,
|
||
|
two spaces, followed by a list of the coefficients, which are printed
|
||
|
in a way depending on the print mode,
|
||
|
\begin{itemize}
|
||
|
\item In the \code{PADIC_TERSE} mode, the coefficients are printed as
|
||
|
rational numbers.
|
||
|
\item The \code{PADIC_SERIES} mode is currently not supported and will
|
||
|
raise an abort signal.
|
||
|
\item In the \code{PADIC_VAL_UNIT} mode, the coefficients are printed
|
||
|
in the form $p^v u$.
|
||
|
\end{itemize}
|
||
|
|
||
|
The zero polynomial is represented by \code{"0"}.
|
||
|
|
||
|
In the current implementation, always returns $1$.
|
||
|
|
||
|
int _padic_poly_print(const fmpz *poly, slong val, slong len,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
int padic_poly_print(const padic_poly_t poly, const padic_ctx_t ctx)
|
||
|
|
||
|
Prints a simple representation of the polynomial \code{poly}
|
||
|
to \code{stdout}.
|
||
|
|
||
|
In the current implementation, always returns $1$.
|
||
|
|
||
|
int _padic_poly_fprint_pretty(FILE *file,
|
||
|
const fmpz *poly, slong val, slong len,
|
||
|
const char *var,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
int padic_poly_fprint_pretty(FILE *file,
|
||
|
const padic_poly_t poly, const char *var,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
int _padic_poly_print_pretty(FILE *file,
|
||
|
const fmpz *poly, slong val, slong len,
|
||
|
const char *var,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
int padic_poly_print_pretty(const padic_poly_t poly, const char *var,
|
||
|
const padic_ctx_t ctx)
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Testing
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
int _padic_poly_is_canonical(const fmpz *op, slong val, slong len,
|
||
|
const padic_ctx_t ctx);
|
||
|
|
||
|
int padic_poly_is_canonical(const padic_poly_t op, const padic_ctx_t ctx);
|
||
|
|
||
|
int _padic_poly_is_reduced(const fmpz *op, slong val, slong len, slong N,
|
||
|
const padic_ctx_t ctx);
|
||
|
|
||
|
int padic_poly_is_reduced(const padic_poly_t op, const padic_ctx_t ctx);
|
||
|
|