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

    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) 2009, 2010, 2011 Sebastian Pancratz

******************************************************************************/

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

    Memory management

    We represent a rational function over $\mathbf{Q}$ as the quotient 
    of two coprime integer polynomials of type \code{fmpz_poly_t}, 
    enforcing that the leading coefficient of the denominator is 
    positive.  The zero function is represented as $0/1$.

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

void fmpz_poly_q_init(fmpz_poly_q_t rop)

    Initialises \code{rop}.

void fmpz_poly_q_clear(fmpz_poly_q_t rop)

    Clears the object \code{rop}.

fmpz_poly_struct * fmpz_poly_q_numref(const fmpz_poly_q_t op)

    Returns a reference to the numerator of \code{op}.

fmpz_poly_struct * fmpz_poly_q_denref(const fmpz_poly_q_t op)

    Returns a reference to the denominator of \code{op}.

void fmpz_poly_q_canonicalise(fmpz_poly_q_t rop)

    Brings \code{rop} into canonical form, only assuming that 
    the denominator is non-zero.

int fmpz_poly_q_is_canonical(const fmpz_poly_q_t op)

    Checks whether the rational function \code{op} is in 
    canonical form.

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

    Randomisation

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

void fmpz_poly_q_randtest(fmpz_poly_q_t poly, flint_rand_t state,
                          slong len1, mp_bitcnt_t bits1, 
                          slong len2, mp_bitcnt_t bits2)

    Sets \code{poly} to a random rational function.

void fmpz_poly_q_randtest_not_zero(fmpz_poly_q_t poly, flint_rand_t state, 
                                   slong len1, mp_bitcnt_t bits1, 
                                   slong len2, mp_bitcnt_t bits2)

    Sets \code{poly} to a random non-zero rational function.

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

    Assignment

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

void fmpz_poly_q_set(fmpz_poly_q_t rop, const fmpz_poly_q_t op)

    Sets the element \code{rop} to the same value as the element \code{op}.

void fmpz_poly_q_set_si(fmpz_poly_q_t rop, slong op)

    Sets the element \code{rop} to the value given by the \code{slong} 
    \code{op}.

void fmpz_poly_q_swap(fmpz_poly_q_t op1, fmpz_poly_q_t op2)

    Swaps the elements \code{op1} and \code{op2}.

    This is done efficiently by swapping pointers.

void fmpz_poly_q_zero(fmpz_poly_q_t rop)

    Sets \code{rop} to zero.

void fmpz_poly_q_one(fmpz_poly_q_t rop)

    Sets \code{rop} to one.

void fmpz_poly_q_neg(fmpz_poly_q_t rop, const fmpz_poly_q_t op)

    Sets the element \code{rop} to the additive inverse of \code{op}.

void fmpz_poly_q_inv(fmpz_poly_q_t rop, const fmpz_poly_q_t op)

    Sets the element \code{rop} to the multiplicative inverse of \code{op}.

    Assumes that the element \code{op} is non-zero.

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

    Comparison

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

int fmpz_poly_q_is_zero(const fmpz_poly_q_t op)

    Returns whether the element \code{op} is zero.

int fmpz_poly_q_is_one(const fmpz_poly_q_t op)

    Returns whether the element \code{rop} is equal to the constant 
    polynomial $1$.

int fmpz_poly_q_equal(const fmpz_poly_q_t op1, const fmpz_poly_q_t op2)

    Returns whether the two elements \code{op1} and \code{op2} are equal.

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

    Addition and subtraction

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

void fmpz_poly_q_add(fmpz_poly_q_t rop, 
                     const fmpz_poly_q_t op1, const fmpz_poly_q_t op2)

    Sets \code{rop} to the sum of \code{op1} and \code{op2}.

void fmpz_poly_q_sub(fmpz_poly_q_t rop, 
                     const fmpz_poly_q_t op1, const fmpz_poly_q_t op2)

    Sets \code{rop} to the difference of \code{op1} and \code{op2}.

void fmpz_poly_q_addmul(fmpz_poly_q_t rop, 
                        const fmpz_poly_q_t op1, const fmpz_poly_q_t op2)

    Adds the product of \code{op1} and \code{op2} to \code{rop}.

void fmpz_poly_q_submul(fmpz_poly_q_t rop, 
                        const fmpz_poly_q_t op1, const fmpz_poly_q_t op2)

    Subtracts the product of \code{op1} and \code{op2} from \code{rop}.

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

    Scalar multiplication and division

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

void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, 
                               const fmpz_poly_q_t op, slong x)

    Sets \code{rop} to the product of the rational function \code{op} 
    and the \code{slong} integer $x$.

