/*=============================================================================

    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 fmpz_poly_set_trunc(fmpz_poly_t res, const fmpz_poly_t poly, slong n)

    Sets \code{res} to a copy of \code{poly}, truncated to length \code{n}.

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_equal_trunc(const fmpz * poly1, const fmpz_t den1, slong len1, 
       const fmpz * poly2, const fmpz_t den2, slong len2, slong n);

    Return $1$ if \code{poly1} and \code{poly2} notionally truncated to length
    $n$ are equal, otherwise returns~$0$.

int fmpq_poly_equal_trunc(const fmpq_poly_t poly1,
                          const fmpq_poly_t poly2, slong n);

    Return $1$ if \code{poly1} and \code{poly2} notionally truncated to length
    $n$ are equal, 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_series_add(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)

    As per \code{_fmpq_poly_add} but the inputs are first notionally truncated
    to length $n$. If $n$ is less than \code{len1} or \code{len2} then the
    output only needs space for $n$ coefficients. We require $n \geq 0$.

void _fmpq_poly_add_series_can(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, int can)

    As per \code{_fmpq_poly_add_can} but the inputs are first notionally
    truncated to length $n$. If $n$ is less than \code{len1} or \code{len2}
    then the output only needs space for $n$ coefficients. We require 
    $n \geq 0$.

void fmpq_poly_add_series(fmpq_poly_t res, fmpq_poly poly1, fmpq_poly poly2, slong n)

    As per \code{fmpq_poly_add} but the inputs are first notionally
    truncated to length $n$. 

void fmpq_poly_add_series_can(fmpq_poly_t res, fmpq_poly poly1, 
                                          fmpq_poly poly2, slong n, int can)

    As per \code{fmpq_poly_add_can} but the inputs are first notionally
    truncated to length $n$. 

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.

void _fmpq_poly_series_sub(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)

    As per \code{_fmpq_poly_sub} but the inputs are first notionally truncated
    to length $n$. If $n$ is less than \code{len1} or \code{len2} then the
    output only needs space for $n$ coefficients. We require $n \geq 0$.

void _fmpq_poly_sub_series_can(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, int can)

    As per \code{_fmpq_poly_sub_can} but the inputs are first notionally
    truncated to length $n$. If $n$ is less than \code{len1} or \code{len2}
    then the output only needs space for $n$ coefficients. We require 
    $n \geq 0$.

void fmpq_poly_sub_series(fmpq_poly_t res, fmpq_poly poly1, fmpq_poly poly2, slong n)

    As per \code{fmpq_poly_sub} but the inputs are first notionally
    truncated to length $n$. 

void fmpq_poly_sub_series_can(fmpq_poly_t res, fmpq_poly poly1, 
                                          fmpq_poly poly2, slong n, int can)

    As per \code{fmpq_poly_sub_can} but the inputs are first notionally
    truncated to length $n$. 

*******************************************************************************

    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 len, slong n)

    Computes the first $n$ terms of the inverse power series of 
    \code{(poly, den, len)} using Newton iteration.

    The result is produced in canonical form.

    Assumes that $n \geq 1$ and that \code{poly} has 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, den, len)}.

    The result is produced in canonical form.

    Assumes that $n \geq 1$ and that \code{poly} has 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, slong lenA,
                       const fmpz * B, const fmpz_t denB, slong lenB, slong n)

    Divides \code{(A, denA, lenA)} by \code{(B, denB, lenB)} as power series 
    over $\Q$, assuming $B$ has non-zero constant term and that
    all lengths are positive.

    Aliasing is not supported.

    This function ensures 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    square root of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the inverse
    square root of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    logarithm of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 hlen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    exponential function of \code{(h, hden, hlen)}.  Assumes
    \code{n > 0, hlen > 0} and
    that \code{(h, hden, hlen)} 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{h} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    inverse tangent of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the inverse
    hyperbolic tangent of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    inverse sine of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the inverse
    hyperbolic sine of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 * f, const fmpz_t fden, slong flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    tangent function of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 f, 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    sine of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    cosine of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    hyperbolic sine of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the hyperbolic
    cosine of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 flen, slong n)

    Sets \code{(g, gden, n)} to the series expansion of the
    hyperbolic tangent of \code{(f, fden, flen)}.  Assumes \code{n > 0} and
    that \code{(f, fden, flen)} 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 len1, slong n)

    Sets \code{(res, den)} to the power series reversion of
    \code{(poly1, den1, len1)} modulo $x^n$.

    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 len1, slong n)

    Sets \code{(res, den)} to the power series reversion of
    \code{(poly1, den1, len1)} modulo $x^n$.

    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 len1, slong n)

    Sets \code{(res, den)} to the power series reversion of
    \code{(poly1, den1, len1)} modulo $x^n$.

    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 len1, slong n)

    Sets \code{(res, den)} to the power series reversion of
    \code{(poly1, den1, len1)} modulo $x^n$.

    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.

