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

    This file is part of FLINT.

    FLINT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    FLINT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with FLINT; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

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

    Copyright (C) 2011 Fredrik Johansson

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

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

    Factoring integers 

    An integer may be represented in factored form using the 
    \code{fmpz_factor_t} data structure. This consists of two \code{fmpz} 
    vectors representing bases and exponents, respectively. Canonically, 
    the bases will be prime numbers sorted in ascending order and the 
    exponents will be positive.

    A separate \code{int} field holds the sign, which may be $-1$, $0$ or $1$.

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

void fmpz_factor_init(fmpz_factor_t factor)

    Initialises an \code{fmpz_factor_t} structure.

void fmpz_factor_clear(fmpz_factor_t factor)

    Clears an \code{fmpz_factor_t} structure.

void _fmpz_factor_append_ui(fmpz_factor_t factor, mp_limb_t p, ulong exp)

    Append a factor $p$ to the given exponent to the 
    \code{fmpz_factor_t} structure \code{factor}.

void _fmpz_factor_append(fmpz_factor_t factor, fmpz_t p, ulong exp)

    Append a factor $p$ to the given exponent to the 
    \code{fmpz_factor_t} structure \code{factor}.

void fmpz_factor(fmpz_factor_t factor, const fmpz_t n)

    Factors $n$ into prime numbers. If $n$ is zero or negative, the
    sign field of the \code{factor} object will be set accordingly.

    This currently only uses trial division, falling back to \code{n_factor()}
    as soon as the number shrinks to a single limb.

void fmpz_factor_si(fmpz_factor_t factor, slong n)

    Like \code{fmpz_factor}, but takes a machine integer $n$ as input.

int fmpz_factor_trial_range(fmpz_factor_t factor, const fmpz_t n, 
                                       ulong start, ulong num_primes)

    Factors $n$ into prime factors using trial division. If $n$ is 
    zero or negative, the sign field of the \code{factor} object will be 
    set accordingly.

    The algorithm starts with the given start index in the \code{flint_primes}
    table and uses at most \code{num_primes} primes from that point. 

    The function returns 1 if $n$ is completely factored, otherwise it returns
    $0$.

void fmpz_factor_expand_iterative(fmpz_t n, const fmpz_factor_t factor)

    Evaluates an integer in factored form back to an \code{fmpz_t}.

    This currently exponentiates the bases separately and multiplies
    them together one by one, although much more efficient algorithms
    exist. 

int fmpz_factor_pp1(fmpz_t factor, const fmpz_t n, 
                                             ulong B1, ulong B2_sqrt, ulong c)

    Use Williams' $p + 1$ method to factor $n$, using a prime bound in
    stage 1 of \code{B1} and a prime limit in stage 2 of at least the square 
    of \code{B2_sqrt}. If a factor is found, the function returns $1$ and 
    \code{factor} is set to the factor that is found. Otherwise, the function 
    returns $0$.

    The value $c$ should be a random value greater than $2$. Successive 
    calls to the function with different values of $c$ give additional 
    chances to factor $n$ with roughly exponentially decaying probability 
    of finding a factor which has been missed (if $p+1$ or $p-1$ is not
    smooth for any prime factors $p$ of $n$ then the function will
    not ever succeed).
