1658 lines
66 KiB
Plaintext
1658 lines
66 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) 2010 Sebastian Pancratz
|
||
|
Copyright (C) 2010 William Hart
|
||
|
Copyright (C) 2011 Fredrik Johansson
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Memory management
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void fmpq_poly_init(fmpq_poly_t poly)
|
||
|
|
||
|
Initialises the polynomial for use. The length is set to zero.
|
||
|
|
||
|
void fmpq_poly_init2(fmpq_poly_t poly, slong alloc)
|
||
|
|
||
|
Initialises the polynomial with space for at least \code{alloc}
|
||
|
coefficients and set the length to zero. The \code{alloc} coefficients
|
||
|
are all set to zero.
|
||
|
|
||
|
void fmpq_poly_realloc(fmpq_poly_t poly, slong alloc)
|
||
|
|
||
|
Reallocates the given polynomial to have space for \code{alloc}
|
||
|
coefficients. If \code{alloc} is zero then the polynomial is cleared
|
||
|
and then reinitialised. If the current length is greater than
|
||
|
\code{alloc} then \code{poly} is first truncated to length
|
||
|
\code{alloc}. Note that this might leave the rational polynomial in
|
||
|
non-canonical form.
|
||
|
|
||
|
void fmpq_poly_fit_length(fmpq_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 \code{len}
|
||
|
is larger than the number of coefficients currently allocated.
|
||
|
|
||
|
void _fmpq_poly_set_length(fmpq_poly_t poly, slong len)
|
||
|
|
||
|
Sets the length of the numerator polynomial to \code{len}, demoting
|
||
|
coefficients beyond the new length. Note that this method does
|
||
|
not guarantee that the rational polynomial is in canonical form.
|
||
|
|
||
|
void fmpq_poly_clear(fmpq_poly_t poly)
|
||
|
|
||
|
Clears the given polynomial, releasing any memory used. The polynomial
|
||
|
must be reinitialised in order to be used again.
|
||
|
|
||
|
void _fmpq_poly_normalise(fmpq_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.
|
||
|
Note that this function does not guarantee the coprimality of the
|
||
|
numerator polynomial and the integer denominator.
|
||
|
|
||
|
void _fmpq_poly_canonicalise(fmpz * poly, fmpz_t den, slong len)
|
||
|
|
||
|
Puts \code{(poly, den)} of length \code{len} into canonical form.
|
||
|
|
||
|
It is assumed that the array \code{poly} contains a non-zero entry in
|
||
|
position \code{len - 1} whenever \code{len > 0}. Assumes that \code{den}
|
||
|
is non-zero.
|
||
|
|
||
|
void fmpq_poly_canonicalise(fmpq_poly_t poly)
|
||
|
|
||
|
Puts the polynomial \code{poly} into canonical form. Firstly, the length
|
||
|
is set to the actual length of the numerator polynomial. For non-zero
|
||
|
polynomials, it is then ensured that the numerator and denominator are
|
||
|
coprime and that the denominator is positive. The canonical form of the
|
||
|
zero polynomial is a zero numerator polynomial and a one denominator.
|
||
|
|
||
|
int _fmpq_poly_is_canonical(const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Returns whether the polynomial is in canonical form.
|
||
|
|
||
|
int fmpq_poly_is_canonical(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns whether the polynomial is in canonical form.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Polynomial parameters
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
slong fmpq_poly_degree(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns the degree of \code{poly}, which is one less than its length, as
|
||
|
a \code{slong}.
|
||
|
|
||
|
slong fmpq_poly_length(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns the length of \code{poly}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Accessing the numerator and denominator
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
fmpz * fmpq_poly_numref(fmpq_poly_t poly)
|
||
|
|
||
|
Returns a reference to the numerator polynomial as an array.
|
||
|
|
||
|
Note that, because of a delayed initialisation approach, this might
|
||
|
be \code{NULL} for zero polynomials. This situation can be salvaged
|
||
|
by calling either \code{fmpq_poly_fit_length()} or
|
||
|
\code{fmpq_poly_realloc()}.
|
||
|
|
||
|
This function is implemented as a macro returning \code{(poly)->coeffs}.
|
||
|
|
||
|
fmpz_t fmpq_poly_denref(fmpq_poly_t poly)
|
||
|
|
||
|
Returns a reference to the denominator as a \code{fmpz_t}. The integer
|
||
|
is guaranteed to be properly initialised.
|
||
|
|
||
|
This function is implemented as a macro returning \code{(poly)->den}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Random testing
|
||
|
|
||
|
The functions \code{fmpq_poly_randtest_foo()} provide random
|
||
|
polynomials suitable for testing. On an integer level, this
|
||
|
means that long strings of zeros and ones in the binary
|
||
|
representation are favoured as well as the special absolute
|
||
|
values $0$, $1$, \code{COEFF_MAX}, and \code{WORD_MAX}. On a
|
||
|
polynomial level, the integer numerator has a reasonable chance
|
||
|
to have a non-trivial content.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void fmpq_poly_randtest(fmpq_poly_t f, flint_rand_t state,
|
||
|
slong len, mp_bitcnt_t bits)
|
||
|
|
||
|
Sets $f$ to a random polynomial with coefficients up to the given
|
||
|
length and where each coefficient has up to the given number of bits.
|
||
|
The coefficients are signed randomly. One must call
|
||
|
\code{flint_randinit()} before calling this function.
|
||
|
|
||
|
void fmpq_poly_randtest_unsigned(fmpq_poly_t f, flint_rand_t state,
|
||
|
slong len, mp_bitcnt_t bits)
|
||
|
|
||
|
Sets $f$ to a random polynomial with coefficients up to the given length
|
||
|
and where each coefficient has up to the given number of bits. One must
|
||
|
call \code{flint_randinit()} before calling this function.
|
||
|
|
||
|
void fmpq_poly_randtest_not_zero(fmpq_poly_t f, flint_rand_t state,
|
||
|
slong len, mp_bitcnt_t bits)
|
||
|
|
||
|
As for \code{fmpq_poly_randtest()} except that \code{len} and \code{bits}
|
||
|
may not be zero and the polynomial generated is guaranteed not to be the
|
||
|
zero polynomial. One must call \code{flint_randinit()} before calling
|
||
|
this function.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Assignment, swap, negation
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void fmpq_poly_set(fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Sets \code{poly1} to equal \code{poly2}.
|
||
|
|
||
|
void fmpq_poly_set_si(fmpq_poly_t poly, slong x)
|
||
|
|
||
|
Sets \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_ui(fmpq_poly_t poly, ulong x)
|
||
|
|
||
|
Sets \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_fmpz(fmpq_poly_t poly, const fmpz_t x)
|
||
|
|
||
|
Sets \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_fmpq(fmpq_poly_t poly, const fmpq_t x)
|
||
|
|
||
|
Sets \code{poly} to the rational $x$, which is assumed to be
|
||
|
given in lowest terms.
|
||
|
|
||
|
void fmpq_poly_set_mpz(fmpq_poly_t poly, const mpz_t x)
|
||
|
|
||
|
Sets \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_mpq(fmpq_poly_t poly, const mpq_t x)
|
||
|
|
||
|
Sets \code{poly} to the rational $x$, which is assumed to be
|
||
|
given in lowest terms.
|
||
|
|
||
|
void fmpq_poly_set_fmpz_poly(fmpq_poly_t rop, const fmpz_poly_t op)
|
||
|
|
||
|
Sets the rational polynomial \code{rop} to the same value
|
||
|
as the integer polynomial \code{op}.
|
||
|
|
||
|
void _fmpq_poly_set_array_mpq(fmpz * poly, fmpz_t den,
|
||
|
const mpq_t * a, slong n)
|
||
|
|
||
|
Sets \code{(poly, den)} to the polynomial given by the
|
||
|
first $n \geq 1$ coefficients in the array $a$, from lowest
|
||
|
degree to highest degree.
|
||
|
|
||
|
The result is only guaranteed to be in lowest terms if all
|
||
|
input coefficients are given in lowest terms.
|
||
|
|
||
|
void fmpq_poly_set_array_mpq(fmpq_poly_t poly, const mpq_t * a, slong n)
|
||
|
|
||
|
Sets \code{poly} to the polynomial with coefficients as given in the
|
||
|
array $a$ of length $n \geq 0$, from lowest degree to highest degree.
|
||
|
|
||
|
The result is only guaranteed to be in canonical form if all
|
||
|
input coefficients are given in lowest terms.
|
||
|
|
||
|
int _fmpq_poly_set_str(fmpz * poly, fmpz_t den, const char * str)
|
||
|
|
||
|
Sets \code{(poly, den)} to the polynomial specified by the null-terminated
|
||
|
string \code{str}.
|
||
|
|
||
|
The result is only guaranteed to be in lowest terms if all
|
||
|
coefficients in the input string are in lowest terms.
|
||
|
|
||
|
Returns $0$ if no error occurred. Otherwise, returns a non-zero value,
|
||
|
in which case the resulting value of \code{(poly, den)} is undefined.
|
||
|
If \code{str} is not null-terminated, calling this method might result
|
||
|
in a segmentation fault.
|
||
|
|
||
|
int fmpq_poly_set_str(fmpq_poly_t poly, const char * str)
|
||
|
|
||
|
Sets \code{poly} to the polynomial specified by the null-terminated
|
||
|
string \code{str}.
|
||
|
|
||
|
The result is only guaranteed to be in canonical for if all
|
||
|
coefficients in the input string are in lowest terms.
|
||
|
|
||
|
Returns $0$ if no error occurred. Otherwise, returns a non-zero
|
||
|
value, in which case the resulting value of \code{poly} is undefined.
|
||
|
If \code{str} is not null-terminated, calling this method might result
|
||
|
in a segmentation fault.
|
||
|
|
||
|
char * fmpq_poly_get_str(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns the string representation of \code{poly}.
|
||
|
|
||
|
char * fmpq_poly_get_str_pretty(const fmpq_poly_t poly, const char * var)
|
||
|
|
||
|
Returns the pretty representation of \code{poly}, using the
|
||
|
null-terminated string \code{var} not equal to \code{"\0"} as
|
||
|
the variable name.
|
||
|
|
||
|
void fmpq_poly_zero(fmpq_poly_t poly)
|
||
|
|
||
|
Sets \code{poly} to zero.
|
||
|
|
||
|
void fmpq_poly_one(fmpq_poly_t poly)
|
||
|
|
||
|
Sets \code{poly} to the constant polynomial $1$.
|
||
|
|
||
|
void fmpq_poly_neg(fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Sets \code{poly1} to the additive inverse of \code{poly2}.
|
||
|
|
||
|
void fmpq_poly_inv(fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Sets \code{poly1} to the multiplicative inverse of \code{poly2}
|
||
|
if possible. Otherwise, if \code{poly2} is not a unit, leaves
|
||
|
\code{poly1} unmodified and calls \code{abort()}.
|
||
|
|
||
|
void fmpq_poly_swap(fmpq_poly_t poly1, fmpq_poly_t poly2)
|
||
|
|
||
|
Efficiently swaps the polynomials \code{poly1} and \code{poly2}.
|
||
|
|
||
|
void fmpq_poly_truncate(fmpq_poly_t poly, slong n)
|
||
|
|
||
|
If the current length of \code{poly} is greater than $n$, it is
|
||
|
truncated to the given length. Discarded coefficients are demoted,
|
||
|
but they are not necessarily set to zero.
|
||
|
|
||
|
void fmpq_poly_get_slice(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, slong i, slong j)
|
||
|
|
||
|
Returns the slice with coefficients from $x^i$ (including) to
|
||
|
$x^j$ (excluding).
|
||
|
|
||
|
void fmpq_poly_reverse(fmpq_poly_t res, const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
This function considers the polynomial \code{poly} to be of length $n$,
|
||
|
notionally truncating and zero padding if required, and reverses
|
||
|
the result. Since the function normalises its result \code{res} may be
|
||
|
of length less than $n$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Getting and setting coefficients
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void fmpq_poly_get_coeff_fmpq(fmpq_t x, const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Retrieves the $n$th coefficient of \code{poly}, in lowest terms.
|
||
|
|
||
|
void fmpq_poly_get_coeff_mpq(mpq_t x, const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Retrieves the $n$th coefficient of \code{poly}, in lowest terms.
|
||
|
|
||
|
void fmpq_poly_set_coeff_si(fmpq_poly_t poly, slong n, slong x)
|
||
|
|
||
|
Sets the $n$th coefficient in \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_coeff_ui(fmpq_poly_t poly, slong n, ulong x)
|
||
|
|
||
|
Sets the $n$th coefficient in \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_coeff_fmpz(fmpq_poly_t poly, slong n, const fmpz_t x)
|
||
|
|
||
|
Sets the $n$th coefficient in \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_coeff_fmpq(fmpq_poly_t poly, slong n, const fmpq_t x)
|
||
|
|
||
|
Sets the $n$th coefficient in \code{poly} to the rational $x$.
|
||
|
|
||
|
void fmpq_poly_set_coeff_mpz(fmpq_poly_t rop, slong n, const mpz_t x)
|
||
|
|
||
|
Sets the $n$th coefficient in \code{poly} to the integer $x$.
|
||
|
|
||
|
void fmpq_poly_set_coeff_mpq(fmpq_poly_t rop, slong n, const mpq_t x)
|
||
|
|
||
|
Sets the $n$th coefficient in \code{poly} to the rational~$x$,
|
||
|
which is expected to be provided in lowest terms.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Comparison
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
int fmpq_poly_equal(const fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Returns $1$ if \code{poly1} is equal to \code{poly2},
|
||
|
otherwise returns~$0$.
|
||
|
|
||
|
int _fmpq_poly_cmp(const fmpz * lpoly, const fmpz_t lden,
|
||
|
const fmpz * rpoly, const fmpz_t rden, slong len)
|
||
|
|
||
|
Compares two non-zero polynomials, assuming they have the same length
|
||
|
\code{len > 0}.
|
||
|
|
||
|
The polynomials are expected to be provided in canonical form.
|
||
|
|
||
|
int fmpq_poly_cmp(const fmpq_poly_t left, const fmpq_poly_t right)
|
||
|
|
||
|
Compares the two polynomials \code{left} and \code{right}.
|
||
|
|
||
|
Compares the two polynomials \code{left} and \code{right}, returning
|
||
|
$-1$, $0$, or $1$ as \code{left} is less than, equal to, or greater
|
||
|
than \code{right}. The comparison is first done by the degree, and
|
||
|
then, in case of a tie, by the individual coefficients from highest
|
||
|
to lowest.
|
||
|
|
||
|
int fmpq_poly_is_one(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns $1$ if \code{poly} is the constant polynomial~$1$, otherwise
|
||
|
returns $0$.
|
||
|
|
||
|
int fmpq_poly_is_zero(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns $1$ if \code{poly} is the zero polynomial, otherwise returns $0$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Addition and subtraction
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_add(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz * poly2, const fmpz_t den2, slong len2)
|
||
|
|
||
|
Forms the sum \code{(rpoly, rden)} of \code{(poly1, den1, len1)} and
|
||
|
\code{(poly2, den2, len2)}, placing the result into canonical form.
|
||
|
|
||
|
Assumes that \code{rpoly} is an array of length the maximum of
|
||
|
\code{len1} and \code{len2}. The input operands are assumed to
|
||
|
be in canonical form and are also allowed to be of length~$0$.
|
||
|
|
||
|
\code{(rpoly, rden)} and \code{(poly1, den1)} may be aliased,
|
||
|
but \code{(rpoly, rden)} and \code{(poly2, den2)} may \emph{not}
|
||
|
be aliased.
|
||
|
|
||
|
void _fmpq_poly_add_can(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz * poly2, const fmpz_t den2, slong len2, int can)
|
||
|
|
||
|
As per \code{_fmpq_poly_add} except that one can specify whether to
|
||
|
canonicalise the output or not. This function is intended to be used with
|
||
|
weak canonicalisation to prevent explosion in memory usage. It exists for
|
||
|
performance reasons.
|
||
|
|
||
|
void fmpq_poly_add(fmpq_poly_t res, fmpq_poly poly1, fmpq_poly poly2)
|
||
|
|
||
|
Sets \code{res} to the sum of \code{poly1} and \code{poly2}, using
|
||
|
Henrici's algorithm.
|
||
|
|
||
|
void fmpq_poly_add_can(fmpq_poly_t res, fmpq_poly poly1,
|
||
|
fmpq_poly poly2, int can)
|
||
|
|
||
|
As per \code{fmpq_poly_add} except that one can specify whether to
|
||
|
canonicalise the output or not. This function is intended to be used with
|
||
|
weak canonicalisation to prevent explosion in memory usage. It exists for
|
||
|
performance reasons.
|
||
|
|
||
|
void _fmpq_poly_sub(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz * poly2, const fmpz_t den2, slong len2)
|
||
|
|
||
|
Forms the difference \code{(rpoly, rden)} of \code{(poly1, den1, len1)}
|
||
|
and \code{(poly2, den2, len2)}, placing the result into canonical form.
|
||
|
|
||
|
Assumes that \code{rpoly} is an array of length the maximum of
|
||
|
\code{len1} and \code{len2}. The input operands are assumed to be in
|
||
|
canonical form and are also allowed to be of length~$0$.
|
||
|
|
||
|
\code{(rpoly, rden)} and \code{(poly1, den1, len1)} may be aliased,
|
||
|
but \code{(rpoly, rden)} and \code{(poly2, den2, len2)} may \emph{not} be
|
||
|
aliased.
|
||
|
|
||
|
void _fmpq_poly_sub_can(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz * poly2, const fmpz_t den2, slong len2, int can)
|
||
|
|
||
|
As per \code{_fmpq_poly_sub} except that one can specify whether to
|
||
|
canonicalise the output or not. This function is intended to be used with
|
||
|
weak canonicalisation to prevent explosion in memory usage. It exists for
|
||
|
performance reasons.
|
||
|
|
||
|
void fmpq_poly_sub(fmpq_poly_t res, fmpq_poly poly1, fmpq_poly poly2)
|
||
|
|
||
|
Sets \code{res} to the difference of \code{poly1} and \code{poly2},
|
||
|
using Henrici's algorithm.
|
||
|
|
||
|
void fmpq_poly_sub_can(fmpq_poly_t res, fmpq_poly poly1,
|
||
|
fmpq_poly poly2, int can)
|
||
|
|
||
|
As per \code{_fmpq_poly_sub} except that one can specify whether to
|
||
|
canonicalise the output or not. This function is intended to be used with
|
||
|
weak canonicalisation to prevent explosion in memory usage. It exists for
|
||
|
performance reasons.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Scalar multiplication and division
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_scalar_mul_si(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len, slong c)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to the product of $c$ of
|
||
|
\code{(poly, den, len)}.
|
||
|
|
||
|
If the input is normalised, then so is the output, provided it is
|
||
|
non-zero. If the input is in lowest terms, then so is the output.
|
||
|
However, even if neither of these conditions are met, the result
|
||
|
will be (mathematically) correct.
|
||
|
|
||
|
Supports exact aliasing between \code{(rpoly, den)}
|
||
|
and \code{(poly, den)}.
|
||
|
|
||
|
void _fmpq_poly_scalar_mul_ui(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len, ulong c)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to the product of $c$ of
|
||
|
\code{(poly, den, len)}.
|
||
|
|
||
|
If the input is normalised, then so is the output, provided it is
|
||
|
non-zero. If the input is in lowest terms, then so is the output.
|
||
|
However, even if neither of these conditions are met, the result
|
||
|
will be (mathematically) correct.
|
||
|
|
||
|
Supports exact aliasing between \code{(rpoly, den)}
|
||
|
and \code{(poly, den)}.
|
||
|
|
||
|
void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len, const fmpz_t c)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to the product of $c$ of
|
||
|
\code{(poly, den, len)}.
|
||
|
|
||
|
If the input is normalised, then so is the output, provided it is
|
||
|
non-zero. If the input is in lowest terms, then so is the output.
|
||
|
However, even if neither of these conditions are met, the result
|
||
|
will be (mathematically) correct.
|
||
|
|
||
|
Supports exact aliasing between \code{(rpoly, den)}
|
||
|
and \code{(poly, den)}.
|
||
|
|
||
|
void _fmpq_poly_scalar_mul_fmpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly,
|
||
|
const fmpz_t den, slong len, const fmpz_t r, const fmpz_t s)
|
||
|
|
||
|
Sets \code{(rpoly, rden)} to the product of $r/s$ and
|
||
|
\code{(poly, den, len)}, in lowest terms.
|
||
|
|
||
|
Assumes that \code{(poly, den, len)} and $r/s$ are provided in lowest
|
||
|
terms. Assumes that \code{rpoly} is an array of length \code{len}.
|
||
|
Supports aliasing of \code{(rpoly, den)} and \code{(poly, den)}.
|
||
|
The \code{fmpz_t}'s $r$ and $s$ may not be part of \code{(rpoly, rden)}.
|
||
|
|
||
|
void fmpq_poly_scalar_mul_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c)
|
||
|
|
||
|
Sets \code{rop} to $c$ times \code{op}.
|
||
|
|
||
|
void fmpq_poly_scalar_mul_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c)
|
||
|
|
||
|
Sets \code{rop} to $c$ times \code{op}.
|
||
|
|
||
|
void fmpq_poly_scalar_mul_fmpz(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const fmpz_t c)
|
||
|
|
||
|
Sets \code{rop} to $c$ times \code{op}. Assumes that the \code{fmpz_t c}
|
||
|
is not part of \code{rop}.
|
||
|
|
||
|
void fmpq_poly_scalar_mul_fmpq(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const mpq_t c)
|
||
|
|
||
|
Sets \code{rop} to $c$ times \code{op}.
|
||
|
|
||
|
void fmpq_poly_scalar_mul_mpz(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const mpz_t c)
|
||
|
|
||
|
Sets \code{rop} to $c$ times \code{op}.
|
||
|
|
||
|
void fmpq_poly_scalar_mul_mpq(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const fmpq_t c)
|
||
|
|
||
|
Sets \code{rop} to $c$ times \code{op}.
|
||
|
|
||
|
void _fmpq_poly_scalar_div_fmpz(fmpz * rpoly, fmpz_t rden, const fmpz * poly,
|
||
|
const fmpz_t den, slong len, const fmpz_t c)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $c$,
|
||
|
in lowest terms.
|
||
|
|
||
|
Assumes that \code{len} is positive. Assumes that $c$ is non-zero.
|
||
|
Supports aliasing between \code{(rpoly, rden)} and \code{(poly, den)}.
|
||
|
Assumes that $c$ is not part of \code{(rpoly, rden)}.
|
||
|
|
||
|
void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly,
|
||
|
const fmpz_t den, slong len, slong c)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $c$,
|
||
|
in lowest terms.
|
||
|
|
||
|
Assumes that \code{len} is positive. Assumes that $c$ is non-zero.
|
||
|
Supports aliasing between \code{(rpoly, rden)} and \code{(poly, den)}.
|
||
|
|
||
|
void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly,
|
||
|
const fmpz_t den, slong len, ulong c)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $c$,
|
||
|
in lowest terms.
|
||
|
|
||
|
Assumes that \code{len} is positive. Assumes that $c$ is non-zero.
|
||
|
Supports aliasing between \code{(rpoly, rden)} and \code{(poly, den)}.
|
||
|
|
||
|
void _fmpq_poly_scalar_div_fmpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly,
|
||
|
const fmpz_t den, slong len, const fmpz_t r, const fmpz_t s)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $r/s$,
|
||
|
in lowest terms.
|
||
|
|
||
|
Assumes that \code{len} is positive. Assumes that $r/s$ is non-zero and
|
||
|
in lowest terms. Supports aliasing between \code{(rpoly, rden)} and
|
||
|
\code{(poly, den)}. The \code{fmpz_t}'s $r$ and $s$ may not be part of
|
||
|
\code{(rpoly, poly)}.
|
||
|
|
||
|
void fmpq_poly_scalar_div_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c)
|
||
|
|
||
|
void fmpq_poly_scalar_div_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c);
|
||
|
|
||
|
void fmpq_poly_scalar_div_fmpz(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const fmpz_t c);
|
||
|
|
||
|
void fmpq_poly_scalar_div_fmpq(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const fmpq_t c);
|
||
|
|
||
|
void fmpq_poly_scalar_div_mpz(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const mpz_t c);
|
||
|
|
||
|
void fmpq_poly_scalar_div_mpq(fmpq_poly_t rop,
|
||
|
const fmpq_poly_t op, const mpq_t c);
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Multiplication
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_mul(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz * poly2, const fmpz_t den2, slong len2)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len1 + len2 - 1)} to the product of
|
||
|
\code{(poly1, den1, len1)} and \code{(poly2, den2, len2)}. If the
|
||
|
input is provided in canonical form, then so is the output.
|
||
|
|
||
|
Assumes \code{len1 >= len2 > 0}. Allows zero-padding in the input.
|
||
|
Does not allow aliasing between the inputs and outputs.
|
||
|
|
||
|
void fmpq_poly_mul(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Sets \code{res} to the product of \code{poly1} and \code{poly2}.
|
||
|
|
||
|
void _fmpq_poly_mullow(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz * poly2, const fmpz_t den2, slong len2,
|
||
|
slong n)
|
||
|
|
||
|
Sets \code{(rpoly, rden, n)} to the low $n$ coefficients of
|
||
|
\code{(poly1, den1)} and \code{(poly2, den2)}. The output is
|
||
|
not guaranteed to be in canonical form.
|
||
|
|
||
|
Assumes \code{len1 >= len2 > 0} and \code{0 < n <= len1 + len2 - 1}.
|
||
|
Allows for zero-padding in the inputs. Does not allow aliasing between
|
||
|
the inputs and outputs.
|
||
|
|
||
|
void fmpq_poly_mullow(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n)
|
||
|
|
||
|
Sets \code{res} to the product of \code{poly1} and \code{poly2},
|
||
|
truncated to length~$n$.
|
||
|
|
||
|
void fmpq_poly_addmul(fmpq_poly_t rop, const fmpq_poly_t op1,
|
||
|
const fmpq_poly_t op2)
|
||
|
|
||
|
Adds the product of \code{op1} and \code{op2} to \code{rop}.
|
||
|
|
||
|
void fmpq_poly_submul(fmpq_poly_t rop, const fmpq_poly_t op1,
|
||
|
const fmpq_poly_t op2)
|
||
|
|
||
|
Subtracts the product of \code{op1} and \code{op2} from \code{rop}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Powering
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_pow(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len, ulong e)
|
||
|
|
||
|
Sets \code{(rpoly, rden)} to \code{(poly, den)^e}, assuming
|
||
|
\code{e, len > 0}. Assumes that \code{rpoly} is an array of
|
||
|
length at least \code{e * (len - 1) + 1}. Supports aliasing
|
||
|
of \code{(rpoly, den)} and \code{(poly, den)}.
|
||
|
|
||
|
void fmpq_poly_pow(fmpq_poly_t res, const fmpq_poly_t poly, ulong e)
|
||
|
|
||
|
Sets \code{res} to \code{pow^e}, where the only special case $0^0$ is
|
||
|
defined as $1$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Shifting
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void fmpz_poly_shift_left(fmpz_poly_t res, const fmpz_poly_t poly, slong n)
|
||
|
|
||
|
Set \code{res} to \code{poly} shifted left by $n$ coefficients. Zero
|
||
|
coefficients are inserted.
|
||
|
|
||
|
void fmpz_poly_shift_right(fmpz_poly_t res, const fmpz_poly_t poly, slong n)
|
||
|
|
||
|
Set \code{res} to \code{poly} shifted right by $n$ coefficients.
|
||
|
If $n$ is equal to or greater than the current length of \code{poly},
|
||
|
\code{res} is set to the zero polynomial.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Euclidean division
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_divrem(fmpz * Q, fmpz_t q, fmpz * R, fmpz_t r,
|
||
|
const fmpz * A, const fmpz_t a, slong lenA,
|
||
|
const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv)
|
||
|
|
||
|
Finds the quotient \code{(Q, q)} and remainder \code{(R, r)} of the
|
||
|
Euclidean division of \code{(A, a)} by \code{(B, b)}.
|
||
|
|
||
|
Assumes that \code{lenA >= lenB > 0}. Assumes that $R$ has space for
|
||
|
\code{lenA} coefficients, although only the bottom \code{lenB - 1} will
|
||
|
carry meaningful data on exit. Supports no aliasing between the two
|
||
|
outputs, or between the inputs and the outputs.
|
||
|
|
||
|
An optional precomputed inverse of the leading coefficient of $B$ from
|
||
|
\code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be
|
||
|
\code{NULL}.
|
||
|
|
||
|
void fmpq_poly_divrem(fmpq_poly_t Q, fmpq_poly_t R,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Finds the quotient $Q$ and remainder $R$ of the Euclidean division of
|
||
|
\code{poly1} by \code{poly2}.
|
||
|
|
||
|
void _fmpq_poly_div(fmpz * Q, fmpz_t q,
|
||
|
const fmpz * A, const fmpz_t a, slong lenA,
|
||
|
const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv)
|
||
|
|
||
|
Finds the quotient \code{(Q, q)} of the Euclidean division
|
||
|
of \code{(A, a)} by \code{(B, b)}.
|
||
|
|
||
|
Assumes that \code{lenA >= lenB > 0}. Supports no aliasing
|
||
|
between the inputs and the outputs.
|
||
|
|
||
|
An optional precomputed inverse of the leading coefficient of $B$ from
|
||
|
\code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be
|
||
|
\code{NULL}.
|
||
|
|
||
|
void fmpq_poly_div(fmpq_poly_t Q,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Finds the quotient $Q$ and remainder $R$ of the Euclidean division
|
||
|
of \code{poly1} by \code{poly2}.
|
||
|
|
||
|
void _fmpq_poly_rem(fmpz * R, fmpz_t r,
|
||
|
const fmpz * A, const fmpz_t a, slong lenA,
|
||
|
const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv)
|
||
|
|
||
|
Finds the remainder \code{(R, r)} of the Euclidean division
|
||
|
of \code{(A, a)} by \code{(B, b)}.
|
||
|
|
||
|
Assumes that \code{lenA >= lenB > 0}. Supports no aliasing between
|
||
|
the inputs and the outputs.
|
||
|
|
||
|
An optional precomputed inverse of the leading coefficient of $B$ from
|
||
|
\code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be
|
||
|
\code{NULL}.
|
||
|
|
||
|
void fmpq_poly_rem(fmpq_poly_t R,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Finds the remainder $R$ of the Euclidean division
|
||
|
of \code{poly1} by \code{poly2}.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Euclidean division
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
fmpq_poly_struct * _fmpq_poly_powers_precompute(const fmpz * B,
|
||
|
const fmpz_t denB, slong len)
|
||
|
|
||
|
Computes \code{2*len - 1} powers of $x$ modulo the polynomial $B$ of
|
||
|
the given length. This is used as a kind of precomputed inverse in
|
||
|
the remainder routine below.
|
||
|
|
||
|
void fmpq_poly_powers_precompute(fmpq_poly_powers_precomp_t pinv,
|
||
|
fmpq_poly_t poly)
|
||
|
Computes \code{2*len - 1} powers of $x$ modulo the polynomial $B$ of
|
||
|
the given length. This is used as a kind of precomputed inverse in
|
||
|
the remainder routine below.
|
||
|
|
||
|
void _fmpq_poly_powers_clear(fmpq_poly_struct * powers, slong len)
|
||
|
|
||
|
Clean up resources used by precomputed powers which have been computed
|
||
|
by\\
|
||
|
\code{_fmpq_poly_powers_precompute}.
|
||
|
|
||
|
void fmpq_poly_powers_clear(fmpq_poly_powers_precomp_t pinv)
|
||
|
|
||
|
Clean up resources used by precomputed powers which have been computed
|
||
|
by\\
|
||
|
\code{fmpq_poly_powers_precompute}.
|
||
|
|
||
|
void _fmpq_poly_rem_powers_precomp(fmpz * A, fmpz_t denA, slong m,
|
||
|
const fmpz * B, const fmpz_t denB, slong n,
|
||
|
const fmpq_poly_struct * const powers)
|
||
|
|
||
|
Set $A$ to the remainder of $A$ divide $B$ given precomputed powers mod $B$
|
||
|
provided by \code{_fmpq_poly_powers_precompute}. No aliasing is allowed.
|
||
|
|
||
|
This function is only faster if $m \leq 2*n - 1$.
|
||
|
|
||
|
The output of this function is \emph{not} canonicalised.
|
||
|
|
||
|
void fmpq_poly_rem_powers_precomp(fmpq_poly_t R, const fmpq_poly_t A,
|
||
|
const fmpq_poly_t B, const fmpq_poly_powers_precomp_t B_inv)
|
||
|
|
||
|
Set $R$ to the remainder of $A$ divide $B$ given precomputed powers mod $B$
|
||
|
provided by \code{fmpq_poly_powers_precompute}.
|
||
|
|
||
|
This function is only faster if \code{A->length <= 2*B->length - 1}.
|
||
|
|
||
|
The output of this function is \emph{not} canonicalised.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Power series division
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_inv_series_newton(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong n)
|
||
|
|
||
|
Computes the first $n$ terms of the inverse power series of
|
||
|
\code{poly} using Newton iteration.
|
||
|
|
||
|
The result is produced in canonical form.
|
||
|
|
||
|
Assumes that $n \geq 1$, that \code{poly} has length at least~$n$
|
||
|
and non-zero constant term. Does not support aliasing.
|
||
|
|
||
|
void fmpq_poly_inv_series_newton(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Computes the first $n$ terms of the inverse power series
|
||
|
of \code{poly} using Newton iteration, assuming that \code{poly}
|
||
|
has non-zero constant term and $n \geq 1$.
|
||
|
|
||
|
void _fmpq_poly_inv_series(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong n)
|
||
|
|
||
|
Computes the first $n$ terms of the inverse power series of \code{poly}.
|
||
|
|
||
|
Assumes that $n \geq 1$, that \code{poly} has length at least~$n$ and
|
||
|
non-zero constant term. Does not support aliasing.
|
||
|
|
||
|
void fmpq_poly_inv_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Computes the first $n$ terms of the inverse power series of \code{poly},
|
||
|
assuming that \code{poly} has non-zero constant term and $n \geq 1$.
|
||
|
|
||
|
void _fmpq_poly_div_series(fmpz * Q, fmpz_t denQ,
|
||
|
const fmpz * A, const fmpz_t denA,
|
||
|
const fmpz * B, const fmpz_t denB, slong n)
|
||
|
|
||
|
Divides \code{(A, denA, n)} by \code{(B, denB, n)} as power series
|
||
|
over $\Q$, assuming $B$ has non-zero constant term and $n \geq 1$.
|
||
|
|
||
|
Supports no aliasing other than that of \code{(Q, denQ, n)}
|
||
|
and \code{(B, denB, n)}.
|
||
|
|
||
|
This function does not ensure that the numerator and denominator
|
||
|
are coprime on exit.
|
||
|
|
||
|
void fmpq_poly_div_series(fmpq_poly_t Q, const fmpq_poly_t A,
|
||
|
const fmpq_poly_t B, slong n)
|
||
|
|
||
|
Performs power series division in $\Q[[x]] / (x^n)$. The function
|
||
|
considers the polynomials $A$ and $B$ as power series of length~$n$
|
||
|
starting with the constant terms. The function assumes that $B$ has
|
||
|
non-zero constant term and $n \geq 1$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Greatest common divisor
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_gcd(fmpz *G, fmpz_t denG,
|
||
|
const fmpz *A, slong lenA, const fmpz *B, slong lenB)
|
||
|
|
||
|
Computes the monic greatest common divisor $G$ of $A$ and $B$.
|
||
|
|
||
|
Assumes that $G$ has space for $\len(B)$ coefficients,
|
||
|
where $\len(A) \geq \len(B) > 0$.
|
||
|
|
||
|
Aliasing between the output and input arguments is not supported.
|
||
|
|
||
|
Does not support zero-padding.
|
||
|
|
||
|
void fmpq_poly_gcd(fmpq_poly_t G, const fmpq_poly_t A, const fmpq_poly_t B)
|
||
|
|
||
|
Computes the monic greatest common divisor $G$ of $A$ and $B$.
|
||
|
|
||
|
In the the special case when $A = B = 0$, sets $G = 0$.
|
||
|
|
||
|
void _fmpq_poly_xgcd(fmpz *G, fmpz_t denG,
|
||
|
fmpz *S, fmpz_t denS, fmpz *T, fmpz_t denT,
|
||
|
const fmpz *A, const fmpz_t denA, slong lenA,
|
||
|
const fmpz *B, const fmpz_t denB, slong lenB)
|
||
|
|
||
|
Computes polynomials $G$, $S$, and $T$ such that
|
||
|
$G = \gcd(A, B) = S A + T B$, where $G$ is the monic
|
||
|
greatest common divisor of $A$ and $B$.
|
||
|
|
||
|
Assumes that $G$, $S$, and $T$ have space for $\len(B)$,
|
||
|
$\len(B)$, and $\len(A)$ coefficients, respectively,
|
||
|
where it is also assumed that $\len(A) \geq \len(B) > 0$.
|
||
|
|
||
|
Does not support zero padding of the input arguments.
|
||
|
|
||
|
void fmpq_poly_xgcd(fmpq_poly_t G, fmpz_poly_t S, fmpz_poly_t T,
|
||
|
const fmpq_poly_t A, const fmpq_poly_t B)
|
||
|
|
||
|
Computes polynomials $G$, $S$, and $T$ such that
|
||
|
$G = \gcd(A, B) = S A + T B$, where $G$ is the monic
|
||
|
greatest common divisor of $A$ and $B$.
|
||
|
|
||
|
Corner cases are handled as follows. If $A = B = 0$, returns
|
||
|
$G = S = T = 0$. If $A \neq 0$, $B = 0$, returns the suitable
|
||
|
scalar multiple of $G = A$, $S = 1$, and $T = 0$. The case
|
||
|
when $A = 0$, $B \neq 0$ is handled similarly.
|
||
|
|
||
|
void _fmpq_poly_lcm(fmpz *L, fmpz_t denL,
|
||
|
const fmpz *A, slong lenA, const fmpz *B, slong lenB)
|
||
|
|
||
|
Computes the monic least common multiple $L$ of $A$ and $B$.
|
||
|
|
||
|
Assumes that $L$ has space for $\len(A) + \len(B) - 1$ coefficients,
|
||
|
where $\len(A) \geq \len(B) > 0$.
|
||
|
|
||
|
Aliasing between the output and input arguments is not supported.
|
||
|
|
||
|
Does not support zero-padding.
|
||
|
|
||
|
void fmpq_poly_lcm(fmpq_poly_t L, const fmpq_poly_t A, const fmpq_poly_t B)
|
||
|
|
||
|
Computes the monic least common multiple $L$ of $A$ and $B$.
|
||
|
|
||
|
In the special case when $A = B = 0$, sets $L = 0$.
|
||
|
|
||
|
void _fmpq_poly_resultant(fmpz_t rnum, fmpz_t rden,
|
||
|
const fmpz *poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz *poly2, const fmpz_t den2, slong len2)
|
||
|
|
||
|
Sets \code{(rnum, rden)} to the resultant of the two input
|
||
|
polynomials.
|
||
|
|
||
|
Assumes that \code{len1 >= len2 > 0}. Does not support zero-padding
|
||
|
of the input polynomials. Does not support aliasing of the input and
|
||
|
output arguments.
|
||
|
|
||
|
void fmpq_poly_resultant(fmpq_t r, const fmpq_poly_t f, const fmpq_poly_t g)
|
||
|
|
||
|
Returns the resultant of $f$ and $g$.
|
||
|
|
||
|
Enumerating the roots of $f$ and $g$ over $\bar{\mathbf{Q}}$ as
|
||
|
$r_1, \dotsc, r_m$ and $s_1, \dotsc, s_n$, respectively, and
|
||
|
letting $x$ and $y$ denote the leading coefficients, the resultant
|
||
|
is defined as
|
||
|
\begin{equation*}
|
||
|
x^{\deg(f)} y^{\deg(g)} \prod_{1 \leq i, j \leq n} (r_i - s_j).
|
||
|
\end{equation*}
|
||
|
|
||
|
We handle special cases as follows: if one of the polynomials is zero,
|
||
|
the resultant is zero. Note that otherwise if one of the polynomials is
|
||
|
constant, the last term in the above expression is the empty product.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Derivative and integral
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_derivative(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len - 1)} to the derivative of
|
||
|
\code{(poly, den, len)}. Does nothing if \code{len <= 1}.
|
||
|
Supports aliasing between the two polynomials.
|
||
|
|
||
|
void fmpq_poly_derivative(fmpq_poly_t res, const fmpq_poly_t poly)
|
||
|
|
||
|
Sets \code{res} to the derivative of \code{poly}.
|
||
|
|
||
|
void _fmpq_poly_integral(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to the integral of
|
||
|
\code{(poly, den, len - 1)}. Assumes \code{len >= 0}.
|
||
|
Supports aliasing between the two polynomials.
|
||
|
|
||
|
void fmpq_poly_integral(fmpq_poly_t res, const fmpq_poly_t poly)
|
||
|
|
||
|
Sets \code{res} to the integral of \code{poly}. The constant
|
||
|
term is set to zero. In particular, the integral of the zero
|
||
|
polynomial is the zero polynomial.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Square roots
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_sqrt_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
square root of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 1.
|
||
|
Does not support aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_sqrt_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the square root of \code{f}
|
||
|
to order \code{n > 1}. Requires \code{f} to have constant term 1.
|
||
|
|
||
|
void _fmpq_poly_invsqrt_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the inverse
|
||
|
square root of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 1.
|
||
|
Does not support aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_invsqrt_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the inverse square root of
|
||
|
\code{f} to order \code{n > 0}. Requires \code{f} to have constant term 1.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Transcendental functions
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_log_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
logarithm of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 1.
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_log_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the logarithm of \code{f}
|
||
|
to order \code{n > 0}. Requires \code{f} to have constant term 1.
|
||
|
|
||
|
void _fmpq_poly_exp_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * h, const fmpz_t hden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
exponential function of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Does not support aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_exp_series(fmpq_poly_t res, const fmpq_poly_t h, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the exponential function
|
||
|
of \code{f} to order \code{n > 0}. Requires \code{f} to have
|
||
|
constant term 0.
|
||
|
|
||
|
void _fmpq_poly_atan_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
inverse tangent of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_atan_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the inverse tangent of \code{f}
|
||
|
to order \code{n > 0}. Requires \code{f} to have constant term 0.
|
||
|
|
||
|
void _fmpq_poly_atanh_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the inverse
|
||
|
hyperbolic tangent of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_atanh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the inverse hyperbolic
|
||
|
tangent of \code{f} to order \code{n > 0}. Requires \code{f} to have
|
||
|
constant term 0.
|
||
|
|
||
|
void _fmpq_poly_asin_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
inverse sine of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_asin_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the inverse sine of \code{f}
|
||
|
to order \code{n > 0}. Requires \code{f} to have constant term 0.
|
||
|
|
||
|
void _fmpq_poly_asinh_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the inverse
|
||
|
hyperbolic sine of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_asinh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the inverse hyperbolic
|
||
|
sine of \code{f} to order \code{n > 0}. Requires \code{f} to have
|
||
|
constant term 0.
|
||
|
|
||
|
void _fmpq_poly_tan_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * h, const fmpz_t hden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
tangent function of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Does not support aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_tan_series(fmpq_poly_t res, const fmpq_poly_t h, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the tangent function
|
||
|
of \code{f} to order \code{n > 0}. Requires \code{f} to have
|
||
|
constant term 0.
|
||
|
|
||
|
void _fmpq_poly_sin_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
sine of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_sin_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the sine of \code{f}
|
||
|
to order \code{n > 0}. Requires \code{f} to have constant term 0.
|
||
|
|
||
|
void _fmpq_poly_cos_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
cosine of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Supports aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_cos_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the cosine of \code{f}
|
||
|
to order \code{n > 0}. Requires \code{f} to have constant term 0.
|
||
|
|
||
|
void _fmpq_poly_sinh_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
hyperbolic sine of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Does not support aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_sinh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the hyperbolic sine of \code{f}
|
||
|
to order \code{n > 0}. Requires \code{f} to have constant term 0.
|
||
|
|
||
|
void _fmpq_poly_cosh_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the hyperbolic
|
||
|
cosine of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Does not support aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_cosh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the hyperbolic cosine of
|
||
|
\code{f} to order \code{n > 0}. Requires \code{f} to have constant term 0.
|
||
|
|
||
|
void _fmpq_poly_tanh_series(fmpz * g, fmpz_t gden,
|
||
|
const fmpz * f, const fmpz_t fden, slong n)
|
||
|
|
||
|
Sets \code{(g, gden, n)} to the series expansion of the
|
||
|
hyperbolic tangent of \code{(f, fden, n)}. Assumes \code{n > 0} and
|
||
|
that \code{(f, fden, n)} has constant term 0.
|
||
|
Does not support aliasing between the input and output polynomials.
|
||
|
|
||
|
void fmpq_poly_tanh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n)
|
||
|
|
||
|
Sets \code{res} to the series expansion of the hyperbolic tangent of
|
||
|
\code{f} to order \code{n > 0}. Requires \code{f} to have constant term 0.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Evaluation
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_evaluate_fmpz(fmpz_t rnum, fmpz_t rden, const fmpz * poly,
|
||
|
const fmpz_t den, slong len, const fmpz_t a)
|
||
|
|
||
|
Evaluates the polynomial \code{(poly, den, len)} at the integer $a$ and
|
||
|
sets \code{(rnum, rden)} to the result in lowest terms.
|
||
|
|
||
|
void fmpq_poly_evaluate_fmpz(fmpq_t res, const fmpq_poly_t poly,
|
||
|
const fmpz_t a)
|
||
|
|
||
|
Evaluates the polynomial \code{poly} at the integer $a$ and sets
|
||
|
\code{res} to the result.
|
||
|
|
||
|
void _fmpq_poly_evaluate_fmpq(fmpz_t rnum, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len,
|
||
|
const fmpz_t anum, const fmpz_t aden)
|
||
|
|
||
|
Evaluates the polynomial \code{(poly, den, len)} at the rational
|
||
|
\code{(anum, aden)} and sets \code{(rnum, rden)} to the result in
|
||
|
lowest terms. Aliasing between \code{(rnum, rden)} and
|
||
|
\code{(anum, aden)} is not supported.
|
||
|
|
||
|
void fmpq_poly_evaluate_fmpq(fmpq_t res,
|
||
|
const fmpq_poly_t poly, const fmpq_t a)
|
||
|
|
||
|
Evaluates the polynomial \code{poly} at the rational $a$ and
|
||
|
sets \code{res} to the result.
|
||
|
|
||
|
void fmpq_poly_evaluate_mpz(mpq_t res, const fmpq_poly_t poly, const mpz_t a)
|
||
|
|
||
|
Evaluates the polynomial \code{poly} at the integer $a$ of type
|
||
|
\code{mpz} and sets \code{res} to the result.
|
||
|
|
||
|
void fmpq_poly_evaluate_mpq(mpq_t res, const fmpq_poly_t poly, const mpq_t a)
|
||
|
|
||
|
Evaluates the polynomial \code{poly} at the rational $a$ of type
|
||
|
\code{mpq} and sets \code{res} to the result.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Interpolation
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void
|
||
|
_fmpq_poly_interpolate_fmpz_vec(fmpz * poly, fmpz_t den,
|
||
|
const fmpz * xs, const fmpz * ys, slong n)
|
||
|
|
||
|
Sets \code{poly} / \code{den} to the unique interpolating polynomial of
|
||
|
degree at most $n - 1$ satisfying $f(x_i) = y_i$ for every pair $x_i, y_i$
|
||
|
in \code{xs} and \code{ys}.
|
||
|
|
||
|
The vector \code{poly} must have room for \code{n+1} coefficients,
|
||
|
even if the interpolating polynomial is shorter.
|
||
|
Aliasing of \code{poly} or \code{den} with any other argument is not
|
||
|
allowed.
|
||
|
|
||
|
It is assumed that the $x$ values are distinct.
|
||
|
|
||
|
This function uses a simple $O(n^2)$ implementation of Lagrange
|
||
|
interpolation, clearing denominators to avoid working with fractions.
|
||
|
It is currently not designed to be efficient for large $n$.
|
||
|
|
||
|
fmpq_poly_interpolate_fmpz_vec(fmpq_poly_t poly,
|
||
|
const fmpz * xs, const fmpz * ys, slong n)
|
||
|
|
||
|
Sets \code{poly} to the unique interpolating polynomial of degree
|
||
|
at most $n - 1$ satisfying $f(x_i) = y_i$ for every pair $x_i, y_i$
|
||
|
in \code{xs} and \code{ys}. It is assumed that the $x$ values are distinct.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Composition
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_compose(fmpz * res, fmpz_t den,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1,
|
||
|
const fmpz * poly2, const fmpz_t den2, slong len2)
|
||
|
|
||
|
Sets \code{(res, den)} to the composition of \code{(poly1, den1, len1)}
|
||
|
and \code{(poly2, den2, len2)}, assuming \code{len1, len2 > 0}.
|
||
|
|
||
|
Assumes that \code{res} has space for \code{(len1 - 1) * (len2 - 1) + 1}
|
||
|
coefficients. Does not support aliasing.
|
||
|
|
||
|
void fmpq_poly_compose(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2)
|
||
|
|
||
|
Sets \code{res} to the composition of \code{poly1} and \code{poly2}.
|
||
|
|
||
|
void _fmpq_poly_rescale(fmpz * res, fmpz_t denr, const fmpz * poly,
|
||
|
const fmpz_t den, slong len, const fmpz_t anum, const fmpz_t aden)
|
||
|
|
||
|
Sets \code{(res, denr, len)} to \code{(poly, den, len)} with the
|
||
|
indeterminate rescaled by \code{(anum, aden)}.
|
||
|
|
||
|
Assumes that \code{len > 0} and that \code{(anum, aden)} is non-zero and
|
||
|
in lowest terms. Supports aliasing between \code{(res, denr, len)} and
|
||
|
\code{(poly, den, len)}.
|
||
|
|
||
|
void fmpz_poly_rescale(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly, const fmpq_t a)
|
||
|
|
||
|
Sets \code{res} to \code{poly} with the indeterminate rescaled by $a$.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Power series composition
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_compose_series_horner(fmpz * res, fmpz_t den,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1, const fmpz * poly2,
|
||
|
const fmpz_t den2, slong len2, slong n)
|
||
|
|
||
|
Sets \code{(res, den, n)} to the composition of
|
||
|
\code{(poly1, den1, len1)} and \code{(poly2, den2, len2)} modulo $x^n$,
|
||
|
where the constant term of \code{poly2} is required to be zero.
|
||
|
|
||
|
Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n},
|
||
|
that \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has
|
||
|
space for \code{n} coefficients. Does not support aliasing between any
|
||
|
of the inputs and the output.
|
||
|
|
||
|
This implementation uses the Horner scheme.
|
||
|
The default \code{fmpz_poly} composition algorithm is automatically
|
||
|
used when the composition can be performed over the integers.
|
||
|
|
||
|
void fmpq_poly_compose_series_horner(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n)
|
||
|
|
||
|
Sets \code{res} to the composition of \code{poly1} and \code{poly2}
|
||
|
modulo $x^n$, where the constant term of \code{poly2} is required
|
||
|
to be zero.
|
||
|
|
||
|
This implementation uses the Horner scheme.
|
||
|
The default \code{fmpz_poly} composition algorithm is automatically
|
||
|
used when the composition can be performed over the integers.
|
||
|
|
||
|
void _fmpq_poly_compose_series_brent_kung(fmpz * res, fmpz_t den,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong len1, const fmpz * poly2,
|
||
|
const fmpz_t den2, slong len2, slong n)
|
||
|
|
||
|
Sets \code{(res, den, n)} to the composition of
|
||
|
\code{(poly1, den1, len1)} and \code{(poly2, den2, len2)} modulo $x^n$,
|
||
|
where the constant term of \code{poly2} is required to be zero.
|
||
|
|
||
|
Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n},
|
||
|
that \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has
|
||
|
space for \code{n} coefficients. Does not support aliasing between any
|
||
|
of the inputs and the output.
|
||
|
|
||
|
This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}.
|
||
|
The default \code{fmpz_poly} composition algorithm is automatically
|
||
|
used when the composition can be performed over the integers.
|
||
|
|
||
|
void fmpq_poly_compose_series_brent_kung(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n)
|
||
|
|
||
|
Sets \code{res} to the composition of \code{poly1} and \code{poly2}
|
||
|
modulo $x^n$, where the constant term of \code{poly2} is required
|
||
|
to be zero.
|
||
|
|
||
|
This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}.
|
||
|
The default \code{fmpz_poly} composition algorithm is automatically
|
||
|
used when the composition can be performed over the integers.
|
||
|
|
||
|
void _fmpq_poly_compose_series(fmpz * res, fmpz_t den, const fmpz * poly1,
|
||
|
const fmpz_t den1, slong len1, const fmpz * poly2,
|
||
|
const fmpz_t den2, slong len2, slong n)
|
||
|
|
||
|
Sets \code{(res, den, n)} to the composition of
|
||
|
\code{(poly1, den1, len1)} and \code{(poly2, den2, len2)} modulo $x^n$,
|
||
|
where the constant term of \code{poly2} is required to be zero.
|
||
|
|
||
|
Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n},
|
||
|
that \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has
|
||
|
space for \code{n} coefficients. Does not support aliasing between any
|
||
|
of the inputs and the output.
|
||
|
|
||
|
This implementation automatically switches between the Horner scheme
|
||
|
and Brent-Kung algorithm 2.1 depending on the size of the inputs.
|
||
|
The default \code{fmpz_poly} composition algorithm is automatically
|
||
|
used when the composition can be performed over the integers.
|
||
|
|
||
|
void fmpq_poly_compose_series(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n)
|
||
|
|
||
|
Sets \code{res} to the composition of \code{poly1} and \code{poly2}
|
||
|
modulo $x^n$, where the constant term of \code{poly2} is required
|
||
|
to be zero.
|
||
|
|
||
|
This implementation automatically switches between the Horner scheme
|
||
|
and Brent-Kung algorithm 2.1 depending on the size of the inputs.
|
||
|
The default \code{fmpz_poly} composition algorithm is automatically
|
||
|
used when the composition can be performed over the integers.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Power series reversion
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_revert_series_lagrange(fmpz * res, fmpz_t den,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong n)
|
||
|
|
||
|
Sets \code{(res, den)} to the power series reversion of
|
||
|
\code{(poly1, den1)} modulo $x^n$, where the input has
|
||
|
length $n$ (possibly being zero-padded).
|
||
|
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero. Assumes that $n > 0$.
|
||
|
Does not support aliasing between any of the inputs and the output.
|
||
|
|
||
|
This implementation uses the Lagrange inversion formula.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
void fmpq_poly_revert_series_lagrange(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$.
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero.
|
||
|
|
||
|
This implementation uses the Lagrange inversion formula.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
void _fmpq_poly_revert_series_lagrange_fast(fmpz * res, fmpz_t den,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong n)
|
||
|
|
||
|
Sets \code{(res, den)} to the power series reversion of
|
||
|
\code{(poly1, den1)} modulo $x^n$, where the input has
|
||
|
length $n$ (possibly being zero-padded).
|
||
|
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero. Assumes that $n > 0$.
|
||
|
Does not support aliasing between any of the inputs and the output.
|
||
|
|
||
|
This implementation uses a reduced-complexity implementation
|
||
|
of the Lagrange inversion formula.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
void fmpq_poly_revert_series_lagrange_fast(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$.
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero.
|
||
|
|
||
|
This implementation uses a reduced-complexity implementation
|
||
|
of the Lagrange inversion formula.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
void _fmpq_poly_revert_series_newton(fmpz * res, fmpz_t den,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong n)
|
||
|
|
||
|
Sets \code{(res, den)} to the power series reversion of
|
||
|
\code{(poly1, den1)} modulo $x^n$, where the input has
|
||
|
length $n$ (possibly being zero-padded).
|
||
|
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero. Assumes that $n > 0$.
|
||
|
Does not support aliasing between any of the inputs and the output.
|
||
|
|
||
|
This implementation uses Newton iteration.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
void fmpq_poly_revert_series_newton(fmpq_poly_t res,
|
||
|
const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$.
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero.
|
||
|
|
||
|
This implementation uses Newton iteration.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
void _fmpq_poly_revert_series(fmpz * res, fmpz_t den,
|
||
|
const fmpz * poly1, const fmpz_t den1, slong n)
|
||
|
|
||
|
Sets \code{(res, den)} to the power series reversion of
|
||
|
\code{(poly1, den1)} modulo $x^n$, where the input has
|
||
|
length $n$ (possibly being zero-padded).
|
||
|
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero. Assumes that $n > 0$.
|
||
|
Does not support aliasing between any of the inputs and the output.
|
||
|
|
||
|
This implementation defaults to using Newton iteration.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
void fmpq_poly_revert_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n)
|
||
|
|
||
|
Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$.
|
||
|
The constant term of \code{poly2} is required to be zero and
|
||
|
the linear term is required to be nonzero.
|
||
|
|
||
|
This implementation defaults to using Newton iteration.
|
||
|
The default \code{fmpz_poly} reversion algorithm is automatically
|
||
|
used when the reversion can be performed over the integers.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Gaussian content
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
void _fmpq_poly_content(fmpq_t res,
|
||
|
const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Sets \code{res} to the content of \code{(poly, den, len)}.
|
||
|
If \code{len == 0}, sets \code{res} to zero.
|
||
|
|
||
|
void fmpq_poly_content(fmpq_t res, const fmpq_poly_t poly)
|
||
|
|
||
|
Sets \code{res} to the content of \code{poly}. The content of the zero
|
||
|
polynomial is defined to be zero.
|
||
|
|
||
|
void _fmpq_poly_primitive_part(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to the primitive part, with non-negative
|
||
|
leading coefficient, of \code{(poly, den, len)}. Assumes that
|
||
|
\code{len > 0}. Supports aliasing between the two polynomials.
|
||
|
|
||
|
void fmpq_poly_primitive_part(fmpq_poly_t res, const fmpq_poly_t poly)
|
||
|
|
||
|
Sets \code{res} to the primitive part, with non-negative leading
|
||
|
coefficient, of \code{poly}.
|
||
|
|
||
|
int _fmpq_poly_is_monic(const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Returns whether the polynomial \code{(poly, den, len)} is monic.
|
||
|
The zero polynomial is not monic by definition.
|
||
|
|
||
|
int fmpq_poly_is_monic(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns whether the polynomial \code{poly} is monic. The zero
|
||
|
polynomial is not monic by definition.
|
||
|
|
||
|
void _fmpq_poly_make_monic(fmpz * rpoly, fmpz_t rden,
|
||
|
const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Sets \code{(rpoly, rden, len)} to the monic scalar multiple of
|
||
|
\code{(poly, den, len)}. Assumes that \code{len > 0}. Supports
|
||
|
aliasing between the two polynomials.
|
||
|
|
||
|
void fmpq_poly_make_monic(fmpq_poly_t res, const fmpq_poly_t poly)
|
||
|
|
||
|
Sets \code{res} to the monic scalar multiple of \code{poly} whenever
|
||
|
\code{poly} is non-zero. If \code{poly} is the zero polynomial, sets
|
||
|
\code{res} to zero.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Square-free
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
int fmpq_poly_is_squarefree(const fmpq_poly_t poly)
|
||
|
|
||
|
Returns whether the polynomial \code{poly} is square-free. A non-zero
|
||
|
polynomial is defined to be square-free if it has no non-unit square
|
||
|
factors. We also define the zero polynomial to be square-free.
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
Input and output
|
||
|
|
||
|
*******************************************************************************
|
||
|
|
||
|
int _fmpq_poly_print(const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Prints the polynomial \code{(poly, den, len)} to \code{stdout}.
|
||
|
|
||
|
In case of success, returns a positive value. In case of failure,
|
||
|
returns a non-positive value.
|
||
|
|
||
|
int fmpq_poly_print(const fmpq_poly_t poly)
|
||
|
|
||
|
Prints the polynomial to \code{stdout}.
|
||
|
|
||
|
In case of success, returns a positive value. In case of failure,
|
||
|
returns a non-positive value.
|
||
|
|
||
|
int _fmpq_poly_print_pretty(const fmpz *poly, const fmpz_t den, slong len,
|
||
|
const char * x)
|
||
|
|
||
|
int fmpq_poly_print_pretty(const fmpq_poly_t poly, const char * var)
|
||
|
|
||
|
Prints the pretty representation of \code{poly} to \code{stdout}, using
|
||
|
the null-terminated string \code{var} not equal to \code{"\0"} as the
|
||
|
variable name.
|
||
|
|
||
|
In the current implementation always returns~$1$.
|
||
|
|
||
|
int _fmpq_poly_fprint(FILE * file,
|
||
|
const fmpz * poly, const fmpz_t den, slong len)
|
||
|
|
||
|
Prints the polynomial \code{(poly, den, len)} to the stream \code{file}.
|
||
|
|
||
|
In case of success, returns a positive value. In case of failure,
|
||
|
returns a non-positive value.
|
||
|
|
||
|
int fmpq_poly_fprint(FILE * file, const fmpq_poly_t poly)
|
||
|
|
||
|
Prints the polynomial to the stream \code{file}.
|
||
|
|
||
|
In case of success, returns a positive value. In case of failure,
|
||
|
returns a non-positive value.
|
||
|
|
||
|
int _fmpq_poly_fprint_pretty(FILE * file,
|
||
|
const fmpz *poly, const fmpz_t den, slong len,
|
||
|
const char * x)
|
||
|
|
||
|
int fmpq_poly_print_pretty(const fmpq_poly_t poly, const char * var)
|
||
|
|
||
|
Prints the pretty representation of \code{poly} to \code{stdout}, using
|
||
|
the null-terminated string \code{var} not equal to \code{"\0"} as the
|
||
|
variable name.
|
||
|
|
||
|
In the current implementation, always returns~$1$.
|
||
|
|
||
|
int fmpq_poly_read(fmpq_poly_t poly)
|
||
|
|
||
|
Reads a polynomial from \code{stdin}, storing the result
|
||
|
in \code{poly}.
|
||
|
|
||
|
In case of success, returns a positive number. In case of failure,
|
||
|
returns a non-positive value.
|
||
|
|
||
|
int fmpq_poly_fread(FILE * file, fmpq_poly_t poly)
|
||
|
|
||
|
Reads a polynomial from the stream \code{file}, storing the result
|
||
|
in \code{poly}.
|
||
|
|
||
|
In case of success, returns a positive number. In case of failure,
|
||
|
returns a non-positive value.
|
||
|
|