1176 lines
41 KiB
C
1176 lines
41 KiB
C
/*=============================================================================
|
|
|
|
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) 2006, 2007, 2008, 2009, 2010, 2013 William Hart
|
|
Copyright (C) 2009, 2011 Andy Novocin
|
|
Copyright (C) 2010 Sebastian Pancratz
|
|
Copyright (C) 2011 Fredrik Johansson
|
|
|
|
******************************************************************************/
|
|
|
|
#ifndef FMPZ_POLY_H
|
|
#define FMPZ_POLY_H
|
|
|
|
#undef ulong
|
|
#define ulong ulongxx /* interferes with system includes */
|
|
#include <stdio.h>
|
|
#undef ulong
|
|
|
|
#include <gmp.h>
|
|
#define ulong mp_limb_t
|
|
|
|
#include "flint.h"
|
|
#include "fmpz.h"
|
|
#include "fmpz_vec.h"
|
|
#include "nmod_poly.h"
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define FMPZ_POLY_INV_NEWTON_CUTOFF 32
|
|
|
|
/* Type definitions *********************************************************/
|
|
|
|
typedef struct
|
|
{
|
|
fmpz * coeffs;
|
|
slong alloc;
|
|
slong length;
|
|
} fmpz_poly_struct;
|
|
|
|
typedef fmpz_poly_struct fmpz_poly_t[1];
|
|
|
|
typedef struct
|
|
{
|
|
fmpz ** powers;
|
|
slong len;
|
|
} fmpz_poly_powers_precomp_struct;
|
|
|
|
typedef fmpz_poly_powers_precomp_struct fmpz_poly_powers_precomp_t[1];
|
|
|
|
typedef struct {
|
|
fmpz c;
|
|
fmpz_poly_struct *p;
|
|
slong *exp;
|
|
slong num;
|
|
slong alloc;
|
|
} fmpz_poly_factor_struct;
|
|
|
|
typedef fmpz_poly_factor_struct fmpz_poly_factor_t[1];
|
|
|
|
/* Memory management ********************************************************/
|
|
|
|
void fmpz_poly_init(fmpz_poly_t poly);
|
|
|
|
void fmpz_poly_init2(fmpz_poly_t poly, slong alloc);
|
|
|
|
void fmpz_poly_realloc(fmpz_poly_t poly, slong alloc);
|
|
|
|
void fmpz_poly_fit_length(fmpz_poly_t poly, slong len);
|
|
|
|
void fmpz_poly_clear(fmpz_poly_t poly);
|
|
|
|
void _fmpz_poly_normalise(fmpz_poly_t poly);
|
|
|
|
static __inline__
|
|
void _fmpz_poly_set_length(fmpz_poly_t poly, slong newlen)
|
|
{
|
|
if (poly->length > newlen)
|
|
{
|
|
slong i;
|
|
for (i = newlen; i < poly->length; i++)
|
|
_fmpz_demote(poly->coeffs + i);
|
|
}
|
|
poly->length = newlen;
|
|
}
|
|
|
|
/* Polynomial parameters ***************************************************/
|
|
|
|
static __inline__
|
|
slong fmpz_poly_length(const fmpz_poly_t poly)
|
|
{
|
|
return poly->length;
|
|
}
|
|
|
|
static __inline__
|
|
slong fmpz_poly_degree(const fmpz_poly_t poly)
|
|
{
|
|
return poly->length - 1;
|
|
}
|
|
|
|
/* Assignment and basic manipulation ***************************************/
|
|
|
|
void fmpz_poly_set(fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void fmpz_poly_set_ui(fmpz_poly_t poly, ulong c);
|
|
|
|
void fmpz_poly_set_si(fmpz_poly_t poly, slong c);
|
|
|
|
void fmpz_poly_set_fmpz(fmpz_poly_t poly, const fmpz_t c);
|
|
|
|
void fmpz_poly_set_mpz(fmpz_poly_t poly, const mpz_t c);
|
|
|
|
int _fmpz_poly_set_str(fmpz * poly, const char * str);
|
|
|
|
int fmpz_poly_set_str(fmpz_poly_t poly, const char * str);
|
|
|
|
char * _fmpz_poly_get_str(const fmpz * poly, slong len);
|
|
|
|
char * fmpz_poly_get_str(const fmpz_poly_t poly);
|
|
|
|
char * _fmpz_poly_get_str_pretty(const fmpz * poly, slong len, const char * x);
|
|
|
|
char * fmpz_poly_get_str_pretty(const fmpz_poly_t poly, const char * x);
|
|
|
|
static __inline__
|
|
void fmpz_poly_zero(fmpz_poly_t poly)
|
|
{
|
|
_fmpz_poly_set_length(poly, 0);
|
|
}
|
|
|
|
static __inline__
|
|
void fmpz_poly_one(fmpz_poly_t poly)
|
|
{
|
|
fmpz_poly_set_ui(poly, UWORD(1));
|
|
}
|
|
|
|
void fmpz_poly_zero_coeffs(fmpz_poly_t poly, slong i, slong j);
|
|
|
|
void fmpz_poly_swap(fmpz_poly_t poly1, fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_reverse(fmpz * res, const fmpz * poly, slong len, slong n);
|
|
|
|
void fmpz_poly_reverse(fmpz_poly_t res, const fmpz_poly_t poly, slong n);
|
|
|
|
static __inline__
|
|
void fmpz_poly_truncate(fmpz_poly_t poly, slong newlen)
|
|
{
|
|
if (poly->length > newlen)
|
|
{
|
|
slong i;
|
|
for (i = newlen; i < poly->length; i++)
|
|
_fmpz_demote(poly->coeffs + i);
|
|
poly->length = newlen;
|
|
_fmpz_poly_normalise(poly);
|
|
}
|
|
}
|
|
|
|
/* Randomisation ***********************************************************/
|
|
|
|
void fmpz_poly_randtest(fmpz_poly_t f, flint_rand_t state,
|
|
slong len, mp_bitcnt_t bits);
|
|
|
|
void fmpz_poly_randtest_unsigned(fmpz_poly_t f, flint_rand_t state,
|
|
slong len, mp_bitcnt_t bits);
|
|
|
|
void fmpz_poly_randtest_not_zero(fmpz_poly_t f, flint_rand_t state,
|
|
slong len, mp_bitcnt_t bits);
|
|
|
|
/* Getting and setting coefficients ****************************************/
|
|
|
|
slong fmpz_poly_get_coeff_si(const fmpz_poly_t poly, slong n);
|
|
|
|
void fmpz_poly_set_coeff_si(fmpz_poly_t poly, slong n, slong x);
|
|
|
|
ulong fmpz_poly_get_coeff_ui(const fmpz_poly_t poly, slong n);
|
|
|
|
void fmpz_poly_set_coeff_ui(fmpz_poly_t poly, slong n, ulong x);
|
|
|
|
void fmpz_poly_set_coeff_fmpz(fmpz_poly_t poly, slong n, const fmpz_t x);
|
|
|
|
void fmpz_poly_get_coeff_fmpz(fmpz_t x, const fmpz_poly_t poly, slong n);
|
|
|
|
#define fmpz_poly_get_coeff_ptr(poly, n) \
|
|
((n) < (poly)->length ? (poly)->coeffs + (n) : NULL)
|
|
|
|
#define fmpz_poly_lead(poly) \
|
|
((poly)->length ? (poly)->coeffs + (poly)->length - 1 : NULL)
|
|
|
|
/* Comparison **************************************************************/
|
|
|
|
int fmpz_poly_equal(const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
#define fmpz_poly_is_zero(poly) \
|
|
((poly)->length == 0)
|
|
|
|
static __inline__
|
|
int _fmpz_poly_is_one(const fmpz *poly, slong len)
|
|
{
|
|
return (len > 0 && fmpz_is_one(poly)
|
|
&& _fmpz_vec_is_zero(poly + 1, len - 1));
|
|
}
|
|
|
|
static __inline__
|
|
int fmpz_poly_is_one(const fmpz_poly_t op)
|
|
{
|
|
return (op->length) == 1 && (*(op->coeffs) == WORD(1));
|
|
}
|
|
|
|
static __inline__
|
|
int fmpz_poly_is_unit(const fmpz_poly_t op)
|
|
{
|
|
return (op->length == 1) && (*(op->coeffs) == WORD(1) || *(op->coeffs) == WORD(-1));
|
|
}
|
|
|
|
static __inline__
|
|
int fmpz_poly_equal_fmpz(const fmpz_poly_t poly, const fmpz_t c)
|
|
{
|
|
return ((poly->length == 0) && fmpz_is_zero(c)) ||
|
|
((poly->length == 1) && fmpz_equal(poly->coeffs, c));
|
|
}
|
|
|
|
/* Addition and subtraction ************************************************/
|
|
|
|
void _fmpz_poly_add(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_add(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_sub(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_sub(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
void fmpz_poly_neg(fmpz_poly_t res, const fmpz_poly_t poly);
|
|
|
|
/* Scalar multiplication and division **************************************/
|
|
|
|
void fmpz_poly_scalar_mul_ui(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, ulong x);
|
|
|
|
void fmpz_poly_scalar_mul_si(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, slong x);
|
|
|
|
void fmpz_poly_scalar_mul_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x);
|
|
|
|
void fmpz_poly_scalar_addmul_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x);
|
|
|
|
void fmpz_poly_scalar_submul_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x);
|
|
|
|
void fmpz_poly_scalar_fdiv_ui(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, ulong x);
|
|
|
|
void fmpz_poly_scalar_fdiv_si(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, slong x);
|
|
|
|
void fmpz_poly_scalar_fdiv_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x);
|
|
|
|
void fmpz_poly_scalar_tdiv_ui(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, ulong x);
|
|
|
|
void fmpz_poly_scalar_tdiv_si(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, slong x);
|
|
|
|
void fmpz_poly_scalar_tdiv_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x);
|
|
|
|
void fmpz_poly_scalar_divexact_ui(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, ulong x);
|
|
|
|
void fmpz_poly_scalar_divexact_si(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, slong x);
|
|
|
|
void fmpz_poly_scalar_divexact_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x);
|
|
|
|
void fmpz_poly_scalar_fdiv_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2,
|
|
ulong exp);
|
|
|
|
void fmpz_poly_scalar_tdiv_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2,
|
|
ulong exp);
|
|
|
|
void fmpz_poly_scalar_mul_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2,
|
|
ulong exp);
|
|
|
|
static __inline__
|
|
void fmpz_poly_scalar_mod_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x)
|
|
{
|
|
if (poly2->length == 0)
|
|
{
|
|
fmpz_poly_zero(poly1);
|
|
}
|
|
else
|
|
{
|
|
fmpz_poly_fit_length(poly1, poly2->length);
|
|
_fmpz_vec_scalar_mod_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x);
|
|
_fmpz_poly_set_length(poly1, poly2->length);
|
|
_fmpz_poly_normalise(poly1);
|
|
}
|
|
}
|
|
|
|
static __inline__
|
|
void fmpz_poly_scalar_smod_fmpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const fmpz_t x)
|
|
{
|
|
if (poly2->length == 0)
|
|
{
|
|
fmpz_poly_zero(poly1);
|
|
}
|
|
else
|
|
{
|
|
fmpz_poly_fit_length(poly1, poly2->length);
|
|
_fmpz_vec_scalar_smod_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x);
|
|
_fmpz_poly_set_length(poly1, poly2->length);
|
|
_fmpz_poly_normalise(poly1);
|
|
|
|
}
|
|
}
|
|
|
|
/* Bit packing *************************************************************/
|
|
|
|
void _fmpz_poly_bit_pack(mp_ptr arr, const fmpz * poly,
|
|
slong len, mp_bitcnt_t bit_size, int negate);
|
|
|
|
int _fmpz_poly_bit_unpack(fmpz * poly, slong len,
|
|
mp_srcptr arr, mp_bitcnt_t bit_size, int negate);
|
|
|
|
void _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len,
|
|
mp_srcptr arr, mp_bitcnt_t bit_size);
|
|
|
|
void fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly,
|
|
mp_bitcnt_t bit_size);
|
|
|
|
void fmpz_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f,
|
|
mp_bitcnt_t bit_size);
|
|
|
|
void fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f,
|
|
mp_bitcnt_t bit_size);
|
|
|
|
|
|
/* Multiplication **********************************************************/
|
|
|
|
void _fmpz_poly_mul_classical(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_mul_classical(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_mullow_classical(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2, slong n);
|
|
|
|
void fmpz_poly_mullow_classical(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, slong n);
|
|
|
|
void _fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1,
|
|
slong len1, const fmpz * poly2, slong len2, slong start);
|
|
|
|
void fmpz_poly_mulhigh_classical(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong start);
|
|
|
|
void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1,
|
|
slong len1, const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_mulmid_classical(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void fmpz_poly_mul_karatsuba(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1,
|
|
slong len1, const fmpz * poly2, slong len2);
|
|
|
|
void _fmpz_poly_mullow_karatsuba_n(fmpz * res, const fmpz * poly1,
|
|
const fmpz * poly2, slong n);
|
|
|
|
void fmpz_poly_mullow_karatsuba_n(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);
|
|
|
|
void _fmpz_poly_mulhigh_karatsuba_n(fmpz * res, const fmpz * poly1,
|
|
const fmpz * poly2, slong len);
|
|
|
|
void fmpz_poly_mulhigh_karatsuba_n(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong length);
|
|
|
|
void _fmpz_poly_mul_KS(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_mul_KS(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_mullow_KS(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2, slong n);
|
|
|
|
void fmpz_poly_mullow_KS(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, slong n);
|
|
|
|
void _fmpz_poly_mul_SS(fmpz * output, const fmpz * input1, slong length1,
|
|
const fmpz * input2, slong length2);
|
|
|
|
void fmpz_poly_mul_SS(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_mullow_SS(fmpz * output, const fmpz * input1, slong length1,
|
|
const fmpz * input2, slong length2, slong n);
|
|
|
|
void fmpz_poly_mullow_SS(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);
|
|
|
|
void _fmpz_poly_mul(fmpz * res, const fmpz * poly1,
|
|
slong len1, const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_mul(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_mullow(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2, slong n);
|
|
|
|
void fmpz_poly_mullow(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);
|
|
|
|
void fmpz_poly_mulhigh_n(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);
|
|
|
|
/* Squaring ******************************************************************/
|
|
|
|
void _fmpz_poly_sqr_KS(fmpz * rop, const fmpz * op, slong len);
|
|
|
|
void fmpz_poly_sqr_KS(fmpz_poly_t rop, const fmpz_poly_t op);
|
|
|
|
void fmpz_poly_sqr_karatsuba(fmpz_poly_t rop, const fmpz_poly_t op);
|
|
|
|
void _fmpz_poly_sqr_karatsuba(fmpz * rop, const fmpz * op, slong len);
|
|
|
|
void _fmpz_poly_sqr_classical(fmpz * rop, const fmpz * op, slong len);
|
|
|
|
void fmpz_poly_sqr_classical(fmpz_poly_t rop, const fmpz_poly_t op);
|
|
|
|
void _fmpz_poly_sqr(fmpz * rop, const fmpz * op, slong len);
|
|
|
|
void fmpz_poly_sqr(fmpz_poly_t rop, const fmpz_poly_t op);
|
|
|
|
void _fmpz_poly_sqrlow_KS(fmpz * res, const fmpz * poly, slong len, slong n);
|
|
|
|
void fmpz_poly_sqrlow_KS(fmpz_poly_t res, const fmpz_poly_t poly, slong n);
|
|
|
|
void _fmpz_poly_sqrlow_karatsuba_n(fmpz * res, const fmpz * poly, slong n);
|
|
|
|
void fmpz_poly_sqrlow_karatsuba_n(fmpz_poly_t res, const fmpz_poly_t poly, slong n);
|
|
|
|
void _fmpz_poly_sqrlow_classical(fmpz * res, const fmpz * poly, slong len, slong n);
|
|
|
|
void fmpz_poly_sqrlow_classical(fmpz_poly_t res, const fmpz_poly_t poly, slong n);
|
|
|
|
void _fmpz_poly_sqrlow(fmpz * res, const fmpz * poly, slong len, slong n);
|
|
|
|
void fmpz_poly_sqrlow(fmpz_poly_t res, const fmpz_poly_t poly, slong n);
|
|
|
|
/* Powering ****************************************************************/
|
|
|
|
void _fmpz_poly_pow_multinomial(fmpz * res, const fmpz * poly, slong len, ulong e);
|
|
|
|
void fmpz_poly_pow_multinomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e);
|
|
|
|
void _fmpz_poly_pow_binomial(fmpz * res, const fmpz * poly, ulong e);
|
|
|
|
void fmpz_poly_pow_binomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e);
|
|
|
|
void _fmpz_poly_pow_binexp(fmpz * res, const fmpz * poly, slong len, ulong e);
|
|
|
|
void fmpz_poly_pow_binexp(fmpz_poly_t res, const fmpz_poly_t poly, ulong e);
|
|
|
|
void _fmpz_poly_pow_addchains(fmpz * res, const fmpz * poly, slong len, const int * a, int n);
|
|
|
|
void fmpz_poly_pow_addchains(fmpz_poly_t res, const fmpz_poly_t poly, ulong e);
|
|
|
|
void _fmpz_poly_pow_small(fmpz * res, const fmpz * poly, slong len, ulong e);
|
|
|
|
void _fmpz_poly_pow(fmpz * res, const fmpz * poly, slong len, ulong e);
|
|
|
|
void fmpz_poly_pow(fmpz_poly_t res, const fmpz_poly_t poly, ulong e);
|
|
|
|
void _fmpz_poly_pow_trunc(fmpz * res, const fmpz * poly, ulong e, slong n);
|
|
|
|
void
|
|
fmpz_poly_pow_trunc(fmpz_poly_t res, const fmpz_poly_t poly, ulong e, slong n);
|
|
|
|
/* Shifting ****************************************************************/
|
|
|
|
void _fmpz_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n);
|
|
|
|
void _fmpz_poly_shift_right(fmpz * res, const fmpz * poly, slong len, slong n);
|
|
|
|
void fmpz_poly_shift_left(fmpz_poly_t res, const fmpz_poly_t poly, slong n);
|
|
|
|
void fmpz_poly_shift_right(fmpz_poly_t res, const fmpz_poly_t poly, slong n);
|
|
|
|
/* Norms *******************************************************************/
|
|
|
|
void _fmpz_poly_2norm(fmpz_t res, const fmpz * poly, slong len);
|
|
|
|
void fmpz_poly_2norm(fmpz_t res, const fmpz_poly_t poly);
|
|
|
|
mp_bitcnt_t _fmpz_poly_2norm_normalised_bits(const fmpz * poly, slong len);
|
|
|
|
static __inline__
|
|
ulong fmpz_poly_max_limbs(const fmpz_poly_t poly)
|
|
{
|
|
return _fmpz_vec_max_limbs(poly->coeffs, poly->length);
|
|
}
|
|
|
|
static __inline__
|
|
slong fmpz_poly_max_bits(const fmpz_poly_t poly)
|
|
{
|
|
return _fmpz_vec_max_bits(poly->coeffs, poly->length);
|
|
}
|
|
|
|
static __inline__ void
|
|
fmpz_poly_height(fmpz_t res, const fmpz_poly_t poly)
|
|
{
|
|
_fmpz_vec_height(res, poly->coeffs, poly->length);
|
|
}
|
|
|
|
/* Greatest common divisor *************************************************/
|
|
|
|
void _fmpz_poly_gcd_subresultant(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_gcd_subresultant(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
int _fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
int fmpz_poly_gcd_heuristic(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_gcd_modular(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_gcd_modular(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_gcd(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_gcd(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_lcm(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_lcm(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_resultant(fmpz_t res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_resultant(fmpz_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_xgcd_modular(fmpz_t r, fmpz * s, fmpz * t,
|
|
const fmpz * poly1, slong len1, const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_xgcd_modular(fmpz_t r, fmpz_poly_t s, fmpz_poly_t t,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2);
|
|
|
|
static __inline__
|
|
void _fmpz_poly_xgcd(fmpz_t r, fmpz * s, fmpz * t,
|
|
const fmpz * poly1, slong len1, const fmpz * poly2, slong len2)
|
|
{
|
|
_fmpz_poly_xgcd_modular(r, s, t, poly1, len1, poly2, len2);
|
|
}
|
|
|
|
static __inline__
|
|
void fmpz_poly_xgcd(fmpz_t r, fmpz_poly_t s, fmpz_poly_t t,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2)
|
|
{
|
|
fmpz_poly_xgcd_modular(r, s, t, poly1, poly2);
|
|
}
|
|
|
|
/* Gaussian content ********************************************************/
|
|
|
|
void _fmpz_poly_content(fmpz_t res, const fmpz * poly, slong len);
|
|
|
|
void fmpz_poly_content(fmpz_t res, const fmpz_poly_t poly);
|
|
|
|
void _fmpz_poly_primitive_part(fmpz * res, const fmpz * poly, slong len);
|
|
|
|
void fmpz_poly_primitive_part(fmpz_poly_t res, const fmpz_poly_t poly);
|
|
|
|
/* Square-free *************************************************************/
|
|
|
|
int _fmpz_poly_is_squarefree(const fmpz * poly, slong len);
|
|
|
|
int fmpz_poly_is_squarefree(const fmpz_poly_t poly);
|
|
|
|
/* Euclidean division ******************************************************/
|
|
|
|
void _fmpz_poly_divrem_basecase(fmpz * Q, fmpz * R, const fmpz * A,
|
|
slong lenA, const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R,
|
|
const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W,
|
|
const fmpz * A, const fmpz * B, slong lenB);
|
|
|
|
void _fmpz_poly_divrem_divconquer(fmpz * Q, fmpz * R,
|
|
const fmpz * A, slong lenA, const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R,
|
|
const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_divrem(fmpz * Q, fmpz * R, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_divrem(fmpz_poly_t Q, fmpz_poly_t R, const fmpz_poly_t A,
|
|
const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_div_basecase(fmpz * Q, fmpz * R, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_div_basecase(fmpz_poly_t Q,
|
|
const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_divremlow_divconquer_recursive(fmpz * Q, fmpz * QB,
|
|
const fmpz * A, const fmpz * B, slong lenB);
|
|
|
|
void _fmpz_poly_div_divconquer_recursive(fmpz * Q, fmpz * temp,
|
|
const fmpz * A, const fmpz * B, slong lenB);
|
|
|
|
void _fmpz_poly_div_divconquer(fmpz * Q, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_div_divconquer(fmpz_poly_t Q,
|
|
const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_div(fmpz * Q, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_div(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_preinvert(fmpz * B_inv, const fmpz * B, slong n);
|
|
|
|
void fmpz_poly_preinvert(fmpz_poly_t B_inv, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_div_preinv(fmpz * Q, const fmpz * A, slong len1,
|
|
const fmpz * B, const fmpz * B_inv, slong len2);
|
|
|
|
void fmpz_poly_div_preinv(fmpz_poly_t Q, const fmpz_poly_t A,
|
|
const fmpz_poly_t B, const fmpz_poly_t B_inv);
|
|
|
|
void _fmpz_poly_divrem_preinv(fmpz * Q, fmpz * A, slong len1,
|
|
const fmpz * B, const fmpz * B_inv, slong len2);
|
|
|
|
void fmpz_poly_divrem_preinv(fmpz_poly_t Q, fmpz_poly_t R,
|
|
const fmpz_poly_t A, const fmpz_poly_t B, const fmpz_poly_t B_inv);
|
|
|
|
fmpz ** _fmpz_poly_powers_precompute(const fmpz * B, slong len);
|
|
|
|
void fmpz_poly_powers_precompute(fmpz_poly_powers_precomp_t pinv,
|
|
fmpz_poly_t poly);
|
|
|
|
void _fmpz_poly_powers_clear(fmpz ** powers, slong len);
|
|
|
|
void fmpz_poly_powers_clear(fmpz_poly_powers_precomp_t pinv);
|
|
|
|
void _fmpz_poly_rem_powers_precomp(fmpz * A, slong m,
|
|
const fmpz * B, slong n, fmpz ** const powers);
|
|
|
|
void fmpz_poly_rem_powers_precomp(fmpz_poly_t R,
|
|
const fmpz_poly_t A, const fmpz_poly_t B,
|
|
const fmpz_poly_powers_precomp_t B_inv);
|
|
|
|
void _fmpz_poly_rem_basecase(fmpz * Q, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_rem_basecase(fmpz_poly_t R,
|
|
const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_rem(fmpz * R, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_rem(fmpz_poly_t R, const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void
|
|
fmpz_poly_div_root(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_t c);
|
|
|
|
void
|
|
_fmpz_poly_div_root(fmpz * Q, const fmpz * A, slong len, const fmpz_t c);
|
|
|
|
/* Power series division ***************************************************/
|
|
|
|
void _fmpz_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n);
|
|
|
|
void fmpz_poly_inv_series_newton(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n);
|
|
|
|
static __inline__ void
|
|
_fmpz_poly_inv_series(fmpz * Qinv, const fmpz * Q, slong n)
|
|
{
|
|
_fmpz_poly_inv_series_newton(Qinv, Q, n);
|
|
}
|
|
|
|
static __inline__ void
|
|
fmpz_poly_inv_series(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n)
|
|
{
|
|
fmpz_poly_inv_series_newton(Qinv, Q, n);
|
|
}
|
|
|
|
void _fmpz_poly_div_series(fmpz * Q, const fmpz * A, const fmpz * B, slong n);
|
|
|
|
void fmpz_poly_div_series(fmpz_poly_t Q, const fmpz_poly_t A,
|
|
const fmpz_poly_t B, slong n);
|
|
|
|
/* Divisibility testing ***************************************************/
|
|
|
|
int _fmpz_poly_divides(fmpz * q, const fmpz * a,
|
|
slong len1, const fmpz * b, slong len2);
|
|
|
|
int fmpz_poly_divides(fmpz_poly_t q, const fmpz_poly_t a, const fmpz_poly_t b);
|
|
|
|
|
|
/* Pseudo division *********************************************************/
|
|
|
|
void _fmpz_poly_pseudo_divrem_basecase(fmpz * Q, fmpz * R,
|
|
ulong * d, const fmpz * A, slong A_len,
|
|
const fmpz * B, slong B_len, const fmpz_preinvn_t inv);
|
|
|
|
void fmpz_poly_pseudo_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R,
|
|
ulong * d, const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_pseudo_divrem_divconquer(fmpz * Q, fmpz * R,
|
|
ulong * d, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB, const fmpz_preinvn_t inv);
|
|
|
|
void fmpz_poly_pseudo_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R,
|
|
ulong * d, const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_pseudo_divrem_cohen(fmpz * Q, fmpz * R, const fmpz * A,
|
|
slong lenA, const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_pseudo_divrem_cohen(fmpz_poly_t Q, fmpz_poly_t R,
|
|
const fmpz_poly_t A, const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_pseudo_rem_cohen(fmpz * R, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB);
|
|
|
|
void fmpz_poly_pseudo_rem_cohen(fmpz_poly_t R, const fmpz_poly_t A,
|
|
const fmpz_poly_t B);
|
|
|
|
static __inline__
|
|
void _fmpz_poly_pseudo_divrem(fmpz * Q, fmpz * R,
|
|
ulong * d, const fmpz * A, slong A_len,
|
|
const fmpz * B, slong B_len, const fmpz_preinvn_t inv)
|
|
{
|
|
_fmpz_poly_pseudo_divrem_divconquer(Q, R, d, A, A_len, B, B_len, inv);
|
|
}
|
|
|
|
static __inline__
|
|
void fmpz_poly_pseudo_divrem(fmpz_poly_t Q, fmpz_poly_t R,
|
|
ulong * d, const fmpz_poly_t A, const fmpz_poly_t B)
|
|
{
|
|
fmpz_poly_pseudo_divrem_divconquer(Q, R, d, A, B);
|
|
}
|
|
|
|
void _fmpz_poly_pseudo_div(fmpz * Q, ulong * d, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB, const fmpz_preinvn_t inv);
|
|
|
|
void fmpz_poly_pseudo_div(fmpz_poly_t Q, ulong * d, const fmpz_poly_t A,
|
|
const fmpz_poly_t B);
|
|
|
|
void _fmpz_poly_pseudo_rem(fmpz * R, ulong * d, const fmpz * A, slong lenA,
|
|
const fmpz * B, slong lenB, const fmpz_preinvn_t inv);
|
|
|
|
void fmpz_poly_pseudo_rem(fmpz_poly_t R, ulong * d, const fmpz_poly_t A,
|
|
const fmpz_poly_t B);
|
|
|
|
/* Derivative **************************************************************/
|
|
|
|
void _fmpz_poly_derivative(fmpz * rpoly, const fmpz * poly, slong len);
|
|
|
|
void fmpz_poly_derivative(fmpz_poly_t res, const fmpz_poly_t poly);
|
|
|
|
/* Evaluation **************************************************************/
|
|
|
|
void
|
|
_fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, const fmpz * poly, slong len,
|
|
const fmpz_t a);
|
|
|
|
void fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, const fmpz_poly_t poly,
|
|
const fmpz_t a);
|
|
|
|
void _fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz * f, slong len,
|
|
const fmpz_t a);
|
|
|
|
void fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz_poly_t f,
|
|
const fmpz_t a);
|
|
|
|
void _fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz * f, slong len, const fmpz_t a);
|
|
|
|
void fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz_poly_t f, const fmpz_t a);
|
|
|
|
void _fmpz_poly_evaluate_horner_mpq(fmpz_t rnum, fmpz_t rden,
|
|
const fmpz * f, slong len,
|
|
const fmpz_t anum, const fmpz_t aden);
|
|
|
|
void fmpz_poly_evaluate_horner_mpq(mpq_t res, const fmpz_poly_t f,
|
|
const mpq_t a);
|
|
|
|
void _fmpz_poly_evaluate_mpq(fmpz_t rnum, fmpz_t rden,
|
|
const fmpz * f, slong len,
|
|
const fmpz_t anum, const fmpz_t aden);
|
|
|
|
void fmpz_poly_evaluate_mpq(mpq_t res, const fmpz_poly_t f, const mpq_t a);
|
|
|
|
mp_limb_t _fmpz_poly_evaluate_mod(const fmpz * poly, slong len, mp_limb_t a,
|
|
mp_limb_t n, mp_limb_t ninv);
|
|
|
|
mp_limb_t fmpz_poly_evaluate_mod(const fmpz_poly_t poly, mp_limb_t a,
|
|
mp_limb_t n);
|
|
|
|
void
|
|
_fmpz_poly_evaluate_divconquer(fmpz * res, const fmpz * poly, slong len,
|
|
const fmpz_t x);
|
|
|
|
void
|
|
fmpz_poly_evaluate_divconquer(fmpz_t res,
|
|
const fmpz_poly_t poly, const fmpz_t x);
|
|
|
|
/* Composition *************************************************************/
|
|
|
|
void _fmpz_poly_compose_horner(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_compose_horner(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_compose_divconquer(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_compose_divconquer(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
void _fmpz_poly_compose(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2);
|
|
|
|
void fmpz_poly_compose(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2);
|
|
|
|
/* Taylor shift ************************************************************/
|
|
|
|
void _fmpz_poly_taylor_shift_horner(fmpz * poly, const fmpz_t c, slong n);
|
|
|
|
void fmpz_poly_taylor_shift_horner(fmpz_poly_t g, const fmpz_poly_t f,
|
|
const fmpz_t c);
|
|
|
|
void _fmpz_poly_taylor_shift_divconquer(fmpz * poly, const fmpz_t c, slong n);
|
|
|
|
void fmpz_poly_taylor_shift_divconquer(fmpz_poly_t g, const fmpz_poly_t f,
|
|
const fmpz_t c);
|
|
|
|
void _fmpz_poly_taylor_shift(fmpz * poly, const fmpz_t c, slong n);
|
|
|
|
void fmpz_poly_taylor_shift(fmpz_poly_t g, const fmpz_poly_t f, const fmpz_t c);
|
|
|
|
/* Power series composition and compositional inverse **********************/
|
|
|
|
void
|
|
_fmpz_poly_compose_series_brent_kung(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2, slong n);
|
|
|
|
void
|
|
fmpz_poly_compose_series_brent_kung(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);
|
|
|
|
void
|
|
_fmpz_poly_compose_series_horner(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2, slong n);
|
|
|
|
void
|
|
fmpz_poly_compose_series_horner(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);
|
|
|
|
void
|
|
_fmpz_poly_compose_series(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz * poly2, slong len2, slong n);
|
|
|
|
void
|
|
fmpz_poly_compose_series(fmpz_poly_t res,
|
|
const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n);
|
|
|
|
void
|
|
_fmpz_poly_revert_series_lagrange(fmpz * Qinv, const fmpz * Q, slong n);
|
|
|
|
void
|
|
fmpz_poly_revert_series_lagrange(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n);
|
|
|
|
void
|
|
_fmpz_poly_revert_series_lagrange_fast(fmpz * Qinv, const fmpz * Q, slong n);
|
|
|
|
void
|
|
fmpz_poly_revert_series_lagrange_fast(fmpz_poly_t Qinv,
|
|
const fmpz_poly_t Q, slong n);
|
|
|
|
void
|
|
_fmpz_poly_revert_series_newton(fmpz * Qinv, const fmpz * Q, slong n);
|
|
|
|
void
|
|
fmpz_poly_revert_series_newton(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n);
|
|
|
|
void
|
|
_fmpz_poly_revert_series(fmpz * Qinv, const fmpz * Q, slong n);
|
|
|
|
void
|
|
fmpz_poly_revert_series(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n);
|
|
|
|
/* Square root *************************************************************/
|
|
|
|
int _fmpz_poly_sqrt_classical(fmpz * res, const fmpz * poly, slong len);
|
|
|
|
int fmpz_poly_sqrt_classical(fmpz_poly_t b, const fmpz_poly_t a);
|
|
|
|
int _fmpz_poly_sqrt(fmpz * res, const fmpz * poly, slong len);
|
|
|
|
int fmpz_poly_sqrt(fmpz_poly_t b, const fmpz_poly_t a);
|
|
|
|
|
|
/* Signature ***************************************************************/
|
|
|
|
void _fmpz_poly_signature(slong * r1, slong * r2, const fmpz * poly, slong len);
|
|
|
|
void fmpz_poly_signature(slong * r1, slong * r2, const fmpz_poly_t poly);
|
|
|
|
/* Input and output ********************************************************/
|
|
|
|
int fmpz_poly_fprint(FILE * file, const fmpz_poly_t poly);
|
|
|
|
int _fmpz_poly_fprint_pretty(FILE * file,
|
|
const fmpz * poly, slong len, const char * x);
|
|
|
|
int fmpz_poly_fprint_pretty(FILE * file,
|
|
const fmpz_poly_t poly, const char * x);
|
|
|
|
static __inline__
|
|
int fmpz_poly_print(const fmpz_poly_t poly)
|
|
{
|
|
return fmpz_poly_fprint(stdout, poly);
|
|
}
|
|
|
|
static __inline__
|
|
int fmpz_poly_print_pretty(const fmpz_poly_t poly, const char * x)
|
|
{
|
|
return fmpz_poly_fprint_pretty(stdout, poly, x);
|
|
}
|
|
|
|
int fmpz_poly_fread(FILE * file, fmpz_poly_t poly);
|
|
|
|
int fmpz_poly_fread_pretty(FILE *file, fmpz_poly_t poly, char **x);
|
|
|
|
static __inline__
|
|
int fmpz_poly_read(fmpz_poly_t poly)
|
|
{
|
|
return fmpz_poly_fread(stdin, poly);
|
|
}
|
|
|
|
static __inline__
|
|
int fmpz_poly_read_pretty(fmpz_poly_t poly, char **x)
|
|
{
|
|
return fmpz_poly_fread_pretty(stdin, poly, x);
|
|
}
|
|
|
|
static __inline__
|
|
void fmpz_poly_debug(const fmpz_poly_t poly)
|
|
{
|
|
flint_printf("(alloc = %wd, length = %wd, vec = ", poly->alloc, poly->length);
|
|
if (poly->coeffs)
|
|
{
|
|
flint_printf("{");
|
|
_fmpz_vec_print(poly->coeffs, poly->alloc);
|
|
flint_printf("}");
|
|
}
|
|
else
|
|
{
|
|
flint_printf("NULL");
|
|
}
|
|
flint_printf(")");
|
|
fflush(stdout);
|
|
}
|
|
|
|
/* CRT ********************************************************************/
|
|
|
|
void fmpz_poly_get_nmod_poly(nmod_poly_t res, const fmpz_poly_t poly);
|
|
|
|
void fmpz_poly_set_nmod_poly(fmpz_poly_t res, const nmod_poly_t poly);
|
|
|
|
void fmpz_poly_set_nmod_poly_unsigned(fmpz_poly_t res, const nmod_poly_t poly);
|
|
|
|
void
|
|
_fmpz_poly_CRT_ui_precomp(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2,
|
|
mp_limb_t m2inv, fmpz_t m1m2, mp_limb_t c, int sign);
|
|
|
|
void _fmpz_poly_CRT_ui(fmpz * res, const fmpz * poly1, slong len1,
|
|
const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2,
|
|
mp_limb_t m2inv, int sign);
|
|
|
|
void fmpz_poly_CRT_ui(fmpz_poly_t res, const fmpz_poly_t poly1,
|
|
const fmpz_t m1, const nmod_poly_t poly2,
|
|
int sign);
|
|
|
|
|
|
/* Products *****************************************************************/
|
|
|
|
void _fmpz_poly_product_roots_fmpz_vec(fmpz * poly,
|
|
const fmpz * xs, slong n);
|
|
|
|
void fmpz_poly_product_roots_fmpz_vec(fmpz_poly_t poly,
|
|
const fmpz * xs, slong n);
|
|
|
|
/* Newton basis *************************************************************/
|
|
|
|
void _fmpz_poly_monomial_to_newton(fmpz * poly, const fmpz * roots, slong n);
|
|
|
|
void _fmpz_poly_newton_to_monomial(fmpz * poly, const fmpz * roots, slong n);
|
|
|
|
|
|
/* Multipoint evaluation and interpolation *********************************/
|
|
|
|
void
|
|
fmpz_poly_evaluate_fmpz_vec(fmpz * res, const fmpz_poly_t f,
|
|
const fmpz * a, slong n);
|
|
|
|
void
|
|
fmpz_poly_interpolate_fmpz_vec(fmpz_poly_t poly,
|
|
const fmpz * xs, const fmpz * ys, slong n);
|
|
|
|
/* Hensel lifting ************************************************************/
|
|
|
|
void fmpz_poly_hensel_build_tree(slong * link, fmpz_poly_t *v, fmpz_poly_t *w,
|
|
const nmod_poly_factor_t fac);
|
|
|
|
void fmpz_poly_hensel_lift(fmpz_poly_t Gout, fmpz_poly_t Hout,
|
|
fmpz_poly_t Aout, fmpz_poly_t Bout,
|
|
const fmpz_poly_t f,
|
|
const fmpz_poly_t g, const fmpz_poly_t h,
|
|
const fmpz_poly_t a, const fmpz_poly_t b,
|
|
const fmpz_t p, const fmpz_t p1);
|
|
|
|
void _fmpz_poly_hensel_lift_without_inverse(fmpz *G, fmpz *H,
|
|
const fmpz *f, slong lenF,
|
|
const fmpz *g, slong lenG, const fmpz *h, slong lenH,
|
|
const fmpz *a, slong lenA, const fmpz *b, slong lenB,
|
|
const fmpz_t p, const fmpz_t p1);
|
|
|
|
void fmpz_poly_hensel_lift_without_inverse(fmpz_poly_t Gout, fmpz_poly_t Hout,
|
|
const fmpz_poly_t f, const fmpz_poly_t g, const fmpz_poly_t h,
|
|
const fmpz_poly_t a, const fmpz_poly_t b,
|
|
const fmpz_t p, const fmpz_t p1);
|
|
|
|
void _fmpz_poly_hensel_lift_only_inverse(fmpz *A, fmpz *B,
|
|
const fmpz *G, slong lenG, const fmpz *H, slong lenH,
|
|
const fmpz *a, slong lenA, const fmpz *b, slong lenB,
|
|
const fmpz_t p, const fmpz_t p1);
|
|
|
|
void fmpz_poly_hensel_lift_only_inverse(fmpz_poly_t Aout, fmpz_poly_t Bout,
|
|
const fmpz_poly_t G, const fmpz_poly_t H,
|
|
const fmpz_poly_t a, const fmpz_poly_t b,
|
|
const fmpz_t p, const fmpz_t p1);
|
|
|
|
void fmpz_poly_hensel_lift_tree_recursive(slong *link,
|
|
fmpz_poly_t *v, fmpz_poly_t *w, fmpz_poly_t f, slong j, slong inv,
|
|
const fmpz_t p0, const fmpz_t p1);
|
|
|
|
void fmpz_poly_hensel_lift_tree(slong *link, fmpz_poly_t *v, fmpz_poly_t *w,
|
|
fmpz_poly_t f, slong r, const fmpz_t p, slong e0, slong e1, slong inv);
|
|
|
|
slong _fmpz_poly_hensel_start_lift(fmpz_poly_factor_t lifted_fac, slong *link,
|
|
fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f,
|
|
const nmod_poly_factor_t local_fac, slong target_exp);
|
|
|
|
slong _fmpz_poly_hensel_continue_lift(fmpz_poly_factor_t lifted_fac,
|
|
slong *link, fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f,
|
|
slong prev, slong curr, slong N, const fmpz_t p);
|
|
|
|
void fmpz_poly_hensel_lift_once(fmpz_poly_factor_t lifted_fac,
|
|
const fmpz_poly_t f,
|
|
const nmod_poly_factor_t local_fac, slong N);
|
|
|
|
/* Some functions for backwards compatibility */
|
|
|
|
static __inline__ void fmpz_poly_scalar_mul_mpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const mpz_t x)
|
|
{
|
|
fmpz_t t;
|
|
fmpz_init_set_readonly(t, x);
|
|
fmpz_poly_scalar_mul_fmpz(poly1, poly2, t);
|
|
fmpz_clear_readonly(t);
|
|
}
|
|
|
|
static __inline__ void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const mpz_t x)
|
|
{
|
|
fmpz_t t;
|
|
fmpz_init_set_readonly(t, x);
|
|
fmpz_poly_scalar_divexact_fmpz(poly1, poly2, t);
|
|
fmpz_clear_readonly(t);
|
|
}
|
|
|
|
static __inline__ void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t poly1,
|
|
const fmpz_poly_t poly2, const mpz_t x)
|
|
{
|
|
fmpz_t t;
|
|
fmpz_init_set_readonly(t, x);
|
|
fmpz_poly_scalar_fdiv_fmpz(poly1, poly2, t);
|
|
fmpz_clear_readonly(t);
|
|
}
|
|
|
|
static __inline__ void fmpz_poly_set_coeff_mpz(fmpz_poly_t poly, slong n,
|
|
const mpz_t x)
|
|
{
|
|
fmpz_t t;
|
|
fmpz_init_set_readonly(t, x);
|
|
fmpz_poly_set_coeff_fmpz(poly, n, t);
|
|
fmpz_clear_readonly(t);
|
|
}
|
|
|
|
static __inline__ void fmpz_poly_get_coeff_mpz(mpz_t x, const fmpz_poly_t poly, slong n)
|
|
{
|
|
fmpz_t t;
|
|
fmpz_init(t);
|
|
fmpz_poly_get_coeff_fmpz(t, poly, n);
|
|
fmpz_get_mpz(x, t);
|
|
fmpz_clear(t);
|
|
}
|
|
|
|
/* Roots */
|
|
|
|
void _fmpz_poly_bound_roots(fmpz_t bound, const fmpz * poly, slong len);
|
|
|
|
void fmpz_poly_bound_roots(fmpz_t bound, const fmpz_poly_t poly);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#include "fmpz_poly_factor.h"
|
|
|
|
#endif
|
|
|