void fmpz_poly_q_scalar_mul_mpz(fmpz_poly_q_t rop, 
                                const fmpz_poly_q_t op, const mpz_t x)

    Sets \code{rop} to the product of the rational function \code{op} 
    and the \code{mpz_t} integer $x$.

void fmpz_poly_q_scalar_mul_mpq(fmpz_poly_q_t rop, 
                                const fmpz_poly_q_t op, const mpq_t x)

    Sets \code{rop} to the product of the rational function \code{op} 
    and the \code{mpq_t} rational $x$.

void fmpz_poly_q_scalar_div_si(fmpz_poly_q_t rop, 
                               const fmpz_poly_q_t op, slong x)

    Sets \code{rop} to the quotient of the rational function \code{op} 
    and the \code{slong} integer $x$.

void fmpz_poly_q_scalar_div_mpz(fmpz_poly_q_t rop, 
                                const fmpz_poly_q_t op, const mpz_t x)

    Sets \code{rop} to the quotient of the rational function \code{op} 
    and the \code{mpz_t} integer $x$.

void fmpz_poly_q_scalar_div_mpq(fmpz_poly_q_t rop, 
                                const fmpz_poly_q_t op, const mpq_t x)

    Sets \code{rop} to the quotient of the rational function \code{op} 
    and the \code{mpq_t} rational $x$.

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

    Multiplication and division

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

void fmpz_poly_q_mul(fmpz_poly_q_t rop, 
                     const fmpz_poly_q_t op1, const fmpz_poly_q_t op2)

    Sets \code{rop} to the product of \code{op1} and \code{op2}.

void fmpz_poly_q_div(fmpz_poly_q_t rop, 
                     const fmpz_poly_q_t op1, const fmpz_poly_q_t op2)

    Sets \code{rop} to the quotient of \code{op1} and \code{op2}.

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

    Powering

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

void fmpz_poly_q_pow(fmpz_poly_q_t rop, const fmpz_poly_q_t op, ulong exp)

    Sets \code{rop} to the \code{exp}-th power of \code{op}.

    The corner case of \code{exp == 0} is handled by setting \code{rop} to 
    the constant function $1$.  Note that this includes the case $0^0 = 1$.

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

    Derivative

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

void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op)

    Sets \code{rop} to the derivative of \code{op}.

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

    Evaluation

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

int fmpz_poly_q_evaluate(mpq_t rop, const fmpz_poly_q_t f, const mpq_t a)

    Sets \code{rop} to $f$ evaluated at the rational $a$.

    If the denominator evaluates to zero at $a$, returns non-zero and 
    does not modify any of the variables.  Otherwise, returns $0$ and 
    sets \code{rop} to the rational $f(a)$.

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

    Input and output

    The following three methods enable users to construct elements of type\\ 
    \code{fmpz_poly_q_t} from strings or to obtain string representations of 
    such elements.

    The format used is based on the FLINT format for integer polynomials of 
    type \code{fmpz_poly_t}, which we recall first: 

    A non-zero polynomial $a_0 + a_1 X + \dotsb + a_n X^n$ of length 
    $n + 1$ is represented by the string \code{"n+1  a_0 a_1 ... a_n"}, 
    where there are two space characters following the length and single 
    space characters separating the individual coefficients.  There is no 
    leading or trailing white-space.  The zero polynomial is simply 
    represented by \code{"0"}.
    
    We adapt this notation for rational functions as follows.  We denote the 
    zero function by \code{"0"}.  Given a non-zero function with numerator 
    and denominator string representations \code{num} and \code{den}, 
    respectively, we use the string \code{num/den} to represent the rational 
    function, unless the denominator is equal to one, in which case we simply 
    use \code{num}.

    There is also a \code{_pretty} variant available, which bases the string 
    parts for the numerator and denominator on the output of the function 
    \code{fmpz_poly_get_str_pretty} and introduces parentheses where 
    necessary.

    Note that currently these functions are not optimised for performance and 
    are intended to be used only for debugging purposes or one-off input and 
    output, rather than as a low-level parser.

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

int fmpz_poly_q_set_str(fmpz_poly_q_t rop, const char *s)

    Sets \code{rop} to the rational function given 
    by the string \code{s}.

char * fmpz_poly_q_get_str(const fmpz_poly_q_t op)

    Returns the string representation of 
    the rational function \code{op}.

char * fmpz_poly_q_get_str_pretty(const fmpz_poly_q_t op, const char *x)

    Returns the pretty string representation of 
    the rational function \code{op}.

int fmpz_poly_q_print(const fmpz_poly_q_t op)

    Prints the representation of the rational 
    function \code{op} to \code{stdout}.

int fmpz_poly_q_print_pretty(const fmpz_poly_q_t op, const char *x)

    Prints the pretty representation of the rational 
    function \code{op} to \code{stdout}.

